summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2003-09-30 18:24:33 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2003-09-30 18:24:33 +0000
commit443cecfb30ac27c22aab562ae83efd813bde3a7b (patch)
tree356336d35072d68cb7699897c268ca1398c12168
parenteb36c355259c8d5556b34b8e45cf53c83efee296 (diff)
downloadppe42-gcc-443cecfb30ac27c22aab562ae83efd813bde3a7b.tar.gz
ppe42-gcc-443cecfb30ac27c22aab562ae83efd813bde3a7b.zip
* jcf-write.c (generate_bytecode_insns): Implement evaluate-once
semantics for SAVE_EXPR, by caching the result in a temporary. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71949 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/java/ChangeLog5
-rw-r--r--gcc/java/jcf-write.c32
2 files changed, 36 insertions, 1 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index f2a990cdf62..bf5da8c9ec9 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,8 @@
+2003-09-30 Roger Sayle <roger@eyesopen.com>
+
+ * jcf-write.c (generate_bytecode_insns): Implement evaluate-once
+ semantics for SAVE_EXPR, by caching the result in a temporary.
+
2003-09-28 Richard Henderson <rth@redhat.com>
* check-init.c (check_init): Save and restore input_location
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index b4a9e1b6876..097177e48b9 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -2149,7 +2149,37 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state)
}
break;
case SAVE_EXPR:
- generate_bytecode_insns (TREE_OPERAND (exp, 0), STACK_TARGET, state);
+ /* Because the state associated with a SAVE_EXPR tree node must
+ be a RTL expression, we use it to store the DECL_LOCAL_INDEX
+ of a temporary variable in a CONST_INT. */
+ if (! SAVE_EXPR_RTL (exp))
+ {
+ tree type = TREE_TYPE (exp);
+ tree decl = build_decl (VAR_DECL, NULL_TREE, type);
+ generate_bytecode_insns (TREE_OPERAND (exp, 0),
+ STACK_TARGET, state);
+ localvar_alloc (decl, state);
+ SAVE_EXPR_RTL (exp) = GEN_INT (DECL_LOCAL_INDEX (decl));
+ emit_dup (TYPE_IS_WIDE (type) ? 2 : 1, 0, state);
+ emit_store (decl, state);
+ }
+ else
+ {
+ /* The following code avoids creating a temporary DECL just
+ to pass to emit_load. This code could be factored with
+ the similar implementation in emit_load_or_store. */
+ tree type = TREE_TYPE (exp);
+ int kind = adjust_typed_op (type, 4);
+ int index = (int) INTVAL (SAVE_EXPR_RTL (exp));
+ if (index <= 3)
+ {
+ RESERVE (1); /* [ilfda]load_[0123] */
+ OP1 (OPCODE_iload + 5 + 4*kind + index);
+ }
+ else /* [ilfda]load */
+ maybe_wide (OPCODE_iload + kind, index, state);
+ NOTE_PUSH (TYPE_IS_WIDE (type) ? 2 : 1);
+ }
break;
case CONVERT_EXPR:
case NOP_EXPR:
OpenPOWER on IntegriCloud