diff options
| author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-09-30 18:24:33 +0000 |
|---|---|---|
| committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-09-30 18:24:33 +0000 |
| commit | 443cecfb30ac27c22aab562ae83efd813bde3a7b (patch) | |
| tree | 356336d35072d68cb7699897c268ca1398c12168 | |
| parent | eb36c355259c8d5556b34b8e45cf53c83efee296 (diff) | |
| download | ppe42-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/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/java/jcf-write.c | 32 |
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: |

