jcf-write.c (generate_bytecode_insns): Implement evaluate-once semantics for SAVE_EXPR...
authorRoger Sayle <roger@eyesopen.com>
Tue, 30 Sep 2003 18:24:33 +0000 (18:24 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 30 Sep 2003 18:24:33 +0000 (18:24 +0000)
* jcf-write.c (generate_bytecode_insns): Implement evaluate-once
semantics for SAVE_EXPR, by caching the result in a temporary.

From-SVN: r71949

gcc/java/ChangeLog
gcc/java/jcf-write.c

index f2a990cdf6288c76f477f3717b5fb229d41b1429..bf5da8c9ec9767dcb8defc44e1da1c55b225cc5e 100644 (file)
@@ -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
index b4a9e1b68768f4827c607a1b1d6143c29e69a738..097177e48b966f1f80f551c43175d60d70f8a381 100644 (file)
@@ -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: