summaryrefslogtreecommitdiff
path: root/gcc/java/jcf-write.c
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-04 22:09:43 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-04 22:09:43 +0000
commit47c4c0f70f05c1a7ba3baf4b08051896d6ad289a (patch)
treedfd466d2608e3f1aa9a7cbd415ee7b23dbb6e9d9 /gcc/java/jcf-write.c
parentc92df8b45987233404a47e9dbea2ca82eff2581c (diff)
downloadgcc-47c4c0f70f05c1a7ba3baf4b08051896d6ad289a.tar.gz
* jcf-write.c (perform_relocations): Optmize a goto to a goto.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54264 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/jcf-write.c')
-rw-r--r--gcc/java/jcf-write.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index 7ddca448448..f419e9f7ad3 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -2677,6 +2677,37 @@ perform_relocations (state)
shrink += 3;
}
+ /* Optimize GOTO L; ... L: GOTO X by changing the first goto to
+ jump directly to X. We're careful here to avoid an infinite
+ loop if the `goto's themselves form one. We do this
+ optimization because we can generate a goto-to-goto for some
+ try/finally blocks. */
+ while (reloc != NULL
+ && reloc->kind == OPCODE_goto_w
+ && reloc->label != block
+ && reloc->label->v.chunk->data != NULL
+ && reloc->label->v.chunk->data[0] == OPCODE_goto)
+ {
+ /* Find the reloc for the first instruction of the
+ destination block. */
+ struct jcf_relocation *first_reloc;
+ for (first_reloc = reloc->label->u.relocations;
+ first_reloc;
+ first_reloc = first_reloc->next)
+ {
+ if (first_reloc->offset == 1
+ && first_reloc->kind == OPCODE_goto_w)
+ {
+ reloc->label = first_reloc->label;
+ break;
+ }
+ }
+
+ /* If we didn't do anything, exit the loop. */
+ if (first_reloc == NULL)
+ break;
+ }
+
for (reloc = block->u.relocations; reloc != NULL; reloc = reloc->next)
{
if (reloc->kind == SWITCH_ALIGN_RELOC)