# HG changeset patch # User Gilles Duboscq # Date 1377796149 -7200 # Node ID 93c63975217e2cff3f45d901e205ad1ff6b5e164 # Parent ff122ed4b9fd1cf9f40b0672afd81141db2cd0de Make ComputeProbabilityClosure more robust to probabilities that to infinity because of loops diff -r ff122ed4b9fd -r 93c63975217e 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 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; } diff -r ff122ed4b9fd -r 93c63975217e 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 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); } diff -r ff122ed4b9fd -r 93c63975217e 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 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 { 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()); } }