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

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

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