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 /**