summaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-17 05:30:37 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-17 05:30:37 +0000
commit51d619308377f16a8ff13df95becfe2282198844 (patch)
tree21b147aea83b41c5c37fba84ea32c18f1c7de253 /gcc/emit-rtl.c
parent9b39d7e80300d4a7fc3399d0896881027479b72a (diff)
downloadgcc-51d619308377f16a8ff13df95becfe2282198844.tar.gz
2012-09-17 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 191371 using svnmerge. [gcc/] 2012-09-17 Basile Starynkevitch <basile@starynkevitch.net> {{when merging trunk svn rev 191371}} * melt-runtime.c (melt_load_module_index): Push an empty slot, not a null pointer, into melt_modinfvec. (meltgc_run_c_extension): Push an empty slot, not a null pointer, into melt_extinfvec. (melt_really_initialize): Better indentation, and increase maximal minore size to 32768Kwords. Push an empty slot, not a null pointer, into melt_modinfvec. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@191373 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 34d85de495f..f7639455909 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -2051,12 +2051,16 @@ change_address (rtx memref, enum machine_mode mode, rtx addr)
/* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address offset by OFFSET bytes. If VALIDATE is
nonzero, the memory address is forced to be valid.
- If ADJUST is zero, OFFSET is only used to update MEM_ATTRS
- and caller is responsible for adjusting MEMREF base register. */
+ If ADJUST_ADDRESS is zero, OFFSET is only used to update MEM_ATTRS
+ and the caller is responsible for adjusting MEMREF base register.
+ If ADJUST_OBJECT is zero, the underlying object associated with the
+ memory reference is left unchanged and the caller is responsible for
+ dealing with it. Otherwise, if the new memory reference is outside
+ the underlying object, even partially, then the object is dropped. */
rtx
adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
- int validate, int adjust)
+ int validate, int adjust_address, int adjust_object)
{
rtx addr = XEXP (memref, 0);
rtx new_rtx;
@@ -2089,7 +2093,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
>> shift);
}
- if (adjust)
+ if (adjust_address)
{
/* If MEMREF is a LO_SUM and the offset is within the alignment of the
object, we can merge it into the LO_SUM. */
@@ -2111,10 +2115,26 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
if (new_rtx == memref && offset != 0)
new_rtx = copy_rtx (new_rtx);
+ /* Conservatively drop the object if we don't know where we start from. */
+ if (adjust_object && (!attrs.offset_known_p || !attrs.size_known_p))
+ {
+ attrs.expr = NULL_TREE;
+ attrs.alias = 0;
+ }
+
/* Compute the new values of the memory attributes due to this adjustment.
We add the offsets and update the alignment. */
if (attrs.offset_known_p)
- attrs.offset += offset;
+ {
+ attrs.offset += offset;
+
+ /* Drop the object if the new left end is not within its bounds. */
+ if (adjust_object && attrs.offset < 0)
+ {
+ attrs.expr = NULL_TREE;
+ attrs.alias = 0;
+ }
+ }
/* 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
@@ -2129,16 +2149,24 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
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. */
+ if (adjust_object && (offset + defattrs->size) > attrs.size)
+ {
+ attrs.expr = NULL_TREE;
+ attrs.alias = 0;
+ }
attrs.size_known_p = true;
attrs.size = defattrs->size;
}
else if (attrs.size_known_p)
- attrs.size -= offset;
+ {
+ attrs.size -= offset;
+ /* ??? The store_by_pieces machinery generates negative sizes. */
+ gcc_assert (!(adjust_object && attrs.size < 0));
+ }
set_mem_attrs (new_rtx, &attrs);
- /* At some point, we should validate that this offset is within the object,
- if all the appropriate values are known. */
return new_rtx;
}
@@ -2152,7 +2180,7 @@ 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);
- return adjust_address_1 (memref, mode, offset, validate, 0);
+ return adjust_address_1 (memref, mode, offset, validate, 0, 0);
}
/* Return a memory reference like MEMREF, but whose address is changed by
@@ -2234,7 +2262,7 @@ replace_equiv_address_nv (rtx memref, rtx addr)
rtx
widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
{
- rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1);
+ rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1, 0);
struct mem_attrs attrs;
unsigned int size = GET_MODE_SIZE (mode);
@@ -6004,7 +6032,7 @@ curr_insn_locator (void)
{
curr_rtl_loc++;
VEC_safe_push (int, heap, locations_locators_locs, curr_rtl_loc);
- VEC_safe_push (location_t, heap, locations_locators_vals, &curr_location);
+ VEC_safe_push (location_t, heap, locations_locators_vals, curr_location);
last_location = curr_location;
}
return curr_rtl_loc;