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

Side by Side Diff: lib/compiler/implementation/ssa/codegen.dart

Issue 10446098: Avoid generating empty else. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/variable_allocator.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 final JavaScriptBackend backend; 6 final JavaScriptBackend backend;
7 SsaCodeGeneratorTask(JavaScriptBackend backend) 7 SsaCodeGeneratorTask(JavaScriptBackend backend)
8 : this.backend = backend, 8 : this.backend = backend,
9 super(backend.compiler); 9 super(backend.compiler);
10 String get name() => 'SSA code generator'; 10 String get name() => 'SSA code generator';
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 } 542 }
543 } else { 543 } else {
544 generateStatements(info.condition); 544 generateStatements(info.condition);
545 addIndented("if ("); 545 addIndented("if (");
546 use(condition, JSPrecedence.EXPRESSION_PRECEDENCE); 546 use(condition, JSPrecedence.EXPRESSION_PRECEDENCE);
547 buffer.add(") {\n"); 547 buffer.add(") {\n");
548 indent++; 548 indent++;
549 generateStatements(info.thenGraph); 549 generateStatements(info.thenGraph);
550 indent--; 550 indent--;
551 addIndented("}"); 551 addIndented("}");
552 if (info.elseGraph !== null) { 552 HSubGraphBlockInformation elseGraph = info.elseGraph;
553 if (elseGraph !== null && !isEmptyElse(elseGraph.start, elseGraph.end)) {
553 buffer.add(" else {\n"); 554 buffer.add(" else {\n");
554 indent++; 555 indent++;
555 generateStatements(info.elseGraph); 556 generateStatements(elseGraph);
556 indent--; 557 indent--;
557 addIndented("}"); 558 addIndented("}");
558 } 559 }
559 buffer.add("\n"); 560 buffer.add("\n");
560 } 561 }
561 return true; 562 return true;
562 } 563 }
563 564
564 bool visitSequenceInfo(HStatementSequenceInformation info) { 565 bool visitSequenceInfo(HStatementSequenceInformation info) {
565 return false; 566 return false;
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 } 1245 }
1245 } 1246 }
1246 1247
1247 visitTry(HTry node) { 1248 visitTry(HTry node) {
1248 // We should never get here. Try/catch/finally is always handled using block 1249 // We should never get here. Try/catch/finally is always handled using block
1249 // information in [visitTryInfo], or not at all, in the case of the bailout 1250 // information in [visitTryInfo], or not at all, in the case of the bailout
1250 // generator. 1251 // generator.
1251 compiler.internalError('visitTry should not be called', instruction: node); 1252 compiler.internalError('visitTry should not be called', instruction: node);
1252 } 1253 }
1253 1254
1255 bool isEmptyElse(HBasicBlock start, HBasicBlock end) {
1256 if (start !== end) return false;
1257 if (start.last is !HGoto
1258 || start.last is HBreak
1259 || start.last is HContinue) {
1260 return false;
1261 }
1262 HInstruction instruction = start.first;
1263 for (HInstruction instruction = start.first;
1264 instruction != start.last;
1265 instruction = instruction.next) {
1266 // Instructions generated at use site are okay because they do
1267 // not generate code in this else block.
1268 if (!isGenerateAtUseSite(instruction)) return false;
1269 }
1270 CopyHandler handler = variableNames.getCopyHandler(start);
1271 if (handler == null || handler.isEmpty()) return true;
1272 if (!handler.assignments.isEmpty()) return false;
1273 // If the block has a copy where the destination and source are
1274 // different, we will emit that copy, and therefore the block is
1275 // not empty.
1276 for (Copy copy in handler.copies) {
1277 String sourceName = variableNames.getName(copy.source);
1278 String destinationName = variableNames.getName(copy.destination);
1279 if (sourceName != destinationName) return false;
1280 }
1281 return true;
1282 }
1283
1254 visitIf(HIf node) { 1284 visitIf(HIf node) {
1255 if (subGraph !== null && node.block === subGraph.end) { 1285 if (subGraph !== null && node.block === subGraph.end) {
1256 if (isGeneratingExpression()) { 1286 if (isGeneratingExpression()) {
1257 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); 1287 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE);
1258 } 1288 }
1259 return; 1289 return;
1260 } 1290 }
1261 HInstruction condition = node.inputs[0]; 1291 HInstruction condition = node.inputs[0];
1262 int preVisitedBlocks = 0; 1292 int preVisitedBlocks = 0;
1263 List<HBasicBlock> dominated = node.block.dominatedBlocks; 1293 List<HBasicBlock> dominated = node.block.dominatedBlocks;
1264 HIfBlockInformation info = node.blockInformation.body; 1294 HIfBlockInformation info = node.blockInformation.body;
1295 HBasicBlock joinBlock = node.joinBlock;
1265 if (condition.isConstant()) { 1296 if (condition.isConstant()) {
1266 HConstant constant = condition; 1297 HConstant constant = condition;
1267 if (constant.constant.isTrue()) { 1298 if (constant.constant.isTrue()) {
1268 generateStatements(info.thenGraph); 1299 generateStatements(info.thenGraph);
1269 } else if (node.hasElse) { 1300 } else if (node.hasElse) {
1270 generateStatements(info.elseGraph); 1301 generateStatements(info.elseGraph);
1271 } 1302 }
1272 // We ignore the other branch, even if it isn't visited. 1303 // We ignore the other branch, even if it isn't visited.
1273 preVisitedBlocks = node.hasElse ? 2 : 1; 1304 preVisitedBlocks = node.hasElse ? 2 : 1;
1274 } else { 1305 } else {
1275 startIf(node); 1306 startIf(node);
1276 assert(!isGenerateAtUseSite(node)); 1307 assert(!isGenerateAtUseSite(node));
1277 startThen(node); 1308 startThen(node);
1278 assert(node.thenBlock === dominated[0]); 1309 assert(node.thenBlock === dominated[0]);
1279 generateStatements(info.thenGraph); 1310 generateStatements(info.thenGraph);
1280 preVisitedBlocks++; 1311 preVisitedBlocks++;
1281 endThen(node); 1312 endThen(node);
1282 if (node.hasElse) { 1313 HBasicBlock endBlock =
1314 (joinBlock == null || joinBlock.predecessors.length != 2)
1315 ? null
1316 : joinBlock.predecessors[1];
1317 if (node.hasElse && !isEmptyElse(node.elseBlock, endBlock)) {
1283 startElse(node); 1318 startElse(node);
1284 assert(node.elseBlock === dominated[1]); 1319 assert(node.elseBlock === dominated[1]);
1285 generateStatements(info.elseGraph); 1320 generateStatements(info.elseGraph);
1286 preVisitedBlocks++; 1321 preVisitedBlocks++;
1287 endElse(node); 1322 endElse(node);
1288 } 1323 }
1289 endIf(node); 1324 endIf(node);
1290 } 1325 }
1291 HBasicBlock joinBlock = node.joinBlock;
1292 if (joinBlock !== null && joinBlock.dominator !== node.block) { 1326 if (joinBlock !== null && joinBlock.dominator !== node.block) {
1293 // The join block is dominated by a block in one of the branches. 1327 // The join block is dominated by a block in one of the branches.
1294 // The subgraph traversal never reached it, so we visit it here 1328 // The subgraph traversal never reached it, so we visit it here
1295 // instead. 1329 // instead.
1296 visitBasicBlock(joinBlock); 1330 visitBasicBlock(joinBlock);
1297 } 1331 }
1298 1332
1299 // Visit all the dominated blocks that are not part of the then or else 1333 // Visit all the dominated blocks that are not part of the then or else
1300 // branches, and is not the join block. 1334 // branches, and is not the join block.
1301 // Depending on how the then/else branches terminate 1335 // Depending on how the then/else branches terminate
(...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 startBailoutSwitch(); 2503 startBailoutSwitch();
2470 } 2504 }
2471 } 2505 }
2472 2506
2473 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2507 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2474 if (labeledBlockInfo.body.start.hasGuards()) { 2508 if (labeledBlockInfo.body.start.hasGuards()) {
2475 endBailoutSwitch(); 2509 endBailoutSwitch();
2476 } 2510 }
2477 } 2511 }
2478 } 2512 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/variable_allocator.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698