rtl.texi (MEM_OFFSET_KNOWN_P): Document.
gcc/ * doc/rtl.texi (MEM_OFFSET_KNOWN_P): Document. (MEM_OFFSET): Change from returning an rtx to returning a HOST_WIDE_INT. * rtl.h (MEM_OFFSET_KNOWN_P): New macro. (MEM_OFFSET): Return a HOST_WIDE_INT rather than an rtx. * emit-rtl.h (set_mem_offset): Take a HOST_WIDE_INT rather than an rtx. (clear_mem_offset): Declare. * alias.c (ao_ref_from_mem): Adjust uses of MEM_OFFSET, using MEM_OFFSET_KNOWN_P to test whether the offset is known, and MEM_OFFSET to get a HOST_WIDE_INT offset. (nonoverlapping_memrefs_p): Likewise. Adjust calls to... (adjust_offset_for_component_ref): Take a bool "known_p" parameter and a HOST_WIDE_INT "offset" parameter. * builtins.c (get_memory_rtx): As for ao_ref_from_mem. Adjust calls to set_mem_offset, passing a HOST_WIDE_INT rather than an rtx. Use clear_mem_offset to clear the offset. * cfgcleanup.c (merge_memattrs): Likewise. * dwarf2out.c (tls_mem_loc_descriptor): Likewise. * function.c (assign_parm_find_stack_rtl): Likewise. (assign_parm_setup_stack): Likewise. * print-rtl.c (print_rtx): Likewise. * reload.c (find_reloads_subreg_address): Likewise. * simplify-rtx.c (delegitimize_mem_from_attrs): Likewise. * var-tracking.c (INT_MEM_OFFSET): Likewise. * emit-rtl.c (set_reg_attrs_from_value): Likewise. (get_mem_align_offset): Likewise. (set_mem_offset): Take a HOST_WIDE_INT rather than an rtx. (clear_mem_offset): New function. * config/mips/mips.c (r10k_safe_mem_expr_p): Take a HOST_WIDE_INT offset rather than an rtx. Assume both the expressio and offset are available. (r10k_needs_protection_p_1): Update accordingly, checking the expression and offset availability here instead. From-SVN: r176477
This commit is contained in:
parent
f5541398ef
commit
527210c448
15 changed files with 142 additions and 86 deletions
|
@ -1,3 +1,39 @@
|
|||
2011-07-19 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* doc/rtl.texi (MEM_OFFSET_KNOWN_P): Document.
|
||||
(MEM_OFFSET): Change from returning an rtx to returning a
|
||||
HOST_WIDE_INT.
|
||||
* rtl.h (MEM_OFFSET_KNOWN_P): New macro.
|
||||
(MEM_OFFSET): Return a HOST_WIDE_INT rather than an rtx.
|
||||
* emit-rtl.h (set_mem_offset): Take a HOST_WIDE_INT rather than an rtx.
|
||||
(clear_mem_offset): Declare.
|
||||
* alias.c (ao_ref_from_mem): Adjust uses of MEM_OFFSET, using
|
||||
MEM_OFFSET_KNOWN_P to test whether the offset is known, and
|
||||
MEM_OFFSET to get a HOST_WIDE_INT offset.
|
||||
(nonoverlapping_memrefs_p): Likewise. Adjust calls to...
|
||||
(adjust_offset_for_component_ref): Take a bool "known_p"
|
||||
parameter and a HOST_WIDE_INT "offset" parameter.
|
||||
* builtins.c (get_memory_rtx): As for ao_ref_from_mem.
|
||||
Adjust calls to set_mem_offset, passing a HOST_WIDE_INT rather
|
||||
than an rtx. Use clear_mem_offset to clear the offset.
|
||||
* cfgcleanup.c (merge_memattrs): Likewise.
|
||||
* dwarf2out.c (tls_mem_loc_descriptor): Likewise.
|
||||
* function.c (assign_parm_find_stack_rtl): Likewise.
|
||||
(assign_parm_setup_stack): Likewise.
|
||||
* print-rtl.c (print_rtx): Likewise.
|
||||
* reload.c (find_reloads_subreg_address): Likewise.
|
||||
* simplify-rtx.c (delegitimize_mem_from_attrs): Likewise.
|
||||
* var-tracking.c (INT_MEM_OFFSET): Likewise.
|
||||
* emit-rtl.c (set_reg_attrs_from_value): Likewise.
|
||||
(get_mem_align_offset): Likewise.
|
||||
(set_mem_offset): Take a HOST_WIDE_INT rather than an rtx.
|
||||
(clear_mem_offset): New function.
|
||||
* config/mips/mips.c (r10k_safe_mem_expr_p): Take a HOST_WIDE_INT
|
||||
offset rather than an rtx. Assume both the expressio and offset
|
||||
are available.
|
||||
(r10k_needs_protection_p_1): Update accordingly, checking the
|
||||
expression and offset availability here instead.
|
||||
|
||||
2011-07-19 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* doc/rtl.texi (MEM_SIZE_KNOWN_P): Document.
|
||||
|
|
72
gcc/alias.c
72
gcc/alias.c
|
@ -162,7 +162,6 @@ static const_rtx fixed_scalar_and_varying_struct_p (const_rtx, const_rtx, rtx, r
|
|||
static int aliases_everything_p (const_rtx);
|
||||
static bool nonoverlapping_component_refs_p (const_tree, const_tree);
|
||||
static tree decl_for_component_ref (tree);
|
||||
static rtx adjust_offset_for_component_ref (tree, rtx);
|
||||
static int write_dependence_p (const_rtx, const_rtx, int);
|
||||
|
||||
static void memory_modified_1 (rtx, const_rtx, void *);
|
||||
|
@ -315,7 +314,7 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
|
|||
|
||||
/* If MEM_OFFSET or MEM_SIZE are unknown we have to punt.
|
||||
Keep points-to related information though. */
|
||||
if (!MEM_OFFSET (mem)
|
||||
if (!MEM_OFFSET_KNOWN_P (mem)
|
||||
|| !MEM_SIZE_KNOWN_P (mem))
|
||||
{
|
||||
ref->ref = NULL_TREE;
|
||||
|
@ -328,12 +327,11 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
|
|||
/* If the base decl is a parameter we can have negative MEM_OFFSET in
|
||||
case of promoted subregs on bigendian targets. Trust the MEM_EXPR
|
||||
here. */
|
||||
if (INTVAL (MEM_OFFSET (mem)) < 0
|
||||
&& ((MEM_SIZE (mem) + INTVAL (MEM_OFFSET (mem)))
|
||||
* BITS_PER_UNIT) == ref->size)
|
||||
if (MEM_OFFSET (mem) < 0
|
||||
&& (MEM_SIZE (mem) + MEM_OFFSET (mem)) * BITS_PER_UNIT == ref->size)
|
||||
return true;
|
||||
|
||||
ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT;
|
||||
ref->offset += MEM_OFFSET (mem) * BITS_PER_UNIT;
|
||||
ref->size = MEM_SIZE (mem) * BITS_PER_UNIT;
|
||||
|
||||
/* The MEM may extend into adjacent fields, so adjust max_size if
|
||||
|
@ -2201,34 +2199,33 @@ decl_for_component_ref (tree x)
|
|||
return x && DECL_P (x) ? x : NULL_TREE;
|
||||
}
|
||||
|
||||
/* Walk up the COMPONENT_REF list and adjust OFFSET to compensate for the
|
||||
offset of the field reference. */
|
||||
/* Walk up the COMPONENT_REF list in X and adjust *OFFSET to compensate
|
||||
for the offset of the field reference. *KNOWN_P says whether the
|
||||
offset is known. */
|
||||
|
||||
static rtx
|
||||
adjust_offset_for_component_ref (tree x, rtx offset)
|
||||
static void
|
||||
adjust_offset_for_component_ref (tree x, bool *known_p,
|
||||
HOST_WIDE_INT *offset)
|
||||
{
|
||||
HOST_WIDE_INT ioffset;
|
||||
|
||||
if (! offset)
|
||||
return NULL_RTX;
|
||||
|
||||
ioffset = INTVAL (offset);
|
||||
if (!*known_p)
|
||||
return;
|
||||
do
|
||||
{
|
||||
tree offset = component_ref_field_offset (x);
|
||||
tree xoffset = component_ref_field_offset (x);
|
||||
tree field = TREE_OPERAND (x, 1);
|
||||
|
||||
if (! host_integerp (offset, 1))
|
||||
return NULL_RTX;
|
||||
ioffset += (tree_low_cst (offset, 1)
|
||||
if (! host_integerp (xoffset, 1))
|
||||
{
|
||||
*known_p = false;
|
||||
return;
|
||||
}
|
||||
*offset += (tree_low_cst (xoffset, 1)
|
||||
+ (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
|
||||
/ BITS_PER_UNIT));
|
||||
|
||||
x = TREE_OPERAND (x, 0);
|
||||
}
|
||||
while (x && TREE_CODE (x) == COMPONENT_REF);
|
||||
|
||||
return GEN_INT (ioffset);
|
||||
}
|
||||
|
||||
/* Return nonzero if we can determine the exprs corresponding to memrefs
|
||||
|
@ -2241,7 +2238,8 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant)
|
|||
tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
|
||||
rtx rtlx, rtly;
|
||||
rtx basex, basey;
|
||||
rtx moffsetx, moffsety;
|
||||
bool moffsetx_known_p, moffsety_known_p;
|
||||
HOST_WIDE_INT moffsetx = 0, moffsety = 0;
|
||||
HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey, tem;
|
||||
|
||||
/* Unless both have exprs, we can't tell anything. */
|
||||
|
@ -2250,9 +2248,9 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant)
|
|||
|
||||
/* For spill-slot accesses make sure we have valid offsets. */
|
||||
if ((exprx == get_spill_slot_decl (false)
|
||||
&& ! MEM_OFFSET (x))
|
||||
&& ! MEM_OFFSET_KNOWN_P (x))
|
||||
|| (expry == get_spill_slot_decl (false)
|
||||
&& ! MEM_OFFSET (y)))
|
||||
&& ! MEM_OFFSET_KNOWN_P (y)))
|
||||
return 0;
|
||||
|
||||
/* If both are field references, we may be able to determine something. */
|
||||
|
@ -2263,23 +2261,27 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant)
|
|||
|
||||
|
||||
/* If the field reference test failed, look at the DECLs involved. */
|
||||
moffsetx = MEM_OFFSET (x);
|
||||
moffsetx_known_p = MEM_OFFSET_KNOWN_P (x);
|
||||
if (moffsetx_known_p)
|
||||
moffsetx = MEM_OFFSET (x);
|
||||
if (TREE_CODE (exprx) == COMPONENT_REF)
|
||||
{
|
||||
tree t = decl_for_component_ref (exprx);
|
||||
if (! t)
|
||||
return 0;
|
||||
moffsetx = adjust_offset_for_component_ref (exprx, moffsetx);
|
||||
adjust_offset_for_component_ref (exprx, &moffsetx_known_p, &moffsetx);
|
||||
exprx = t;
|
||||
}
|
||||
|
||||
moffsety = MEM_OFFSET (y);
|
||||
moffsety_known_p = MEM_OFFSET_KNOWN_P (y);
|
||||
if (moffsety_known_p)
|
||||
moffsety = MEM_OFFSET (y);
|
||||
if (TREE_CODE (expry) == COMPONENT_REF)
|
||||
{
|
||||
tree t = decl_for_component_ref (expry);
|
||||
if (! t)
|
||||
return 0;
|
||||
moffsety = adjust_offset_for_component_ref (expry, moffsety);
|
||||
adjust_offset_for_component_ref (expry, &moffsety_known_p, &moffsety);
|
||||
expry = t;
|
||||
}
|
||||
|
||||
|
@ -2346,17 +2348,17 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant)
|
|||
|
||||
/* If we have an offset for either memref, it can update the values computed
|
||||
above. */
|
||||
if (moffsetx)
|
||||
offsetx += INTVAL (moffsetx), sizex -= INTVAL (moffsetx);
|
||||
if (moffsety)
|
||||
offsety += INTVAL (moffsety), sizey -= INTVAL (moffsety);
|
||||
if (moffsetx_known_p)
|
||||
offsetx += moffsetx, sizex -= moffsetx;
|
||||
if (moffsety_known_p)
|
||||
offsety += moffsety, sizey -= moffsety;
|
||||
|
||||
/* If a memref has both a size and an offset, we can use the smaller size.
|
||||
We can't do this if the offset isn't known because we must view this
|
||||
memref as being anywhere inside the DECL's MEM. */
|
||||
if (MEM_SIZE_KNOWN_P (x) && moffsetx)
|
||||
if (MEM_SIZE_KNOWN_P (x) && moffsetx_known_p)
|
||||
sizex = MEM_SIZE (x);
|
||||
if (MEM_SIZE_KNOWN_P (y) && moffsety)
|
||||
if (MEM_SIZE_KNOWN_P (y) && moffsety_known_p)
|
||||
sizey = MEM_SIZE (y);
|
||||
|
||||
/* Put the values of the memref with the lower offset in X's values. */
|
||||
|
|
|
@ -1238,9 +1238,8 @@ get_memory_rtx (tree exp, tree len)
|
|||
|
||||
gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
|
||||
|
||||
if (MEM_OFFSET (mem)
|
||||
&& CONST_INT_P (MEM_OFFSET (mem)))
|
||||
offset = INTVAL (MEM_OFFSET (mem));
|
||||
if (MEM_OFFSET_KNOWN_P (mem))
|
||||
offset = MEM_OFFSET (mem);
|
||||
|
||||
if (offset >= 0 && len && host_integerp (len, 0))
|
||||
length = tree_low_cst (len, 0);
|
||||
|
@ -1295,7 +1294,10 @@ get_memory_rtx (tree exp, tree len)
|
|||
if (mem_expr != MEM_EXPR (mem))
|
||||
{
|
||||
set_mem_expr (mem, mem_expr);
|
||||
set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
|
||||
if (offset >= 0)
|
||||
set_mem_offset (mem, offset);
|
||||
else
|
||||
clear_mem_offset (mem);
|
||||
}
|
||||
}
|
||||
set_mem_alias_set (mem, 0);
|
||||
|
|
|
@ -895,13 +895,15 @@ merge_memattrs (rtx x, rtx y)
|
|||
{
|
||||
set_mem_expr (x, 0);
|
||||
set_mem_expr (y, 0);
|
||||
set_mem_offset (x, 0);
|
||||
set_mem_offset (y, 0);
|
||||
clear_mem_offset (x);
|
||||
clear_mem_offset (y);
|
||||
}
|
||||
else if (MEM_OFFSET (x) != MEM_OFFSET (y))
|
||||
else if (MEM_OFFSET_KNOWN_P (x) != MEM_OFFSET_KNOWN_P (y)
|
||||
|| (MEM_OFFSET_KNOWN_P (x)
|
||||
&& MEM_OFFSET (x) != MEM_OFFSET (y)))
|
||||
{
|
||||
set_mem_offset (x, 0);
|
||||
set_mem_offset (y, 0);
|
||||
clear_mem_offset (x);
|
||||
clear_mem_offset (y);
|
||||
}
|
||||
|
||||
if (MEM_SIZE_KNOWN_P (x) && MEM_SIZE_KNOWN_P (y))
|
||||
|
|
|
@ -13765,13 +13765,9 @@ r10k_safe_address_p (rtx x, rtx insn)
|
|||
a link-time-constant address. */
|
||||
|
||||
static bool
|
||||
r10k_safe_mem_expr_p (tree expr, rtx offset)
|
||||
r10k_safe_mem_expr_p (tree expr, HOST_WIDE_INT offset)
|
||||
{
|
||||
if (expr == NULL_TREE
|
||||
|| offset == NULL_RTX
|
||||
|| !CONST_INT_P (offset)
|
||||
|| INTVAL (offset) < 0
|
||||
|| INTVAL (offset) >= int_size_in_bytes (TREE_TYPE (expr)))
|
||||
if (offset < 0 || offset >= int_size_in_bytes (TREE_TYPE (expr)))
|
||||
return false;
|
||||
|
||||
while (TREE_CODE (expr) == COMPONENT_REF)
|
||||
|
@ -13797,7 +13793,9 @@ r10k_needs_protection_p_1 (rtx *loc, void *data)
|
|||
if (!MEM_P (mem))
|
||||
return 0;
|
||||
|
||||
if (r10k_safe_mem_expr_p (MEM_EXPR (mem), MEM_OFFSET (mem)))
|
||||
if (MEM_EXPR (mem)
|
||||
&& MEM_OFFSET_KNOWN_P (mem)
|
||||
&& r10k_safe_mem_expr_p (MEM_EXPR (mem), MEM_OFFSET (mem)))
|
||||
return -1;
|
||||
|
||||
if (r10k_safe_address_p (XEXP (mem, 0), (rtx) data))
|
||||
|
|
|
@ -409,9 +409,15 @@ and @code{TREE_OPERAND (@var{x}, 0)} contains the declaration,
|
|||
or another @code{COMPONENT_REF}, or null if there is no compile-time
|
||||
object associated with the reference.
|
||||
|
||||
@findex MEM_OFFSET_KNOWN_P
|
||||
@item MEM_OFFSET_KNOWN_P (@var{x})
|
||||
True if the offset of the memory reference from @code{MEM_EXPR} is known.
|
||||
@samp{MEM_OFFSET (@var{x})} provides the offset if so.
|
||||
|
||||
@findex MEM_OFFSET
|
||||
@item MEM_OFFSET (@var{x})
|
||||
The offset from the start of @code{MEM_EXPR} as a @code{CONST_INT} rtx.
|
||||
The offset from the start of @code{MEM_EXPR}. The value is only valid if
|
||||
@samp{MEM_OFFSET_KNOWN_P (@var{x})} is true.
|
||||
|
||||
@findex MEM_SIZE_KNOWN_P
|
||||
@item MEM_SIZE_KNOWN_P (@var{x})
|
||||
|
|
|
@ -10453,7 +10453,7 @@ tls_mem_loc_descriptor (rtx mem)
|
|||
tree base;
|
||||
dw_loc_descr_ref loc_result;
|
||||
|
||||
if (MEM_EXPR (mem) == NULL_TREE || MEM_OFFSET (mem) == NULL_RTX)
|
||||
if (MEM_EXPR (mem) == NULL_TREE || !MEM_OFFSET_KNOWN_P (mem))
|
||||
return NULL;
|
||||
|
||||
base = get_base_address (MEM_EXPR (mem));
|
||||
|
@ -10466,8 +10466,8 @@ tls_mem_loc_descriptor (rtx mem)
|
|||
if (loc_result == NULL)
|
||||
return NULL;
|
||||
|
||||
if (INTVAL (MEM_OFFSET (mem)))
|
||||
loc_descr_plus_const (&loc_result, INTVAL (MEM_OFFSET (mem)));
|
||||
if (MEM_OFFSET (mem))
|
||||
loc_descr_plus_const (&loc_result, MEM_OFFSET (mem));
|
||||
|
||||
return loc_result;
|
||||
}
|
||||
|
|
|
@ -969,9 +969,9 @@ set_reg_attrs_from_value (rtx reg, rtx x)
|
|||
offset = byte_lowpart_offset (GET_MODE (reg), GET_MODE (x));
|
||||
if (MEM_P (x))
|
||||
{
|
||||
if (MEM_OFFSET (x) && CONST_INT_P (MEM_OFFSET (x)))
|
||||
REG_ATTRS (reg)
|
||||
= get_reg_attrs (MEM_EXPR (x), INTVAL (MEM_OFFSET (x)) + offset);
|
||||
if (MEM_OFFSET_KNOWN_P (x))
|
||||
REG_ATTRS (reg) = get_reg_attrs (MEM_EXPR (x),
|
||||
MEM_OFFSET (x) + offset);
|
||||
if (MEM_POINTER (x))
|
||||
mark_reg_pointer (reg, 0);
|
||||
}
|
||||
|
@ -1460,14 +1460,13 @@ get_mem_align_offset (rtx mem, unsigned int align)
|
|||
unsigned HOST_WIDE_INT offset;
|
||||
|
||||
/* This function can't use
|
||||
if (!MEM_EXPR (mem) || !MEM_OFFSET (mem)
|
||||
|| !CONST_INT_P (MEM_OFFSET (mem))
|
||||
if (!MEM_EXPR (mem) || !MEM_OFFSET_KNOWN_P (mem)
|
||||
|| (MAX (MEM_ALIGN (mem),
|
||||
get_object_alignment (MEM_EXPR (mem), align))
|
||||
< align))
|
||||
return -1;
|
||||
else
|
||||
return (- INTVAL (MEM_OFFSET (mem))) & (align / BITS_PER_UNIT - 1);
|
||||
return (- MEM_OFFSET (mem)) & (align / BITS_PER_UNIT - 1);
|
||||
for two reasons:
|
||||
- COMPONENT_REFs in MEM_EXPR can have NULL first operand,
|
||||
for <variable>. get_inner_reference doesn't handle it and
|
||||
|
@ -1477,12 +1476,10 @@ get_mem_align_offset (rtx mem, unsigned int align)
|
|||
isn't sufficiently aligned, the object it is in might be. */
|
||||
gcc_assert (MEM_P (mem));
|
||||
expr = MEM_EXPR (mem);
|
||||
if (expr == NULL_TREE
|
||||
|| MEM_OFFSET (mem) == NULL_RTX
|
||||
|| !CONST_INT_P (MEM_OFFSET (mem)))
|
||||
if (expr == NULL_TREE || !MEM_OFFSET_KNOWN_P (mem))
|
||||
return -1;
|
||||
|
||||
offset = INTVAL (MEM_OFFSET (mem));
|
||||
offset = MEM_OFFSET (mem);
|
||||
if (DECL_P (expr))
|
||||
{
|
||||
if (DECL_ALIGN (expr) < align)
|
||||
|
@ -1901,12 +1898,24 @@ set_mem_expr (rtx mem, tree expr)
|
|||
/* Set the offset of MEM to OFFSET. */
|
||||
|
||||
void
|
||||
set_mem_offset (rtx mem, rtx offset)
|
||||
set_mem_offset (rtx mem, HOST_WIDE_INT offset)
|
||||
{
|
||||
struct mem_attrs attrs;
|
||||
|
||||
attrs = *get_mem_attrs (mem);
|
||||
attrs.offset = offset;
|
||||
attrs.offset = GEN_INT (offset);
|
||||
set_mem_attrs (mem, &attrs);
|
||||
}
|
||||
|
||||
/* Clear the offset of MEM. */
|
||||
|
||||
void
|
||||
clear_mem_offset (rtx mem)
|
||||
{
|
||||
struct mem_attrs attrs;
|
||||
|
||||
attrs = *get_mem_attrs (mem);
|
||||
attrs.offset = NULL_RTX;
|
||||
set_mem_attrs (mem, &attrs);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,10 @@ extern void set_mem_addr_space (rtx, addr_space_t);
|
|||
extern void set_mem_expr (rtx, tree);
|
||||
|
||||
/* Set the offset for MEM to OFFSET. */
|
||||
extern void set_mem_offset (rtx, rtx);
|
||||
extern void set_mem_offset (rtx, HOST_WIDE_INT);
|
||||
|
||||
/* Clear the offset recorded for MEM. */
|
||||
extern void clear_mem_offset (rtx);
|
||||
|
||||
/* Set the size for MEM to SIZE. */
|
||||
extern void set_mem_size (rtx, HOST_WIDE_INT);
|
||||
|
|
|
@ -2577,14 +2577,12 @@ assign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data)
|
|||
&& data->promoted_mode != DECL_MODE (parm))
|
||||
{
|
||||
set_mem_size (stack_parm, GET_MODE_SIZE (data->promoted_mode));
|
||||
if (MEM_EXPR (stack_parm) && MEM_OFFSET (stack_parm))
|
||||
if (MEM_EXPR (stack_parm) && MEM_OFFSET_KNOWN_P (stack_parm))
|
||||
{
|
||||
int offset = subreg_lowpart_offset (DECL_MODE (parm),
|
||||
data->promoted_mode);
|
||||
if (offset)
|
||||
set_mem_offset (stack_parm,
|
||||
plus_constant (MEM_OFFSET (stack_parm),
|
||||
-offset));
|
||||
set_mem_offset (stack_parm, MEM_OFFSET (stack_parm) - offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3198,10 +3196,9 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
|
|||
/* ??? This may need a big-endian conversion on sparc64. */
|
||||
data->stack_parm
|
||||
= adjust_address (data->stack_parm, data->nominal_mode, 0);
|
||||
if (offset && MEM_OFFSET (data->stack_parm))
|
||||
if (offset && MEM_OFFSET_KNOWN_P (data->stack_parm))
|
||||
set_mem_offset (data->stack_parm,
|
||||
plus_constant (MEM_OFFSET (data->stack_parm),
|
||||
offset));
|
||||
MEM_OFFSET (data->stack_parm) + offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -597,9 +597,8 @@ print_rtx (const_rtx in_rtx)
|
|||
if (MEM_EXPR (in_rtx))
|
||||
print_mem_expr (outfile, MEM_EXPR (in_rtx));
|
||||
|
||||
if (MEM_OFFSET (in_rtx))
|
||||
fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
|
||||
INTVAL (MEM_OFFSET (in_rtx)));
|
||||
if (MEM_OFFSET_KNOWN_P (in_rtx))
|
||||
fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx));
|
||||
|
||||
if (MEM_SIZE_KNOWN_P (in_rtx))
|
||||
fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx));
|
||||
|
|
|
@ -6137,8 +6137,8 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
|
|||
|
||||
XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
|
||||
PUT_MODE (tem, GET_MODE (x));
|
||||
if (MEM_OFFSET (tem))
|
||||
set_mem_offset (tem, plus_constant (MEM_OFFSET (tem), offset));
|
||||
if (MEM_OFFSET_KNOWN_P (tem))
|
||||
set_mem_offset (tem, MEM_OFFSET (tem) + offset);
|
||||
if (MEM_SIZE_KNOWN_P (tem)
|
||||
&& MEM_SIZE (tem) != (HOST_WIDE_INT) outer_size)
|
||||
set_mem_size (tem, outer_size);
|
||||
|
|
|
@ -1302,9 +1302,11 @@ do { \
|
|||
refer to part of a DECL. It may also be a COMPONENT_REF. */
|
||||
#define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr)
|
||||
|
||||
/* For a MEM rtx, the offset from the start of MEM_EXPR, if known, as a
|
||||
RTX that is always a CONST_INT. */
|
||||
#define MEM_OFFSET(RTX) (get_mem_attrs (RTX)->offset)
|
||||
/* For a MEM rtx, true if its MEM_OFFSET is known. */
|
||||
#define MEM_OFFSET_KNOWN_P(RTX) (get_mem_attrs (RTX)->offset != NULL_RTX)
|
||||
|
||||
/* For a MEM rtx, the offset from the start of MEM_EXPR. */
|
||||
#define MEM_OFFSET(RTX) INTVAL (get_mem_attrs (RTX)->offset)
|
||||
|
||||
/* For a MEM rtx, the address space. */
|
||||
#define MEM_ADDR_SPACE(RTX) (get_mem_attrs (RTX)->addrspace)
|
||||
|
|
|
@ -268,7 +268,7 @@ delegitimize_mem_from_attrs (rtx x)
|
|||
use their base addresses as equivalent. */
|
||||
if (MEM_P (x)
|
||||
&& MEM_EXPR (x)
|
||||
&& MEM_OFFSET (x))
|
||||
&& MEM_OFFSET_KNOWN_P (x))
|
||||
{
|
||||
tree decl = MEM_EXPR (x);
|
||||
enum machine_mode mode = GET_MODE (x);
|
||||
|
@ -321,7 +321,7 @@ delegitimize_mem_from_attrs (rtx x)
|
|||
{
|
||||
rtx newx;
|
||||
|
||||
offset += INTVAL (MEM_OFFSET (x));
|
||||
offset += MEM_OFFSET (x);
|
||||
|
||||
newx = DECL_RTL (decl);
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ typedef const struct value_chain_def *const_value_chain;
|
|||
#define VTI(BB) ((variable_tracking_info) (BB)->aux)
|
||||
|
||||
/* Macro to access MEM_OFFSET as an HOST_WIDE_INT. Evaluates MEM twice. */
|
||||
#define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : 0)
|
||||
#define INT_MEM_OFFSET(mem) (MEM_OFFSET_KNOWN_P (mem) ? MEM_OFFSET (mem) : 0)
|
||||
|
||||
/* Alloc pool for struct attrs_def. */
|
||||
static alloc_pool attrs_pool;
|
||||
|
|
Loading…
Add table
Reference in a new issue