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;