Mercurial > hg > truffle
comparison graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java @ 2708:4272b7af2d17
merge
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Wed, 18 May 2011 18:40:58 +0200 |
parents | 7ed72769d51a efbdb3ea95c9 |
children | bd85cf08720a |
comparison
equal
deleted
inserted
replaced
2707:7ed72769d51a | 2708:4272b7af2d17 |
---|---|
124 clearNonNaturalLoops(startBlock); | 124 clearNonNaturalLoops(startBlock); |
125 assignLoopDepth(startBlock); | 125 assignLoopDepth(startBlock); |
126 } | 126 } |
127 | 127 |
128 computeOrder(startBlock); | 128 computeOrder(startBlock); |
129 computeDominators(); | |
130 | 129 |
131 printBlocks(); | 130 printBlocks(); |
132 assert verify(); | 131 assert verify(); |
133 } | 132 } |
134 | 133 |
142 */ | 141 */ |
143 private void countEdges(final BlockBegin cur, BlockBegin parent) { | 142 private void countEdges(final BlockBegin cur, BlockBegin parent) { |
144 if (C1XOptions.TraceLinearScanLevel >= 3) { | 143 if (C1XOptions.TraceLinearScanLevel >= 3) { |
145 TTY.println("Counting edges for block B%d%s", cur.blockID, parent == null ? "" : " coming from B" + parent.blockID); | 144 TTY.println("Counting edges for block B%d%s", cur.blockID, parent == null ? "" : " coming from B" + parent.blockID); |
146 } | 145 } |
147 assert cur.dominator() == null : "dominator already initialized"; | |
148 | 146 |
149 if (isActive(cur)) { | 147 if (isActive(cur)) { |
150 if (C1XOptions.TraceLinearScanLevel >= 3) { | 148 if (C1XOptions.TraceLinearScanLevel >= 3) { |
151 TTY.println("backward branch"); | 149 TTY.println("backward branch"); |
152 } | 150 } |
218 int loopIdx = loopStart.loopIndex(); | 216 int loopIdx = loopStart.loopIndex(); |
219 | 217 |
220 if (C1XOptions.TraceLinearScanLevel >= 3) { | 218 if (C1XOptions.TraceLinearScanLevel >= 3) { |
221 TTY.println("Processing loop from B%d to B%d (loop %d):", loopStart.blockID, loopEnd.blockID, loopIdx); | 219 TTY.println("Processing loop from B%d to B%d (loop %d):", loopStart.blockID, loopEnd.blockID, loopIdx); |
222 } | 220 } |
223 assert loopEnd.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd) : "loop end flag must be set"; | 221 assert loopEnd.isLinearScanLoopEnd() : "loop end flag must be set"; |
224 assert loopStart.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "loop header flag must be set"; | 222 assert loopStart.isLinearScanLoopHeader() : "loop header flag must be set"; |
225 assert loopIdx >= 0 && loopIdx < numLoops : "loop index not set"; | 223 assert loopIdx >= 0 && loopIdx < numLoops : "loop index not set"; |
226 assert workList.isEmpty() : "work list must be empty before processing"; | 224 assert workList.isEmpty() : "work list must be empty before processing"; |
227 | 225 |
228 // add the end-block of the loop to the working list | 226 // add the end-block of the loop to the working list |
229 workList.add(loopEnd); | 227 workList.add(loopEnd); |
315 }); | 313 }); |
316 } | 314 } |
317 } while (!workList.isEmpty()); | 315 } while (!workList.isEmpty()); |
318 } | 316 } |
319 | 317 |
320 private BlockBegin commonDominator(BlockBegin a, BlockBegin b) { | |
321 assert a != null && b != null : "must have input blocks"; | |
322 | |
323 dominatorBlocks.clearAll(); | |
324 while (a != null) { | |
325 dominatorBlocks.set(a.blockID); | |
326 assert a.dominator() != null || a == linearScanOrder.get(0) : "dominator must be initialized"; | |
327 a = a.dominator(); | |
328 } | |
329 while (b != null && !dominatorBlocks.get(b.blockID)) { | |
330 assert b.dominator() != null || b == linearScanOrder.get(0) : "dominator must be initialized"; | |
331 b = b.dominator(); | |
332 } | |
333 | |
334 assert b != null : "could not find dominator"; | |
335 return b; | |
336 } | |
337 | |
338 private void computeDominator(BlockBegin cur, BlockBegin parent) { | |
339 if (cur.dominator() == null) { | |
340 if (C1XOptions.TraceLinearScanLevel >= 4) { | |
341 TTY.println("DOM: initializing dominator of B%d to B%d", cur.blockID, parent.blockID); | |
342 } | |
343 cur.setDominator(parent); | |
344 | |
345 } else if (!(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) && parent.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd))) { | |
346 if (C1XOptions.TraceLinearScanLevel >= 4) { | |
347 TTY.println("DOM: computing dominator of B%d: common dominator of B%d and B%d is B%d", cur.blockID, parent.blockID, cur.dominator().blockID, commonDominator(cur.dominator(), parent).blockID); | |
348 } | |
349 assert cur.numberOfPreds() > 1 : ""; | |
350 cur.setDominator(commonDominator(cur.dominator(), parent)); | |
351 } | |
352 } | |
353 | |
354 private int computeWeight(BlockBegin cur) { | 318 private int computeWeight(BlockBegin cur) { |
355 BlockBegin singleSux = null; | 319 BlockBegin singleSux = null; |
356 if (cur.numberOfSux() == 1) { | 320 if (cur.numberOfSux() == 1) { |
357 singleSux = cur.suxAt(0); | 321 singleSux = cur.suxAt(0); |
358 } | 322 } |
363 int curBit = 15; | 327 int curBit = 15; |
364 | 328 |
365 // this is necessary for the (very rare) case that two successive blocks have | 329 // this is necessary for the (very rare) case that two successive blocks have |
366 // the same loop depth, but a different loop index (can happen for endless loops | 330 // the same loop depth, but a different loop index (can happen for endless loops |
367 // with exception handlers) | 331 // with exception handlers) |
368 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) { | 332 if (!cur.isLinearScanLoopHeader()) { |
369 weight |= (1 << curBit); | 333 weight |= (1 << curBit); |
370 } | 334 } |
371 curBit--; | 335 curBit--; |
372 | 336 |
373 // loop end blocks (blocks that end with a backward branch) are added | 337 // loop end blocks (blocks that end with a backward branch) are added |
374 // after all other blocks of the loop. | 338 // after all other blocks of the loop. |
375 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd)) { | 339 if (!cur.isLinearScanLoopEnd()) { |
376 weight |= (1 << curBit); | |
377 } | |
378 curBit--; | |
379 | |
380 // critical edge split blocks are preferred because then they have a greater | |
381 // probability to be completely empty | |
382 if (cur.isCriticalEdgeSplit()) { | |
383 weight |= (1 << curBit); | 340 weight |= (1 << curBit); |
384 } | 341 } |
385 curBit--; | 342 curBit--; |
386 | 343 |
387 // exceptions should not be thrown in normal control flow, so these blocks | 344 // exceptions should not be thrown in normal control flow, so these blocks |
491 final BlockBegin cur = workList.remove(workList.size() - 1); | 448 final BlockBegin cur = workList.remove(workList.size() - 1); |
492 appendBlock(cur); | 449 appendBlock(cur); |
493 | 450 |
494 cur.allSuccessorsDo(false, new BlockClosure() { | 451 cur.allSuccessorsDo(false, new BlockClosure() { |
495 public void apply(BlockBegin block) { | 452 public void apply(BlockBegin block) { |
496 computeDominator(block, cur); | |
497 if (readyForProcessing(block)) { | 453 if (readyForProcessing(block)) { |
498 sortIntoWorkList(block); | 454 sortIntoWorkList(block); |
499 } | 455 } |
500 } | 456 } |
501 }); | 457 }); |
502 } while (workList.size() > 0); | 458 } while (workList.size() > 0); |
503 } | |
504 | |
505 private boolean computeDominatorsIter() { | |
506 boolean changed = false; | |
507 int numBlocks = linearScanOrder.size(); | |
508 | |
509 assert linearScanOrder.get(0).dominator() == null : "must not have dominator"; | |
510 assert linearScanOrder.get(0).numberOfPreds() == 0 : "must not have predecessors"; | |
511 for (int i = 1; i < numBlocks; i++) { | |
512 BlockBegin block = linearScanOrder.get(i); | |
513 | |
514 assert block.numberOfPreds() > 0; | |
515 BlockBegin dominator = block.predAt(0).block(); | |
516 | |
517 int numPreds = block.numberOfPreds(); | |
518 for (int j = 1; j < numPreds; j++) { | |
519 BlockBegin curPred = block.predAt(j).block(); | |
520 dominator = commonDominator(dominator, curPred); | |
521 } | |
522 | |
523 if (dominator != block.dominator()) { | |
524 if (C1XOptions.TraceLinearScanLevel >= 4) { | |
525 TTY.println("DOM: updating dominator of B%d from B%d to B%d", block.blockID, block.dominator().blockID, dominator.blockID); | |
526 } | |
527 block.setDominator(dominator); | |
528 changed = true; | |
529 } | |
530 } | |
531 return changed; | |
532 } | |
533 | |
534 private void computeDominators() { | |
535 if (C1XOptions.TraceLinearScanLevel >= 3) { | |
536 TTY.println("----- computing dominators (iterative computation required: %b)", iterativeDominators); | |
537 } | |
538 | |
539 // iterative computation of dominators is only required for methods with non-natural loops | |
540 // and OSR-methods. For all other methods : the dominators computed when generating the | |
541 // linear scan block order are correct. | |
542 if (iterativeDominators) { | |
543 do { | |
544 if (C1XOptions.TraceLinearScanLevel >= 1) { | |
545 TTY.println("DOM: next iteration of fix-point calculation"); | |
546 } | |
547 } while (computeDominatorsIter()); | |
548 } | |
549 | |
550 // check that dominators are correct | |
551 assert !computeDominatorsIter() : "fix point not reached"; | |
552 } | 459 } |
553 | 460 |
554 public void printBlocks() { | 461 public void printBlocks() { |
555 if (C1XOptions.TraceLinearScanLevel >= 2) { | 462 if (C1XOptions.TraceLinearScanLevel >= 2) { |
556 TTY.println("----- loop information:"); | 463 TTY.println("----- loop information:"); |
566 if (C1XOptions.TraceLinearScanLevel >= 1) { | 473 if (C1XOptions.TraceLinearScanLevel >= 1) { |
567 TTY.println("----- linear-scan block order:"); | 474 TTY.println("----- linear-scan block order:"); |
568 for (BlockBegin cur : linearScanOrder) { | 475 for (BlockBegin cur : linearScanOrder) { |
569 TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID, cur.loopIndex(), cur.loopDepth())); | 476 TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID, cur.loopIndex(), cur.loopDepth())); |
570 | 477 |
571 TTY.print(cur.isCriticalEdgeSplit() ? " ce" : " "); | 478 TTY.print(cur.isLinearScanLoopHeader() ? " lh" : " "); |
572 TTY.print(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) ? " lh" : " "); | 479 TTY.print(cur.isLinearScanLoopEnd() ? " le" : " "); |
573 TTY.print(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd) ? " le" : " "); | |
574 | |
575 if (cur.dominator() != null) { | |
576 TTY.print(" dom: B%d ", cur.dominator().blockID); | |
577 } else { | |
578 TTY.print(" dom: null "); | |
579 } | |
580 | 480 |
581 if (cur.numberOfPreds() > 0) { | 481 if (cur.numberOfPreds() > 0) { |
582 TTY.print(" preds: "); | 482 TTY.print(" preds: "); |
583 for (int j = 0; j < cur.numberOfPreds(); j++) { | 483 for (int j = 0; j < cur.numberOfPreds(); j++) { |
584 BlockBegin pred = cur.predAt(j).block(); | 484 BlockBegin pred = cur.predAt(j).block(); |
632 assert cur.linearScanNumber() > begin.linearScanNumber() : "invalid order"; | 532 assert cur.linearScanNumber() > begin.linearScanNumber() : "invalid order"; |
633 } | 533 } |
634 if (cur.loopDepth() == begin.loopDepth()) { | 534 if (cur.loopDepth() == begin.loopDepth()) { |
635 assert cur.loopIndex() == begin.loopIndex() || cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index"; | 535 assert cur.loopIndex() == begin.loopIndex() || cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index"; |
636 } | 536 } |
637 | 537 } |
638 assert cur.dominator().linearScanNumber() <= begin.linearScanNumber() : "dominator must be before predecessors"; | |
639 } | |
640 | |
641 // check dominator | |
642 if (i == 0) { | |
643 assert cur.dominator() == null : "first block has no dominator"; | |
644 } else { | |
645 assert cur.dominator() != null : "all but first block must have dominator"; | |
646 } | |
647 assert cur.numberOfPreds() != 1 || cur.dominator() == cur.predAt(0).block() : "Single predecessor must also be dominator"; | |
648 } | 538 } |
649 | 539 |
650 // check that all loops are continuous | 540 // check that all loops are continuous |
651 for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) { | 541 for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) { |
652 int blockIdx = 0; | 542 int blockIdx = 0; |