Mercurial > hg > graal-compiler
comparison graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java @ 2707:7ed72769d51a
exception handling related changes:
* changed blockPredecessors to list of Instructions, instead of Blocks
* removed explicit predecessor management in BlockBegin, now using predecessors from Graph structure
* replaced generated LIR exception entries with exception dispatch chains in IR
* added Unwind and ExceptionDispatch instructions
* removed ExceptionEntry flag in BlockBegin and all code depending on it
* removed exceptionHandler list from Instruction, replaced by exception Edge on Invoke and Throw
* replaced list of ExceptionHandlers with single exception edge in debug info
misc:
* changed GraphvizPrinter layout (smaller ports on large nodes)
* removed defunct run config
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Wed, 18 May 2011 18:09:20 +0200 |
parents | 6ab73784566a |
children | 4272b7af2d17 |
comparison
equal
deleted
inserted
replaced
2677:0ea5f12e873a | 2707:7ed72769d51a |
---|---|
138 * 1. Count of total number of blocks. | 138 * 1. Count of total number of blocks. |
139 * 2. Count of all incoming edges and backward incoming edges. | 139 * 2. Count of all incoming edges and backward incoming edges. |
140 * 3. Number loop header blocks. | 140 * 3. Number loop header blocks. |
141 * 4. Create a list with all loop end blocks. | 141 * 4. Create a list with all loop end blocks. |
142 */ | 142 */ |
143 private void countEdges(BlockBegin cur, BlockBegin parent) { | 143 private void countEdges(final BlockBegin cur, BlockBegin parent) { |
144 if (C1XOptions.TraceLinearScanLevel >= 3) { | 144 if (C1XOptions.TraceLinearScanLevel >= 3) { |
145 TTY.println("Counting edges for block B%d%s", cur.blockID, parent == null ? "" : " coming from B" + parent.blockID); | 145 TTY.println("Counting edges for block B%d%s", cur.blockID, parent == null ? "" : " coming from B" + parent.blockID); |
146 } | 146 } |
147 assert cur.dominator() == null : "dominator already initialized"; | 147 assert cur.dominator() == null : "dominator already initialized"; |
148 | 148 |
156 cur.setBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader); | 156 cur.setBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader); |
157 cur.setBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget); | 157 cur.setBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget); |
158 | 158 |
159 parent.setBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd); | 159 parent.setBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd); |
160 | 160 |
161 // When a loop header is also the start of an exception handler, then the backward branch is | |
162 // an exception edge. Because such edges are usually critical edges which cannot be split, the | |
163 // loop must be excluded here from processing. | |
164 if (cur.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry)) { | |
165 // Make sure that dominators are correct in this weird situation | |
166 iterativeDominators = true; | |
167 return; | |
168 } | |
169 | |
170 loopEndBlocks.add(parent); | 161 loopEndBlocks.add(parent); |
171 return; | 162 return; |
172 } | 163 } |
173 | 164 |
174 // increment number of incoming forward branches | 165 // increment number of incoming forward branches |
184 numBlocks++; | 175 numBlocks++; |
185 setVisited(cur); | 176 setVisited(cur); |
186 setActive(cur); | 177 setActive(cur); |
187 | 178 |
188 // recursive call for all successors | 179 // recursive call for all successors |
189 int i; | 180 cur.allSuccessorsDo(true, new BlockClosure() { |
190 for (i = cur.numberOfSux() - 1; i >= 0; i--) { | 181 public void apply(BlockBegin block) { |
191 countEdges(cur.suxAt(i), cur); | 182 countEdges(block, cur); |
192 } | 183 } |
193 for (i = cur.numberOfExceptionHandlers() - 1; i >= 0; i--) { | 184 }); |
194 countEdges(cur.exceptionHandlerAt(i), cur); | |
195 } | |
196 | 185 |
197 clearActive(cur); | 186 clearActive(cur); |
198 | 187 |
199 // Each loop has a unique number. | 188 // Each loop has a unique number. |
200 // When multiple loops are nested, assignLoopDepth assumes that the | 189 // When multiple loops are nested, assignLoopDepth assumes that the |
248 assert isBlockInLoop(loopIdx, cur) : "bit in loop map must be set when block is in work list"; | 237 assert isBlockInLoop(loopIdx, cur) : "bit in loop map must be set when block is in work list"; |
249 | 238 |
250 // recursive processing of all predecessors ends when start block of loop is reached | 239 // recursive processing of all predecessors ends when start block of loop is reached |
251 if (cur != loopStart) { | 240 if (cur != loopStart) { |
252 for (int j = cur.numberOfPreds() - 1; j >= 0; j--) { | 241 for (int j = cur.numberOfPreds() - 1; j >= 0; j--) { |
253 BlockBegin pred = cur.predAt(j).begin(); | 242 BlockBegin pred = cur.predAt(j).block(); |
254 | 243 |
255 if (!isBlockInLoop(loopIdx, pred)) { | 244 if (!isBlockInLoop(loopIdx, pred)) { |
256 // this predecessor has not been processed yet, so add it to work list | 245 // this predecessor has not been processed yet, so add it to work list |
257 if (C1XOptions.TraceLinearScanLevel >= 3) { | 246 if (C1XOptions.TraceLinearScanLevel >= 3) { |
258 TTY.println(" pushing B%d", pred.blockID); | 247 TTY.println(" pushing B%d", pred.blockID); |
317 } | 306 } |
318 cur.setLoopDepth(loopDepth); | 307 cur.setLoopDepth(loopDepth); |
319 cur.setLoopIndex(minLoopIdx); | 308 cur.setLoopIndex(minLoopIdx); |
320 | 309 |
321 // append all unvisited successors to work list | 310 // append all unvisited successors to work list |
322 for (i = cur.numberOfSux() - 1; i >= 0; i--) { | 311 cur.allSuccessorsDo(true, new BlockClosure() { |
323 workList.add(cur.suxAt(i)); | 312 public void apply(BlockBegin block) { |
324 } | 313 workList.add(block); |
325 for (i = cur.numberOfExceptionHandlers() - 1; i >= 0; i--) { | 314 } |
326 workList.add(cur.exceptionHandlerAt(i)); | 315 }); |
327 } | |
328 } | 316 } |
329 } while (!workList.isEmpty()); | 317 } while (!workList.isEmpty()); |
330 } | 318 } |
331 | 319 |
332 private BlockBegin commonDominator(BlockBegin a, BlockBegin b) { | 320 private BlockBegin commonDominator(BlockBegin a, BlockBegin b) { |
350 private void computeDominator(BlockBegin cur, BlockBegin parent) { | 338 private void computeDominator(BlockBegin cur, BlockBegin parent) { |
351 if (cur.dominator() == null) { | 339 if (cur.dominator() == null) { |
352 if (C1XOptions.TraceLinearScanLevel >= 4) { | 340 if (C1XOptions.TraceLinearScanLevel >= 4) { |
353 TTY.println("DOM: initializing dominator of B%d to B%d", cur.blockID, parent.blockID); | 341 TTY.println("DOM: initializing dominator of B%d to B%d", cur.blockID, parent.blockID); |
354 } | 342 } |
355 if (cur.isExceptionEntry()) { | 343 cur.setDominator(parent); |
356 assert parent.dominator() != null; | |
357 cur.setDominator(parent.dominator()); | |
358 } else { | |
359 cur.setDominator(parent); | |
360 } | |
361 | 344 |
362 } else if (!(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) && parent.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd))) { | 345 } else if (!(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) && parent.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd))) { |
363 if (C1XOptions.TraceLinearScanLevel >= 4) { | 346 if (C1XOptions.TraceLinearScanLevel >= 4) { |
364 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); | 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); |
365 } | 348 } |
410 if (!(cur.end() instanceof Return) && (singleSux == null || !(singleSux.end() instanceof Return))) { | 393 if (!(cur.end() instanceof Return) && (singleSux == null || !(singleSux.end() instanceof Return))) { |
411 weight |= (1 << curBit); | 394 weight |= (1 << curBit); |
412 } | 395 } |
413 curBit--; | 396 curBit--; |
414 | 397 |
415 // exceptions handlers are added as late as possible | 398 // // exceptions handlers are added as late as possible |
416 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry)) { | 399 // if (!cur.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry)) { |
417 weight |= (1 << curBit); | 400 // weight |= (1 << curBit); |
418 } | 401 // } |
419 curBit--; | 402 curBit--; |
420 | 403 |
421 // guarantee that weight is > 0 | 404 // guarantee that weight is > 0 |
422 weight |= 1; | 405 weight |= 1; |
423 | 406 |
503 } else { | 486 } else { |
504 throw new CiBailout("the stdEntry must be ready for processing (otherwise, the method has no start block)"); | 487 throw new CiBailout("the stdEntry must be ready for processing (otherwise, the method has no start block)"); |
505 } | 488 } |
506 | 489 |
507 do { | 490 do { |
508 BlockBegin cur = workList.remove(workList.size() - 1); | 491 final BlockBegin cur = workList.remove(workList.size() - 1); |
509 appendBlock(cur); | 492 appendBlock(cur); |
510 | 493 |
511 int i; | 494 cur.allSuccessorsDo(false, new BlockClosure() { |
512 int numSux = cur.numberOfSux(); | 495 public void apply(BlockBegin block) { |
513 // changed loop order to get "intuitive" order of if- and else-blocks | 496 computeDominator(block, cur); |
514 for (i = 0; i < numSux; i++) { | 497 if (readyForProcessing(block)) { |
515 BlockBegin sux = cur.suxAt(i); | 498 sortIntoWorkList(block); |
516 computeDominator(sux, cur); | 499 } |
517 if (readyForProcessing(sux)) { | 500 } |
518 sortIntoWorkList(sux); | 501 }); |
519 } | |
520 } | |
521 numSux = cur.numberOfExceptionHandlers(); | |
522 for (i = 0; i < numSux; i++) { | |
523 BlockBegin sux = cur.exceptionHandlerAt(i); | |
524 computeDominator(sux, cur); | |
525 if (readyForProcessing(sux)) { | |
526 sortIntoWorkList(sux); | |
527 } | |
528 } | |
529 } while (workList.size() > 0); | 502 } while (workList.size() > 0); |
530 } | 503 } |
531 | 504 |
532 private boolean computeDominatorsIter() { | 505 private boolean computeDominatorsIter() { |
533 boolean changed = false; | 506 boolean changed = false; |
537 assert linearScanOrder.get(0).numberOfPreds() == 0 : "must not have predecessors"; | 510 assert linearScanOrder.get(0).numberOfPreds() == 0 : "must not have predecessors"; |
538 for (int i = 1; i < numBlocks; i++) { | 511 for (int i = 1; i < numBlocks; i++) { |
539 BlockBegin block = linearScanOrder.get(i); | 512 BlockBegin block = linearScanOrder.get(i); |
540 | 513 |
541 assert block.numberOfPreds() > 0; | 514 assert block.numberOfPreds() > 0; |
542 BlockBegin dominator = block.predAt(0).begin(); | 515 BlockBegin dominator = block.predAt(0).block(); |
543 if (block.isExceptionEntry()) { | |
544 dominator = dominator.dominator(); | |
545 } | |
546 | 516 |
547 int numPreds = block.numberOfPreds(); | 517 int numPreds = block.numberOfPreds(); |
548 for (int j = 1; j < numPreds; j++) { | 518 for (int j = 1; j < numPreds; j++) { |
549 BlockBegin curPred = block.predAt(j).begin(); | 519 BlockBegin curPred = block.predAt(j).block(); |
550 if (block.isExceptionEntry()) { | |
551 curPred = curPred.dominator(); | |
552 } | |
553 dominator = commonDominator(dominator, curPred); | 520 dominator = commonDominator(dominator, curPred); |
554 } | 521 } |
555 | 522 |
556 if (dominator != block.dominator()) { | 523 if (dominator != block.dominator()) { |
557 if (C1XOptions.TraceLinearScanLevel >= 4) { | 524 if (C1XOptions.TraceLinearScanLevel >= 4) { |
599 if (C1XOptions.TraceLinearScanLevel >= 1) { | 566 if (C1XOptions.TraceLinearScanLevel >= 1) { |
600 TTY.println("----- linear-scan block order:"); | 567 TTY.println("----- linear-scan block order:"); |
601 for (BlockBegin cur : linearScanOrder) { | 568 for (BlockBegin cur : linearScanOrder) { |
602 TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID, cur.loopIndex(), cur.loopDepth())); | 569 TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID, cur.loopIndex(), cur.loopDepth())); |
603 | 570 |
604 TTY.print(cur.isExceptionEntry() ? " ex" : " "); | |
605 TTY.print(cur.isCriticalEdgeSplit() ? " ce" : " "); | 571 TTY.print(cur.isCriticalEdgeSplit() ? " ce" : " "); |
606 TTY.print(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) ? " lh" : " "); | 572 TTY.print(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) ? " lh" : " "); |
607 TTY.print(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd) ? " le" : " "); | 573 TTY.print(cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd) ? " le" : " "); |
608 | 574 |
609 if (cur.dominator() != null) { | 575 if (cur.dominator() != null) { |
613 } | 579 } |
614 | 580 |
615 if (cur.numberOfPreds() > 0) { | 581 if (cur.numberOfPreds() > 0) { |
616 TTY.print(" preds: "); | 582 TTY.print(" preds: "); |
617 for (int j = 0; j < cur.numberOfPreds(); j++) { | 583 for (int j = 0; j < cur.numberOfPreds(); j++) { |
618 BlockBegin pred = cur.predAt(j).begin(); | 584 BlockBegin pred = cur.predAt(j).block(); |
619 TTY.print("B%d ", pred.blockID); | 585 TTY.print("B%d ", pred.blockID); |
620 } | 586 } |
621 } | 587 } |
622 if (cur.numberOfSux() > 0) { | 588 if (cur.numberOfSux() > 0) { |
623 TTY.print(" sux: "); | 589 TTY.print(" sux: "); |
624 for (int j = 0; j < cur.numberOfSux(); j++) { | 590 for (int j = 0; j < cur.numberOfSux(); j++) { |
625 BlockBegin sux = cur.suxAt(j); | 591 BlockBegin sux = cur.suxAt(j); |
626 TTY.print("B%d ", sux.blockID); | 592 TTY.print("B%d ", sux.blockID); |
627 } | 593 } |
628 } | 594 } |
629 if (cur.numberOfExceptionHandlers() > 0) { | |
630 TTY.print(" ex: "); | |
631 for (int j = 0; j < cur.numberOfExceptionHandlers(); j++) { | |
632 BlockBegin ex = cur.exceptionHandlerAt(j); | |
633 TTY.print("B%d ", ex.blockID); | |
634 } | |
635 } | |
636 TTY.println(); | 595 TTY.println(); |
637 } | 596 } |
638 } | 597 } |
639 } | 598 } |
640 | 599 |
664 if (cur.loopDepth() == sux.loopDepth()) { | 623 if (cur.loopDepth() == sux.loopDepth()) { |
665 assert cur.loopIndex() == sux.loopIndex() || sux.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index"; | 624 assert cur.loopIndex() == sux.loopIndex() || sux.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader) : "successing blocks with same loop depth must have same loop index"; |
666 } | 625 } |
667 } | 626 } |
668 | 627 |
669 for (BlockEnd pred : cur.blockPredecessors()) { | 628 for (Instruction pred : cur.blockPredecessors()) { |
670 BlockBegin begin = pred.begin(); | 629 BlockBegin begin = pred.block(); |
671 assert begin.linearScanNumber() >= 0 && begin.linearScanNumber() == linearScanOrder.indexOf(begin) : "incorrect linearScanNumber"; | 630 assert begin.linearScanNumber() >= 0 && begin.linearScanNumber() == linearScanOrder.indexOf(begin) : "incorrect linearScanNumber"; |
672 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) { | 631 if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) { |
673 assert cur.linearScanNumber() > begin.linearScanNumber() : "invalid order"; | 632 assert cur.linearScanNumber() > begin.linearScanNumber() : "invalid order"; |
674 } | 633 } |
675 if (cur.loopDepth() == begin.loopDepth()) { | 634 if (cur.loopDepth() == begin.loopDepth()) { |
683 if (i == 0) { | 642 if (i == 0) { |
684 assert cur.dominator() == null : "first block has no dominator"; | 643 assert cur.dominator() == null : "first block has no dominator"; |
685 } else { | 644 } else { |
686 assert cur.dominator() != null : "all but first block must have dominator"; | 645 assert cur.dominator() != null : "all but first block must have dominator"; |
687 } | 646 } |
688 assert cur.numberOfPreds() != 1 || cur.dominator() == cur.predAt(0).begin() || cur.isExceptionEntry() : "Single predecessor must also be dominator"; | 647 assert cur.numberOfPreds() != 1 || cur.dominator() == cur.predAt(0).block() : "Single predecessor must also be dominator"; |
689 } | 648 } |
690 | 649 |
691 // check that all loops are continuous | 650 // check that all loops are continuous |
692 for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) { | 651 for (int loopIdx = 0; loopIdx < numLoops; loopIdx++) { |
693 int blockIdx = 0; | 652 int blockIdx = 0; |