# HG changeset patch # User Thomas Wuerthinger # Date 1433286618 -7200 # Node ID 7355942cb270654040bfdd677287fc1d9f0fc6b9 # Parent 5731adc3a10aa731ef1f8723fb6c1475149885c9 Improve lowering of the type check node. diff -r 5731adc3a10a -r 7355942cb270 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Jun 02 23:20:46 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Wed Jun 03 01:10:18 2015 +0200 @@ -33,6 +33,7 @@ import com.oracle.jvmci.meta.ResolvedJavaType; import com.oracle.jvmci.meta.ForeignCallDescriptor; import com.oracle.jvmci.meta.Kind; + import static com.oracle.jvmci.meta.LocationIdentity.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProviderImpl.*; @@ -129,7 +130,7 @@ } } else if (n instanceof TypeCheckNode) { if (graph.getGuardsStage().areDeoptsFixed()) { - instanceofSnippets.lower((TypeCheckNode) n, tool); + lowerTypeCheckNode((TypeCheckNode) n, tool, graph); } } else if (n instanceof InstanceOfDynamicNode) { if (graph.getGuardsStage().areDeoptsFixed()) { @@ -211,6 +212,13 @@ } } + private void lowerTypeCheckNode(TypeCheckNode n, LoweringTool tool, StructuredGraph graph) { + ValueNode hub = createReadHub(graph, n.getValue(), null); + ValueNode clazz = graph.unique(ConstantNode.forConstant(KlassPointerStamp.klass(), n.type().getObjectHub(), tool.getMetaAccess())); + LogicNode objectEquals = graph.unique(PointerEqualsNode.create(hub, clazz)); + n.replaceAndDelete(objectEquals); + } + private void lowerKlassLayoutHelperNode(KlassLayoutHelperNode n, LoweringTool tool) { if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) { return; diff -r 5731adc3a10a -r 7355942cb270 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 Tue Jun 02 23:20:46 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Jun 03 01:10:18 2015 +0200 @@ -182,7 +182,7 @@ if (x.stamp() instanceof AbstractObjectStamp) { comparison = ObjectEqualsNode.create(x, y, constantReflection); } else if (x.stamp() instanceof AbstractPointerStamp) { - comparison = new PointerEqualsNode(x, y); + comparison = PointerEqualsNode.create(x, y); } else { assert x.getKind().isNumericInteger(); comparison = IntegerEqualsNode.create(x, y, constantReflection); diff -r 5731adc3a10a -r 7355942cb270 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Tue Jun 02 23:20:46 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Wed Jun 03 01:10:18 2015 +0200 @@ -41,6 +41,14 @@ this(TYPE, x, y); } + public static LogicNode create(ValueNode x, ValueNode y) { + LogicNode result = findSynonym(x, y); + if (result != null) { + return result; + } + return new PointerEqualsNode(x, y); + } + protected PointerEqualsNode(NodeClass c, ValueNode x, ValueNode y) { super(c, Condition.EQ, false, x, y); assert x.stamp() instanceof AbstractPointerStamp; diff -r 5731adc3a10a -r 7355942cb270 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/GetClassNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/GetClassNode.java Tue Jun 02 23:20:46 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/GetClassNode.java Wed Jun 03 01:10:18 2015 +0200 @@ -48,6 +48,7 @@ public GetClassNode(Stamp stamp, ValueNode object) { super(TYPE, stamp); this.object = object; + assert ((ObjectStamp) object.stamp()).nonNull(); } @Override diff -r 5731adc3a10a -r 7355942cb270 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java Tue Jun 02 23:20:46 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java Wed Jun 03 01:10:18 2015 +0200 @@ -27,13 +27,13 @@ import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.meta.*; import com.oracle.jvmci.meta.Assumptions.AssumptionResult; /** - * The {@code TypeCheckNode} represents a test equivalent to (o != null && o.getClass() == type). + * The {@code TypeCheckNode} represents a test equivalent to {@code o.getClass() == type}. The node + * may only be used if {@code o != null} is known to be true as indicated by the object's stamp. */ @NodeInfo public final class TypeCheckNode extends UnaryOpLogicNode implements Lowerable, Virtualizable { @@ -41,7 +41,7 @@ protected final ResolvedJavaType type; - public TypeCheckNode(ResolvedJavaType type, ValueNode object) { + protected TypeCheckNode(ResolvedJavaType type, ValueNode object) { super(TYPE, object); this.type = type; assert type != null; @@ -50,7 +50,8 @@ public static LogicNode create(ResolvedJavaType type, ValueNode object) { ObjectStamp objectStamp = (ObjectStamp) object.stamp(); - LogicNode constantValue = findSynonym(type, objectStamp.type(), objectStamp.nonNull(), objectStamp.isExactType()); + assert objectStamp.nonNull() : object; + LogicNode constantValue = findSynonym(type, objectStamp.type(), true, objectStamp.isExactType()); if (constantValue != null) { return constantValue; } else { @@ -69,13 +70,11 @@ return this; } ObjectStamp objectStamp = (ObjectStamp) forValue.stamp(); - if (objectStamp.alwaysNull()) { - return LogicConstantNode.contradiction(); - } + assert objectStamp.nonNull(); ResolvedJavaType stampType = objectStamp.type(); if (stampType != null) { - ValueNode result = check(forValue, stampType, objectStamp.nonNull(), objectStamp.isExactType()); + ValueNode result = findSynonym(type(), stampType, true, objectStamp.isExactType()); if (result != null) { return result; } @@ -83,7 +82,7 @@ if (assumptions != null) { AssumptionResult leafConcreteSubtype = stampType.findLeafConcreteSubtype(); if (leafConcreteSubtype != null) { - result = check(forValue, leafConcreteSubtype.getResult(), objectStamp.nonNull(), true); + result = findSynonym(type(), leafConcreteSubtype.getResult(), true, true); if (result != null) { assumptions.record(leafConcreteSubtype); return result; @@ -94,22 +93,6 @@ return this; } - private ValueNode check(ValueNode forValue, ResolvedJavaType inputType, boolean nonNull, boolean exactType) { - ValueNode result = findSynonym(type(), inputType, nonNull, exactType); - if (result != null) { - return result; - } - if (type().equals(inputType)) { - boolean mightBeNull = !nonNull; - if (exactType && mightBeNull) { - // the instanceof matches if the object is non-null, so return true - // depending on the null-ness. - return LogicNegationNode.create(new IsNullNode(forValue)); - } - } - return null; - } - public static LogicNode findSynonym(ResolvedJavaType type, ResolvedJavaType inputType, boolean nonNull, boolean exactType) { if (inputType == null) { return null;