# HG changeset patch # User Gilles Duboscq # Date 1386764963 -3600 # Node ID 17c9afa0bfcb678d680ec5224fbaf80a5e13485b # Parent dc4128904f0b51710d247b16ca7401aafcf7b17b Allow GuardLoweringPhase, FrameStateAssignementPhase and the different lowerings to work with graph at any valid guards stage diff -r dc4128904f0b -r 17c9afa0bfcb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- 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); } } diff -r dc4128904f0b -r 17c9afa0bfcb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- 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); diff -r dc4128904f0b -r 17c9afa0bfcb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- 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); diff -r dc4128904f0b -r 17c9afa0bfcb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java --- 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(); diff -r dc4128904f0b -r 17c9afa0bfcb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java --- 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) { diff -r dc4128904f0b -r 17c9afa0bfcb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- 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) { diff -r dc4128904f0b -r 17c9afa0bfcb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- 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