1 /* 2 * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.nodes; 24 25 import org.graalvm.compiler.core.common.type.Stamp; 26 import org.graalvm.compiler.graph.Node; 27 import org.graalvm.compiler.graph.NodeClass; 28 import org.graalvm.compiler.graph.iterators.NodePredicate; 29 import org.graalvm.compiler.nodeinfo.InputType; 30 import org.graalvm.compiler.nodeinfo.NodeInfo; 31 import org.graalvm.compiler.nodes.spi.NodeValueMap; 32 33 import jdk.vm.ci.meta.Constant; 34 import jdk.vm.ci.meta.JavaConstant; 35 import jdk.vm.ci.meta.JavaKind; 36 37 /** 38 * This class represents a value within the graph, including local variables, phis, and all other 39 * instructions. 40 */ 41 @NodeInfo 42 public abstract class ValueNode extends org.graalvm.compiler.graph.Node implements ValueNodeInterface { 43 44 public static final NodeClass<ValueNode> TYPE = NodeClass.create(ValueNode.class); 45 /** 46 * The kind of this value. This is {@link JavaKind#Void} for instructions that produce no value. 47 * This kind is guaranteed to be a {@linkplain JavaKind#getStackKind() stack kind}. 48 */ 49 protected Stamp stamp; 50 51 public ValueNode(NodeClass<? extends ValueNode> c, Stamp stamp) { 52 super(c); 53 this.stamp = stamp; 54 } 55 56 public final Stamp stamp() { 57 return stamp; 58 } 59 60 public final void setStamp(Stamp stamp) { 61 this.stamp = stamp; 62 assert !isAlive() || !inferStamp() : "setStamp called on a node that overrides inferStamp: " + this; 63 } 64 65 @Override 66 public final StructuredGraph graph() { 67 return (StructuredGraph) super.graph(); 68 } 69 70 /** 71 * Checks if the given stamp is different than the current one ( 72 * {@code newStamp.equals(oldStamp) == false}). If it is different then the new stamp will 73 * become the current stamp for this node. 74 * 75 * @return true if the stamp has changed, false otherwise. 76 */ 77 protected final boolean updateStamp(Stamp newStamp) { 78 if (newStamp == null || newStamp.equals(stamp)) { 79 return false; 80 } else { 81 stamp = newStamp; 82 return true; 83 } 84 } 85 86 /** 87 * This method can be overridden by subclasses of {@link ValueNode} if they need to recompute 88 * their stamp if their inputs change. A typical implementation will compute the stamp and pass 89 * it to {@link #updateStamp(Stamp)}, whose return value can be used as the result of this 90 * method. 91 * 92 * @return true if the stamp has changed, false otherwise. 93 */ 94 public boolean inferStamp() { 95 return false; 96 } 97 98 public final JavaKind getStackKind() { 99 return stamp().getStackKind(); 100 } 101 102 /** 103 * Checks whether this value is a constant (i.e. it is of type {@link ConstantNode}. 104 * 105 * @return {@code true} if this value is a constant 106 */ 107 public final boolean isConstant() { 108 return this instanceof ConstantNode; 109 } 110 111 private static final NodePredicate IS_CONSTANT = new NodePredicate() { 112 @Override 113 public boolean apply(Node n) { 114 return n instanceof ConstantNode; 115 } 116 }; 117 118 public static NodePredicate isConstantPredicate() { 119 return IS_CONSTANT; 120 } 121 122 /** 123 * Checks whether this value represents the null constant. 124 * 125 * @return {@code true} if this value represents the null constant 126 */ 127 public final boolean isNullConstant() { 128 JavaConstant value = asJavaConstant(); 129 return value != null && value.isNull(); 130 } 131 132 /** 133 * Convert this value to a constant if it is a constant, otherwise return null. 134 * 135 * @return the {@link JavaConstant} represented by this value if it is a constant; {@code null} 136 * otherwise 137 */ 138 public final Constant asConstant() { 139 if (this instanceof ConstantNode) { 140 return ((ConstantNode) this).getValue(); 141 } else { 142 return null; 143 } 144 } 145 146 public final JavaConstant asJavaConstant() { 147 Constant value = asConstant(); 148 if (value instanceof JavaConstant) { 149 return (JavaConstant) value; 150 } else { 151 return null; 152 } 153 } 154 155 @Override 156 public ValueNode asNode() { 157 return this; 158 } 159 160 @Override 161 public boolean isAllowedUsageType(InputType type) { 162 if (getStackKind() != JavaKind.Void && type == InputType.Value) { 163 return true; 164 } else { 165 return super.isAllowedUsageType(type); 166 } 167 } 168 169 /** 170 * Checks if this node has usages other than the given node {@code node}. 171 * 172 * @param node node which is ignored when searching for usages 173 * @param nodeValueMap 174 * @return true if this node has other usages, false otherwise 175 */ 176 public boolean hasUsagesOtherThan(ValueNode node, NodeValueMap nodeValueMap) { 177 for (Node usage : usages()) { 178 if (usage != node && usage instanceof ValueNode && nodeValueMap.hasOperand(usage)) { 179 return true; 180 } 181 } 182 return false; 183 } 184 185 }