changeset 6290:01d274503562

canonicalize reads and writes on null objects to deopts
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 28 Aug 2012 12:15:10 +0200
parents 72eb3a1a20c4
children 904517c1cd06
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MaterializeObjectNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java
diffstat 9 files changed, 45 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Tue Aug 28 12:15:10 2012 +0200
@@ -152,7 +152,7 @@
             if (state instanceof MaterializedObjectState) {
                 return toValue(((MaterializedObjectState) state).materializedValue());
             } else {
-                assert state instanceof VirtualObjectState;
+                assert obj.fieldsCount() == 0 || state instanceof VirtualObjectState;
                 VirtualObject ciObj = virtualObjects.get(value);
                 if (ciObj == null) {
                     ciObj = VirtualObject.get(obj.type(), null, virtualObjects.size());
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java	Tue Aug 28 12:15:10 2012 +0200
@@ -180,6 +180,7 @@
 
     public static boolean tryCanonicalize(final Node node, final StructuredGraph graph, final SimplifierTool tool) {
         if (node instanceof Canonicalizable) {
+            assert !(node instanceof Simplifiable);
             METRIC_CANONICALIZATION_CONSIDERED_NODES.increment();
             return Debug.scope("CanonicalizeNode", node, new Callable<Boolean>(){
                 public Boolean call() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Tue Aug 28 12:15:10 2012 +0200
@@ -53,6 +53,11 @@
 
     @Override
     public boolean inferStamp() {
+        if (object().objectStamp().alwaysNull() && objectStamp().nonNull()) {
+            // a null value flowing into a nonNull PiNode can happen should be guarded by a type/isNull guard, but the
+            // compiler might see this situation before the branch is deleted
+            return false;
+        }
         return updateStamp(stamp().join(object().stamp()));
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Tue Aug 28 12:15:10 2012 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.extended;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -31,7 +32,7 @@
 /**
  * Reads an {@linkplain AccessNode accessed} value.
  */
-public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable/*, Canonicalizable*/ {
+public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Simplifiable/*, Canonicalizable*/ {
 
     public ReadNode(ValueNode object, LocationNode location, Stamp stamp) {
         super(object, location, stamp);
@@ -42,7 +43,7 @@
         gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck()));
     }
 
-    // Canonicalization disabled untill we have a solution for non-Object oops in Hotspot
+    // Canonicalization disabled until we have a solution for non-Object oops in Hotspot
     /*@Override
     public ValueNode canonical(CanonicalizerTool tool) {
         return canonicalizeRead(this, tool);
@@ -64,4 +65,16 @@
         }
         return (ValueNode) read;
     }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (object().isConstant() && object().asConstant().isNull()) {
+            FixedNode successor = next();
+            tool.deleteBranch(successor);
+            if (isAlive()) {
+                replaceAtPredecessor(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException)));
+                safeDelete();
+            }
+        }
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Tue Aug 28 12:15:10 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.extended;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -30,7 +32,7 @@
 /**
  * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}.
  */
-public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable {
+public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, Simplifiable {
     @Input private ValueNode value;
     @Input(notDataflow = true) private FrameState stateAfter;
 
@@ -61,4 +63,16 @@
     public void generate(LIRGeneratorTool gen) {
         gen.emitStore(gen.makeAddress(location(), object()), gen.operand(value()), getNullCheck());
     }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (object().isConstant() && object().asConstant().isNull()) {
+            FixedNode successor = next();
+            tool.deleteBranch(successor);
+            if (isAlive()) {
+                replaceAtPredecessor(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException)));
+                safeDelete();
+            }
+        }
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Tue Aug 28 12:15:10 2012 +0200
@@ -24,13 +24,14 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 /**
  * The {@code AccessIndexedNode} class is the base class of instructions that read or write
  * elements of an array.
  */
-public abstract class AccessIndexedNode extends AccessArrayNode {
+public abstract class AccessIndexedNode extends AccessArrayNode implements Lowerable {
 
     @Input private ValueNode index;
     private final Kind elementType;
@@ -65,4 +66,9 @@
     public long leafGraphId() {
         return leafGraphId;
     }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Tue Aug 28 12:15:10 2012 +0200
@@ -33,7 +33,7 @@
 /**
  * The {@code LoadIndexedNode} represents a read from an element of an array.
  */
-public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Lowerable, Node.IterableNodeType {
+public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Node.IterableNodeType {
 
     /**
      * Creates a new LoadIndexedNode.
@@ -54,11 +54,6 @@
     }
 
     @Override
-    public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
-    }
-
-    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         MetaAccessProvider runtime = tool.runtime();
         if (runtime != null && index().isConstant() && array().isConstant() && !array().isNullConstant()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MaterializeObjectNode.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MaterializeObjectNode.java	Tue Aug 28 12:15:10 2012 +0200
@@ -25,7 +25,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Tue Aug 28 11:27:39 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Tue Aug 28 12:15:10 2012 +0200
@@ -64,9 +64,4 @@
         super(StampFactory.forVoid(), array, index, elementKind, leafGraphId);
         this.value = value;
     }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
-    }
 }