diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7eaad55107..0cc7a236dab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Tue Aug 25 00:57:54 1998 J"orn Rennecke + + * reload1.c (reload_cse_regs_1): When deleting a no-op move that + loads the function result, substitute with a USE. + Mon Aug 24 15:20:19 1998 David Edelsohn * rs6000.h (GO_IF_LEGITIMATE_ADDRESS): Use TARGET_POWERPC64 diff --git a/gcc/reload1.c b/gcc/reload1.c index 239afd82df0..346fbcc201f 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -8290,9 +8290,27 @@ reload_cse_regs (first) int count = 0; if (reload_cse_noop_set_p (body, insn)) { - PUT_CODE (insn, NOTE); - NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; - NOTE_SOURCE_FILE (insn) = 0; + /* If this sets the return value of the function, we must keep + a USE around, in case this is in a different basic block + than the final USE. Otherwise, we could loose important + register lifeness information on SMALL_REGISTER_CLASSES + machines, where return registers might be used as spills: + subsequent passes assume that spill registers are dead at + the end of a basic block. */ + if (REG_FUNCTION_VALUE_P (SET_DEST (body))) + { + pop_obstacks (); + PATTERN (insn) = gen_rtx_USE (VOIDmode, SET_DEST (body)); + INSN_CODE (insn) = -1; + REG_NOTES (insn) = NULL_RTX; + push_obstacks (&reload_obstack, &reload_obstack); + } + else + { + PUT_CODE (insn, NOTE); + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (insn) = 0; + } reload_cse_delete_death_notes (insn); /* We're done with this insn. */ @@ -8313,19 +8331,43 @@ reload_cse_regs (first) else if (GET_CODE (body) == PARALLEL) { int count = 0; + rtx value = NULL_RTX; /* If every action in a PARALLEL is a noop, we can delete the entire PARALLEL. */ for (i = XVECLEN (body, 0) - 1; i >= 0; --i) - if ((GET_CODE (XVECEXP (body, 0, i)) != SET - || ! reload_cse_noop_set_p (XVECEXP (body, 0, i), insn)) - && GET_CODE (XVECEXP (body, 0, i)) != CLOBBER) - break; + { + rtx part = XVECEXP (body, 0, i); + if (GET_CODE (part) == SET) + { + if (! reload_cse_noop_set_p (part, insn)) + break; + if (REG_FUNCTION_VALUE_P (SET_DEST (part))) + { + if (value) + break; + value = SET_DEST (part); + } + } + else if (GET_CODE (part) != CLOBBER) + break; + } if (i < 0) { - PUT_CODE (insn, NOTE); - NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; - NOTE_SOURCE_FILE (insn) = 0; + if (value) + { + pop_obstacks (); + PATTERN (insn) = gen_rtx_USE (VOIDmode, value); + INSN_CODE (insn) = -1; + REG_NOTES (insn) = NULL_RTX; + push_obstacks (&reload_obstack, &reload_obstack); + } + else + { + PUT_CODE (insn, NOTE); + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (insn) = 0; + } reload_cse_delete_death_notes (insn); /* We're done with this insn. */