summaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog4
-rw-r--r--gcc/java/jcf-write.c31
2 files changed, 35 insertions, 0 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index e05dba1504f..10a4746a8d0 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,7 @@
+2002-06-04 Tom Tromey <tromey@redhat.com>
+
+ * jcf-write.c (perform_relocations): Optmize a goto to a goto.
+
2002-06-04 Michael Koch <konqueror@gmx.de>
* gcj.texi (Input Options): Fixed typo.
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)