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}