# HG changeset patch # User Christos Kotselidis # Date 1377863818 -7200 # Node ID c121402a62d8419fbc4be600d349e65597733101 # Parent df18a4214c7ce8f7d02e2b5c5719b7fa01920c64# Parent 93c63975217e2cff3f45d901e205ad1ff6b5e164 Merge diff -r df18a4214c7c -r c121402a62d8 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 Aug 30 13:51:22 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Aug 30 13:56:58 2013 +0200 @@ -47,6 +47,7 @@ } public void setLoopFrequency(double loopFrequency) { + assert loopFrequency >= 0; this.loopFrequency = loopFrequency; } diff -r df18a4214c7c -r c121402a62d8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodesToDoubles.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodesToDoubles.java Fri Aug 30 13:51:22 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodesToDoubles.java Fri Aug 30 13:56:58 2013 +0200 @@ -35,7 +35,7 @@ } public void put(FixedNode n, double value) { - assert value >= 0.0; + assert value >= 0.0 : value; nodeProbabilities.put(n, value); } diff -r df18a4214c7c -r c121402a62d8 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Fri Aug 30 13:51:22 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Fri Aug 30 13:56:58 2013 +0200 @@ -34,7 +34,7 @@ * This phase will find branches which always end with a {@link DeoptimizeNode} and replace their * {@link ControlSplitNode ControlSplitNodes} with {@link FixedGuardNode FixedGuardNodes}. * - * This is useful because {@link FixedGuardNode FixedGuardNodes FixedGuardNodess} will be lowered to + * This is useful because {@link FixedGuardNode FixedGuardNodes} will be lowered to * {@link GuardNode GuardNodes} which can later be optimized more aggressively than control-flow * constructs. * diff -r df18a4214c7c -r c121402a62d8 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 Fri Aug 30 13:51:22 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Aug 30 13:56:58 2013 +0200 @@ -128,7 +128,7 @@ } private void setLastFixedNode(FixedWithNextNode n) { - assert n == null || n.isAlive() : n; + assert n.isAlive() : n; lastFixedNode = n; } } @@ -220,7 +220,7 @@ // Lower the instructions of this block. List nodes = schedule.nodesFor(b); - loweringTool.setLastFixedNode(null); + loweringTool.setLastFixedNode(b.getBeginNode()); for (Node node : nodes) { if (node.isDeleted()) { @@ -228,23 +228,11 @@ continue; } - if (loweringTool.lastFixedNode() == null) { - AbstractBeginNode beginNode = b.getBeginNode(); - if (node == beginNode) { - loweringTool.setLastFixedNode(beginNode); - } else { - assert !(node instanceof Lowerable) : "SchedulingError: Lowerable " + node + " should not float before begin node " + beginNode; - assert node instanceof FloatingNode : "skipped node must be a FloatingNode: " + node; - continue; - } - } - // Cache the next node to be able to reconstruct the previous of the next node // after lowering. FixedNode nextNode = null; if (node instanceof FixedWithNextNode) { - FixedWithNextNode fixed = (FixedWithNextNode) node; - nextNode = fixed.next(); + nextNode = ((FixedWithNextNode) node).next(); } else { nextNode = loweringTool.lastFixedNode().next(); } @@ -255,14 +243,19 @@ } if (!nextNode.isAlive()) { + // can happen when the rest of the block is killed by lowering (e.g. by a + // unconditional deopt) break; } else { Node nextLastFixed = nextNode.predecessor(); - if (nextLastFixed instanceof FixedWithNextNode) { - loweringTool.setLastFixedNode((FixedWithNextNode) nextLastFixed); - } else { - loweringTool.setLastFixedNode((FixedWithNextNode) nextNode); + if (!(nextLastFixed instanceof FixedWithNextNode)) { + // insert begin node, to have a valid last fixed for next lowerable node. + BeginNode begin = node.graph().add(new BeginNode()); + nextLastFixed.replaceFirstSuccessor(nextNode, begin); + begin.setNext(nextNode); + nextLastFixed = begin; } + loweringTool.setLastFixedNode((FixedWithNextNode) nextLastFixed); } } } diff -r df18a4214c7c -r c121402a62d8 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java Fri Aug 30 13:51:22 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java Fri Aug 30 13:56:58 2013 +0200 @@ -187,7 +187,7 @@ if (t == -1) { return -1; } - factor *= t; + factor = multiplySaturate(factor, t); } backEdgeProb += nodeProbabilities.get(le) * factor; } @@ -203,6 +203,21 @@ } } + /** + * Multiplies a and b and saturates the result to 1/{@link Double#MIN_NORMAL}. + * + * @param a + * @param b + * @return a times b saturated to 1/{@link Double#MIN_NORMAL} + */ + public static double multiplySaturate(double a, double b) { + double r = a * b; + if (r > 1 / Double.MIN_NORMAL) { + return 1 / Double.MIN_NORMAL; + } + return r; + } + private class Probability extends MergeableState { public double probability; @@ -236,7 +251,7 @@ if (loopFrequency == -1) { return false; } - probability *= loopFrequency; + probability = multiplySaturate(probability, loopFrequency); assert probability >= 0; } } @@ -248,7 +263,7 @@ if (loopFrequency == -1) { return false; } - prob *= loopFrequency; + prob = multiplySaturate(prob, loopFrequency); assert prob >= 0; } } @@ -335,7 +350,7 @@ assert loops != null; double countProd = 1; for (LoopInfo loop : loops) { - countProd *= loop.loopFrequency(nodeProbabilities); + countProd = multiplySaturate(countProd, loop.loopFrequency(nodeProbabilities)); } count = countProd; } @@ -344,7 +359,7 @@ @Override public void loopBegin(LoopBeginNode loopBegin) { - count *= loopBegin.loopFrequency(); + count = multiplySaturate(count, loopBegin.loopFrequency()); } } diff -r df18a4214c7c -r c121402a62d8 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Aug 30 13:51:22 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Aug 30 13:56:58 2013 +0200 @@ -770,12 +770,12 @@ // If a FrameState is an outer FrameState this method behaves as if the inner // FrameState was the actual usage, by recursing. blocksForUsage(node, unscheduledUsage, closure, strategy); - } else if (unscheduledUsage instanceof MergeNode) { - // Only FrameStates can be connected to MergeNodes. + } else if (unscheduledUsage instanceof AbstractBeginNode) { + // Only FrameStates can be connected to BeginNodes. if (!(usage instanceof FrameState)) { throw new SchedulingError(usage.toString()); } - // If a FrameState belongs to a MergeNode then it's inputs will be placed at the + // If a FrameState belongs to a BeginNode then it's inputs will be placed at the // common dominator of all EndNodes. for (Node pred : unscheduledUsage.cfgPredecessors()) { closure.apply(cfg.getNodeToBlock().get(pred));