Mercurial > hg > truffle
comparison graal/com.oracle.graal.java/src/com/oracle/graal/java/ComputeLoopFrequenciesClosure.java @ 16590:c62c1e0060cc
Don't allow infinite loops to explode loop frequencies
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Wed, 23 Jul 2014 17:36:15 -0700 |
parents | c55f44b3c5e5 |
children | 5d468add216f |
comparison
equal
deleted
inserted
replaced
16589:6bdd2ec553eb | 16590:c62c1e0060cc |
---|---|
20 * or visit www.oracle.com if you need additional information or have any | 20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. | 21 * questions. |
22 */ | 22 */ |
23 package com.oracle.graal.java; | 23 package com.oracle.graal.java; |
24 | 24 |
25 import static com.oracle.graal.nodes.cfg.ControlFlowGraph.*; | |
26 | |
25 import java.util.*; | 27 import java.util.*; |
26 import java.util.stream.*; | 28 import java.util.stream.*; |
27 | 29 |
28 import com.oracle.graal.nodes.*; | 30 import com.oracle.graal.nodes.*; |
29 import com.oracle.graal.phases.graph.*; | 31 import com.oracle.graal.phases.graph.*; |
30 | 32 |
31 public class ComputeLoopFrequenciesClosure extends ReentrantNodeIterator.NodeIteratorClosure<Double> { | 33 public class ComputeLoopFrequenciesClosure extends ReentrantNodeIterator.NodeIteratorClosure<Double> { |
32 | 34 |
33 private static final double EPSILON = Double.MIN_NORMAL; | |
34 private static final ComputeLoopFrequenciesClosure INSTANCE = new ComputeLoopFrequenciesClosure(); | 35 private static final ComputeLoopFrequenciesClosure INSTANCE = new ComputeLoopFrequenciesClosure(); |
35 | 36 |
36 private ComputeLoopFrequenciesClosure() { | 37 private ComputeLoopFrequenciesClosure() { |
37 // nothing to do | 38 // nothing to do |
38 } | 39 } |
60 protected Map<LoopExitNode, Double> processLoop(LoopBeginNode loop, Double initialState) { | 61 protected Map<LoopExitNode, Double> processLoop(LoopBeginNode loop, Double initialState) { |
61 Map<LoopExitNode, Double> exitStates = ReentrantNodeIterator.processLoop(this, loop, 1D).exitStates; | 62 Map<LoopExitNode, Double> exitStates = ReentrantNodeIterator.processLoop(this, loop, 1D).exitStates; |
62 | 63 |
63 double exitProbability = exitStates.values().stream().mapToDouble(d -> d).sum(); | 64 double exitProbability = exitStates.values().stream().mapToDouble(d -> d).sum(); |
64 assert exitProbability <= 1D && exitProbability >= 0D; | 65 assert exitProbability <= 1D && exitProbability >= 0D; |
65 if (exitProbability < EPSILON) { | 66 if (exitProbability < MIN_PROBABILITY) { |
66 exitProbability = EPSILON; | 67 exitProbability = MIN_PROBABILITY; |
67 } | 68 } |
68 double loopFrequency = 1D / exitProbability; | 69 double loopFrequency = 1D / exitProbability; |
69 loop.setLoopFrequency(loopFrequency); | 70 loop.setLoopFrequency(loopFrequency); |
70 | 71 |
71 double adjustmentFactor = initialState * loopFrequency; | 72 double adjustmentFactor = initialState * loopFrequency; |
73 | 74 |
74 return exitStates; | 75 return exitStates; |
75 } | 76 } |
76 | 77 |
77 /** | 78 /** |
78 * Multiplies a and b and saturates the result to 1/{@link Double#MIN_NORMAL}. | 79 * Multiplies a and b and saturates the result to 1/{@link #MIN_PROBABILITY}. |
79 * | 80 * |
80 * @return a times b saturated to 1/{@link Double#MIN_NORMAL} | 81 * @return a times b saturated to 1/{@link #MIN_PROBABILITY} |
81 */ | 82 */ |
82 public static double multiplySaturate(double a, double b) { | 83 public static double multiplySaturate(double a, double b) { |
83 double r = a * b; | 84 double r = a * b; |
84 if (r > 1 / Double.MIN_NORMAL) { | 85 if (r > 1 / MIN_PROBABILITY) { |
85 return 1 / Double.MIN_NORMAL; | 86 return 1 / MIN_PROBABILITY; |
86 } | 87 } |
87 return r; | 88 return r; |
88 } | 89 } |
89 | 90 |
90 /** | 91 /** |