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

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

Issue 10100001: Refactoring if block-information. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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
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 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 799 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 Map<Element, HInstruction> fieldValues) { 810 Map<Element, HInstruction> fieldValues) {
811 constructors.addLast(constructor); 811 constructors.addLast(constructor);
812 812
813 List<HInstruction> compiledArguments = new List<HInstruction>(); 813 List<HInstruction> compiledArguments = new List<HInstruction>();
814 bool succeeded = addStaticSendArgumentsToList(selector, 814 bool succeeded = addStaticSendArgumentsToList(selector,
815 arguments, 815 arguments,
816 constructor, 816 constructor,
817 compiledArguments); 817 compiledArguments);
818 if (!succeeded) { 818 if (!succeeded) {
819 // Non-matching super and redirects are compile-time errors and thus 819 // Non-matching super and redirects are compile-time errors and thus
820 // checked by the resolver. 820 // checked by the resolver.
821 compiler.internalError( 821 compiler.internalError(
822 "Parameters and arguments didn't match for super/redirect call", 822 "Parameters and arguments didn't match for super/redirect call",
823 element: constructor); 823 element: constructor);
824 } 824 }
825 825
826 int index = 0; 826 int index = 0;
827 FunctionParameters parameters = constructor.computeParameters(compiler); 827 FunctionParameters parameters = constructor.computeParameters(compiler);
828 parameters.forEachParameter((Element parameter) { 828 parameters.forEachParameter((Element parameter) {
829 HInstruction argument = compiledArguments[index++]; 829 HInstruction argument = compiledArguments[index++];
830 localsHandler.updateLocal(parameter, argument); 830 localsHandler.updateLocal(parameter, argument);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 1023
1024 void goto(HBasicBlock from, HBasicBlock to) { 1024 void goto(HBasicBlock from, HBasicBlock to) {
1025 from.close(new HGoto()); 1025 from.close(new HGoto());
1026 from.addSuccessor(to); 1026 from.addSuccessor(to);
1027 } 1027 }
1028 1028
1029 bool isAborted() { 1029 bool isAborted() {
1030 return current === null; 1030 return current === null;
1031 } 1031 }
1032 1032
1033 /**
1034 * Creates a new block, transitions to it from any current block, and
1035 * opens the new block.
1036 */
1037 HBasicBlock openNewBlock() {
1038 HBasicBlock newBlock = addNewBlock();
1039 if (!isAborted()) goto(current, newBlock);
1040 open(newBlock);
1041 return newBlock;
1042 }
1043
1033 void add(HInstruction instruction) { 1044 void add(HInstruction instruction) {
1034 current.add(instruction); 1045 current.add(instruction);
1035 } 1046 }
1036 1047
1037 void push(HInstruction instruction) { 1048 void push(HInstruction instruction) {
1038 add(instruction); 1049 add(instruction);
1039 stack.add(instruction); 1050 stack.add(instruction);
1040 } 1051 }
1041 1052
1042 HInstruction pop() { 1053 HInstruction pop() {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 // loop-entry: 1154 // loop-entry:
1144 // if (!<condition>) goto loop-exit; 1155 // if (!<condition>) goto loop-exit;
1145 // <body> 1156 // <body>
1146 // <updates> 1157 // <updates>
1147 // goto loop-entry; 1158 // goto loop-entry;
1148 // loop-exit: 1159 // loop-exit:
1149 1160
1150 localsHandler.startLoop(loop); 1161 localsHandler.startLoop(loop);
1151 1162
1152 // The initializer. 1163 // The initializer.
1153 HBasicBlock initializerBlock = graph.addNewBlock(); 1164 HBasicBlock initializerBlock = openNewBlock();
1154 goto(current, initializerBlock);
1155 open(initializerBlock);
1156 initialize(); 1165 initialize();
1157 assert(!isAborted()); 1166 assert(!isAborted());
1158 SubGraph initializerGraph = new SubGraph(initializerBlock, current); 1167 SubGraph initializerGraph = new SubGraph(initializerBlock, current);
1159 1168
1160 JumpHandler jumpHandler = beginLoopHeader(loop); 1169 JumpHandler jumpHandler = beginLoopHeader(loop);
1161 HBasicBlock conditionBlock = current; 1170 HBasicBlock conditionBlock = current;
1162 HLoopInformation loopInfo = current.loopInformation; 1171 HLoopInformation loopInfo = current.blockInformation;
1163 // The initializer graph is currently unused due to the way we 1172 // The initializer graph is currently unused due to the way we
1164 // generate code. 1173 // generate code.
1165 loopInfo.initializer = initializerGraph; 1174 loopInfo.initializer = initializerGraph;
1166 1175
1167 HInstruction conditionInstruction = condition(); 1176 HInstruction conditionInstruction = condition();
1168 HBasicBlock conditionExitBlock = 1177 HBasicBlock conditionExitBlock =
1169 close(new HLoopBranch(conditionInstruction)); 1178 close(new HLoopBranch(conditionInstruction));
1170 loopInfo.condition = new SubExpression(conditionBlock, 1179 loopInfo.condition = new SubExpression(conditionBlock,
1171 conditionExitBlock, 1180 conditionExitBlock,
1172 conditionInstruction); 1181 conditionInstruction);
(...skipping 27 matching lines...) Expand all
1200 continueLocals.add(localsHandler); 1209 continueLocals.add(localsHandler);
1201 1210
1202 open(updateBlock); 1211 open(updateBlock);
1203 1212
1204 localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock); 1213 localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock);
1205 1214
1206 HLabeledBlockInformation labelInfo; 1215 HLabeledBlockInformation labelInfo;
1207 List<LabelElement> labels = jumpHandler.labels(); 1216 List<LabelElement> labels = jumpHandler.labels();
1208 TargetElement target = elements[loop]; 1217 TargetElement target = elements[loop];
1209 if (!labels.isEmpty()) { 1218 if (!labels.isEmpty()) {
1210 beginBodyBlock.labeledBlockInformation = 1219 beginBodyBlock.blockInformation =
1211 new HLabeledBlockInformation(bodyGraph, updateBlock, 1220 new HLabeledBlockInformation(bodyGraph, updateBlock,
1212 jumpHandler.labels(), isContinue: true); 1221 jumpHandler.labels(), isContinue: true);
1213 } else if (target !== null && target.isContinueTarget) { 1222 } else if (target !== null && target.isContinueTarget) {
1214 beginBodyBlock.labeledBlockInformation = 1223 beginBodyBlock.blockInformation =
1215 new HLabeledBlockInformation.implicit(bodyGraph, updateBlock, 1224 new HLabeledBlockInformation.implicit(bodyGraph, updateBlock,
1216 target, isContinue: true); 1225 target, isContinue: true);
1217 } 1226 }
1218 1227
1219 localsHandler.enterLoopUpdates(loop); 1228 localsHandler.enterLoopUpdates(loop);
1220 1229
1221 update(); 1230 update();
1222 1231
1223 HBasicBlock updateEndBlock = close(new HGoto()); 1232 HBasicBlock updateEndBlock = close(new HGoto());
1224 // The back-edge completing the cycle. 1233 // The back-edge completing the cycle.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 () {}, 1282 () {},
1274 buildCondition, 1283 buildCondition,
1275 () {}, 1284 () {},
1276 () { visit(node.body); }); 1285 () { visit(node.body); });
1277 } 1286 }
1278 1287
1279 visitDoWhile(DoWhile node) { 1288 visitDoWhile(DoWhile node) {
1280 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1289 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1281 localsHandler.startLoop(node); 1290 localsHandler.startLoop(node);
1282 JumpHandler jumpHandler = beginLoopHeader(node); 1291 JumpHandler jumpHandler = beginLoopHeader(node);
1283 HLoopInformation loopInfo = current.loopInformation; 1292 HLoopInformation loopInfo = current.blockInformation;
1284 HBasicBlock loopEntryBlock = current; 1293 HBasicBlock loopEntryBlock = current;
1285 HBasicBlock bodyEntryBlock = current; 1294 HBasicBlock bodyEntryBlock = current;
1286 TargetElement target = elements[node]; 1295 TargetElement target = elements[node];
1287 bool hasContinues = target !== null && target.isContinueTarget; 1296 bool hasContinues = target !== null && target.isContinueTarget;
1288 if (hasContinues) { 1297 if (hasContinues) {
1289 // Add extra block to hang labels on. 1298 // Add extra block to hang labels on.
1290 // It doesn't currently work if they are on the same block as the 1299 // It doesn't currently work if they are on the same block as the
1291 // HLoopInfo. The handling of HLabeledBlockInformation will visit a 1300 // HLoopInfo. The handling of HLabeledBlockInformation will visit a
1292 // SubGraph that starts at the same block again, so the HLoopInfo is 1301 // SubGraph that starts at the same block again, so the HLoopInfo is
1293 // either handled twice, or it's handled after the labeled block info, 1302 // either handled twice, or it's handled after the labeled block info,
1294 // both of which generate the wrong code. 1303 // both of which generate the wrong code.
1295 // Using a separate block is just a simple workaround. 1304 // Using a separate block is just a simple workaround.
1296 bodyEntryBlock = graph.addNewBlock(); 1305 bodyEntryBlock = openNewBlock();
1297 goto(current, bodyEntryBlock);
1298 open(bodyEntryBlock);
1299 } 1306 }
1300 localsHandler.enterLoopBody(node); 1307 localsHandler.enterLoopBody(node);
1301 hackAroundPossiblyAbortingBody(node, () { visit(node.body); }); 1308 hackAroundPossiblyAbortingBody(node, () { visit(node.body); });
1302 1309
1303 // If there are no continues we could avoid the creation of the condition 1310 // If there are no continues we could avoid the creation of the condition
1304 // block. This could also lead to a block having multiple entries and exits. 1311 // block. This could also lead to a block having multiple entries and exits.
1305 HBasicBlock bodyExitBlock = close(new HGoto()); 1312 HBasicBlock bodyExitBlock = close(new HGoto());
1306 HBasicBlock conditionBlock = addNewBlock(); 1313 HBasicBlock conditionBlock = addNewBlock();
1307 1314
1308 List<LocalsHandler> continueLocals = <LocalsHandler>[]; 1315 List<LocalsHandler> continueLocals = <LocalsHandler>[];
1309 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { 1316 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) {
1310 instruction.block.addSuccessor(conditionBlock); 1317 instruction.block.addSuccessor(conditionBlock);
1311 continueLocals.add(locals); 1318 continueLocals.add(locals);
1312 }); 1319 });
1313 bodyExitBlock.addSuccessor(conditionBlock); 1320 bodyExitBlock.addSuccessor(conditionBlock);
1314 if (!continueLocals.isEmpty()) { 1321 if (!continueLocals.isEmpty()) {
1315 continueLocals.add(localsHandler); 1322 continueLocals.add(localsHandler);
1316 localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock); 1323 localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock);
1317 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); 1324 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
1318 List<LabelElement> labels = jumpHandler.labels(); 1325 List<LabelElement> labels = jumpHandler.labels();
1319 if (!labels.isEmpty()) { 1326 if (!labels.isEmpty()) {
1320 bodyEntryBlock.labeledBlockInformation = 1327 bodyEntryBlock.blockInformation =
1321 new HLabeledBlockInformation(bodyGraph, 1328 new HLabeledBlockInformation(bodyGraph,
1322 conditionBlock, 1329 conditionBlock,
1323 labels, 1330 labels,
1324 isContinue: true); 1331 isContinue: true);
1325 } else { 1332 } else {
1326 bodyEntryBlock.labeledBlockInformation = 1333 bodyEntryBlock.blockInformation =
1327 new HLabeledBlockInformation.implicit(bodyGraph, 1334 new HLabeledBlockInformation.implicit(bodyGraph,
1328 conditionBlock, 1335 conditionBlock,
1329 target, 1336 target,
1330 isContinue: true); 1337 isContinue: true);
1331 } 1338 }
1332 } 1339 }
1333 open(conditionBlock); 1340 open(conditionBlock);
1334 1341
1335 visit(node.condition); 1342 visit(node.condition);
1336 assert(!isAborted()); 1343 assert(!isAborted());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 visitIdentifier(Identifier node) { 1395 visitIdentifier(Identifier node) {
1389 if (node.isThis()) { 1396 if (node.isThis()) {
1390 stack.add(localsHandler.readThis()); 1397 stack.add(localsHandler.readThis());
1391 } else { 1398 } else {
1392 compiler.internalError("SsaBuilder.visitIdentifier on non-this", 1399 compiler.internalError("SsaBuilder.visitIdentifier on non-this",
1393 node: node); 1400 node: node);
1394 } 1401 }
1395 } 1402 }
1396 1403
1397 visitIf(If node) { 1404 visitIf(If node) {
1398 visit(node.condition); 1405 handleIf(() => visit(node.condition),
1399 Function visitElse; 1406 () => visit(node.thenPart),
1400 if (node.elsePart != null) { 1407 node.elsePart != null ? () => visit(node.elsePart) : null);
1401 visitElse = () {
1402 visit(node.elsePart);
1403 };
1404 }
1405 handleIf(() => visit(node.thenPart), visitElse);
1406 } 1408 }
1407 1409
1408 void handleIf(void visitThen(), void visitElse()) { 1410 void handleIf(void visitCondition(), void visitThen(), void visitElse()) {
1411 HBasicBlock conditionStartBlock = openNewBlock();
1412 visitCondition();
1413 SubExpression conditionGraph =
1414 new SubExpression(conditionStartBlock, lastOpenedBlock, stack.last());
1409 bool hasElse = visitElse != null; 1415 bool hasElse = visitElse != null;
1410 HIf condition = new HIf(popBoolified(), hasElse); 1416 HInstruction condition = popBoolified();
1411 HBasicBlock conditionBlock = close(condition); 1417 HIf branch = new HIf(condition, hasElse);
1418 HBasicBlock conditionBlock = close(branch);
1412 1419
1413 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1420 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1414 1421
1415 // The then part. 1422 // The then part.
1416 HBasicBlock thenBlock = addNewBlock(); 1423 HBasicBlock thenBlock = addNewBlock();
1417 conditionBlock.addSuccessor(thenBlock); 1424 conditionBlock.addSuccessor(thenBlock);
1418 open(thenBlock); 1425 open(thenBlock);
1419 visitThen(); 1426 visitThen();
1420 SubGraph thenGraph = new SubGraph(thenBlock, lastOpenedBlock); 1427 SubGraph thenGraph = new SubGraph(thenBlock, lastOpenedBlock);
1421 thenBlock = current; 1428 thenBlock = current;
(...skipping 27 matching lines...) Expand all
1449 // with the set of locals we got after visiting the then 1456 // with the set of locals we got after visiting the then
1450 // part of the if. 1457 // part of the if.
1451 open(joinBlock); 1458 open(joinBlock);
1452 if (joinBlock.predecessors.length == 2) { 1459 if (joinBlock.predecessors.length == 2) {
1453 localsHandler.mergeWith(thenLocals, joinBlock); 1460 localsHandler.mergeWith(thenLocals, joinBlock);
1454 } else if (thenBlock !== null) { 1461 } else if (thenBlock !== null) {
1455 // The only predecessor is the then branch. 1462 // The only predecessor is the then branch.
1456 localsHandler = thenLocals; 1463 localsHandler = thenLocals;
1457 } 1464 }
1458 } 1465 }
1459 condition.blockInformation = 1466 HIfBlockInformation info = new HIfBlockInformation(conditionGraph,
1460 new HIfBlockInformation(condition, thenGraph, elseGraph, joinBlock); 1467 thenGraph,
1468 elseGraph,
1469 joinBlock);
1470 conditionStartBlock.blockInformation = info;
1471 branch.blockInformation = info;
1461 } 1472 }
1462 1473
1463 void visitLogicalAndOr(Send node, Operator op) { 1474 void visitLogicalAndOr(Send node, Operator op) {
1464 handleLogicalAndOr(() { visit(node.receiver); }, 1475 handleLogicalAndOr(() { visit(node.receiver); },
1465 () { visit(node.argumentsNode); }, 1476 () { visit(node.argumentsNode); },
1466 isAnd: (const SourceString("&&") == op.source)); 1477 isAnd: (const SourceString("&&") == op.source));
1467 } 1478 }
1468 1479
1469 1480
1470 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) { 1481 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) {
1471 // x && y is transformed into: 1482 // x && y is transformed into:
1472 // t0 = boolify(x); 1483 // t0 = boolify(x);
1473 // if (t0) t1 = boolify(y); 1484 // if (t0) t1 = boolify(y);
1474 // result = phi(t0, t1); 1485 // result = phi(t0, t1);
1475 // 1486 //
1476 // x || y is transformed into: 1487 // x || y is transformed into:
1477 // t0 = boolify(x); 1488 // t0 = boolify(x);
1478 // if (not(t0)) t1 = boolify(y); 1489 // if (not(t0)) t1 = boolify(y);
1479 // result = phi(t0, t1); 1490 // result = phi(t0, t1);
1491 HBasicBlock leftBlock = openNewBlock();
1480 left(); 1492 left();
1481 HInstruction boolifiedLeft = popBoolified(); 1493 HInstruction boolifiedLeft = popBoolified();
1482 HInstruction condition; 1494 HInstruction condition;
1483 if (isAnd) { 1495 if (isAnd) {
1484 condition = boolifiedLeft; 1496 condition = boolifiedLeft;
1485 } else { 1497 } else {
1486 condition = new HNot(boolifiedLeft); 1498 condition = new HNot(boolifiedLeft);
1487 add(condition); 1499 add(condition);
1488 } 1500 }
1501 SubExpression leftGraph =
1502 new SubExpression(leftBlock, lastOpenedBlock, boolifiedLeft);
1489 HIf branch = new HIf(condition, false); 1503 HIf branch = new HIf(condition, false);
1490 HBasicBlock leftBlock = close(branch); 1504 leftBlock = close(branch);
1491 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1505 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1492 1506
1493 HBasicBlock rightBlock = addNewBlock(); 1507 HBasicBlock rightBlock = addNewBlock();
1494 leftBlock.addSuccessor(rightBlock); 1508 leftBlock.addSuccessor(rightBlock);
1495 open(rightBlock); 1509 open(rightBlock);
1496 1510
1497 right(); 1511 right();
1498 HInstruction boolifiedRight = popBoolified(); 1512 HInstruction boolifiedRight = popBoolified();
1499 SubGraph rightGraph = new SubGraph(rightBlock, current); 1513 SubExpression rightGraph =
1514 new SubExpression(rightBlock, current, boolifiedRight);
1500 rightBlock = close(new HGoto()); 1515 rightBlock = close(new HGoto());
1501 1516
1502 HBasicBlock joinBlock = addNewBlock(); 1517 HBasicBlock joinBlock = addNewBlock();
1503 leftBlock.addSuccessor(joinBlock); 1518 leftBlock.addSuccessor(joinBlock);
1504 rightBlock.addSuccessor(joinBlock); 1519 rightBlock.addSuccessor(joinBlock);
1505 open(joinBlock); 1520 open(joinBlock);
1506 1521
1522 leftGraph.start.blockInformation =
1523 new HAndOrBlockInformation(isAnd, leftGraph, rightGraph, joinBlock);
1507 branch.blockInformation = 1524 branch.blockInformation =
1508 new HIfBlockInformation(branch, rightGraph, null, joinBlock); 1525 new HIfBlockInformation(leftGraph, rightGraph, null, joinBlock);
1509 1526
1510 localsHandler.mergeWith(savedLocals, joinBlock); 1527 localsHandler.mergeWith(savedLocals, joinBlock);
1511 HPhi result = new HPhi.manyInputs(null, 1528 HPhi result = new HPhi.manyInputs(null,
1512 <HInstruction>[boolifiedLeft, boolifiedRight]); 1529 <HInstruction>[boolifiedLeft, boolifiedRight]);
1513 joinBlock.addPhi(result); 1530 joinBlock.addPhi(result);
1514 stack.add(result); 1531 stack.add(result);
1515 } 1532 }
1516 1533
1517 void visitLogicalNot(Send node) { 1534 void visitLogicalNot(Send node) {
1518 assert(node.argumentsNode is Prefix); 1535 assert(node.argumentsNode is Prefix);
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 // A different target statement only happens if the body is itself 2594 // A different target statement only happens if the body is itself
2578 // a break or continue for a different target. In that case, this 2595 // a break or continue for a different target. In that case, this
2579 // label is also always unused. 2596 // label is also always unused.
2580 visit(body); 2597 visit(body);
2581 return; 2598 return;
2582 } 2599 }
2583 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler); 2600 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler);
2584 assert(targetElement.isBreakTarget); 2601 assert(targetElement.isBreakTarget);
2585 JumpHandler handler = new JumpHandler(this, targetElement); 2602 JumpHandler handler = new JumpHandler(this, targetElement);
2586 // Introduce a new basic block. 2603 // Introduce a new basic block.
2587 HBasicBlock entryBlock = graph.addNewBlock(); 2604 HBasicBlock entryBlock = openNewBlock();
2588 goto(current, entryBlock);
2589 open(entryBlock);
2590 hackAroundPossiblyAbortingBody(node, () { visit(body); }); 2605 hackAroundPossiblyAbortingBody(node, () { visit(body); });
2591 SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock); 2606 SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock);
2592 2607
2593 HBasicBlock joinBlock = graph.addNewBlock(); 2608 HBasicBlock joinBlock = graph.addNewBlock();
2594 List<LocalsHandler> breakLocals = <LocalsHandler>[]; 2609 List<LocalsHandler> breakLocals = <LocalsHandler>[];
2595 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { 2610 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
2596 breakInstruction.block.addSuccessor(joinBlock); 2611 breakInstruction.block.addSuccessor(joinBlock);
2597 breakLocals.add(locals); 2612 breakLocals.add(locals);
2598 }); 2613 });
2599 bool hasBreak = breakLocals.length > 0; 2614 bool hasBreak = breakLocals.length > 0;
2600 if (!isAborted()) { 2615 if (!isAborted()) {
2601 goto(current, joinBlock); 2616 goto(current, joinBlock);
2602 breakLocals.add(localsHandler); 2617 breakLocals.add(localsHandler);
2603 } 2618 }
2604 open(joinBlock); 2619 open(joinBlock);
2605 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock); 2620 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock);
2606 2621
2607 if (hasBreak) { 2622 if (hasBreak) {
2608 // There was at least one reachable break, so the label is needed. 2623 // There was at least one reachable break, so the label is needed.
2609 HLabeledBlockInformation blockInfo = 2624 entryBlock.blockInformation =
2610 new HLabeledBlockInformation(bodyGraph, joinBlock, handler.labels()); 2625 new HLabeledBlockInformation(bodyGraph, joinBlock, handler.labels());
2611 entryBlock.labeledBlockInformation = blockInfo;
2612 } 2626 }
2613 handler.close(); 2627 handler.close();
2614 } 2628 }
2615 2629
2616 visitLiteralMap(LiteralMap node) { 2630 visitLiteralMap(LiteralMap node) {
2617 if (node.isConst()) { 2631 if (node.isConst()) {
2618 ConstantHandler handler = compiler.constantHandler; 2632 ConstantHandler handler = compiler.constantHandler;
2619 Constant constant = handler.compileNodeWithDefinitions(node, elements); 2633 Constant constant = handler.compileNodeWithDefinitions(node, elements);
2620 stack.add(graph.addConstant(constant)); 2634 stack.add(graph.addConstant(constant));
2621 return; 2635 return;
(...skipping 19 matching lines...) Expand all
2641 visit(node.key); 2655 visit(node.key);
2642 } 2656 }
2643 2657
2644 visitNamedArgument(NamedArgument node) { 2658 visitNamedArgument(NamedArgument node) {
2645 visit(node.expression); 2659 visit(node.expression);
2646 } 2660 }
2647 2661
2648 visitSwitchStatement(SwitchStatement node) { 2662 visitSwitchStatement(SwitchStatement node) {
2649 work.allowSpeculativeOptimization = false; 2663 work.allowSpeculativeOptimization = false;
2650 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 2664 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
2651 HBasicBlock startBlock = graph.addNewBlock(); 2665 HBasicBlock startBlock = openNewBlock();
2652 goto(current, startBlock);
2653 open(startBlock);
2654 visit(node.expression); 2666 visit(node.expression);
2655 HInstruction expression = pop(); 2667 HInstruction expression = pop();
2656 if (node.cases.isEmpty()) { 2668 if (node.cases.isEmpty()) {
2657 return; 2669 return;
2658 } 2670 }
2659 Link<Node> cases = node.cases.nodes; 2671 Link<Node> cases = node.cases.nodes;
2660 2672
2661 JumpHandler jumpHandler = createJumpHandler(node); 2673 JumpHandler jumpHandler = createJumpHandler(node);
2662 2674
2663 buildSwitchCases(cases, expression); 2675 buildSwitchCases(cases, expression);
(...skipping 19 matching lines...) Expand all
2683 open(joinBlock); 2695 open(joinBlock);
2684 if (caseLocals.length == 1) { 2696 if (caseLocals.length == 1) {
2685 localsHandler = caseLocals[0]; 2697 localsHandler = caseLocals[0];
2686 } else { 2698 } else {
2687 localsHandler = savedLocals.mergeMultiple(caseLocals, joinBlock); 2699 localsHandler = savedLocals.mergeMultiple(caseLocals, joinBlock);
2688 } 2700 }
2689 } else { 2701 } else {
2690 // The joinblock is not used. 2702 // The joinblock is not used.
2691 joinBlock = null; 2703 joinBlock = null;
2692 } 2704 }
2693 startBlock.labeledBlockInformation = new HLabeledBlockInformation.implicit( 2705 startBlock.blockInformation = new HLabeledBlockInformation.implicit(
2694 new SubGraph(startBlock, lastBlock), 2706 new SubGraph(startBlock, lastBlock),
2695 joinBlock, 2707 joinBlock,
2696 elements[node]); 2708 elements[node]);
2697 jumpHandler.close(); 2709 jumpHandler.close();
2698 } 2710 }
2699 2711
2700 2712
2701 // Recursively build an if/else structure to match the cases. 2713 // Recursively build an if/else structure to match the cases.
2702 buildSwitchCases(Link<Node> cases, HInstruction expression) { 2714 buildSwitchCases(Link<Node> cases, HInstruction expression) {
2703 SwitchCase node = cases.head; 2715 SwitchCase node = cases.head;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2748 left(); 2760 left();
2749 return; 2761 return;
2750 } 2762 }
2751 2763
2752 void right() { 2764 void right() {
2753 buildTests(remainingExpressions.tail); 2765 buildTests(remainingExpressions.tail);
2754 } 2766 }
2755 handleLogicalAndOr(left, right, isAnd: false); 2767 handleLogicalAndOr(left, right, isAnd: false);
2756 } 2768 }
2757 2769
2758 buildTests(expressions);
2759 HInstruction result = popBoolified();
2760
2761 if (node.isDefaultCase) { 2770 if (node.isDefaultCase) {
2762 // Don't actually use the condition result. 2771 buildTests(expressions);
2763 // This must be final case, so don't check for abort. 2772 // Throw away the test result. We always execute the default case.
2773 pop();
2764 visit(node.statements); 2774 visit(node.statements);
2765 } else { 2775 } else {
2766 stack.add(result);
2767 if (cases.tail.isEmpty()) { 2776 if (cases.tail.isEmpty()) {
2768 handleIf(() { visit(node.statements); }, null); 2777 handleIf(() { buildTests(expressions); },
2778 () { visit(node.statements); },
2779 null);
2769 } else { 2780 } else {
2770 handleIf(() { visitStatementsAndAbort(); }, 2781 handleIf(() { buildTests(expressions); },
2782 () { visitStatementsAndAbort(); },
2771 () { buildSwitchCases(cases.tail, expression); }); 2783 () { buildSwitchCases(cases.tail, expression); });
2772 } 2784 }
2773 } 2785 }
2774 } 2786 }
2775 2787
2776 visitSwitchCase(SwitchCase node) { 2788 visitSwitchCase(SwitchCase node) {
2777 unreachable(); 2789 unreachable();
2778 } 2790 }
2779 2791
2780 visitTryStatement(TryStatement node) { 2792 visitTryStatement(TryStatement node) {
2781 work.allowSpeculativeOptimization = false; 2793 work.allowSpeculativeOptimization = false;
2782 HBasicBlock enterBlock = graph.addNewBlock(); 2794 HBasicBlock enterBlock = openNewBlock();
2783 close(new HGoto()).addSuccessor(enterBlock);
2784 open(enterBlock);
2785 HTry tryInstruction = new HTry(); 2795 HTry tryInstruction = new HTry();
2786 List<HBasicBlock> blocks = <HBasicBlock>[]; 2796 List<HBasicBlock> blocks = <HBasicBlock>[];
2787 blocks.add(close(tryInstruction)); 2797 blocks.add(close(tryInstruction));
2788 2798
2789 HBasicBlock tryBody = graph.addNewBlock(); 2799 HBasicBlock tryBody = graph.addNewBlock();
2790 enterBlock.addSuccessor(tryBody); 2800 enterBlock.addSuccessor(tryBody);
2791 open(tryBody); 2801 open(tryBody);
2792 visit(node.tryBlock); 2802 visit(node.tryBlock);
2793 if (!isAborted()) blocks.add(close(new HGoto())); 2803 if (!isAborted()) blocks.add(close(new HGoto()));
2794 2804
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2842 localsHandler.updateLocal(elements[trace], traceInstruction); 2852 localsHandler.updateLocal(elements[trace], traceInstruction);
2843 } 2853 }
2844 visit(catchBlock); 2854 visit(catchBlock);
2845 } 2855 }
2846 2856
2847 void visitElse() { 2857 void visitElse() {
2848 if (link.isEmpty()) { 2858 if (link.isEmpty()) {
2849 close(new HThrow(exception, isRethrow: true)); 2859 close(new HThrow(exception, isRethrow: true));
2850 } else { 2860 } else {
2851 CatchBlock newBlock = link.head; 2861 CatchBlock newBlock = link.head;
2852 pushCondition(newBlock); 2862 handleIf(() { pushCondition(newBlock); },
2853 handleIf(visitThen, visitElse); 2863 visitThen, visitElse);
2854 } 2864 }
2855 } 2865 }
2856 2866
2857 CatchBlock firstBlock = link.head; 2867 CatchBlock firstBlock = link.head;
2858 pushCondition(firstBlock); 2868 handleIf(() { pushCondition(firstBlock); }, visitThen, visitElse);
2859 handleIf(visitThen, visitElse);
2860 if (!isAborted()) blocks.add(close(new HGoto())); 2869 if (!isAborted()) blocks.add(close(new HGoto()));
2861 rethrowableException = oldRethrowableException; 2870 rethrowableException = oldRethrowableException;
2862 } 2871 }
2863 2872
2864 if (node.finallyBlock != null) { 2873 if (node.finallyBlock != null) {
2865 HBasicBlock finallyBlock = graph.addNewBlock(); 2874 HBasicBlock finallyBlock = graph.addNewBlock();
2866 enterBlock.addSuccessor(finallyBlock); 2875 enterBlock.addSuccessor(finallyBlock);
2867 open(finallyBlock); 2876 open(finallyBlock);
2868 visit(node.finallyBlock); 2877 visit(node.finallyBlock);
2869 if (!isAborted()) blocks.add(close(new HGoto())); 2878 if (!isAborted()) blocks.add(close(new HGoto()));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2904 // calling [add] does not work as it asserts that the instruction 2913 // calling [add] does not work as it asserts that the instruction
2905 // isn't a control flow instruction. So we inline parts of [add]. 2914 // isn't a control flow instruction. So we inline parts of [add].
2906 current.addAfter(current.last, new HThrow(message)); 2915 current.addAfter(current.last, new HThrow(message));
2907 if (isExpression) { 2916 if (isExpression) {
2908 stack.add(graph.addConstantNull()); 2917 stack.add(graph.addConstantNull());
2909 } 2918 }
2910 } 2919 }
2911 2920
2912 /** HACK HACK HACK */ 2921 /** HACK HACK HACK */
2913 void hackAroundPossiblyAbortingBody(Node statement, void body()) { 2922 void hackAroundPossiblyAbortingBody(Node statement, void body()) {
2914 stack.add(graph.addConstantBool(true)); 2923 visitCondition() {
2924 stack.add(graph.addConstantBool(true));
2925 }
2915 buildBody() { 2926 buildBody() {
2916 // TODO(lrn): Make sure to take continue into account. 2927 // TODO(lrn): Make sure to take continue into account.
2917 body(); 2928 body();
2918 if (isAborted()) { 2929 if (isAborted()) {
2919 compiler.reportWarning(statement, "aborting loop body"); 2930 compiler.reportWarning(statement, "aborting loop body");
2920 } 2931 }
2921 } 2932 }
2922 handleIf(buildBody, null); 2933 handleIf(visitCondition, buildBody, null);
2923 } 2934 }
2924 } 2935 }
2925 2936
2926 /** 2937 /**
2927 * Visitor that handles generation of string literals (LiteralString, 2938 * Visitor that handles generation of string literals (LiteralString,
2928 * StringInterpolation), and otherwise delegates to the given visitor for 2939 * StringInterpolation), and otherwise delegates to the given visitor for
2929 * non-literal subexpressions. 2940 * non-literal subexpressions.
2930 * TODO(lrn): Consider whether to handle compile time constant int/boolean 2941 * TODO(lrn): Consider whether to handle compile time constant int/boolean
2931 * expressions as well. 2942 * expressions as well.
2932 */ 2943 */
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
3074 false, 3085 false,
3075 <HInstruction>[target, input])); 3086 <HInstruction>[target, input]));
3076 return builder.pop(); 3087 return builder.pop();
3077 } 3088 }
3078 3089
3079 HInstruction result() { 3090 HInstruction result() {
3080 flushLiterals(); 3091 flushLiterals();
3081 return prefix; 3092 return prefix;
3082 } 3093 }
3083 } 3094 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/native_handler.dart ('k') | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698