aboutsummaryrefslogtreecommitdiff
path: root/gcc/explow.c
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2014-05-17 07:00:02 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2014-05-17 07:00:02 +0000
commit23b33725083ba1a1c3340b81475f2940d8f2e436 (patch)
treed0bbc16685eb58141c00c2372960b318c757d524 /gcc/explow.c
parente16db39967ab6aaef964cae249087d37c18984a0 (diff)
downloadgcc-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.c34
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 (&copy);
-
- *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;