diff options
Diffstat (limited to 'gcc/reorg.c')
-rw-r--r-- | gcc/reorg.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/reorg.c b/gcc/reorg.c index 65d8ce8ea96..f4b9f1f9dd7 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -4200,6 +4200,40 @@ relax_delay_slots (first) continue; } + /* See if we have a RETURN insn with a filled delay slot followed + by a RETURN insn with an unfilled a delay slot. If so, we can delete + the first RETURN (but not it's delay insn). This gives the same + effect in fewer instructions. + + Only do so if optimizing for size since this results in slower, but + smaller code. */ + if (optimize_size + && GET_CODE (PATTERN (delay_insn)) == RETURN + && next + && GET_CODE (next) == JUMP_INSN + && GET_CODE (PATTERN (next)) == RETURN) + { + int i; + + /* Delete the RETURN and just execute the delay list insns. + + We do this by deleting the INSN containing the SEQUENCE, then + re-emitting the insns separately, and then deleting the RETURN. + This allows the count of the jump target to be properly + decremented. */ + + /* Clear the from target bit, since these insns are no longer + in delay slots. */ + for (i = 0; i < XVECLEN (pat, 0); i++) + INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0; + + trial = PREV_INSN (insn); + delete_insn (insn); + emit_insn_after (pat, trial); + delete_scheduled_jump (delay_insn); + continue; + } + /* Now look only at the cases where we have a filled JUMP_INSN. */ if (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) != JUMP_INSN || ! (condjump_p (XVECEXP (PATTERN (insn), 0, 0)) |