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

Unified Diff: frog/leg/ssa/codegen.dart

Issue 9718034: Continue for simple loops (while/for). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments. Created 8 years, 9 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
« no previous file with comments | « frog/leg/ssa/builder.dart ('k') | frog/leg/ssa/nodes.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/ssa/codegen.dart
diff --git a/frog/leg/ssa/codegen.dart b/frog/leg/ssa/codegen.dart
index 957f323e3b23d09d2cf2a6b85a1e072f17fd657f..bfbc1a18d3269a5000d7d68373c0ea7d2516e6f2 100644
--- a/frog/leg/ssa/codegen.dart
+++ b/frog/leg/ssa/codegen.dart
@@ -247,14 +247,22 @@ class SsaCodeGenerator implements HVisitor {
void handleLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
addIndentation();
for (LabelElement label in labeledBlockInfo.labels) {
- addLabel(label);
+ if (labeledBlockInfo.isContinue) {
+ addContinueLabel(label);
+ } else {
+ addBreakLabel(label);
+ }
buffer.add(':');
}
TargetElement target = labeledBlockInfo.target;
if (target.isSwitch) {
- addImplicitLabel(target);
+ addImplicitBreakLabel(target);
buffer.add(@':');
}
+ if (labeledBlockInfo.isContinue) {
+ addImplicitContinueLabel(target);
+ buffer.add(':');
+ }
buffer.add('{\n');
indent++;
@@ -433,15 +441,24 @@ class SsaCodeGenerator implements HVisitor {
}
// Used to write the name of labels.
- // The default implementation uses the unmodified Dart label name.
- // Specializations might change this.
- void addLabel(LabelElement label) {
+ void addBreakLabel(LabelElement label) {
buffer.add(@'$');
buffer.add(label.labelName);
}
- void addImplicitLabel(TargetElement target) {
- buffer.add('\$${target.nestingLevel}');
+ void addContinueLabel(LabelElement label) {
+ buffer.add(@'c$');
+ buffer.add(label.labelName);
+ }
+
+ void addImplicitBreakLabel(TargetElement target) {
+ buffer.add(@'$');
+ buffer.add('${target.nestingLevel}');
+ }
+
+ void addImplicitContinueLabel(TargetElement target) {
+ buffer.add(@'c$');
+ buffer.add('${target.nestingLevel}');
}
visitBreak(HBreak node) {
@@ -450,18 +467,34 @@ class SsaCodeGenerator implements HVisitor {
buffer.add("break");
if (node.label !== null) {
buffer.add(" ");
- addLabel(node.label);
+ addBreakLabel(node.label);
} else {
TargetElement target = node.target;
if (target.isSwitch) {
+ // We are wrapping switches in a labeled block so that we can
+ // break from them even when they are implemented as if/else chains.
+ // For that reason, we need to use a labeled break targeting the
+ // "implicit" label we gave to the block.
buffer.add(@' ');
- addImplicitLabel(target);
+ addImplicitBreakLabel(target);
}
}
buffer.add(";\n");
- // We never follow the break to its target, even if it dominates the
- // break target block. That block is always handled by the structure
- // that introduced the break.
+ }
+
+ visitContinue(HContinue node) {
+ assert(currentBlock.successors.length == 1);
+ addIndentation();
+ // We currently implement "continue" in a loop as a break of a block
+ // containing the loop body. If we ever implement for-loops as such,
+ // we should use a real continue.
+ buffer.add("break ");
+ if (node.label !== null) {
+ addContinueLabel(node.label);
+ } else {
+ addImplicitContinueLabel(node.target);
+ }
+ buffer.add(";\n");
}
visitTry(HTry node) {
@@ -1179,7 +1212,7 @@ class SsaOptimizedCodeGenerator extends SsaCodeGenerator {
void beginLoop(HBasicBlock block) {
addIndentation();
for (LabelElement label in block.loopInformation.labels) {
- addLabel(label);
+ addBreakLabel(label);
buffer.add(":");
}
buffer.add('while (true) {\n');
@@ -1343,12 +1376,6 @@ class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator {
buffer.add('}\n'); // Close 'switch'.
}
- // Adds a "$" in front of names of labels from the original source.
- // This avoids conflicts with labels introduced by bailouts, which
- // starts with a non-"$" character.
- void addLabel(LabelElement label) {
- buffer.add("\$${label.labelName}");
- }
void beginLoop(HBasicBlock block) {
// TODO(ngeoffray): Don't put labels on loops that don't bailout.
@@ -1358,8 +1385,8 @@ class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator {
}
addIndentation();
- for (LabelElement label in block.loopInformation.labels) {
- addLabel(label);
+ for (SourceString label in block.loopInformation.labels) {
+ addBreakLabel(label);
buffer.add(":");
}
buffer.add('$newLabel: while (true) {\n');
« no previous file with comments | « frog/leg/ssa/builder.dart ('k') | frog/leg/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698