Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
| 9 * methods. We need to implement [TypedElement.type] because our | 9 * methods. We need to implement [TypedElement.type] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 2379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2390 jumpHandler.labels()); | 2390 jumpHandler.labels()); |
| 2391 previousBlock.addSuccessor(loopEntry); | 2391 previousBlock.addSuccessor(loopEntry); |
| 2392 open(loopEntry); | 2392 open(loopEntry); |
| 2393 | 2393 |
| 2394 localsHandler.beginLoopHeader(loopEntry); | 2394 localsHandler.beginLoopHeader(loopEntry); |
| 2395 return jumpHandler; | 2395 return jumpHandler; |
| 2396 } | 2396 } |
| 2397 | 2397 |
| 2398 /** | 2398 /** |
| 2399 * Ends the loop: | 2399 * Ends the loop: |
| 2400 * - creates a new block and adds it as successor to the [branchBlock] and | 2400 * - creates a new block and adds it as successor to the [branchExitBlock] and |
| 2401 * any blocks that end in break. | 2401 * any blocks that end in break. |
| 2402 * - opens the new block (setting as [current]). | 2402 * - opens the new block (setting as [current]). |
| 2403 * - notifies the locals handler that we're exiting a loop. | 2403 * - notifies the locals handler that we're exiting a loop. |
| 2404 * [savedLocals] are the locals from the end of the loop condition. | 2404 * [savedLocals] are the locals from the end of the loop condition. |
| 2405 * [branchBlock] is the exit (branching) block of the condition. For the | 2405 * [branchExitBlock] is the exit (branching) block of the condition. Generally |
| 2406 * while and for loops this is at the top of the loop. For do-while it is | 2406 * this is not the top of the loop, since this would lead to critical edges. |
| 2407 * the end of the body. It is null for degenerate do-while loops that have | 2407 * It is null for degenerate do-while loops that have |
| 2408 * no back edge because they abort (throw/return/break in the body and have | 2408 * no back edge because they abort (throw/return/break in the body and have |
| 2409 * no continues). | 2409 * no continues). |
| 2410 */ | 2410 */ |
| 2411 void endLoop(HBasicBlock loopEntry, | 2411 void endLoop(HBasicBlock loopEntry, |
| 2412 HBasicBlock branchBlock, | 2412 HBasicBlock branchExitBlock, |
| 2413 JumpHandler jumpHandler, | 2413 JumpHandler jumpHandler, |
| 2414 LocalsHandler savedLocals) { | 2414 LocalsHandler savedLocals) { |
| 2415 HBasicBlock loopExitBlock = addNewBlock(); | 2415 HBasicBlock loopExitBlock = addNewBlock(); |
| 2416 | |
| 2416 List<LocalsHandler> breakHandlers = <LocalsHandler>[]; | 2417 List<LocalsHandler> breakHandlers = <LocalsHandler>[]; |
| 2417 // Collect data for the successors and the phis at each break. | 2418 // Collect data for the successors and the phis at each break. |
| 2418 jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { | 2419 jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { |
| 2419 breakInstruction.block.addSuccessor(loopExitBlock); | 2420 breakInstruction.block.addSuccessor(loopExitBlock); |
| 2420 breakHandlers.add(locals); | 2421 breakHandlers.add(locals); |
| 2421 }); | 2422 }); |
| 2423 | |
| 2422 // The exit block is a successor of the loop condition if it is reached. | 2424 // The exit block is a successor of the loop condition if it is reached. |
| 2423 // We don't add the successor in the case of a while/for loop that aborts | 2425 // We don't add the successor in the case of a while/for loop that aborts |
| 2424 // because the caller of endLoop will be wiring up a special empty else | 2426 // because the caller of endLoop will be wiring up a special empty else |
| 2425 // block instead. | 2427 // block instead. |
| 2426 if (branchBlock != null) { | 2428 if (branchExitBlock != null) { |
| 2427 branchBlock.addSuccessor(loopExitBlock); | 2429 branchExitBlock.addSuccessor(loopExitBlock); |
| 2428 } | 2430 } |
| 2429 // Update the phis at the loop entry with the current values of locals. | 2431 // Update the phis at the loop entry with the current values of locals. |
| 2430 localsHandler.endLoop(loopEntry); | 2432 localsHandler.endLoop(loopEntry); |
| 2431 | 2433 |
| 2432 // Start generating code for the exit block. | 2434 // Start generating code for the exit block. |
| 2433 open(loopExitBlock); | 2435 open(loopExitBlock); |
| 2434 | 2436 |
| 2435 // Create a new localsHandler for the loopExitBlock with the correct phis. | 2437 // Create a new localsHandler for the loopExitBlock with the correct phis. |
| 2436 if (!breakHandlers.isEmpty) { | 2438 if (!breakHandlers.isEmpty) { |
| 2437 if (branchBlock != null) { | 2439 if (branchExitBlock != null) { |
| 2438 // Add the values of the locals at the end of the condition block to | 2440 // Add the values of the locals at the end of the condition block to |
| 2439 // the phis. These are the values that flow to the exit if the | 2441 // the phis. These are the values that flow to the exit if the |
| 2440 // condition fails. | 2442 // condition fails. |
| 2441 breakHandlers.add(savedLocals); | 2443 breakHandlers.add(savedLocals); |
| 2442 } | 2444 } |
| 2443 localsHandler = savedLocals.mergeMultiple(breakHandlers, loopExitBlock); | 2445 localsHandler = savedLocals.mergeMultiple(breakHandlers, loopExitBlock); |
| 2444 } else { | 2446 } else { |
| 2445 localsHandler = savedLocals; | 2447 localsHandler = savedLocals; |
| 2446 } | 2448 } |
| 2447 } | 2449 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2487 new SubExpression(initializerBlock, current); | 2489 new SubExpression(initializerBlock, current); |
| 2488 } | 2490 } |
| 2489 | 2491 |
| 2490 loopNesting++; | 2492 loopNesting++; |
| 2491 JumpHandler jumpHandler = beginLoopHeader(loop); | 2493 JumpHandler jumpHandler = beginLoopHeader(loop); |
| 2492 HLoopInformation loopInfo = current.loopInformation; | 2494 HLoopInformation loopInfo = current.loopInformation; |
| 2493 HBasicBlock conditionBlock = current; | 2495 HBasicBlock conditionBlock = current; |
| 2494 if (startBlock == null) startBlock = conditionBlock; | 2496 if (startBlock == null) startBlock = conditionBlock; |
| 2495 | 2497 |
| 2496 HInstruction conditionInstruction = condition(); | 2498 HInstruction conditionInstruction = condition(); |
| 2497 HBasicBlock conditionExitBlock = | 2499 HBasicBlock conditionEndBlock = |
| 2498 close(new HLoopBranch(conditionInstruction)); | 2500 close(new HLoopBranch(conditionInstruction)); |
| 2499 SubExpression conditionExpression = | 2501 SubExpression conditionExpression = |
| 2500 new SubExpression(conditionBlock, conditionExitBlock); | 2502 new SubExpression(conditionBlock, conditionEndBlock); |
| 2501 | 2503 |
| 2502 // Save the values of the local variables at the end of the condition | 2504 // Save the values of the local variables at the end of the condition |
| 2503 // block. These are the values that will flow to the loop exit if the | 2505 // block. These are the values that will flow to the loop exit if the |
| 2504 // condition fails. | 2506 // condition fails. |
| 2505 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); | 2507 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| 2506 | 2508 |
| 2507 // The body. | 2509 // The body. |
| 2508 HBasicBlock beginBodyBlock = addNewBlock(); | 2510 HBasicBlock beginBodyBlock = addNewBlock(); |
| 2509 conditionExitBlock.addSuccessor(beginBodyBlock); | 2511 conditionEndBlock.addSuccessor(beginBodyBlock); |
| 2510 open(beginBodyBlock); | 2512 open(beginBodyBlock); |
| 2511 | 2513 |
| 2512 localsHandler.enterLoopBody(loop); | 2514 localsHandler.enterLoopBody(loop); |
| 2513 body(); | 2515 body(); |
| 2514 | 2516 |
| 2515 SubGraph bodyGraph = new SubGraph(beginBodyBlock, lastOpenedBlock); | 2517 SubGraph bodyGraph = new SubGraph(beginBodyBlock, lastOpenedBlock); |
| 2516 HBasicBlock bodyBlock = current; | 2518 HBasicBlock bodyBlock = current; |
| 2517 if (current != null) close(new HGoto()); | 2519 if (current != null) close(new HGoto()); |
| 2518 | 2520 |
| 2519 SubExpression updateGraph; | 2521 SubExpression updateGraph; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2564 | 2566 |
| 2565 localsHandler.enterLoopUpdates(loop); | 2567 localsHandler.enterLoopUpdates(loop); |
| 2566 | 2568 |
| 2567 update(); | 2569 update(); |
| 2568 | 2570 |
| 2569 HBasicBlock updateEndBlock = close(new HGoto()); | 2571 HBasicBlock updateEndBlock = close(new HGoto()); |
| 2570 // The back-edge completing the cycle. | 2572 // The back-edge completing the cycle. |
| 2571 updateEndBlock.addSuccessor(conditionBlock); | 2573 updateEndBlock.addSuccessor(conditionBlock); |
| 2572 updateGraph = new SubExpression(updateBlock, updateEndBlock); | 2574 updateGraph = new SubExpression(updateBlock, updateEndBlock); |
| 2573 | 2575 |
| 2576 // Avoid a critical edge from the condition to the loop-exit body. | |
|
ngeoffray
2014/06/24 12:39:13
Unconditionally? Isn't it when there can be multip
floitsch
2014/06/24 14:44:38
Yes. We could try to avoid them (and I started thi
| |
| 2577 HBasicBlock conditionExitBlock = addNewBlock(); | |
| 2578 open(conditionExitBlock); | |
| 2579 close(new HGoto()); | |
| 2580 conditionEndBlock.addSuccessor(conditionExitBlock); | |
| 2581 | |
| 2574 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); | 2582 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); |
| 2575 | 2583 |
| 2576 conditionBlock.postProcessLoopHeader(); | 2584 conditionBlock.postProcessLoopHeader(); |
| 2577 HLoopBlockInformation info = | 2585 HLoopBlockInformation info = |
| 2578 new HLoopBlockInformation( | 2586 new HLoopBlockInformation( |
| 2579 HLoopBlockInformation.loopType(loop), | 2587 HLoopBlockInformation.loopType(loop), |
| 2580 wrapExpressionGraph(initializerGraph), | 2588 wrapExpressionGraph(initializerGraph), |
| 2581 wrapExpressionGraph(conditionExpression), | 2589 wrapExpressionGraph(conditionExpression), |
| 2582 wrapStatementGraph(bodyGraph), | 2590 wrapStatementGraph(bodyGraph), |
| 2583 wrapExpressionGraph(updateGraph), | 2591 wrapExpressionGraph(updateGraph), |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 2605 // Pass the elseBlock as the branchBlock, because that's the block we go | 2613 // Pass the elseBlock as the branchBlock, because that's the block we go |
| 2606 // to just before leaving the 'loop'. | 2614 // to just before leaving the 'loop'. |
| 2607 endLoop(conditionBlock, elseBlock, jumpHandler, savedLocals); | 2615 endLoop(conditionBlock, elseBlock, jumpHandler, savedLocals); |
| 2608 | 2616 |
| 2609 SubGraph elseGraph = new SubGraph(elseBlock, elseBlock); | 2617 SubGraph elseGraph = new SubGraph(elseBlock, elseBlock); |
| 2610 // Remove the loop information attached to the header. | 2618 // Remove the loop information attached to the header. |
| 2611 conditionBlock.loopInformation = null; | 2619 conditionBlock.loopInformation = null; |
| 2612 | 2620 |
| 2613 // Remove the [HLoopBranch] instruction and replace it with | 2621 // Remove the [HLoopBranch] instruction and replace it with |
| 2614 // [HIf]. | 2622 // [HIf]. |
| 2615 HInstruction condition = conditionExitBlock.last.inputs[0]; | 2623 HInstruction condition = conditionEndBlock.last.inputs[0]; |
| 2616 conditionExitBlock.addAtExit(new HIf(condition)); | 2624 conditionEndBlock.addAtExit(new HIf(condition)); |
| 2617 conditionExitBlock.addSuccessor(elseBlock); | 2625 conditionEndBlock.addSuccessor(elseBlock); |
| 2618 conditionExitBlock.remove(conditionExitBlock.last); | 2626 conditionEndBlock.remove(conditionEndBlock.last); |
| 2619 HIfBlockInformation info = | 2627 HIfBlockInformation info = |
| 2620 new HIfBlockInformation( | 2628 new HIfBlockInformation( |
| 2621 wrapExpressionGraph(conditionExpression), | 2629 wrapExpressionGraph(conditionExpression), |
| 2622 wrapStatementGraph(bodyGraph), | 2630 wrapStatementGraph(bodyGraph), |
| 2623 wrapStatementGraph(elseGraph)); | 2631 wrapStatementGraph(elseGraph)); |
| 2624 | 2632 |
| 2625 conditionExitBlock.setBlockFlow(info, current); | 2633 conditionEndBlock.setBlockFlow(info, current); |
| 2626 HIf ifBlock = conditionExitBlock.last; | 2634 HIf ifBlock = conditionEndBlock.last; |
| 2627 ifBlock.blockInformation = conditionExitBlock.blockFlow; | 2635 ifBlock.blockInformation = conditionEndBlock.blockFlow; |
| 2628 | 2636 |
| 2629 // If the body has any break, attach a synthesized label to the | 2637 // If the body has any break, attach a synthesized label to the |
| 2630 // if block. | 2638 // if block. |
| 2631 if (jumpHandler.hasAnyBreak()) { | 2639 if (jumpHandler.hasAnyBreak()) { |
| 2632 TargetElement target = elements[loop]; | 2640 TargetElement target = elements[loop]; |
| 2633 LabelElement label = target.addLabel(null, 'loop'); | 2641 LabelElement label = target.addLabel(null, 'loop'); |
| 2634 label.setBreakTarget(); | 2642 label.setBreakTarget(); |
| 2635 SubGraph labelGraph = new SubGraph(conditionBlock, current); | 2643 SubGraph labelGraph = new SubGraph(conditionBlock, current); |
| 2636 HLabeledBlockInformation labelInfo = new HLabeledBlockInformation( | 2644 HLabeledBlockInformation labelInfo = new HLabeledBlockInformation( |
| 2637 new HSubGraphBlockInformation(labelGraph), | 2645 new HSubGraphBlockInformation(labelGraph), |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2777 | 2785 |
| 2778 HBasicBlock avoidCriticalEdge = addNewBlock(); | 2786 HBasicBlock avoidCriticalEdge = addNewBlock(); |
| 2779 conditionEndBlock.addSuccessor(avoidCriticalEdge); | 2787 conditionEndBlock.addSuccessor(avoidCriticalEdge); |
| 2780 open(avoidCriticalEdge); | 2788 open(avoidCriticalEdge); |
| 2781 close(new HGoto()); | 2789 close(new HGoto()); |
| 2782 avoidCriticalEdge.addSuccessor(loopEntryBlock); // The back-edge. | 2790 avoidCriticalEdge.addSuccessor(loopEntryBlock); // The back-edge. |
| 2783 | 2791 |
| 2784 conditionExpression = | 2792 conditionExpression = |
| 2785 new SubExpression(conditionBlock, conditionEndBlock); | 2793 new SubExpression(conditionBlock, conditionEndBlock); |
| 2786 | 2794 |
| 2787 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); | 2795 // Avoid a critical edge from the condition to the loop-exit body. |
|
ngeoffray
2014/06/24 12:39:13
ditto
floitsch
2014/06/24 14:44:38
ditto.
| |
| 2796 HBasicBlock conditionExitBlock = addNewBlock(); | |
| 2797 open(conditionExitBlock); | |
| 2798 close(new HGoto()); | |
| 2799 conditionEndBlock.addSuccessor(conditionExitBlock); | |
| 2800 | |
| 2801 endLoop(loopEntryBlock, conditionExitBlock, jumpHandler, localsHandler); | |
| 2788 | 2802 |
| 2789 loopEntryBlock.postProcessLoopHeader(); | 2803 loopEntryBlock.postProcessLoopHeader(); |
| 2790 SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock); | 2804 SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock); |
| 2791 HLoopBlockInformation loopBlockInfo = | 2805 HLoopBlockInformation loopBlockInfo = |
| 2792 new HLoopBlockInformation( | 2806 new HLoopBlockInformation( |
| 2793 HLoopBlockInformation.DO_WHILE_LOOP, | 2807 HLoopBlockInformation.DO_WHILE_LOOP, |
| 2794 null, | 2808 null, |
| 2795 wrapExpressionGraph(conditionExpression), | 2809 wrapExpressionGraph(conditionExpression), |
| 2796 wrapStatementGraph(bodyGraph), | 2810 wrapStatementGraph(bodyGraph), |
| 2797 null, | 2811 null, |
| (...skipping 3567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6365 DartType unaliased = type.unalias(builder.compiler); | 6379 DartType unaliased = type.unalias(builder.compiler); |
| 6366 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6380 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 6367 unaliased.accept(this, builder); | 6381 unaliased.accept(this, builder); |
| 6368 } | 6382 } |
| 6369 | 6383 |
| 6370 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6384 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 6371 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); | 6385 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); |
| 6372 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); | 6386 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); |
| 6373 } | 6387 } |
| 6374 } | 6388 } |
| OLD | NEW |