# HG changeset patch # User Christian Haeubl # Date 1329505339 28800 # Node ID 495a81cd6969c95e2a22fdf7737d6e529b97e884 # Parent f35c183f33cea48dc66fa34944665ddf8576f6d6 avoid code generation for typechecks that are only used for anchoring diff -r f35c183f33ce -r 495a81cd6969 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Feb 17 10:34:34 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Feb 17 11:02:19 2012 -0800 @@ -521,8 +521,10 @@ @Override public void visitCheckCast(CheckCastNode x) { - XirSnippet snippet = xir.genCheckCast(site(x), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact()); - emitXir(snippet, x, state(), true); + if (x.emitCode()) { + XirSnippet snippet = xir.genCheckCast(site(x), 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 f35c183f33ce -r 495a81cd6969 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Fri Feb 17 10:34:34 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Fri Feb 17 11:02:19 2012 -0800 @@ -178,8 +178,7 @@ AnchorNode anchor = graph.add(new AnchorNode()); assert invoke.predecessor() != null; - ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(type.getEncoding(Representation.ObjectHub), runtime, graph)); - CheckCastNode checkCast = graph.unique(new CheckCastNode(anchor, typeConst, type, receiver)); + CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, anchor, type, receiver); invoke.callTarget().replaceFirstInput(receiver, checkCast); graph.addBeforeFixed(invoke.node(), objectClass); @@ -326,11 +325,10 @@ for (int i = 0; i < calleeEntryNodes.length; i++) { BeginNode node = calleeEntryNodes[i]; Invoke invokeForInlining = (Invoke) node.next(); + RiResolvedType commonType = getLeastCommonType(i); - ValueNode receiver = invokeForInlining.callTarget().receiver(); - ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(commonType.getEncoding(Representation.ObjectHub), runtime, graph)); - CheckCastNode checkCast = graph.unique(new CheckCastNode(node, typeConst, commonType, receiver)); + CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, node, commonType, receiver); invokeForInlining.callTarget().replaceFirstInput(receiver, checkCast); RiResolvedMethod concrete = concretes.get(i); @@ -661,6 +659,13 @@ } } + private static CheckCastNode createAnchoredReceiver(StructuredGraph graph, GraalRuntime runtime, 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; + } + private static void convertTypeToBranchProbabilities(double[] typeProbabilities, double notRecordedTypeProbability) { // avoid branches with 0.0/1.0 probability double total = Math.max(1E-10, notRecordedTypeProbability); diff -r f35c183f33ce -r 495a81cd6969 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java Fri Feb 17 10:34:34 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java Fri Feb 17 11:02:19 2012 -0800 @@ -38,11 +38,16 @@ public final class CheckCastNode extends TypeCheckNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType { @Input protected final FixedNode anchor; + @Data protected final boolean emitCode; public FixedNode anchor() { return anchor; } + public boolean emitCode() { + return emitCode; + } + /** * Creates a new CheckCast instruction. * @@ -54,9 +59,18 @@ 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