diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2014-05-17 07:00:02 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2014-05-17 07:00:02 +0000 |
commit | 23b33725083ba1a1c3340b81475f2940d8f2e436 (patch) | |
tree | d0bbc16685eb58141c00c2372960b318c757d524 /gcc/explow.c | |
parent | e16db39967ab6aaef964cae249087d37c18984a0 (diff) | |
download | gcc-23b33725083ba1a1c3340b81475f2940d8f2e436.zip gcc-23b33725083ba1a1c3340b81475f2940d8f2e436.tar.gz gcc-23b33725083ba1a1c3340b81475f2940d8f2e436.tar.bz2 |
emit-rtl.h (replace_equiv_address, [...]): Add an inplace argument.
gcc/
* emit-rtl.h (replace_equiv_address, replace_equiv_address_nv): Add an
inplace argument. Store the new address in the original MEM when true.
* emit-rtl.c (change_address_1): Likewise.
(adjust_address_1, adjust_automodify_address_1, offset_address):
Update accordingly.
* rtl.h (plus_constant): Add an inplace argument.
* explow.c (plus_constant): Likewise. Try to reuse the original PLUS
when true. Avoid generating (plus X (const_int 0)).
* function.c (instantiate_virtual_regs_in_rtx): Adjust the PLUS
in-place. Pass true to plus_constant.
(instantiate_virtual_regs_in_insn): Pass true to replace_equiv_address.
From-SVN: r210543
Diffstat (limited to 'gcc/explow.c')
-rw-r--r-- | gcc/explow.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/gcc/explow.c b/gcc/explow.c index bc97c96..e39db05 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -74,10 +74,12 @@ trunc_int_for_mode (HOST_WIDE_INT c, enum machine_mode mode) } /* Return an rtx for the sum of X and the integer C, given that X has - mode MODE. */ + mode MODE. INPLACE is true if X can be modified inplace or false + if it must be treated as immutable. */ rtx -plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c) +plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c, + bool inplace) { RTX_CODE code; rtx y; @@ -116,6 +118,8 @@ plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c) case CONST: /* If adding to something entirely constant, set a flag so that we can add a CONST around the result. */ + if (inplace && shared_const_p (x)) + inplace = false; x = XEXP (x, 0); all_constant = 1; goto restart; @@ -136,19 +140,25 @@ plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c) if (CONSTANT_P (XEXP (x, 1))) { - x = gen_rtx_PLUS (mode, XEXP (x, 0), - plus_constant (mode, XEXP (x, 1), c)); + rtx term = plus_constant (mode, XEXP (x, 1), c, inplace); + if (term == const0_rtx) + x = XEXP (x, 0); + else if (inplace) + XEXP (x, 1) = term; + else + x = gen_rtx_PLUS (mode, XEXP (x, 0), term); c = 0; } - else if (find_constant_term_loc (&y)) + else if (rtx *const_loc = find_constant_term_loc (&y)) { - /* We need to be careful since X may be shared and we can't - modify it in place. */ - rtx copy = copy_rtx (x); - rtx *const_loc = find_constant_term_loc (©); - - *const_loc = plus_constant (mode, *const_loc, c); - x = copy; + if (!inplace) + { + /* We need to be careful since X may be shared and we can't + modify it in place. */ + x = copy_rtx (x); + const_loc = find_constant_term_loc (&x); + } + *const_loc = plus_constant (mode, *const_loc, c, true); c = 0; } break; |