Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 15009) |
| +++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -1800,11 +1800,11 @@ |
| // For while loops, initializer and update are null. |
| // The condition function must return a boolean result. |
| // None of the functions must leave anything on the stack. |
| - handleLoop(Node loop, |
| - void initialize(), |
| - HInstruction condition(), |
| - void update(), |
| - void body()) { |
| + void handleLoop(Node loop, |
| + void initialize(), |
|
Lasse Reichstein Nielsen
2012/11/16 15:09:11
Is this tabs?
ngeoffray
2012/11/16 16:45:28
No.
|
| + HInstruction condition(), |
| + void update(), |
| + void body()) { |
| // Generate: |
| // <initializer> |
| // loop-entry: |
| @@ -1909,23 +1909,81 @@ |
| updateGraph = new SubExpression(updateBlock, updateEndBlock); |
| } |
| - conditionBlock.postProcessLoopHeader(); |
| + if (jumpHandler.hasAnyContinue() || bodyBlock != null) { |
| + endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); |
| + conditionBlock.postProcessLoopHeader(); |
| + HLoopBlockInformation info = |
| + new HLoopBlockInformation( |
| + HLoopBlockInformation.loopType(loop), |
| + wrapExpressionGraph(initializerGraph), |
| + wrapExpressionGraph(conditionExpression), |
| + wrapStatementGraph(bodyGraph), |
| + wrapExpressionGraph(updateGraph), |
| + conditionBlock.loopInformation.target, |
| + conditionBlock.loopInformation.labels, |
| + sourceFileLocationForBeginToken(loop), |
| + sourceFileLocationForEndToken(loop)); |
| - endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); |
| - HLoopBlockInformation info = |
| - new HLoopBlockInformation( |
| - HLoopBlockInformation.loopType(loop), |
| - wrapExpressionGraph(initializerGraph), |
| + startBlock.setBlockFlow(info, current); |
| + loopInfo.loopBlockInformation = info; |
| + } else { |
| + // There is no back edge for the loop, so we turn the code into: |
| + // if (condition) { |
| + // body; |
| + // } else { |
|
Lasse Reichstein Nielsen
2012/11/16 15:09:11
Explain the empty else block.
ngeoffray
2012/11/16 16:45:28
Done.
|
| + // } |
| + // |
| + // If there is any break in the body, we attach a synthesized |
|
Lasse Reichstein Nielsen
2012/11/16 15:09:11
I prefer "synthetic".
ngeoffray
2012/11/16 16:45:28
Done.
|
| + // label to the if. |
| + HBasicBlock elseBlock = addNewBlock(); |
| + open(elseBlock); |
| + close(new HGoto()); |
| + endLoop(conditionBlock, null, jumpHandler, savedLocals); |
| + |
| + // [endLoop] will not create an exit block if there are no |
| + // breaks. |
| + if (current == null) open(addNewBlock()); |
| + elseBlock.addSuccessor(current); |
| + SubGraph elseGraph = new SubGraph(elseBlock, elseBlock); |
| + // Remove the loop information attached to the header. |
| + conditionBlock.loopInformation = null; |
| + |
| + // Remove the [HLoopBranch] instruction and replace it with |
| + // [HIf]. |
| + HInstruction condition = conditionExitBlock.last.inputs[0]; |
| + conditionExitBlock.addAtExit(new HIf(condition)); |
| + conditionExitBlock.addSuccessor(elseBlock); |
| + conditionExitBlock.remove(conditionExitBlock.last); |
| + HIfBlockInformation info = |
| + new HIfBlockInformation( |
| wrapExpressionGraph(conditionExpression), |
| wrapStatementGraph(bodyGraph), |
| - wrapExpressionGraph(updateGraph), |
| - conditionBlock.loopInformation.target, |
| - conditionBlock.loopInformation.labels, |
| - sourceFileLocationForBeginToken(loop), |
| - sourceFileLocationForEndToken(loop)); |
| + wrapStatementGraph(elseGraph)); |
| - startBlock.setBlockFlow(info, current); |
| - loopInfo.loopBlockInformation = info; |
| + conditionBlock.setBlockFlow(info, current); |
| + conditionBlock.last.blockInformation = conditionBlock.blockFlow; |
| + |
| + // If the body has any break, attach a synthesized label to the |
| + // if block. |
| + if (jumpHandler.hasAnyBreak()) { |
| + TargetElement target = elements[loop]; |
| + LabelElement label = target.addLabel(null, 'loop'); |
| + label.isBreakTarget = true; |
| + SubGraph labelGraph = new SubGraph(conditionBlock, current); |
| + HLabeledBlockInformation labelInfo = new HLabeledBlockInformation( |
| + new HSubGraphBlockInformation(labelGraph), |
| + <LabelElement>[label]); |
| + |
| + conditionBlock.setBlockFlow(labelInfo, current); |
| + |
| + jumpHandler.forEachBreak((HBreak breakInstruction, _) { |
| + HBasicBlock block = breakInstruction.block; |
| + block.addAtExit(new HBreak.toLabel(label)); |
| + block.remove(breakInstruction); |
| + }); |
| + } |
| + } |
| + jumpHandler.close(); |
| } |
| visitFor(For node) { |
| @@ -2054,26 +2112,46 @@ |
| new SubExpression(conditionBlock, conditionEndBlock); |
| } |
| - loopEntryBlock.postProcessLoopHeader(); |
| + endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); |
| + if (!isAbortingBody || hasContinues) { |
| + loopEntryBlock.postProcessLoopHeader(); |
| + SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| + HLoopBlockInformation loopBlockInfo = |
| + new HLoopBlockInformation( |
| + HLoopBlockInformation.DO_WHILE_LOOP, |
| + null, |
| + wrapExpressionGraph(conditionExpression), |
| + wrapStatementGraph(bodyGraph), |
| + null, |
| + loopEntryBlock.loopInformation.target, |
| + loopEntryBlock.loopInformation.labels, |
| + sourceFileLocationForBeginToken(node), |
| + sourceFileLocationForEndToken(node)); |
| + loopEntryBlock.setBlockFlow(loopBlockInfo, current); |
| + loopInfo.loopBlockInformation = loopBlockInfo; |
| + } else { |
| + // If the loop has no back edge, we remove the loop information |
| + // on the header. |
| + loopEntryBlock.loopInformation = null; |
| - endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); |
| + // If the body of the loop has any break, we attach a |
| + // synthesized label to the body. |
| + if (jumpHandler.hasAnyBreak()) { |
| + SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| + TargetElement target = elements[node]; |
| + LabelElement label = target.addLabel(null, 'doWhile'); |
|
Lasse Reichstein Nielsen
2012/11/16 15:09:11
This label is "doWhile" and the other one was "loo
ngeoffray
2012/11/16 16:45:28
Done.
|
| + label.isBreakTarget = true; |
| + HLabeledBlockInformation info = new HLabeledBlockInformation( |
| + new HSubGraphBlockInformation(bodyGraph), <LabelElement>[label]); |
| + loopEntryBlock.setBlockFlow(info, current); |
| + jumpHandler.forEachBreak((HBreak breakInstruction, _) { |
| + HBasicBlock block = breakInstruction.block; |
| + block.addAtExit(new HBreak.toLabel(label)); |
| + block.remove(breakInstruction); |
| + }); |
| + } |
| + } |
| jumpHandler.close(); |
| - |
| - SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| - |
| - HLoopBlockInformation loopBlockInfo = |
| - new HLoopBlockInformation( |
| - HLoopBlockInformation.DO_WHILE_LOOP, |
| - null, |
| - wrapExpressionGraph(conditionExpression), |
| - wrapStatementGraph(bodyGraph), |
| - null, |
| - loopEntryBlock.loopInformation.target, |
| - loopEntryBlock.loopInformation.labels, |
| - sourceFileLocationForBeginToken(node), |
| - sourceFileLocationForEndToken(node)); |
| - loopEntryBlock.setBlockFlow(loopBlockInfo, current); |
| - loopInfo.loopBlockInformation = loopBlockInfo; |
| } |
| visitFunctionExpression(FunctionExpression node) { |