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

Unified Diff: frog/leg/ssa/builder.dart

Issue 9753005: Change visitLoop to handleLoop that takes closures as arguments. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 8 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/co19/co19-leg.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/ssa/builder.dart
diff --git a/frog/leg/ssa/builder.dart b/frog/leg/ssa/builder.dart
index 086bc88312d503b6c231df69ca385656e088d155..040c768a5996d2a7d0dd1ebb2445bf66192e0611 100644
--- a/frog/leg/ssa/builder.dart
+++ b/frog/leg/ssa/builder.dart
@@ -557,7 +557,8 @@ class LocalsHandler {
if (instruction === mine) {
joinedLocals[element] = instruction;
} else {
- HInstruction phi = new HPhi.manyInputs(element, [instruction, mine]);
+ HInstruction phi =
+ new HPhi.manyInputs(element, <HInstruction>[instruction, mine]);
joinBlock.addPhi(phi);
joinedLocals[element] = phi;
}
@@ -1096,11 +1097,13 @@ class SsaBuilder implements Visitor {
}
// For while loops, initializer and update are null.
- visitLoop(Node loop,
- Node initializer,
- Expression condition,
- NodeList updates,
- Node body) {
+ // The condition function must return a boolean result.
+ // None of the functions must leave anything on the stack.
+ handleLoop(Node loop,
+ void initialize(),
+ HInstruction condition(),
+ void update(),
+ void body()) {
// Generate:
// <initializer>
// loop-entry:
@@ -1109,34 +1112,17 @@ class SsaBuilder implements Visitor {
// <updates>
// goto loop-entry;
// loop-exit:
- if (body === null) {
- compiler.unimplemented(
- 'SsaBuilder.visitLoop with empty body',
- node: loop);
- }
localsHandler.startLoop(loop);
// The initializer.
- if (initializer !== null) {
- visit(initializer);
- // We don't care about the value of the initialization.
- if (initializer.asExpression() !== null) pop();
- }
+ initialize();
assert(!isAborted());
JumpHandler jumpHandler = beginLoopHeader(loop);
HBasicBlock conditionBlock = current;
- HInstruction conditionInstruction;
- if (condition != null) {
- visit(condition);
- conditionInstruction = popBoolified();
- } else {
- // TODO(ngeoffray): Once our loop recognition does not require a
- // HLoopBranch, we could just generate a HGoto.
- conditionInstruction = graph.addConstantBool(true);
- }
+ HInstruction conditionInstruction = condition();
HBasicBlock conditionExitBlock =
close(new HLoopBranch(conditionInstruction));
@@ -1148,8 +1134,8 @@ class SsaBuilder implements Visitor {
open(beginBodyBlock);
localsHandler.enterLoopBody(loop);
+ hackAroundPossiblyAbortingBody(loop, body);
- hackAroundPossiblyAbortingBody(body);
SubGraph bodyGraph = new SubGraph(beginBodyBlock, current);
HBasicBlock bodyBlock = close(new HGoto());
@@ -1181,15 +1167,8 @@ class SsaBuilder implements Visitor {
localsHandler.enterLoopUpdates(loop);
- if (updates !== null) {
- for (Expression expression in updates) {
- visit(expression);
- assert(!isAborted());
- // The result of the update instruction isn't used, and can just
- // be dropped.
- HInstruction updateInstruction = pop();
- }
- }
+ update();
+
updateBlock = close(new HGoto());
// The back-edge completing the cycle.
updateBlock.addSuccessor(conditionBlock);
@@ -1200,11 +1179,48 @@ class SsaBuilder implements Visitor {
visitFor(For node) {
assert(node.body !== null);
- visitLoop(node, node.initializer, node.condition, node.update, node.body);
+ void buildInitializer() {
+ if (node.initializer === null) return;
+ Node initializer = node.initializer;
+ if (initializer !== null) {
+ visit(initializer);
+ if (initializer.asExpression() !== null) {
+ pop();
+ }
+ }
+ }
+ HInstruction buildCondition() {
+ if (node.condition === null) {
+ return graph.addConstantBool(true);
+ }
+ visit(node.condition);
+ return popBoolified();
+ }
+ void buildUpdate() {
+ for (Expression expression in node.update) {
+ visit(expression);
+ assert(!isAborted());
+ // The result of the update instruction isn't used, and can just
+ // be dropped.
+ HInstruction updateInstruction = pop();
+ }
+ }
+ void buildBody() {
+ visit(node.body);
+ }
+ handleLoop(node, buildInitializer, buildCondition, buildUpdate, buildBody);
}
visitWhile(While node) {
- visitLoop(node, null, node.condition, null, node.body);
+ HInstruction buildCondition() {
+ visit(node.condition);
+ return popBoolified();
+ }
+ handleLoop(node,
+ () {},
+ buildCondition,
+ () {},
+ () { visit(node.body); });
}
visitDoWhile(DoWhile node) {
@@ -1213,7 +1229,7 @@ class SsaBuilder implements Visitor {
HBasicBlock loopEntryBlock = current;
localsHandler.enterLoopBody(node);
- hackAroundPossiblyAbortingBody(node.body);
+ hackAroundPossiblyAbortingBody(node, () { 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.
@@ -1390,7 +1406,8 @@ class SsaBuilder implements Visitor {
new HIfBlockInformation(branch, rightGraph, null, joinBlock);
localsHandler.mergeWith(savedLocals, joinBlock);
- HPhi result = new HPhi.manyInputs(null, [boolifiedLeft, boolifiedRight]);
+ HPhi result = new HPhi.manyInputs(null,
+ <HInstruction>[boolifiedLeft, boolifiedRight]);
joinBlock.addPhi(result);
stack.add(result);
}
@@ -2209,7 +2226,8 @@ class SsaBuilder implements Visitor {
open(joinBlock);
localsHandler.mergeWith(thenLocals, joinBlock);
- HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]);
+ HPhi phi = new HPhi.manyInputs(null,
+ <HInstruction>[thenInstruction, elseInstruction]);
joinBlock.addPhi(phi);
stack.add(phi);
}
@@ -2285,76 +2303,44 @@ class SsaBuilder implements Visitor {
// E <declaredIdentifier> = $iter.next();
// <body>
// }
- localsHandler.startLoop(node);
-
- SourceString iteratorName = const SourceString("iterator");
+ // All the generated calls are to zero-argument functions.
Selector selector = Selector.INVOCATION_0;
- Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0);
- assert(interceptor != null);
- HStatic target = new HStatic(interceptor);
- add(target);
- visit(node.expression);
- List<HInstruction> inputs = <HInstruction>[target, pop()];
- HInstruction iterator = new HInvokeInterceptor(
- selector, iteratorName, false, inputs);
- add(iterator);
-
- JumpHandler jumpHandler = beginLoopHeader(node);
- HBasicBlock conditionBlock = current;
-
- // The condition.
- push(new HInvokeDynamicMethod(
- selector, const SourceString('hasNext'), [iterator]));
- HBasicBlock conditionExitBlock = close(new HLoopBranch(popBoolified()));
-
- LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
-
- // The body.
- HBasicBlock bodyBlock = addNewBlock();
- conditionExitBlock.addSuccessor(bodyBlock);
- open(bodyBlock);
-
- // The call to next is considered to be part of the loop body.
- localsHandler.enterLoopBody(node);
-
- push(new HInvokeDynamicMethod(
- selector, const SourceString('next'), [iterator]));
+ // The iterator is shared between initializer, condition and body.
+ HInstruction iterator;
+ void buildInitializer() {
+ SourceString iteratorName = const SourceString("iterator");
+ Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0);
+ assert(interceptor != null);
+ HStatic target = new HStatic(interceptor);
+ add(target);
+ visit(node.expression);
+ List<HInstruction> inputs = <HInstruction>[target, pop()];
+ iterator = new HInvokeInterceptor(selector, iteratorName, false, inputs);
+ add(iterator);
+ }
+ HInstruction buildCondition() {
+ push(new HInvokeDynamicMethod(
+ selector, const SourceString('hasNext'), <HInstruction>[iterator]));
+ return popBoolified();
+ }
+ void buildBody() {
+ push(new HInvokeDynamicMethod(
+ selector, const SourceString('next'), <HInstruction>[iterator]));
+
+ Element variable;
+ if (node.declaredIdentifier.asSend() !== null) {
+ variable = elements[node.declaredIdentifier];
+ } else {
+ assert(node.declaredIdentifier.asVariableDefinitions() !== null);
+ VariableDefinitions variableDefinitions = node.declaredIdentifier;
+ variable = elements[variableDefinitions.definitions.nodes.head];
+ }
+ localsHandler.updateLocal(variable, pop());
- Element variable;
- if (node.declaredIdentifier.asSend() !== null) {
- variable = elements[node.declaredIdentifier];
- } else {
- assert(node.declaredIdentifier.asVariableDefinitions() !== null);
- VariableDefinitions variableDefinitions = node.declaredIdentifier;
- variable = elements[variableDefinitions.definitions.nodes.head];
+ visit(node.body);
}
- localsHandler.updateLocal(variable, pop());
-
- hackAroundPossiblyAbortingBody(node.body);
- bodyBlock = close(new HGoto());
-
- jumpHandler.forEachContinue((x,y) {
- // TODO(lrn): Handle continue in for-in.
- // TODO(lrn): Or, preferably, use an abstraction of visitLoop for for-in.
- compiler.cancel('for-in with continue', node: node);
- });
-
- // Update.
- // We create an update block, even if we are in a for-in loop. 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();
-
- bodyBlock.addSuccessor(updateBlock);
- open(updateBlock);
- updateBlock = close(new HGoto());
- // The back-edge completing the cycle.
- updateBlock.addSuccessor(conditionBlock);
- conditionBlock.postProcessLoopHeader();
-
- endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals);
- jumpHandler.close();
+ handleLoop(node, buildInitializer, buildCondition, () {}, buildBody);
}
visitLabeledStatement(LabeledStatement node) {
@@ -2381,7 +2367,7 @@ class SsaBuilder implements Visitor {
HBasicBlock entryBlock = graph.addNewBlock();
goto(current, entryBlock);
open(entryBlock);
- hackAroundPossiblyAbortingBody(body);
+ hackAroundPossiblyAbortingBody(node, () { visit(body); });
SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock);
HBasicBlock joinBlock = graph.addNewBlock();
@@ -2699,13 +2685,13 @@ class SsaBuilder implements Visitor {
}
/** HACK HACK HACK */
- void hackAroundPossiblyAbortingBody(Node body) {
+ void hackAroundPossiblyAbortingBody(Node statement, void body()) {
stack.add(graph.addConstantBool(true));
buildBody() {
// TODO(lrn): Make sure to take continue into account.
- visit(body);
+ body();
if (isAborted()) {
- compiler.reportWarning(body, "aborting loop body");
+ compiler.reportWarning(statement, "aborting loop body");
}
}
handleIf(buildBody, null);
« no previous file with comments | « no previous file | tests/co19/co19-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698