From 9bb5f693e5afa6097053fdfcbf669f15ef1b5a43 Mon Sep 17 00:00:00 2001 From: bernds Date: Tue, 31 Mar 2009 15:15:04 +0000 Subject: [PATCH] * loop-iv.c (suitable_set_for_replacement): Renamed from simplify_using_assignment; changed to return bool and to accept new args DEST and SRC. Return true iff we find a source/destination pair that can be used to make a replacement, and fill SRC and DEST if so. Remove arg ALTERED. Don't deal with altered regs here. All callers changed. (simplify_using_initial_values): Deal with altered regs here and track more precisely the effect they have on the validity of our expression. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145351 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 ++++++ gcc/loop-iv.c | 106 +++++++++++++++++++++++++++++++++------------------------- 2 files changed, 71 insertions(+), 46 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ccdb4c0c3c..007b00e8c02 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2009-03-31 Bernd Schmidt + + * loop-iv.c (suitable_set_for_replacement): Renamed from + simplify_using_assignment; changed to return bool and to accept new + args DEST and SRC. Return true iff we find a source/destination pair + that can be used to make a replacement, and fill SRC and DEST if so. + Remove arg ALTERED. Don't deal with altered regs here. All callers + changed. + (simplify_using_initial_values): Deal with altered regs here and track + more precisely the effect they have on the validity of our expression. + 2009-03-31 Ramana Radhakrishnan PR target/27237 diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index e02f1649c64..483a868859d 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -1364,39 +1364,23 @@ simple_rhs_p (rtx rhs) } } -/* Simplifies *EXPR using assignment in INSN. ALTERED is the set of registers - altered so far. */ +/* A subroutine of simplify_using_initial_values, this function examines INSN + to see if it contains a suitable set that we can use to make a replacement. + If it is suitable, return true and set DEST and SRC to the lhs and rhs of + the set; return false otherwise. */ -static void -simplify_using_assignment (rtx insn, rtx *expr, regset altered) +static bool +suitable_set_for_replacement (rtx insn, rtx *dest, rtx *src) { rtx set = single_set (insn); rtx lhs = NULL_RTX, rhs; - bool ret = false; - if (set) - { - lhs = SET_DEST (set); - if (!REG_P (lhs) - || altered_reg_used (&lhs, altered)) - ret = true; - } - else - ret = true; - - note_stores (PATTERN (insn), mark_altered, altered); - if (CALL_P (insn)) - { - int i; - - /* Kill all call clobbered registers. */ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) - SET_REGNO_REG_SET (altered, i); - } + if (!set) + return false; - if (ret) - return; + lhs = SET_DEST (set); + if (!REG_P (lhs)) + return false; rhs = find_reg_equal_equiv_note (insn); if (rhs) @@ -1405,12 +1389,11 @@ simplify_using_assignment (rtx insn, rtx *expr, regset altered) rhs = SET_SRC (set); if (!simple_rhs_p (rhs)) - return; - - if (for_each_rtx (&rhs, altered_reg_used, altered)) - return; + return false; - *expr = simplify_replace_rtx (*expr, lhs, rhs); + *dest = lhs; + *src = rhs; + return true; } /* Checks whether A implies B. */ @@ -1762,9 +1745,10 @@ eliminate_implied_conditions (enum rtx_code op, rtx *head, rtx tail) static void simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) { - rtx head, tail, insn; + bool expression_valid; + rtx head, tail, insn, last_valid_expr; rtx neutral, aggr; - regset altered; + regset altered, this_altered; edge e; if (!*expr) @@ -1829,7 +1813,10 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) return; altered = ALLOC_REG_SET (®_obstack); + this_altered = ALLOC_REG_SET (®_obstack); + expression_valid = true; + last_valid_expr = *expr; while (1) { insn = BB_END (e->src); @@ -1843,29 +1830,52 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) { simplify_using_condition (cond, expr, altered); if (CONSTANT_P (*expr)) - { - FREE_REG_SET (altered); - return; - } + goto out; } } FOR_BB_INSNS_REVERSE (e->src, insn) { + rtx src, dest; + if (!INSN_P (insn)) continue; - - simplify_using_assignment (insn, expr, altered); - if (CONSTANT_P (*expr)) + + CLEAR_REG_SET (this_altered); + note_stores (PATTERN (insn), mark_altered, this_altered); + if (CALL_P (insn)) { - FREE_REG_SET (altered); - return; + int i; + + /* Kill all call clobbered registers. */ + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) + SET_REGNO_REG_SET (this_altered, i); } - if (for_each_rtx (expr, altered_reg_used, altered)) + + if (suitable_set_for_replacement (insn, &dest, &src)) { - FREE_REG_SET (altered); - return; + *expr = simplify_replace_rtx (*expr, dest, src); + if (CONSTANT_P (*expr)) + goto out; } + else + /* If we did not use this insn to make a replacement, any overlap + between stores in this insn and our expression will cause the + expression to become invalid. */ + if (for_each_rtx (expr, altered_reg_used, this_altered)) + goto out; + + IOR_REG_SET (altered, this_altered); + + /* If the expression now contains regs that have been altered, we + can't return it to the caller. However, it is still valid for + further simplification, so keep searching to see if we can + eventually turn it into a constant. */ + if (for_each_rtx (expr, altered_reg_used, altered)) + expression_valid = false; + if (expression_valid) + last_valid_expr = *expr; } if (!single_pred_p (e->src) @@ -1874,7 +1884,11 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) e = single_pred_edge (e->src); } + out: + if (!CONSTANT_P (*expr)) + *expr = last_valid_expr; FREE_REG_SET (altered); + FREE_REG_SET (this_altered); } /* Transforms invariant IV into MODE. Adds assumptions based on the fact -- 2.11.0