# HG changeset patch # User Lukas Stadler # Date 1335963351 -7200 # Node ID e8f80481326db41534d4fddb231ad3a77d65a897 # Parent 17a84768b1cdaa5ff98d27c6c90f4d676303c8b7 use PiNodes instead of CheckCastNodes to pin inlining receivers, remove emitCode flag diff -r 17a84768b1cd -r e8f80481326d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed May 02 14:53:20 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed May 02 14:55:51 2012 +0200 @@ -509,10 +509,8 @@ @Override public void visitCheckCast(CheckCastNode x) { - if (x.emitCode()) { - XirSnippet snippet = xir.genCheckCast(site(x, x.object()), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact()); - emitXir(snippet, x, state(), true); - } + XirSnippet snippet = xir.genCheckCast(site(x, x.object()), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact()); + emitXir(snippet, x, state(), true); // The result of a checkcast is the unmodified object, so no need to allocate a new variable for it. setResult(x, operand(x.object())); } diff -r 17a84768b1cd -r e8f80481326d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Wed May 02 14:53:20 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Wed May 02 14:55:51 2012 +0200 @@ -26,9 +26,6 @@ import java.util.*; import java.util.concurrent.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; -import com.oracle.max.cri.ri.RiType.Representation; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; import com.oracle.graal.cri.*; @@ -40,7 +37,10 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; public class InliningUtil { @@ -193,8 +193,8 @@ AnchorNode anchor = graph.add(new AnchorNode()); assert invoke.predecessor() != null; - CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, anchor, type, receiver); - invoke.callTarget().replaceFirstInput(receiver, checkCast); + ValueNode anchoredReceiver = createAnchoredReceiver(graph, anchor, type, receiver); + invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver); graph.addBeforeFixed(invoke.node(), objectClass); graph.addBeforeFixed(invoke.node(), guard); @@ -348,8 +348,8 @@ RiResolvedType commonType = getLeastCommonType(i); ValueNode receiver = invokeForInlining.callTarget().receiver(); - CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, node, commonType, receiver); - invokeForInlining.callTarget().replaceFirstInput(receiver, checkCast); + ValueNode anchoredReceiver = createAnchoredReceiver(graph, node, commonType, receiver); + invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver); RiResolvedMethod concrete = concretes.get(i); StructuredGraph calleeGraph = getGraph(concrete, callback); @@ -693,11 +693,9 @@ } } - private static CheckCastNode createAnchoredReceiver(StructuredGraph graph, GraalRuntime runtime, FixedNode anchor, RiResolvedType commonType, ValueNode receiver) { + private static ValueNode createAnchoredReceiver(StructuredGraph graph, FixedNode anchor, RiResolvedType commonType, ValueNode receiver) { // to avoid that floating reads on receiver fields float above the type check - ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(commonType.getEncoding(Representation.ObjectHub), runtime, graph)); - CheckCastNode checkCast = graph.unique(new CheckCastNode(anchor, typeConst, commonType, receiver, false)); - return checkCast; + return graph.unique(new PiNode(receiver, anchor, StampFactory.declaredNonNull(commonType))); } private static boolean checkInvokeConditions(Invoke invoke) { diff -r 17a84768b1cd -r e8f80481326d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NullCheckNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NullCheckNode.java Wed May 02 14:53:20 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NullCheckNode.java Wed May 02 14:55:51 2012 +0200 @@ -28,6 +28,10 @@ import com.oracle.graal.nodes.spi.types.*; import com.oracle.graal.nodes.type.*; +/** + * A NullCheckNode will be true if the supplied value is non-null, and false if it is null. + * This behavior can be inverted by setting {@link #expectedNull} to true. + */ public final class NullCheckNode extends BooleanNode implements Canonicalizable, LIRLowerable, ConditionalTypeFeedbackProvider, TypeCanonicalizable { @Input private ValueNode object; diff -r 17a84768b1cd -r e8f80481326d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Wed May 02 14:53:20 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Wed May 02 14:55:51 2012 +0200 @@ -40,16 +40,11 @@ public final class CheckCastNode extends TypeCheckNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, TypeFeedbackProvider, TypeCanonicalizable { @Input(notDataflow = true) protected final FixedNode anchor; - protected final boolean emitCode; public FixedNode anchor() { return anchor; } - public boolean emitCode() { - return emitCode; - } - /** * Creates a new CheckCast instruction. * @@ -61,18 +56,9 @@ this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false); } - public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, boolean emitCode) { - this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false, emitCode); - } - public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact) { - this(anchor, targetClassInstruction, targetClass, object, hints, hintsExact, true); - } - - private CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, boolean emitCode) { super(targetClassInstruction, targetClass, object, hints, hintsExact, targetClass == null ? StampFactory.forKind(CiKind.Object) : StampFactory.declared(targetClass)); this.anchor = anchor; - this.emitCode = emitCode; } @Override @@ -82,12 +68,16 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { + assert object() != null : this; + RiResolvedType objectDeclaredType = object().declaredType(); RiResolvedType targetClass = targetClass(); if (objectDeclaredType != null && targetClass != null && objectDeclaredType.isSubtypeOf(targetClass)) { + // we don't have to check for null types here because they will also pass the checkcast. freeAnchor(); return object(); } + CiConstant constant = object().asConstant(); if (constant != null) { assert constant.kind == CiKind.Object;