comparison graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java @ 2778:2ac7b30b7290

Enabled new block finding algorithm.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Tue, 24 May 2011 21:39:45 +0200
parents 27512ea6bbcb
children df4c5254c5cc
comparison
equal deleted inserted replaced
2777:3e4d992fd312 2778:2ac7b30b7290
25 25
26 import java.util.*; 26 import java.util.*;
27 27
28 import com.sun.c1x.*; 28 import com.sun.c1x.*;
29 import com.sun.c1x.debug.*; 29 import com.sun.c1x.debug.*;
30 import com.sun.c1x.lir.*;
30 import com.sun.c1x.util.*; 31 import com.sun.c1x.util.*;
31 import com.sun.cri.ci.*; 32 import com.sun.cri.ci.*;
32 33
33 public final class ComputeLinearScanOrder { 34 public final class ComputeLinearScanOrder {
34 35
35 private final int maxBlockId; // the highest blockId of a block 36 private final int maxBlockId; // the highest blockId of a block
36 private int numBlocks; // total number of blocks (smaller than maxBlockId) 37 private int numBlocks; // total number of blocks (smaller than maxBlockId)
37 private int numLoops; // total number of loops 38 private int numLoops; // total number of loops
38 39 private boolean iterativeDominators; // method requires iterative computation of dominators
39 List<BlockBegin> linearScanOrder; // the resulting list of blocks in correct order 40
41 List<LIRBlock> linearScanOrder; // the resulting list of blocks in correct order
40 42
41 final CiBitMap visitedBlocks; // used for recursive processing of blocks 43 final CiBitMap visitedBlocks; // used for recursive processing of blocks
42 final CiBitMap activeBlocks; // used for recursive processing of blocks 44 final CiBitMap activeBlocks; // used for recursive processing of blocks
45 final CiBitMap dominatorBlocks; // temporary BitMap used for computation of dominator
43 final int[] forwardBranches; // number of incoming forward branches for each block 46 final int[] forwardBranches; // number of incoming forward branches for each block
44 final List<BlockBegin> loopEndBlocks; // list of all loop end blocks collected during countEdges 47 final List<LIRBlock> loopEndBlocks; // list of all loop end blocks collected during countEdges
45 BitMap2D loopMap; // two-dimensional bit set: a bit is set if a block is contained in a loop 48 BitMap2D loopMap; // two-dimensional bit set: a bit is set if a block is contained in a loop
46 final List<BlockBegin> workList; // temporary list (used in markLoops and computeOrder) 49 final List<LIRBlock> workList; // temporary list (used in markLoops and computeOrder)
47 50
48 // accessors for visitedBlocks and activeBlocks 51 // accessors for visitedBlocks and activeBlocks
49 private void initVisited() { 52 void initVisited() {
50 activeBlocks.clearAll(); 53 activeBlocks.clearAll();
51 visitedBlocks.clearAll(); 54 visitedBlocks.clearAll();
52 } 55 }
53 56
54 private boolean isVisited(BlockBegin b) { 57 boolean isVisited(LIRBlock b) {
55 return visitedBlocks.get(b.blockID); 58 return visitedBlocks.get(b.blockID());
56 } 59 }
57 60
58 private boolean isActive(BlockBegin b) { 61 boolean isActive(LIRBlock b) {
59 return activeBlocks.get(b.blockID); 62 return activeBlocks.get(b.blockID());
60 } 63 }
61 64
62 private void setVisited(BlockBegin b) { 65 void setVisited(LIRBlock b) {
63 assert !isVisited(b) : "already set"; 66 assert !isVisited(b) : "already set";
64 visitedBlocks.set(b.blockID); 67 visitedBlocks.set(b.blockID());
65 } 68 }
66 69
67 private void setActive(BlockBegin b) { 70 void setActive(LIRBlock b) {
68 assert !isActive(b) : "already set"; 71 assert !isActive(b) : "already set";
69 activeBlocks.set(b.blockID); 72 activeBlocks.set(b.blockID());
70 } 73 }
71 74
72 private void clearActive(BlockBegin b) { 75 void clearActive(LIRBlock b) {
73 assert isActive(b) : "not already"; 76 assert isActive(b) : "not already";
74 activeBlocks.clear(b.blockID); 77 activeBlocks.clear(b.blockID());
75 } 78 }
76 79
77 // accessors for forwardBranches 80 // accessors for forwardBranches
78 private void incForwardBranches(BlockBegin b) { 81 void incForwardBranches(LIRBlock b) {
79 forwardBranches[b.blockID]++; 82 forwardBranches[b.blockID()]++;
80 } 83 }
81 84
82 private int decForwardBranches(BlockBegin b) { 85 int decForwardBranches(LIRBlock b) {
83 return --forwardBranches[b.blockID]; 86 return --forwardBranches[b.blockID()];
84 } 87 }
85 88
86 // accessors for loopMap 89 // accessors for loopMap
87 private boolean isBlockInLoop(int loopIdx, BlockBegin b) { 90 boolean isBlockInLoop(int loopIdx, LIRBlock b) {
88 return loopMap.at(loopIdx, b.blockID); 91 return loopMap.at(loopIdx, b.blockID());
89 } 92 }
90 93
91 private void setBlockInLoop(int loopIdx, BlockBegin b) { 94 void setBlockInLoop(int loopIdx, LIRBlock b) {
92 loopMap.setBit(loopIdx, b.blockID); 95 loopMap.setBit(loopIdx, b.blockID());
93 } 96 }
94 97
95 private void clearBlockInLoop(int loopIdx, int blockId) { 98 void clearBlockInLoop(int loopIdx, int blockId) {
96 loopMap.clearBit(loopIdx, blockId); 99 loopMap.clearBit(loopIdx, blockId);
97 } 100 }
98 101
99 // accessors for final result 102 // accessors for final result
100 public List<BlockBegin> linearScanOrder() { 103 public List<LIRBlock> linearScanOrder() {
101 return linearScanOrder; 104 return linearScanOrder;
102 } 105 }
103 106
104 public int numLoops() { 107 public int numLoops() {
105 return numLoops; 108 return numLoops;
106 } 109 }
107 110
108 public ComputeLinearScanOrder(int maxBlockId, BlockBegin startBlock) { 111 public ComputeLinearScanOrder(int maxBlockId, LIRBlock startBlock) {
109 112
110 this.maxBlockId = maxBlockId; 113 this.maxBlockId = maxBlockId;
111 visitedBlocks = new CiBitMap(maxBlockId); 114 visitedBlocks = new CiBitMap(maxBlockId);
112 activeBlocks = new CiBitMap(maxBlockId); 115 activeBlocks = new CiBitMap(maxBlockId);
116 dominatorBlocks = new CiBitMap(maxBlockId);
113 forwardBranches = new int[maxBlockId]; 117 forwardBranches = new int[maxBlockId];
114 loopEndBlocks = new ArrayList<BlockBegin>(8); 118 loopEndBlocks = new ArrayList<LIRBlock>(8);
115 workList = new ArrayList<BlockBegin>(8); 119 workList = new ArrayList<LIRBlock>(8);
120
121 splitCriticalEdges();
116 122
117 countEdges(startBlock, null); 123 countEdges(startBlock, null);
118 124
125 if (numLoops > 0) {
126 markLoops();
127 clearNonNaturalLoops(startBlock);
128 assignLoopDepth(startBlock);
129 }
130
119 computeOrder(startBlock); 131 computeOrder(startBlock);
132
133 printBlocks();
134 assert verify();
135 }
136
137 void splitCriticalEdges() {
138 // TODO: move critical edge splitting from IR to here
120 } 139 }
121 140
122 /** 141 /**
123 * Traverses the CFG to analyze block and edge info. The analysis performed is: 142 * Traverses the CFG to analyze block and edge info. The analysis performed is:
124 * 143 *
125 * 1. Count of total number of blocks. 144 * 1. Count of total number of blocks.
126 * 2. Count of all incoming edges and backward incoming edges. 145 * 2. Count of all incoming edges and backward incoming edges.
127 * 3. Number loop header blocks. 146 * 3. Number loop header blocks.
128 * 4. Create a list with all loop end blocks. 147 * 4. Create a list with all loop end blocks.
129 */ 148 */
130 private void countEdges(final BlockBegin cur, BlockBegin parent) { 149 void countEdges(LIRBlock cur, LIRBlock parent) {
131 if (C1XOptions.TraceLinearScanLevel >= 3) { 150 if (C1XOptions.TraceLinearScanLevel >= 3) {
132 TTY.println("Counting edges for block B%d%s", cur.blockID, parent == null ? "" : " coming from B" + parent.blockID); 151 TTY.println("Counting edges for block B%d%s", cur.blockID(), parent == null ? "" : " coming from B" + parent.blockID());
133 } 152 }
134 153
135 if (isActive(cur)) { 154 if (isActive(cur)) {
136 if (C1XOptions.TraceLinearScanLevel >= 3) { 155 if (C1XOptions.TraceLinearScanLevel >= 3) {
137 TTY.println("backward branch"); 156 TTY.println("backward branch");
138 } 157 }
139 assert isVisited(cur) : "block must be visited when block is active"; 158 assert isVisited(cur) : "block must be visited when block is active";
140 assert parent != null : "must have parent"; 159 assert parent != null : "must have parent";
141 160
142 //cur.setBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader); 161 cur.setLinearScanLoopHeader();
143 162 cur.setBackwardBranchTarget(true);
144 //parent.setBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd); 163 parent.setLinearScanLoopEnd();
164
165 // When a loop header is also the start of an exception handler, then the backward branch is
166 // an exception edge. Because such edges are usually critical edges which cannot be split, the
167 // loop must be excluded here from processing.
168 if (cur.isExceptionEntry()) {
169 // Make sure that dominators are correct in this weird situation
170 iterativeDominators = true;
171 return;
172 }
173 // assert parent.numberOfSux() == 1 && parent.suxAt(0) == cur : "loop end blocks must have one successor (critical edges are split)";
145 174
146 loopEndBlocks.add(parent); 175 loopEndBlocks.add(parent);
147 return; 176 return;
148 } 177 }
149 178
160 numBlocks++; 189 numBlocks++;
161 setVisited(cur); 190 setVisited(cur);
162 setActive(cur); 191 setActive(cur);
163 192
164 // recursive call for all successors 193 // recursive call for all successors
165 cur.allSuccessorsDo(true, new BlockClosure() { 194 int i;
166 public void apply(BlockBegin block) { 195 for (i = cur.numberOfSux() - 1; i >= 0; i--) {
167 countEdges(block, cur); 196 countEdges(cur.suxAt(i), cur);
168 } 197 }
169 }); 198 for (LIRBlock ex : cur.getExceptionHandlerSuccessors()) {
199 countEdges(ex, cur);
200 }
170 201
171 clearActive(cur); 202 clearActive(cur);
172 203
204 // Each loop has a unique number.
205 // When multiple loops are nested, assignLoopDepth assumes that the
206 // innermost loop has the lowest number. This is guaranteed by setting
207 // the loop number after the recursive calls for the successors above
208 // have returned.
209 if (cur.isLinearScanLoopHeader()) {
210 assert cur.loopIndex() == -1 : "cannot set loop-index twice";
211 if (C1XOptions.TraceLinearScanLevel >= 3) {
212 TTY.println("Block B%d is loop header of loop %d", cur.blockID(), numLoops);
213 }
214
215 cur.setLoopIndex(numLoops);
216 numLoops++;
217 }
218
173 if (C1XOptions.TraceLinearScanLevel >= 3) { 219 if (C1XOptions.TraceLinearScanLevel >= 3) {
174 TTY.println("Finished counting edges for block B%d", cur.blockID); 220 TTY.println("Finished counting edges for block B%d", cur.blockID());
175 } 221 }
176 } 222 }
177 223
178 private int computeWeight(BlockBegin cur) { 224 void markLoops() {
179 BlockBegin singleSux = null; 225 if (C1XOptions.TraceLinearScanLevel >= 3) {
180 BlockEnd end = cur.end(); 226 TTY.println("----- marking loops");
181 if (end.blockSuccessorCount() == 1) { 227 }
182 singleSux = end.blockSuccessor(0); 228
229 loopMap = new BitMap2D(numLoops, maxBlockId);
230
231 for (int i = loopEndBlocks.size() - 1; i >= 0; i--) {
232 LIRBlock loopEnd = loopEndBlocks.get(i);
233 LIRBlock loopStart = loopEnd.suxAt(0);
234 int loopIdx = loopStart.loopIndex();
235
236 if (C1XOptions.TraceLinearScanLevel >= 3) {
237 TTY.println("Processing loop from B%d to B%d (loop %d):", loopStart.blockID(), loopEnd.blockID(), loopIdx);
238 }
239 assert loopEnd.isLinearScanLoopEnd() : "loop end flag must be set";
240 // assert loopEnd.numberOfSux() == 1 : "incorrect number of successors";
241 assert loopStart.isLinearScanLoopHeader() : "loop header flag must be set";
242 assert loopIdx >= 0 && loopIdx < numLoops : "loop index not set";
243 assert workList.isEmpty() : "work list must be empty before processing";
244
245 // add the end-block of the loop to the working list
246 workList.add(loopEnd);
247 setBlockInLoop(loopIdx, loopEnd);
248 do {
249 LIRBlock cur = workList.remove(workList.size() - 1);
250
251 if (C1XOptions.TraceLinearScanLevel >= 3) {
252 TTY.println(" processing B%d", cur.blockID());
253 }
254 assert isBlockInLoop(loopIdx, cur) : "bit in loop map must be set when block is in work list";
255
256 // recursive processing of all predecessors ends when start block of loop is reached
257 if (cur != loopStart) {
258 for (int j = cur.numberOfPreds() - 1; j >= 0; j--) {
259 LIRBlock pred = cur.predAt(j);
260
261 if (!isBlockInLoop(loopIdx, pred)) {
262 // this predecessor has not been processed yet, so add it to work list
263 if (C1XOptions.TraceLinearScanLevel >= 3) {
264 TTY.println(" pushing B%d", pred.blockID());
265 }
266 workList.add(pred);
267 setBlockInLoop(loopIdx, pred);
268 }
269 }
270 }
271 } while (!workList.isEmpty());
272 }
273 }
274
275 // check for non-natural loops (loops where the loop header does not dominate
276 // all other loop blocks = loops with multiple entries).
277 // such loops are ignored
278 void clearNonNaturalLoops(LIRBlock startBlock) {
279 for (int i = numLoops - 1; i >= 0; i--) {
280 if (isBlockInLoop(i, startBlock)) {
281 // loop i contains the entry block of the method.
282 // this is not a natural loop, so ignore it
283 if (C1XOptions.TraceLinearScanLevel >= 2) {
284 TTY.println("Loop %d is non-natural, so it is ignored", i);
285 }
286
287 for (int blockId = maxBlockId - 1; blockId >= 0; blockId--) {
288 clearBlockInLoop(i, blockId);
289 }
290 iterativeDominators = true;
291 }
292 }
293 }
294
295 void assignLoopDepth(LIRBlock startBlock) {
296 if (C1XOptions.TraceLinearScanLevel >= 3) {
297 TTY.println("----- computing loop-depth and weight");
298 }
299 initVisited();
300
301 assert workList.isEmpty() : "work list must be empty before processing";
302 workList.add(startBlock);
303
304 do {
305 LIRBlock cur = workList.remove(workList.size() - 1);
306
307 if (!isVisited(cur)) {
308 setVisited(cur);
309 if (C1XOptions.TraceLinearScanLevel >= 4) {
310 TTY.println("Computing loop depth for block B%d", cur.blockID());
311 }
312
313 // compute loop-depth and loop-index for the block
314 assert cur.loopDepth() == 0 : "cannot set loop-depth twice";
315 int i;
316 int loopDepth = 0;
317 int minLoopIdx = -1;
318 for (i = numLoops - 1; i >= 0; i--) {
319 if (isBlockInLoop(i, cur)) {
320 loopDepth++;
321 minLoopIdx = i;
322 }
323 }
324 cur.setLoopDepth(loopDepth);
325 cur.setLoopIndex(minLoopIdx);
326
327 // append all unvisited successors to work list
328 for (i = cur.numberOfSux() - 1; i >= 0; i--) {
329 workList.add(cur.suxAt(i));
330 }
331 for (LIRBlock ex : cur.getExceptionHandlerSuccessors()) {
332 workList.add(ex);
333 }
334 }
335 } while (!workList.isEmpty());
336 }
337
338 int computeWeight(LIRBlock cur) {
339 LIRBlock singleSux = null;
340 if (cur.numberOfSux() == 1) {
341 singleSux = cur.suxAt(0);
183 } 342 }
184 343
185 // limit loop-depth to 15 bit (only for security reason, it will never be so big) 344 // limit loop-depth to 15 bit (only for security reason, it will never be so big)
186 int loopDepth = 0; // TODO(tw): Assign loop depth 345 int weight = (cur.loopDepth() & 0x7FFF) << 16;
187 int weight = (loopDepth & 0x7FFF) << 16;
188 346
189 int curBit = 15; 347 int curBit = 15;
348
349 // this is necessary for the (very rare) case that two successive blocks have
350 // the same loop depth, but a different loop index (can happen for endless loops
351 // with exception handlers)
352 if (!cur.isLinearScanLoopHeader()) {
353 weight |= 1 << curBit;
354 }
355 curBit--;
356
357 // loop end blocks (blocks that end with a backward branch) are added
358 // after all other blocks of the loop.
359 if (!cur.isLinearScanLoopEnd()) {
360 weight |= 1 << curBit;
361 }
362 curBit--;
363
364 // critical edge split blocks are preferred because then they have a greater
365 // probability to be completely empty
366 //if (cur.isCriticalEdgeSplit()) {
367 // weight |= 1 << curBit;
368 //}
369 //curBit--;
190 370
191 // exceptions should not be thrown in normal control flow, so these blocks 371 // exceptions should not be thrown in normal control flow, so these blocks
192 // are added as late as possible 372 // are added as late as possible
193 if (!(cur.end() instanceof Throw) && (singleSux == null || !(singleSux.end() instanceof Throw))) { 373 // if (!(cur.end() instanceof Throw) && (singleSux == null || !(singleSux.end() instanceof Throw))) {
194 weight |= (1 << curBit); 374 // weight |= 1 << curBit;
195 } 375 // }
196 curBit--; 376 // curBit--;
197 if (!(cur.end() instanceof Return) && (singleSux == null || !(singleSux.end() instanceof Return))) { 377 // if (!(cur.end() instanceof Return) && (singleSux == null || !(singleSux.end() instanceof Return))) {
198 weight |= (1 << curBit); 378 // weight |= 1 << curBit;
379 // }
380 // curBit--;
381
382 // exceptions handlers are added as late as possible
383 if (!cur.isExceptionEntry()) {
384 weight |= 1 << curBit;
199 } 385 }
200 curBit--; 386 curBit--;
201 387
202 // guarantee that weight is > 0 388 // guarantee that weight is > 0
203 weight |= 1; 389 weight |= 1;
206 assert weight > 0 : "weight cannot become negative"; 392 assert weight > 0 : "weight cannot become negative";
207 393
208 return weight; 394 return weight;
209 } 395 }
210 396
211 private boolean readyForProcessing(BlockBegin cur) { 397 boolean readyForProcessing(LIRBlock cur) {
212 // Discount the edge just traveled. 398 // Discount the edge just traveled.
213 // When the number drops to zero, all forward branches were processed 399 // When the number drops to zero, all forward branches were processed
214 if (decForwardBranches(cur) != 0) { 400 if (decForwardBranches(cur) != 0) {
215 return false; 401 return false;
216 } 402 }
218 assert !linearScanOrder.contains(cur) : "block already processed (block can be ready only once)"; 404 assert !linearScanOrder.contains(cur) : "block already processed (block can be ready only once)";
219 assert !workList.contains(cur) : "block already in work-list (block can be ready only once)"; 405 assert !workList.contains(cur) : "block already in work-list (block can be ready only once)";
220 return true; 406 return true;
221 } 407 }
222 408
223 private void sortIntoWorkList(BlockBegin cur) { 409 void sortIntoWorkList(LIRBlock cur) {
224 assert !workList.contains(cur) : "block already in work list"; 410 assert !workList.contains(cur) : "block already in work list";
225 411
226 int curWeight = computeWeight(cur); 412 int curWeight = computeWeight(cur);
227 413
228 // the linearScanNumber is used to cache the weight of a block 414 // the linearScanNumber is used to cache the weight of a block
241 insertIdx--; 427 insertIdx--;
242 } 428 }
243 workList.set(insertIdx, cur); 429 workList.set(insertIdx, cur);
244 430
245 if (C1XOptions.TraceLinearScanLevel >= 3) { 431 if (C1XOptions.TraceLinearScanLevel >= 3) {
246 TTY.println("Sorted B%d into worklist. new worklist:", cur.blockID); 432 TTY.println("Sorted B%d into worklist. new worklist:", cur.blockID());
247 for (int i = 0; i < workList.size(); i++) { 433 for (int i = 0; i < workList.size(); i++) {
248 TTY.println(String.format("%8d B%02d weight:%6x", i, workList.get(i).blockID, workList.get(i).linearScanNumber())); 434 TTY.println(String.format("%8d B%02d weight:%6x", i, workList.get(i).blockID(), workList.get(i).linearScanNumber()));
249 } 435 }
250 } 436 }
251 437
252 for (int i = 0; i < workList.size(); i++) { 438 for (int i = 0; i < workList.size(); i++) {
253 assert workList.get(i).linearScanNumber() > 0 : "weight not set"; 439 assert workList.get(i).linearScanNumber() > 0 : "weight not set";
254 assert i == 0 || workList.get(i - 1).linearScanNumber() <= workList.get(i).linearScanNumber() : "incorrect order in worklist"; 440 assert i == 0 || workList.get(i - 1).linearScanNumber() <= workList.get(i).linearScanNumber() : "incorrect order in worklist";
255 } 441 }
256 } 442 }
257 443
258 private void appendBlock(BlockBegin cur) { 444 void appendBlock(LIRBlock cur) {
259 if (C1XOptions.TraceLinearScanLevel >= 3) { 445 if (C1XOptions.TraceLinearScanLevel >= 3) {
260 TTY.println("appending block B%d (weight 0x%06x) to linear-scan order", cur.blockID, cur.linearScanNumber()); 446 TTY.println("appending block B%d (weight 0x%06x) to linear-scan order", cur.blockID(), cur.linearScanNumber());
261 } 447 }
262 assert !linearScanOrder.contains(cur) : "cannot add the same block twice"; 448 assert !linearScanOrder.contains(cur) : "cannot add the same block twice";
263 449
264 // currently, the linear scan order and code emit order are equal. 450 // currently, the linear scan order and code emit order are equal.
265 // therefore the linearScanNumber and the weight of a block must also 451 // therefore the linearScanNumber and the weight of a block must also
266 // be equal. 452 // be equal.
267 cur.setLinearScanNumber(linearScanOrder.size()); 453 cur.setLinearScanNumber(linearScanOrder.size());
268 linearScanOrder.add(cur); 454 linearScanOrder.add(cur);
269 } 455 }
270 456
271 private void computeOrder(BlockBegin startBlock) { 457 void computeOrder(LIRBlock startBlock) {
272 if (C1XOptions.TraceLinearScanLevel >= 3) { 458 if (C1XOptions.TraceLinearScanLevel >= 3) {
273 TTY.println("----- computing final block order"); 459 TTY.println("----- computing final block order");
274 } 460 }
275 461
276 // the start block is always the first block in the linear scan order 462 // the start block is always the first block in the linear scan order
277 linearScanOrder = new ArrayList<BlockBegin>(numBlocks); 463 linearScanOrder = new ArrayList<LIRBlock>(numBlocks);
464 appendBlock(startBlock);
465
466 LIRBlock stdEntry = startBlock.suxAt(0);
278 467
279 // start processing with standard entry block 468 // start processing with standard entry block
280 assert workList.isEmpty() : "list must be empty before processing"; 469 assert workList.isEmpty() : "list must be empty before processing";
281 470
282 if (readyForProcessing(startBlock)) { 471 if (readyForProcessing(stdEntry)) {
283 sortIntoWorkList(startBlock); 472 sortIntoWorkList(stdEntry);
284 } else { 473 } else {
285 throw new CiBailout("the stdEntry must be ready for processing (otherwise, the method has no start block)"); 474 throw new CiBailout("the stdEntry must be ready for processing (otherwise, the method has no start block)");
286 } 475 }
287 476
288 do { 477 do {
289 final BlockBegin cur = workList.remove(workList.size() - 1); 478 LIRBlock cur = workList.remove(workList.size() - 1);
479
290 appendBlock(cur); 480 appendBlock(cur);
291 481
292 cur.allSuccessorsDo(false, new BlockClosure() { 482 int i;
293 public void apply(BlockBegin block) { 483 int numSux = cur.numberOfSux();
294 if (readyForProcessing(block)) { 484 // changed loop order to get "intuitive" order of if- and else-blocks
295 sortIntoWorkList(block); 485 for (i = 0; i < numSux; i++) {
486 LIRBlock sux = cur.suxAt(i);
487 if (readyForProcessing(sux)) {
488 sortIntoWorkList(sux);
489 }
490 }
491 for (LIRBlock ex : cur.getExceptionHandlerSuccessors()) {
492 if (readyForProcessing(ex)) {
493 sortIntoWorkList(ex);
494 }
495 }
496 } while (workList.size() > 0);
497 }
498
499 public void printBlocks() {
500 if (C1XOptions.TraceLinearScanLevel >= 2) {
501 TTY.println("----- loop information:");
502 for (LIRBlock cur : linearScanOrder) {
503 TTY.print(String.format("%4d: B%02d: ", cur.linearScanNumber(), cur.blockID()));
504 for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) {
505 TTY.print(String.format("%d = %b ", loopIdx, isBlockInLoop(loopIdx, cur)));
506 }
507 TTY.println(String.format(" . loopIndex: %2d, loopDepth: %2d", cur.loopIndex(), cur.loopDepth()));
508 }
509 }
510
511 if (C1XOptions.TraceLinearScanLevel >= 1) {
512 TTY.println("----- linear-scan block order:");
513 for (LIRBlock cur : linearScanOrder) {
514 TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID(), cur.loopIndex(), cur.loopDepth()));
515
516 TTY.print(cur.isExceptionEntry() ? " ex" : " ");
517 TTY.print(cur.isLinearScanLoopHeader() ? " lh" : " ");
518 TTY.print(cur.isLinearScanLoopEnd() ? " le" : " ");
519
520 TTY.print(" dom: null ");
521
522
523 if (cur.numberOfPreds() > 0) {
524 TTY.print(" preds: ");
525 for (int j = 0; j < cur.numberOfPreds(); j++) {
526 LIRBlock pred = cur.predAt(j);
527 TTY.print("B%d ", pred.blockID());
296 } 528 }
297 } 529 }
298 }); 530 if (cur.numberOfSux() > 0) {
299 } while (workList.size() > 0); 531 TTY.print(" sux: ");
532 for (int j = 0; j < cur.numberOfSux(); j++) {
533 LIRBlock sux = cur.suxAt(j);
534 TTY.print("B%d ", sux.blockID());
535 }
536 }
537 TTY.println();
538 }
539 }
540 }
541
542 boolean verify() {
543 /* assert linearScanOrder.size() == numBlocks : "wrong number of blocks in list";
544
545 if (C1XOptions.StressLinearScan) {
546 // blocks are scrambled when StressLinearScan is used
547 return true;
548 }
549
550 // check that all successors of a block have a higher linear-scan-number
551 // and that all predecessors of a block have a lower linear-scan-number
552 // (only backward branches of loops are ignored)
553 int i;
554 for (i = 0; i < linearScanOrder.size(); i++) {
555 BlockBegin cur = linearScanOrder.get(i);
556
557 assert cur.linearScanNumber() == i : "incorrect linearScanNumber";
558 assert cur.linearScanNumber() >= 0 && cur.linearScanNumber() == linearScanOrder.indexOf(cur) : "incorrect linearScanNumber";
559
560 for (BlockBegin sux : cur.end().successors()) {
561 assert sux.linearScanNumber() >= 0 && sux.linearScanNumber() == linearScanOrder.indexOf(sux) : "incorrect linearScanNumber";
562 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd)) {
563 assert cur.linearScanNumber() < sux.linearScanNumber() : "invalid order";
564 }
565 if (cur.loopDepth() == sux.loopDepth()) {
566 assert cur.loopIndex() == sux.loopIndex() || sux.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index";
567 }
568 }
569
570 for (BlockBegin pred : cur.predecessors()) {
571 assert pred.linearScanNumber() >= 0 && pred.linearScanNumber() == linearScanOrder.indexOf(pred) : "incorrect linearScanNumber";
572 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) {
573 assert cur.linearScanNumber() > pred.linearScanNumber() : "invalid order";
574 }
575 if (cur.loopDepth() == pred.loopDepth()) {
576 assert cur.loopIndex() == pred.loopIndex() || cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index";
577 }
578
579 assert cur.dominator().linearScanNumber() <= pred.linearScanNumber() : "dominator must be before predecessors";
580 }
581
582 // check dominator
583 if (i == 0) {
584 assert cur.dominator() == null : "first block has no dominator";
585 } else {
586 assert cur.dominator() != null : "all but first block must have dominator";
587 }
588 assert cur.numberOfPreds() != 1 || cur.dominator() == cur.predAt(0) || cur.isExceptionEntry() : "Single predecessor must also be dominator";
589 }
590
591 // check that all loops are continuous
592 for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) {
593 int blockIdx = 0;
594 assert !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx)) : "the first block must not be present in any loop";
595
596 // skip blocks before the loop
597 while (blockIdx < numBlocks && !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx))) {
598 blockIdx++;
599 }
600 // skip blocks of loop
601 while (blockIdx < numBlocks && isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx))) {
602 blockIdx++;
603 }
604 // after the first non-loop block : there must not be another loop-block
605 while (blockIdx < numBlocks) {
606 assert !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx)) : "loop not continuous in linear-scan order";
607 blockIdx++;
608 }
609 }
610 */
611 return true;
300 } 612 }
301 } 613 }