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); |
} |
} |