From c8f5fc7032940ad6633f932ac40cade82ec4d0cc Mon Sep 17 00:00:00 2001 From: obrien Date: Thu, 9 May 2002 20:02:13 +0000 Subject: Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT. --- contrib/gcc/reload1.c | 58 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 9 deletions(-) (limited to 'contrib/gcc/reload1.c') 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; } -- cgit v1.1