From: Ulrich Weigand Date: Mon, 2 May 2011 14:06:48 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-4.5.4~671 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7a3f9ef07281d1ef1b84cf4a34e8688914feb4f;p=thirdparty%2Fgcc.git backport: [multiple changes] 2011-05-02 Ulrich Weigand PR middle-end/43085 Backport from mainline: 2010-04-29 Bernd Schmidt From Dominique d'Humieres PR bootstrap/43858 * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs to compute test_set. 2010-04-26 Bernd Schmidt * df-problems.c (df_simulate_initialize_forwards): Set, don't clear, bits for artificial defs at the top of the block. * fwprop.c (single_def_use_enter_block): Don't call it. 2010-04-22 Bernd Schmidt * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs and df_simulate_find_noclobber_defs as appropriate. Keep track of an extra set merge_set_noclobber, and use it to relax the final test slightly. * df.h (df_simulate_find_noclobber_defs): Declare. * df-problems.c (df_simulate_find_defs): Don't ignore partial or conditional defs. (df_simulate_find_noclobber_defs): New function. From-SVN: r173252 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 94ccb22622a1..434c4ca1dcf5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2011-05-02 Ulrich Weigand + + PR middle-end/43085 + Backport from mainline: + + 2010-04-29 Bernd Schmidt + + From Dominique d'Humieres + PR bootstrap/43858 + * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs to compute + test_set. + + 2010-04-26 Bernd Schmidt + + * df-problems.c (df_simulate_initialize_forwards): Set, don't clear, + bits for artificial defs at the top of the block. + * fwprop.c (single_def_use_enter_block): Don't call it. + + 2010-04-22 Bernd Schmidt + + * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs and + df_simulate_find_noclobber_defs as appropriate. Keep track of an + extra set merge_set_noclobber, and use it to relax the final test + slightly. + * df.h (df_simulate_find_noclobber_defs): Declare. + * df-problems.c (df_simulate_find_defs): Don't ignore partial or + conditional defs. + (df_simulate_find_noclobber_defs): New function. + 2011-04-29 John David Anglin PR target/48288 diff --git a/gcc/df-problems.c b/gcc/df-problems.c index 0ec650bad09e..1fa80ea3abb1 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -3748,9 +3748,22 @@ df_simulate_find_defs (rtx insn, bitmap defs) for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) { df_ref def = *def_rec; - /* If the def is to only part of the reg, it does - not kill the other defs that reach here. */ - if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) + bitmap_set_bit (defs, DF_REF_REGNO (def)); + } +} + +/* Find the set of real DEFs, which are not clobbers, for INSN. */ + +void +df_simulate_find_noclobber_defs (rtx insn, bitmap defs) +{ + df_ref *def_rec; + unsigned int uid = INSN_UID (insn); + + for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + { + df_ref def = *def_rec; + if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))) bitmap_set_bit (defs, DF_REF_REGNO (def)); } } @@ -3903,13 +3916,9 @@ df_simulate_finalize_backwards (basic_block bb, bitmap live) the block, starting with the first one. ----------------------------------------------------------------------------*/ -/* Apply the artificial uses and defs at the top of BB in a forwards - direction. ??? This is wrong; defs mark the point where a pseudo - becomes live when scanning forwards (unless a def is unused). Since - there are no REG_UNUSED notes for artificial defs, passes that - require artificial defs probably should not call this function - unless (as is the case for fwprop) they are correct when liveness - bitmaps are *under*estimated. */ +/* Initialize the LIVE bitmap, which should be copied from DF_LIVE_IN or + DF_LR_IN for basic block BB, for forward scanning by marking artificial + defs live. */ void df_simulate_initialize_forwards (basic_block bb, bitmap live) @@ -3921,7 +3930,7 @@ df_simulate_initialize_forwards (basic_block bb, bitmap live) { df_ref def = *def_rec; if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - bitmap_clear_bit (live, DF_REF_REGNO (def)); + bitmap_set_bit (live, DF_REF_REGNO (def)); } } @@ -3942,7 +3951,7 @@ df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live) while here the scan is performed forwards! So, first assume that the def is live, and if this is not true REG_UNUSED notes will rectify the situation. */ - df_simulate_find_defs (insn, live); + df_simulate_find_noclobber_defs (insn, live); /* Clear all of the registers that go dead. */ for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) diff --git a/gcc/df.h b/gcc/df.h index 194cbcf26393..c73f00fe6ceb 100644 --- a/gcc/df.h +++ b/gcc/df.h @@ -978,6 +978,7 @@ extern void df_note_add_problem (void); extern void df_md_add_problem (void); extern void df_md_simulate_artificial_defs_at_top (basic_block, bitmap); extern void df_md_simulate_one_insn (basic_block, rtx, bitmap); +extern void df_simulate_find_noclobber_defs (rtx, bitmap); extern void df_simulate_find_defs (rtx, bitmap); extern void df_simulate_defs (rtx, bitmap); extern void df_simulate_uses (rtx, bitmap); diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 7ac64aa5e001..6e65093859db 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -228,7 +228,10 @@ single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP); process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP); - df_simulate_initialize_forwards (bb, local_lr); + + /* We don't call df_simulate_initialize_forwards, as it may overestimate + the live registers if there are unused artificial defs. We prefer + liveness to be underestimated. */ FOR_BB_INSNS (bb, insn) if (INSN_P (insn)) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index c1e86bf6b0ac..061e7dfc5eb6 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -3818,7 +3818,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, basic_block other_bb, basic_block new_dest, int reversep) { rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX; - bitmap merge_set = NULL; + bitmap merge_set = NULL, merge_set_noclobber = NULL; /* Number of pending changes. */ int n_validated_changes = 0; @@ -3951,11 +3951,14 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, /* Collect: MERGE_SET = set of registers set in MERGE_BB + MERGE_SET_NOCLOBBER = like MERGE_SET, but only includes registers + that are really set, not just clobbered. TEST_LIVE = set of registers live at EARLIEST - TEST_SET = set of registers set between EARLIEST and the - end of the block. */ + TEST_SET = set of registers set between EARLIEST and the + end of the block. */ merge_set = BITMAP_ALLOC (®_obstack); + merge_set_noclobber = BITMAP_ALLOC (®_obstack); /* If we allocated new pseudos (e.g. in the conditional move expander called from noce_emit_cmove), we must resize the @@ -3967,13 +3970,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, { if (NONDEBUG_INSN_P (insn)) { - unsigned int uid = INSN_UID (insn); - df_ref *def_rec; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - bitmap_set_bit (merge_set, DF_REF_REGNO (def)); - } + df_simulate_find_defs (insn, merge_set); + df_simulate_find_noclobber_defs (insn, merge_set_noclobber); } } @@ -3984,7 +3982,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, unsigned i; bitmap_iterator bi; - EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi) + EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi) { if (i < FIRST_PSEUDO_REGISTER && ! fixed_regs[i] @@ -4015,12 +4013,14 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, } /* We can perform the transformation if - MERGE_SET & (TEST_SET | TEST_LIVE) + MERGE_SET_NOCLOBBER & TEST_SET + and + MERGE_SET & TEST_LIVE and TEST_SET & DF_LIVE_IN (merge_bb) are empty. */ - if (bitmap_intersect_p (merge_set, test_set) + if (bitmap_intersect_p (merge_set_noclobber, test_set) || bitmap_intersect_p (merge_set, test_live) || bitmap_intersect_p (test_set, df_get_live_in (merge_bb))) intersect = true; @@ -4104,10 +4104,11 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, unsigned i; bitmap_iterator bi; - EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi) + EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi) remove_reg_equal_equiv_notes_for_regno (i); BITMAP_FREE (merge_set); + BITMAP_FREE (merge_set_noclobber); } reorder_insns (head, end, PREV_INSN (earliest)); @@ -4128,7 +4129,10 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, cancel_changes (0); fail: if (merge_set) - BITMAP_FREE (merge_set); + { + BITMAP_FREE (merge_set); + BITMAP_FREE (merge_set_noclobber); + } return FALSE; }