comparison graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java @ 2718:c1ce2a53d6c3

Attempt to remove dependency between backend and BlockBegin.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Thu, 19 May 2011 16:05:42 +0200
parents bd85cf08720a
children 3fbe58ac818d
comparison
equal deleted inserted replaced
2717:bd85cf08720a 2718:c1ce2a53d6c3
39 39
40 List<BlockBegin> linearScanOrder; // the resulting list of blocks in correct order 40 List<BlockBegin> linearScanOrder; // the resulting list of blocks in correct order
41 41
42 final CiBitMap visitedBlocks; // used for recursive processing of blocks 42 final CiBitMap visitedBlocks; // used for recursive processing of blocks
43 final CiBitMap activeBlocks; // used for recursive processing of blocks 43 final CiBitMap activeBlocks; // used for recursive processing of blocks
44 final CiBitMap dominatorBlocks; // temporary BitMap used for computation of dominator
45 final int[] forwardBranches; // number of incoming forward branches for each block 44 final int[] forwardBranches; // number of incoming forward branches for each block
46 final List<BlockBegin> loopEndBlocks; // list of all loop end blocks collected during countEdges 45 final List<BlockBegin> loopEndBlocks; // list of all loop end blocks collected during countEdges
47 BitMap2D loopMap; // two-dimensional bit set: a bit is set if a block is contained in a loop 46 BitMap2D loopMap; // two-dimensional bit set: a bit is set if a block is contained in a loop
48 final List<BlockBegin> workList; // temporary list (used in markLoops and computeOrder) 47 final List<BlockBegin> workList; // temporary list (used in markLoops and computeOrder)
49 48
110 public ComputeLinearScanOrder(int maxBlockId, BlockBegin startBlock) { 109 public ComputeLinearScanOrder(int maxBlockId, BlockBegin startBlock) {
111 110
112 this.maxBlockId = maxBlockId; 111 this.maxBlockId = maxBlockId;
113 visitedBlocks = new CiBitMap(maxBlockId); 112 visitedBlocks = new CiBitMap(maxBlockId);
114 activeBlocks = new CiBitMap(maxBlockId); 113 activeBlocks = new CiBitMap(maxBlockId);
115 dominatorBlocks = new CiBitMap(maxBlockId);
116 forwardBranches = new int[maxBlockId]; 114 forwardBranches = new int[maxBlockId];
117 loopEndBlocks = new ArrayList<BlockBegin>(8); 115 loopEndBlocks = new ArrayList<BlockBegin>(8);
118 workList = new ArrayList<BlockBegin>(8); 116 workList = new ArrayList<BlockBegin>(8);
119 117
120 countEdges(startBlock, null); 118 countEdges(startBlock, null);
121 119
122 if (numLoops > 0) { 120 if (numLoops > 0) {
123 markLoops(); 121 markLoops();
124 clearNonNaturalLoops(startBlock); 122 clearNonNaturalLoops(startBlock);
125 assignLoopDepth(startBlock);
126 } 123 }
127 124
128 computeOrder(startBlock); 125 computeOrder(startBlock);
129 126
130 printBlocks(); 127 printBlocks();
186 // Each loop has a unique number. 183 // Each loop has a unique number.
187 // When multiple loops are nested, assignLoopDepth assumes that the 184 // When multiple loops are nested, assignLoopDepth assumes that the
188 // innermost loop has the lowest number. This is guaranteed by setting 185 // innermost loop has the lowest number. This is guaranteed by setting
189 // the loop number after the recursive calls for the successors above 186 // the loop number after the recursive calls for the successors above
190 // have returned. 187 // have returned.
191 if (cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) { 188 // if (cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) {
192 assert cur.loopIndex() == -1 : "cannot set loop-index twice"; 189 // // assert cur.loopIndex() == -1 : "cannot set loop-index twice";
193 if (C1XOptions.TraceLinearScanLevel >= 3) { 190 // if (C1XOptions.TraceLinearScanLevel >= 3) {
194 TTY.println("Block B%d is loop header of loop %d", cur.blockID, numLoops); 191 // TTY.println("Block B%d is loop header of loop %d", cur.blockID, numLoops);
195 } 192 // }
196 193 //
197 cur.setLoopIndex(numLoops); 194 // cur.setLoopIndex(numLoops);
198 numLoops++; 195 // numLoops++;
199 } 196 // }
200 197
201 if (C1XOptions.TraceLinearScanLevel >= 3) { 198 if (C1XOptions.TraceLinearScanLevel >= 3) {
202 TTY.println("Finished counting edges for block B%d", cur.blockID); 199 TTY.println("Finished counting edges for block B%d", cur.blockID);
203 } 200 }
204 } 201 }
205 202
206 private void markLoops() { 203 private void markLoops() {
207 if (C1XOptions.TraceLinearScanLevel >= 3) { 204 // if (C1XOptions.TraceLinearScanLevel >= 3) {
208 TTY.println("----- marking loops"); 205 // TTY.println("----- marking loops");
209 } 206 // }
210 207 //
211 loopMap = new BitMap2D(numLoops, maxBlockId); 208 // loopMap = new BitMap2D(numLoops, maxBlockId);
212 209 //
213 for (int i = loopEndBlocks.size() - 1; i >= 0; i--) { 210 // for (int i = loopEndBlocks.size() - 1; i >= 0; i--) {
214 BlockBegin loopEnd = loopEndBlocks.get(i); 211 // BlockBegin loopEnd = loopEndBlocks.get(i);
215 BlockBegin loopStart = loopEnd.suxAt(0); 212 // BlockBegin loopStart = loopEnd.suxAt(0);
216 int loopIdx = loopStart.loopIndex(); 213 // int loopIdx = loopStart.loopIndex();
217 214 //
218 if (C1XOptions.TraceLinearScanLevel >= 3) { 215 // if (C1XOptions.TraceLinearScanLevel >= 3) {
219 TTY.println("Processing loop from B%d to B%d (loop %d):", loopStart.blockID, loopEnd.blockID, loopIdx); 216 // TTY.println("Processing loop from B%d to B%d (loop %d):", loopStart.blockID, loopEnd.blockID, loopIdx);
220 } 217 // }
221 assert loopEnd.isLinearScanLoopEnd() : "loop end flag must be set"; 218 // assert loopEnd.isLinearScanLoopEnd() : "loop end flag must be set";
222 assert loopStart.isLinearScanLoopHeader() : "loop header flag must be set"; 219 // assert loopStart.isLinearScanLoopHeader() : "loop header flag must be set";
223 assert loopIdx >= 0 && loopIdx < numLoops : "loop index not set"; 220 // assert loopIdx >= 0 && loopIdx < numLoops : "loop index not set";
224 assert workList.isEmpty() : "work list must be empty before processing"; 221 // assert workList.isEmpty() : "work list must be empty before processing";
225 222 //
226 // add the end-block of the loop to the working list 223 // // add the end-block of the loop to the working list
227 workList.add(loopEnd); 224 // workList.add(loopEnd);
228 setBlockInLoop(loopIdx, loopEnd); 225 // setBlockInLoop(loopIdx, loopEnd);
229 do { 226 // do {
230 BlockBegin cur = workList.remove(workList.size() - 1); 227 // BlockBegin cur = workList.remove(workList.size() - 1);
231 228 //
232 if (C1XOptions.TraceLinearScanLevel >= 3) { 229 // if (C1XOptions.TraceLinearScanLevel >= 3) {
233 TTY.println(" processing B%d", cur.blockID); 230 // TTY.println(" processing B%d", cur.blockID);
234 } 231 // }
235 assert isBlockInLoop(loopIdx, cur) : "bit in loop map must be set when block is in work list"; 232 // //assert isBlockInLoop(loopIdx, cur) : "bit in loop map must be set when block is in work list";
236 233 //
237 // recursive processing of all predecessors ends when start block of loop is reached 234 // // recursive processing of all predecessors ends when start block of loop is reached
238 if (cur != loopStart) { 235 // if (cur != loopStart) {
239 for (int j = cur.numberOfPreds() - 1; j >= 0; j--) { 236 // for (int j = cur.numberOfPreds() - 1; j >= 0; j--) {
240 BlockBegin pred = cur.predAt(j).block(); 237 // BlockBegin pred = cur.predAt(j).block();
241 238 //
242 if (!isBlockInLoop(loopIdx, pred)) { 239 // if (!isBlockInLoop(loopIdx, pred)) {
243 // this predecessor has not been processed yet, so add it to work list 240 // // this predecessor has not been processed yet, so add it to work list
244 if (C1XOptions.TraceLinearScanLevel >= 3) { 241 // if (C1XOptions.TraceLinearScanLevel >= 3) {
245 TTY.println(" pushing B%d", pred.blockID); 242 // TTY.println(" pushing B%d", pred.blockID);
246 } 243 // }
247 workList.add(pred); 244 // workList.add(pred);
248 setBlockInLoop(loopIdx, pred); 245 // setBlockInLoop(loopIdx, pred);
249 } 246 // }
250 } 247 // }
251 } 248 // }
252 } while (!workList.isEmpty()); 249 // } while (!workList.isEmpty());
253 } 250 // }
254 } 251 }
255 252
256 // check for non-natural loops (loops where the loop header does not dominate 253 // check for non-natural loops (loops where the loop header does not dominate
257 // all other loop blocks = loops with multiple entries). 254 // all other loop blocks = loops with multiple entries).
258 // such loops are ignored 255 // such loops are ignored
259 private void clearNonNaturalLoops(BlockBegin startBlock) { 256 private void clearNonNaturalLoops(BlockBegin startBlock) {
260 for (int i = numLoops - 1; i >= 0; i--) { 257 // for (int i = numLoops - 1; i >= 0; i--) {
261 if (isBlockInLoop(i, startBlock)) { 258 // if (isBlockInLoop(i, startBlock)) {
262 // loop i contains the entry block of the method. 259 // // loop i contains the entry block of the method.
263 // this is not a natural loop, so ignore it 260 // // this is not a natural loop, so ignore it
264 if (C1XOptions.TraceLinearScanLevel >= 2) { 261 // if (C1XOptions.TraceLinearScanLevel >= 2) {
265 TTY.println("Loop %d is non-natural, so it is ignored", i); 262 // TTY.println("Loop %d is non-natural, so it is ignored", i);
266 } 263 // }
267 264 //
268 for (int blockId = maxBlockId - 1; blockId >= 0; blockId--) { 265 // for (int blockId = maxBlockId - 1; blockId >= 0; blockId--) {
269 clearBlockInLoop(i, blockId); 266 // clearBlockInLoop(i, blockId);
270 } 267 // }
271 iterativeDominators = true; 268 // iterativeDominators = true;
272 } 269 // }
273 } 270 // }
274 }
275
276 private void assignLoopDepth(BlockBegin startBlock) {
277 if (C1XOptions.TraceLinearScanLevel >= 3) {
278 TTY.println("----- computing loop-depth and weight");
279 }
280 initVisited();
281
282 assert workList.isEmpty() : "work list must be empty before processing";
283 workList.add(startBlock);
284
285 do {
286 BlockBegin cur = workList.remove(workList.size() - 1);
287
288 if (!isVisited(cur)) {
289 setVisited(cur);
290 if (C1XOptions.TraceLinearScanLevel >= 4) {
291 TTY.println("Computing loop depth for block B%d", cur.blockID);
292 }
293
294 // compute loop-depth and loop-index for the block
295 assert cur.loopDepth() == 0 : "cannot set loop-depth twice";
296 int i;
297 int loopDepth = 0;
298 int minLoopIdx = -1;
299 for (i = numLoops - 1; i >= 0; i--) {
300 if (isBlockInLoop(i, cur)) {
301 loopDepth++;
302 minLoopIdx = i;
303 }
304 }
305 cur.setLoopDepth(loopDepth);
306 cur.setLoopIndex(minLoopIdx);
307
308 // append all unvisited successors to work list
309 cur.allSuccessorsDo(true, new BlockClosure() {
310 public void apply(BlockBegin block) {
311 workList.add(block);
312 }
313 });
314 }
315 } while (!workList.isEmpty());
316 } 271 }
317 272
318 private int computeWeight(BlockBegin cur) { 273 private int computeWeight(BlockBegin cur) {
319 BlockBegin singleSux = null; 274 BlockBegin singleSux = null;
320 if (cur.numberOfSux() == 1) { 275 if (cur.numberOfSux() == 1) {
321 singleSux = cur.suxAt(0); 276 singleSux = cur.suxAt(0);
322 } 277 }
323 278
324 // limit loop-depth to 15 bit (only for security reason, it will never be so big) 279 // limit loop-depth to 15 bit (only for security reason, it will never be so big)
325 int weight = (cur.loopDepth() & 0x7FFF) << 16; 280 int loopDepth = 0; // TODO(tw): Assign loop depth
281 int weight = (loopDepth & 0x7FFF) << 16;
326 282
327 int curBit = 15; 283 int curBit = 15;
328 284
329 // this is necessary for the (very rare) case that two successive blocks have 285 // this is necessary for the (very rare) case that two successive blocks have
330 // the same loop depth, but a different loop index (can happen for endless loops 286 // the same loop depth, but a different loop index (can happen for endless loops
455 public void printBlocks() { 411 public void printBlocks() {
456 if (C1XOptions.TraceLinearScanLevel >= 2) { 412 if (C1XOptions.TraceLinearScanLevel >= 2) {
457 TTY.println("----- loop information:"); 413 TTY.println("----- loop information:");
458 for (BlockBegin cur : linearScanOrder) { 414 for (BlockBegin cur : linearScanOrder) {
459 TTY.print(String.format("%4d: B%02d: ", cur.linearScanNumber(), cur.blockID)); 415 TTY.print(String.format("%4d: B%02d: ", cur.linearScanNumber(), cur.blockID));
460 for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) { 416 // for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) {
461 TTY.print(String.format("%d = %b ", loopIdx, isBlockInLoop(loopIdx, cur))); 417 // TTY.print(String.format("%d = %b ", loopIdx, isBlockInLoop(loopIdx, cur)));
462 } 418 // }
463 TTY.println(String.format(" . loopIndex: %2d, loopDepth: %2d", cur.loopIndex(), cur.loopDepth())); 419 TTY.println(String.format(" . loopIndex: %2d, loopDepth: %2d", -1, -1));
464 } 420 }
465 } 421 }
466 422
467 if (C1XOptions.TraceLinearScanLevel >= 1) { 423 if (C1XOptions.TraceLinearScanLevel >= 1) {
468 TTY.println("----- linear-scan block order:"); 424 TTY.println("----- linear-scan block order:");
469 for (BlockBegin cur : linearScanOrder) { 425 for (BlockBegin cur : linearScanOrder) {
470 TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID, cur.loopIndex(), cur.loopDepth())); 426 TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID, -1, -1));
471 427
472 TTY.print(cur.isLinearScanLoopHeader() ? " lh" : " "); 428 TTY.print(cur.isLinearScanLoopHeader() ? " lh" : " ");
473 TTY.print(cur.isLinearScanLoopEnd() ? " le" : " "); 429 TTY.print(cur.isLinearScanLoopEnd() ? " le" : " ");
474 430
475 if (cur.numberOfPreds() > 0) { 431 if (cur.numberOfPreds() > 0) {
512 for (BlockBegin sux : cur.end().blockSuccessors()) { 468 for (BlockBegin sux : cur.end().blockSuccessors()) {
513 assert sux.linearScanNumber() >= 0 && sux.linearScanNumber() == linearScanOrder.indexOf(sux) : "incorrect linearScanNumber"; 469 assert sux.linearScanNumber() >= 0 && sux.linearScanNumber() == linearScanOrder.indexOf(sux) : "incorrect linearScanNumber";
514 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd)) { 470 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd)) {
515 assert cur.linearScanNumber() < sux.linearScanNumber() : "invalid order"; 471 assert cur.linearScanNumber() < sux.linearScanNumber() : "invalid order";
516 } 472 }
517 if (cur.loopDepth() == sux.loopDepth()) { 473 //if (cur.loopDepth() == sux.loopDepth()) {
518 assert cur.loopIndex() == sux.loopIndex() || sux.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index"; 474 // assert cur.loopIndex() == sux.loopIndex() || sux.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index";
519 } 475 //}
520 } 476 }
521 477
522 for (Instruction pred : cur.blockPredecessors()) { 478 for (Instruction pred : cur.blockPredecessors()) {
523 BlockBegin begin = pred.block(); 479 BlockBegin begin = pred.block();
524 assert begin.linearScanNumber() >= 0 && begin.linearScanNumber() == linearScanOrder.indexOf(begin) : "incorrect linearScanNumber"; 480 assert begin.linearScanNumber() >= 0 && begin.linearScanNumber() == linearScanOrder.indexOf(begin) : "incorrect linearScanNumber";
525 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) { 481 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) {
526 assert cur.linearScanNumber() > begin.linearScanNumber() : "invalid order"; 482 assert cur.linearScanNumber() > begin.linearScanNumber() : "invalid order";
527 } 483 }
528 if (cur.loopDepth() == begin.loopDepth()) { 484 //if (cur.loopDepth() == begin.loopDepth()) {
529 assert cur.loopIndex() == begin.loopIndex() || cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index"; 485 // assert cur.loopIndex() == begin.loopIndex() || cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index";
530 } 486 //}
531 } 487 }
532 } 488 }
533 489
534 // check that all loops are continuous 490 // check that all loops are continuous
535 for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) { 491 // for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) {
536 int blockIdx = 0; 492 // int blockIdx = 0;
537 assert !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx)) : "the first block must not be present in any loop"; 493 // assert !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx)) : "the first block must not be present in any loop";
538 494 //
539 // skip blocks before the loop 495 // // skip blocks before the loop
540 while (blockIdx < numBlocks && !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx))) { 496 // while (blockIdx < numBlocks && !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx))) {
541 blockIdx++; 497 // blockIdx++;
542 } 498 // }
543 // skip blocks of loop 499 // // skip blocks of loop
544 while (blockIdx < numBlocks && isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx))) { 500 // while (blockIdx < numBlocks && isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx))) {
545 blockIdx++; 501 // blockIdx++;
546 } 502 // }
547 // after the first non-loop block : there must not be another loop-block 503 // // after the first non-loop block : there must not be another loop-block
548 while (blockIdx < numBlocks) { 504 // while (blockIdx < numBlocks) {
549 assert !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx)) : "loop not continuous in linear-scan order"; 505 // assert !isBlockInLoop(loopIdx, linearScanOrder.get(blockIdx)) : "loop not continuous in linear-scan order";
550 blockIdx++; 506 // blockIdx++;
551 } 507 // }
552 } 508 // }
553 509
554 return true; 510 return true;
555 } 511 }
556 } 512 }