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

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

Issue 331343004: Avoid critical edge for loop-exits. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove bad comment. Created 6 years, 6 months 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
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index cdf25f8544806458a08c0095e551b3f6e9c177fa..70f09a6bdad19131db8f522bcebb0387605bf217 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -755,6 +755,12 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
HExpressionInformation condition = info.condition;
bool isConditionExpression = isJSCondition(condition);
+ // Assert that the block we inserted to avoid critical edges satisfies
+ // basic assumptions.
+ assert(!condition.end.successors.last.isEmpty);
+ assert(condition.end.successors.last.first is HGoto);
+ assert(condition.end.successors.last.first.next == null);
ngeoffray 2014/06/24 12:39:14 Should that be in validator.dart instead?
floitsch 2014/06/24 14:44:38 Done.
+
js.Loop loop;
switch (info.kind) {
@@ -772,7 +778,18 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
initialization = null;
}
}
+
+ // We inserted a basic block to avoid critical edges. This block is
+ // part of the LoopBlockInformation and must therefore be handled here.
+ js.Block oldContainer = currentContainer;
+ js.Block avoidContainer = new js.Block.empty();
+ currentContainer = avoidContainer;
+ assignPhisOfSuccessors(condition.end.successors.last);
+ bool hasPhiUpdates = !avoidContainer.statements.isEmpty;
+ currentContainer = oldContainer;
+
if (isConditionExpression &&
+ !hasPhiUpdates &&
info.updates != null && isJSExpression(info.updates)) {
// If we have an updates graph, and it's expressible as an
// expression, generate a for-loop.
@@ -828,7 +845,7 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
// subgraph.
// TODO(lrn): Remove this extra labeling when handling all loops
// using subgraphs.
- js.Block oldContainer = currentContainer;
+ oldContainer = currentContainer;
js.Statement body = new js.Block.empty();
currentContainer = body;
visitBodyIgnoreLabels(info);
@@ -844,7 +861,7 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
js.Expression jsCondition;
js.Block oldContainer = currentContainer;
js.Statement body = new js.Block.empty();
- if (isConditionExpression) {
+ if (isConditionExpression && !hasPhiUpdates) {
jsCondition = generateExpression(condition);
currentContainer = body;
} else {
@@ -853,8 +870,15 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
generateStatements(condition);
use(condition.conditionExpression);
js.Expression ifTest = new js.Prefix("!", pop());
- js.Break jsBreak = new js.Break(null);
- pushStatement(new js.If.noElse(ifTest, jsBreak));
+ js.Statement jsBreak = new js.Break(null);
+ js.Statement exitLoop;
+ if (avoidContainer.statements.isEmpty) {
+ exitLoop = jsBreak;
+ } else {
+ avoidContainer.statements.add(jsBreak);
+ exitLoop = avoidContainer;
+ }
+ pushStatement(new js.If.noElse(ifTest, exitLoop));
}
if (info.updates != null) {
wrapLoopBodyForContinue(info);
@@ -871,7 +895,17 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
if (info.initializer != null) {
generateStatements(info.initializer);
}
+ // We inserted a basic block to avoid critical edges. This block is
+ // part of the LoopBlockInformation and must therefore be handled here.
js.Block oldContainer = currentContainer;
+ js.Block exitAvoidContainer = new js.Block.empty();
+ currentContainer = exitAvoidContainer;
+ assignPhisOfSuccessors(condition.end.successors.last);
+ bool hasExitPhiUpdates = !exitAvoidContainer.statements.isEmpty;
+ currentContainer = oldContainer;
+
+
+ oldContainer = currentContainer;
js.Block 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:
@@ -907,10 +941,18 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
// at the end of the loop anyway.
loop = new js.While(newLiteralBool(true), unwrapStatement(body));
} else {
- if (hasPhiUpdates) {
+ if (hasPhiUpdates || hasExitPhiUpdates) {
updateBody.statements.add(new js.Continue(null));
+ js.Statement jsBreak = new js.Break(null);
+ js.Statement exitLoop;
+ if (exitAvoidContainer.statements.isEmpty) {
+ exitLoop = jsBreak;
+ } else {
+ exitAvoidContainer.statements.add(jsBreak);
+ exitLoop = exitAvoidContainer;
+ }
body.statements.add(
- new js.If(jsCondition, updateBody, new js.Break(null)));
+ new js.If(jsCondition, updateBody, exitLoop));
jsCondition = newLiteralBool(true);
}
loop = new js.Do(unwrapStatement(body), jsCondition);

Powered by Google App Engine
This is Rietveld 408576698