Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 14539) |
| +++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -665,6 +665,9 @@ |
| } |
| void endLoop(HBasicBlock loopEntry) { |
| + // If the loop has an aborting body, we don't update the loop |
| + // phis. |
| + if (loopEntry.predecessors.length == 1) return; |
| loopEntry.forEachPhi((HPhi phi) { |
| Element element = phi.sourceElement; |
| HInstruction postLoopDefinition = directLocals[element]; |
| @@ -767,6 +770,7 @@ |
| void forEachBreak(void action(HBreak instruction, LocalsHandler locals)); |
| void forEachContinue(void action(HContinue instruction, |
| LocalsHandler locals)); |
| + bool hasAnyContinue(); |
| void close(); |
| final TargetElement target; |
| List<LabelElement> labels(); |
| @@ -791,6 +795,7 @@ |
| void forEachBreak(Function ignored) { } |
| void forEachContinue(Function ignored) { } |
| void close() { } |
| + bool hasAnyContinue() => false; |
| List<LabelElement> labels() => const <LabelElement>[]; |
| TargetElement get target => null; |
| @@ -848,6 +853,13 @@ |
| } |
| } |
| + bool hasAnyContinue() { |
| + for (JumpHandlerEntry entry in jumps) { |
| + if (entry.isContinue()) return true; |
| + } |
| + return false; |
| + } |
| + |
| void close() { |
| // The mapping from TargetElement to JumpHandler is no longer needed. |
| builder.jumpTargets.remove(target); |
| @@ -1793,57 +1805,69 @@ |
| open(beginBodyBlock); |
| localsHandler.enterLoopBody(loop); |
| - hackAroundPossiblyAbortingBody(loop, body); |
| + body(); |
| - SubGraph bodyGraph = new SubGraph(beginBodyBlock, current); |
| - HBasicBlock bodyBlock = close(new HGoto()); |
| + SubGraph bodyGraph = new SubGraph(beginBodyBlock, lastOpenedBlock); |
| + HBasicBlock bodyBlock = current; |
| + if (current != null) close(new HGoto()); |
| - // Update. |
| - // We create an update block, even when we are in a while loop. There the |
| - // update block is the jump-target for continue statements. We could avoid |
| - // the creation if there is no continue, but for now we always create it. |
| - HBasicBlock updateBlock = addNewBlock(); |
| + SubExpression updateGraph; |
| - List<LocalsHandler> continueLocals = <LocalsHandler>[]; |
| - jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { |
| - instruction.block.addSuccessor(updateBlock); |
| - continueLocals.add(locals); |
| - }); |
| - bodyBlock.addSuccessor(updateBlock); |
| - continueLocals.add(localsHandler); |
| + // Check that the loop has at least one back-edge. |
| + if (jumpHandler.hasAnyContinue() || bodyBlock != null) { |
| + // Update. |
| + // We create an update block, even when we are in a while loop. There the |
| + // update block is the jump-target for continue statements. We could avoid |
|
floitsch
2012/11/05 17:36:09
It seems trivial to avoid the creation of the bloc
ngeoffray
2012/11/06 08:55:27
Will do in another CL.
|
| + // the creation if there is no continue, but for now we always create it. |
| + HBasicBlock updateBlock = addNewBlock(); |
| - open(updateBlock); |
| + List<LocalsHandler> continueLocals = <LocalsHandler>[]; |
| + jumpHandler.forEachContinue((HContinue instruction, |
| + LocalsHandler locals) { |
| + instruction.block.addSuccessor(updateBlock); |
| + continueLocals.add(locals); |
| + }); |
| - localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock); |
| - HLabeledBlockInformation labelInfo; |
| - List<LabelElement> labels = jumpHandler.labels(); |
| - TargetElement target = elements[loop]; |
| - if (!labels.isEmpty) { |
| - beginBodyBlock.setBlockFlow( |
| - new HLabeledBlockInformation( |
| - new HSubGraphBlockInformation(bodyGraph), |
| - jumpHandler.labels(), |
| - isContinue: true), |
| - updateBlock); |
| - } else if (target != null && target.isContinueTarget) { |
| - beginBodyBlock.setBlockFlow( |
| - new HLabeledBlockInformation.implicit( |
| - new HSubGraphBlockInformation(bodyGraph), |
| - target, |
| - isContinue: true), |
| - updateBlock); |
| - } |
| + if (bodyBlock != null) { |
| + continueLocals.add(localsHandler); |
| + bodyBlock.addSuccessor(updateBlock); |
| + } |
| - localsHandler.enterLoopUpdates(loop); |
| + open(updateBlock); |
| + localsHandler = |
| + continueLocals[0].mergeMultiple(continueLocals, updateBlock); |
| - update(); |
| + HLabeledBlockInformation labelInfo; |
| + List<LabelElement> labels = jumpHandler.labels(); |
| + TargetElement target = elements[loop]; |
| + if (!labels.isEmpty) { |
| + beginBodyBlock.setBlockFlow( |
| + new HLabeledBlockInformation( |
| + new HSubGraphBlockInformation(bodyGraph), |
| + jumpHandler.labels(), |
| + isContinue: true), |
| + updateBlock); |
| + } else if (target != null && target.isContinueTarget) { |
| + beginBodyBlock.setBlockFlow( |
| + new HLabeledBlockInformation.implicit( |
| + new HSubGraphBlockInformation(bodyGraph), |
| + target, |
| + isContinue: true), |
| + updateBlock); |
| + } |
| - HBasicBlock updateEndBlock = close(new HGoto()); |
| - // The back-edge completing the cycle. |
| - updateEndBlock.addSuccessor(conditionBlock); |
| + localsHandler.enterLoopUpdates(loop); |
| + |
| + update(); |
| + |
| + HBasicBlock updateEndBlock = close(new HGoto()); |
| + // The back-edge completing the cycle. |
| + updateEndBlock.addSuccessor(conditionBlock); |
| + updateGraph = new SubExpression(updateBlock, updateEndBlock); |
| + } |
| + |
| conditionBlock.postProcessLoopHeader(); |
| - SubExpression updateGraph = new SubExpression(updateBlock, updateEndBlock); |
| endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); |
| HLoopBlockInformation info = |