bryanhundven@2943: ------------------------------------------------------------------------ bryanhundven@2943: r186424 | vries | 2012-04-13 18:44:18 +0200 (Fri, 13 Apr 2012) | 12 lines bryanhundven@2943: bryanhundven@2943: 2012-04-13 Tom de Vries bryanhundven@2943: bryanhundven@2943: Backport from mainline r186418. bryanhundven@2943: bryanhundven@2943: 2012-04-13 Tom de Vries bryanhundven@2943: bryanhundven@2943: * tree-ssa-tail-merge.c (gsi_advance_bw_nondebug_nonlocal): Add bryanhundven@2943: parameters vuse and vuse_escaped. bryanhundven@2943: (find_duplicate): Init vuse1, vuse2 and vuse_escaped. Pass to bryanhundven@2943: gsi_advance_bw_nondebug_nonlocal. Return if vuse_escaped and bryanhundven@2943: vuse1 != vuse2. bryanhundven@2943: bryanhundven@2943: ------------------------------------------------------------------------ bryanhundven@2943: Index: gcc/tree-ssa-tail-merge.c bryanhundven@2943: =================================================================== bryanhundven@2943: --- gcc-4.7.0/gcc/tree-ssa-tail-merge.c (revision 186423) bryanhundven@2943: +++ gcc-4.7.0/gcc/tree-ssa-tail-merge.c (revision 186424) bryanhundven@2943: @@ -1123,18 +1123,31 @@ bryanhundven@2943: } bryanhundven@2943: } bryanhundven@2943: bryanhundven@2943: -/* Let GSI skip backwards over local defs. */ bryanhundven@2943: +/* Let GSI skip backwards over local defs. Return the earliest vuse in VUSE. bryanhundven@2943: + Return true in VUSE_ESCAPED if the vuse influenced a SSA_OP_DEF of one of the bryanhundven@2943: + processed statements. */ bryanhundven@2943: bryanhundven@2943: static void bryanhundven@2943: -gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi) bryanhundven@2943: +gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi, tree *vuse, bryanhundven@2943: + bool *vuse_escaped) bryanhundven@2943: { bryanhundven@2943: gimple stmt; bryanhundven@2943: + tree lvuse; bryanhundven@2943: bryanhundven@2943: while (true) bryanhundven@2943: { bryanhundven@2943: if (gsi_end_p (*gsi)) bryanhundven@2943: return; bryanhundven@2943: stmt = gsi_stmt (*gsi); bryanhundven@2943: + bryanhundven@2943: + lvuse = gimple_vuse (stmt); bryanhundven@2943: + if (lvuse != NULL_TREE) bryanhundven@2943: + { bryanhundven@2943: + *vuse = lvuse; bryanhundven@2943: + if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_DEF)) bryanhundven@2943: + *vuse_escaped = true; bryanhundven@2943: + } bryanhundven@2943: + bryanhundven@2943: if (!(is_gimple_assign (stmt) && local_def (gimple_get_lhs (stmt)) bryanhundven@2943: && !gimple_has_side_effects (stmt))) bryanhundven@2943: return; bryanhundven@2943: @@ -1150,9 +1163,11 @@ bryanhundven@2943: { bryanhundven@2943: gimple_stmt_iterator gsi1 = gsi_last_nondebug_bb (bb1); bryanhundven@2943: gimple_stmt_iterator gsi2 = gsi_last_nondebug_bb (bb2); bryanhundven@2943: + tree vuse1 = NULL_TREE, vuse2 = NULL_TREE; bryanhundven@2943: + bool vuse_escaped = false; bryanhundven@2943: bryanhundven@2943: - gsi_advance_bw_nondebug_nonlocal (&gsi1); bryanhundven@2943: - gsi_advance_bw_nondebug_nonlocal (&gsi2); bryanhundven@2943: + gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1, &vuse_escaped); bryanhundven@2943: + gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped); bryanhundven@2943: bryanhundven@2943: while (!gsi_end_p (gsi1) && !gsi_end_p (gsi2)) bryanhundven@2943: { bryanhundven@2943: @@ -1161,13 +1176,20 @@ bryanhundven@2943: bryanhundven@2943: gsi_prev_nondebug (&gsi1); bryanhundven@2943: gsi_prev_nondebug (&gsi2); bryanhundven@2943: - gsi_advance_bw_nondebug_nonlocal (&gsi1); bryanhundven@2943: - gsi_advance_bw_nondebug_nonlocal (&gsi2); bryanhundven@2943: + gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1, &vuse_escaped); bryanhundven@2943: + gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped); bryanhundven@2943: } bryanhundven@2943: bryanhundven@2943: if (!(gsi_end_p (gsi1) && gsi_end_p (gsi2))) bryanhundven@2943: return; bryanhundven@2943: bryanhundven@2943: + /* If the incoming vuses are not the same, and the vuse escaped into an bryanhundven@2943: + SSA_OP_DEF, then merging the 2 blocks will change the value of the def, bryanhundven@2943: + which potentially means the semantics of one of the blocks will be changed. bryanhundven@2943: + TODO: make this check more precise. */ bryanhundven@2943: + if (vuse_escaped && vuse1 != vuse2) bryanhundven@2943: + return; bryanhundven@2943: + bryanhundven@2943: if (dump_file) bryanhundven@2943: fprintf (dump_file, "find_duplicates: duplicate of \n", bryanhundven@2943: bb1->index, bb2->index);