IsNullNode.java revision 12651:6ef01bd40ce2
1283766Sgrembo/* 2283766Sgrembo * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. 3283766Sgrembo * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4283766Sgrembo * 5283766Sgrembo * This code is free software; you can redistribute it and/or modify it 6283766Sgrembo * under the terms of the GNU General Public License version 2 only, as 7283766Sgrembo * published by the Free Software Foundation. 8283766Sgrembo * 9283766Sgrembo * This code is distributed in the hope that it will be useful, but WITHOUT 10283766Sgrembo * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11283766Sgrembo * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12283766Sgrembo * version 2 for more details (a copy is included in the LICENSE file that 13283766Sgrembo * accompanied this code). 14283766Sgrembo * 15283766Sgrembo * You should have received a copy of the GNU General Public License version 16283766Sgrembo * 2 along with this work; if not, write to the Free Software Foundation, 17283766Sgrembo * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18283766Sgrembo * 19283766Sgrembo * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20283766Sgrembo * or visit www.oracle.com if you need additional information or have any 21283766Sgrembo * questions. 22283766Sgrembo */ 23283766Sgrembopackage org.graalvm.compiler.nodes.calc; 24283766Sgrembo 25283766Sgremboimport org.graalvm.compiler.core.common.type.AbstractPointerStamp; 26283766Sgremboimport org.graalvm.compiler.core.common.type.ObjectStamp; 27283766Sgremboimport org.graalvm.compiler.core.common.type.Stamp; 28283766Sgremboimport org.graalvm.compiler.core.common.type.StampFactory; 29283766Sgremboimport org.graalvm.compiler.graph.NodeClass; 30283766Sgremboimport org.graalvm.compiler.graph.spi.CanonicalizerTool; 31283766Sgremboimport org.graalvm.compiler.nodeinfo.NodeCycles; 32283766Sgremboimport org.graalvm.compiler.nodeinfo.NodeInfo; 33283766Sgremboimport org.graalvm.compiler.nodes.LogicConstantNode; 34283766Sgremboimport org.graalvm.compiler.nodes.LogicNode; 35283766Sgremboimport org.graalvm.compiler.nodes.PiNode; 36283766Sgremboimport org.graalvm.compiler.nodes.UnaryOpLogicNode; 37283766Sgremboimport org.graalvm.compiler.nodes.ValueNode; 38283766Sgremboimport org.graalvm.compiler.nodes.spi.LIRLowerable; 39283766Sgremboimport org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; 40283766Sgremboimport org.graalvm.compiler.nodes.spi.PiPushable; 41283766Sgremboimport org.graalvm.compiler.nodes.spi.Virtualizable; 42283766Sgremboimport org.graalvm.compiler.nodes.spi.VirtualizerTool; 43283766Sgremboimport org.graalvm.compiler.nodes.type.StampTool; 44283766Sgrembo 45283766Sgremboimport jdk.vm.ci.meta.TriState; 46283766Sgrembo 47283766Sgrembo/** 48283766Sgrembo * An IsNullNode will be true if the supplied value is null, and false if it is non-null. 49283766Sgrembo */ 50310517Savg@NodeInfo(cycles = NodeCycles.CYCLES_2) 51310517Savgpublic final class IsNullNode extends UnaryOpLogicNode implements LIRLowerable, Virtualizable, PiPushable { 52310517Savg 53310517Savg public static final NodeClass<IsNullNode> TYPE = NodeClass.create(IsNullNode.class); 54283766Sgrembo 55283766Sgrembo public IsNullNode(ValueNode object) { 56310517Savg super(TYPE, object); 57310517Savg assert object != null; 58283766Sgrembo } 59283766Sgrembo 60283766Sgrembo public static LogicNode create(ValueNode forValue) { 61283766Sgrembo LogicNode result = tryCanonicalize(forValue); 62283766Sgrembo return result == null ? new IsNullNode(forValue) : result; 63283766Sgrembo } 64283766Sgrembo 65283766Sgrembo public static LogicNode tryCanonicalize(ValueNode forValue) { 66283766Sgrembo if (StampTool.isPointerAlwaysNull(forValue)) { 67283766Sgrembo return LogicConstantNode.tautology(); 68283766Sgrembo } else if (StampTool.isPointerNonNull(forValue)) { 69283766Sgrembo return LogicConstantNode.contradiction(); 70283766Sgrembo } 71283766Sgrembo return null; 72283766Sgrembo } 73283766Sgrembo 74283766Sgrembo @Override 75283766Sgrembo public void generate(NodeLIRBuilderTool gen) { 76283766Sgrembo // Nothing to do. 77283766Sgrembo } 78283766Sgrembo 79283766Sgrembo @Override 80339029Sgonzo public boolean verify() { 81283766Sgrembo assertTrue(getValue() != null, "is null input must not be null"); 82283766Sgrembo assertTrue(getValue().stamp() instanceof AbstractPointerStamp, "input must be a pointer not %s", getValue().stamp()); 83283766Sgrembo return super.verify(); 84283766Sgrembo } 85283766Sgrembo 86283766Sgrembo @Override 87283766Sgrembo public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { 88283766Sgrembo LogicNode result = tryCanonicalize(forValue); 89283766Sgrembo return result == null ? this : result; 90283766Sgrembo } 91283766Sgrembo 92283766Sgrembo @Override 93283766Sgrembo public void virtualize(VirtualizerTool tool) { 94283766Sgrembo ValueNode alias = tool.getAlias(getValue()); 95339029Sgonzo TriState fold = tryFold(alias.stamp()); 96283766Sgrembo if (fold != TriState.UNKNOWN) { 97339029Sgonzo tool.replaceWithValue(LogicConstantNode.forBoolean(fold.isTrue(), graph())); 98283766Sgrembo } 99283766Sgrembo } 100283766Sgrembo 101283766Sgrembo @Override 102283766Sgrembo public boolean push(PiNode parent) { 103283766Sgrembo if (parent.stamp() instanceof ObjectStamp && parent.object().stamp() instanceof ObjectStamp) { 104283766Sgrembo ObjectStamp piStamp = (ObjectStamp) parent.stamp(); 105283766Sgrembo ObjectStamp piValueStamp = (ObjectStamp) parent.object().stamp(); 106283766Sgrembo if (piStamp.nonNull() == piValueStamp.nonNull() && piStamp.alwaysNull() == piValueStamp.alwaysNull()) { 107283766Sgrembo replaceFirstInput(parent, parent.object()); 108283766Sgrembo return true; 109283766Sgrembo } 110283766Sgrembo } 111283766Sgrembo return false; 112283766Sgrembo } 113339029Sgonzo 114283766Sgrembo @NodeIntrinsic 115331834Sgonzo public static native IsNullNode isNull(Object object); 116283766Sgrembo 117283766Sgrembo @Override 118331834Sgonzo public Stamp getSucceedingStampForValue(boolean negated) { 119283766Sgrembo return negated ? getValue().stamp().join(StampFactory.objectNonNull()) : StampFactory.alwaysNull(); 120331834Sgonzo } 121331834Sgonzo 122331834Sgonzo @Override 123331834Sgonzo public TriState tryFold(Stamp valueStamp) { 124339029Sgonzo if (valueStamp instanceof ObjectStamp) { 125339029Sgonzo ObjectStamp objectStamp = (ObjectStamp) valueStamp; 126339029Sgonzo if (objectStamp.alwaysNull()) { 127331834Sgonzo return TriState.TRUE; 128283766Sgrembo } else if (objectStamp.nonNull()) { 129331834Sgonzo return TriState.FALSE; 130331834Sgonzo } 131283766Sgrembo } 132331834Sgonzo return TriState.UNKNOWN; 133283766Sgrembo } 134283766Sgrembo} 135283766Sgrembo