Commit 754c3d5d by Richard Sandiford Committed by Richard Sandiford

rtl.h (mem_attrs): Turn offset and size fields into HOST_WIDE_INTs.

gcc/
	* rtl.h (mem_attrs): Turn offset and size fields into HOST_WIDE_INTs.
	Add offset_known_p and size_known_p fields.
	(MEM_OFFSET_KNOWN_P): Update accordingly.
	(MEM_OFFSET, MEM_SIZE_KNOWN_P, MEM_SIZE): Likewise.
	* emit-rtl.c (mem_attrs_htab_hash): Update after mem_attrs changes.
	(mem_attrs_eq_p, set_mem_attributes_minus_bitpos, set_mem_offset)
	(clear_mem_offset, set_mem_size, clear_mem_size, change_address)
	(adjust_address_1, widen_memory_access, set_mem_attrs_for_spill)
	(init_emit_regs): Likewise.

From-SVN: r176478
parent 527210c4
2011-07-19 Richard Sandiford <rdsandiford@googlemail.com> 2011-07-19 Richard Sandiford <rdsandiford@googlemail.com>
* rtl.h (mem_attrs): Turn offset and size fields into HOST_WIDE_INTs.
Add offset_known_p and size_known_p fields.
(MEM_OFFSET_KNOWN_P): Update accordingly.
(MEM_OFFSET, MEM_SIZE_KNOWN_P, MEM_SIZE): Likewise.
* emit-rtl.c (mem_attrs_htab_hash): Update after mem_attrs changes.
(mem_attrs_eq_p, set_mem_attributes_minus_bitpos, set_mem_offset)
(clear_mem_offset, set_mem_size, clear_mem_size, change_address)
(adjust_address_1, widen_memory_access, set_mem_attrs_for_spill)
(init_emit_regs): Likewise.
2011-07-19 Richard Sandiford <rdsandiford@googlemail.com>
* doc/rtl.texi (MEM_OFFSET_KNOWN_P): Document. * doc/rtl.texi (MEM_OFFSET_KNOWN_P): Document.
(MEM_OFFSET): Change from returning an rtx to returning a (MEM_OFFSET): Change from returning an rtx to returning a
HOST_WIDE_INT. HOST_WIDE_INT.
......
...@@ -256,8 +256,8 @@ mem_attrs_htab_hash (const void *x) ...@@ -256,8 +256,8 @@ mem_attrs_htab_hash (const void *x)
return (p->alias ^ (p->align * 1000) return (p->alias ^ (p->align * 1000)
^ (p->addrspace * 4000) ^ (p->addrspace * 4000)
^ ((p->offset ? INTVAL (p->offset) : 0) * 50000) ^ ((p->offset_known_p ? p->offset : 0) * 50000)
^ ((p->size ? INTVAL (p->size) : 0) * 2500000) ^ ((p->size_known_p ? p->size : 0) * 2500000)
^ (size_t) iterative_hash_expr (p->expr, 0)); ^ (size_t) iterative_hash_expr (p->expr, 0));
} }
...@@ -266,8 +266,12 @@ mem_attrs_htab_hash (const void *x) ...@@ -266,8 +266,12 @@ mem_attrs_htab_hash (const void *x)
static bool static bool
mem_attrs_eq_p (const struct mem_attrs *p, const struct mem_attrs *q) mem_attrs_eq_p (const struct mem_attrs *p, const struct mem_attrs *q)
{ {
return (p->alias == q->alias && p->offset == q->offset return (p->alias == q->alias
&& p->size == q->size && p->align == q->align && p->offset_known_p == q->offset_known_p
&& (!p->offset_known_p || p->offset == q->offset)
&& p->size_known_p == q->size_known_p
&& (!p->size_known_p || p->size == q->size)
&& p->align == q->align
&& p->addrspace == q->addrspace && p->addrspace == q->addrspace
&& (p->expr == q->expr && (p->expr == q->expr
|| (p->expr != NULL_TREE && q->expr != NULL_TREE || (p->expr != NULL_TREE && q->expr != NULL_TREE
...@@ -1585,7 +1589,9 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1585,7 +1589,9 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
/* ??? Can this ever happen? Calling this routine on a MEM that /* ??? Can this ever happen? Calling this routine on a MEM that
already carries memory attributes should probably be invalid. */ already carries memory attributes should probably be invalid. */
attrs.expr = refattrs->expr; attrs.expr = refattrs->expr;
attrs.offset_known_p = refattrs->offset_known_p;
attrs.offset = refattrs->offset; attrs.offset = refattrs->offset;
attrs.size_known_p = refattrs->size_known_p;
attrs.size = refattrs->size; attrs.size = refattrs->size;
attrs.align = refattrs->align; attrs.align = refattrs->align;
} }
...@@ -1595,9 +1601,10 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1595,9 +1601,10 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
{ {
defattrs = mode_mem_attrs[(int) GET_MODE (ref)]; defattrs = mode_mem_attrs[(int) GET_MODE (ref)];
gcc_assert (!defattrs->expr); gcc_assert (!defattrs->expr);
gcc_assert (!defattrs->offset); gcc_assert (!defattrs->offset_known_p);
/* Respect mode size. */ /* Respect mode size. */
attrs.size_known_p = defattrs->size_known_p;
attrs.size = defattrs->size; attrs.size = defattrs->size;
/* ??? Is this really necessary? We probably should always get /* ??? Is this really necessary? We probably should always get
the size from the type below. */ the size from the type below. */
...@@ -1656,7 +1663,10 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1656,7 +1663,10 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
/* If the size is known, we can set that. */ /* If the size is known, we can set that. */
if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1)) if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
attrs.size = GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1)); {
attrs.size_known_p = true;
attrs.size = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
}
/* If T is not a type, we may be able to deduce some more information about /* If T is not a type, we may be able to deduce some more information about
the expression. */ the expression. */
...@@ -1694,11 +1704,16 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1694,11 +1704,16 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
if (DECL_P (t)) if (DECL_P (t))
{ {
attrs.expr = t; attrs.expr = t;
attrs.offset = const0_rtx; attrs.offset_known_p = true;
attrs.offset = 0;
apply_bitpos = bitpos; apply_bitpos = bitpos;
attrs.size = (DECL_SIZE_UNIT (t) if (DECL_SIZE_UNIT (t) && host_integerp (DECL_SIZE_UNIT (t), 1))
&& host_integerp (DECL_SIZE_UNIT (t), 1) {
? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0); attrs.size_known_p = true;
attrs.size = tree_low_cst (DECL_SIZE_UNIT (t), 1);
}
else
attrs.size_known_p = false;
attrs.align = DECL_ALIGN (t); attrs.align = DECL_ALIGN (t);
align_computed = true; align_computed = true;
} }
...@@ -1721,7 +1736,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1721,7 +1736,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
&& ! DECL_BIT_FIELD (TREE_OPERAND (t, 1))) && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
{ {
attrs.expr = t; attrs.expr = t;
attrs.offset = const0_rtx; attrs.offset_known_p = true;
attrs.offset = 0;
apply_bitpos = bitpos; apply_bitpos = bitpos;
/* ??? Any reason the field size would be different than /* ??? Any reason the field size would be different than
the size we got from the type? */ the size we got from the type? */
...@@ -1762,7 +1778,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1762,7 +1778,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
if (DECL_P (t2)) if (DECL_P (t2))
{ {
attrs.expr = t2; attrs.expr = t2;
attrs.offset = NULL; attrs.offset_known_p = false;
if (host_integerp (off_tree, 1)) if (host_integerp (off_tree, 1))
{ {
HOST_WIDE_INT ioff = tree_low_cst (off_tree, 1); HOST_WIDE_INT ioff = tree_low_cst (off_tree, 1);
...@@ -1771,17 +1787,19 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1771,17 +1787,19 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
if (aoff && (unsigned HOST_WIDE_INT) aoff < attrs.align) if (aoff && (unsigned HOST_WIDE_INT) aoff < attrs.align)
attrs.align = aoff; attrs.align = aoff;
align_computed = true; align_computed = true;
attrs.offset = GEN_INT (ioff); attrs.offset_known_p = true;
attrs.offset = ioff;
apply_bitpos = bitpos; apply_bitpos = bitpos;
} }
} }
else if (TREE_CODE (t2) == COMPONENT_REF) else if (TREE_CODE (t2) == COMPONENT_REF)
{ {
attrs.expr = t2; attrs.expr = t2;
attrs.offset = NULL; attrs.offset_known_p = false;
if (host_integerp (off_tree, 1)) if (host_integerp (off_tree, 1))
{ {
attrs.offset = GEN_INT (tree_low_cst (off_tree, 1)); attrs.offset_known_p = true;
attrs.offset = tree_low_cst (off_tree, 1);
apply_bitpos = bitpos; apply_bitpos = bitpos;
} }
/* ??? Any reason the field size would be different than /* ??? Any reason the field size would be different than
...@@ -1792,7 +1810,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1792,7 +1810,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
else if (TREE_CODE (t) == MEM_REF) else if (TREE_CODE (t) == MEM_REF)
{ {
attrs.expr = t; attrs.expr = t;
attrs.offset = const0_rtx; attrs.offset_known_p = true;
attrs.offset = 0;
apply_bitpos = bitpos; apply_bitpos = bitpos;
} }
} }
...@@ -1802,7 +1821,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1802,7 +1821,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|| TREE_CODE (t) == TARGET_MEM_REF) || TREE_CODE (t) == TARGET_MEM_REF)
{ {
attrs.expr = t; attrs.expr = t;
attrs.offset = const0_rtx; attrs.offset_known_p = true;
attrs.offset = 0;
apply_bitpos = bitpos; apply_bitpos = bitpos;
} }
...@@ -1818,10 +1838,10 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1818,10 +1838,10 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
object to contain the negative offset. */ object to contain the negative offset. */
if (apply_bitpos) if (apply_bitpos)
{ {
attrs.offset = plus_constant (attrs.offset, gcc_assert (attrs.offset_known_p);
-(apply_bitpos / BITS_PER_UNIT)); attrs.offset -= apply_bitpos / BITS_PER_UNIT;
if (attrs.size) if (attrs.size_known_p)
attrs.size = plus_constant (attrs.size, apply_bitpos / BITS_PER_UNIT); attrs.size += apply_bitpos / BITS_PER_UNIT;
} }
/* Now set the attributes we computed above. */ /* Now set the attributes we computed above. */
...@@ -1903,7 +1923,8 @@ set_mem_offset (rtx mem, HOST_WIDE_INT offset) ...@@ -1903,7 +1923,8 @@ set_mem_offset (rtx mem, HOST_WIDE_INT offset)
struct mem_attrs attrs; struct mem_attrs attrs;
attrs = *get_mem_attrs (mem); attrs = *get_mem_attrs (mem);
attrs.offset = GEN_INT (offset); attrs.offset_known_p = true;
attrs.offset = offset;
set_mem_attrs (mem, &attrs); set_mem_attrs (mem, &attrs);
} }
...@@ -1915,7 +1936,7 @@ clear_mem_offset (rtx mem) ...@@ -1915,7 +1936,7 @@ clear_mem_offset (rtx mem)
struct mem_attrs attrs; struct mem_attrs attrs;
attrs = *get_mem_attrs (mem); attrs = *get_mem_attrs (mem);
attrs.offset = NULL_RTX; attrs.offset_known_p = false;
set_mem_attrs (mem, &attrs); set_mem_attrs (mem, &attrs);
} }
...@@ -1927,7 +1948,8 @@ set_mem_size (rtx mem, HOST_WIDE_INT size) ...@@ -1927,7 +1948,8 @@ set_mem_size (rtx mem, HOST_WIDE_INT size)
struct mem_attrs attrs; struct mem_attrs attrs;
attrs = *get_mem_attrs (mem); attrs = *get_mem_attrs (mem);
attrs.size = GEN_INT (size); attrs.size_known_p = true;
attrs.size = size;
set_mem_attrs (mem, &attrs); set_mem_attrs (mem, &attrs);
} }
...@@ -1939,7 +1961,7 @@ clear_mem_size (rtx mem) ...@@ -1939,7 +1961,7 @@ clear_mem_size (rtx mem)
struct mem_attrs attrs; struct mem_attrs attrs;
attrs = *get_mem_attrs (mem); attrs = *get_mem_attrs (mem);
attrs.size = NULL_RTX; attrs.size_known_p = false;
set_mem_attrs (mem, &attrs); set_mem_attrs (mem, &attrs);
} }
...@@ -1993,8 +2015,9 @@ change_address (rtx memref, enum machine_mode mode, rtx addr) ...@@ -1993,8 +2015,9 @@ change_address (rtx memref, enum machine_mode mode, rtx addr)
attrs = *get_mem_attrs (memref); attrs = *get_mem_attrs (memref);
defattrs = mode_mem_attrs[(int) mmode]; defattrs = mode_mem_attrs[(int) mmode];
attrs.expr = defattrs->expr; attrs.expr = NULL_TREE;
attrs.offset = defattrs->offset; attrs.offset_known_p = false;
attrs.size_known_p = defattrs->size_known_p;
attrs.size = defattrs->size; attrs.size = defattrs->size;
attrs.align = defattrs->align; attrs.align = defattrs->align;
...@@ -2076,8 +2099,8 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset, ...@@ -2076,8 +2099,8 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
/* Compute the new values of the memory attributes due to this adjustment. /* Compute the new values of the memory attributes due to this adjustment.
We add the offsets and update the alignment. */ We add the offsets and update the alignment. */
if (attrs.offset) if (attrs.offset_known_p)
attrs.offset = GEN_INT (offset + INTVAL (attrs.offset)); attrs.offset += offset;
/* Compute the new alignment by taking the MIN of the alignment and the /* Compute the new alignment by taking the MIN of the alignment and the
lowest-order set bit in OFFSET, but don't change the alignment if OFFSET lowest-order set bit in OFFSET, but don't change the alignment if OFFSET
...@@ -2090,10 +2113,13 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset, ...@@ -2090,10 +2113,13 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
/* We can compute the size in a number of ways. */ /* We can compute the size in a number of ways. */
defattrs = mode_mem_attrs[(int) GET_MODE (new_rtx)]; defattrs = mode_mem_attrs[(int) GET_MODE (new_rtx)];
if (defattrs->size) if (defattrs->size_known_p)
{
attrs.size_known_p = true;
attrs.size = defattrs->size; attrs.size = defattrs->size;
else if (attrs.size) }
attrs.size = plus_constant (attrs.size, -offset); else if (attrs.size_known_p)
attrs.size -= offset;
set_mem_attrs (new_rtx, &attrs); set_mem_attrs (new_rtx, &attrs);
...@@ -2124,7 +2150,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2) ...@@ -2124,7 +2150,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
{ {
rtx new_rtx, addr = XEXP (memref, 0); rtx new_rtx, addr = XEXP (memref, 0);
enum machine_mode address_mode; enum machine_mode address_mode;
struct mem_attrs attrs; struct mem_attrs attrs, *defattrs;
attrs = *get_mem_attrs (memref); attrs = *get_mem_attrs (memref);
address_mode = targetm.addr_space.address_mode (attrs.addrspace); address_mode = targetm.addr_space.address_mode (attrs.addrspace);
...@@ -2155,8 +2181,10 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2) ...@@ -2155,8 +2181,10 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
/* Update the alignment to reflect the offset. Reset the offset, which /* Update the alignment to reflect the offset. Reset the offset, which
we don't know. */ we don't know. */
attrs.offset = 0; defattrs = mode_mem_attrs[(int) GET_MODE (new_rtx)];
attrs.size = mode_mem_attrs[(int) GET_MODE (new_rtx)]->size; attrs.offset_known_p = false;
attrs.size_known_p = defattrs->size_known_p;
attrs.size = defattrs->size;
attrs.align = MIN (attrs.align, pow2 * BITS_PER_UNIT); attrs.align = MIN (attrs.align, pow2 * BITS_PER_UNIT);
set_mem_attrs (new_rtx, &attrs); set_mem_attrs (new_rtx, &attrs);
return new_rtx; return new_rtx;
...@@ -2204,7 +2232,7 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset) ...@@ -2204,7 +2232,7 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
/* If we don't know what offset we were at within the expression, then /* If we don't know what offset we were at within the expression, then
we can't know if we've overstepped the bounds. */ we can't know if we've overstepped the bounds. */
if (! attrs.offset) if (! attrs.offset_known_p)
attrs.expr = NULL_TREE; attrs.expr = NULL_TREE;
while (attrs.expr) while (attrs.expr)
...@@ -2224,7 +2252,7 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset) ...@@ -2224,7 +2252,7 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
otherwise strip back to the containing structure. */ otherwise strip back to the containing structure. */
if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST
&& compare_tree_int (DECL_SIZE_UNIT (field), size) >= 0 && compare_tree_int (DECL_SIZE_UNIT (field), size) >= 0
&& INTVAL (attrs.offset) >= 0) && attrs.offset >= 0)
break; break;
if (! host_integerp (offset, 1)) if (! host_integerp (offset, 1))
...@@ -2234,18 +2262,16 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset) ...@@ -2234,18 +2262,16 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
} }
attrs.expr = TREE_OPERAND (attrs.expr, 0); attrs.expr = TREE_OPERAND (attrs.expr, 0);
attrs.offset attrs.offset += tree_low_cst (offset, 1);
= (GEN_INT (INTVAL (attrs.offset) attrs.offset += (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
+ tree_low_cst (offset, 1) / BITS_PER_UNIT);
+ (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
/ BITS_PER_UNIT)));
} }
/* Similarly for the decl. */ /* Similarly for the decl. */
else if (DECL_P (attrs.expr) else if (DECL_P (attrs.expr)
&& DECL_SIZE_UNIT (attrs.expr) && DECL_SIZE_UNIT (attrs.expr)
&& TREE_CODE (DECL_SIZE_UNIT (attrs.expr)) == INTEGER_CST && TREE_CODE (DECL_SIZE_UNIT (attrs.expr)) == INTEGER_CST
&& compare_tree_int (DECL_SIZE_UNIT (attrs.expr), size) >= 0 && compare_tree_int (DECL_SIZE_UNIT (attrs.expr), size) >= 0
&& (! attrs.offset || INTVAL (attrs.offset) >= 0)) && (! attrs.offset_known_p || attrs.offset >= 0))
break; break;
else else
{ {
...@@ -2257,12 +2283,13 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset) ...@@ -2257,12 +2283,13 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
} }
if (! attrs.expr) if (! attrs.expr)
attrs.offset = NULL_RTX; attrs.offset_known_p = false;
/* The widened memory may alias other stuff, so zap the alias set. */ /* The widened memory may alias other stuff, so zap the alias set. */
/* ??? Maybe use get_alias_set on any remaining expression. */ /* ??? Maybe use get_alias_set on any remaining expression. */
attrs.alias = 0; attrs.alias = 0;
attrs.size = GEN_INT (size); attrs.size_known_p = true;
attrs.size = size;
set_mem_attrs (new_rtx, &attrs); set_mem_attrs (new_rtx, &attrs);
return new_rtx; return new_rtx;
} }
...@@ -2319,10 +2346,11 @@ set_mem_attrs_for_spill (rtx mem) ...@@ -2319,10 +2346,11 @@ set_mem_attrs_for_spill (rtx mem)
(mem:MODE (plus (reg sfp) (const_int offset))) (mem:MODE (plus (reg sfp) (const_int offset)))
with perhaps the plus missing for offset = 0. */ with perhaps the plus missing for offset = 0. */
addr = XEXP (mem, 0); addr = XEXP (mem, 0);
attrs.offset = const0_rtx; attrs.offset_known_p = true;
attrs.offset = 0;
if (GET_CODE (addr) == PLUS if (GET_CODE (addr) == PLUS
&& CONST_INT_P (XEXP (addr, 1))) && CONST_INT_P (XEXP (addr, 1)))
attrs.offset = XEXP (addr, 1); attrs.offset = INTVAL (XEXP (addr, 1));
set_mem_attrs (mem, &attrs); set_mem_attrs (mem, &attrs);
MEM_NOTRAP_P (mem) = 1; MEM_NOTRAP_P (mem) = 1;
...@@ -5522,7 +5550,8 @@ init_emit_regs (void) ...@@ -5522,7 +5550,8 @@ init_emit_regs (void)
attrs->addrspace = ADDR_SPACE_GENERIC; attrs->addrspace = ADDR_SPACE_GENERIC;
if (mode != BLKmode) if (mode != BLKmode)
{ {
attrs->size = GEN_INT (GET_MODE_SIZE (mode)); attrs->size_known_p = true;
attrs->size = GET_MODE_SIZE (mode);
if (STRICT_ALIGNMENT) if (STRICT_ALIGNMENT)
attrs->align = GET_MODE_ALIGNMENT (mode); attrs->align = GET_MODE_ALIGNMENT (mode);
} }
......
...@@ -136,19 +136,38 @@ typedef struct ...@@ -136,19 +136,38 @@ typedef struct
/* Structure used to describe the attributes of a MEM. These are hashed /* Structure used to describe the attributes of a MEM. These are hashed
so MEMs that the same attributes share a data structure. This means so MEMs that the same attributes share a data structure. This means
they cannot be modified in place. If any element is nonzero, it means they cannot be modified in place. */
the value of the corresponding attribute is unknown. */
/* ALIGN and SIZE are the alignment and size of the MEM itself,
while EXPR can describe a larger underlying object, which might have a
stricter alignment; OFFSET is the offset of the MEM within that object. */
typedef struct GTY(()) mem_attrs typedef struct GTY(()) mem_attrs
{ {
tree expr; /* expr corresponding to MEM. */ /* The expression that the MEM accesses, or null if not known.
rtx offset; /* Offset from start of DECL, as CONST_INT. */ This expression might be larger than the memory reference itself.
rtx size; /* Size in bytes, as a CONST_INT. */ (In other words, the MEM might access only part of the object.) */
alias_set_type alias; /* Memory alias set. */ tree expr;
unsigned int align; /* Alignment of MEM in bits. */
unsigned char addrspace; /* Address space (0 for generic). */ /* The offset of the memory reference from the start of EXPR.
Only valid if OFFSET_KNOWN_P. */
HOST_WIDE_INT offset;
/* The size of the memory reference in bytes. Only valid if
SIZE_KNOWN_P. */
HOST_WIDE_INT size;
/* The alias set of the memory reference. */
alias_set_type alias;
/* The alignment of the reference in bits. Always a multiple of
BITS_PER_UNIT. Note that EXPR may have a stricter alignment
than the memory reference itself. */
unsigned int align;
/* The address space that the memory reference uses. */
unsigned char addrspace;
/* True if OFFSET is known. */
bool offset_known_p;
/* True if SIZE is known. */
bool size_known_p;
} mem_attrs; } mem_attrs;
/* Structure used to describe the attributes of a REG in similar way as /* Structure used to describe the attributes of a REG in similar way as
...@@ -1303,19 +1322,19 @@ do { \ ...@@ -1303,19 +1322,19 @@ do { \
#define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr) #define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr)
/* For a MEM rtx, true if its MEM_OFFSET is known. */ /* For a MEM rtx, true if its MEM_OFFSET is known. */
#define MEM_OFFSET_KNOWN_P(RTX) (get_mem_attrs (RTX)->offset != NULL_RTX) #define MEM_OFFSET_KNOWN_P(RTX) (get_mem_attrs (RTX)->offset_known_p)
/* For a MEM rtx, the offset from the start of MEM_EXPR. */ /* For a MEM rtx, the offset from the start of MEM_EXPR. */
#define MEM_OFFSET(RTX) INTVAL (get_mem_attrs (RTX)->offset) #define MEM_OFFSET(RTX) (get_mem_attrs (RTX)->offset)
/* For a MEM rtx, the address space. */ /* For a MEM rtx, the address space. */
#define MEM_ADDR_SPACE(RTX) (get_mem_attrs (RTX)->addrspace) #define MEM_ADDR_SPACE(RTX) (get_mem_attrs (RTX)->addrspace)
/* For a MEM rtx, true if its MEM_SIZE is known. */ /* For a MEM rtx, true if its MEM_SIZE is known. */
#define MEM_SIZE_KNOWN_P(RTX) (get_mem_attrs (RTX)->size != NULL_RTX) #define MEM_SIZE_KNOWN_P(RTX) (get_mem_attrs (RTX)->size_known_p)
/* For a MEM rtx, the size in bytes of the MEM. */ /* For a MEM rtx, the size in bytes of the MEM. */
#define MEM_SIZE(RTX) INTVAL (get_mem_attrs (RTX)->size) #define MEM_SIZE(RTX) (get_mem_attrs (RTX)->size)
/* For a MEM rtx, the alignment in bits. We can use the alignment of the /* For a MEM rtx, the alignment in bits. We can use the alignment of the
mode as a default when STRICT_ALIGNMENT, but not if not. */ mode as a default when STRICT_ALIGNMENT, but not if not. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment