diff options
author | J"orn Rennecke <amylaar@cygnus.co.uk> | 1998-11-11 19:36:29 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 1998-11-11 19:36:29 +0000 |
commit | 135eb61ca459bf9556cfe7846553b678d11e6a52 (patch) | |
tree | c8cab010883f75fa1d7c0a582cd529b2af211861 /gcc/reload1.c | |
parent | b62d42fef48e4c1ac746efbc7b396047a2a36502 (diff) | |
download | gcc-135eb61ca459bf9556cfe7846553b678d11e6a52.zip gcc-135eb61ca459bf9556cfe7846553b678d11e6a52.tar.gz gcc-135eb61ca459bf9556cfe7846553b678d11e6a52.tar.bz2 |
Handle equivalences that have been obscured by gcse:
* reload1.c (reload): Handle equivalences set up in multiple places.
* local-alloc.c (reg_equiv_init_insns): New variable.
(no_equiv): New function.
(update_equiv_regs): Handle equivalences set up in multiple places.
Don't ignore an insn just because its destination is likely to be
spilled.
From-SVN: r23610
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index ea8bc1f..5df3c15 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -114,7 +114,7 @@ rtx *reg_equiv_mem; /* Widest width in which each pseudo reg is referred to (via subreg). */ static int *reg_max_ref_width; -/* Element N is the insn that initialized reg N from its equivalent +/* Element N is the list of insns that initialized reg N from its equivalent constant or memory slot. */ static rtx *reg_equiv_init; @@ -710,7 +710,8 @@ reload (first, global, dumpfile) So don't mark this insn now. */ if (GET_CODE (x) != MEM || rtx_equal_p (SET_SRC (set), x)) - reg_equiv_init[i] = insn; + reg_equiv_init[i] + = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[i]); } } } @@ -722,7 +723,9 @@ reload (first, global, dumpfile) && reg_equiv_memory_loc[REGNO (SET_SRC (set))] && rtx_equal_p (SET_DEST (set), reg_equiv_memory_loc[REGNO (SET_SRC (set))])) - reg_equiv_init[REGNO (SET_SRC (set))] = insn; + reg_equiv_init[REGNO (SET_SRC (set))] + = gen_rtx_INSN_LIST (VOIDmode, insn, + reg_equiv_init[REGNO (SET_SRC (set))]); if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') scan_paradoxical_subregs (PATTERN (insn)); @@ -971,22 +974,30 @@ reload (first, global, dumpfile) If that insn didn't set the register (i.e., it copied the register to memory), just delete that insn instead of the equivalencing insn plus anything now dead. If we call delete_dead_insn on that insn, we may - delete the insn that actually sets the register if the register die + delete the insn that actually sets the register if the register dies there and that is incorrect. */ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) - if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0 - && GET_CODE (reg_equiv_init[i]) != NOTE) - { - if (reg_set_p (regno_reg_rtx[i], PATTERN (reg_equiv_init[i]))) - delete_dead_insn (reg_equiv_init[i]); - else - { - PUT_CODE (reg_equiv_init[i], NOTE); - NOTE_SOURCE_FILE (reg_equiv_init[i]) = 0; - NOTE_LINE_NUMBER (reg_equiv_init[i]) = NOTE_INSN_DELETED; - } - } + { + if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0) + { + rtx list; + for (list = reg_equiv_init[i]; list; list = XEXP (list, 1)) + { + rtx equiv_insn = XEXP (list, 0); + if (GET_CODE (equiv_insn) == NOTE) + continue; + if (reg_set_p (regno_reg_rtx[i], PATTERN (equiv_insn))) + delete_dead_insn (equiv_insn); + else + { + PUT_CODE (equiv_insn, NOTE); + NOTE_SOURCE_FILE (equiv_insn) = 0; + NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED; + } + } + } + } /* Use the reload registers where necessary by generating move instructions to move the must-be-register |