changeset 11475:c121402a62d8

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Fri, 30 Aug 2013 13:56:58 +0200
parents df18a4214c7c (current diff) 93c63975217e (diff)
children 1cd98fee2139
files
diffstat 6 files changed, 38 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- 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;
     }
 
--- 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);
     }
 
--- 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.
  * 
--- 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<ScheduledNode> 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);
                 }
             }
         }
--- 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<Probability> {
 
         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());
         }
     }
 
--- 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));