Mercurial > hg > truffle
comparison graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java @ 9993:053b837d0d7d
Readded the pass that fixes DeoptimizeNode probabilities.
author | Christian Haeubl <haeubl@ssw.jku.at> |
---|---|
date | Tue, 11 Jun 2013 13:10:25 +0200 |
parents | 1b33ef6544b4 |
children | 5260095a574b |
comparison
equal
deleted
inserted
replaced
9992:b2aea23ee2b1 | 9993:053b837d0d7d |
---|---|
22 */ | 22 */ |
23 package com.oracle.graal.phases.graph; | 23 package com.oracle.graal.phases.graph; |
24 | 24 |
25 import java.util.*; | 25 import java.util.*; |
26 | 26 |
27 import com.oracle.graal.debug.internal.*; | |
27 import com.oracle.graal.graph.*; | 28 import com.oracle.graal.graph.*; |
28 import com.oracle.graal.nodes.*; | 29 import com.oracle.graal.nodes.*; |
29 import com.oracle.graal.nodes.util.*; | 30 import com.oracle.graal.nodes.util.*; |
30 | 31 |
31 /** | 32 /** |
61 this.loopInfos = new HashSet<>(); | 62 this.loopInfos = new HashSet<>(); |
62 this.mergeLoops = new IdentityHashMap<>(); | 63 this.mergeLoops = new IdentityHashMap<>(); |
63 } | 64 } |
64 | 65 |
65 public NodesToDoubles apply() { | 66 public NodesToDoubles apply() { |
67 adjustControlSplitProbabilities(); | |
66 new PropagateProbability(graph.start()).apply(); | 68 new PropagateProbability(graph.start()).apply(); |
67 computeLoopFactors(); | 69 computeLoopFactors(); |
68 new PropagateLoopFrequency(graph.start()).apply(); | 70 new PropagateLoopFrequency(graph.start()).apply(); |
71 assert verifyProbabilities(); | |
69 return nodeProbabilities; | 72 return nodeProbabilities; |
73 } | |
74 | |
75 /** | |
76 * Assume that paths with a DeoptimizeNode at their end are taken infrequently. | |
77 */ | |
78 private void adjustControlSplitProbabilities() { | |
79 HashSet<ControlSplitNode> result = new HashSet<>(); | |
80 NodeBitMap visitedNodes = new NodeBitMap(graph); | |
81 for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) { | |
82 if (n.action().doesInvalidateCompilation()) { | |
83 findParentControlSplitNodes(result, n, visitedNodes); | |
84 } | |
85 } | |
86 | |
87 for (ControlSplitNode n : result) { | |
88 if (!allSuxVisited(n, visitedNodes)) { | |
89 modifyProbabilities(n, visitedNodes); | |
90 } | |
91 } | |
92 } | |
93 | |
94 private static void findParentControlSplitNodes(HashSet<ControlSplitNode> result, DeoptimizeNode n, NodeBitMap visitedNodes) { | |
95 ArrayDeque<FixedNode> nodes = new ArrayDeque<>(); | |
96 nodes.push(n); | |
97 | |
98 Node currentNode; | |
99 do { | |
100 currentNode = nodes.pop(); | |
101 visitedNodes.mark(currentNode); | |
102 | |
103 for (Node pred : currentNode.cfgPredecessors()) { | |
104 FixedNode fixedPred = (FixedNode) pred; | |
105 if (visitedNodes.isMarked(fixedPred) && allPredsVisited(fixedPred, visitedNodes)) { | |
106 DebugScope.dump(n.graph(), "ComputeProbabilityClosure"); | |
107 GraalInternalError.shouldNotReachHere(String.format("Endless loop because %s was already visited", fixedPred)); | |
108 } else if (allSuxVisited(fixedPred, visitedNodes)) { | |
109 nodes.push(fixedPred); | |
110 } else { | |
111 assert fixedPred instanceof ControlSplitNode : "only control splits can have more than one sux"; | |
112 result.add((ControlSplitNode) fixedPred); | |
113 } | |
114 } | |
115 } while (!nodes.isEmpty()); | |
116 } | |
117 | |
118 private static void modifyProbabilities(ControlSplitNode controlSplit, NodeBitMap visitedNodes) { | |
119 assert !allSuxVisited(controlSplit, visitedNodes); | |
120 for (Node sux : controlSplit.successors()) { | |
121 if (visitedNodes.isMarked(sux)) { | |
122 controlSplit.setProbability((AbstractBeginNode) sux, 0); | |
123 } | |
124 } | |
125 } | |
126 | |
127 private static boolean allSuxVisited(FixedNode node, NodeBitMap visitedNodes) { | |
128 return allVisited(node.successors(), visitedNodes); | |
129 } | |
130 | |
131 private static boolean allPredsVisited(FixedNode node, NodeBitMap visitedNodes) { | |
132 return allVisited(node.cfgPredecessors(), visitedNodes); | |
133 } | |
134 | |
135 private static boolean allVisited(Iterable<? extends Node> nodes, NodeBitMap visitedNodes) { | |
136 for (Node sux : nodes) { | |
137 if (!visitedNodes.contains(sux)) { | |
138 return false; | |
139 } | |
140 } | |
141 return true; | |
142 } | |
143 | |
144 private boolean verifyProbabilities() { | |
145 if (doesNotAlwaysDeopt(graph)) { | |
146 for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) { | |
147 if (n.action().doesInvalidateCompilation() && nodeProbabilities.get(n) > 0.01) { | |
148 throw new AssertionError(String.format("%s with reason %s and probability %f in graph %s", n, n.reason(), nodeProbabilities.get(n), graph)); | |
149 } | |
150 } | |
151 } | |
152 return true; | |
153 } | |
154 | |
155 private static boolean doesNotAlwaysDeopt(StructuredGraph graph) { | |
156 return graph.getNodes(ReturnNode.class).iterator().hasNext(); | |
70 } | 157 } |
71 | 158 |
72 private void computeLoopFactors() { | 159 private void computeLoopFactors() { |
73 for (LoopInfo info : loopInfos) { | 160 for (LoopInfo info : loopInfos) { |
74 double frequency = info.loopFrequency(nodeProbabilities); | 161 double frequency = info.loopFrequency(nodeProbabilities); |