patches/gcc/4.7.0/100-PR52734-tree-ssa-tail-merge.patch
changeset 2943 ededa826097f
     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 Mar 23 01:36:42 2012 -0700
     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);