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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/leg/ssa/builder.dart ('k') | frog/leg/ssa/nodes.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class SsaCodeGeneratorTask extends CompilerTask { 5 class SsaCodeGeneratorTask extends CompilerTask {
6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler);
7 String get name() => 'SSA code generator'; 7 String get name() => 'SSA code generator';
8 8
9 String generate(WorkItem work, HGraph graph) { 9 String generate(WorkItem work, HGraph graph) {
10 return measure(() { 10 return measure(() {
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 visit(HInstruction node, int expectedPrecedence) { 240 visit(HInstruction node, int expectedPrecedence) {
241 int oldPrecedence = this.expectedPrecedence; 241 int oldPrecedence = this.expectedPrecedence;
242 this.expectedPrecedence = expectedPrecedence; 242 this.expectedPrecedence = expectedPrecedence;
243 node.accept(this); 243 node.accept(this);
244 this.expectedPrecedence = oldPrecedence; 244 this.expectedPrecedence = oldPrecedence;
245 } 245 }
246 246
247 void handleLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 247 void handleLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
248 addIndentation(); 248 addIndentation();
249 for (LabelElement label in labeledBlockInfo.labels) { 249 for (LabelElement label in labeledBlockInfo.labels) {
250 addLabel(label); 250 if (labeledBlockInfo.isContinue) {
251 addContinueLabel(label);
252 } else {
253 addBreakLabel(label);
254 }
251 buffer.add(':'); 255 buffer.add(':');
252 } 256 }
253 TargetElement target = labeledBlockInfo.target; 257 TargetElement target = labeledBlockInfo.target;
254 if (target.isSwitch) { 258 if (target.isSwitch) {
255 addImplicitLabel(target); 259 addImplicitBreakLabel(target);
256 buffer.add(@':'); 260 buffer.add(@':');
257 } 261 }
262 if (labeledBlockInfo.isContinue) {
263 addImplicitContinueLabel(target);
264 buffer.add(':');
265 }
258 buffer.add('{\n'); 266 buffer.add('{\n');
259 indent++; 267 indent++;
260 268
261 visitSubGraph(labeledBlockInfo.body); 269 visitSubGraph(labeledBlockInfo.body);
262 270
263 indent--; 271 indent--;
264 addIndentation(); 272 addIndentation();
265 buffer.add('}\n'); 273 buffer.add('}\n');
266 274
267 if (labeledBlockInfo.joinBlock !== null) { 275 if (labeledBlockInfo.joinBlock !== null) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 if (dominated.isEmpty()) return; 434 if (dominated.isEmpty()) return;
427 if (dominated.length > 2) unreachable(); 435 if (dominated.length > 2) unreachable();
428 if (dominated.length == 2 && currentBlock !== currentGraph.entry) { 436 if (dominated.length == 2 && currentBlock !== currentGraph.entry) {
429 unreachable(); 437 unreachable();
430 } 438 }
431 assert(dominated[0] == currentBlock.successors[0]); 439 assert(dominated[0] == currentBlock.successors[0]);
432 visitBasicBlock(dominated[0]); 440 visitBasicBlock(dominated[0]);
433 } 441 }
434 442
435 // Used to write the name of labels. 443 // Used to write the name of labels.
436 // The default implementation uses the unmodified Dart label name. 444 void addBreakLabel(LabelElement label) {
437 // Specializations might change this.
438 void addLabel(LabelElement label) {
439 buffer.add(@'$'); 445 buffer.add(@'$');
440 buffer.add(label.labelName); 446 buffer.add(label.labelName);
441 } 447 }
442 448
443 void addImplicitLabel(TargetElement target) { 449 void addContinueLabel(LabelElement label) {
444 buffer.add('\$${target.nestingLevel}'); 450 buffer.add(@'c$');
451 buffer.add(label.labelName);
452 }
453
454 void addImplicitBreakLabel(TargetElement target) {
455 buffer.add(@'$');
456 buffer.add('${target.nestingLevel}');
457 }
458
459 void addImplicitContinueLabel(TargetElement target) {
460 buffer.add(@'c$');
461 buffer.add('${target.nestingLevel}');
445 } 462 }
446 463
447 visitBreak(HBreak node) { 464 visitBreak(HBreak node) {
448 assert(currentBlock.successors.length == 1); 465 assert(currentBlock.successors.length == 1);
449 addIndentation(); 466 addIndentation();
450 buffer.add("break"); 467 buffer.add("break");
451 if (node.label !== null) { 468 if (node.label !== null) {
452 buffer.add(" "); 469 buffer.add(" ");
453 addLabel(node.label); 470 addBreakLabel(node.label);
454 } else { 471 } else {
455 TargetElement target = node.target; 472 TargetElement target = node.target;
456 if (target.isSwitch) { 473 if (target.isSwitch) {
474 // We are wrapping switches in a labeled block so that we can
475 // break from them even when they are implemented as if/else chains.
476 // For that reason, we need to use a labeled break targeting the
477 // "implicit" label we gave to the block.
457 buffer.add(@' '); 478 buffer.add(@' ');
458 addImplicitLabel(target); 479 addImplicitBreakLabel(target);
459 } 480 }
460 } 481 }
461 buffer.add(";\n"); 482 buffer.add(";\n");
462 // We never follow the break to its target, even if it dominates the 483 }
463 // break target block. That block is always handled by the structure 484
464 // that introduced the break. 485 visitContinue(HContinue node) {
486 assert(currentBlock.successors.length == 1);
487 addIndentation();
488 // We currently implement "continue" in a loop as a break of a block
489 // containing the loop body. If we ever implement for-loops as such,
490 // we should use a real continue.
491 buffer.add("break ");
492 if (node.label !== null) {
493 addContinueLabel(node.label);
494 } else {
495 addImplicitContinueLabel(node.target);
496 }
497 buffer.add(";\n");
465 } 498 }
466 499
467 visitTry(HTry node) { 500 visitTry(HTry node) {
468 addIndentation(); 501 addIndentation();
469 buffer.add('try {\n'); 502 buffer.add('try {\n');
470 indent++; 503 indent++;
471 List<HBasicBlock> successors = node.block.successors; 504 List<HBasicBlock> successors = node.block.successors;
472 visitBasicBlock(successors[0]); 505 visitBasicBlock(successors[0]);
473 indent--; 506 indent--;
474 507
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 buffer.add(')) '); 1205 buffer.add(')) ');
1173 bailout(node, 'Not a string or array'); 1206 bailout(node, 'Not a string or array');
1174 } else { 1207 } else {
1175 unreachable(); 1208 unreachable();
1176 } 1209 }
1177 } 1210 }
1178 1211
1179 void beginLoop(HBasicBlock block) { 1212 void beginLoop(HBasicBlock block) {
1180 addIndentation(); 1213 addIndentation();
1181 for (LabelElement label in block.loopInformation.labels) { 1214 for (LabelElement label in block.loopInformation.labels) {
1182 addLabel(label); 1215 addBreakLabel(label);
1183 buffer.add(":"); 1216 buffer.add(":");
1184 } 1217 }
1185 buffer.add('while (true) {\n'); 1218 buffer.add('while (true) {\n');
1186 indent++; 1219 indent++;
1187 } 1220 }
1188 1221
1189 void endLoop(HBasicBlock block) { 1222 void endLoop(HBasicBlock block) {
1190 indent--; 1223 indent--;
1191 addIndentation(); 1224 addIndentation();
1192 buffer.add('}\n'); // Close 'while' loop. 1225 buffer.add('}\n'); // Close 'while' loop.
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 indent++; 1369 indent++;
1337 } 1370 }
1338 1371
1339 void endBailoutSwitch() { 1372 void endBailoutSwitch() {
1340 indent--; // Close 'case'. 1373 indent--; // Close 'case'.
1341 indent--; 1374 indent--;
1342 addIndentation(); 1375 addIndentation();
1343 buffer.add('}\n'); // Close 'switch'. 1376 buffer.add('}\n'); // Close 'switch'.
1344 } 1377 }
1345 1378
1346 // Adds a "$" in front of names of labels from the original source.
1347 // This avoids conflicts with labels introduced by bailouts, which
1348 // starts with a non-"$" character.
1349 void addLabel(LabelElement label) {
1350 buffer.add("\$${label.labelName}");
1351 }
1352 1379
1353 void beginLoop(HBasicBlock block) { 1380 void beginLoop(HBasicBlock block) {
1354 // TODO(ngeoffray): Don't put labels on loops that don't bailout. 1381 // TODO(ngeoffray): Don't put labels on loops that don't bailout.
1355 String newLabel = pushLabel(); 1382 String newLabel = pushLabel();
1356 if (block.hasBailouts()) { 1383 if (block.hasBailouts()) {
1357 startBailoutCase(block.bailouts, const <HBailoutTarget>[]); 1384 startBailoutCase(block.bailouts, const <HBailoutTarget>[]);
1358 } 1385 }
1359 1386
1360 addIndentation(); 1387 addIndentation();
1361 for (LabelElement label in block.loopInformation.labels) { 1388 for (SourceString label in block.loopInformation.labels) {
1362 addLabel(label); 1389 addBreakLabel(label);
1363 buffer.add(":"); 1390 buffer.add(":");
1364 } 1391 }
1365 buffer.add('$newLabel: while (true) {\n'); 1392 buffer.add('$newLabel: while (true) {\n');
1366 indent++; 1393 indent++;
1367 1394
1368 if (block.hasBailouts()) { 1395 if (block.hasBailouts()) {
1369 startBailoutSwitch(); 1396 startBailoutSwitch();
1370 } 1397 }
1371 } 1398 }
1372 1399
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 startBailoutSwitch(); 1471 startBailoutSwitch();
1445 } 1472 }
1446 } 1473 }
1447 1474
1448 void endElse(HIf node) { 1475 void endElse(HIf node) {
1449 if (node.elseBlock.hasBailouts()) { 1476 if (node.elseBlock.hasBailouts()) {
1450 endBailoutSwitch(); 1477 endBailoutSwitch();
1451 } 1478 }
1452 } 1479 }
1453 } 1480 }
OLDNEW
« 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