changeset 13283:17c9afa0bfcb

Allow GuardLoweringPhase, FrameStateAssignementPhase and the different lowerings to work with graph at any valid guards stage
author Gilles Duboscq <duboscq@ssw.jku.at>
date Wed, 11 Dec 2013 13:29:23 +0100
parents dc4128904f0b
children a3500d145fe1
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java
diffstat 7 files changed, 69 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Thu Dec 05 13:49:42 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Wed Dec 11 13:29:23 2013 +0100
@@ -106,7 +106,7 @@
             ValueNode array = arrayLengthNode.array();
             ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt(),
                             BarrierType.NONE, false));
-            tool.createNullCheckGuard(arrayLengthRead, array);
+            tool.createNullCheckGuard(arrayLengthNode, arrayLengthRead, array);
             graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead);
         } else if (n instanceof Invoke) {
             Invoke invoke = (Invoke) n;
@@ -117,7 +117,7 @@
                 ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
                 GuardingNode receiverNullCheck = null;
                 if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !ObjectStamp.isObjectNonNull(receiver)) {
-                    receiverNullCheck = tool.createNullCheckGuard(invoke, receiver);
+                    receiverNullCheck = tool.createNullCheckGuard(invoke.asNode(), invoke, receiver);
                 }
                 JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
 
@@ -161,7 +161,7 @@
             BarrierType barrierType = getFieldLoadBarrierType(field);
             ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object)));
             graph.replaceFixedWithFixed(loadField, memoryRead);
-            tool.createNullCheckGuard(memoryRead, object);
+            tool.createNullCheckGuard(memoryRead, memoryRead, object);
 
             if (loadField.isVolatile()) {
                 MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
@@ -175,9 +175,9 @@
             ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : storeField.object();
             BarrierType barrierType = getFieldStoreBarrierType(storeField);
             WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object));
-            tool.createNullCheckGuard(memoryWrite, object);
             memoryWrite.setStateAfter(storeField.stateAfter());
             graph.replaceFixedWithFixed(storeField, memoryWrite);
+            tool.createNullCheckGuard(memoryWrite, memoryWrite, object);
             FixedWithNextNode last = memoryWrite;
             FixedWithNextNode first = memoryWrite;
 
@@ -197,11 +197,10 @@
             graph.replaceFixedWithFixed(cas, atomicNode);
         } else if (n instanceof LoadIndexedNode) {
             LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
-            GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool);
             Kind elementKind = loadIndexed.elementKind();
             LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false);
             ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object));
-            memoryRead.setGuard(boundsCheck);
+            memoryRead.setGuard(createBoundsCheck(loadIndexed, tool));
             graph.replaceFixedWithFixed(loadIndexed, memoryRead);
         } else if (n instanceof StoreIndexedNode) {
             StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
@@ -719,11 +718,11 @@
             Stamp stamp = StampFactory.positiveInt();
             ReadNode readArrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, runtime.getConfig().arrayLengthOffset, g), stamp, BarrierType.NONE, false));
             g.addBeforeFixed(n, readArrayLength);
-            tool.createNullCheckGuard(readArrayLength, array);
+            tool.createNullCheckGuard(readArrayLength, readArrayLength, array);
             arrayLength = readArrayLength;
         }
 
-        return tool.createGuard(g.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile);
+        return tool.createGuard(n, g.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile);
     }
 
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Thu Dec 05 13:49:42 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Dec 11 13:29:23 2013 +0100
@@ -63,7 +63,7 @@
     @Override
     public void lower(LoweringTool tool) {
         if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) {
-            ValueNode guard = tool.createGuard(condition(), getReason(), getAction(), isNegated()).asNode();
+            ValueNode guard = tool.createGuard(this, condition(), getReason(), getAction(), isNegated()).asNode();
             this.replaceAtUsages(guard);
             ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(guard.asNode()));
             graph().replaceFixedWithFixed(this, newAnchor);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Thu Dec 05 13:49:42 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Wed Dec 11 13:29:23 2013 +0100
@@ -77,7 +77,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        GuardingNode guard = tool.createGuard(condition, reason, action, negated);
+        GuardingNode guard = tool.createGuard(next(), condition, reason, action, negated);
         ValueAnchorNode anchor = graph().add(new ValueAnchorNode((ValueNode) guard));
         PiNode pi = graph().unique(new PiNode(object, stamp(), (ValueNode) guard));
         replaceAtUsages(pi);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Thu Dec 05 13:49:42 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Wed Dec 11 13:29:23 2013 +0100
@@ -39,11 +39,11 @@
 
     Replacements getReplacements();
 
-    GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object);
+    GuardingNode createNullCheckGuard(FixedNode before, GuardedNode guardedNode, ValueNode object);
 
-    GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action);
+    GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action);
 
-    GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated);
+    GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated);
 
     Assumptions assumptions();
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java	Thu Dec 05 13:49:42 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java	Wed Dec 11 13:29:23 2013 +0100
@@ -86,10 +86,11 @@
 
     @Override
     protected void run(StructuredGraph graph) {
-        assert checkFixedDeopts(graph);
-        ReentrantNodeIterator.apply(new FrameStateAssignmentClosure(), graph.start(), null, null);
-
-        graph.setGuardsStage(GuardsStage.AFTER_FSA);
+        assert graph.getGuardsStage().ordinal() >= GuardsStage.FIXED_DEOPTS.ordinal() && checkFixedDeopts(graph);
+        if (graph.getGuardsStage().ordinal() < GuardsStage.AFTER_FSA.ordinal()) {
+            ReentrantNodeIterator.apply(new FrameStateAssignmentClosure(), graph.start(), null, null);
+            graph.setGuardsStage(GuardsStage.AFTER_FSA);
+        }
     }
 
     private static boolean checkFixedDeopts(StructuredGraph graph) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Thu Dec 05 13:49:42 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Wed Dec 11 13:29:23 2013 +0100
@@ -185,14 +185,17 @@
 
     @Override
     protected void run(StructuredGraph graph, MidTierContext context) {
-        SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST);
-        schedule.apply(graph);
+        if (graph.getGuardsStage().ordinal() < GuardsStage.FIXED_DEOPTS.ordinal()) {
+            SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST);
+            schedule.apply(graph);
 
-        for (Block block : schedule.getCFG().getBlocks()) {
-            processBlock(block, schedule, context.getTarget().implicitNullCheckLimit);
+            for (Block block : schedule.getCFG().getBlocks()) {
+                processBlock(block, schedule, context.getTarget().implicitNullCheckLimit);
+            }
+            graph.setGuardsStage(GuardsStage.FIXED_DEOPTS);
         }
 
-        graph.setGuardsStage(GuardsStage.FIXED_DEOPTS);
+        assert graph.getNodes(GuardNode.class).isEmpty();
     }
 
     private static void processBlock(Block block, SchedulePhase schedule, int implicitNullCheckLimit) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Thu Dec 05 13:49:42 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Dec 11 13:29:23 2013 +0100
@@ -89,7 +89,7 @@
         }
 
         @Override
-        public GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object) {
+        public GuardingNode createNullCheckGuard(FixedNode before, GuardedNode guardedNode, ValueNode object) {
             if (ObjectStamp.isObjectNonNull(object)) {
                 // Short cut creation of null check guard if the object is known to be non-null.
                 return null;
@@ -97,10 +97,10 @@
             StructuredGraph graph = guardedNode.asNode().graph();
             if (graph.getGuardsStage().ordinal() > GuardsStage.FLOATING_GUARDS.ordinal()) {
                 NullCheckNode nullCheck = graph.add(new NullCheckNode(object));
-                graph.addBeforeFixed((FixedNode) guardedNode, nullCheck);
+                graph.addBeforeFixed(before, nullCheck);
                 return nullCheck;
             } else {
-                GuardingNode guard = createGuard(graph.unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true);
+                GuardingNode guard = createGuard(before, graph.unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true);
                 assert guardedNode.getGuard() == null;
                 guardedNode.setGuard(guard);
                 return guard;
@@ -108,8 +108,8 @@
         }
 
         @Override
-        public GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
-            return createGuard(condition, deoptReason, action, false);
+        public GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
+            return createGuard(before, condition, deoptReason, action, false);
         }
 
         @Override
@@ -117,11 +117,32 @@
             return context.getAssumptions();
         }
 
+        private class DummyGuardHandle extends ValueNode implements GuardedNode {
+            @Input private GuardingNode guard;
+
+            public DummyGuardHandle(GuardingNode guard) {
+                super(StampFactory.forVoid());
+                this.guard = guard;
+            }
+
+            public GuardingNode getGuard() {
+                return guard;
+            }
+
+            public void setGuard(GuardingNode guard) {
+                updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode());
+                this.guard = guard;
+            }
+
+            @Override
+            public ValueNode asNode() {
+                return this;
+            }
+
+        }
+
         @Override
-        public GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
-            if (condition.graph().getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) {
-                throw new GraalInternalError("Cannot create guards after guard lowering");
-            }
+        public GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
             if (OptEliminateGuards.getValue()) {
                 for (Node usage : condition.usages()) {
                     if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).negated() == negated) {
@@ -129,12 +150,21 @@
                     }
                 }
             }
-            GuardNode newGuard = guardAnchor.asNode().graph().unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated));
-            if (OptEliminateGuards.getValue()) {
-                activeGuards.grow();
-                activeGuards.mark(newGuard);
+            StructuredGraph graph = before.graph();
+            if (condition.graph().getGuardsStage().ordinal() >= StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) {
+                FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, deoptReason, action, negated));
+                graph.addBeforeFixed(before, fixedGuard);
+                DummyGuardHandle handle = graph.add(new DummyGuardHandle(fixedGuard));
+                fixedGuard.lower(this);
+                return handle.getGuard();
+            } else {
+                GuardNode newGuard = graph.unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated));
+                if (OptEliminateGuards.getValue()) {
+                    activeGuards.grow();
+                    activeGuards.mark(newGuard);
+                }
+                return newGuard;
             }
-            return newGuard;
         }
 
         @Override