diff options
author | Jim Wilson <wilson@cygnus.com> | 1997-09-02 21:40:31 +0000 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1997-09-02 14:40:31 -0700 |
commit | a172951945776ac4033b7e9f63070f48da8eaf74 (patch) | |
tree | 969de79a6e26ab0230a130085da738fc62913631 /gcc | |
parent | 37dac03995186a0404c5f17a39d69c8bb248dfc9 (diff) | |
download | gcc-a172951945776ac4033b7e9f63070f48da8eaf74.zip gcc-a172951945776ac4033b7e9f63070f48da8eaf74.tar.gz gcc-a172951945776ac4033b7e9f63070f48da8eaf74.tar.bz2 |
Fix i386 code generation error reported by Mumit Khan.
* local-alloc.c (contains_replace_regs): New function.
(update_equiv_regs): When adding a REG_EQUIV note for a set of a MEM,
verify that there is no existing REG_EQUIV note, and add a call to
contains_place_regs.
From-SVN: r15041
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/local-alloc.c | 61 |
2 files changed, 67 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 94b8962..d982628 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Tue Sep 2 14:22:43 1997 Jim Wilson <wilson@cygnus.com> + + * local-alloc.c (contains_replace_regs): New function. + (update_equiv_regs): When adding a REG_EQUIV note for a set of a MEM, + verify that there is no existing REG_EQUIV note, and add a call to + contains_place_regs. + Tue Sep 2 12:48:11 1997 H.J. Lu (hjl@gnu.ai.mit.edu) * config/alpha/elf.h (CPP_PREDEFINES): Add -D__PIC__ -D__pic__. diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index 677801e..7a3e103 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -246,6 +246,7 @@ static void alloc_qty PROTO((int, enum machine_mode, int, int)); static void alloc_qty_for_scratch PROTO((rtx, int, rtx, int, int)); static void validate_equiv_mem_from_store PROTO((rtx, rtx)); static int validate_equiv_mem PROTO((rtx, rtx, rtx)); +static int contains_replace_regs PROTO((rtx, char *)); static int memref_referenced_p PROTO((rtx, rtx)); static int memref_used_between_p PROTO((rtx, rtx, rtx)); static void optimize_reg_copy_1 PROTO((rtx, rtx, rtx)); @@ -600,6 +601,52 @@ validate_equiv_mem (start, reg, memref) return 0; } + +/* TRUE if X uses any registers for which reg_equiv_replace is true. */ + +static int +contains_replace_regs (x, reg_equiv_replace) + rtx x; + char *reg_equiv_replace; +{ + int i, j; + char *fmt; + enum rtx_code code = GET_CODE (x); + + switch (code) + { + case CONST_INT: + case CONST: + case LABEL_REF: + case SYMBOL_REF: + case CONST_DOUBLE: + case PC: + case CC0: + case HIGH: + case LO_SUM: + return 0; + + case REG: + return reg_equiv_replace[REGNO (x)]; + } + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + switch (fmt[i]) + { + case 'e': + if (contains_replace_regs (XEXP (x, i), reg_equiv_replace)) + return 1; + break; + case 'E': + for (j = XVECLEN (x, i) - 1; j >= 0; j--) + if (contains_replace_regs (XVECEXP (x, i, j), reg_equiv_replace)) + return 1; + break; + } + + return 0; +} /* TRUE if X references a memory location that would be affected by a store to MEMREF. */ @@ -1005,12 +1052,24 @@ update_equiv_regs () in a single basic block, see if the register is always equivalent to that memory location and if moving the store from INSN to the insn that set REG is safe. If so, put a REG_EQUIV note on the - initializing insn. */ + initializing insn. + + Don't add a REG_EQUIV note if the insn already has one. The existing + REG_EQUIV is likely more useful than the one we are adding. + + If one of the regs in the address is marked as reg_equiv_replace, + then we can't add this REG_EQUIV note. The reg_equiv_replace + optimization may move the set of this register immediately before + insn, which puts it after reg_equiv_init_insn[regno], and hence + the mention in the REG_EQUIV note would be to an uninitialized + pseudo. */ if (GET_CODE (dest) == MEM && GET_CODE (SET_SRC (set)) == REG && (regno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER && REG_BASIC_BLOCK (regno) >= 0 && reg_equiv_init_insn[regno] != 0 + && ! find_reg_note (insn, REG_EQUIV, NULL_RTX) + && ! contains_replace_regs (XEXP (dest, 0), reg_equiv_replace) && validate_equiv_mem (reg_equiv_init_insn[regno], SET_SRC (set), dest) && ! memref_used_between_p (SET_DEST (set), |