changeset 13154:1e22792abdbc

Make GuardNode extensible.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 25 Nov 2013 17:19:29 +0100
parents ae0001b445c0
children 1dd9aa5a9ee5
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java
diffstat 4 files changed, 135 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java	Mon Nov 25 17:19:29 2013 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013, 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.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+
+public abstract class AbstractFixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, GuardingNode {
+
+    @Input private LogicNode condition;
+    private final DeoptimizationReason reason;
+    private final DeoptimizationAction action;
+    private boolean negated;
+
+    public LogicNode condition() {
+        return condition;
+    }
+
+    public void setCondition(LogicNode x) {
+        updateUsages(condition, x);
+        condition = x;
+    }
+
+    protected AbstractFixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
+        super(StampFactory.dependency());
+        this.action = action;
+        this.negated = negated;
+        this.condition = condition;
+        this.reason = deoptReason;
+    }
+
+    public DeoptimizationReason getReason() {
+        return reason;
+    }
+
+    public DeoptimizationAction getAction() {
+        return action;
+    }
+
+    public boolean isNegated() {
+        return negated;
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name && negated) {
+            return "!" + super.toString(verbosity);
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        while (condition instanceof LogicNegationNode) {
+            LogicNegationNode negation = (LogicNegationNode) condition;
+            setCondition(negation.getInput());
+            negated = !negated;
+        }
+    }
+
+    public void lowerToIf() {
+        FixedNode next = next();
+        setNext(null);
+        DeoptimizeNode deopt = graph().add(new DeoptimizeNode(action, reason));
+        deopt.setDeoptimizationState(getDeoptimizationState());
+        IfNode ifNode;
+        AbstractBeginNode noDeoptSuccessor;
+        if (negated) {
+            ifNode = graph().add(new IfNode(condition, deopt, next, 0));
+            noDeoptSuccessor = ifNode.falseSuccessor();
+        } else {
+            ifNode = graph().add(new IfNode(condition, next, deopt, 1));
+            noDeoptSuccessor = ifNode.trueSuccessor();
+        }
+        ((FixedWithNextNode) predecessor()).setNext(ifNode);
+        this.replaceAtUsages(noDeoptSuccessor);
+        GraphUtil.killWithUnusedFloatingInputs(this);
+    }
+
+    @Override
+    public boolean canDeoptimize() {
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Mon Nov 25 17:10:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Mon Nov 25 17:19:29 2013 +0100
@@ -27,78 +27,31 @@
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.util.*;
 
 @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}")
-public final class FixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable, IterableNodeType, GuardingNode {
-
-    @Input private LogicNode condition;
-    private final DeoptimizationReason reason;
-    private final DeoptimizationAction action;
-    private boolean negated;
-
-    public LogicNode condition() {
-        return condition;
-    }
-
-    public void setCondition(LogicNode x) {
-        updateUsages(condition, x);
-        condition = x;
-    }
+public final class FixedGuardNode extends AbstractFixedGuardNode implements Lowerable, IterableNodeType {
 
     public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
         this(condition, deoptReason, action, false);
     }
 
     public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
-        super(StampFactory.dependency());
-        this.action = action;
-        this.negated = negated;
-        this.condition = condition;
-        this.reason = deoptReason;
-
-        assert action != null && reason != null;
-    }
-
-    public DeoptimizationReason getReason() {
-        return reason;
-    }
-
-    public DeoptimizationAction getAction() {
-        return action;
-    }
-
-    public boolean isNegated() {
-        return negated;
-    }
-
-    @Override
-    public String toString(Verbosity verbosity) {
-        if (verbosity == Verbosity.Name && negated) {
-            return "!" + super.toString(verbosity);
-        } else {
-            return super.toString(verbosity);
-        }
+        super(condition, deoptReason, action, negated);
     }
 
     @Override
     public void simplify(SimplifierTool tool) {
-        while (condition instanceof LogicNegationNode) {
-            LogicNegationNode negation = (LogicNegationNode) condition;
-            setCondition(negation.getInput());
-            negated = !negated;
-        }
+        super.simplify(tool);
 
-        if (condition instanceof LogicConstantNode) {
-            LogicConstantNode c = (LogicConstantNode) condition;
-            if (c.getValue() == negated) {
+        if (condition() instanceof LogicConstantNode) {
+            LogicConstantNode c = (LogicConstantNode) condition();
+            if (c.getValue() == isNegated()) {
                 FixedNode next = this.next();
                 if (next != null) {
                     tool.deleteBranch(next);
                 }
 
-                DeoptimizeNode deopt = graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, reason));
+                DeoptimizeNode deopt = graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, getReason()));
                 deopt.setDeoptimizationState(getDeoptimizationState());
                 setNext(deopt);
             }
@@ -115,22 +68,7 @@
             ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(guard.asNode()));
             graph().replaceFixedWithFixed(this, newAnchor);
         } else {
-            FixedNode next = next();
-            setNext(null);
-            DeoptimizeNode deopt = graph().add(new DeoptimizeNode(action, reason));
-            deopt.setDeoptimizationState(getDeoptimizationState());
-            IfNode ifNode;
-            AbstractBeginNode noDeoptSuccessor;
-            if (negated) {
-                ifNode = graph().add(new IfNode(condition, deopt, next, 0));
-                noDeoptSuccessor = ifNode.falseSuccessor();
-            } else {
-                ifNode = graph().add(new IfNode(condition, next, deopt, 1));
-                noDeoptSuccessor = ifNode.trueSuccessor();
-            }
-            ((FixedWithNextNode) predecessor()).setNext(ifNode);
-            this.replaceAtUsages(noDeoptSuccessor);
-            GraphUtil.killWithUnusedFloatingInputs(this);
+            lowerToIf();
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Mon Nov 25 17:10:22 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Mon Nov 25 17:19:29 2013 +0100
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -41,7 +42,7 @@
  * control flow would have reached the guarded node (without taking exceptions into account).
  */
 @NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}")
-public final class GuardNode extends FloatingGuardedNode implements Canonicalizable, IterableNodeType, GuardingNode, GuardedNode {
+public class GuardNode extends FloatingGuardedNode implements Canonicalizable, IterableNodeType, GuardingNode, GuardedNode {
 
     @Input private LogicNode condition;
     private final DeoptimizationReason reason;
@@ -104,6 +105,20 @@
         return this;
     }
 
+    public FixedWithNextNode lowerGuard() {
+        if (negated() && condition() instanceof IsNullNode) {
+            IsNullNode isNull = (IsNullNode) condition();
+            NullCheckNode nullCheck = graph().add(new NullCheckNode(isNull.object()));
+            setCondition(null);
+            if (isNull.usages().isEmpty()) {
+                isNull.safeDelete();
+            }
+            return nullCheck;
+        }
+
+        return null;
+    }
+
     public void negate() {
         negated = !negated;
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Mon Nov 25 17:10:22 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Mon Nov 25 17:19:29 2013 +0100
@@ -142,8 +142,9 @@
         protected void processNode(Node node) {
             if (node instanceof GuardNode) {
                 GuardNode guard = (GuardNode) node;
-                if (guard.negated() && guard.condition() instanceof IsNullNode) {
-                    lowerToNullCheck(guard);
+                FixedWithNextNode lowered = guard.lowerGuard();
+                if (lowered != null) {
+                    replaceCurrent(lowered);
                 } else {
                     lowerToIf(guard);
                 }
@@ -171,15 +172,6 @@
             insert(ifNode, fastPath);
         }
 
-        private void lowerToNullCheck(GuardNode guard) {
-            IsNullNode isNull = (IsNullNode) guard.condition();
-            NullCheckNode nullCheck = guard.graph().add(new NullCheckNode(isNull.object()));
-            replaceCurrent(nullCheck);
-            if (isNull.usages().isEmpty()) {
-                isNull.safeDelete();
-            }
-        }
-
         private void insertLoopExits(DeoptimizeNode deopt) {
             Loop loop = block.getLoop();
             StructuredGraph graph = deopt.graph();