/* Emit RTL for the GCC expander.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
/* Set the REG_ATTRS for registers in value X, given that X represents
decl T. */
-static void
+void
set_reg_attrs_for_decl_rtl (tree t, rtx x)
{
if (GET_CODE (x) == SUBREG)
inner = NULL_TREE;
}
- if (inner == TREE_OPERAND (ref, 0))
+ if (inner == TREE_OPERAND (ref, 0)
+ /* Don't leak SSA-names in the third operand. */
+ && (!TREE_OPERAND (ref, 2)
+ || TREE_CODE (TREE_OPERAND (ref, 2)) != SSA_NAME))
return ref;
else
return build3 (COMPONENT_REF, TREE_TYPE (ref), inner,
-1 if not known. */
int
-get_mem_align_offset (rtx mem, int align)
+get_mem_align_offset (rtx mem, unsigned int align)
{
tree expr;
unsigned HOST_WIDE_INT offset;
set_mem_attributes_minus_bitpos (ref, t, objectp, 0);
}
-/* Set MEM to the decl that REG refers to. */
-
-void
-set_mem_attrs_from_reg (rtx mem, rtx reg)
-{
- MEM_ATTRS (mem)
- = get_mem_attrs (MEM_ALIAS_SET (mem), REG_EXPR (reg),
- GEN_INT (REG_OFFSET (reg)),
- MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
-}
-
/* Set the alias set of MEM to SET. */
void
rtx memoffset = MEM_OFFSET (memref);
rtx size = 0;
unsigned int memalign = MEM_ALIGN (memref);
+ int pbits;
/* If there are no changes, just return the original memory reference. */
if (mode == GET_MODE (memref) && !offset
(plus (plus reg reg) const_int) -- so do this always. */
addr = copy_rtx (addr);
+ /* Convert a possibly large offset to a signed value within the
+ range of the target address space. */
+ pbits = GET_MODE_BITSIZE (Pmode);
+ if (HOST_BITS_PER_WIDE_INT > pbits)
+ {
+ int shift = HOST_BITS_PER_WIDE_INT - pbits;
+ offset = (((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) offset << shift))
+ >> shift);
+ }
+
if (adjust)
{
/* If MEMREF is a LO_SUM and the offset is within the alignment of the
new_rtx = change_address_1 (memref, mode, addr, validate);
+ /* If the address is a REG, change_address_1 rightfully returns memref,
+ but this would destroy memref's MEM_ATTRS. */
+ if (new_rtx == memref && offset != 0)
+ new_rtx = copy_rtx (new_rtx);
+
/* Compute the new values of the memory attributes due to this adjustment.
We add the offsets and update the alignment. */
if (memoffset)
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
- 0, /* tv_id */
+ TV_NONE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */