--- /dev/null 2017-01-22 10:16:57.869617664 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java 2017-02-15 17:06:53.278273469 -0800 @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2009, 2016, 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 org.graalvm.compiler.nodes; + +import org.graalvm.compiler.core.common.type.Stamp; +import org.graalvm.compiler.graph.Node; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.graph.iterators.NodePredicate; +import org.graalvm.compiler.nodeinfo.InputType; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.spi.NodeValueMap; + +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; + +/** + * This class represents a value within the graph, including local variables, phis, and all other + * instructions. + */ +@NodeInfo +public abstract class ValueNode extends org.graalvm.compiler.graph.Node implements ValueNodeInterface { + + public static final NodeClass TYPE = NodeClass.create(ValueNode.class); + /** + * The kind of this value. This is {@link JavaKind#Void} for instructions that produce no value. + * This kind is guaranteed to be a {@linkplain JavaKind#getStackKind() stack kind}. + */ + protected Stamp stamp; + + public ValueNode(NodeClass c, Stamp stamp) { + super(c); + this.stamp = stamp; + } + + public final Stamp stamp() { + return stamp; + } + + public final void setStamp(Stamp stamp) { + this.stamp = stamp; + assert !isAlive() || !inferStamp() : "setStamp called on a node that overrides inferStamp: " + this; + } + + @Override + public final StructuredGraph graph() { + return (StructuredGraph) super.graph(); + } + + /** + * Checks if the given stamp is different than the current one ( + * {@code newStamp.equals(oldStamp) == false}). If it is different then the new stamp will + * become the current stamp for this node. + * + * @return true if the stamp has changed, false otherwise. + */ + protected final boolean updateStamp(Stamp newStamp) { + if (newStamp == null || newStamp.equals(stamp)) { + return false; + } else { + stamp = newStamp; + return true; + } + } + + /** + * This method can be overridden by subclasses of {@link ValueNode} if they need to recompute + * their stamp if their inputs change. A typical implementation will compute the stamp and pass + * it to {@link #updateStamp(Stamp)}, whose return value can be used as the result of this + * method. + * + * @return true if the stamp has changed, false otherwise. + */ + public boolean inferStamp() { + return false; + } + + public final JavaKind getStackKind() { + return stamp().getStackKind(); + } + + /** + * Checks whether this value is a constant (i.e. it is of type {@link ConstantNode}. + * + * @return {@code true} if this value is a constant + */ + public final boolean isConstant() { + return this instanceof ConstantNode; + } + + private static final NodePredicate IS_CONSTANT = new NodePredicate() { + @Override + public boolean apply(Node n) { + return n instanceof ConstantNode; + } + }; + + public static NodePredicate isConstantPredicate() { + return IS_CONSTANT; + } + + /** + * Checks whether this value represents the null constant. + * + * @return {@code true} if this value represents the null constant + */ + public final boolean isNullConstant() { + JavaConstant value = asJavaConstant(); + return value != null && value.isNull(); + } + + /** + * Convert this value to a constant if it is a constant, otherwise return null. + * + * @return the {@link JavaConstant} represented by this value if it is a constant; {@code null} + * otherwise + */ + public final Constant asConstant() { + if (this instanceof ConstantNode) { + return ((ConstantNode) this).getValue(); + } else { + return null; + } + } + + public final JavaConstant asJavaConstant() { + Constant value = asConstant(); + if (value instanceof JavaConstant) { + return (JavaConstant) value; + } else { + return null; + } + } + + @Override + public ValueNode asNode() { + return this; + } + + @Override + public boolean isAllowedUsageType(InputType type) { + if (getStackKind() != JavaKind.Void && type == InputType.Value) { + return true; + } else { + return super.isAllowedUsageType(type); + } + } + + /** + * Checks if this node has usages other than the given node {@code node}. + * + * @param node node which is ignored when searching for usages + * @param nodeValueMap + * @return true if this node has other usages, false otherwise + */ + public boolean hasUsagesOtherThan(ValueNode node, NodeValueMap nodeValueMap) { + for (Node usage : usages()) { + if (usage != node && usage instanceof ValueNode && nodeValueMap.hasOperand(usage)) { + return true; + } + } + return false; + } + +}