# HG changeset patch # User Gilles Duboscq # Date 1368198915 -7200 # Node ID a230bfbd94979777174eaba709c8a75de089066c # Parent afc3e97391bf26c3fb3f4aed196fef2e3becd648 Use specialized node inputs for loopbegin's overflow check and for value anchor's anchored values diff -r afc3e97391bf -r a230bfbd9497 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Fri May 10 16:48:00 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Fri May 10 17:15:15 2013 +0200 @@ -37,7 +37,6 @@ private InductionVariable iv; private ValueNode end; private boolean oneOff; - private ValueNode overflowGuard; private AbstractBeginNode body; CountedLoopInfo(LoopEx loop, InductionVariable iv, ValueNode end, boolean oneOff, AbstractBeginNode body) { @@ -127,27 +126,34 @@ } public ValueNode getOverFlowGuard() { - if (overflowGuard == null) { - Kind kind = iv.valueNode().kind(); - Graph graph = iv.valueNode().graph(); - CompareNode cond; // we use a negated guard with a < condition to achieve a >= - ConstantNode one = ConstantNode.forIntegerKind(kind, 1, graph); - if (iv.direction() == Direction.Up) { - IntegerArithmeticNode v1 = sub(ConstantNode.forIntegerKind(kind, kind.getMaxValue(), graph), sub(iv.strideNode(), one)); - if (oneOff) { - v1 = sub(v1, one); - } - cond = graph.unique(new IntegerLessThanNode(v1, end)); - } else { - assert iv.direction() == Direction.Down; - IntegerArithmeticNode v1 = add(ConstantNode.forIntegerKind(kind, kind.getMinValue(), graph), sub(one, iv.strideNode())); - if (oneOff) { - v1 = add(v1, one); - } - cond = graph.unique(new IntegerLessThanNode(end, v1)); + return loop.loopBegin().getOverflowGuard(); + } + + public ValueNode createOverFlowGuard() { + ValueNode overflowGuard = getOverFlowGuard(); + if (overflowGuard != null) { + return overflowGuard; + } + Kind kind = iv.valueNode().kind(); + Graph graph = iv.valueNode().graph(); + CompareNode cond; // we use a negated guard with a < condition to achieve a >= + ConstantNode one = ConstantNode.forIntegerKind(kind, 1, graph); + if (iv.direction() == Direction.Up) { + IntegerArithmeticNode v1 = sub(ConstantNode.forIntegerKind(kind, kind.getMaxValue(), graph), sub(iv.strideNode(), one)); + if (oneOff) { + v1 = sub(v1, one); } - overflowGuard = graph.unique(new GuardNode(cond, BeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true)); + cond = graph.unique(new IntegerLessThanNode(v1, end)); + } else { + assert iv.direction() == Direction.Down; + IntegerArithmeticNode v1 = add(ConstantNode.forIntegerKind(kind, kind.getMinValue(), graph), sub(one, iv.strideNode())); + if (oneOff) { + v1 = add(v1, one); + } + cond = graph.unique(new IntegerLessThanNode(end, v1)); } + overflowGuard = graph.unique(new GuardNode(cond, BeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true)); + loop.loopBegin().setOverflowGuard(overflowGuard); return overflowGuard; } diff -r afc3e97391bf -r a230bfbd9497 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java Fri May 10 16:48:00 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java Fri May 10 17:15:15 2013 +0200 @@ -39,7 +39,7 @@ loops.detectedCountedLoops(); for (LoopEx loop : loops.countedLoops()) { if (loop.lirLoop().children.isEmpty() && loop.counted().getKind() == Kind.Int) { - loop.loopBegin().dependencies().add(loop.counted().getOverFlowGuard()); + loop.counted().createOverFlowGuard(); for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) { loopEnd.disableSafepoint(); } diff -r afc3e97391bf -r a230bfbd9497 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri May 10 16:48:00 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri May 10 17:15:15 2013 +0200 @@ -35,6 +35,7 @@ private double loopFrequency; private int nextEndIndex; private int unswitches; + @Input private ValueNode overflowGuard; public LoopBeginNode() { loopFrequency = 1; @@ -183,4 +184,13 @@ graph().replaceFixedWithFixed(loopexit, graph().add(new BeginNode())); } } + + public ValueNode getOverflowGuard() { + return overflowGuard; + } + + public void setOverflowGuard(ValueNode overflowGuard) { + updateUsages(this.overflowGuard, overflowGuard); + this.overflowGuard = overflowGuard; + } } diff -r afc3e97391bf -r a230bfbd9497 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri May 10 16:48:00 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri May 10 17:15:15 2013 +0200 @@ -36,13 +36,16 @@ */ public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, Virtualizable { + @Input private NodeInputList anchored; + public ValueAnchorNode(ValueNode... values) { this(false, values); } public ValueAnchorNode(boolean permanent, ValueNode... values) { - super(StampFactory.dependency(), values); + super(StampFactory.dependency()); this.permanent = permanent; + this.anchored = new NodeInputList<>(this, values); } private final boolean permanent; @@ -53,8 +56,8 @@ } public void addAnchoredNode(ValueNode value) { - if (!this.dependencies().contains(value)) { - this.dependencies().add(value); + if (!anchored.contains(value)) { + this.anchored.add(value); } } @@ -67,13 +70,13 @@ ValueAnchorNode previousAnchor = (ValueAnchorNode) this.predecessor(); if (previousAnchor.usages().isEmpty()) { // avoid creating cycles // transfer values and remove - for (ValueNode node : dependencies().nonNull().distinct()) { + for (ValueNode node : anchored.nonNull().distinct()) { previousAnchor.addAnchoredNode(node); } return previousAnchor; } } - for (Node node : dependencies().nonNull().and(isNotA(FixedNode.class))) { + for (Node node : anchored.nonNull().and(isNotA(FixedNode.class))) { if (node instanceof ConstantNode) { continue; } @@ -100,7 +103,7 @@ if (permanent) { return; } - for (ValueNode node : dependencies().nonNull().and(isNotA(AbstractBeginNode.class))) { + for (ValueNode node : anchored.nonNull().and(isNotA(AbstractBeginNode.class))) { State state = tool.getObjectState(node); if (state == null || state.getState() != EscapeState.Virtual) { return;