| Index: lib/compiler/implementation/ssa/builder.dart
|
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
|
| index 6feb26e04488f8480af89ef4e21ebf26e0bd48d9..094733ea990a3aedde02cae5e19edd3bb5a0d615 100644
|
| --- a/lib/compiler/implementation/ssa/builder.dart
|
| +++ b/lib/compiler/implementation/ssa/builder.dart
|
| @@ -817,7 +817,7 @@ class SsaBuilder implements Visitor {
|
| compiledArguments);
|
| if (!succeeded) {
|
| // Non-matching super and redirects are compile-time errors and thus
|
| - // checked by the resolver.
|
| + // checked by the resolver.
|
| compiler.internalError(
|
| "Parameters and arguments didn't match for super/redirect call",
|
| element: constructor);
|
| @@ -1030,17 +1030,6 @@ class SsaBuilder implements Visitor {
|
| return current === null;
|
| }
|
|
|
| - /**
|
| - * Creates a new block, transitions to it from any current block, and
|
| - * opens the new block.
|
| - */
|
| - HBasicBlock openNewBlock() {
|
| - HBasicBlock newBlock = addNewBlock();
|
| - if (!isAborted()) goto(current, newBlock);
|
| - open(newBlock);
|
| - return newBlock;
|
| - }
|
| -
|
| void add(HInstruction instruction) {
|
| current.add(instruction);
|
| }
|
| @@ -1161,14 +1150,16 @@ class SsaBuilder implements Visitor {
|
| localsHandler.startLoop(loop);
|
|
|
| // The initializer.
|
| - HBasicBlock initializerBlock = openNewBlock();
|
| + HBasicBlock initializerBlock = graph.addNewBlock();
|
| + goto(current, initializerBlock);
|
| + open(initializerBlock);
|
| initialize();
|
| assert(!isAborted());
|
| SubGraph initializerGraph = new SubGraph(initializerBlock, current);
|
|
|
| JumpHandler jumpHandler = beginLoopHeader(loop);
|
| HBasicBlock conditionBlock = current;
|
| - HLoopInformation loopInfo = current.blockInformation;
|
| + HLoopInformation loopInfo = current.loopInformation;
|
| // The initializer graph is currently unused due to the way we
|
| // generate code.
|
| loopInfo.initializer = initializerGraph;
|
| @@ -1216,11 +1207,11 @@ class SsaBuilder implements Visitor {
|
| List<LabelElement> labels = jumpHandler.labels();
|
| TargetElement target = elements[loop];
|
| if (!labels.isEmpty()) {
|
| - beginBodyBlock.blockInformation =
|
| + beginBodyBlock.labeledBlockInformation =
|
| new HLabeledBlockInformation(bodyGraph, updateBlock,
|
| jumpHandler.labels(), isContinue: true);
|
| } else if (target !== null && target.isContinueTarget) {
|
| - beginBodyBlock.blockInformation =
|
| + beginBodyBlock.labeledBlockInformation =
|
| new HLabeledBlockInformation.implicit(bodyGraph, updateBlock,
|
| target, isContinue: true);
|
| }
|
| @@ -1289,7 +1280,7 @@ class SsaBuilder implements Visitor {
|
| LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
|
| localsHandler.startLoop(node);
|
| JumpHandler jumpHandler = beginLoopHeader(node);
|
| - HLoopInformation loopInfo = current.blockInformation;
|
| + HLoopInformation loopInfo = current.loopInformation;
|
| HBasicBlock loopEntryBlock = current;
|
| HBasicBlock bodyEntryBlock = current;
|
| TargetElement target = elements[node];
|
| @@ -1302,7 +1293,9 @@ class SsaBuilder implements Visitor {
|
| // either handled twice, or it's handled after the labeled block info,
|
| // both of which generate the wrong code.
|
| // Using a separate block is just a simple workaround.
|
| - bodyEntryBlock = openNewBlock();
|
| + bodyEntryBlock = graph.addNewBlock();
|
| + goto(current, bodyEntryBlock);
|
| + open(bodyEntryBlock);
|
| }
|
| localsHandler.enterLoopBody(node);
|
| hackAroundPossiblyAbortingBody(node, () { visit(node.body); });
|
| @@ -1324,13 +1317,13 @@ class SsaBuilder implements Visitor {
|
| SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
|
| List<LabelElement> labels = jumpHandler.labels();
|
| if (!labels.isEmpty()) {
|
| - bodyEntryBlock.blockInformation =
|
| + bodyEntryBlock.labeledBlockInformation =
|
| new HLabeledBlockInformation(bodyGraph,
|
| conditionBlock,
|
| labels,
|
| isContinue: true);
|
| } else {
|
| - bodyEntryBlock.blockInformation =
|
| + bodyEntryBlock.labeledBlockInformation =
|
| new HLabeledBlockInformation.implicit(bodyGraph,
|
| conditionBlock,
|
| target,
|
| @@ -1402,20 +1395,20 @@ class SsaBuilder implements Visitor {
|
| }
|
|
|
| visitIf(If node) {
|
| - handleIf(() => visit(node.condition),
|
| - () => visit(node.thenPart),
|
| - node.elsePart != null ? () => visit(node.elsePart) : null);
|
| + visit(node.condition);
|
| + Function visitElse;
|
| + if (node.elsePart != null) {
|
| + visitElse = () {
|
| + visit(node.elsePart);
|
| + };
|
| + }
|
| + handleIf(() => visit(node.thenPart), visitElse);
|
| }
|
|
|
| - void handleIf(void visitCondition(), void visitThen(), void visitElse()) {
|
| - HBasicBlock conditionStartBlock = openNewBlock();
|
| - visitCondition();
|
| - SubExpression conditionGraph =
|
| - new SubExpression(conditionStartBlock, lastOpenedBlock, stack.last());
|
| + void handleIf(void visitThen(), void visitElse()) {
|
| bool hasElse = visitElse != null;
|
| - HInstruction condition = popBoolified();
|
| - HIf branch = new HIf(condition, hasElse);
|
| - HBasicBlock conditionBlock = close(branch);
|
| + HIf condition = new HIf(popBoolified(), hasElse);
|
| + HBasicBlock conditionBlock = close(condition);
|
|
|
| LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
|
|
|
| @@ -1463,12 +1456,8 @@ class SsaBuilder implements Visitor {
|
| localsHandler = thenLocals;
|
| }
|
| }
|
| - HIfBlockInformation info = new HIfBlockInformation(conditionGraph,
|
| - thenGraph,
|
| - elseGraph,
|
| - joinBlock);
|
| - conditionStartBlock.blockInformation = info;
|
| - branch.blockInformation = info;
|
| + condition.blockInformation =
|
| + new HIfBlockInformation(condition, thenGraph, elseGraph, joinBlock);
|
| }
|
|
|
| void visitLogicalAndOr(Send node, Operator op) {
|
| @@ -1488,7 +1477,6 @@ class SsaBuilder implements Visitor {
|
| // t0 = boolify(x);
|
| // if (not(t0)) t1 = boolify(y);
|
| // result = phi(t0, t1);
|
| - HBasicBlock leftBlock = openNewBlock();
|
| left();
|
| HInstruction boolifiedLeft = popBoolified();
|
| HInstruction condition;
|
| @@ -1498,10 +1486,8 @@ class SsaBuilder implements Visitor {
|
| condition = new HNot(boolifiedLeft);
|
| add(condition);
|
| }
|
| - SubExpression leftGraph =
|
| - new SubExpression(leftBlock, lastOpenedBlock, boolifiedLeft);
|
| HIf branch = new HIf(condition, false);
|
| - leftBlock = close(branch);
|
| + HBasicBlock leftBlock = close(branch);
|
| LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
|
|
|
| HBasicBlock rightBlock = addNewBlock();
|
| @@ -1510,8 +1496,7 @@ class SsaBuilder implements Visitor {
|
|
|
| right();
|
| HInstruction boolifiedRight = popBoolified();
|
| - SubExpression rightGraph =
|
| - new SubExpression(rightBlock, current, boolifiedRight);
|
| + SubGraph rightGraph = new SubGraph(rightBlock, current);
|
| rightBlock = close(new HGoto());
|
|
|
| HBasicBlock joinBlock = addNewBlock();
|
| @@ -1519,10 +1504,8 @@ class SsaBuilder implements Visitor {
|
| rightBlock.addSuccessor(joinBlock);
|
| open(joinBlock);
|
|
|
| - leftGraph.start.blockInformation =
|
| - new HAndOrBlockInformation(isAnd, leftGraph, rightGraph, joinBlock);
|
| branch.blockInformation =
|
| - new HIfBlockInformation(leftGraph, rightGraph, null, joinBlock);
|
| + new HIfBlockInformation(branch, rightGraph, null, joinBlock);
|
|
|
| localsHandler.mergeWith(savedLocals, joinBlock);
|
| HPhi result = new HPhi.manyInputs(null,
|
| @@ -2601,7 +2584,9 @@ class SsaBuilder implements Visitor {
|
| assert(targetElement.isBreakTarget);
|
| JumpHandler handler = new JumpHandler(this, targetElement);
|
| // Introduce a new basic block.
|
| - HBasicBlock entryBlock = openNewBlock();
|
| + HBasicBlock entryBlock = graph.addNewBlock();
|
| + goto(current, entryBlock);
|
| + open(entryBlock);
|
| hackAroundPossiblyAbortingBody(node, () { visit(body); });
|
| SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock);
|
|
|
| @@ -2621,8 +2606,9 @@ class SsaBuilder implements Visitor {
|
|
|
| if (hasBreak) {
|
| // There was at least one reachable break, so the label is needed.
|
| - entryBlock.blockInformation =
|
| + HLabeledBlockInformation blockInfo =
|
| new HLabeledBlockInformation(bodyGraph, joinBlock, handler.labels());
|
| + entryBlock.labeledBlockInformation = blockInfo;
|
| }
|
| handler.close();
|
| }
|
| @@ -2662,7 +2648,9 @@ class SsaBuilder implements Visitor {
|
| visitSwitchStatement(SwitchStatement node) {
|
| work.allowSpeculativeOptimization = false;
|
| LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
|
| - HBasicBlock startBlock = openNewBlock();
|
| + HBasicBlock startBlock = graph.addNewBlock();
|
| + goto(current, startBlock);
|
| + open(startBlock);
|
| visit(node.expression);
|
| HInstruction expression = pop();
|
| if (node.cases.isEmpty()) {
|
| @@ -2702,7 +2690,7 @@ class SsaBuilder implements Visitor {
|
| // The joinblock is not used.
|
| joinBlock = null;
|
| }
|
| - startBlock.blockInformation = new HLabeledBlockInformation.implicit(
|
| + startBlock.labeledBlockInformation = new HLabeledBlockInformation.implicit(
|
| new SubGraph(startBlock, lastBlock),
|
| joinBlock,
|
| elements[node]);
|
| @@ -2767,19 +2755,19 @@ class SsaBuilder implements Visitor {
|
| handleLogicalAndOr(left, right, isAnd: false);
|
| }
|
|
|
| + buildTests(expressions);
|
| + HInstruction result = popBoolified();
|
| +
|
| if (node.isDefaultCase) {
|
| - buildTests(expressions);
|
| - // Throw away the test result. We always execute the default case.
|
| - pop();
|
| + // Don't actually use the condition result.
|
| + // This must be final case, so don't check for abort.
|
| visit(node.statements);
|
| } else {
|
| + stack.add(result);
|
| if (cases.tail.isEmpty()) {
|
| - handleIf(() { buildTests(expressions); },
|
| - () { visit(node.statements); },
|
| - null);
|
| + handleIf(() { visit(node.statements); }, null);
|
| } else {
|
| - handleIf(() { buildTests(expressions); },
|
| - () { visitStatementsAndAbort(); },
|
| + handleIf(() { visitStatementsAndAbort(); },
|
| () { buildSwitchCases(cases.tail, expression); });
|
| }
|
| }
|
| @@ -2791,7 +2779,9 @@ class SsaBuilder implements Visitor {
|
|
|
| visitTryStatement(TryStatement node) {
|
| work.allowSpeculativeOptimization = false;
|
| - HBasicBlock enterBlock = openNewBlock();
|
| + HBasicBlock enterBlock = graph.addNewBlock();
|
| + close(new HGoto()).addSuccessor(enterBlock);
|
| + open(enterBlock);
|
| HTry tryInstruction = new HTry();
|
| List<HBasicBlock> blocks = <HBasicBlock>[];
|
| blocks.add(close(tryInstruction));
|
| @@ -2859,13 +2849,14 @@ class SsaBuilder implements Visitor {
|
| close(new HThrow(exception, isRethrow: true));
|
| } else {
|
| CatchBlock newBlock = link.head;
|
| - handleIf(() { pushCondition(newBlock); },
|
| - visitThen, visitElse);
|
| + pushCondition(newBlock);
|
| + handleIf(visitThen, visitElse);
|
| }
|
| }
|
|
|
| CatchBlock firstBlock = link.head;
|
| - handleIf(() { pushCondition(firstBlock); }, visitThen, visitElse);
|
| + pushCondition(firstBlock);
|
| + handleIf(visitThen, visitElse);
|
| if (!isAborted()) blocks.add(close(new HGoto()));
|
| rethrowableException = oldRethrowableException;
|
| }
|
| @@ -2920,9 +2911,7 @@ class SsaBuilder implements Visitor {
|
|
|
| /** HACK HACK HACK */
|
| void hackAroundPossiblyAbortingBody(Node statement, void body()) {
|
| - visitCondition() {
|
| - stack.add(graph.addConstantBool(true));
|
| - }
|
| + stack.add(graph.addConstantBool(true));
|
| buildBody() {
|
| // TODO(lrn): Make sure to take continue into account.
|
| body();
|
| @@ -2930,7 +2919,7 @@ class SsaBuilder implements Visitor {
|
| compiler.reportWarning(statement, "aborting loop body");
|
| }
|
| }
|
| - handleIf(visitCondition, buildBody, null);
|
| + handleIf(buildBody, null);
|
| }
|
| }
|
|
|
|
|