changeset 19708:8f21e30a29c2

Add Graph#reverseUsageOrder facility. Add test case for guard elimination corner case.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 05 Mar 2015 14:26:16 +0100
parents 32b4b06b6fac
children 2fd45bb25118
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java
diffstat 3 files changed, 130 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java	Thu Mar 05 14:26:16 2015 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2015, 2015, 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.compiler.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.directives.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class GuardEliminationCornerCasesTest extends GraalCompilerTest {
+
+    static class A {
+
+    }
+
+    static class B extends A {
+
+    }
+
+    static class C extends B {
+
+    }
+
+    static class D extends C {
+
+    }
+
+    @SuppressWarnings({"static-method", "unused"})
+    private int testMethod(Object a) {
+        if (a instanceof A) {
+            if (a instanceof C) {
+                if (a instanceof B) {
+                    B b = (B) a;
+                    if (b instanceof C) {
+                        return 1;
+                    } else {
+                        GraalDirectives.deoptimize();
+                    }
+                }
+            } else {
+                GraalDirectives.deoptimize();
+            }
+        }
+        return 0;
+    }
+
+    @Test
+    public void testFloatingGuards() {
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        StructuredGraph graph = parseEager("testMethod", AllowAssumptions.YES);
+        new ConvertDeoptimizeToGuardPhase().apply(graph, context);
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(false);
+        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+        Debug.dump(graph, "after parsing");
+
+        GuardNode myGuardNode = null;
+        for (Node n : graph.getNodes()) {
+            if (n instanceof GuardNode) {
+                GuardNode guardNode = (GuardNode) n;
+                LogicNode condition = guardNode.condition();
+                if (condition instanceof InstanceOfNode) {
+                    InstanceOfNode instanceOfNode = (InstanceOfNode) condition;
+                    if (instanceOfNode.getValue() instanceof ValueProxy) {
+                        myGuardNode = guardNode;
+                        break;
+                    }
+                }
+            }
+        }
+
+        AbstractBeginNode myBegin = (AbstractBeginNode) myGuardNode.getAnchor();
+        AbstractBeginNode prevBegin = BeginNode.prevBegin((FixedNode) myBegin.predecessor());
+        myGuardNode.setAnchor(prevBegin);
+
+        Debug.dump(graph, "after manual modification");
+        graph.reverseUsageOrder();
+        new ConditionalEliminationPhase().apply(graph);
+        new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST).apply(graph);
+    }
+}
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Wed Mar 04 16:38:36 2015 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Thu Mar 05 14:26:16 2015 +0100
@@ -891,6 +891,16 @@
         }
     }
 
+    /**
+     * Reverses the usage orders of all nodes. This is used for debugging to make sure an unorthodox
+     * usage order does not trigger bugs in the compiler.
+     */
+    public void reverseUsageOrder() {
+        for (Node n : getNodes()) {
+            n.reverseUsageOrder();
+        }
+    }
+
     public boolean isFrozen() {
         return isFrozen;
     }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Wed Mar 04 16:38:36 2015 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Thu Mar 05 14:26:16 2015 +0100
@@ -345,6 +345,17 @@
         return this.usage0 == null;
     }
 
+    void reverseUsageOrder() {
+        List<Node> snapshot = this.usages().snapshot();
+        for (Node n : snapshot) {
+            this.removeUsage(n);
+        }
+        Collections.reverse(snapshot);
+        for (Node n : snapshot) {
+            this.addUsage(n);
+        }
+    }
+
     /**
      * Adds a given node to this node's {@linkplain #usages() usages}.
      *