[gcjx] Patch: FYI: bytecode optimizer fix
Tom Tromey
tromey@redhat.com
Wed Sep 14 03:58:00 GMT 2005
I'm checking this in on the gcjx branch.
While working on the previous fix I noticed that we were not
optimizing bytecode like this:
ifnonnull X
goto Y
X:...
I forgot that we could also see this when the 'goto' is in its own
block. While there I took the opportunity to turn a goto-to-return
into a plain return.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* bytecode/byteutil.hh (return_p): New function.
* bytecode/block.cc (optimize): Handle 'if' optimization when
'goto' is in following block. Optimize a 'goto' to a 'return'.
Include byteutil.hh.
Index: bytecode/block.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/block.cc,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 block.cc
--- bytecode/block.cc 8 Mar 2005 00:17:53 -0000 1.1.2.3
+++ bytecode/block.cc 14 Sep 2005 03:56:13 -0000
@@ -25,6 +25,7 @@
#include "bytecode/block.hh"
#include "bytecode/attribute.hh"
#include "bytecode/generate.hh"
+#include "bytecode/byteutil.hh"
bool
bytecode_block::optimize ()
@@ -87,10 +88,33 @@
changed = true;
}
}
+ else if (last->conditional_p ()
+ && last->get_target () == next_block->next_block
+ && ! next_block->relocations.empty ())
+ {
+ // We might also encounter this case if the next block
+ // starts with a goto.
+ ref_relocation next_rel = next_block->relocations.front ();
+ if (next_rel->get_kind () == reloc_goto)
+ {
+ // Remove the goto relocation and the byte representing
+ // the instruction.
+ next_block->relocations.pop_back ();
+ next_block->bytecode.pop_back ();
+ assert (! next_block->fall_through);
+ next_block->fall_through = true;
+ last->set_target (next_rel->get_target ());
+ last->invert_condition ();
+ // Rewrite the bytecode. We know that the relocation
+ // type can be directly converted to an instruction.
+ bytecode[bytecode.size () - 1] = jbyte (last->get_kind ());
+ changed = true;
+ }
+ }
}
- // Second, we rewrite goto L; ... L: goto X by changing the first
- // goto to jump directly to X.
+ // Rewrite goto L; ... L: goto X by changing the first goto to jump
+ // directly to X.
for (std::list<ref_relocation>::iterator i = relocations.begin ();
i != relocations.end ();
++i)
@@ -128,6 +152,22 @@
}
}
+ // If we see goto L; ... L: return, we hoist the return into the
+ // original block. Do this after hoisting gotos so that a chain of
+ // gotos leading to a return is optimized.
+ if (! relocations.empty () && relocations.back ()->get_kind () == reloc_goto)
+ {
+ int ret = (relocations.back ()->get_target ()->bytecode[0] & 0xff);
+ if (return_p (java_opcode (ret)))
+ {
+ // Delete our last relocation.
+ relocations.pop_back ();
+ // Turn the last bytecode value into the appropriate return.
+ bytecode[bytecode.size () - 1] = ret;
+ changed = true;
+ }
+ }
+
return changed;
}
Index: bytecode/byteutil.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/byteutil.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 byteutil.hh
--- bytecode/byteutil.hh 13 Jan 2005 03:18:34 -0000 1.1.2.1
+++ bytecode/byteutil.hh 14 Sep 2005 03:56:13 -0000
@@ -1,6 +1,6 @@
// Bytecode utility functions.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -38,6 +38,14 @@
return java_opcode ((base & 1) ? base + 1 : base - 1);
}
+/// Return true if the value is a 'return' bytecode of any kind.
+inline bool
+return_p (int op)
+{
+ return (op == op_ireturn || op == op_lreturn || op == op_freturn
+ || op == op_dreturn || op == op_areturn || op == op_return);
+}
+
inline bool
wide_p (const model_type *t)
{
More information about the Java-patches
mailing list