]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/21562 (Quiet bad codegen (unrolling + tail call interaction))
authorJan Hubicka <jh@suse.cz>
Sat, 28 May 2005 22:27:04 +0000 (00:27 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 28 May 2005 22:27:04 +0000 (22:27 +0000)
PR tree-optimization/21562
* cfgexpand.c (construct_init_block): Deal properly with the case
of entry edge not pointing to very first basic block.

From-SVN: r100305

gcc/ChangeLog
gcc/cfgexpand.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr21562.c [new file with mode: 0644]

index e0a1575a2ddd4facd576c12656188a5996c1b253..f25e76e862ca6687c087c9639e31d2a7b6f012a8 100644 (file)
@@ -1,3 +1,9 @@
+2005-05-29  Jan Hubicka  <jh@suse.cz>
+
+       PR tree-optimization/21562
+       * cfgexpand.c (construct_init_block): Deal properly with the case
+       of entry edge not pointing to very first basic block.
+
 2005-05-28  Kazu Hirata  <kazu@cs.umass.edu>
 
        * tree-ssa-ccp.c (ccp_fold): Remove code that produces
index cd9829e60deb95f13460ef43fd2a170ae75a707f..4e4a8e208c3e36a5725cc86b337abb8ace6045ee 100644 (file)
@@ -1157,22 +1157,25 @@ static basic_block
 construct_init_block (void)
 {
   basic_block init_block, first_block;
-  edge e = NULL, e2;
-  edge_iterator ei;
+  edge e = NULL;
+  int flags;
 
-  FOR_EACH_EDGE (e2, ei, ENTRY_BLOCK_PTR->succs)
-    {
-      /* Clear EDGE_EXECUTABLE.  This flag is never used in the backend.
+  /* Multiple entry points not supported yet.  */
+  gcc_assert (EDGE_COUNT (ENTRY_BLOCK_PTR->succs) == 1);
 
-        For all other blocks this edge flag is cleared while expanding
-        a basic block in expand_gimple_basic_block, but there we never
-        looked at the successors of the entry block.
-        This caused PR17513.  */
-      e2->flags &= ~EDGE_EXECUTABLE;
+  e = EDGE_SUCC (ENTRY_BLOCK_PTR, 0);
 
-      if (e2->dest == ENTRY_BLOCK_PTR->next_bb)
-       e = e2;
+  /* When entry edge points to first basic block, we don't need jump,
+     otherwise we have to jump into proper target.  */
+  if (e && e->dest != ENTRY_BLOCK_PTR->next_bb)
+    {
+      tree label = tree_block_label (e->dest);
+
+      emit_jump (label_rtx (label));
+      flags = 0;
     }
+  else
+    flags = EDGE_FALLTHRU;
 
   init_block = create_basic_block (NEXT_INSN (get_insns ()),
                                   get_last_insn (),
@@ -1183,7 +1186,7 @@ construct_init_block (void)
     {
       first_block = e->dest;
       redirect_edge_succ (e, init_block);
-      e = make_edge (init_block, first_block, EDGE_FALLTHRU);
+      e = make_edge (init_block, first_block, flags);
     }
   else
     e = make_edge (init_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
index f1eafd2500e26adccfb50fcf5ed3c2b8bb06a95a..f9a5e6a19898915c3618c631aa5d2071b518a602 100644 (file)
@@ -1,3 +1,7 @@
+2005-05-29  Jan Hubicka  <jh@suse.cz>
+
+       * gcc.c-torture/compile/pr21562.c: New.
+
 2005-05-28  Steven G. Kargl <kargls@comcast.net>
 
        * gfortran.dg/subnormal_1.f90: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr21562.c b/gcc/testsuite/gcc.c-torture/compile/pr21562.c
new file mode 100644 (file)
index 0000000..d100b28
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-options "-O3 -fno-inline" } */
+struct foo { int a, b, c; };
+void abort(void);
+void exit(int);
+
+void
+brother (int a, int b, int c)
+{
+  if (a)
+    abort ();
+}
+
+void
+sister (struct foo f, int b, int c)
+{
+  brother ((f.b == b), b, c);
+}
+
+int
+main ()
+{
+  struct foo f = { 7, 8, 9 };
+  sister (f, 1, 2);
+  exit (0);
+}