summarylogtreecommitdiffstats
path: root/gcc-4.9-tree-ssa-threadedge.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9-tree-ssa-threadedge.patch')
-rw-r--r--gcc-4.9-tree-ssa-threadedge.patch38
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc-4.9-tree-ssa-threadedge.patch b/gcc-4.9-tree-ssa-threadedge.patch
new file mode 100644
index 00000000000..8827427e4d6
--- /dev/null
+++ b/gcc-4.9-tree-ssa-threadedge.patch
@@ -0,0 +1,38 @@
+--- trunk/gcc/tree-ssa-threadedge.c 2014/04/23 17:53:56 209715
++++ trunk/gcc/tree-ssa-threadedge.c 2014/04/23 18:04:46 209716
+@@ -387,7 +387,34 @@
+ && (gimple_code (stmt) != GIMPLE_CALL
+ || gimple_call_lhs (stmt) == NULL_TREE
+ || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME))
+- continue;
++ {
++ /* STMT might still have DEFS and we need to invalidate any known
++ equivalences for them.
++
++ Consider if STMT is a GIMPLE_ASM with one or more outputs that
++ feeds a conditional inside a loop. We might derive an equivalence
++ due to the conditional. */
++ tree op;
++ ssa_op_iter iter;
++
++ if (backedge_seen)
++ FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
++ {
++ /* This call only invalidates equivalences created by
++ PHI nodes. This is by design to keep the cost of
++ of invalidation reasonable. */
++ invalidate_equivalences (op, stack, src_map, dst_map);
++
++ /* However, conditionals can imply values for real
++ operands as well. And those won't be recorded in the
++ maps. In fact, those equivalences may be recorded totally
++ outside the threading code. We can just create a new
++ temporary NULL equivalence here. */
++ record_temporary_equivalence (op, NULL_TREE, stack);
++ }
++
++ continue;
++ }
+
+ /* The result of __builtin_object_size depends on all the arguments
+ of a phi node. Temporarily using only one edge produces invalid