aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2008-10-12 13:26:24 -0700
committerRichard Henderson <rth@gcc.gnu.org>2008-10-12 13:26:24 -0700
commitf6129d66bce280604f349fe2144ae5649964a476 (patch)
treebbec7b5c162660943ed96247083662af72606da7 /gcc
parentdc8bd8d973f962ff4ea11f455e0daf398aa8d732 (diff)
downloadgcc-f6129d66bce280604f349fe2144ae5649964a476.zip
gcc-f6129d66bce280604f349fe2144ae5649964a476.tar.gz
gcc-f6129d66bce280604f349fe2144ae5649964a476.tar.bz2
re PR middle-end/37447 (test pr28982b.c fails execution on power4 or later with ira change)
PR middle-end/37447 * Makefile.in (reload1.o): Depend on EMIT_RTL_H. * alias.c (value_addr_p, stack_addr_p): Remove. (nonoverlapping_memrefs_p): Remove IRA special case. * emit-rtl.c (get_spill_slot_decl, set_mem_attrs_for_spill): New. * emit-rtl.h (set_mem_attrs_for_spill): Declare. * reload1.c (alter_reg): Use it. From-SVN: r141077
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/alias.c46
-rw-r--r--gcc/emit-rtl.c59
-rw-r--r--gcc/emit-rtl.h3
-rw-r--r--gcc/reload1.c82
6 files changed, 94 insertions, 108 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a206cf..a7da214 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2008-10-12 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/37447
+ * Makefile.in (reload1.o): Depend on EMIT_RTL_H.
+ * alias.c (value_addr_p, stack_addr_p): Remove.
+ (nonoverlapping_memrefs_p): Remove IRA special case.
+ * emit-rtl.c (get_spill_slot_decl, set_mem_attrs_for_spill): New.
+ * emit-rtl.h (set_mem_attrs_for_spill): Declare.
+ * reload1.c (alter_reg): Use it.
+
2008-10-12 Uros Bizjak <ubizjak@gmail.com>
* config/i386/driver-i386.c (detect_caches_cpuid2): Use array
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f067a91..5cb1241 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2868,7 +2868,7 @@ reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
$(BASIC_BLOCK_H) $(RECOG_H) output.h $(FUNCTION_H) $(TOPLEV_H) $(TM_P_H) \
addresses.h except.h $(TREE_H) $(REAL_H) $(FLAGS_H) $(MACHMODE_H) \
- $(OBSTACK_H) $(DF_H) $(TARGET_H) dse.h ira.h
+ $(OBSTACK_H) $(DF_H) $(TARGET_H) $(EMIT_RTL_H) ira.h
rtlhooks.o : rtlhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
rtlhooks-def.h $(EXPR_H) $(RECOG_H)
postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
diff --git a/gcc/alias.c b/gcc/alias.c
index 1135489..4cadb6b 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1983,34 +1983,6 @@ adjust_offset_for_component_ref (tree x, rtx offset)
return GEN_INT (ioffset);
}
-/* The function returns nonzero if X is an address containg VALUE. */
-static int
-value_addr_p (rtx x)
-{
- if (GET_CODE (x) == VALUE)
- return 1;
- if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == VALUE)
- return 1;
- return 0;
-}
-
-/* The function returns nonzero if X is a stack address. */
-static int
-stack_addr_p (rtx x)
-{
- if (x == hard_frame_pointer_rtx || x == frame_pointer_rtx
- || x == arg_pointer_rtx || x == stack_pointer_rtx)
- return 1;
- if (GET_CODE (x) == PLUS
- && (XEXP (x, 0) == hard_frame_pointer_rtx
- || XEXP (x, 0) == frame_pointer_rtx
- || XEXP (x, 0) == arg_pointer_rtx
- || XEXP (x, 0) == stack_pointer_rtx)
- && CONSTANT_P (XEXP (x, 1)))
- return 1;
- return 0;
-}
-
/* Return nonzero if we can determine the exprs corresponding to memrefs
X and Y and they do not overlap. */
@@ -2020,27 +1992,9 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y)
tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
rtx rtlx, rtly;
rtx basex, basey;
- rtx x_addr, y_addr;
rtx moffsetx, moffsety;
HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey, tem;
- if (flag_ira && optimize && reload_completed)
- {
- /* We need this code for IRA because of stack slot sharing. RTL
- in decl can be different than RTL used in insns. It is a
- safe code although it can be conservative sometime. */
- x_addr = canon_rtx (get_addr (XEXP (x, 0)));
- y_addr = canon_rtx (get_addr (XEXP (y, 0)));
-
- if (value_addr_p (x_addr) || value_addr_p (y_addr))
- return 0;
-
- if (stack_addr_p (x_addr) && stack_addr_p (y_addr)
- && memrefs_conflict_p (SIZE_FOR_MODE (y), y_addr,
- SIZE_FOR_MODE (x), x_addr, 0))
- return 0;
- }
-
/* Unless both have exprs, we can't tell anything. */
if (exprx == 0 || expry == 0)
return 0;
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 4564a0b..46fefda 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -2138,6 +2138,65 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
return new_rtx;
}
+/* A fake decl that is used as the MEM_EXPR of spill slots. */
+static GTY(()) tree spill_slot_decl;
+
+static tree
+get_spill_slot_decl (void)
+{
+ tree d = spill_slot_decl;
+ rtx rd;
+
+ if (d)
+ return d;
+
+ d = build_decl (VAR_DECL, get_identifier ("%sfp"), void_type_node);
+ DECL_ARTIFICIAL (d) = 1;
+ DECL_IGNORED_P (d) = 1;
+ TREE_USED (d) = 1;
+ TREE_THIS_NOTRAP (d) = 1;
+ spill_slot_decl = d;
+
+ rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
+ MEM_NOTRAP_P (rd) = 1;
+ MEM_ATTRS (rd) = get_mem_attrs (new_alias_set (), d, const0_rtx,
+ NULL_RTX, 0, BLKmode);
+ SET_DECL_RTL (d, rd);
+
+ return d;
+}
+
+/* Given MEM, a result from assign_stack_local, fill in the memory
+ attributes as appropriate for a register allocator spill slot.
+ These slots are not aliasable by other memory. We arrange for
+ them all to use a single MEM_EXPR, so that the aliasing code can
+ work properly in the case of shared spill slots. */
+
+void
+set_mem_attrs_for_spill (rtx mem)
+{
+ alias_set_type alias;
+ rtx addr, offset;
+ tree expr;
+
+ expr = get_spill_slot_decl ();
+ alias = MEM_ALIAS_SET (DECL_RTL (expr));
+
+ /* We expect the incoming memory to be of the form:
+ (mem:MODE (plus (reg sfp) (const_int offset)))
+ with perhaps the plus missing for offset = 0. */
+ addr = XEXP (mem, 0);
+ offset = const0_rtx;
+ if (GET_CODE (addr) == PLUS
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ offset = XEXP (addr, 1);
+
+ MEM_ATTRS (mem) = get_mem_attrs (alias, expr, offset,
+ MEM_SIZE (mem), MEM_ALIGN (mem),
+ GET_MODE (mem));
+ MEM_NOTRAP_P (mem) = 1;
+}
+
/* Return a newly created CODE_LABEL rtx with a unique label number. */
rtx
diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h
index 32f5c91..6d4249f 100644
--- a/gcc/emit-rtl.h
+++ b/gcc/emit-rtl.h
@@ -35,6 +35,9 @@ extern void set_mem_offset (rtx, rtx);
/* Set the size for MEM to SIZE. */
extern void set_mem_size (rtx, rtx);
+/* Set the attributes for MEM appropriate for a spill slot. */
+extern void set_mem_attrs_for_spill (rtx);
+
/* Return a memory reference like MEMREF, but with its address changed to
ADDR. The caller is asserting that the actual piece of memory pointed
to is the same, just the form of the address is being changed, such as
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 684f859..76175e3 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "ira.h"
#include "df.h"
#include "target.h"
-#include "dse.h"
+#include "emit-rtl.h"
/* This file contains the reload pass of the compiler, which is
run after register allocation has been done. It checks that
@@ -2150,22 +2150,25 @@ alter_reg (int i, int from_reg, bool dont_share_p)
&& (reg_equiv_invariant[i] == 0 || reg_equiv_init[i] == 0)
&& reg_equiv_memory_loc[i] == 0)
{
- rtx x;
+ rtx x = NULL_RTX;
enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
unsigned int inherent_size = PSEUDO_REGNO_BYTES (i);
unsigned int inherent_align = GET_MODE_ALIGNMENT (mode);
unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);
unsigned int min_align = reg_max_ref_width[i] * BITS_PER_UNIT;
int adjust = 0;
- bool shared_p = false;
if (flag_ira && optimize)
- /* Mark the spill for IRA. */
- SET_REGNO_REG_SET (&spilled_pseudos, i);
- x = (dont_share_p || ! flag_ira || ! optimize
- ? NULL_RTX : ira_reuse_stack_slot (i, inherent_size, total_size));
+ {
+ /* Mark the spill for IRA. */
+ SET_REGNO_REG_SET (&spilled_pseudos, i);
+ if (!dont_share_p)
+ x = ira_reuse_stack_slot (i, inherent_size, total_size);
+ }
+
if (x)
- shared_p = true;
+ ;
+
/* Each pseudo reg has an inherent size which comes from its own mode,
and a total size which provides room for paradoxical subregs
which refer to the pseudo reg in wider modes.
@@ -2174,10 +2177,9 @@ alter_reg (int i, int from_reg, bool dont_share_p)
enough inherent space and enough total space.
Otherwise, we allocate a new slot, making sure that it has no less
inherent space, and no less total space, then the previous slot. */
- else if (from_reg == -1 || (! dont_share_p && flag_ira && optimize))
+ else if (from_reg == -1 || (!dont_share_p && flag_ira && optimize))
{
rtx stack_slot;
- alias_set_type alias_set = new_alias_set ();
/* No known place to spill from => no slot to reuse. */
x = assign_stack_local (mode, total_size,
@@ -2186,12 +2188,11 @@ alter_reg (int i, int from_reg, bool dont_share_p)
stack_slot = x;
+ /* Cancel the big-endian correction done in assign_stack_local.
+ Get the address of the beginning of the slot. This is so we
+ can do a big-endian correction unconditionally below. */
if (BYTES_BIG_ENDIAN)
{
- /* Cancel the big-endian correction done in assign_stack_local.
- Get the address of the beginning of the slot.
- This is so we can do a big-endian correction unconditionally
- below. */
adjust = inherent_size - total_size;
if (adjust)
stack_slot
@@ -2201,10 +2202,6 @@ alter_reg (int i, int from_reg, bool dont_share_p)
adjust);
}
- /* Nothing can alias this slot except this pseudo. */
- set_mem_alias_set (x, alias_set);
- dse_record_singleton_alias_set (alias_set, mode);
-
if (! dont_share_p && flag_ira && optimize)
/* Inform IRA about allocation a new stack slot. */
ira_mark_new_stack_slot (stack_slot, i, total_size);
@@ -2217,6 +2214,7 @@ alter_reg (int i, int from_reg, bool dont_share_p)
>= inherent_size)
&& MEM_ALIGN (spill_stack_slot[from_reg]) >= min_align)
x = spill_stack_slot[from_reg];
+
/* Allocate a bigger slot. */
else
{
@@ -2241,27 +2239,11 @@ alter_reg (int i, int from_reg, bool dont_share_p)
|| total_size > inherent_size ? -1 : 0);
stack_slot = x;
- /* All pseudos mapped to this slot can alias each other. */
- if (spill_stack_slot[from_reg])
- {
- alias_set_type alias_set
- = MEM_ALIAS_SET (spill_stack_slot[from_reg]);
- set_mem_alias_set (x, alias_set);
- dse_invalidate_singleton_alias_set (alias_set);
- }
- else
- {
- alias_set_type alias_set = new_alias_set ();
- set_mem_alias_set (x, alias_set);
- dse_record_singleton_alias_set (alias_set, mode);
- }
-
+ /* Cancel the big-endian correction done in assign_stack_local.
+ Get the address of the beginning of the slot. This is so we
+ can do a big-endian correction unconditionally below. */
if (BYTES_BIG_ENDIAN)
{
- /* Cancel the big-endian correction done in assign_stack_local.
- Get the address of the beginning of the slot.
- This is so we can do a big-endian correction unconditionally
- below. */
adjust = GET_MODE_SIZE (mode) - total_size;
if (adjust)
stack_slot
@@ -2284,30 +2266,8 @@ alter_reg (int i, int from_reg, bool dont_share_p)
wrong mode, make a new stack slot. */
x = adjust_address_nv (x, GET_MODE (regno_reg_rtx[i]), adjust);
- /* If we have a decl for the original register, set it for the
- memory. If this is a shared MEM, make a copy. */
- if (shared_p)
- {
- x = copy_rtx (x);
- set_mem_attrs_from_reg (x, regno_reg_rtx[i]);
- }
- else if (REG_EXPR (regno_reg_rtx[i])
- && DECL_P (REG_EXPR (regno_reg_rtx[i])))
- {
- rtx decl = DECL_RTL_IF_SET (REG_EXPR (regno_reg_rtx[i]));
-
- /* We can do this only for the DECLs home pseudo, not for
- any copies of it, since otherwise when the stack slot
- is reused, nonoverlapping_memrefs_p might think they
- cannot overlap. */
- if (decl && REG_P (decl) && REGNO (decl) == (unsigned) i)
- {
- if (from_reg != -1 && spill_stack_slot[from_reg] == x)
- x = copy_rtx (x);
-
- set_mem_attrs_from_reg (x, regno_reg_rtx[i]);
- }
- }
+ /* Set all of the memory attributes as appropriate for a spill. */
+ set_mem_attrs_for_spill (x);
/* Save the stack slot for later. */
reg_equiv_memory_loc[i] = x;