changeset 11463:93c63975217e

Make ComputeProbabilityClosure more robust to probabilities that to infinity because of loops
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 29 Aug 2013 19:09:09 +0200
parents ff122ed4b9fd
children 5dd02961efdc c121402a62d8 78d96d411965 20b642493616 12f1d5fe0133 3d358ea11300
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodesToDoubles.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java
diffstat 3 files changed, 22 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Thu Aug 29 18:02:20 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Thu Aug 29 19:09:09 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	Thu Aug 29 18:02:20 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodesToDoubles.java	Thu Aug 29 19:09:09 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/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Thu Aug 29 18:02:20 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Thu Aug 29 19:09:09 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());
         }
     }