changeset 11317:12fe444e68d2

Fix bug in ConditionalElimination phase: when replacing a ifnode with a guard, the guard has to be checked before entering the surviving branch
author Gilles Duboscq <duboscq@ssw.jku.at>
date Fri, 16 Aug 2013 14:33:45 +0200
parents 33ea8e2addac
children 345bce66c04a
files graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation01.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation02.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java
diffstat 3 files changed, 157 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation01.java	Fri Aug 16 14:33:45 2013 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.optimize;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.test.*;
+import com.oracle.graal.jtt.*;
+
+@SuppressWarnings("unused")
+public class ConditionalEliminiation01 extends JTTTest {
+
+    private static int x;
+    private static Object o = new Object();
+
+    private static class A {
+
+        public A(int y) {
+            this.y = y;
+        }
+
+        int y;
+    }
+
+    @Override
+    protected void before(Method method) {
+        super.before(method);
+        x = 0;
+    }
+
+    public int test(A a) {
+        if (o == null) {
+            return -1;
+        }
+        if (a == null) {
+            return -2;
+        }
+        if (o == null) {
+            return -3;
+        }
+        x = 3;
+        return a.y + x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", new A(5));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", new Object[]{null});
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation02.java	Fri Aug 16 14:33:45 2013 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.optimize;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.test.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.jtt.*;
+
+@SuppressWarnings("unused")
+public class ConditionalEliminiation02 extends JTTTest {
+
+    private static Object o = null;
+
+    private static class A {
+
+        public A(int y) {
+            this.y = y;
+        }
+
+        int y;
+    }
+
+    public int test(A a, boolean isNull, boolean isVeryNull) {
+        if (o == null) {
+            if (!isNull) {
+                if (o == null) {
+                    return a.y;
+                }
+            }
+            if (!isVeryNull) {
+                if (o == null) {
+                    return a.y;
+                }
+            }
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new A(5), false, false);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new Object[]{null, true, true});
+    }
+
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Aug 16 14:31:28 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Aug 16 14:33:45 2013 +0200
@@ -33,7 +33,7 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
@@ -547,6 +547,10 @@
                 }
 
                 if (replacement != null) {
+                    if (replacementAnchor instanceof GuardNode) {
+                        ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor));
+                        graph.addBeforeFixed(ifNode, anchor);
+                    }
                     for (Node n : survivingSuccessor.usages().snapshot()) {
                         if (n instanceof GuardNode || n instanceof ProxyNode) {
                             // Keep wired to the begin node.
@@ -555,7 +559,6 @@
                                 // Cannot simplify this IfNode as there is no anchor.
                                 return;
                             }
-
                             // Rewire to the replacement anchor.
                             n.replaceFirstInput(survivingSuccessor, replacementAnchor);
                         }