This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix removal of trivially empty bb's even in CFGRTL mode (PR middle-end/44102)


Hi!

On Thu, May 13, 2010 at 12:44:44PM +0200, Jakub Jelinek wrote:
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.5?

Honza mentioned on IRC that there might be multiple EDGE_FALLTHRU
predecessors, so this patch attempts to handle all of them, not just the
first one.

2010-05-13  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/44102
	* cfgcleanup.c (try_optimize_cfg): When removing trivially empty
	bb with no successors, move footer whenever in IR_RTL_CFGLAYOUT
	mode, not just when CLEANUP_CFGLAYOUT, and when in IR_RTL_CFGRTL
	add BARRIER after previous bb if needed.

	* g++.dg/ext/asmgoto1.C: New test.

--- gcc/cfgcleanup.c.jj	2010-05-13 12:39:54.000000000 +0200
+++ gcc/cfgcleanup.c	2010-05-13 15:57:40.000000000 +0200
@@ -1999,24 +1999,40 @@ try_optimize_cfg (int mode)
 		      && single_succ_edge (ENTRY_BLOCK_PTR)->dest != b))
 		{
 		  c = b->prev_bb;
-		  if ((mode & CLEANUP_CFGLAYOUT)
-		      && EDGE_COUNT (b->preds) > 0
-		      && b->il.rtl->footer
-		      && BARRIER_P (b->il.rtl->footer))
+		  if (EDGE_COUNT (b->preds) > 0)
 		    {
 		      edge e;
 		      edge_iterator ei;
 
-		      FOR_EACH_EDGE (e, ei, b->preds)
-			if (e->flags & EDGE_FALLTHRU)
-			  {
-			    if (e->src->il.rtl->footer == NULL)
-			      {
-				e->src->il.rtl->footer = b->il.rtl->footer;
-				b->il.rtl->footer = NULL;
-			      }
-			    break;
-			  }
+		      if (current_ir_type () == IR_RTL_CFGLAYOUT)
+			{
+			  if (b->il.rtl->footer
+			      && BARRIER_P (b->il.rtl->footer))
+			    FOR_EACH_EDGE (e, ei, b->preds)
+			      if ((e->flags & EDGE_FALLTHRU)
+				  && e->src->il.rtl->footer == NULL)
+				{
+				  if (b->il.rtl->footer)
+				    {
+				      e->src->il.rtl->footer = b->il.rtl->footer;
+				      b->il.rtl->footer = NULL;
+				    }
+				  else
+				    {
+				      start_sequence ();
+				      e->src->il.rtl->footer = emit_barrier ();
+				      end_sequence ();
+				    }
+				}
+			}
+		      else
+			{
+			  rtx last = get_last_bb_insn (b);
+			  if (last && BARRIER_P (last))
+			    FOR_EACH_EDGE (e, ei, b->preds)
+			      if ((e->flags & EDGE_FALLTHRU))
+				emit_barrier_after (BB_END (e->src));
+			}
 		    }
 		  delete_basic_block (b);
 		  if (!(mode & CLEANUP_CFGLAYOUT))
--- gcc/testsuite/g++.dg/ext/asmgoto1.C.jj	2010-05-13 15:36:49.000000000 +0200
+++ gcc/testsuite/g++.dg/ext/asmgoto1.C	2010-05-13 15:36:49.000000000 +0200
@@ -0,0 +1,32 @@
+// PR middle-end/44102
+// { dg-do compile }
+// { dg-options "-O2" }
+
+void baz (void);
+struct A { A (); ~A (); };
+
+static inline int
+foo (void)
+{
+  asm goto ("" : : : : l1, l2);
+  __builtin_unreachable ();
+ l1:
+  return 1;
+ l2:
+  return 0;
+}
+
+int
+bar (int x)
+{
+  if (x == 5)
+    {
+      A a, b;
+      baz ();
+    }
+  if (foo () || x == 6)
+    x = 1;
+  else
+    x = 2;
+  return x;
+}


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]