# HG changeset patch # User Doug Simon # Date 1373031842 -7200 # Node ID 1fdcc58bff2ac819f0d068ce93d3b1cd1c3bc05f # Parent ae12060a0f7d30fbb24ae7866b5e0f5199f2deea added GuardingPiNode diff -r ae12060a0f7d -r 1fdcc58bff2a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- /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; + } +} diff -r ae12060a0f7d -r 1fdcc58bff2a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- 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); } } }