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
This commit is contained in:
parent
e16db39967
commit
23b3372508
@ -1,3 +1,17 @@
|
||||
2014-05-17 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2014-05-16 Dehao Chen <dehao@google.com>
|
||||
|
||||
* tree-cfg.c (gimple_merge_blocks): Updates bb count with max count.
|
||||
|
@ -145,7 +145,6 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
|
||||
#define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid)
|
||||
#define first_label_num (crtl->emit.x_first_label_num)
|
||||
|
||||
static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
|
||||
static void set_used_decls (tree);
|
||||
static void mark_label_nuses (rtx);
|
||||
static hashval_t const_int_htab_hash (const void *);
|
||||
@ -2010,11 +2009,15 @@ clear_mem_size (rtx mem)
|
||||
/* Return a memory reference like MEMREF, but with its mode changed to MODE
|
||||
and its address changed to ADDR. (VOIDmode means don't change the mode.
|
||||
NULL for ADDR means don't change the address.) VALIDATE is nonzero if the
|
||||
returned memory location is required to be valid. The memory
|
||||
attributes are not changed. */
|
||||
returned memory location is required to be valid. INPLACE is true if any
|
||||
changes can be made directly to MEMREF or false if MEMREF must be treated
|
||||
as immutable.
|
||||
|
||||
The memory attributes are not changed. */
|
||||
|
||||
static rtx
|
||||
change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
|
||||
change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate,
|
||||
bool inplace)
|
||||
{
|
||||
addr_space_t as;
|
||||
rtx new_rtx;
|
||||
@ -2042,6 +2045,12 @@ change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
|
||||
if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
|
||||
return memref;
|
||||
|
||||
if (inplace)
|
||||
{
|
||||
XEXP (memref, 0) = addr;
|
||||
return memref;
|
||||
}
|
||||
|
||||
new_rtx = gen_rtx_MEM (mode, addr);
|
||||
MEM_COPY_ATTRIBUTES (new_rtx, memref);
|
||||
return new_rtx;
|
||||
@ -2053,7 +2062,7 @@ change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
|
||||
rtx
|
||||
change_address (rtx memref, enum machine_mode mode, rtx addr)
|
||||
{
|
||||
rtx new_rtx = change_address_1 (memref, mode, addr, 1);
|
||||
rtx new_rtx = change_address_1 (memref, mode, addr, 1, false);
|
||||
enum machine_mode mmode = GET_MODE (new_rtx);
|
||||
struct mem_attrs attrs, *defattrs;
|
||||
|
||||
@ -2166,7 +2175,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
|
||||
addr = plus_constant (address_mode, addr, offset);
|
||||
}
|
||||
|
||||
new_rtx = change_address_1 (memref, mode, addr, validate);
|
||||
new_rtx = change_address_1 (memref, mode, addr, validate, false);
|
||||
|
||||
/* If the address is a REG, change_address_1 rightfully returns memref,
|
||||
but this would destroy memref's MEM_ATTRS. */
|
||||
@ -2236,7 +2245,7 @@ rtx
|
||||
adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
|
||||
HOST_WIDE_INT offset, int validate)
|
||||
{
|
||||
memref = change_address_1 (memref, VOIDmode, addr, validate);
|
||||
memref = change_address_1 (memref, VOIDmode, addr, validate, false);
|
||||
return adjust_address_1 (memref, mode, offset, validate, 0, 0, 0);
|
||||
}
|
||||
|
||||
@ -2272,7 +2281,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
|
||||
}
|
||||
|
||||
update_temp_slot_address (XEXP (memref, 0), new_rtx);
|
||||
new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1);
|
||||
new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1, false);
|
||||
|
||||
/* If there are no changes, just return the original memory reference. */
|
||||
if (new_rtx == memref)
|
||||
@ -2292,23 +2301,25 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
|
||||
/* Return a memory reference like MEMREF, but with its address changed to
|
||||
ADDR. The caller is asserting that the actual piece of memory pointed
|
||||
to is the same, just the form of the address is being changed, such as
|
||||
by putting something into a register. */
|
||||
by putting something into a register. INPLACE is true if any changes
|
||||
can be made directly to MEMREF or false if MEMREF must be treated as
|
||||
immutable. */
|
||||
|
||||
rtx
|
||||
replace_equiv_address (rtx memref, rtx addr)
|
||||
replace_equiv_address (rtx memref, rtx addr, bool inplace)
|
||||
{
|
||||
/* change_address_1 copies the memory attribute structure without change
|
||||
and that's exactly what we want here. */
|
||||
update_temp_slot_address (XEXP (memref, 0), addr);
|
||||
return change_address_1 (memref, VOIDmode, addr, 1);
|
||||
return change_address_1 (memref, VOIDmode, addr, 1, inplace);
|
||||
}
|
||||
|
||||
/* Likewise, but the reference is not required to be valid. */
|
||||
|
||||
rtx
|
||||
replace_equiv_address_nv (rtx memref, rtx addr)
|
||||
replace_equiv_address_nv (rtx memref, rtx addr, bool inplace)
|
||||
{
|
||||
return change_address_1 (memref, VOIDmode, addr, 0);
|
||||
return change_address_1 (memref, VOIDmode, addr, 0, inplace);
|
||||
}
|
||||
|
||||
/* Return a memory reference like MEMREF, but with its mode widened to
|
||||
|
@ -52,10 +52,10 @@ extern tree get_spill_slot_decl (bool);
|
||||
ADDR. The caller is asserting that the actual piece of memory pointed
|
||||
to is the same, just the form of the address is being changed, such as
|
||||
by putting something into a register. */
|
||||
extern rtx replace_equiv_address (rtx, rtx);
|
||||
extern rtx replace_equiv_address (rtx, rtx, bool = false);
|
||||
|
||||
/* Likewise, but the reference is not required to be valid. */
|
||||
extern rtx replace_equiv_address_nv (rtx, rtx);
|
||||
extern rtx replace_equiv_address_nv (rtx, rtx, bool = false);
|
||||
|
||||
extern rtx gen_blockage (void);
|
||||
extern rtvec gen_rtvec (int, ...);
|
||||
|
34
gcc/explow.c
34
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;
|
||||
|
@ -1459,8 +1459,8 @@ instantiate_virtual_regs_in_rtx (rtx *loc, void *data)
|
||||
new_rtx = instantiate_new_reg (XEXP (x, 0), &offset);
|
||||
if (new_rtx)
|
||||
{
|
||||
new_rtx = plus_constant (GET_MODE (x), new_rtx, offset);
|
||||
*loc = simplify_gen_binary (PLUS, GET_MODE (x), new_rtx, XEXP (x, 1));
|
||||
XEXP (x, 0) = new_rtx;
|
||||
*loc = plus_constant (GET_MODE (x), x, offset, true);
|
||||
if (changed)
|
||||
*changed = true;
|
||||
return -1;
|
||||
@ -1622,7 +1622,7 @@ instantiate_virtual_regs_in_insn (rtx insn)
|
||||
continue;
|
||||
|
||||
start_sequence ();
|
||||
x = replace_equiv_address (x, addr);
|
||||
x = replace_equiv_address (x, addr, true);
|
||||
/* It may happen that the address with the virtual reg
|
||||
was valid (e.g. based on the virtual stack reg, which might
|
||||
be acceptable to the predicates with all offsets), whereas
|
||||
@ -1635,7 +1635,7 @@ instantiate_virtual_regs_in_insn (rtx insn)
|
||||
if (!safe_insn_predicate (insn_code, i, x))
|
||||
{
|
||||
addr = force_reg (GET_MODE (addr), addr);
|
||||
x = replace_equiv_address (x, addr);
|
||||
x = replace_equiv_address (x, addr, true);
|
||||
}
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
|
@ -1952,7 +1952,7 @@ extern int currently_expanding_to_rtl;
|
||||
|
||||
/* In explow.c */
|
||||
extern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, enum machine_mode);
|
||||
extern rtx plus_constant (enum machine_mode, rtx, HOST_WIDE_INT);
|
||||
extern rtx plus_constant (enum machine_mode, rtx, HOST_WIDE_INT, bool = false);
|
||||
|
||||
/* In rtl.c */
|
||||
extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
|
||||
|
Loading…
Reference in New Issue
Block a user