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

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 11364134: Merge libv1. (Closed) Base URL: https://dart.googlecode.com/svn/experimental/lib_v2/dart
Patch Set: Reupload due to error Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 5275c522e4afb2f63360f01e228616963d3517c6..cab86dd5aa5504f8855e7144bd3a9d0b860804a3 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -332,8 +332,7 @@ class LocalsHandler {
if (element != null && element.isGenerativeConstructorBody()) {
// The box is passed as a parameter to a generative
// constructor body.
- box = new HParameterValue(scopeData.boxElement);
- builder.add(box);
+ box = builder.addParameter(scopeData.boxElement);
} else {
box = createBox();
}
@@ -394,8 +393,7 @@ class LocalsHandler {
FunctionElement functionElement = element;
FunctionSignature params = functionElement.computeSignature(compiler);
params.orderedForEachParameter((Element parameterElement) {
- HInstruction parameter = new HParameterValue(parameterElement);
- builder.add(parameter);
+ HInstruction parameter = builder.addParameter(parameterElement);
builder.parameters[parameterElement] = parameter;
directLocals[parameterElement] = parameter;
parameter.guaranteedType =
@@ -665,6 +663,9 @@ class LocalsHandler {
}
void endLoop(HBasicBlock loopEntry) {
+ // If the loop has an aborting body, we don't update the loop
+ // phis.
+ if (loopEntry.predecessors.length == 1) return;
loopEntry.forEachPhi((HPhi phi) {
Element element = phi.sourceElement;
HInstruction postLoopDefinition = directLocals[element];
@@ -767,6 +768,8 @@ abstract class JumpHandler {
void forEachBreak(void action(HBreak instruction, LocalsHandler locals));
void forEachContinue(void action(HContinue instruction,
LocalsHandler locals));
+ bool hasAnyContinue();
+ bool hasAnyBreak();
void close();
final TargetElement target;
List<LabelElement> labels();
@@ -791,6 +794,8 @@ class NullJumpHandler implements JumpHandler {
void forEachBreak(Function ignored) { }
void forEachContinue(Function ignored) { }
void close() { }
+ bool hasAnyContinue() => false;
+ bool hasAnyBreak() => false;
List<LabelElement> labels() => const <LabelElement>[];
TargetElement get target => null;
@@ -848,6 +853,20 @@ class TargetJumpHandler implements JumpHandler {
}
}
+ bool hasAnyContinue() {
+ for (JumpHandlerEntry entry in jumps) {
+ if (entry.isContinue()) return true;
+ }
+ return false;
+ }
+
+ bool hasAnyBreak() {
+ for (JumpHandlerEntry entry in jumps) {
+ if (entry.isBreak()) return true;
+ }
+ return false;
+ }
+
void close() {
// The mapping from TargetElement to JumpHandler is no longer needed.
builder.jumpTargets.remove(target);
@@ -875,6 +894,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HInstruction rethrowableException;
Map<Element, HInstruction> parameters;
final RuntimeTypeInformation rti;
+ HParameterValue lastAddedParameter;
Map<TargetElement, JumpHandler> jumpTargets;
@@ -926,6 +946,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
List<InliningState> inliningStack;
Element returnElement;
DartType returnType;
+ bool inTryStatement = false;
void disableMethodInterception() {
assert(methodInterceptionEnabled);
@@ -1017,6 +1038,17 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
return bodyElement;
}
+ HParameterValue addParameter(Element element) {
+ HParameterValue result = new HParameterValue(element);
+ if (lastAddedParameter == null) {
+ graph.entry.addBefore(graph.entry.first, result);
+ } else {
+ graph.entry.addAfter(lastAddedParameter, result);
+ }
+ lastAddedParameter = result;
+ return result;
+ }
+
/**
* Documentation wanted -- johnniwinther
*
@@ -1435,8 +1467,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
if (currentElement.isGenerativeConstructorBody()) {
// A generative constructor body receives extra parameters that
// indicate if a parameter was passed to the factory.
- check = new HParameterValue(checkResultElement);
- add(check);
+ check = addParameter(checkResultElement);
} else {
// This is the code we emit for a parameter that is being checked
// on whether it was given at value at the call site:
@@ -1528,8 +1559,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
var enclosing = element.enclosingElement;
if (element.isConstructor() && compiler.world.needsRti(enclosing)) {
enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
- HParameterValue param = new HParameterValue(typeVariable.element);
- add(param);
+ HParameterValue param = addParameter(typeVariable.element);
localsHandler.directLocals[typeVariable.element] = param;
});
}
@@ -1715,14 +1745,18 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HBasicBlock branchBlock,
JumpHandler jumpHandler,
LocalsHandler savedLocals) {
+ if (branchBlock == null && !jumpHandler.hasAnyBreak()) return;
+
HBasicBlock loopExitBlock = addNewBlock();
- assert(branchBlock.successors.length == 1);
+ assert(branchBlock == null || branchBlock.successors.length == 1);
List<LocalsHandler> breakLocals = <LocalsHandler>[];
jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
breakInstruction.block.addSuccessor(loopExitBlock);
breakLocals.add(locals);
});
- branchBlock.addSuccessor(loopExitBlock);
+ if (branchBlock != null) {
+ branchBlock.addSuccessor(loopExitBlock);
+ }
open(loopExitBlock);
localsHandler.endLoop(loopEntry);
if (!breakLocals.isEmpty) {
@@ -1793,57 +1827,69 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
open(beginBodyBlock);
localsHandler.enterLoopBody(loop);
- hackAroundPossiblyAbortingBody(loop, body);
+ body();
+
+ SubGraph bodyGraph = new SubGraph(beginBodyBlock, lastOpenedBlock);
+ HBasicBlock bodyBlock = current;
+ if (current != null) close(new HGoto());
+
+ SubExpression updateGraph;
+
+ // Check that the loop has at least one back-edge.
+ if (jumpHandler.hasAnyContinue() || bodyBlock != null) {
+ // Update.
+ // We create an update block, even when we are in a while loop. There the
+ // update block is the jump-target for continue statements. We could avoid
+ // the creation if there is no continue, but for now we always create it.
+ HBasicBlock updateBlock = addNewBlock();
+
+ List<LocalsHandler> continueLocals = <LocalsHandler>[];
+ jumpHandler.forEachContinue((HContinue instruction,
+ LocalsHandler locals) {
+ instruction.block.addSuccessor(updateBlock);
+ continueLocals.add(locals);
+ });
- SubGraph bodyGraph = new SubGraph(beginBodyBlock, current);
- HBasicBlock bodyBlock = close(new HGoto());
- // Update.
- // We create an update block, even when we are in a while loop. There the
- // update block is the jump-target for continue statements. We could avoid
- // the creation if there is no continue, but for now we always create it.
- HBasicBlock updateBlock = addNewBlock();
+ if (bodyBlock != null) {
+ continueLocals.add(localsHandler);
+ bodyBlock.addSuccessor(updateBlock);
+ }
+
+ open(updateBlock);
+ localsHandler =
+ continueLocals[0].mergeMultiple(continueLocals, updateBlock);
+
+ HLabeledBlockInformation labelInfo;
+ List<LabelElement> labels = jumpHandler.labels();
+ TargetElement target = elements[loop];
+ if (!labels.isEmpty) {
+ beginBodyBlock.setBlockFlow(
+ new HLabeledBlockInformation(
+ new HSubGraphBlockInformation(bodyGraph),
+ jumpHandler.labels(),
+ isContinue: true),
+ updateBlock);
+ } else if (target != null && target.isContinueTarget) {
+ beginBodyBlock.setBlockFlow(
+ new HLabeledBlockInformation.implicit(
+ new HSubGraphBlockInformation(bodyGraph),
+ target,
+ isContinue: true),
+ updateBlock);
+ }
+
+ localsHandler.enterLoopUpdates(loop);
+
+ update();
+
+ HBasicBlock updateEndBlock = close(new HGoto());
+ // The back-edge completing the cycle.
+ updateEndBlock.addSuccessor(conditionBlock);
+ updateGraph = new SubExpression(updateBlock, updateEndBlock);
+ }
- List<LocalsHandler> continueLocals = <LocalsHandler>[];
- jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) {
- instruction.block.addSuccessor(updateBlock);
- continueLocals.add(locals);
- });
- bodyBlock.addSuccessor(updateBlock);
- continueLocals.add(localsHandler);
-
- open(updateBlock);
-
- localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock);
-
- HLabeledBlockInformation labelInfo;
- List<LabelElement> labels = jumpHandler.labels();
- TargetElement target = elements[loop];
- if (!labels.isEmpty) {
- beginBodyBlock.setBlockFlow(
- new HLabeledBlockInformation(
- new HSubGraphBlockInformation(bodyGraph),
- jumpHandler.labels(),
- isContinue: true),
- updateBlock);
- } else if (target != null && target.isContinueTarget) {
- beginBodyBlock.setBlockFlow(
- new HLabeledBlockInformation.implicit(
- new HSubGraphBlockInformation(bodyGraph),
- target,
- isContinue: true),
- updateBlock);
- }
-
- localsHandler.enterLoopUpdates(loop);
-
- update();
-
- HBasicBlock updateEndBlock = close(new HGoto());
- // The back-edge completing the cycle.
- updateEndBlock.addSuccessor(conditionBlock);
conditionBlock.postProcessLoopHeader();
- SubExpression updateGraph = new SubExpression(updateBlock, updateEndBlock);
endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals);
HLoopBlockInformation info =
@@ -1928,51 +1974,71 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
bodyEntryBlock = openNewBlock();
}
localsHandler.enterLoopBody(node);
- hackAroundPossiblyAbortingBody(node, () { visit(node.body); });
+ visit(node.body);
// If there are no continues we could avoid the creation of the condition
// block. This could also lead to a block having multiple entries and exits.
- HBasicBlock bodyExitBlock = close(new HGoto());
- HBasicBlock conditionBlock = addNewBlock();
+ HBasicBlock bodyExitBlock;
+ bool isAbortingBody = false;
+ if (current != null) {
+ bodyExitBlock = close(new HGoto());
+ } else {
+ isAbortingBody = true;
+ bodyExitBlock = lastOpenedBlock;
+ }
- List<LocalsHandler> continueLocals = <LocalsHandler>[];
- jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) {
- instruction.block.addSuccessor(conditionBlock);
- continueLocals.add(locals);
- });
- bodyExitBlock.addSuccessor(conditionBlock);
- if (!continueLocals.isEmpty) {
- continueLocals.add(localsHandler);
- localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock);
- SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
- List<LabelElement> labels = jumpHandler.labels();
- HSubGraphBlockInformation bodyInfo =
- new HSubGraphBlockInformation(bodyGraph);
- HLabeledBlockInformation info;
- if (!labels.isEmpty) {
- info = new HLabeledBlockInformation(bodyInfo, labels, isContinue: true);
- } else {
- info = new HLabeledBlockInformation.implicit(bodyInfo, target,
- isContinue: true);
+ SubExpression conditionExpression;
+ HBasicBlock conditionEndBlock;
+ if (!isAbortingBody || hasContinues) {
+ HBasicBlock conditionBlock = addNewBlock();
+
+ List<LocalsHandler> continueLocals = <LocalsHandler>[];
+ jumpHandler.forEachContinue((HContinue instruction,
+ LocalsHandler locals) {
+ instruction.block.addSuccessor(conditionBlock);
+ continueLocals.add(locals);
+ });
+
+ if (!isAbortingBody) {
+ bodyExitBlock.addSuccessor(conditionBlock);
}
- bodyEntryBlock.setBlockFlow(info, conditionBlock);
- }
- open(conditionBlock);
- visit(node.condition);
- assert(!isAborted());
- HInstruction conditionInstruction = popBoolified();
- HBasicBlock conditionEndBlock =
- close(new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP));
+ if (!continueLocals.isEmpty) {
+ if (!isAbortingBody) continueLocals.add(localsHandler);
+ localsHandler =
+ savedLocals.mergeMultiple(continueLocals, conditionBlock);
+ SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
+ List<LabelElement> labels = jumpHandler.labels();
+ HSubGraphBlockInformation bodyInfo =
+ new HSubGraphBlockInformation(bodyGraph);
+ HLabeledBlockInformation info;
+ if (!labels.isEmpty) {
+ info = new HLabeledBlockInformation(bodyInfo, labels,
+ isContinue: true);
+ } else {
+ info = new HLabeledBlockInformation.implicit(bodyInfo, target,
+ isContinue: true);
+ }
+ bodyEntryBlock.setBlockFlow(info, conditionBlock);
+ }
+ open(conditionBlock);
+
+ visit(node.condition);
+ assert(!isAborted());
+ HInstruction conditionInstruction = popBoolified();
+ conditionEndBlock = close(
+ new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP));
+
+ conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge.
+ conditionExpression =
+ new SubExpression(conditionBlock, conditionEndBlock);
+ }
- conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge.
loopEntryBlock.postProcessLoopHeader();
endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler);
jumpHandler.close();
- SubExpression conditionExpression =
- new SubExpression(conditionBlock, conditionEndBlock);
SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
HLoopBlockInformation loopBlockInfo =
@@ -2198,7 +2264,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
String getTargetName(ErroneousElement error, [String prefix]) {
- String result = error.targetName.slowToString();
+ String result = error.name.slowToString();
if (?prefix) {
result = '$prefix $result';
}
@@ -3007,7 +3073,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
compiler.internalError("Unresolved element: $constructor", node: node);
}
FunctionElement functionElement = constructor;
- constructor = functionElement.defaultImplementation;
+ constructor = functionElement.redirectionTarget;
// TODO(5346): Try to avoid the need for calling [declaration] before
// creating an [HStatic].
HInstruction target = new HStatic(constructor.declaration);
@@ -3241,6 +3307,9 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
visitNewExpression(NewExpression node) {
Element element = elements[node.send];
+ if (!Elements.isErroneousElement(element)) {
+ element = element.redirectionTarget;
+ }
if (Elements.isErroneousElement(element)) {
ErroneousElement error = element;
if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
@@ -3444,15 +3513,20 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
dup();
}
+ void handleInTryStatement() {
+ if (!inTryStatement) return;
+ HBasicBlock block = close(new HExitTry());
+ HBasicBlock newBlock = graph.addNewBlock();
+ block.addSuccessor(newBlock);
+ open(newBlock);
+ }
+
visitReturn(Return node) {
if (identical(node.getBeginToken().stringValue, 'native')) {
native.handleSsaNative(this, node.expression);
return;
}
- if (node.isRedirectingFactoryBody) {
- compiler.internalError("Unimplemented: Redirecting factory constructor",
- node: node);
- }
+ assert(invariant(node, !node.isRedirectingFactoryBody));
HInstruction value;
if (node.expression == null) {
value = graph.addConstantNull(constantSystem);
@@ -3465,6 +3539,9 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
value = potentiallyCheckType(value, returnType);
}
}
+
+ handleInTryStatement();
+
if (!inliningStack.isEmpty) {
localsHandler.updateLocal(returnElement, value);
} else {
@@ -3555,6 +3632,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
visitBreakStatement(BreakStatement node) {
assert(!isAborted());
+ handleInTryStatement();
TargetElement target = elements[node];
assert(target != null);
JumpHandler handler = jumpTargets[target];
@@ -3568,6 +3646,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
visitContinueStatement(ContinueStatement node) {
+ handleInTryStatement();
TargetElement target = elements[node];
assert(target != null);
JumpHandler handler = jumpTargets[target];
@@ -3678,7 +3757,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
JumpHandler handler = new JumpHandler(this, targetElement);
// Introduce a new basic block.
HBasicBlock entryBlock = openNewBlock();
- hackAroundPossiblyAbortingBody(node, () { visit(body); });
+ visit(body);
SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock);
HBasicBlock joinBlock = graph.addNewBlock();
@@ -4107,6 +4186,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HBasicBlock enterBlock = openNewBlock();
HTry tryInstruction = new HTry();
close(tryInstruction);
+ bool oldInTryStatement = inTryStatement;
+ inTryStatement = true;
HBasicBlock startTryBlock;
HBasicBlock endTryBlock;
@@ -4221,6 +4302,22 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HBasicBlock exitBlock = graph.addNewBlock();
addOptionalSuccessor(b1, b2) { if (b2 != null) b1.addSuccessor(b2); }
+ addExitTrySuccessor(successor) {
+ if (successor == null) return;
+ // Iterate over all blocks created inside this try/catch, and
+ // attach successor information to blocks that end with
+ // [HExitTry].
+ for (int i = startTryBlock.id; i < successor.id; i++) {
+ HBasicBlock block = graph.blocks[i];
+ var last = block.last;
+ if (last is HExitTry) {
+ block.addSuccessor(successor);
+ } else if (last is HTry) {
+ // Skip all blocks inside this nested try/catch.
+ i = last.joinBlock.id;
+ }
+ }
+ }
// Setup all successors. The entry block that contains the [HTry]
// has 1) the body, 2) the catch, 3) the finally, and 4) the exit
@@ -4249,6 +4346,12 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
endFinallyBlock.addSuccessor(exitBlock);
}
+ // If a block inside try/catch aborts (eg with a return statement),
+ // we explicitely mark this block a predecessor of the catch
+ // block and the finally block.
+ addExitTrySuccessor(startCatchBlock);
+ addExitTrySuccessor(startFinallyBlock);
+
// Use the locals handler not altered by the catch and finally
// blocks.
localsHandler = savedLocals;
@@ -4260,6 +4363,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
wrapStatementGraph(catchGraph),
wrapStatementGraph(finallyGraph)),
exitBlock);
+ inTryStatement = oldInTryStatement;
}
visitScriptTag(ScriptTag node) {
@@ -4290,18 +4394,6 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
if (element == builder.compiler.stringClass) return HType.STRING;
return HType.UNKNOWN;
}
-
- /** HACK HACK HACK */
- void hackAroundPossiblyAbortingBody(Node statement, void body()) {
- visitCondition() {
- stack.add(graph.addConstantBool(true, constantSystem));
- }
- buildBody() {
- // TODO(lrn): Make sure to take continue into account.
- body();
- }
- handleIf(statement, visitCondition, buildBody, null);
- }
}
/**

Powered by Google App Engine
This is Rietveld 408576698