diff mbox

[PR,middle-end/70807] Free dominance info in CSE pass

Message ID 20160510161934.GD46462@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Enkovich May 10, 2016, 4:19 p.m. UTC
Hi,

Curretly CSE may modify CFG and leave invalid dominance info.  This patch
improves track of CFG changes by CSE passes and frees dominance info if
required.  This allows to remove corresponding workaround from STV pass.

Does it look OK?

Bootstrapped and regtested on x86-64-unknown-linux-gnu.

Thanks,
Ilya
--
gcc/

2016-05-10  Ilya Enkovich  <ilya.enkovich@intel.com>

	PR middle-end/70807
	* cfgrtl.h (delete_insn_and_edges): Now return bool.
	* cfgrtl.c (delete_insn_and_edges): Likewise.
	* config/i386/i386.c (convert_scalars_to_vector): Remove
	redundant code.
	* cse.c (cse_insn): Compute cse_cfg_altered.
	(delete_trivially_dead_insns): Likewise.
	(cse_cc_succs): Likewise.
	(rest_of_handle_cse): Free dominance info if required.
	(rest_of_handle_cse2): Likewise.
	(rest_of_handle_cse_after_global_opts): Likewise.

gcc/testsuite/

2016-05-10  Ilya Enkovich  <ilya.enkovich@intel.com>

	PR middle-end/70807
	* gcc.dg/pr70807.c: New test.

Comments

Bernd Schmidt May 10, 2016, 4:59 p.m. UTC | #1
On 05/10/2016 06:19 PM, Ilya Enkovich wrote:
> Curretly CSE may modify CFG and leave invalid dominance info.  This patch
> improves track of CFG changes by CSE passes and frees dominance info if
> required.  This allows to remove corresponding workaround from STV pass.
>
> Does it look OK?

Better tracking of cse_cfg_altered seems good regardless. So that's an 
OK for everything but...

> +  if (cse_cfg_altered && dom_info_available_p (CDI_DOMINATORS))
> +    free_dominance_info (CDI_DOMINATORS);

I wonder whether it should be the last user of dominance info that 
should be freeing it (maybe it's not just cse that can destroy it?)

Which pass is leaving it around?


Bernd
Richard Biener May 10, 2016, 5:06 p.m. UTC | #2
On May 10, 2016 6:59:31 PM GMT+02:00, Bernd Schmidt <bschmidt@redhat.com> wrote:
>On 05/10/2016 06:19 PM, Ilya Enkovich wrote:
>> Curretly CSE may modify CFG and leave invalid dominance info.  This
>patch
>> improves track of CFG changes by CSE passes and frees dominance info
>if
>> required.  This allows to remove corresponding workaround from STV
>pass.
>>
>> Does it look OK?
>
>Better tracking of cse_cfg_altered seems good regardless. So that's an 
>OK for everything but...
>
>> +  if (cse_cfg_altered && dom_info_available_p (CDI_DOMINATORS))
>> +    free_dominance_info (CDI_DOMINATORS);
>
>I wonder whether it should be the last user of dominance info that 
>should be freeing it (maybe it's not just cse that can destroy it?)
>
>Which pass is leaving it around?

Dominators are never freed.

Richard.

>
>Bernd
Bernd Schmidt May 10, 2016, 5:17 p.m. UTC | #3
On 05/10/2016 07:06 PM, Richard Biener wrote:
>
> Dominators are never freed.

Not sure what you're trying to say here. There's lots of calls to 
free_dominance_info in the tree and obviously we need to do something to 
prevent the bug Ilya is trying to fix.


Bernd
Richard Biener May 10, 2016, 5:36 p.m. UTC | #4
On May 10, 2016 7:17:59 PM GMT+02:00, Bernd Schmidt <bschmidt@redhat.com> wrote:
>On 05/10/2016 07:06 PM, Richard Biener wrote:
>>
>> Dominators are never freed.
>
>Not sure what you're trying to say here. There's lots of calls to 
>free_dominance_info in the tree and obviously we need to do something
>to 
>prevent the bug Ilya is trying to fix.

The policy for passes is to only free dominator info if they wreck it.  They have to expect it being present but can also choose to free it early of course.

Richard.

>
>Bernd
Bernd Schmidt May 10, 2016, 5:57 p.m. UTC | #5
On 05/10/2016 07:36 PM, Richard Biener wrote:
>
> The policy for passes is to only free dominator info if they wreck
> it.  They have to expect it being present but can also choose to free
> it early of course.

Seems like a policy that's inviting surprises such as this one, but if 
this is the case, the entire patch is OK.


Bernd
H.J. Lu May 10, 2016, 6:13 p.m. UTC | #6
On Tue, May 10, 2016 at 9:19 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> Hi,
>
> Curretly CSE may modify CFG and leave invalid dominance info.  This patch
> improves track of CFG changes by CSE passes and frees dominance info if
> required.  This allows to remove corresponding workaround from STV pass.
>
> Does it look OK?
>
> Bootstrapped and regtested on x86-64-unknown-linux-gnu.
>

> diff --git a/gcc/testsuite/gcc.dg/pr70807.c b/gcc/testsuite/gcc.dg/pr70807.c
> new file mode 100644
> index 0000000..9ef2a4d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr70807.c
> @@ -0,0 +1,18 @@
> +/* PR middle-end/70807 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +typedef int INT;
> +int a, b, c, d, e, f;
> +void fn1() {
> +  INT g;
> +  if (d && a)
> +    ;
> +  else if (e && b)
> +    ;
> +  else if (!a && !b && c)
> +    ;
> +  else if (b && d || a && e)
> +    a = 0;
> +  f = g || d;
> +}

Does this test fail without the fix?
Ilya Enkovich May 11, 2016, 9:26 a.m. UTC | #7
2016-05-10 21:13 GMT+03:00 H.J. Lu <hjl.tools@gmail.com>:
> On Tue, May 10, 2016 at 9:19 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>> Hi,
>>
>> Curretly CSE may modify CFG and leave invalid dominance info.  This patch
>> improves track of CFG changes by CSE passes and frees dominance info if
>> required.  This allows to remove corresponding workaround from STV pass.
>>
>> Does it look OK?
>>
>> Bootstrapped and regtested on x86-64-unknown-linux-gnu.
>>
>
>> diff --git a/gcc/testsuite/gcc.dg/pr70807.c b/gcc/testsuite/gcc.dg/pr70807.c
>> new file mode 100644
>> index 0000000..9ef2a4d
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pr70807.c
>> @@ -0,0 +1,18 @@
>> +/* PR middle-end/70807 */
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2" } */
>> +
>> +typedef int INT;
>> +int a, b, c, d, e, f;
>> +void fn1() {
>> +  INT g;
>> +  if (d && a)
>> +    ;
>> +  else if (e && b)
>> +    ;
>> +  else if (!a && !b && c)
>> +    ;
>> +  else if (b && d || a && e)
>> +    a = 0;
>> +  f = g || d;
>> +}
>
> Does this test fail without the fix?

Yes, I creduced it from a libgcc build fail caused by the trigger
patch from the tracker.

Thanks,
Ilya

>
> --
> H.J.
H.J. Lu May 11, 2016, 12:45 p.m. UTC | #8
On Wed, May 11, 2016 at 2:26 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> 2016-05-10 21:13 GMT+03:00 H.J. Lu <hjl.tools@gmail.com>:
>> On Tue, May 10, 2016 at 9:19 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>>> Hi,
>>>
>>> Curretly CSE may modify CFG and leave invalid dominance info.  This patch
>>> improves track of CFG changes by CSE passes and frees dominance info if
>>> required.  This allows to remove corresponding workaround from STV pass.
>>>
>>> Does it look OK?
>>>
>>> Bootstrapped and regtested on x86-64-unknown-linux-gnu.
>>>
>>
>>> diff --git a/gcc/testsuite/gcc.dg/pr70807.c b/gcc/testsuite/gcc.dg/pr70807.c
>>> new file mode 100644
>>> index 0000000..9ef2a4d
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.dg/pr70807.c
>>> @@ -0,0 +1,18 @@
>>> +/* PR middle-end/70807 */
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-O2" } */
>>> +
>>> +typedef int INT;
>>> +int a, b, c, d, e, f;
>>> +void fn1() {
>>> +  INT g;
>>> +  if (d && a)
>>> +    ;
>>> +  else if (e && b)
>>> +    ;
>>> +  else if (!a && !b && c)
>>> +    ;
>>> +  else if (b && d || a && e)
>>> +    a = 0;
>>> +  f = g || d;
>>> +}
>>
>> Does this test fail without the fix?
>
> Yes, I creduced it from a libgcc build fail caused by the trigger
> patch from the tracker.
>

This test only uses int, which is 32-bit.  How does it trigger
STV?
Ilya Enkovich May 11, 2016, 12:53 p.m. UTC | #9
2016-05-11 15:45 GMT+03:00 H.J. Lu <hjl.tools@gmail.com>:
> On Wed, May 11, 2016 at 2:26 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>> 2016-05-10 21:13 GMT+03:00 H.J. Lu <hjl.tools@gmail.com>:
>>> On Tue, May 10, 2016 at 9:19 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>>>> Hi,
>>>>
>>>> Curretly CSE may modify CFG and leave invalid dominance info.  This patch
>>>> improves track of CFG changes by CSE passes and frees dominance info if
>>>> required.  This allows to remove corresponding workaround from STV pass.
>>>>
>>>> Does it look OK?
>>>>
>>>> Bootstrapped and regtested on x86-64-unknown-linux-gnu.
>>>>
>>>
>>>> diff --git a/gcc/testsuite/gcc.dg/pr70807.c b/gcc/testsuite/gcc.dg/pr70807.c
>>>> new file mode 100644
>>>> index 0000000..9ef2a4d
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.dg/pr70807.c
>>>> @@ -0,0 +1,18 @@
>>>> +/* PR middle-end/70807 */
>>>> +/* { dg-do compile } */
>>>> +/* { dg-options "-O2" } */
>>>> +
>>>> +typedef int INT;
>>>> +int a, b, c, d, e, f;
>>>> +void fn1() {
>>>> +  INT g;
>>>> +  if (d && a)
>>>> +    ;
>>>> +  else if (e && b)
>>>> +    ;
>>>> +  else if (!a && !b && c)
>>>> +    ;
>>>> +  else if (b && d || a && e)
>>>> +    a = 0;
>>>> +  f = g || d;
>>>> +}
>>>
>>> Does this test fail without the fix?
>>
>> Yes, I creduced it from a libgcc build fail caused by the trigger
>> patch from the tracker.
>>
>
> This test only uses int, which is 32-bit.  How does it trigger
> STV?

I don't fix any bug in STV.  This test should trigger CSE.

Thanks,
Ilya

>
> --
> H.J.
diff mbox

Patch

diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 62b0596..3d8ed60 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -215,9 +215,10 @@  delete_insn (rtx uncast_insn)
     }
 }
 
-/* Like delete_insn but also purge dead edges from BB.  */
+/* Like delete_insn but also purge dead edges from BB.
+   Return true if any edges are eliminated.  */
 
-void
+bool
 delete_insn_and_edges (rtx_insn *insn)
 {
   bool purge = false;
@@ -228,7 +229,8 @@  delete_insn_and_edges (rtx_insn *insn)
     purge = true;
   delete_insn (insn);
   if (purge)
-    purge_dead_edges (BLOCK_FOR_INSN (insn));
+    return purge_dead_edges (BLOCK_FOR_INSN (insn));
+  return false;
 }
 
 /* Unlink a chain of insns between START and FINISH, leaving notes
diff --git a/gcc/cfgrtl.h b/gcc/cfgrtl.h
index 0d88024..d81928a 100644
--- a/gcc/cfgrtl.h
+++ b/gcc/cfgrtl.h
@@ -21,7 +21,7 @@  along with GCC; see the file COPYING3.  If not see
 #define GCC_CFGRTL_H
 
 extern void delete_insn (rtx);
-extern void delete_insn_and_edges (rtx_insn *);
+extern bool delete_insn_and_edges (rtx_insn *);
 extern void delete_insn_chain (rtx, rtx, bool);
 extern basic_block create_basic_block_structure (rtx_insn *, rtx_insn *,
 						 rtx_note *, basic_block);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 05476f3..7c023b7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3911,13 +3911,6 @@  convert_scalars_to_vector ()
   bitmap_obstack_release (NULL);
   df_process_deferred_rescans ();
 
-  /* FIXME: Since the CSE pass may change dominance info, which isn't
-     expected by the fwprop pass, call free_dominance_info to
-     invalidate dominance info.  Otherwise, the fwprop pass may crash
-     when dominance info is changed.  */
-  if (TARGET_64BIT)
-    free_dominance_info (CDI_DOMINATORS);
-
   /* Conversion means we may have 128bit register spills/fills
      which require aligned stack.  */
   if (converted_insns)
diff --git a/gcc/cse.c b/gcc/cse.c
index 7456e84..04e1a85 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -5505,7 +5505,7 @@  cse_insn (rtx_insn *insn)
       else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx)
 	{
 	  /* One less use of the label this insn used to jump to.  */
-	  delete_insn_and_edges (insn);
+	  cse_cfg_altered |= delete_insn_and_edges (insn);
 	  cse_jumps_altered = true;
 	  /* No more processing for this set.  */
 	  sets[i].rtl = 0;
@@ -5516,7 +5516,7 @@  cse_insn (rtx_insn *insn)
 	{
 	  if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))
 	    cse_cfg_altered = true;
-	  delete_insn_and_edges (insn);
+	  cse_cfg_altered |= delete_insn_and_edges (insn);
 	  /* No more processing for this set.  */
 	  sets[i].rtl = 0;
 	}
@@ -5551,7 +5551,7 @@  cse_insn (rtx_insn *insn)
 		  REG_NOTES (new_rtx) = note;
 		}
 
-	      delete_insn_and_edges (insn);
+	      cse_cfg_altered |= delete_insn_and_edges (insn);
 	      insn = new_rtx;
 	    }
 	  else
@@ -7131,7 +7131,7 @@  delete_trivially_dead_insns (rtx_insn *insns, int nreg)
 	      count_reg_usage (insn, counts, NULL_RTX, -1);
 	      ndead++;
 	    }
-	  delete_insn_and_edges (insn);
+	  cse_cfg_altered |= delete_insn_and_edges (insn);
 	}
     }
 
@@ -7427,7 +7427,7 @@  cse_cc_succs (basic_block bb, basic_block orig_bb, rtx cc_reg, rtx cc_src,
 				    newreg);
 	}
 
-      delete_insn_and_edges (insns[i]);
+      cse_cfg_altered |= delete_insn_and_edges (insns[i]);
     }
 
   return mode;
@@ -7568,6 +7568,9 @@  rest_of_handle_cse (void)
   else if (tem == 1 || optimize > 1)
     cleanup_cfg (0);
 
+  if (cse_cfg_altered && dom_info_available_p (CDI_DOMINATORS))
+    free_dominance_info (CDI_DOMINATORS);
+
   return 0;
 }
 
@@ -7637,6 +7640,9 @@  rest_of_handle_cse2 (void)
   else if (tem == 1)
     cleanup_cfg (0);
 
+  if (cse_cfg_altered && dom_info_available_p (CDI_DOMINATORS))
+    free_dominance_info (CDI_DOMINATORS);
+
   cse_not_expected = 1;
   return 0;
 }
@@ -7695,7 +7701,7 @@  rest_of_handle_cse_after_global_opts (void)
 
   rebuild_jump_labels (get_insns ());
   tem = cse_main (get_insns (), max_reg_num ());
-  purge_all_dead_edges ();
+  cse_cfg_altered |= purge_all_dead_edges ();
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
 
   cse_not_expected = !flag_rerun_cse_after_loop;
@@ -7711,6 +7717,9 @@  rest_of_handle_cse_after_global_opts (void)
   else if (tem == 1)
     cleanup_cfg (0);
 
+  if (cse_cfg_altered && dom_info_available_p (CDI_DOMINATORS))
+    free_dominance_info (CDI_DOMINATORS);
+
   flag_cse_follow_jumps = save_cfj;
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/pr70807.c b/gcc/testsuite/gcc.dg/pr70807.c
new file mode 100644
index 0000000..9ef2a4d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr70807.c
@@ -0,0 +1,18 @@ 
+/* PR middle-end/70807 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int INT;
+int a, b, c, d, e, f;
+void fn1() {
+  INT g;
+  if (d && a)
+    ;
+  else if (e && b)
+    ;
+  else if (!a && !b && c)
+    ;
+  else if (b && d || a && e)
+    a = 0;
+  f = g || d;
+}