| 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 Interceptors { | 5 class Interceptors { |
| 6 Compiler compiler; | 6 Compiler compiler; |
| 7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
| 8 | 8 |
| 9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
| 10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
| (...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 * Creates a new loop-header block. The previous [current] block | 1162 * Creates a new loop-header block. The previous [current] block |
| 1163 * is closed with an [HGoto] and replaced by the newly created block. | 1163 * is closed with an [HGoto] and replaced by the newly created block. |
| 1164 * Also notifies the locals handler that we're entering a loop. | 1164 * Also notifies the locals handler that we're entering a loop. |
| 1165 */ | 1165 */ |
| 1166 JumpHandler beginLoopHeader(Node node) { | 1166 JumpHandler beginLoopHeader(Node node) { |
| 1167 assert(!isAborted()); | 1167 assert(!isAborted()); |
| 1168 HBasicBlock previousBlock = close(new HGoto()); | 1168 HBasicBlock previousBlock = close(new HGoto()); |
| 1169 | 1169 |
| 1170 JumpHandler jumpHandler = createJumpHandler(node); | 1170 JumpHandler jumpHandler = createJumpHandler(node); |
| 1171 HBasicBlock loopEntry = graph.addNewLoopHeaderBlock( | 1171 HBasicBlock loopEntry = graph.addNewLoopHeaderBlock( |
| 1172 HLoopInformation.loopType(node), | |
| 1173 jumpHandler.target, | 1172 jumpHandler.target, |
| 1174 jumpHandler.labels()); | 1173 jumpHandler.labels()); |
| 1175 previousBlock.addSuccessor(loopEntry); | 1174 previousBlock.addSuccessor(loopEntry); |
| 1176 open(loopEntry); | 1175 open(loopEntry); |
| 1177 | 1176 |
| 1178 localsHandler.beginLoopHeader(node, loopEntry); | 1177 localsHandler.beginLoopHeader(node, loopEntry); |
| 1179 return jumpHandler; | 1178 return jumpHandler; |
| 1180 } | 1179 } |
| 1181 | 1180 |
| 1182 /** | 1181 /** |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1200 open(loopExitBlock); | 1199 open(loopExitBlock); |
| 1201 localsHandler.endLoop(loopEntry); | 1200 localsHandler.endLoop(loopEntry); |
| 1202 if (!breakLocals.isEmpty()) { | 1201 if (!breakLocals.isEmpty()) { |
| 1203 breakLocals.add(savedLocals); | 1202 breakLocals.add(savedLocals); |
| 1204 localsHandler = savedLocals.mergeMultiple(breakLocals, loopExitBlock); | 1203 localsHandler = savedLocals.mergeMultiple(breakLocals, loopExitBlock); |
| 1205 } else { | 1204 } else { |
| 1206 localsHandler = savedLocals; | 1205 localsHandler = savedLocals; |
| 1207 } | 1206 } |
| 1208 } | 1207 } |
| 1209 | 1208 |
| 1209 HSubGraphBlockInformation wrapStatementGraph(SubGraph statements) { |
| 1210 if (statements === null) return null; |
| 1211 return new HSubGraphBlockInformation(statements); |
| 1212 } |
| 1213 |
| 1214 HSubExpressionBlockInformation wrapExpressionGraph(SubExpression expression) { |
| 1215 if (expression === null) return null; |
| 1216 return new HSubExpressionBlockInformation(expression); |
| 1217 } |
| 1218 |
| 1210 // For while loops, initializer and update are null. | 1219 // For while loops, initializer and update are null. |
| 1211 // The condition function must return a boolean result. | 1220 // The condition function must return a boolean result. |
| 1212 // None of the functions must leave anything on the stack. | 1221 // None of the functions must leave anything on the stack. |
| 1213 handleLoop(Node loop, | 1222 handleLoop(Node loop, |
| 1214 void initialize(), | 1223 void initialize(), |
| 1215 HInstruction condition(), | 1224 HInstruction condition(), |
| 1216 void update(), | 1225 void update(), |
| 1217 void body()) { | 1226 void body()) { |
| 1218 // Generate: | 1227 // Generate: |
| 1219 // <initializer> | 1228 // <initializer> |
| 1220 // loop-entry: | 1229 // loop-entry: |
| 1221 // if (!<condition>) goto loop-exit; | 1230 // if (!<condition>) goto loop-exit; |
| 1222 // <body> | 1231 // <body> |
| 1223 // <updates> | 1232 // <updates> |
| 1224 // goto loop-entry; | 1233 // goto loop-entry; |
| 1225 // loop-exit: | 1234 // loop-exit: |
| 1226 | 1235 |
| 1227 localsHandler.startLoop(loop); | 1236 localsHandler.startLoop(loop); |
| 1228 | 1237 |
| 1229 // The initializer. | 1238 // The initializer. |
| 1230 HBasicBlock initializerBlock = openNewBlock(); | 1239 SubExpression initializerGraph = null; |
| 1231 initialize(); | 1240 HBasicBlock startBlock; |
| 1232 assert(!isAborted()); | 1241 if (initialize !== null) { |
| 1233 SubExpression initializerGraph = | 1242 HBasicBlock initializerBlock = openNewBlock(); |
| 1234 new SubExpression(initializerBlock, current); | 1243 startBlock = initializerBlock; |
| 1244 initialize(); |
| 1245 assert(!isAborted()); |
| 1246 initializerGraph = |
| 1247 new SubExpression(initializerBlock, current); |
| 1248 } |
| 1235 | 1249 |
| 1236 JumpHandler jumpHandler = beginLoopHeader(loop); | 1250 JumpHandler jumpHandler = beginLoopHeader(loop); |
| 1251 HLoopInformation loopInfo = current.loopInformation; |
| 1237 HBasicBlock conditionBlock = current; | 1252 HBasicBlock conditionBlock = current; |
| 1238 HLoopInformation loopInfo = current.blockInformation; | 1253 if (startBlock === null) startBlock = conditionBlock; |
| 1239 // The initializer graph is currently unused due to the way we | |
| 1240 // generate code. | |
| 1241 loopInfo.initializer = new HSubExpressionBlockInformation(initializerGraph); | |
| 1242 | 1254 |
| 1243 HInstruction conditionInstruction = condition(); | 1255 HInstruction conditionInstruction = condition(); |
| 1244 HBasicBlock conditionExitBlock = | 1256 HBasicBlock conditionExitBlock = |
| 1245 close(new HLoopBranch(conditionInstruction)); | 1257 close(new HLoopBranch(conditionInstruction)); |
| 1246 SubExpression conditionExpression = | 1258 SubExpression conditionExpression = |
| 1247 new SubExpression(conditionBlock, conditionExitBlock); | 1259 new SubExpression(conditionBlock, conditionExitBlock); |
| 1248 loopInfo.condition = | |
| 1249 new HSubExpressionBlockInformation(conditionExpression); | |
| 1250 | 1260 |
| 1251 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); | 1261 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| 1252 | 1262 |
| 1253 // The body. | 1263 // The body. |
| 1254 HBasicBlock beginBodyBlock = addNewBlock(); | 1264 HBasicBlock beginBodyBlock = addNewBlock(); |
| 1255 conditionExitBlock.addSuccessor(beginBodyBlock); | 1265 conditionExitBlock.addSuccessor(beginBodyBlock); |
| 1256 open(beginBodyBlock); | 1266 open(beginBodyBlock); |
| 1257 | 1267 |
| 1258 localsHandler.enterLoopBody(loop); | 1268 localsHandler.enterLoopBody(loop); |
| 1259 hackAroundPossiblyAbortingBody(loop, body); | 1269 hackAroundPossiblyAbortingBody(loop, body); |
| 1260 | 1270 |
| 1261 SubGraph bodyGraph = new SubGraph(beginBodyBlock, current); | 1271 SubGraph bodyGraph = new SubGraph(beginBodyBlock, current); |
| 1262 HBasicBlock bodyBlock = close(new HGoto()); | 1272 HBasicBlock bodyBlock = close(new HGoto()); |
| 1263 loopInfo.body = new HSubGraphBlockInformation(bodyGraph); | |
| 1264 | 1273 |
| 1265 // Update. | 1274 // Update. |
| 1266 // We create an update block, even when we are in a while loop. There the | 1275 // We create an update block, even when we are in a while loop. There the |
| 1267 // update block is the jump-target for continue statements. We could avoid | 1276 // update block is the jump-target for continue statements. We could avoid |
| 1268 // the creation if there is no continue, but for now we always create it. | 1277 // the creation if there is no continue, but for now we always create it. |
| 1269 HBasicBlock updateBlock = addNewBlock(); | 1278 HBasicBlock updateBlock = addNewBlock(); |
| 1270 | 1279 |
| 1271 List<LocalsHandler> continueLocals = <LocalsHandler>[]; | 1280 List<LocalsHandler> continueLocals = <LocalsHandler>[]; |
| 1272 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { | 1281 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { |
| 1273 instruction.block.addSuccessor(updateBlock); | 1282 instruction.block.addSuccessor(updateBlock); |
| 1274 continueLocals.add(locals); | 1283 continueLocals.add(locals); |
| 1275 }); | 1284 }); |
| 1276 bodyBlock.addSuccessor(updateBlock); | 1285 bodyBlock.addSuccessor(updateBlock); |
| 1277 continueLocals.add(localsHandler); | 1286 continueLocals.add(localsHandler); |
| 1278 | 1287 |
| 1279 open(updateBlock); | 1288 open(updateBlock); |
| 1280 | 1289 |
| 1281 localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock); | 1290 localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock); |
| 1282 | 1291 |
| 1283 HLabeledBlockInformation labelInfo; | 1292 HLabeledBlockInformation labelInfo; |
| 1284 List<LabelElement> labels = jumpHandler.labels(); | 1293 List<LabelElement> labels = jumpHandler.labels(); |
| 1285 TargetElement target = elements[loop]; | 1294 TargetElement target = elements[loop]; |
| 1286 if (!labels.isEmpty()) { | 1295 if (!labels.isEmpty()) { |
| 1287 beginBodyBlock.blockInformation = new HLabeledBlockInformation( | 1296 beginBodyBlock.setBlockFlow( |
| 1288 new HSubGraphBlockInformation(bodyGraph), | 1297 new HLabeledBlockInformation( |
| 1289 updateBlock, | 1298 new HSubGraphBlockInformation(bodyGraph), |
| 1290 jumpHandler.labels(), | 1299 jumpHandler.labels(), |
| 1291 isContinue: true); | 1300 isContinue: true), |
| 1301 updateBlock); |
| 1292 } else if (target !== null && target.isContinueTarget) { | 1302 } else if (target !== null && target.isContinueTarget) { |
| 1293 beginBodyBlock.blockInformation = new HLabeledBlockInformation.implicit( | 1303 beginBodyBlock.setBlockFlow( |
| 1294 new HSubGraphBlockInformation(bodyGraph), | 1304 new HLabeledBlockInformation.implicit( |
| 1295 updateBlock, | 1305 new HSubGraphBlockInformation(bodyGraph), |
| 1296 target, | 1306 target, |
| 1297 isContinue: true); | 1307 isContinue: true), |
| 1308 updateBlock); |
| 1298 } | 1309 } |
| 1299 | 1310 |
| 1300 localsHandler.enterLoopUpdates(loop); | 1311 localsHandler.enterLoopUpdates(loop); |
| 1301 | 1312 |
| 1302 update(); | 1313 update(); |
| 1303 | 1314 |
| 1304 HBasicBlock updateEndBlock = close(new HGoto()); | 1315 HBasicBlock updateEndBlock = close(new HGoto()); |
| 1305 // The back-edge completing the cycle. | 1316 // The back-edge completing the cycle. |
| 1306 updateEndBlock.addSuccessor(conditionBlock); | 1317 updateEndBlock.addSuccessor(conditionBlock); |
| 1307 conditionBlock.postProcessLoopHeader(); | 1318 conditionBlock.postProcessLoopHeader(); |
| 1308 SubExpression updateGraph = new SubExpression(updateBlock, updateEndBlock); | 1319 SubExpression updateGraph = new SubExpression(updateBlock, updateEndBlock); |
| 1309 loopInfo.updates = new HSubExpressionBlockInformation(updateGraph); | |
| 1310 | 1320 |
| 1311 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); | 1321 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); |
| 1312 loopInfo.joinBlock = current; | 1322 HLoopBlockInformation info = |
| 1313 initializerBlock.blockInformation = loopInfo; | 1323 new HLoopBlockInformation( |
| 1324 HLoopBlockInformation.loopType(loop), |
| 1325 wrapExpressionGraph(initializerGraph), |
| 1326 wrapExpressionGraph(conditionExpression), |
| 1327 wrapStatementGraph(bodyGraph), |
| 1328 wrapExpressionGraph(updateGraph), |
| 1329 conditionBlock.loopInformation.target, |
| 1330 conditionBlock.loopInformation.labels); |
| 1331 |
| 1332 startBlock.setBlockFlow(info, current); |
| 1333 loopInfo.loopBlockInformation = info; |
| 1314 } | 1334 } |
| 1315 | 1335 |
| 1316 visitFor(For node) { | 1336 visitFor(For node) { |
| 1317 assert(node.body !== null); | 1337 assert(node.body !== null); |
| 1318 void buildInitializer() { | 1338 void buildInitializer() { |
| 1319 if (node.initializer === null) return; | 1339 if (node.initializer === null) return; |
| 1320 Node initializer = node.initializer; | 1340 Node initializer = node.initializer; |
| 1321 if (initializer !== null) { | 1341 if (initializer !== null) { |
| 1322 visit(initializer); | 1342 visit(initializer); |
| 1323 if (initializer.asExpression() !== null) { | 1343 if (initializer.asExpression() !== null) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1356 () {}, | 1376 () {}, |
| 1357 buildCondition, | 1377 buildCondition, |
| 1358 () {}, | 1378 () {}, |
| 1359 () { visit(node.body); }); | 1379 () { visit(node.body); }); |
| 1360 } | 1380 } |
| 1361 | 1381 |
| 1362 visitDoWhile(DoWhile node) { | 1382 visitDoWhile(DoWhile node) { |
| 1363 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); | 1383 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| 1364 localsHandler.startLoop(node); | 1384 localsHandler.startLoop(node); |
| 1365 JumpHandler jumpHandler = beginLoopHeader(node); | 1385 JumpHandler jumpHandler = beginLoopHeader(node); |
| 1366 HLoopInformation loopInfo = current.blockInformation; | 1386 HLoopInformation loopInfo = current.loopInformation; |
| 1367 HBasicBlock loopEntryBlock = current; | 1387 HBasicBlock loopEntryBlock = current; |
| 1368 HBasicBlock bodyEntryBlock = current; | 1388 HBasicBlock bodyEntryBlock = current; |
| 1369 TargetElement target = elements[node]; | 1389 TargetElement target = elements[node]; |
| 1370 bool hasContinues = target !== null && target.isContinueTarget; | 1390 bool hasContinues = target !== null && target.isContinueTarget; |
| 1371 if (hasContinues) { | 1391 if (hasContinues) { |
| 1372 // Add extra block to hang labels on. | 1392 // Add extra block to hang labels on. |
| 1373 // It doesn't currently work if they are on the same block as the | 1393 // It doesn't currently work if they are on the same block as the |
| 1374 // HLoopInfo. The handling of HLabeledBlockInformation will visit a | 1394 // HLoopInfo. The handling of HLabeledBlockInformation will visit a |
| 1375 // SubGraph that starts at the same block again, so the HLoopInfo is | 1395 // SubGraph that starts at the same block again, so the HLoopInfo is |
| 1376 // either handled twice, or it's handled after the labeled block info, | 1396 // either handled twice, or it's handled after the labeled block info, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1390 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { | 1410 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { |
| 1391 instruction.block.addSuccessor(conditionBlock); | 1411 instruction.block.addSuccessor(conditionBlock); |
| 1392 continueLocals.add(locals); | 1412 continueLocals.add(locals); |
| 1393 }); | 1413 }); |
| 1394 bodyExitBlock.addSuccessor(conditionBlock); | 1414 bodyExitBlock.addSuccessor(conditionBlock); |
| 1395 if (!continueLocals.isEmpty()) { | 1415 if (!continueLocals.isEmpty()) { |
| 1396 continueLocals.add(localsHandler); | 1416 continueLocals.add(localsHandler); |
| 1397 localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock); | 1417 localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock); |
| 1398 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); | 1418 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| 1399 List<LabelElement> labels = jumpHandler.labels(); | 1419 List<LabelElement> labels = jumpHandler.labels(); |
| 1420 HSubGraphBlockInformation bodyInfo = |
| 1421 new HSubGraphBlockInformation(bodyGraph); |
| 1422 HLabeledBlockInformation info; |
| 1400 if (!labels.isEmpty()) { | 1423 if (!labels.isEmpty()) { |
| 1401 bodyEntryBlock.blockInformation = new HLabeledBlockInformation( | 1424 info = new HLabeledBlockInformation(bodyInfo, labels, isContinue: true); |
| 1402 new HSubGraphBlockInformation(bodyGraph), | |
| 1403 conditionBlock, | |
| 1404 labels, | |
| 1405 isContinue: true); | |
| 1406 } else { | 1425 } else { |
| 1407 bodyEntryBlock.blockInformation = new HLabeledBlockInformation.implicit( | 1426 info = new HLabeledBlockInformation.implicit(bodyInfo, target, |
| 1408 new HSubGraphBlockInformation(bodyGraph), | 1427 isContinue: true); |
| 1409 conditionBlock, | |
| 1410 target, | |
| 1411 isContinue: true); | |
| 1412 } | 1428 } |
| 1429 bodyEntryBlock.setBlockFlow(info, conditionBlock); |
| 1413 } | 1430 } |
| 1414 open(conditionBlock); | 1431 open(conditionBlock); |
| 1415 | 1432 |
| 1416 visit(node.condition); | 1433 visit(node.condition); |
| 1417 assert(!isAborted()); | 1434 assert(!isAborted()); |
| 1418 HInstruction conditionInstruction = popBoolified(); | 1435 HInstruction conditionInstruction = popBoolified(); |
| 1419 HBasicBlock conditionEndBlock = | 1436 HBasicBlock conditionEndBlock = |
| 1420 close(new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP)); | 1437 close(new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP)); |
| 1421 | 1438 |
| 1422 conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge. | 1439 conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge. |
| 1423 loopEntryBlock.postProcessLoopHeader(); | 1440 loopEntryBlock.postProcessLoopHeader(); |
| 1424 | 1441 |
| 1425 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); | 1442 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); |
| 1426 jumpHandler.close(); | 1443 jumpHandler.close(); |
| 1427 | 1444 |
| 1428 loopInfo.body = new HSubGraphBlockInformation( | 1445 SubExpression conditionExpression = |
| 1429 new SubGraph(bodyEntryBlock, bodyExitBlock)); | 1446 new SubExpression(conditionBlock, conditionEndBlock); |
| 1430 loopInfo.condition = new HSubExpressionBlockInformation( | 1447 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| 1431 new SubExpression(conditionBlock, conditionEndBlock)); | 1448 |
| 1432 loopInfo.joinBlock = current; | 1449 HLoopBlockInformation loopBlockInfo = |
| 1450 new HLoopBlockInformation( |
| 1451 HLoopBlockInformation.DO_WHILE_LOOP, |
| 1452 null, |
| 1453 wrapExpressionGraph(conditionExpression), |
| 1454 wrapStatementGraph(bodyGraph), |
| 1455 null, |
| 1456 loopEntryBlock.loopInformation.target, |
| 1457 loopEntryBlock.loopInformation.labels); |
| 1458 loopEntryBlock.setBlockFlow(loopBlockInfo, current); |
| 1459 loopInfo.loopBlockInformation = loopBlockInfo; |
| 1433 } | 1460 } |
| 1434 | 1461 |
| 1435 visitFunctionExpression(FunctionExpression node) { | 1462 visitFunctionExpression(FunctionExpression node) { |
| 1436 ClosureData nestedClosureData = compiler.builder.closureDataCache[node]; | 1463 ClosureData nestedClosureData = compiler.builder.closureDataCache[node]; |
| 1437 if (nestedClosureData === null) { | 1464 if (nestedClosureData === null) { |
| 1438 // TODO(floitsch): we can only assume that the reason for not having a | 1465 // TODO(floitsch): we can only assume that the reason for not having a |
| 1439 // closure data here is, because the function is inside an initializer. | 1466 // closure data here is, because the function is inside an initializer. |
| 1440 compiler.unimplemented("Closures inside initializers", node: node); | 1467 compiler.unimplemented("Closures inside initializers", node: node); |
| 1441 } | 1468 } |
| 1442 assert(nestedClosureData !== null); | 1469 assert(nestedClosureData !== null); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1531 // with the set of locals we got after visiting the then | 1558 // with the set of locals we got after visiting the then |
| 1532 // part of the if. | 1559 // part of the if. |
| 1533 open(joinBlock); | 1560 open(joinBlock); |
| 1534 if (joinBlock.predecessors.length == 2) { | 1561 if (joinBlock.predecessors.length == 2) { |
| 1535 localsHandler.mergeWith(thenLocals, joinBlock); | 1562 localsHandler.mergeWith(thenLocals, joinBlock); |
| 1536 } else if (thenBlock !== null) { | 1563 } else if (thenBlock !== null) { |
| 1537 // The only predecessor is the then branch. | 1564 // The only predecessor is the then branch. |
| 1538 localsHandler = thenLocals; | 1565 localsHandler = thenLocals; |
| 1539 } | 1566 } |
| 1540 } | 1567 } |
| 1541 HIfBlockInformation info = new HIfBlockInformation( | 1568 HIfBlockInformation info = |
| 1542 new HSubExpressionBlockInformation(conditionGraph), | 1569 new HIfBlockInformation( |
| 1543 new HSubGraphBlockInformation(thenGraph), | 1570 new HSubExpressionBlockInformation(conditionGraph), |
| 1544 (elseGraph === null) ? null : new HSubGraphBlockInformation(elseGraph), | 1571 new HSubGraphBlockInformation(thenGraph), |
| 1545 joinBlock); | 1572 wrapStatementGraph(elseGraph)); |
| 1546 conditionStartBlock.blockInformation = info; | 1573 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 1547 branch.blockInformation = info; | 1574 branch.blockInformation = conditionStartBlock.blockFlow; |
| 1548 } | 1575 } |
| 1549 | 1576 |
| 1550 void visitLogicalAndOr(Send node, Operator op) { | 1577 void visitLogicalAndOr(Send node, Operator op) { |
| 1551 handleLogicalAndOr(() { visit(node.receiver); }, | 1578 handleLogicalAndOr(() { visit(node.receiver); }, |
| 1552 () { visit(node.argumentsNode); }, | 1579 () { visit(node.argumentsNode); }, |
| 1553 isAnd: (const SourceString("&&") == op.source)); | 1580 isAnd: (const SourceString("&&") == op.source)); |
| 1554 } | 1581 } |
| 1555 | 1582 |
| 1556 | 1583 |
| 1557 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) { | 1584 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1588 HInstruction boolifiedRight = popBoolified(); | 1615 HInstruction boolifiedRight = popBoolified(); |
| 1589 SubExpression rightGraph = | 1616 SubExpression rightGraph = |
| 1590 new SubExpression(rightBlock, current); | 1617 new SubExpression(rightBlock, current); |
| 1591 rightBlock = close(new HGoto()); | 1618 rightBlock = close(new HGoto()); |
| 1592 | 1619 |
| 1593 HBasicBlock joinBlock = addNewBlock(); | 1620 HBasicBlock joinBlock = addNewBlock(); |
| 1594 leftBlock.addSuccessor(joinBlock); | 1621 leftBlock.addSuccessor(joinBlock); |
| 1595 rightBlock.addSuccessor(joinBlock); | 1622 rightBlock.addSuccessor(joinBlock); |
| 1596 open(joinBlock); | 1623 open(joinBlock); |
| 1597 | 1624 |
| 1598 leftGraph.start.blockInformation = new HAndOrBlockInformation( | 1625 leftGraph.start.setBlockFlow( |
| 1599 isAnd, | 1626 new HAndOrBlockInformation( |
| 1600 new HSubExpressionBlockInformation(leftGraph), | 1627 isAnd, |
| 1601 new HSubExpressionBlockInformation(rightGraph), | 1628 new HSubExpressionBlockInformation(leftGraph), |
| 1629 new HSubExpressionBlockInformation(rightGraph)), |
| 1602 joinBlock); | 1630 joinBlock); |
| 1603 // Fallback until we handle and-or-information better. | 1631 // Fallback until we handle and-or-information better. |
| 1604 branch.blockInformation = new HIfBlockInformation( | 1632 branch.blockInformation = new HBlockFlow( |
| 1605 new HSubExpressionBlockInformation(leftGraph), | 1633 new HIfBlockInformation( |
| 1606 new HSubGraphBlockInformation(rightGraph), | 1634 new HSubExpressionBlockInformation(leftGraph), |
| 1607 null, | 1635 new HSubGraphBlockInformation(rightGraph), |
| 1608 joinBlock | 1636 null |
| 1609 ); | 1637 ), joinBlock); |
| 1610 | 1638 |
| 1611 localsHandler.mergeWith(savedLocals, joinBlock); | 1639 localsHandler.mergeWith(savedLocals, joinBlock); |
| 1612 HPhi result = new HPhi.manyInputs(null, | 1640 HPhi result = new HPhi.manyInputs(null, |
| 1613 <HInstruction>[boolifiedLeft, boolifiedRight]); | 1641 <HInstruction>[boolifiedLeft, boolifiedRight]); |
| 1614 joinBlock.addPhi(result); | 1642 joinBlock.addPhi(result); |
| 1615 stack.add(result); | 1643 stack.add(result); |
| 1616 } | 1644 } |
| 1617 | 1645 |
| 1618 void visitLogicalNot(Send node) { | 1646 void visitLogicalNot(Send node) { |
| 1619 assert(node.argumentsNode is Prefix); | 1647 assert(node.argumentsNode is Prefix); |
| (...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2650 visit(node.elseExpression); | 2678 visit(node.elseExpression); |
| 2651 HInstruction elseInstruction = pop(); | 2679 HInstruction elseInstruction = pop(); |
| 2652 SubGraph elseGraph = new SubGraph(elseBlock, current); | 2680 SubGraph elseGraph = new SubGraph(elseBlock, current); |
| 2653 elseBlock = close(new HGoto()); | 2681 elseBlock = close(new HGoto()); |
| 2654 | 2682 |
| 2655 HBasicBlock joinBlock = addNewBlock(); | 2683 HBasicBlock joinBlock = addNewBlock(); |
| 2656 thenBlock.addSuccessor(joinBlock); | 2684 thenBlock.addSuccessor(joinBlock); |
| 2657 elseBlock.addSuccessor(joinBlock); | 2685 elseBlock.addSuccessor(joinBlock); |
| 2658 | 2686 |
| 2659 // TODO(lrn): Handle expressions better. | 2687 // TODO(lrn): Handle expressions better. |
| 2660 condition.blockInformation = new HIfBlockInformation( | 2688 condition.blockInformation = new HBlockFlow( |
| 2661 new HSubExpressionBlockInformation(conditionGraph), | 2689 new HIfBlockInformation( |
| 2662 new HSubGraphBlockInformation(thenGraph), | 2690 new HSubExpressionBlockInformation(conditionGraph), |
| 2663 new HSubGraphBlockInformation(elseGraph), | 2691 new HSubGraphBlockInformation(thenGraph), |
| 2692 new HSubGraphBlockInformation(elseGraph)), |
| 2664 joinBlock); | 2693 joinBlock); |
| 2665 open(joinBlock); | 2694 open(joinBlock); |
| 2666 | 2695 |
| 2667 localsHandler.mergeWith(thenLocals, joinBlock); | 2696 localsHandler.mergeWith(thenLocals, joinBlock); |
| 2668 HPhi phi = new HPhi.manyInputs(null, | 2697 HPhi phi = new HPhi.manyInputs(null, |
| 2669 <HInstruction>[thenInstruction, elseInstruction]); | 2698 <HInstruction>[thenInstruction, elseInstruction]); |
| 2670 joinBlock.addPhi(phi); | 2699 joinBlock.addPhi(phi); |
| 2671 stack.add(phi); | 2700 stack.add(phi); |
| 2672 } | 2701 } |
| 2673 | 2702 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2815 bool hasBreak = breakLocals.length > 0; | 2844 bool hasBreak = breakLocals.length > 0; |
| 2816 if (!isAborted()) { | 2845 if (!isAborted()) { |
| 2817 goto(current, joinBlock); | 2846 goto(current, joinBlock); |
| 2818 breakLocals.add(localsHandler); | 2847 breakLocals.add(localsHandler); |
| 2819 } | 2848 } |
| 2820 open(joinBlock); | 2849 open(joinBlock); |
| 2821 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock); | 2850 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock); |
| 2822 | 2851 |
| 2823 if (hasBreak) { | 2852 if (hasBreak) { |
| 2824 // There was at least one reachable break, so the label is needed. | 2853 // There was at least one reachable break, so the label is needed. |
| 2825 entryBlock.blockInformation = | 2854 entryBlock.setBlockFlow( |
| 2826 new HLabeledBlockInformation(new HSubGraphBlockInformation(bodyGraph), | 2855 new HLabeledBlockInformation(new HSubGraphBlockInformation(bodyGraph), |
| 2827 joinBlock, handler.labels()); | 2856 handler.labels()), |
| 2857 joinBlock); |
| 2828 } | 2858 } |
| 2829 handler.close(); | 2859 handler.close(); |
| 2830 } | 2860 } |
| 2831 | 2861 |
| 2832 visitLiteralMap(LiteralMap node) { | 2862 visitLiteralMap(LiteralMap node) { |
| 2833 if (node.isConst()) { | 2863 if (node.isConst()) { |
| 2834 ConstantHandler handler = compiler.constantHandler; | 2864 ConstantHandler handler = compiler.constantHandler; |
| 2835 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 2865 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 2836 stack.add(graph.addConstant(constant)); | 2866 stack.add(graph.addConstant(constant)); |
| 2837 return; | 2867 return; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2897 open(joinBlock); | 2927 open(joinBlock); |
| 2898 if (caseLocals.length == 1) { | 2928 if (caseLocals.length == 1) { |
| 2899 localsHandler = caseLocals[0]; | 2929 localsHandler = caseLocals[0]; |
| 2900 } else { | 2930 } else { |
| 2901 localsHandler = savedLocals.mergeMultiple(caseLocals, joinBlock); | 2931 localsHandler = savedLocals.mergeMultiple(caseLocals, joinBlock); |
| 2902 } | 2932 } |
| 2903 } else { | 2933 } else { |
| 2904 // The joinblock is not used. | 2934 // The joinblock is not used. |
| 2905 joinBlock = null; | 2935 joinBlock = null; |
| 2906 } | 2936 } |
| 2907 startBlock.blockInformation = new HLabeledBlockInformation.implicit( | 2937 startBlock.setBlockFlow( |
| 2908 new HSubGraphBlockInformation(new SubGraph(startBlock, lastBlock)), | 2938 new HLabeledBlockInformation.implicit( |
| 2909 joinBlock, | 2939 new HSubGraphBlockInformation(new SubGraph(startBlock, lastBlock)), |
| 2910 elements[node]); | 2940 elements[node]), |
| 2941 joinBlock); |
| 2911 jumpHandler.close(); | 2942 jumpHandler.close(); |
| 2912 } | 2943 } |
| 2913 | 2944 |
| 2914 | 2945 |
| 2915 // Recursively build an if/else structure to match the cases. | 2946 // Recursively build an if/else structure to match the cases. |
| 2916 buildSwitchCases(Link<Node> cases, HInstruction expression) { | 2947 buildSwitchCases(Link<Node> cases, HInstruction expression) { |
| 2917 SwitchCase node = cases.head; | 2948 SwitchCase node = cases.head; |
| 2918 | 2949 |
| 2919 // Called for the statements on all but the last case block. | 2950 // Called for the statements on all but the last case block. |
| 2920 // Ensures that a user expecting a fallthrough gets an error. | 2951 // Ensures that a user expecting a fallthrough gets an error. |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3087 finallyGraph = new SubGraph(finallyBlock, lastOpenedBlock); | 3118 finallyGraph = new SubGraph(finallyBlock, lastOpenedBlock); |
| 3088 } | 3119 } |
| 3089 | 3120 |
| 3090 HBasicBlock exitBlock = graph.addNewBlock(); | 3121 HBasicBlock exitBlock = graph.addNewBlock(); |
| 3091 | 3122 |
| 3092 for (HBasicBlock block in blocks) { | 3123 for (HBasicBlock block in blocks) { |
| 3093 block.addSuccessor(exitBlock); | 3124 block.addSuccessor(exitBlock); |
| 3094 } | 3125 } |
| 3095 | 3126 |
| 3096 open(exitBlock); | 3127 open(exitBlock); |
| 3097 enterBlock.blockInformation = new HTryBlockInformation( | 3128 enterBlock.setBlockFlow( |
| 3098 new HSubGraphBlockInformation(bodyGraph), | 3129 new HTryBlockInformation( |
| 3099 exception, | 3130 wrapStatementGraph(bodyGraph), |
| 3100 catchGraph == null ? null : new HSubGraphBlockInformation(catchGraph), | 3131 exception, |
| 3101 finallyGraph == null ? null : new HSubGraphBlockInformation(finallyGraph), | 3132 wrapStatementGraph(catchGraph), |
| 3102 exitBlock); | 3133 wrapStatementGraph(finallyGraph)), |
| 3134 exitBlock); |
| 3103 } | 3135 } |
| 3104 | 3136 |
| 3105 visitScriptTag(ScriptTag node) { | 3137 visitScriptTag(ScriptTag node) { |
| 3106 compiler.unimplemented('SsaBuilder.visitScriptTag', node: node); | 3138 compiler.unimplemented('SsaBuilder.visitScriptTag', node: node); |
| 3107 } | 3139 } |
| 3108 | 3140 |
| 3109 visitCatchBlock(CatchBlock node) { | 3141 visitCatchBlock(CatchBlock node) { |
| 3110 visit(node.block); | 3142 visit(node.block); |
| 3111 } | 3143 } |
| 3112 | 3144 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3279 <HInstruction>[target, input], | 3311 <HInstruction>[target, input], |
| 3280 HType.STRING)); | 3312 HType.STRING)); |
| 3281 return builder.pop(); | 3313 return builder.pop(); |
| 3282 } | 3314 } |
| 3283 | 3315 |
| 3284 HInstruction result() { | 3316 HInstruction result() { |
| 3285 flushLiterals(); | 3317 flushLiterals(); |
| 3286 return prefix; | 3318 return prefix; |
| 3287 } | 3319 } |
| 3288 } | 3320 } |
| OLD | NEW |