This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: N19990310_4.java regression fix
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Subject: Patch: N19990310_4.java regression fix
- From: Tom Tromey <tromey at redhat dot com>
- Date: 10 Apr 2001 09:19:34 -0600
- Cc: Java Patch List <java-patches at gcc dot gnu dot org>, Per Bothner <per at bothner dot com>
- Reply-To: tromey at redhat dot com
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) \