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

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 988 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 999
1000 void goto(HBasicBlock from, HBasicBlock to) { 1000 void goto(HBasicBlock from, HBasicBlock to) {
1001 from.close(new HGoto()); 1001 from.close(new HGoto());
1002 from.addSuccessor(to); 1002 from.addSuccessor(to);
1003 } 1003 }
1004 1004
1005 bool isAborted() { 1005 bool isAborted() {
1006 return current === null; 1006 return current === null;
1007 } 1007 }
1008 1008
1009 /**
1010 * Creates a new block, transitions to it from any current block, and
1011 * opens the new block.
1012 */
1013 HBasicBlock openNewBlock() {
1014 HBasicBlock newBlock = addNewBlock();
1015 if (!isAborted()) goto(current, newBlock);
1016 open(newBlock);
1017 return newBlock;
1018 }
1019
1009 void add(HInstruction instruction) { 1020 void add(HInstruction instruction) {
1010 current.add(instruction); 1021 current.add(instruction);
1011 } 1022 }
1012 1023
1013 void push(HInstruction instruction) { 1024 void push(HInstruction instruction) {
1014 add(instruction); 1025 add(instruction);
1015 stack.add(instruction); 1026 stack.add(instruction);
1016 } 1027 }
1017 1028
1018 HInstruction pop() { 1029 HInstruction pop() {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 // loop-entry: 1126 // loop-entry:
1116 // if (!<condition>) goto loop-exit; 1127 // if (!<condition>) goto loop-exit;
1117 // <body> 1128 // <body>
1118 // <updates> 1129 // <updates>
1119 // goto loop-entry; 1130 // goto loop-entry;
1120 // loop-exit: 1131 // loop-exit:
1121 1132
1122 localsHandler.startLoop(loop); 1133 localsHandler.startLoop(loop);
1123 1134
1124 // The initializer. 1135 // The initializer.
1125 HBasicBlock initializerBlock = graph.addNewBlock(); 1136 HBasicBlock initializerBlock = openNewBlock();
1126 goto(current, initializerBlock);
1127 open(initializerBlock);
1128 initialize(); 1137 initialize();
1129 assert(!isAborted()); 1138 assert(!isAborted());
1130 SubGraph initializerGraph = new SubGraph(initializerBlock, current); 1139 SubGraph initializerGraph = new SubGraph(initializerBlock, current);
1131 1140
1132 JumpHandler jumpHandler = beginLoopHeader(loop); 1141 JumpHandler jumpHandler = beginLoopHeader(loop);
1133 HBasicBlock conditionBlock = current; 1142 HBasicBlock conditionBlock = current;
1134 HLoopInformation loopInfo = current.loopInformation; 1143 HLoopInformation loopInfo = current.blockInformation;
1135 // The initializer graph is currently unused due to the way we 1144 // The initializer graph is currently unused due to the way we
1136 // generate code. 1145 // generate code.
1137 loopInfo.initializer = initializerGraph; 1146 loopInfo.initializer = initializerGraph;
1138 1147
1139 HInstruction conditionInstruction = condition(); 1148 HInstruction conditionInstruction = condition();
1140 HBasicBlock conditionExitBlock = 1149 HBasicBlock conditionExitBlock =
1141 close(new HLoopBranch(conditionInstruction)); 1150 close(new HLoopBranch(conditionInstruction));
1142 loopInfo.condition = new SubExpression(conditionBlock, 1151 loopInfo.condition = new SubExpression(conditionBlock,
1143 conditionExitBlock, 1152 conditionExitBlock,
1144 conditionInstruction); 1153 conditionInstruction);
(...skipping 27 matching lines...) Expand all
1172 continueLocals.add(localsHandler); 1181 continueLocals.add(localsHandler);
1173 1182
1174 open(updateBlock); 1183 open(updateBlock);
1175 1184
1176 localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock); 1185 localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock);
1177 1186
1178 HLabeledBlockInformation labelInfo; 1187 HLabeledBlockInformation labelInfo;
1179 List<LabelElement> labels = jumpHandler.labels(); 1188 List<LabelElement> labels = jumpHandler.labels();
1180 TargetElement target = elements[loop]; 1189 TargetElement target = elements[loop];
1181 if (!labels.isEmpty()) { 1190 if (!labels.isEmpty()) {
1182 beginBodyBlock.labeledBlockInformation = 1191 beginBodyBlock.blockInformation =
1183 new HLabeledBlockInformation(bodyGraph, updateBlock, 1192 new HLabeledBlockInformation(bodyGraph, updateBlock,
1184 jumpHandler.labels(), isContinue: true); 1193 jumpHandler.labels(), isContinue: true);
1185 } else if (target !== null && target.isContinueTarget) { 1194 } else if (target !== null && target.isContinueTarget) {
1186 beginBodyBlock.labeledBlockInformation = 1195 beginBodyBlock.blockInformation =
1187 new HLabeledBlockInformation.implicit(bodyGraph, updateBlock, 1196 new HLabeledBlockInformation.implicit(bodyGraph, updateBlock,
1188 target, isContinue: true); 1197 target, isContinue: true);
1189 } 1198 }
1190 1199
1191 localsHandler.enterLoopUpdates(loop); 1200 localsHandler.enterLoopUpdates(loop);
1192 1201
1193 update(); 1202 update();
1194 1203
1195 HBasicBlock updateEndBlock = close(new HGoto()); 1204 HBasicBlock updateEndBlock = close(new HGoto());
1196 // The back-edge completing the cycle. 1205 // The back-edge completing the cycle.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 () {}, 1254 () {},
1246 buildCondition, 1255 buildCondition,
1247 () {}, 1256 () {},
1248 () { visit(node.body); }); 1257 () { visit(node.body); });
1249 } 1258 }
1250 1259
1251 visitDoWhile(DoWhile node) { 1260 visitDoWhile(DoWhile node) {
1252 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1261 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1253 localsHandler.startLoop(node); 1262 localsHandler.startLoop(node);
1254 JumpHandler jumpHandler = beginLoopHeader(node); 1263 JumpHandler jumpHandler = beginLoopHeader(node);
1255 HLoopInformation loopInfo = current.loopInformation; 1264 HLoopInformation loopInfo = current.blockInformation;
1256 HBasicBlock loopEntryBlock = current; 1265 HBasicBlock loopEntryBlock = current;
1257 HBasicBlock bodyEntryBlock = current; 1266 HBasicBlock bodyEntryBlock = current;
1258 TargetElement target = elements[node]; 1267 TargetElement target = elements[node];
1259 bool hasContinues = target !== null && target.isContinueTarget; 1268 bool hasContinues = target !== null && target.isContinueTarget;
1260 if (hasContinues) { 1269 if (hasContinues) {
1261 // Add extra block to hang labels on. 1270 // Add extra block to hang labels on.
1262 // It doesn't currently work if they are on the same block as the 1271 // It doesn't currently work if they are on the same block as the
1263 // HLoopInfo. The handling of HLabeledBlockInformation will visit a 1272 // HLoopInfo. The handling of HLabeledBlockInformation will visit a
1264 // SubGraph that starts at the same block again, so the HLoopInfo is 1273 // SubGraph that starts at the same block again, so the HLoopInfo is
1265 // either handled twice, or it's handled after the labeled block info, 1274 // either handled twice, or it's handled after the labeled block info,
1266 // both of which generate the wrong code. 1275 // both of which generate the wrong code.
1267 // Using a separate block is just a simple workaround. 1276 // Using a separate block is just a simple workaround.
1268 bodyEntryBlock = graph.addNewBlock(); 1277 bodyEntryBlock = openNewBlock();
1269 goto(current, bodyEntryBlock);
1270 open(bodyEntryBlock);
1271 } 1278 }
1272 localsHandler.enterLoopBody(node); 1279 localsHandler.enterLoopBody(node);
1273 hackAroundPossiblyAbortingBody(node, () { visit(node.body); }); 1280 hackAroundPossiblyAbortingBody(node, () { visit(node.body); });
1274 1281
1275 // If there are no continues we could avoid the creation of the condition 1282 // If there are no continues we could avoid the creation of the condition
1276 // block. This could also lead to a block having multiple entries and exits. 1283 // block. This could also lead to a block having multiple entries and exits.
1277 HBasicBlock bodyExitBlock = close(new HGoto()); 1284 HBasicBlock bodyExitBlock = close(new HGoto());
1278 HBasicBlock conditionBlock = addNewBlock(); 1285 HBasicBlock conditionBlock = addNewBlock();
1279 1286
1280 List<LocalsHandler> continueLocals = <LocalsHandler>[]; 1287 List<LocalsHandler> continueLocals = <LocalsHandler>[];
1281 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { 1288 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) {
1282 instruction.block.addSuccessor(conditionBlock); 1289 instruction.block.addSuccessor(conditionBlock);
1283 continueLocals.add(locals); 1290 continueLocals.add(locals);
1284 }); 1291 });
1285 bodyExitBlock.addSuccessor(conditionBlock); 1292 bodyExitBlock.addSuccessor(conditionBlock);
1286 if (!continueLocals.isEmpty()) { 1293 if (!continueLocals.isEmpty()) {
1287 continueLocals.add(localsHandler); 1294 continueLocals.add(localsHandler);
1288 localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock); 1295 localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock);
1289 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); 1296 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
1290 List<LabelElement> labels = jumpHandler.labels(); 1297 List<LabelElement> labels = jumpHandler.labels();
1291 if (!labels.isEmpty()) { 1298 if (!labels.isEmpty()) {
1292 bodyEntryBlock.labeledBlockInformation = 1299 bodyEntryBlock.blockInformation =
1293 new HLabeledBlockInformation(bodyGraph, 1300 new HLabeledBlockInformation(bodyGraph,
1294 conditionBlock, 1301 conditionBlock,
1295 labels, 1302 labels,
1296 isContinue: true); 1303 isContinue: true);
1297 } else { 1304 } else {
1298 bodyEntryBlock.labeledBlockInformation = 1305 bodyEntryBlock.blockInformation =
1299 new HLabeledBlockInformation.implicit(bodyGraph, 1306 new HLabeledBlockInformation.implicit(bodyGraph,
1300 conditionBlock, 1307 conditionBlock,
1301 target, 1308 target,
1302 isContinue: true); 1309 isContinue: true);
1303 } 1310 }
1304 } 1311 }
1305 open(conditionBlock); 1312 open(conditionBlock);
1306 1313
1307 visit(node.condition); 1314 visit(node.condition);
1308 assert(!isAborted()); 1315 assert(!isAborted());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 1366
1360 visitIdentifier(Identifier node) { 1367 visitIdentifier(Identifier node) {
1361 if (node.isThis()) { 1368 if (node.isThis()) {
1362 stack.add(localsHandler.readThis()); 1369 stack.add(localsHandler.readThis());
1363 } else { 1370 } else {
1364 compiler.internalError("SsaBuilder.visitIdentifier on non-this", 1371 compiler.internalError("SsaBuilder.visitIdentifier on non-this",
1365 node: node); 1372 node: node);
1366 } 1373 }
1367 } 1374 }
1368 1375
1369 visitIf(If node) { 1376 visitIf(If node) {
ngeoffray 2012/04/17 07:44:20 You can remove the five lines below
Lasse Reichstein Nielsen 2012/04/17 12:58:22 Well spotted.
1370 visit(node.condition);
1371 Function visitElse; 1377 Function visitElse;
1372 if (node.elsePart != null) { 1378 if (node.elsePart != null) {
1373 visitElse = () { 1379 visitElse = () {
1374 visit(node.elsePart); 1380 visit(node.elsePart);
1375 }; 1381 };
1376 } 1382 }
1377 handleIf(() => visit(node.thenPart), visitElse); 1383 handleIf(() => visit(node.condition),
1384 () => visit(node.thenPart),
1385 node.elsePart != null ? () => visit(node.elsePart) : null);
1378 } 1386 }
1379 1387
1380 void handleIf(void visitThen(), void visitElse()) { 1388 void handleIf(void visitCondition(), void visitThen(), void visitElse()) {
1389 HBasicBlock conditionStartBlock = openNewBlock();
1390 visitCondition();
1391 SubExpression conditionGraph =
1392 new SubExpression(conditionStartBlock, lastOpenedBlock, stack.last());
1381 bool hasElse = visitElse != null; 1393 bool hasElse = visitElse != null;
1382 HIf condition = new HIf(popBoolified(), hasElse); 1394 HInstruction condition = popBoolified();
1383 HBasicBlock conditionBlock = close(condition); 1395 HBasicBlock conditionBlock = close(new HIf(condition, hasElse));
1384 1396
1385 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1397 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1386 1398
1387 // The then part. 1399 // The then part.
1388 HBasicBlock thenBlock = addNewBlock(); 1400 HBasicBlock thenBlock = addNewBlock();
1389 conditionBlock.addSuccessor(thenBlock); 1401 conditionBlock.addSuccessor(thenBlock);
1390 open(thenBlock); 1402 open(thenBlock);
1391 visitThen(); 1403 visitThen();
1392 SubGraph thenGraph = new SubGraph(thenBlock, lastOpenedBlock); 1404 SubGraph thenGraph = new SubGraph(thenBlock, lastOpenedBlock);
1393 thenBlock = current; 1405 thenBlock = current;
(...skipping 27 matching lines...) Expand all
1421 // with the set of locals we got after visiting the then 1433 // with the set of locals we got after visiting the then
1422 // part of the if. 1434 // part of the if.
1423 open(joinBlock); 1435 open(joinBlock);
1424 if (joinBlock.predecessors.length == 2) { 1436 if (joinBlock.predecessors.length == 2) {
1425 localsHandler.mergeWith(thenLocals, joinBlock); 1437 localsHandler.mergeWith(thenLocals, joinBlock);
1426 } else if (thenBlock !== null) { 1438 } else if (thenBlock !== null) {
1427 // The only predecessor is the then branch. 1439 // The only predecessor is the then branch.
1428 localsHandler = thenLocals; 1440 localsHandler = thenLocals;
1429 } 1441 }
1430 } 1442 }
1431 condition.blockInformation = 1443 HIfBlockInformation info = new HIfBlockInformation(conditionGraph,
1432 new HIfBlockInformation(condition, thenGraph, elseGraph, joinBlock); 1444 thenGraph,
1445 elseGraph,
1446 joinBlock);
1447 conditionStartBlock.blockInformation = info;
1448 conditionBlock.last.blockInformation = info;
1433 } 1449 }
1434 1450
1435 void visitLogicalAndOr(Send node, Operator op) { 1451 void visitLogicalAndOr(Send node, Operator op) {
1436 handleLogicalAndOr(() { visit(node.receiver); }, 1452 handleLogicalAndOr(() { visit(node.receiver); },
1437 () { visit(node.argumentsNode); }, 1453 () { visit(node.argumentsNode); },
1438 isAnd: (const SourceString("&&") == op.source)); 1454 isAnd: (const SourceString("&&") == op.source));
1439 } 1455 }
1440 1456
1441 1457
1442 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) { 1458 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) {
1443 // x && y is transformed into: 1459 // x && y is transformed into:
1444 // t0 = boolify(x); 1460 // t0 = boolify(x);
1445 // if (t0) t1 = boolify(y); 1461 // if (t0) t1 = boolify(y);
1446 // result = phi(t0, t1); 1462 // result = phi(t0, t1);
1447 // 1463 //
1448 // x || y is transformed into: 1464 // x || y is transformed into:
1449 // t0 = boolify(x); 1465 // t0 = boolify(x);
1450 // if (not(t0)) t1 = boolify(y); 1466 // if (not(t0)) t1 = boolify(y);
1451 // result = phi(t0, t1); 1467 // result = phi(t0, t1);
1468 HBasicBlock leftBlock = openNewBlock();
1452 left(); 1469 left();
1453 HInstruction boolifiedLeft = popBoolified(); 1470 HInstruction boolifiedLeft = popBoolified();
1454 HInstruction condition; 1471 HInstruction condition;
1455 if (isAnd) { 1472 if (isAnd) {
1456 condition = boolifiedLeft; 1473 condition = boolifiedLeft;
1457 } else { 1474 } else {
1458 condition = new HNot(boolifiedLeft); 1475 condition = new HNot(boolifiedLeft);
1459 add(condition); 1476 add(condition);
1460 } 1477 }
1478 SubExpression leftGraph =
1479 new SubExpression(leftBlock, lastOpenedBlock, boolifiedLeft);
1461 HIf branch = new HIf(condition, false); 1480 HIf branch = new HIf(condition, false);
1462 HBasicBlock leftBlock = close(branch); 1481 leftBlock = close(branch);
1463 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1482 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1464 1483
1465 HBasicBlock rightBlock = addNewBlock(); 1484 HBasicBlock rightBlock = addNewBlock();
1466 leftBlock.addSuccessor(rightBlock); 1485 leftBlock.addSuccessor(rightBlock);
1467 open(rightBlock); 1486 open(rightBlock);
1468 1487
1469 right(); 1488 right();
1470 HInstruction boolifiedRight = popBoolified(); 1489 HInstruction boolifiedRight = popBoolified();
1471 SubGraph rightGraph = new SubGraph(rightBlock, current); 1490 SubExpression rightGraph =
1491 new SubExpression(rightBlock, current, boolifiedRight);
1472 rightBlock = close(new HGoto()); 1492 rightBlock = close(new HGoto());
1473 1493
1474 HBasicBlock joinBlock = addNewBlock(); 1494 HBasicBlock joinBlock = addNewBlock();
1475 leftBlock.addSuccessor(joinBlock); 1495 leftBlock.addSuccessor(joinBlock);
1476 rightBlock.addSuccessor(joinBlock); 1496 rightBlock.addSuccessor(joinBlock);
1477 open(joinBlock); 1497 open(joinBlock);
1478 1498
1499 leftGraph.start.blockInformation =
1500 new HAndOrBlockInformation(isAnd, leftGraph, rightGraph, joinBlock);
1479 branch.blockInformation = 1501 branch.blockInformation =
1480 new HIfBlockInformation(branch, rightGraph, null, joinBlock); 1502 new HIfBlockInformation(leftGraph, rightGraph, null, joinBlock);
1481 1503
1482 localsHandler.mergeWith(savedLocals, joinBlock); 1504 localsHandler.mergeWith(savedLocals, joinBlock);
1483 HPhi result = new HPhi.manyInputs(null, 1505 HPhi result = new HPhi.manyInputs(null,
1484 <HInstruction>[boolifiedLeft, boolifiedRight]); 1506 <HInstruction>[boolifiedLeft, boolifiedRight]);
1485 joinBlock.addPhi(result); 1507 joinBlock.addPhi(result);
1486 stack.add(result); 1508 stack.add(result);
1487 } 1509 }
1488 1510
1489 void visitLogicalNot(Send node) { 1511 void visitLogicalNot(Send node) {
1490 assert(node.argumentsNode is Prefix); 1512 assert(node.argumentsNode is Prefix);
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after
2527 // A different target statement only happens if the body is itself 2549 // A different target statement only happens if the body is itself
2528 // a break or continue for a different target. In that case, this 2550 // a break or continue for a different target. In that case, this
2529 // label is also always unused. 2551 // label is also always unused.
2530 visit(body); 2552 visit(body);
2531 return; 2553 return;
2532 } 2554 }
2533 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler); 2555 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler);
2534 assert(targetElement.isBreakTarget); 2556 assert(targetElement.isBreakTarget);
2535 JumpHandler handler = new JumpHandler(this, targetElement); 2557 JumpHandler handler = new JumpHandler(this, targetElement);
2536 // Introduce a new basic block. 2558 // Introduce a new basic block.
2537 HBasicBlock entryBlock = graph.addNewBlock(); 2559 HBasicBlock entryBlock = openNewBlock();
2538 goto(current, entryBlock);
2539 open(entryBlock);
2540 hackAroundPossiblyAbortingBody(node, () { visit(body); }); 2560 hackAroundPossiblyAbortingBody(node, () { visit(body); });
2541 SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock); 2561 SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock);
2542 2562
2543 HBasicBlock joinBlock = graph.addNewBlock(); 2563 HBasicBlock joinBlock = graph.addNewBlock();
2544 List<LocalsHandler> breakLocals = <LocalsHandler>[]; 2564 List<LocalsHandler> breakLocals = <LocalsHandler>[];
2545 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { 2565 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
2546 breakInstruction.block.addSuccessor(joinBlock); 2566 breakInstruction.block.addSuccessor(joinBlock);
2547 breakLocals.add(locals); 2567 breakLocals.add(locals);
2548 }); 2568 });
2549 bool hasBreak = breakLocals.length > 0; 2569 bool hasBreak = breakLocals.length > 0;
2550 if (!isAborted()) { 2570 if (!isAborted()) {
2551 goto(current, joinBlock); 2571 goto(current, joinBlock);
2552 breakLocals.add(localsHandler); 2572 breakLocals.add(localsHandler);
2553 } 2573 }
2554 open(joinBlock); 2574 open(joinBlock);
2555 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock); 2575 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock);
2556 2576
2557 if (hasBreak) { 2577 if (hasBreak) {
2558 // There was at least one reachable break, so the label is needed. 2578 // There was at least one reachable break, so the label is needed.
2559 HLabeledBlockInformation blockInfo = 2579 entryBlock.blockInformation =
2560 new HLabeledBlockInformation(bodyGraph, joinBlock, handler.labels()); 2580 new HLabeledBlockInformation(bodyGraph, joinBlock, handler.labels());
2561 entryBlock.labeledBlockInformation = blockInfo;
2562 } 2581 }
2563 handler.close(); 2582 handler.close();
2564 } 2583 }
2565 2584
2566 visitLiteralMap(LiteralMap node) { 2585 visitLiteralMap(LiteralMap node) {
2567 if (node.isConst()) { 2586 if (node.isConst()) {
2568 ConstantHandler handler = compiler.constantHandler; 2587 ConstantHandler handler = compiler.constantHandler;
2569 Constant constant = handler.compileNodeWithDefinitions(node, elements); 2588 Constant constant = handler.compileNodeWithDefinitions(node, elements);
2570 stack.add(graph.addConstant(constant)); 2589 stack.add(graph.addConstant(constant));
2571 return; 2590 return;
(...skipping 19 matching lines...) Expand all
2591 visit(node.key); 2610 visit(node.key);
2592 } 2611 }
2593 2612
2594 visitNamedArgument(NamedArgument node) { 2613 visitNamedArgument(NamedArgument node) {
2595 visit(node.expression); 2614 visit(node.expression);
2596 } 2615 }
2597 2616
2598 visitSwitchStatement(SwitchStatement node) { 2617 visitSwitchStatement(SwitchStatement node) {
2599 work.allowSpeculativeOptimization = false; 2618 work.allowSpeculativeOptimization = false;
2600 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 2619 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
2601 HBasicBlock startBlock = graph.addNewBlock(); 2620 HBasicBlock startBlock = openNewBlock();
2602 goto(current, startBlock);
2603 open(startBlock);
2604 visit(node.expression); 2621 visit(node.expression);
2605 HInstruction expression = pop(); 2622 HInstruction expression = pop();
2606 if (node.cases.isEmpty()) { 2623 if (node.cases.isEmpty()) {
2607 return; 2624 return;
2608 } 2625 }
2609 Link<Node> cases = node.cases.nodes; 2626 Link<Node> cases = node.cases.nodes;
2610 2627
2611 JumpHandler jumpHandler = createJumpHandler(node); 2628 JumpHandler jumpHandler = createJumpHandler(node);
2612 2629
2613 buildSwitchCases(cases, expression); 2630 buildSwitchCases(cases, expression);
(...skipping 19 matching lines...) Expand all
2633 open(joinBlock); 2650 open(joinBlock);
2634 if (caseLocals.length == 1) { 2651 if (caseLocals.length == 1) {
2635 localsHandler = caseLocals[0]; 2652 localsHandler = caseLocals[0];
2636 } else { 2653 } else {
2637 localsHandler = savedLocals.mergeMultiple(caseLocals, joinBlock); 2654 localsHandler = savedLocals.mergeMultiple(caseLocals, joinBlock);
2638 } 2655 }
2639 } else { 2656 } else {
2640 // The joinblock is not used. 2657 // The joinblock is not used.
2641 joinBlock = null; 2658 joinBlock = null;
2642 } 2659 }
2643 startBlock.labeledBlockInformation = new HLabeledBlockInformation.implicit( 2660 startBlock.blockInformation = new HLabeledBlockInformation.implicit(
2644 new SubGraph(startBlock, lastBlock), 2661 new SubGraph(startBlock, lastBlock),
2645 joinBlock, 2662 joinBlock,
2646 elements[node]); 2663 elements[node]);
2647 jumpHandler.close(); 2664 jumpHandler.close();
2648 } 2665 }
2649 2666
2650 2667
2651 // Recursively build an if/else structure to match the cases. 2668 // Recursively build an if/else structure to match the cases.
2652 buildSwitchCases(Link<Node> cases, HInstruction expression) { 2669 buildSwitchCases(Link<Node> cases, HInstruction expression) {
2653 SwitchCase node = cases.head; 2670 SwitchCase node = cases.head;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2698 left(); 2715 left();
2699 return; 2716 return;
2700 } 2717 }
2701 2718
2702 void right() { 2719 void right() {
2703 buildTests(expressions.tail); 2720 buildTests(expressions.tail);
2704 } 2721 }
2705 handleLogicalAndOr(left, right, isAnd: false); 2722 handleLogicalAndOr(left, right, isAnd: false);
2706 } 2723 }
2707 2724
2708 buildTests(expressions);
2709 HInstruction result = popBoolified();
2710
2711 if (node.isDefaultCase) { 2725 if (node.isDefaultCase) {
2712 // Don't actually use the condition result. 2726 // Don't actually bother testing the expressions.
ngeoffray 2012/04/17 07:44:20 The comment and the line below don't seem to match
Lasse Reichstein Nielsen 2012/04/17 12:58:22 Reworded.
2713 // This must be final case, so don't check for abort. 2727 buildTests(expressions);
2728 pop();
2714 visit(node.statements); 2729 visit(node.statements);
2715 } else { 2730 } else {
2716 stack.add(result);
2717 if (cases.tail.isEmpty()) { 2731 if (cases.tail.isEmpty()) {
2718 handleIf(() { visit(node.statements); }, null); 2732 handleIf(() { buildTests(expressions); },
2733 () { visit(node.statements); },
2734 null);
2719 } else { 2735 } else {
2720 handleIf(() { visitStatementsAndAbort(); }, 2736 handleIf(() { buildTests(expressions); },
2737 () { visitStatementsAndAbort(); },
2721 () { buildSwitchCases(cases.tail, expression); }); 2738 () { buildSwitchCases(cases.tail, expression); });
2722 } 2739 }
2723 } 2740 }
2724 } 2741 }
2725 2742
2726 visitSwitchCase(SwitchCase node) { 2743 visitSwitchCase(SwitchCase node) {
2727 unreachable(); 2744 unreachable();
2728 } 2745 }
2729 2746
2730 visitTryStatement(TryStatement node) { 2747 visitTryStatement(TryStatement node) {
2731 work.allowSpeculativeOptimization = false; 2748 work.allowSpeculativeOptimization = false;
2732 HBasicBlock enterBlock = graph.addNewBlock(); 2749 HBasicBlock enterBlock = openNewBlock();
2733 close(new HGoto()).addSuccessor(enterBlock);
2734 open(enterBlock);
2735 HTry tryInstruction = new HTry(); 2750 HTry tryInstruction = new HTry();
2736 List<HBasicBlock> blocks = <HBasicBlock>[]; 2751 List<HBasicBlock> blocks = <HBasicBlock>[];
2737 blocks.add(close(tryInstruction)); 2752 blocks.add(close(tryInstruction));
2738 2753
2739 HBasicBlock tryBody = graph.addNewBlock(); 2754 HBasicBlock tryBody = graph.addNewBlock();
2740 enterBlock.addSuccessor(tryBody); 2755 enterBlock.addSuccessor(tryBody);
2741 open(tryBody); 2756 open(tryBody);
2742 visit(node.tryBlock); 2757 visit(node.tryBlock);
2743 if (!isAborted()) blocks.add(close(new HGoto())); 2758 if (!isAborted()) blocks.add(close(new HGoto()));
2744 2759
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2792 localsHandler.updateLocal(elements[trace], traceInstruction); 2807 localsHandler.updateLocal(elements[trace], traceInstruction);
2793 } 2808 }
2794 visit(catchBlock); 2809 visit(catchBlock);
2795 } 2810 }
2796 2811
2797 void visitElse() { 2812 void visitElse() {
2798 if (link.isEmpty()) { 2813 if (link.isEmpty()) {
2799 close(new HThrow(exception, isRethrow: true)); 2814 close(new HThrow(exception, isRethrow: true));
2800 } else { 2815 } else {
2801 CatchBlock newBlock = link.head; 2816 CatchBlock newBlock = link.head;
2802 pushCondition(newBlock); 2817 handleIf(() { pushCondition(newBlock); },
2803 handleIf(visitThen, visitElse); 2818 visitThen, visitElse);
2804 } 2819 }
2805 } 2820 }
2806 2821
2807 CatchBlock firstBlock = link.head; 2822 CatchBlock firstBlock = link.head;
2808 pushCondition(firstBlock); 2823 handleIf(() { pushCondition(firstBlock); }, visitThen, visitElse);
2809 handleIf(visitThen, visitElse);
2810 if (!isAborted()) blocks.add(close(new HGoto())); 2824 if (!isAborted()) blocks.add(close(new HGoto()));
2811 rethrowableException = oldRethrowableException; 2825 rethrowableException = oldRethrowableException;
2812 } 2826 }
2813 2827
2814 if (node.finallyBlock != null) { 2828 if (node.finallyBlock != null) {
2815 HBasicBlock finallyBlock = graph.addNewBlock(); 2829 HBasicBlock finallyBlock = graph.addNewBlock();
2816 enterBlock.addSuccessor(finallyBlock); 2830 enterBlock.addSuccessor(finallyBlock);
2817 open(finallyBlock); 2831 open(finallyBlock);
2818 visit(node.finallyBlock); 2832 visit(node.finallyBlock);
2819 if (!isAborted()) blocks.add(close(new HGoto())); 2833 if (!isAborted()) blocks.add(close(new HGoto()));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2854 // calling [add] does not work as it asserts that the instruction 2868 // calling [add] does not work as it asserts that the instruction
2855 // isn't a control flow instruction. So we inline parts of [add]. 2869 // isn't a control flow instruction. So we inline parts of [add].
2856 current.addAfter(current.last, new HThrow(message)); 2870 current.addAfter(current.last, new HThrow(message));
2857 if (isExpression) { 2871 if (isExpression) {
2858 stack.add(graph.addConstantNull()); 2872 stack.add(graph.addConstantNull());
2859 } 2873 }
2860 } 2874 }
2861 2875
2862 /** HACK HACK HACK */ 2876 /** HACK HACK HACK */
2863 void hackAroundPossiblyAbortingBody(Node statement, void body()) { 2877 void hackAroundPossiblyAbortingBody(Node statement, void body()) {
2864 stack.add(graph.addConstantBool(true)); 2878 visitCondition() {
2879 stack.add(graph.addConstantBool(true));
2880 }
2865 buildBody() { 2881 buildBody() {
2866 // TODO(lrn): Make sure to take continue into account. 2882 // TODO(lrn): Make sure to take continue into account.
2867 body(); 2883 body();
2868 if (isAborted()) { 2884 if (isAborted()) {
2869 compiler.reportWarning(statement, "aborting loop body"); 2885 compiler.reportWarning(statement, "aborting loop body");
2870 } 2886 }
2871 } 2887 }
2872 handleIf(buildBody, null); 2888 handleIf(visitCondition, buildBody, null);
2873 } 2889 }
2874 } 2890 }
2875 2891
2876 /** 2892 /**
2877 * Visitor that handles generation of string literals (LiteralString, 2893 * Visitor that handles generation of string literals (LiteralString,
2878 * StringInterpolation), and otherwise delegates to the given visitor for 2894 * StringInterpolation), and otherwise delegates to the given visitor for
2879 * non-literal subexpressions. 2895 * non-literal subexpressions.
2880 * TODO(lrn): Consider whether to handle compile time constant int/boolean 2896 * TODO(lrn): Consider whether to handle compile time constant int/boolean
2881 * expressions as well. 2897 * expressions as well.
2882 */ 2898 */
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
3024 false, 3040 false,
3025 <HInstruction>[target, input])); 3041 <HInstruction>[target, input]));
3026 return builder.pop(); 3042 return builder.pop();
3027 } 3043 }
3028 3044
3029 HInstruction result() { 3045 HInstruction result() {
3030 flushLiterals(); 3046 flushLiterals();
3031 return prefix; 3047 return prefix;
3032 } 3048 }
3033 } 3049 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698