diff options
author | Timothy Moore <moore@gnu.org> | 1992-09-10 22:20:15 +0000 |
---|---|---|
committer | Timothy Moore <moore@gnu.org> | 1992-09-10 22:20:15 +0000 |
commit | 48f25c7ad60d9bbfba2926e7ece89d8c4568c557 (patch) | |
tree | 085d7912e332a366b6169fe11315d31a422a28dd /gcc | |
parent | ed50ab354cc6a70b81a14fc72298d4ac7af07b36 (diff) | |
download | gcc-48f25c7ad60d9bbfba2926e7ece89d8c4568c557.zip gcc-48f25c7ad60d9bbfba2926e7ece89d8c4568c557.tar.gz gcc-48f25c7ad60d9bbfba2926e7ece89d8c4568c557.tar.bz2 |
(shorten_branches): Do shorten branches with delay slots
if the number of delay slots is constant.
From-SVN: r2098
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/final.c | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/gcc/final.c b/gcc/final.c index cef184f..166c527 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -527,13 +527,15 @@ shorten_branches (first) else if (GET_CODE (body) == SEQUENCE) { int i; - + int const_delay_slots; +#ifdef DELAY_SLOTS + const_delay_slots = const_num_delay_slots (XVECEXP (body, 0, 1)); +#else + const_delay_slots = 0; +#endif /* Inside a delay slot sequence, we do not do any branch shortening - (on the only machine known to have both variable-length branches - and delay slots, the ROMP, branch-with-execute is the same size - as the maximum branch anyway). So we only have to handle normal - insns (actually, reorg never puts ASM insns in a delay slot, but - we don't take advantage of that knowledge here). */ + if the shortening could change the number of delay slots + of the branch. */ for (i = 0; i < XVECLEN (body, 0); i++) { rtx inner_insn = XVECEXP (body, 0, i); @@ -547,7 +549,16 @@ shorten_branches (first) inner_length = insn_default_length (inner_insn); insn_lengths[inner_uid] = inner_length; - varying_length[inner_uid] = 0; + if (const_delay_slots) + { + if ((varying_length[inner_uid] + = insn_variable_length_p (inner_insn)) != 0) + varying_length[uid] = 1; + insn_addresses[inner_uid] = (insn_current_address + + insn_lengths[uid]); + } + else + varying_length[inner_uid] = 0; insn_lengths[uid] += inner_length; } } @@ -572,16 +583,45 @@ shorten_branches (first) something_changed = 0; for (insn_current_address = FIRST_INSN_ADDRESS, insn = first; insn != 0; - insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn)) + insn = NEXT_INSN (insn)) { int new_length; uid = INSN_UID (insn); insn_addresses[uid] = insn_current_address; if (! varying_length[uid]) - continue; + { + insn_current_address += insn_lengths[uid]; + continue; + } + if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE) + { + int i; + + body = PATTERN (insn); + new_length = 0; + for (i = 0; i < XVECLEN (body, 0); i++) + { + rtx inner_insn = XVECEXP (body, 0, i); + int inner_uid = INSN_UID (inner_insn); + int inner_length; - new_length = insn_current_length (insn); + insn_addresses[inner_uid] = insn_current_address; + inner_length = insn_current_length (inner_insn); + if (inner_length != insn_lengths[inner_uid]) + { + insn_lengths[inner_uid] = inner_length; + something_changed = 1; + } + insn_current_address += insn_lengths[inner_uid]; + new_length += inner_length; + } + } + else + { + new_length = insn_current_length (insn); + insn_current_address += new_length; + } if (new_length != insn_lengths[uid]) { insn_lengths[uid] = new_length; |