public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][PR rtl-optimization/81308] Conditionally cleanup the CFG after insn splitting
@ 2018-01-08  4:45 Jeff Law
  2018-01-08 11:42 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Jeff Law @ 2018-01-08  4:45 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1313 bytes --]


This patch fixes the original problem reported in 81308.  Namely that
g++.dg/pr62079.C will trigger a checking failure on 32bit x86.

As Jakub noted in the BZ the problem is we had an insn with an EH region
note.  That insn gets split and the split insns do not have an EH region
note (nor do they need one AFAICT).

With the EH region note gone, the actual EH region becomes unreachable
and we get a verification error in the dominance code.

My solution is relatively simple.  During splitting we track if the
current insn has an EH region note.  If it does and we end splitting the
insn or deleting it as a nop-move, then we note that we're going to need
a cfg cleanup.

After splitting all insns, we conditionally cleanup the CFG.

This should keep the overhead relatively low -- primarily it's the cost
to look for the EH region note on each insn as I don't expect the cfg
cleanup is often needed.

If we could prove to ourselves that the situation only occurs with
-fnon-call-exceptions, then we could further reduce the overhead by
exploiting that invariant as well.  I haven't really thought too much
about this.

No new testcase as the existing pr62079.C will trigger on x86.

Bootstrapped and regression tested on x86_64.  Verified pr62079.C now
passes by hand in 32 bit mode.

OK for the trunk?

Jeff

[-- Attachment #2: P --]
[-- Type: text/plain, Size: 2097 bytes --]

	PR rtl-optimization/81308
	* recog.c (split_all_insns): Conditionally cleanup the CFG after
	splitting insns.

diff --git a/gcc/recog.c b/gcc/recog.c
index d6aa903..cc28b71 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -2931,6 +2931,7 @@ void
 split_all_insns (void)
 {
   bool changed;
+  bool need_cfg_cleanup = false;
   basic_block bb;
 
   auto_sbitmap blocks (last_basic_block_for_fn (cfun));
@@ -2949,6 +2950,18 @@ split_all_insns (void)
 	     CODE_LABELS and short-out basic blocks.  */
 	  next = NEXT_INSN (insn);
 	  finish = (insn == BB_END (bb));
+
+	  /* If INSN has a REG_EH_REGION note and we split INSN, the
+	     resulting split may not have/need REG_EH_REGION notes.
+
+	     If that happens and INSN was the last reference to the
+	     given EH region, then the EH region will become unreachable.
+	     We can not leave the unreachable blocks in the CFG as that
+	     will trigger a checking failure.
+
+	     So track if INSN has a REG_EH_REGION note.  If so and we
+	     split INSN, then trigger a CFG cleanup.  */
+	  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
 	  if (INSN_P (insn))
 	    {
 	      rtx set = single_set (insn);
@@ -2965,6 +2978,8 @@ split_all_insns (void)
 		     nops then anyways.  */
 		  if (reload_completed)
 		      delete_insn_and_edges (insn);
+		  if (note)
+		    need_cfg_cleanup = true;
 		}
 	      else
 		{
@@ -2972,6 +2987,8 @@ split_all_insns (void)
 		    {
 		      bitmap_set_bit (blocks, bb->index);
 		      changed = true;
+		      if (note)
+			need_cfg_cleanup = true;
 		    }
 		}
 	    }
@@ -2980,7 +2997,16 @@ split_all_insns (void)
 
   default_rtl_profile ();
   if (changed)
-    find_many_sub_basic_blocks (blocks);
+    {
+      find_many_sub_basic_blocks (blocks);
+
+      /* Splitting could drop an REG_EH_REGION if it potentially
+	 trapped in its original form, but does not in its split
+	 form.  Consider a FLOAT_TRUNCATE which splits into a memory
+	 store/load pair and -fnon-call-exceptions.  */
+      if (need_cfg_cleanup)
+	cleanup_cfg (0);
+    }
 
   checking_verify_flow_info ();
 }

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH][PR rtl-optimization/81308] Conditionally cleanup the CFG after insn splitting
  2018-01-08  4:45 [PATCH][PR rtl-optimization/81308] Conditionally cleanup the CFG after insn splitting Jeff Law
@ 2018-01-08 11:42 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2018-01-08 11:42 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

On Mon, Jan 8, 2018 at 5:22 AM, Jeff Law <law@redhat.com> wrote:
>
> This patch fixes the original problem reported in 81308.  Namely that
> g++.dg/pr62079.C will trigger a checking failure on 32bit x86.
>
> As Jakub noted in the BZ the problem is we had an insn with an EH region
> note.  That insn gets split and the split insns do not have an EH region
> note (nor do they need one AFAICT).
>
> With the EH region note gone, the actual EH region becomes unreachable
> and we get a verification error in the dominance code.
>
> My solution is relatively simple.  During splitting we track if the
> current insn has an EH region note.  If it does and we end splitting the
> insn or deleting it as a nop-move, then we note that we're going to need
> a cfg cleanup.
>
> After splitting all insns, we conditionally cleanup the CFG.
>
> This should keep the overhead relatively low -- primarily it's the cost
> to look for the EH region note on each insn as I don't expect the cfg
> cleanup is often needed.
>
> If we could prove to ourselves that the situation only occurs with
> -fnon-call-exceptions, then we could further reduce the overhead by
> exploiting that invariant as well.  I haven't really thought too much
> about this.
>
> No new testcase as the existing pr62079.C will trigger on x86.
>
> Bootstrapped and regression tested on x86_64.  Verified pr62079.C now
> passes by hand in 32 bit mode.
>
> OK for the trunk?

Ok.

Richard.

> Jeff
>
>         PR rtl-optimization/81308
>         * recog.c (split_all_insns): Conditionally cleanup the CFG after
>         splitting insns.
>
> diff --git a/gcc/recog.c b/gcc/recog.c
> index d6aa903..cc28b71 100644
> --- a/gcc/recog.c
> +++ b/gcc/recog.c
> @@ -2931,6 +2931,7 @@ void
>  split_all_insns (void)
>  {
>    bool changed;
> +  bool need_cfg_cleanup = false;
>    basic_block bb;
>
>    auto_sbitmap blocks (last_basic_block_for_fn (cfun));
> @@ -2949,6 +2950,18 @@ split_all_insns (void)
>              CODE_LABELS and short-out basic blocks.  */
>           next = NEXT_INSN (insn);
>           finish = (insn == BB_END (bb));
> +
> +         /* If INSN has a REG_EH_REGION note and we split INSN, the
> +            resulting split may not have/need REG_EH_REGION notes.
> +
> +            If that happens and INSN was the last reference to the
> +            given EH region, then the EH region will become unreachable.
> +            We can not leave the unreachable blocks in the CFG as that
> +            will trigger a checking failure.
> +
> +            So track if INSN has a REG_EH_REGION note.  If so and we
> +            split INSN, then trigger a CFG cleanup.  */
> +         rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
>           if (INSN_P (insn))
>             {
>               rtx set = single_set (insn);
> @@ -2965,6 +2978,8 @@ split_all_insns (void)
>                      nops then anyways.  */
>                   if (reload_completed)
>                       delete_insn_and_edges (insn);
> +                 if (note)
> +                   need_cfg_cleanup = true;
>                 }
>               else
>                 {
> @@ -2972,6 +2987,8 @@ split_all_insns (void)
>                     {
>                       bitmap_set_bit (blocks, bb->index);
>                       changed = true;
> +                     if (note)
> +                       need_cfg_cleanup = true;
>                     }
>                 }
>             }
> @@ -2980,7 +2997,16 @@ split_all_insns (void)
>
>    default_rtl_profile ();
>    if (changed)
> -    find_many_sub_basic_blocks (blocks);
> +    {
> +      find_many_sub_basic_blocks (blocks);
> +
> +      /* Splitting could drop an REG_EH_REGION if it potentially
> +        trapped in its original form, but does not in its split
> +        form.  Consider a FLOAT_TRUNCATE which splits into a memory
> +        store/load pair and -fnon-call-exceptions.  */
> +      if (need_cfg_cleanup)
> +       cleanup_cfg (0);
> +    }
>
>    checking_verify_flow_info ();
>  }
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-01-08 11:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-08  4:45 [PATCH][PR rtl-optimization/81308] Conditionally cleanup the CFG after insn splitting Jeff Law
2018-01-08 11:42 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).