changeset 4636:495a81cd6969

avoid code generation for typechecks that are only used for anchoring
author Christian Haeubl <christian.haeubl@oracle.com>
date Fri, 17 Feb 2012 11:02:19 -0800
parents f35c183f33ce
children 5a5c603f7e0f
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java
diffstat 3 files changed, 28 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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()));
     }
--- 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);
--- 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