diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-31 15:16:41 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-31 15:16:41 +0000 |
commit | 7f7a6f4a129b77b67da8db39c088223443fd8d23 (patch) | |
tree | f70a92f822f9ed585d42284f367304878fc9253d /gcc/loop-iv.c | |
parent | 9bb5f693e5afa6097053fdfcbf669f15ef1b5a43 (diff) | |
download | gcc-7f7a6f4a129b77b67da8db39c088223443fd8d23.tar.gz |
* loop-iv.c (simplify_using_condition): A condition of the form
(EQ REG CONST) can be used to simply make a substitution.
(simplify_using_initial_values): Keep track of conditions we have seen
and keep using them to simplify new expressions, while applying the
same substitutions to them as to the expression.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145352 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop-iv.c')
-rw-r--r-- | gcc/loop-iv.c | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 483a868859d..123e37cff59 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -1636,15 +1636,22 @@ simplify_using_condition (rtx cond, rtx *expr, regset altered) { rtx rev, reve, exp = *expr; - if (!COMPARISON_P (exp)) - return; - /* If some register gets altered later, we do not really speak about its value at the time of comparison. */ if (altered && for_each_rtx (&cond, altered_reg_used, altered)) return; + if (GET_CODE (cond) == EQ + && REG_P (XEXP (cond, 0)) && CONSTANT_P (XEXP (cond, 1))) + { + *expr = simplify_replace_rtx (*expr, XEXP (cond, 0), XEXP (cond, 1)); + return; + } + + if (!COMPARISON_P (exp)) + return; + rev = reversed_condition (cond); reve = reversed_condition (exp); @@ -1661,7 +1668,6 @@ simplify_using_condition (rtx cond, rtx *expr, regset altered) return; } - if (rev && rtx_equal_p (exp, rev)) { *expr = const0_rtx; @@ -1746,7 +1752,7 @@ static void simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) { bool expression_valid; - rtx head, tail, insn, last_valid_expr; + rtx head, tail, insn, cond_list, last_valid_expr; rtx neutral, aggr; regset altered, this_altered; edge e; @@ -1817,26 +1823,40 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) expression_valid = true; last_valid_expr = *expr; + cond_list = NULL_RTX; while (1) { insn = BB_END (e->src); if (any_condjump_p (insn)) { rtx cond = get_condition (BB_END (e->src), NULL, false, true); - + if (cond && (e->flags & EDGE_FALLTHRU)) cond = reversed_condition (cond); if (cond) { + rtx old = *expr; simplify_using_condition (cond, expr, altered); - if (CONSTANT_P (*expr)) - goto out; + if (old != *expr) + { + rtx note; + if (CONSTANT_P (*expr)) + goto out; + for (note = cond_list; note; note = XEXP (note, 1)) + { + simplify_using_condition (XEXP (note, 0), expr, altered); + if (CONSTANT_P (*expr)) + goto out; + } + } + cond_list = alloc_EXPR_LIST (0, cond, cond_list); } } FOR_BB_INSNS_REVERSE (e->src, insn) { rtx src, dest; + rtx old = *expr; if (!INSN_P (insn)) continue; @@ -1855,9 +1875,34 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) if (suitable_set_for_replacement (insn, &dest, &src)) { + rtx *pnote, *pnote_next; + *expr = simplify_replace_rtx (*expr, dest, src); if (CONSTANT_P (*expr)) goto out; + + for (pnote = &cond_list; *pnote; pnote = pnote_next) + { + rtx note = *pnote; + rtx old_cond = XEXP (note, 0); + + pnote_next = &XEXP (note, 1); + XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), dest, + src); + /* We can no longer use a condition that has been simplified + to a constant, and simplify_using_condition will abort if + we try. */ + if (CONSTANT_P (XEXP (note, 0))) + { + *pnote = *pnote_next; + pnote_next = pnote; + free_EXPR_LIST_node (note); + } + /* Retry simplifications with this condition if either the + expression or the condition changed. */ + else if (old_cond != XEXP (note, 0) || old != *expr) + simplify_using_condition (XEXP (note, 0), expr, altered); + } } else /* If we did not use this insn to make a replacement, any overlap @@ -1866,6 +1911,9 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) if (for_each_rtx (expr, altered_reg_used, this_altered)) goto out; + if (CONSTANT_P (*expr)) + goto out; + IOR_REG_SET (altered, this_altered); /* If the expression now contains regs that have been altered, we @@ -1885,6 +1933,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) } out: + free_EXPR_LIST_list (&cond_list); if (!CONSTANT_P (*expr)) *expr = last_valid_expr; FREE_REG_SET (altered); |