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
This commit is contained in:
parent
dc8bd8d973
commit
f6129d66bc
6 changed files with 94 additions and 108 deletions
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
46
gcc/alias.c
46
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue