changeset 10635:1fdcc58bff2a

added GuardingPiNode
author Doug Simon <doug.simon@oracle.com>
date Fri, 05 Jul 2013 15:44:02 +0200
parents ae12060a0f7d
children bef82f0cf71d
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java
diffstat 2 files changed, 109 insertions(+), 5 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/GuardingPiNode.java	Fri Jul 05 15:44:02 2013 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, 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.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * A node that changes the stamp of its input based on some condition being true.
+ */
+@NodeInfo(nameTemplate = "GuardingPi(!={p#negated}) {p#reason/s}")
+public class GuardingPiNode extends FixedWithNextNode implements Lowerable, GuardingNode, Canonicalizable {
+
+    @Input private ValueNode object;
+    @Input private LogicNode condition;
+    private final DeoptimizationReason reason;
+    private final DeoptimizationAction action;
+    private boolean negated;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public GuardingPiNode(ValueNode object, ValueNode condition, boolean negateCondition, DeoptimizationReason reason, DeoptimizationAction action, Stamp stamp) {
+        super(object.stamp().join(stamp));
+        assert stamp() != null;
+        this.object = object;
+        this.condition = (LogicNode) condition;
+        this.reason = reason;
+        this.action = action;
+        this.negated = negateCondition;
+    }
+
+    @Override
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        if (loweringType == LoweringType.AFTER_GUARDS) {
+            throw new GraalInternalError("Cannot create guards in after-guard lowering");
+        }
+        FixedGuardNode guard = graph().add(new FixedGuardNode(condition, reason, action, negated));
+        PiNode pi = graph().add(new PiNode(object, stamp(), guard));
+        replaceAtUsages(pi);
+        graph().replaceFixedWithFixed(this, guard);
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(stamp().join(object().stamp()));
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (condition instanceof LogicConstantNode) {
+            LogicConstantNode c = (LogicConstantNode) condition;
+            if (c.getValue() != negated && stamp().equals(object().stamp())) {
+                return object;
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static native Object guardingPi(Object object, LogicNode condition, @ConstantNodeParameter boolean negateCondition, @ConstantNodeParameter DeoptimizationReason reason,
+                    @ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter Stamp stamp);
+
+    @Override
+    public ValueNode asNode() {
+        return this;
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Fri Jul 05 15:43:22 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Fri Jul 05 15:44:02 2013 +0200
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
@@ -319,9 +320,13 @@
             usage.replaceFirstInput(input, intrinsifiedNode);
             Debug.log("%s: Checkcast used in a return with forNodeIntrinsic stamp", Debug.contextSnapshot(JavaMethod.class));
         } else if (usage instanceof IsNullNode) {
-            assert usage.usages().count() == 1 && usage.usages().first().predecessor() == input;
-            graph.replaceFloating((FloatingNode) usage, LogicConstantNode.contradiction(graph));
-            Debug.log("%s: Replaced IsNull with false", Debug.contextSnapshot(JavaMethod.class));
+            if (!usage.usages().isEmpty()) {
+                assert usage.usages().count() == 1 && usage.usages().first().predecessor() == input : usage + " " + input;
+                graph.replaceFloating((FloatingNode) usage, LogicConstantNode.contradiction(graph));
+                Debug.log("%s: Replaced IsNull with false", Debug.contextSnapshot(JavaMethod.class));
+            } else {
+                // Removed as usage of a GuardingPiNode
+            }
         } else if (usage instanceof ProxyNode) {
             ProxyNode proxy = (ProxyNode) usage;
             assert proxy.type() == PhiType.Value;
@@ -333,9 +338,15 @@
             for (Node piUsage : usage.usages().snapshot()) {
                 checkCheckCastUsage(graph, intrinsifiedNode, usage, piUsage);
             }
+        } else if (usage instanceof GuardingPiNode) {
+            GuardingPiNode pi = (GuardingPiNode) usage;
+            for (Node piUsage : pi.usages().snapshot()) {
+                checkCheckCastUsage(graph, intrinsifiedNode, usage, piUsage);
+            }
+            graph.removeFixed(pi);
         } else {
-            Debug.dump(graph, "exception");
-            assert false : sourceLocation(usage) + " has unexpected usage " + usage + " of checkcast at " + sourceLocation(input);
+            DebugScope.dump(graph, "exception");
+            assert false : sourceLocation(usage) + " has unexpected usage " + usage + " of checkcast " + input + " at " + sourceLocation(input);
         }
     }
 }