diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-20 08:05:12 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-20 08:05:12 +0000 |
commit | b718fe638db7f365e5c5ff86eb12b0246aee9554 (patch) | |
tree | 049852a66bb3c2b176b99851ac916058e794f7d0 /gcc | |
parent | fdcb802df2ec636e96d2200ea957fef6045ebce6 (diff) | |
download | gcc-b718fe638db7f365e5c5ff86eb12b0246aee9554.tar.gz |
PR rtl-optimization/32283
* tree-ssa-loop-niter.c (scev_probably_wraps_p): Use type of the base
of the induction variable to decide whether it may wrap.
* tree-ssa-loop-ivopts.c (rewrite_use_compare): Emit the initialization
of the bound before the loop.
* simplify-rtx.c (simplify_binary_operation_1): Add two simplifications
regarding AND.
(simplify_plus_minus): Only fail if no simplification is possible.
* loop-iv.c (simple_rhs_p): Consider reg + reg and reg << cst simple.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142035 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/loop-iv.c | 25 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 34 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 8 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-niter.c | 2 |
5 files changed, 62 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 48757a5f155..8731154e131 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2008-11-19 Zdenek Dvorak <ook@ucw.cz> + + PR rtl-optimization/32283 + * tree-ssa-loop-niter.c (scev_probably_wraps_p): Use type of the base + of the induction variable to decide whether it may wrap. + * tree-ssa-loop-ivopts.c (rewrite_use_compare): Emit the initialization + of the bound before the loop. + * simplify-rtx.c (simplify_binary_operation_1): Add two simplifications + regarding AND. + (simplify_plus_minus): Only fail if no simplification is possible. + * loop-iv.c (simple_rhs_p): Consider reg + reg and reg << cst simple. + 2008-11-20 Jakub Jelinek <jakub@redhat.com> PR c++/36631 diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 2523963f36d..3723dbd463a 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -1337,13 +1337,26 @@ simple_rhs_p (rtx rhs) case MINUS: op0 = XEXP (rhs, 0); op1 = XEXP (rhs, 1); - /* Allow reg + const sets only. */ - if (REG_P (op0) && !HARD_REGISTER_P (op0) && CONSTANT_P (op1)) - return true; - if (REG_P (op1) && !HARD_REGISTER_P (op1) && CONSTANT_P (op0)) - return true; + /* Allow reg + const and reg + reg. */ + if (!(REG_P (op0) && !HARD_REGISTER_P (op0)) + && !CONSTANT_P (op0)) + return false; + if (!(REG_P (op1) && !HARD_REGISTER_P (op1)) + && !CONSTANT_P (op1)) + return false; - return false; + return true; + + case ASHIFT: + op0 = XEXP (rhs, 0); + op1 = XEXP (rhs, 1); + /* Allow reg << const. */ + if (!(REG_P (op0) && !HARD_REGISTER_P (op0))) + return false; + if (!CONSTANT_P (op1)) + return false; + + return true; default: return false; diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index dd91e120d23..16d0d48688d 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2304,12 +2304,19 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, case AND: if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0)) return trueop1; - /* If we are turning off bits already known off in OP0, we need - not do an AND. */ if (GET_CODE (trueop1) == CONST_INT - && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT - && (nonzero_bits (trueop0, mode) & ~INTVAL (trueop1)) == 0) - return op0; + && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) + { + HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode); + HOST_WIDE_INT val1 = INTVAL (trueop1); + /* If we are turning off bits already known off in OP0, we need + not do an AND. */ + if ((nzop0 & ~val1) == 0) + return op0; + /* If we are clearing all the nonzero bits, the result is zero. */ + if ((val1 & nzop0) == 0 && !side_effects_p (op0)) + return CONST0_RTX (mode); + } if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0) && GET_MODE_CLASS (mode) != MODE_CC) return op0; @@ -2391,7 +2398,9 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, ((A & N) + B) & M -> (A + B) & M Similarly if (N & M) == 0, ((A | N) + B) & M -> (A + B) & M - and for - instead of + and/or ^ instead of |. */ + and for - instead of + and/or ^ instead of |. + Also, if (N & M) == 0, then + (A +- N) & M -> A & M. */ if (GET_CODE (trueop1) == CONST_INT && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT && ~INTVAL (trueop1) @@ -2404,6 +2413,10 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, pmop[0] = XEXP (op0, 0); pmop[1] = XEXP (op0, 1); + if (GET_CODE (pmop[1]) == CONST_INT + && (INTVAL (pmop[1]) & INTVAL (trueop1)) == 0) + return simplify_gen_binary (AND, mode, pmop[0], op1); + for (which = 0; which < 2; which++) { tem = pmop[which]; @@ -3591,10 +3604,6 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0, ops[j + 1] = save; } - /* This is only useful the first time through. */ - if (!canonicalized) - return NULL_RTX; - changed = 0; for (i = n_ops - 1; i > 0; i--) for (j = i - 1; j >= 0; j--) @@ -3650,10 +3659,15 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0, ops[i].neg = lneg; ops[j].op = NULL_RTX; changed = 1; + canonicalized = 1; } } } + /* If nothing changed, fail. */ + if (!canonicalized) + return NULL_RTX; + /* Pack all the operands to the lower-numbered entries. */ for (i = 0, j = 0; j < n_ops; j++) if (ops[j].op) diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 92d9c751aab..aa0472ea364 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -5323,11 +5323,15 @@ rewrite_use_compare (struct ivopts_data *data, { tree var = var_at_stmt (data->current_loop, cand, use->stmt); tree var_type = TREE_TYPE (var); + gimple_seq stmts; compare = iv_elimination_compare (data, use); bound = unshare_expr (fold_convert (var_type, bound)); - op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE, - true, GSI_SAME_STMT); + op = force_gimple_operand (bound, &stmts, true, NULL_TREE); + if (stmts) + gsi_insert_seq_on_edge_immediate ( + loop_preheader_edge (data->current_loop), + stmts); gimple_cond_set_lhs (use->stmt, var); gimple_cond_set_code (use->stmt, compare); diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 33aacae83b5..13b10c9f1c4 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -3053,7 +3053,7 @@ scev_probably_wraps_p (tree base, tree step, /* If we can use the fact that signed and pointer arithmetics does not wrap, we are done. */ - if (use_overflow_semantics && nowrap_type_p (type)) + if (use_overflow_semantics && nowrap_type_p (TREE_TYPE (base))) return false; /* To be able to use estimates on number of iterations of the loop, |