diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-07-17 14:46:06 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-07-17 14:46:06 +0000 |
commit | 1d322a970556023c6ef430b2617c126fefb1e9d2 (patch) | |
tree | adf0dd2a995e73cabb5b041099bb2f890e671cc9 /gcc/fold-const.c | |
parent | 0e9ea1e384fd35916e7b2771f5589e7200c99ff4 (diff) | |
download | ppe42-gcc-1d322a970556023c6ef430b2617c126fefb1e9d2.tar.gz ppe42-gcc-1d322a970556023c6ef430b2617c126fefb1e9d2.zip |
* loop.h (struct induction): Add no_const_addval.
* loop.c (the_movables, reg_address_cost): New variables.
(init_loop): Init reg_address_cost.
(loop_optimize): Call end_alias_analysis.
(scan_loop): Init the_movables.
(record_giv): Init induction->no_const_addval.
(basic_induction_var) [PLUS]: Use rtx_equal_p instead of ==.
[REG]: Rearrange loop search test to catch more cases.
(general_induction_var): Return success not benefit; take an extra
argument for that. Change all callers.
(simplify_giv_expr) [PLUS]: Always combine invariants. Use sge_plus.
[MULT]: Use rtx_equal_p instead of ==. Combine simple invariants.
[default]: Search the_movables for additional combinations.
(sge_plus_constant, sge_plus): New functions.
(express_from_1): New function.
(express_from): Always define. Rewrite using express_from_1.
(combine_givs_p): Handle more cases. Ignore address cost.
(cmp_combine_givs_stats): New function.
(combine_givs_used_once, combine_givs_benefit_from): New functions.
(combine_givs): Rewrite to do best-fit combination.
* fold-const.c (operand_equal_p): Handle RTL_EXPR.
(fold): Do a complete (A*C)+(B*C) association check.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@21263 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 8849608795a..4fe68994454 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1928,6 +1928,11 @@ operand_equal_p (arg0, arg1, only_const) default: return 0; } + + case 'e': + if (TREE_CODE (arg0) == RTL_EXPR) + return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1)); + return 0; default: return 0; @@ -4413,18 +4418,36 @@ fold (expr) goto bit_ior; } - /* (A * C) + (B * C) -> (A+B) * C. Since we are most concerned - about the case where C is a constant, just try one of the - four possibilities. */ - - if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR - && operand_equal_p (TREE_OPERAND (arg0, 1), - TREE_OPERAND (arg1, 1), 0)) - return fold (build (MULT_EXPR, type, - fold (build (PLUS_EXPR, type, - TREE_OPERAND (arg0, 0), - TREE_OPERAND (arg1, 0))), - TREE_OPERAND (arg0, 1))); + if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR) + { + tree arg00, arg01, arg10, arg11; + tree alt0, alt1, same; + + /* (A * C) + (B * C) -> (A+B) * C. + We are most concerned about the case where C is a constant, + but other combinations show up during loop reduction. Since + it is not difficult, try all four possibilities. */ + + arg00 = TREE_OPERAND (arg0, 0); + arg01 = TREE_OPERAND (arg0, 1); + arg10 = TREE_OPERAND (arg1, 0); + arg11 = TREE_OPERAND (arg1, 1); + same = NULL_TREE; + + if (operand_equal_p (arg01, arg11, 0)) + same = arg01, alt0 = arg00, alt1 = arg10; + else if (operand_equal_p (arg00, arg10, 0)) + same = arg00, alt0 = arg01, alt1 = arg11; + else if (operand_equal_p (arg00, arg11, 0)) + same = arg00, alt0 = arg01, alt1 = arg10; + else if (operand_equal_p (arg01, arg10, 0)) + same = arg01, alt0 = arg00, alt1 = arg11; + + if (same) + return fold (build (MULT_EXPR, type, + fold (build (PLUS_EXPR, type, alt0, alt1)), + same)); + } } /* In IEEE floating point, x+0 may not equal x. */ else if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT |