Commit 5f2cbd0d by Richard Sandiford Committed by Richard Sandiford

expr.h (adjust_address_1): Add a size parameter.

gcc/
	* expr.h (adjust_address_1): Add a size parameter.
	(adjust_address, adjust_address_nv, adjust_bitfield_address)
	(adjust_bitfield_address_nv): Adjust accordingly.
	(adjust_bitfield_address_size): Define.
	* emit-rtl.c (adjust_address_1): Add a size parameter.
	Use it to set the size if MODE has no size.  Check whether
	the size matches before returning the original memref.
	Require the size to be known for adjust_object.
	(adjust_automodify_address_1, widen_memory_access): Update calls
	to adjust_address_1.

From-SVN: r193601
parent 6cf99649
2012-11-18 Richard Sandiford <rdsandiford@googlemail.com> 2012-11-18 Richard Sandiford <rdsandiford@googlemail.com>
* expr.h (adjust_address_1): Add a size parameter.
(adjust_address, adjust_address_nv, adjust_bitfield_address)
(adjust_bitfield_address_nv): Adjust accordingly.
(adjust_bitfield_address_size): Define.
* emit-rtl.c (adjust_address_1): Add a size parameter.
Use it to set the size if MODE has no size. Check whether
the size matches before returning the original memref.
Require the size to be known for adjust_object.
(adjust_automodify_address_1, widen_memory_access): Update calls
to adjust_address_1.
2012-11-18 Richard Sandiford <rdsandiford@googlemail.com>
* combine.c (make_extraction): Handle TRUNCATEd INNERs. * combine.c (make_extraction): Handle TRUNCATEd INNERs.
2012-11-18 Richard Sandiford <rdsandiford@googlemail.com> 2012-11-18 Richard Sandiford <rdsandiford@googlemail.com>
...@@ -2052,11 +2052,14 @@ change_address (rtx memref, enum machine_mode mode, rtx addr) ...@@ -2052,11 +2052,14 @@ change_address (rtx memref, enum machine_mode mode, rtx addr)
If ADJUST_OBJECT is zero, the underlying object associated with the If ADJUST_OBJECT is zero, the underlying object associated with the
memory reference is left unchanged and the caller is responsible for memory reference is left unchanged and the caller is responsible for
dealing with it. Otherwise, if the new memory reference is outside dealing with it. Otherwise, if the new memory reference is outside
the underlying object, even partially, then the object is dropped. */ the underlying object, even partially, then the object is dropped.
SIZE, if nonzero, is the size of an access in cases where MODE
has no inherent size. */
rtx rtx
adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset, adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
int validate, int adjust_address, int adjust_object) int validate, int adjust_address, int adjust_object,
HOST_WIDE_INT size)
{ {
rtx addr = XEXP (memref, 0); rtx addr = XEXP (memref, 0);
rtx new_rtx; rtx new_rtx;
...@@ -2069,8 +2072,14 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset, ...@@ -2069,8 +2072,14 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
= targetm.addr_space.pointer_mode (attrs.addrspace); = targetm.addr_space.pointer_mode (attrs.addrspace);
#endif #endif
/* Take the size of non-BLKmode accesses from the mode. */
defattrs = mode_mem_attrs[(int) mode];
if (defattrs->size_known_p)
size = defattrs->size;
/* If there are no changes, just return the original memory reference. */ /* If there are no changes, just return the original memory reference. */
if (mode == GET_MODE (memref) && !offset if (mode == GET_MODE (memref) && !offset
&& (size == 0 || (attrs.size_known_p && attrs.size == size))
&& (!validate || memory_address_addr_space_p (mode, addr, && (!validate || memory_address_addr_space_p (mode, addr,
attrs.addrspace))) attrs.addrspace)))
return memref; return memref;
...@@ -2155,24 +2164,23 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset, ...@@ -2155,24 +2164,23 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
attrs.align = MIN (attrs.align, max_align); attrs.align = MIN (attrs.align, max_align);
} }
/* We can compute the size in a number of ways. */ if (size)
defattrs = mode_mem_attrs[(int) GET_MODE (new_rtx)];
if (defattrs->size_known_p)
{ {
/* Drop the object if the new right end is not within its bounds. */ /* Drop the object if the new right end is not within its bounds. */
if (adjust_object && (offset + defattrs->size) > attrs.size) if (adjust_object && (offset + size) > attrs.size)
{ {
attrs.expr = NULL_TREE; attrs.expr = NULL_TREE;
attrs.alias = 0; attrs.alias = 0;
} }
attrs.size_known_p = true; attrs.size_known_p = true;
attrs.size = defattrs->size; attrs.size = size;
} }
else if (attrs.size_known_p) else if (attrs.size_known_p)
{ {
gcc_assert (!adjust_object);
attrs.size -= offset; attrs.size -= offset;
/* ??? The store_by_pieces machinery generates negative sizes. */ /* ??? The store_by_pieces machinery generates negative sizes,
gcc_assert (!(adjust_object && attrs.size < 0)); so don't assert for that here. */
} }
set_mem_attrs (new_rtx, &attrs); set_mem_attrs (new_rtx, &attrs);
...@@ -2190,7 +2198,7 @@ adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr, ...@@ -2190,7 +2198,7 @@ adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
HOST_WIDE_INT offset, int validate) HOST_WIDE_INT offset, int validate)
{ {
memref = change_address_1 (memref, VOIDmode, addr, validate); memref = change_address_1 (memref, VOIDmode, addr, validate);
return adjust_address_1 (memref, mode, offset, validate, 0, 0); return adjust_address_1 (memref, mode, offset, validate, 0, 0, 0);
} }
/* Return a memory reference like MEMREF, but whose address is changed by /* Return a memory reference like MEMREF, but whose address is changed by
...@@ -2272,7 +2280,7 @@ replace_equiv_address_nv (rtx memref, rtx addr) ...@@ -2272,7 +2280,7 @@ replace_equiv_address_nv (rtx memref, rtx addr)
rtx rtx
widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset) widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
{ {
rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1, 0); rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1, 0, 0);
struct mem_attrs attrs; struct mem_attrs attrs;
unsigned int size = GET_MODE_SIZE (mode); unsigned int size = GET_MODE_SIZE (mode);
......
...@@ -557,22 +557,27 @@ extern rtx change_address (rtx, enum machine_mode, rtx); ...@@ -557,22 +557,27 @@ extern rtx change_address (rtx, enum machine_mode, rtx);
/* Return a memory reference like MEMREF, but with its mode changed /* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address offset by OFFSET bytes. */ to MODE and its address offset by OFFSET bytes. */
#define adjust_address(MEMREF, MODE, OFFSET) \ #define adjust_address(MEMREF, MODE, OFFSET) \
adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 0) adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 0, 0)
/* Likewise, but the reference is not required to be valid. */ /* Likewise, but the reference is not required to be valid. */
#define adjust_address_nv(MEMREF, MODE, OFFSET) \ #define adjust_address_nv(MEMREF, MODE, OFFSET) \
adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 0) adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 0, 0)
/* Return a memory reference like MEMREF, but with its mode changed /* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address offset by OFFSET bytes. Assume that it's to MODE and its address offset by OFFSET bytes. Assume that it's
for a bitfield and conservatively drop the underlying object if we for a bitfield and conservatively drop the underlying object if we
cannot be sure to stay within its bounds. */ cannot be sure to stay within its bounds. */
#define adjust_bitfield_address(MEMREF, MODE, OFFSET) \ #define adjust_bitfield_address(MEMREF, MODE, OFFSET) \
adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1) adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, 0)
/* As for adjust_bitfield_address, but specify that the width of
BLKmode accesses is SIZE bytes. */
#define adjust_bitfield_address_size(MEMREF, MODE, OFFSET, SIZE) \
adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, SIZE)
/* Likewise, but the reference is not required to be valid. */ /* Likewise, but the reference is not required to be valid. */
#define adjust_bitfield_address_nv(MEMREF, MODE, OFFSET) \ #define adjust_bitfield_address_nv(MEMREF, MODE, OFFSET) \
adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 1) adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 1, 0)
/* Return a memory reference like MEMREF, but with its mode changed /* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address changed to ADDR, which is assumed to be to MODE and its address changed to ADDR, which is assumed to be
...@@ -585,7 +590,7 @@ extern rtx change_address (rtx, enum machine_mode, rtx); ...@@ -585,7 +590,7 @@ extern rtx change_address (rtx, enum machine_mode, rtx);
adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0) adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)
extern rtx adjust_address_1 (rtx, enum machine_mode, HOST_WIDE_INT, int, int, extern rtx adjust_address_1 (rtx, enum machine_mode, HOST_WIDE_INT, int, int,
int); int, HOST_WIDE_INT);
extern rtx adjust_automodify_address_1 (rtx, enum machine_mode, rtx, extern rtx adjust_automodify_address_1 (rtx, enum machine_mode, rtx,
HOST_WIDE_INT, int); HOST_WIDE_INT, int);
......
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