===================================================================
@@ -308,14 +308,24 @@ tree_forwarder_block_p (basic_block bb, bool phi_w
if (current_loops)
{
basic_block dest;
- /* Protect loop latches, headers and preheaders. */
+ /* Protect loop headers. */
if (bb->loop_father->header == bb)
return false;
+
dest = EDGE_SUCC (bb, 0)->dest;
+ /* Protect loop preheaders and latches if requested. */
+ if (dest->loop_father->header == dest)
+ {
+ if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS)
+ && bb->loop_father->header != dest)
+ return false;
- if (dest->loop_father->header == dest)
- return false;
+ if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)
+ && bb->loop_father->header == dest)
+ return false;
+ }
}
+
return true;
}
@@ -497,6 +507,11 @@ remove_forwarder_block (basic_block bb)
set_immediate_dominator (CDI_DOMINATORS, dest, dom);
}
+ /* Adjust latch infomation of BB's parent loop as otherwise
+ the cfg hook has a hard time not to kill the loop. */
+ if (current_loops && bb->loop_father->latch == bb)
+ bb->loop_father->latch = dest;
+
/* And kill the forwarder block. */
delete_basic_block (bb);
===================================================================
@@ -849,9 +849,15 @@ tree_ssa_dominator_optimize (void)
/* We need to know loop structures in order to avoid destroying them
in jump threading. Note that we still can e.g. thread through loop
headers to an exit edge, or through loop header to the loop body, assuming
- that we update the loop info. */
- loop_optimizer_init (LOOPS_HAVE_SIMPLE_LATCHES);
+ that we update the loop info.
+ TODO: We don't need to set LOOPS_HAVE_PREHEADERS generally, but due
+ to several overly conservative bail-outs in jump threading, case
+ gcc.dg/tree-ssa/pr21417.c can't be threaded if loop preheader is
+ missing. We should improve jump threading in future then
+ LOOPS_HAVE_PREHEADERS won't be needed here. */
+ loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES);
+
/* Initialize the value-handle array. */
threadedge_initialize_values ();
===================================================================
@@ -26,5 +26,5 @@ package body Renaming5 is
end Renaming5;
+-- { dg-final { scan-tree-dump-times "goto" 2 "optimized" } }
-- { dg-final { cleanup-tree-dump "optimized" } }
===================================================================
@@ -13,5 +13,5 @@ void foo (int i_width, TYPE dst, TYPE src1, TYPE s
}
}
-/* { dg-final { scan-tree-dump-times "PHI <ivtmp" 1 "ivopts"} } */
+/* { dg-final { scan-tree-dump-times "ivtmp.\[0-9_\]* = PHI <" 1 "ivopts"} } */
/* { dg-final { cleanup-tree-dump "ivopts" } } */
===================================================================
@@ -36,8 +36,9 @@ void foo (void)
/* Second, we should thread the edge out of the loop via the break
statement. We also realize that the final bytes == 0 test is useless,
- and thread over it. */
-/* { dg-final { scan-tree-dump-times "Threaded jump" 2 "vrp1" } } */
+ and thread over it. We also know that toread != 0 is useless when
+ entering while loop and thread over it. */
+/* { dg-final { scan-tree-dump-times "Threaded jump" 3 "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
===================================================================
@@ -15,5 +15,5 @@ void foo (int i_width, TYPE dst, TYPE src1, TYPE s
}
}
-/* { dg-final { scan-tree-dump-times "PHI <ivtmp" 1 "ivopts"} } */
+/* { dg-final { scan-tree-dump-times "ivtmp.\[0-9_\]* = PHI <" 1 "ivopts"} } */
/* { dg-final { cleanup-tree-dump "ivopts" } } */
===================================================================
@@ -14,5 +14,5 @@ void foo (int i_width, TYPE dst, TYPE src1, TYPE s
}
-/* { dg-final { scan-tree-dump-times "PHI <ivtmp" 1 "ivopts"} } */
+/* { dg-final { scan-tree-dump-times "ivtmp.\[0-9_\]* = PHI <" 1 "ivopts"} } */
/* { dg-final { cleanup-tree-dump "ivopts" } } */
===================================================================
@@ -14,7 +14,7 @@ void foo (int i_width, char* dst, char* src1, char
src1+=sizeof(TYPE);
src2+=sizeof(TYPE);
}
-}
+}
-/* { dg-final { scan-tree-dump-times "PHI <ivtmp" 1 "ivopts"} } */
+/* { dg-final { scan-tree-dump-times "ivtmp.\[0-9_\]* = PHI <" 1 "ivopts"} } */
/* { dg-final { cleanup-tree-dump "ivopts" } } */
===================================================================
@@ -16,6 +16,7 @@ main ()
edge. */
/* { dg-final-use { scan-ipa-dump "loop depth 1, count 33334" "profile"} } */
/* { dg-final-use { scan-tree-dump "loop depth 1, count 33332" "optimized"} } */
-/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { scan-tree-dump-times "Removing basic block \[^\r\n\]*\[\\r\\n\]+\[^\r\n\]*\[\\r\\n\]+Invalid sum of\[^\r\n\]*\[\\r\\n\]+Invalid sum of" 1 "optimized"} } */
+/* { dg-final-use { scan-tree-dump-times "Invalid sum of" 2 "optimized"} } */
/* { dg-final-use { cleanup-ipa-dump "profile" } } */
/* { dg-final-use { cleanup-tree-dump "optimized" } } */