| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |