Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 11414029: At SSA build-time, change the block information that we attach to loop with aborting bodies. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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(),
+ HInstruction condition(),
+ void update(),
+ void body()) {
// Generate:
// <initializer>
// loop-entry:
@@ -1909,23 +1909,82 @@
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 {
+ // // We always create an empty else block to avoid critical edges.
+ // }
+ //
+ // If there is any break in the body, we attach a synthetic
+ // 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 +2113,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, 'loop');
+ 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) {

Powered by Google App Engine
This is Rietveld 408576698