summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/reload1.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
committerobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
commitc8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch)
tree29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/reload1.c
parentc9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff)
downloadFreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.zip
FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.tar.gz
Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.
Diffstat (limited to 'contrib/gcc/reload1.c')
-rw-r--r--contrib/gcc/reload1.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/contrib/gcc/reload1.c b/contrib/gcc/reload1.c
index 5211b5f..d67bd1e 100644
--- a/contrib/gcc/reload1.c
+++ b/contrib/gcc/reload1.c
@@ -41,6 +41,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#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
@@ -459,7 +460,7 @@ static void failed_reload PARAMS ((rtx, int));
static int set_reload_reg PARAMS ((int, int));
static void reload_cse_delete_noop_set PARAMS ((rtx, rtx));
static void reload_cse_simplify PARAMS ((rtx));
-static void fixup_abnormal_edges PARAMS ((void));
+void fixup_abnormal_edges PARAMS ((void));
extern void dump_needs PARAMS ((struct insn_chain *));
/* Initialize the reload pass once per compilation. */
@@ -790,7 +791,12 @@ reload (first, global)
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
@@ -1278,6 +1284,11 @@ reload (first, global)
unused_insn_chains = 0;
fixup_abnormal_edges ();
+ /* Replacing pseudos with their memory equivalents might have
+ created shared rtx. Subsequent passes would get confused
+ by this, so unshare everything here. */
+ unshare_all_rtl_again (first);
+
return failure;
}
@@ -2057,10 +2068,19 @@ alter_reg (i, from_reg)
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. */
@@ -2282,6 +2302,7 @@ eliminate_regs (x, mem_mode, insn)
{
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case CODE_LABEL:
@@ -2552,7 +2573,7 @@ eliminate_regs (x, mem_mode, insn)
)
|| 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));
}
@@ -2660,6 +2681,7 @@ elimination_effects (x, mem_mode)
{
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case CODE_LABEL:
@@ -3749,6 +3771,7 @@ scan_paradoxical_subregs (x)
case SYMBOL_REF:
case LABEL_REF:
case CONST_DOUBLE:
+ case CONST_VECTOR: /* shouldn't happen, but just in case. */
case CC0:
case PC:
case USE:
@@ -5552,6 +5575,7 @@ choose_reload_regs (chain)
&& ! 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. */
@@ -5722,7 +5746,9 @@ choose_reload_regs (chain)
/* 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;
@@ -8011,6 +8037,7 @@ static void
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);
@@ -8019,6 +8046,8 @@ reload_cse_delete_noop_set (insn, value)
}
else
delete_insn (insn);
+ if (purge)
+ purge_dead_edges (BLOCK_FOR_INSN (insn));
}
/* See whether a single set SET is a noop. */
@@ -9457,7 +9486,7 @@ copy_eh_notes (insn, x)
proper call and fix the damage.
Similar handle instructions throwing exceptions internally. */
-static void
+void
fixup_abnormal_edges ()
{
int i;
@@ -9501,8 +9530,19 @@ fixup_abnormal_edges ()
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;
}
OpenPOWER on IntegriCloud