1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/patches/gcc/4.7.0/100-PR52734-tree-ssa-tail-merge.patch Fri May 25 19:09:43 2012 +0200
1.3 @@ -0,0 +1,91 @@
1.4 +------------------------------------------------------------------------
1.5 +r186424 | vries | 2012-04-13 18:44:18 +0200 (Fri, 13 Apr 2012) | 12 lines
1.6 +
1.7 +2012-04-13 Tom de Vries <tom@codesourcery.com>
1.8 +
1.9 + Backport from mainline r186418.
1.10 +
1.11 + 2012-04-13 Tom de Vries <tom@codesourcery.com>
1.12 +
1.13 + * tree-ssa-tail-merge.c (gsi_advance_bw_nondebug_nonlocal): Add
1.14 + parameters vuse and vuse_escaped.
1.15 + (find_duplicate): Init vuse1, vuse2 and vuse_escaped. Pass to
1.16 + gsi_advance_bw_nondebug_nonlocal. Return if vuse_escaped and
1.17 + vuse1 != vuse2.
1.18 +
1.19 +------------------------------------------------------------------------
1.20 +Index: gcc/tree-ssa-tail-merge.c
1.21 +===================================================================
1.22 +--- gcc-4.7.0/gcc/tree-ssa-tail-merge.c (revision 186423)
1.23 ++++ gcc-4.7.0/gcc/tree-ssa-tail-merge.c (revision 186424)
1.24 +@@ -1123,18 +1123,31 @@
1.25 + }
1.26 + }
1.27 +
1.28 +-/* Let GSI skip backwards over local defs. */
1.29 ++/* Let GSI skip backwards over local defs. Return the earliest vuse in VUSE.
1.30 ++ Return true in VUSE_ESCAPED if the vuse influenced a SSA_OP_DEF of one of the
1.31 ++ processed statements. */
1.32 +
1.33 + static void
1.34 +-gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi)
1.35 ++gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi, tree *vuse,
1.36 ++ bool *vuse_escaped)
1.37 + {
1.38 + gimple stmt;
1.39 ++ tree lvuse;
1.40 +
1.41 + while (true)
1.42 + {
1.43 + if (gsi_end_p (*gsi))
1.44 + return;
1.45 + stmt = gsi_stmt (*gsi);
1.46 ++
1.47 ++ lvuse = gimple_vuse (stmt);
1.48 ++ if (lvuse != NULL_TREE)
1.49 ++ {
1.50 ++ *vuse = lvuse;
1.51 ++ if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_DEF))
1.52 ++ *vuse_escaped = true;
1.53 ++ }
1.54 ++
1.55 + if (!(is_gimple_assign (stmt) && local_def (gimple_get_lhs (stmt))
1.56 + && !gimple_has_side_effects (stmt)))
1.57 + return;
1.58 +@@ -1150,9 +1163,11 @@
1.59 + {
1.60 + gimple_stmt_iterator gsi1 = gsi_last_nondebug_bb (bb1);
1.61 + gimple_stmt_iterator gsi2 = gsi_last_nondebug_bb (bb2);
1.62 ++ tree vuse1 = NULL_TREE, vuse2 = NULL_TREE;
1.63 ++ bool vuse_escaped = false;
1.64 +
1.65 +- gsi_advance_bw_nondebug_nonlocal (&gsi1);
1.66 +- gsi_advance_bw_nondebug_nonlocal (&gsi2);
1.67 ++ gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1, &vuse_escaped);
1.68 ++ gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
1.69 +
1.70 + while (!gsi_end_p (gsi1) && !gsi_end_p (gsi2))
1.71 + {
1.72 +@@ -1161,13 +1176,20 @@
1.73 +
1.74 + gsi_prev_nondebug (&gsi1);
1.75 + gsi_prev_nondebug (&gsi2);
1.76 +- gsi_advance_bw_nondebug_nonlocal (&gsi1);
1.77 +- gsi_advance_bw_nondebug_nonlocal (&gsi2);
1.78 ++ gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1, &vuse_escaped);
1.79 ++ gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
1.80 + }
1.81 +
1.82 + if (!(gsi_end_p (gsi1) && gsi_end_p (gsi2)))
1.83 + return;
1.84 +
1.85 ++ /* If the incoming vuses are not the same, and the vuse escaped into an
1.86 ++ SSA_OP_DEF, then merging the 2 blocks will change the value of the def,
1.87 ++ which potentially means the semantics of one of the blocks will be changed.
1.88 ++ TODO: make this check more precise. */
1.89 ++ if (vuse_escaped && vuse1 != vuse2)
1.90 ++ return;
1.91 ++
1.92 + if (dump_file)
1.93 + fprintf (dump_file, "find_duplicates: <bb %d> duplicate of <bb %d>\n",
1.94 + bb1->index, bb2->index);