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

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

Issue 11299011: Avoid critical edge on do/while, and do not make handleLoopInfo return conditionnaly false: block b… (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/codegen.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (revision 15011)
+++ sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (working copy)
@@ -943,18 +943,29 @@
}
break;
case HLoopBlockInformation.DO_WHILE_LOOP:
- // If there are phi copies after the condition, we cannot emit
- // a pretty do/while loop, se we fallback to the generic
- // emission of a loop.
- CopyHandler handler = variableNames.getCopyHandler(info.end);
- if (handler != null && !handler.isEmpty) return false;
if (info.initializer != null) {
generateStatements(info.initializer);
}
js.Block oldContainer = currentContainer;
js.Statement body = new js.Block.empty();
+ // If there are phi copies in the block that jumps to the
+ // loop entry, we must emit the condition like this:
+ // do {
+ // body;
+ // if (condition) {
+ // phi updates;
+ // continue;
+ // } else {
+ // break;
+ // }
+ // } while (true);
+ HBasicBlock avoidEdge = info.end.successors[0];
+ js.Statement updateBody = new js.Block.empty();
+ currentContainer = updateBody;
+ assignPhisOfSuccessors(avoidEdge);
+ bool hasPhiUpdates = !updateBody.statements.isEmpty;
currentContainer = body;
- if (!isConditionExpression || info.updates != null) {
+ if (hasPhiUpdates || !isConditionExpression || info.updates != null) {
wrapLoopBodyForContinue(info);
} else {
visitBodyIgnoreLabels(info);
@@ -971,9 +982,13 @@
use(condition.conditionExpression);
}
js.Expression jsCondition = pop();
+ if (hasPhiUpdates) {
+ updateBody.statements.add(new js.Continue(null));
+ body.statements.add(
+ new js.If(jsCondition, updateBody, new js.Break(null)));
+ }
+ loop = new js.Do(unwrapStatement(body), jsCondition);
currentContainer = oldContainer;
- body = unwrapStatement(body);
- loop = new js.Do(body, jsCondition);
break;
default:
compiler.internalError(
@@ -1244,16 +1259,7 @@
}
instruction = instruction.next;
}
- if (instruction is HLoopBranch) {
- HLoopBranch branch = instruction;
- // If the loop is a do/while loop, the phi updates must happen
- // after the evaluation of the condition.
- if (!branch.isDoWhile()) {
- assignPhisOfSuccessors(node);
- }
- } else {
- assignPhisOfSuccessors(node);
- }
+ assignPhisOfSuccessors(node);
visit(instruction);
}
@@ -1870,11 +1876,7 @@
HBasicBlock branchBlock = currentBlock;
handleLoopCondition(node);
List<HBasicBlock> dominated = currentBlock.dominatedBlocks;
- if (node.isDoWhile()) {
- // Now that the condition has been evaluated, we can update the
- // phis of a do/while loop.
- assignPhisOfSuccessors(node.block);
- } else {
+ if (!node.isDoWhile()) {
// For a do while loop, the body has already been visited.
visitBasicBlock(dominated[0]);
}
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/builder.dart ('k') | tests/compiler/dart2js_extra/dart2js_extra.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698