# HG changeset patch # User Lukas Stadler # Date 1398329052 -7200 # Node ID 1c347436d596d5170eb86b37911d3c503ae71573 # Parent 78882562556b3263e69539f45c0e45af806fc5ca added UnaryOpLogicNode base class, renamed BinaryLogicNode diff -r 78882562556b -r 1c347436d596 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryLogicNode.java Thu Apr 24 08:38:00 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011, 2014, 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 com.oracle.graal.nodes; - -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; - -public abstract class BinaryLogicNode extends LogicNode implements LIRLowerable, MemoryArithmeticLIRLowerable { - - @Input private ValueNode x; - @Input private ValueNode y; - - public ValueNode x() { - return x; - } - - public ValueNode y() { - return y; - } - - protected void setX(ValueNode x) { - updateUsages(this.x, x); - this.x = x; - } - - protected void setY(ValueNode y) { - updateUsages(this.y, y); - this.y = y; - } - - public BinaryLogicNode(ValueNode x, ValueNode y) { - assert x != null && y != null && x.getKind() == y.getKind(); - this.x = x; - this.y = y; - } - - @Override - public boolean verify() { - assertTrue(x.stamp().isCompatible(y.stamp()), "stamps not compatible: %s, %s", x.stamp(), y.stamp()); - return super.verify(); - } - - @Override - public void generate(NodeLIRBuilderTool gen) { - } - - @Override - public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { - return false; - } -} diff -r 78882562556b -r 1c347436d596 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Thu Apr 24 10:44:12 2014 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011, 2014, 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 com.oracle.graal.nodes; + +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; + +public abstract class BinaryOpLogicNode extends LogicNode implements LIRLowerable, MemoryArithmeticLIRLowerable { + + @Input private ValueNode x; + @Input private ValueNode y; + + public ValueNode x() { + return x; + } + + public ValueNode y() { + return y; + } + + protected void setX(ValueNode x) { + updateUsages(this.x, x); + this.x = x; + } + + protected void setY(ValueNode y) { + updateUsages(this.y, y); + this.y = y; + } + + public BinaryOpLogicNode(ValueNode x, ValueNode y) { + assert x != null && y != null && x.getKind() == y.getKind(); + this.x = x; + this.y = y; + } + + @Override + public boolean verify() { + assertTrue(x.stamp().isCompatible(y.stamp()), "stamps not compatible: %s, %s", x.stamp(), y.stamp()); + return super.verify(); + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + return false; + } +} diff -r 78882562556b -r 1c347436d596 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java Thu Apr 24 10:44:12 2014 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011, 2014, 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 com.oracle.graal.nodes; + +import com.oracle.graal.api.meta.ProfilingInfo.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; + +public abstract class UnaryOpLogicNode extends LogicNode implements LIRLowerable, MemoryArithmeticLIRLowerable { + + @Input private ValueNode object; + + public ValueNode object() { + return object; + } + + protected void setX(ValueNode object) { + updateUsages(this.object, object); + this.object = object; + } + + public UnaryOpLogicNode(ValueNode object) { + assert object != null; + this.object = object; + } + + public abstract TriState evaluate(ValueNode forObject); + + @Override + public void generate(NodeLIRBuilderTool gen) { + } + + @Override + public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) { + return false; + } +} diff -r 78882562556b -r 1c347436d596 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Thu Apr 24 08:38:00 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Thu Apr 24 10:44:12 2014 +0200 @@ -35,7 +35,7 @@ * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed * into variants that do not materialize the value (CompareIf, CompareGuard...) */ -public abstract class CompareNode extends BinaryLogicNode implements Canonicalizable { +public abstract class CompareNode extends BinaryOpLogicNode implements Canonicalizable { /** * Constructs a new Compare instruction. diff -r 78882562556b -r 1c347436d596 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Thu Apr 24 08:38:00 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Thu Apr 24 10:44:12 2014 +0200 @@ -32,7 +32,7 @@ * expression "(x & y) == 0", meaning that it will return true if (and only if) no bit is set in * both x and y. */ -public class IntegerTestNode extends BinaryLogicNode implements Canonicalizable { +public class IntegerTestNode extends BinaryOpLogicNode implements Canonicalizable { /** * Constructs a new Test instruction. diff -r 78882562556b -r 1c347436d596 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Thu Apr 24 08:38:00 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Thu Apr 24 10:44:12 2014 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -33,21 +34,15 @@ /** * An IsNullNode will be true if the supplied value is null, and false if it is non-null. */ -public final class IsNullNode extends LogicNode implements Canonicalizable, LIRLowerable, Virtualizable, PiPushable { - - @Input private ValueNode object; - - public ValueNode object() { - return object; - } +public final class IsNullNode extends UnaryOpLogicNode implements Canonicalizable, LIRLowerable, Virtualizable, PiPushable { /** * Constructs a new IsNullNode instruction. - * + * * @param object the instruction producing the object to check against null */ public IsNullNode(ValueNode object) { - this.object = object; + super(object); } @Override @@ -64,20 +59,31 @@ @Override public Node canonical(CanonicalizerTool tool) { - Constant constant = object().asConstant(); - if (constant != null) { - assert constant.getKind() == Kind.Object; - return LogicConstantNode.forBoolean(constant.isNull(), graph()); - } - if (StampTool.isObjectNonNull(object.stamp())) { - return LogicConstantNode.contradiction(graph()); + switch (evaluate(object())) { + case FALSE: + return LogicConstantNode.contradiction(graph()); + case TRUE: + return LogicConstantNode.tautology(graph()); } return this; } @Override + public TriState evaluate(ValueNode forObject) { + Constant constant = forObject.asConstant(); + if (constant != null) { + assert constant.getKind() == Kind.Object; + return TriState.get(constant.isNull()); + } + if (StampTool.isObjectNonNull(forObject.stamp())) { + return TriState.FALSE; + } + return TriState.UNKNOWN; + } + + @Override public void virtualize(VirtualizerTool tool) { - if (tool.getObjectState(object) != null) { + if (tool.getObjectState(object()) != null) { tool.replaceWithValue(LogicConstantNode.contradiction(graph())); } } diff -r 78882562556b -r 1c347436d596 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Apr 24 08:38:00 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Apr 24 10:44:12 2014 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -33,21 +34,20 @@ /** * The {@code InstanceOfNode} represents an instanceof test. */ -public final class InstanceOfNode extends LogicNode implements Canonicalizable, Lowerable, Virtualizable { +public final class InstanceOfNode extends UnaryOpLogicNode implements Canonicalizable, Lowerable, Virtualizable { - @Input private ValueNode object; private final ResolvedJavaType type; private JavaTypeProfile profile; /** * Constructs a new InstanceOfNode. - * + * * @param type the target type of the instanceof check * @param object the object being tested by the instanceof */ public InstanceOfNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) { + super(object); this.type = type; - this.object = object; this.profile = profile; assert type != null; } @@ -59,13 +59,39 @@ @Override public Node canonical(CanonicalizerTool tool) { - Stamp stamp = object().stamp(); + switch (evaluate(object())) { + case FALSE: + return LogicConstantNode.contradiction(graph()); + case TRUE: + return LogicConstantNode.tautology(graph()); + case UNKNOWN: + Stamp stamp = object().stamp(); + if (stamp instanceof ObjectStamp) { + ObjectStamp objectStamp = (ObjectStamp) stamp; + ResolvedJavaType stampType = objectStamp.type(); + if (stampType != null && type().isAssignableFrom(stampType)) { + if (!objectStamp.nonNull()) { + // the instanceof matches if the object is non-null, so return true + // depending on the null-ness. + IsNullNode isNull = graph().unique(new IsNullNode(object())); + return graph().unique(new LogicNegationNode(isNull)); + } + } + } + return this; + } + return this; + } + + @Override + public TriState evaluate(ValueNode forObject) { + Stamp stamp = forObject.stamp(); if (!(stamp instanceof ObjectStamp)) { - return this; + return TriState.UNKNOWN; } ObjectStamp objectStamp = (ObjectStamp) stamp; if (objectStamp.alwaysNull()) { - return LogicConstantNode.contradiction(graph()); + return TriState.FALSE; } ResolvedJavaType stampType = objectStamp.type(); @@ -74,34 +100,25 @@ if (subType) { if (objectStamp.nonNull()) { // the instanceOf matches, so return true - return LogicConstantNode.tautology(graph()); - } else { - // the instanceof matches if the object is non-null, so return true depending on - // the null-ness. - IsNullNode isNull = graph().unique(new IsNullNode(object())); - return graph().unique(new LogicNegationNode(isNull)); + return TriState.TRUE; } } else { if (objectStamp.isExactType()) { // since this type check failed for an exact type we know that it can never // succeed at run time. we also don't care about null values, since they will // also make the check fail. - return LogicConstantNode.contradiction(graph()); + return TriState.FALSE; } else { boolean superType = stampType.isAssignableFrom(type()); if (!superType && !stampType.isInterface() && !type().isInterface()) { - return LogicConstantNode.contradiction(graph()); + return TriState.FALSE; } // since the subtype comparison was only performed on a declared type we don't // really know if it might be true at run time... } } } - return this; - } - - public ValueNode object() { - return object; + return TriState.UNKNOWN; } /** @@ -121,7 +138,7 @@ @Override public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(object); + State state = tool.getObjectState(object()); if (state != null) { tool.replaceWithValue(LogicConstantNode.forBoolean(type().isAssignableFrom(state.getVirtualObject().type()), graph())); }