@@ -1,3 +1,14 @@
+2016-06-10 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/71335
+ * tree-ssa-threadbackward.c (profitable_jump_thread_path): Filter out
+ zero length paths here.
+ (convert_and_register_jump_thread_path): Remove hacks related to
+ duplicated blocks in the jump thread path.
+ (fsm_find_control_statement_thread_paths): Avoid putting the same
+ block on the thread path twice, but ensure the thread path is
+ unchanged from the caller's point of view.
+
2016-06-10 Jan Hubicka <hubicka@ucw.cz>
* predict.c (predict_loops): Remove PRED_LOOP_BRANCH.
@@ -1,3 +1,8 @@
+2016-06-10 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/71335
+ * gcc.c-torture/execute/pr71335.c: New test.
+
2016-06-10 David Malcolm <dmalcolm@redhat.com>
* gcc.dg/plugin/must-tail-call-2.c: Remove all details from
new file mode 100644
@@ -0,0 +1,13 @@
+int a;
+int
+main ()
+{
+ int b = 0;
+ while (a < 0 || b)
+ {
+ b = 0;
+ for (; b < 9; b++)
+ ;
+ }
+ exit (0);
+}
@@ -109,6 +109,19 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
/* Note BBI is not in the path yet, hence the +1 in the test below
to make sure BBI is accounted for in the path length test. */
int path_length = path->length ();
+
+ /* We can get a length of 0 here when the statement that
+ makes a conditional generate a compile-time constant
+ result is in the same block as the conditional.
+
+ That's not really a jump threading opportunity, but instead is
+ simple cprop & simplification. We could handle it here if we
+ wanted by wiring up all the incoming edges. If we run this
+ early in IPA, that might be worth doing. For now we just
+ reject that case. */
+ if (path_length == 0)
+ return NULL;
+
if (path_length + 1 > PARAM_VALUE (PARAM_MAX_FSM_THREAD_LENGTH))
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -376,34 +389,12 @@ convert_and_register_jump_thread_path (vec<basic_block, va_gc> *&path,
basic_block bb1 = (*path)[path->length () - j - 1];
basic_block bb2 = (*path)[path->length () - j - 2];
- /* This can happen when we have an SSA_NAME as a PHI argument and
- its initialization block is the head of the PHI argument's
- edge. */
- if (bb1 == bb2)
- continue;
-
edge e = find_edge (bb1, bb2);
gcc_assert (e);
jump_thread_edge *x = new jump_thread_edge (e, EDGE_FSM_THREAD);
jump_thread_path->safe_push (x);
}
- /* As a consequence of the test for duplicate blocks in the path
- above, we can get a path with no blocks. This happens if a
- conditional can be fully evaluated at compile time using just
- defining statements in the same block as the test.
-
- When we no longer push the block associated with a PHI argument
- onto the stack, then this as well as the test in the loop above
- can be removed. */
- if (jump_thread_path->length () == 0)
- {
- jump_thread_path->release ();
- delete jump_thread_path;
- path->pop ();
- return;
- }
-
/* Add the edge taken when the control variable has value ARG. */
jump_thread_edge *x
= new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
@@ -579,10 +570,19 @@ fsm_find_control_statement_thread_paths (tree name,
else
{
+ /* profitable_jump_thread_path is going to push the current
+ block onto the path. But the path will always have the current
+ block at this point. So we can just pop it. */
+ path->pop ();
+
edge taken_edge = profitable_jump_thread_path (path, var_bb,
name, arg);
if (taken_edge)
convert_and_register_jump_thread_path (path, taken_edge);
+
+ /* And put the current block back onto the path so that the
+ state of the stack is unchanged when we leave. */
+ vec_safe_push (path, var_bb);
}
}