changeset 3032:2433838f0414

Create null checks as guard nodes.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Mon, 20 Jun 2011 15:14:36 +0200
parents 7f807764e7fc
children ebd1d48a1ae1
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/ir/Compare.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java
diffstat 10 files changed, 100 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Mon Jun 20 15:14:36 2011 +0200
@@ -407,20 +407,7 @@
 
     @Override
     public void visitGuardNode(GuardNode x) {
-        FrameState state = lastState;
-        assert state != null : "deoptimize instruction always needs a state";
-
-        if (deoptimizationStubs == null) {
-            deoptimizationStubs = new ArrayList<DeoptimizationStub>();
-        }
-
-        DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state);
-        deoptimizationStubs.add(stub);
-
-        emitCompare(x.node());
-        //emitBranch(x.node(), stub.label)
-        throw new RuntimeException();
-        //lir.branch(x.condition.negate(), stub.label, stub.info);
+        emitGuardComp(x.node());
     }
 
 
@@ -453,28 +440,38 @@
 
     @Override
     public void visitIf(If x) {
-        emitCompare(x.compare());
-        emitBranch(x.compare(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()));
+        Condition cond = emitBooleanBranch(x.compare());
+        emitBranch(x.compare(), cond, getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()));
         assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination above";
         LIRBlock block = getLIRBlock(x.defaultSuccessor());
         assert block != null : x;
         lir.jump(block);
     }
 
-    public void emitBranch(Compare compare, LIRBlock trueSuccessor, LIRBlock falseSucc) {
-        Condition cond = compare.condition();
-        if (compare.x().kind.isFloat() || compare.x().kind.isDouble()) {
-            LIRBlock unorderedSuccBlock = falseSucc;
-            if (compare.unorderedIsTrue()) {
-                unorderedSuccBlock = trueSuccessor;
+    public void emitBranch(BooleanNode n, Condition cond, LIRBlock trueSuccessor, LIRBlock falseSucc) {
+        if (n instanceof Compare) {
+            Compare compare = (Compare) n;
+            if (compare.x().kind.isFloat() || compare.x().kind.isDouble()) {
+                LIRBlock unorderedSuccBlock = falseSucc;
+                if (compare.unorderedIsTrue()) {
+                    unorderedSuccBlock = trueSuccessor;
+                }
+                lir.branch(cond, trueSuccessor, unorderedSuccBlock);
+                return;
             }
-            lir.branch(cond, trueSuccessor, unorderedSuccBlock);
+        }
+        lir.branch(cond, trueSuccessor);
+    }
+
+    public Condition emitBooleanBranch(BooleanNode node) {
+        if (node instanceof Compare) {
+            return emitCompare((Compare) node);
         } else {
-            lir.branch(cond, trueSuccessor);
+            throw Util.unimplemented();
         }
     }
 
-    public void emitCompare(Compare compare) {
+    public Condition emitCompare(Compare compare) {
         CiKind kind = compare.x().kind;
 
         Condition cond = compare.condition();
@@ -505,6 +502,7 @@
         CiValue left = xin.result();
         CiValue right = yin.result();
         lir.cmp(cond, left, right);
+        return cond;
     }
 
     @Override
@@ -700,11 +698,11 @@
 
     @Override
     public void visitFixedGuard(FixedGuard fixedGuard) {
-        Node comp = fixedGuard.node();
+        BooleanNode comp = fixedGuard.node();
         emitGuardComp(comp);
     }
 
-    public void emitGuardComp(Node comp) {
+    public void emitGuardComp(BooleanNode comp) {
         if (comp instanceof IsNonNull) {
             IsNonNull x = (IsNonNull) comp;
             CiValue value = load(x.object());
@@ -717,6 +715,19 @@
             XirArgument clazz = toXirArgument(x.type().getEncoding(Representation.ObjectHub));
             XirSnippet typeCheck = xir.genTypeCheck(site(x), toXirArgument(x.object()), clazz, x.type());
             emitXir(typeCheck, x, info, compilation.method, false);
+        } else {
+            FrameState state = lastState;
+            assert state != null : "deoptimize instruction always needs a state";
+
+            if (deoptimizationStubs == null) {
+                deoptimizationStubs = new ArrayList<DeoptimizationStub>();
+            }
+
+            DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state);
+            deoptimizationStubs.add(stub);
+
+            Condition cond = emitBooleanBranch(comp);
+            lir.branch(cond.negate(), stub.label, stub.info);
         }
     }
 
@@ -1427,9 +1438,6 @@
 
     @Override
     public void visitMemoryRead(MemoryRead memRead) {
-        if (memRead.guard() != null) {
-            emitGuardComp(memRead.guard());
-        }
         lir.move(new CiAddress(memRead.valueKind(), load(memRead.location()), memRead.displacement()), createResultVariable(memRead), memRead.valueKind());
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Mon Jun 20 15:14:36 2011 +0200
@@ -34,7 +34,7 @@
  * into variants that do not materialize the value (CompareIf, CompareGuard...)
  *
  */
-public final class Compare extends FloatingNode {
+public final class Compare extends BooleanNode {
 
     private static final int INPUT_COUNT = 2;
     private static final int INPUT_X = 0;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Mon Jun 20 15:14:36 2011 +0200
@@ -36,12 +36,12 @@
     /**
      * The instruction that produces the object tested against null.
      */
-     public FloatingNode node() {
-        return (FloatingNode) inputs().get(super.inputCount() + INPUT_NODE);
+     public BooleanNode node() {
+        return (BooleanNode) inputs().get(super.inputCount() + INPUT_NODE);
     }
 
-    public FloatingNode setNode(FloatingNode n) {
-        return (FloatingNode) inputs().set(super.inputCount() + INPUT_NODE, n);
+    public void setNode(BooleanNode n) {
+        inputs().set(super.inputCount() + INPUT_NODE, n);
     }
 
     public FixedGuard(Graph graph) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Mon Jun 20 15:14:36 2011 +0200
@@ -27,21 +27,30 @@
 import com.sun.cri.ci.*;
 
 
-public final class GuardNode extends Instruction {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_NODE = 0;
+public final class GuardNode extends FloatingNode {
+    private static final int INPUT_COUNT = 2;
+    private static final int INPUT_ANCHOR = 0;
+    private static final int INPUT_NODE = 1;
 
     private static final int SUCCESSOR_COUNT = 0;
 
+    public FixedNode anchor() {
+        return (FixedNode) inputs().get(super.inputCount() + INPUT_ANCHOR);
+    }
+
+    public void setAnchor(FixedNode anchor) {
+        inputs().set(super.inputCount() + INPUT_ANCHOR, anchor);
+    }
+
     /**
      * The instruction that produces the object tested against null.
      */
-     public Compare node() {
-        return (Compare) inputs().get(super.inputCount() + INPUT_NODE);
+    public BooleanNode node() {
+        return (BooleanNode) inputs().get(super.inputCount() + INPUT_NODE);
     }
 
-    public Compare setNode(Compare n) {
-        return (Compare) inputs().set(super.inputCount() + INPUT_NODE, n);
+    public void setNode(BooleanNode n) {
+        inputs().set(super.inputCount() + INPUT_NODE, n);
     }
 
     public GuardNode(Graph graph) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java	Mon Jun 20 15:14:36 2011 +0200
@@ -50,17 +50,17 @@
     /**
      * The instruction that produces the first input to this comparison.
      */
-     public Compare compare() {
-        return (Compare) inputs().get(super.inputCount() + INPUT_COMPARE);
+     public BooleanNode compare() {
+        return (BooleanNode) inputs().get(super.inputCount() + INPUT_COMPARE);
     }
 
-    public Value setCompare(Compare n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_COMPARE, n);
+    public void setCompare(BooleanNode n) {
+        inputs().set(super.inputCount() + INPUT_COMPARE, n);
     }
 
-    public If(Compare compare, Graph graph) {
+    public If(BooleanNode condition, Graph graph) {
         super(CiKind.Illegal, 2, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-        setCompare(compare);
+        setCompare(condition);
     }
 
     /**
@@ -96,11 +96,7 @@
     @Override
     public void print(LogStream out) {
         out.print("if ").
-        print(compare().x()).
-        print(' ').
-        print(compare().condition().operator).
-        print(' ').
-        print(compare().y()).
+        print(compare()).
         print(" then ").
         print(trueSuccessor()).
         print(" else ").
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Mon Jun 20 15:14:36 2011 +0200
@@ -32,7 +32,7 @@
 /**
  * The {@code NullCheck} class represents an explicit null check instruction.
  */
-public final class IsNonNull extends FloatingNode {
+public final class IsNonNull extends BooleanNode {
 
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_OBJECT = 0;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Mon Jun 20 15:14:36 2011 +0200
@@ -34,7 +34,7 @@
 /**
  * The {@code TypeCheck} class represents an explicit type check instruction.
  */
-public final class IsType extends FloatingNode {
+public final class IsType extends BooleanNode {
 
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_OBJECT = 0;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java	Mon Jun 20 15:14:36 2011 +0200
@@ -51,12 +51,12 @@
     /**
      * The instruction that produces the object tested against null.
      */
-     public FloatingNode guard() {
-        return (FloatingNode) inputs().get(super.inputCount() + INPUT_GUARD);
+     public GuardNode guard() {
+        return (GuardNode) inputs().get(super.inputCount() + INPUT_GUARD);
     }
 
-    public FloatingNode setGuard(FloatingNode n) {
-        return (FloatingNode) inputs().set(super.inputCount() + INPUT_GUARD, n);
+    public void setGuard(GuardNode n) {
+        inputs().set(super.inputCount() + INPUT_GUARD, n);
     }
 
     public int displacement() {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Mon Jun 20 15:14:36 2011 +0200
@@ -24,7 +24,6 @@
 
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.compiler.schedule.*;
-import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
@@ -50,28 +49,43 @@
         s.apply(graph);
 
         for (Block b : s.getBlocks()) {
-            //final Node firstNode = b.firstNode();
+            final Node[] firstNodeValue = new Node[]{b.firstNode()};
 
             final CiLoweringTool loweringTool = new CiLoweringTool() {
                 @Override
                 public Node getGuardAnchor() {
-                    throw Util.unimplemented();
-//                    if (!(firstNode instanceof Anchor) && !(firstNode instanceof Merge)) {
-//                        Anchor a = new Anchor(graph);
-//                        assert firstNode.predecessors().size() == 1;
-//                        Node pred = firstNode.predecessors().get(0);
-//                        int predIndex = firstNode.predecessorsIndex().get(0);
-//                        a.successors().setAndClear(Instruction.SUCCESSOR_NEXT, pred, predIndex);
-//                        pred.successors().set(predIndex, a);
-//                        return a;
-//                    }
-//                    return firstNode;
+                    Node firstNode = firstNodeValue[0];
+                    if (firstNode == firstNode.graph().start()) {
+                        Anchor a = new Anchor(graph);
+                        a.setNext((FixedNode) firstNode.graph().start().start());
+                        firstNode.graph().start().setStart(a);
+                        firstNodeValue[0] = a;
+                        return a;
+                    } else if (!(firstNode instanceof Anchor) && !(firstNode instanceof Merge)) {
+                        Anchor a = new Anchor(graph);
+                        assert firstNode.predecessors().size() == 1;
+                        Node pred = firstNode.predecessors().get(0);
+                        int predIndex = pred.successors().indexOf(firstNode);
+                        pred.successors().set(predIndex, a);
+                        a.setNext((FixedNode) firstNode);
+                        firstNodeValue[0] = a;
+                        return a;
+                    }
+                    return firstNode;
                 }
 
                 @Override
                 public RiRuntime getRuntime() {
                     return runtime;
                 }
+
+                @Override
+                public Node createGuard(Node condition) {
+                    GuardNode guard = new GuardNode(graph);
+                    guard.setAnchor((FixedNode) getGuardAnchor());
+                    guard.setNode((BooleanNode) condition);
+                    return guard;
+                }
             };
 
             for (final Node n : b.getInstructions()) {
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Mon Jun 20 14:29:16 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Mon Jun 20 15:14:36 2011 +0200
@@ -251,7 +251,7 @@
             int displacement = ((HotSpotField) field.field()).offset();
             assert field.kind != CiKind.Illegal;
             MemoryRead memoryRead = new MemoryRead(field.field().kind(), displacement, graph);
-            memoryRead.setGuard(new IsNonNull(field.object(), graph));
+            memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
             memoryRead.setNext(field.next());
             memoryRead.setLocation(field.object());
             return memoryRead;