001/* 002 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.nodes; 024 025import jdk.internal.jvmci.meta.*; 026 027import com.oracle.graal.compiler.common.type.*; 028import com.oracle.graal.graph.*; 029import com.oracle.graal.graph.iterators.*; 030import com.oracle.graal.nodeinfo.*; 031 032/** 033 * This class represents a value within the graph, including local variables, phis, and all other 034 * instructions. 035 */ 036@NodeInfo 037public abstract class ValueNode extends com.oracle.graal.graph.Node implements KindProvider { 038 039 public static final NodeClass<ValueNode> TYPE = NodeClass.create(ValueNode.class); 040 /** 041 * The kind of this value. This is {@link Kind#Void} for instructions that produce no value. 042 * This kind is guaranteed to be a {@linkplain Kind#getStackKind() stack kind}. 043 */ 044 protected Stamp stamp; 045 046 public ValueNode(NodeClass<? extends ValueNode> c, Stamp stamp) { 047 super(c); 048 this.stamp = stamp; 049 } 050 051 public final Stamp stamp() { 052 return stamp; 053 } 054 055 public final void setStamp(Stamp stamp) { 056 this.stamp = stamp; 057 } 058 059 @Override 060 public final StructuredGraph graph() { 061 return (StructuredGraph) super.graph(); 062 } 063 064 /** 065 * Checks if the given stamp is different than the current one ( 066 * {@code newStamp.equals(oldStamp) == false}). If it is different then the new stamp will 067 * become the current stamp for this node. 068 * 069 * @return true if the stamp has changed, false otherwise. 070 */ 071 protected final boolean updateStamp(Stamp newStamp) { 072 if (newStamp == null || newStamp.equals(stamp)) { 073 return false; 074 } else { 075 stamp = newStamp; 076 return true; 077 } 078 } 079 080 /** 081 * This method can be overridden by subclasses of {@link ValueNode} if they need to recompute 082 * their stamp if their inputs change. A typical implementation will compute the stamp and pass 083 * it to {@link #updateStamp(Stamp)}, whose return value can be used as the result of this 084 * method. 085 * 086 * @return true if the stamp has changed, false otherwise. 087 */ 088 public boolean inferStamp() { 089 return false; 090 } 091 092 public final Kind getKind() { 093 return stamp().getStackKind(); 094 } 095 096 /** 097 * Checks whether this value is a constant (i.e. it is of type {@link ConstantNode}. 098 * 099 * @return {@code true} if this value is a constant 100 */ 101 public final boolean isConstant() { 102 return this instanceof ConstantNode; 103 } 104 105 private static final NodePredicate IS_CONSTANT = new NodePredicate() { 106 public boolean apply(Node n) { 107 return n instanceof ConstantNode; 108 } 109 }; 110 111 public static NodePredicate isConstantPredicate() { 112 return IS_CONSTANT; 113 } 114 115 /** 116 * Checks whether this value represents the null constant. 117 * 118 * @return {@code true} if this value represents the null constant 119 */ 120 public final boolean isNullConstant() { 121 JavaConstant value = asJavaConstant(); 122 return value != null && value.isNull(); 123 } 124 125 /** 126 * Convert this value to a constant if it is a constant, otherwise return null. 127 * 128 * @return the {@link JavaConstant} represented by this value if it is a constant; {@code null} 129 * otherwise 130 */ 131 public final Constant asConstant() { 132 if (this instanceof ConstantNode) { 133 return ((ConstantNode) this).getValue(); 134 } else { 135 return null; 136 } 137 } 138 139 public final JavaConstant asJavaConstant() { 140 Constant value = asConstant(); 141 if (value instanceof JavaConstant) { 142 return (JavaConstant) value; 143 } else { 144 return null; 145 } 146 } 147 148 public ValueNode asNode() { 149 return this; 150 } 151 152 @Override 153 public boolean isAllowedUsageType(InputType type) { 154 if (getKind() != Kind.Void && type == InputType.Value) { 155 return true; 156 } else { 157 return super.isAllowedUsageType(type); 158 } 159 } 160}