#include "real.h"
#include "toplev.h"
#include "except.h"
+#include "tree.h"
/* This file contains the reload pass of the compiler, which is
run after register allocation has been done. It checks that
i = REGNO (SET_DEST (set));
if (i > LAST_VIRTUAL_REGISTER)
{
- if (GET_CODE (x) == MEM)
+ /* It can happen that a REG_EQUIV note contains a MEM
+ that is not a legitimate memory operand. As later
+ stages of reload assume that all addresses found
+ in the reg_equiv_* arrays were originally legitimate,
+ we ignore such REG_EQUIV notes. */
+ if (memory_operand (x, VOIDmode))
{
/* Always unshare the equivalence, so we can
substitute into this insn without touching the
{
rtx reg = regno_reg_rtx[i];
+ REG_USERVAR_P (reg) = 0;
PUT_CODE (reg, MEM);
XEXP (reg, 0) = addr;
- REG_USERVAR_P (reg) = 0;
if (reg_equiv_memory_loc[i])
MEM_COPY_ATTRIBUTES (reg, reg_equiv_memory_loc[i]);
else
memory. If this is a shared MEM, make a copy. */
if (REGNO_DECL (i))
{
- if (from_reg != -1 && spill_stack_slot[from_reg] == x)
- x = copy_rtx (x);
+ rtx decl = DECL_RTL_IF_SET (REGNO_DECL (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 && GET_CODE (decl) == REG && REGNO (decl) == (unsigned) i)
+ {
+ if (from_reg != -1 && spill_stack_slot[from_reg] == x)
+ x = copy_rtx (x);
- set_mem_expr (x, REGNO_DECL (i));
+ set_mem_expr (x, REGNO_DECL (i));
+ }
}
/* Save the stack slot for later. */
)
|| x_size == new_size)
)
- return adjust_address_nv (x, GET_MODE (x), SUBREG_BYTE (x));
+ return adjust_address_nv (new, GET_MODE (x), SUBREG_BYTE (x));
else
return gen_rtx_SUBREG (GET_MODE (x), new, SUBREG_BYTE (x));
}
&& ! TEST_HARD_REG_BIT (reg_reloaded_dead, i))
/* Don't clobber the frame pointer. */
|| (i == HARD_FRAME_POINTER_REGNUM
+ && frame_pointer_needed
&& rld[r].out)
/* Don't really use the inherited spill reg
if we need it wider than we've got it. */
/* If we found an equivalent reg, say no code need be generated
to load it, and use it as our reload reg. */
- if (equiv != 0 && regno != HARD_FRAME_POINTER_REGNUM)
+ if (equiv != 0
+ && (regno != HARD_FRAME_POINTER_REGNUM
+ || !frame_pointer_needed))
{
int nr = HARD_REGNO_NREGS (regno, rld[r].mode);
int k;
reload_cse_delete_noop_set (insn, value)
rtx insn, value;
{
+ bool purge = BLOCK_FOR_INSN (insn)->end == insn;
if (value)
{
PATTERN (insn) = gen_rtx_USE (VOIDmode, value);
}
else
delete_insn (insn);
+ if (purge)
+ purge_dead_edges (BLOCK_FOR_INSN (insn));
}
/* See whether a single set SET is a noop. */
if (!count && reload_cse_noop_set_p (body))
{
rtx value = SET_DEST (body);
- if (! REG_FUNCTION_VALUE_P (SET_DEST (body)))
+ if (GET_CODE (body) == REG
+ && ! REG_FUNCTION_VALUE_P (SET_DEST (body)))
value = 0;
reload_cse_delete_noop_set (insn, value);
return;
next = NEXT_INSN (insn);
if (INSN_P (insn))
{
- insert_insn_on_edge (PATTERN (insn), e);
+ rtx seq;
+
delete_insn (insn);
+
+ /* We're not deleting it, we're moving it. */
+ INSN_DELETED_P (insn) = 0;
+
+ /* Emit a sequence, rather than scarfing the pattern, so
+ that we don't lose REG_NOTES etc. */
+ /* ??? Could copy the test from gen_sequence, but don't
+ think it's worth the bother. */
+ seq = gen_rtx_SEQUENCE (VOIDmode, gen_rtvec (1, insn));
+ insert_insn_on_edge (seq, e);
}
insn = next;
}