This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: N19990310_4.java regression fix


This patch fixes the N19990310_4.java test case.  I believe that this
failure represents a regression from 2.95 (if not it is a regression
from some point in the past since I believe this test used to work).

The basic bug here is that we are compiling bytecode like this:

  0: bipush 9
  2: istore_1
  3: iload_1
  4: iconst_3
  5: istore_1
  6: iconst_3
  7: iadd

The load at #3 isn't processed until after the store at #5, so the
wrong value is used.

This patch works by changing iload (and others) to introduce a new
local variable at the time of the load.  This makes the processing
happen in the right order.

This is a bit ugly.  I'm not sure it is the best patch, or even a good
one.

I ran it against our test suite and there were no regressions.

Is this important for the branch?  I don't know.  Is it ok?

2001-04-10  Tom Tromey  <tromey@redhat.com>

	* expr.c (expand_load_internal): New function.
	(LOAD_INTERNAL): Use it.

Tom

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.102.2.1
diff -u -r1.102.2.1 expr.c
--- expr.c	2001/02/16 22:32:24	1.102.2.1
+++ expr.c	2001/04/10 14:29:02
@@ -57,6 +57,7 @@
 static tree build_java_monitor PARAMS ((tree, tree));
 static void expand_java_pushc PARAMS ((int, tree));
 static void expand_java_return PARAMS ((tree));
+static void expand_load_internal PARAMS ((int, tree, int));
 static void expand_java_NEW PARAMS ((tree));
 static void expand_java_INSTANCEOF PARAMS ((tree));
 static void expand_java_CHECKCAST PARAMS ((tree));
@@ -1083,6 +1084,32 @@
     }
 }
 
+static void
+expand_load_internal (index, type, pc)
+     int index;
+     tree type;
+     int pc;
+{
+  tree copy;
+  tree var = find_local_variable (index, type, pc);
+
+  /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
+     on the stack.  If there is an assignment to this VAR_DECL between
+     the stack push and the use, then the wrong code could be
+     generated.  To avoid this we create a new local and copy our
+     value into it.  Then we push this new local on the stack.
+     Hopefully this all gets optimized out.  */
+  copy = build_decl (VAR_DECL, NULL_TREE, type);
+  DECL_CONTEXT (copy) = current_function_decl;
+  layout_decl (copy, 0);
+  DECL_REGISTER (copy) = 1;
+  expand_decl (copy);
+  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
+  DECL_INITIAL (copy) = var;
+  expand_decl_init (copy);
+  push_value (save_expr (copy));
+}
+
 tree
 build_address_of (value)
      tree value;
@@ -2844,7 +2871,7 @@
 
 /* internal macro added for use by the WIDE case */
 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
-  push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
+  expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
 
 /* Push local variable onto the opcode stack. */
 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]