Chromium Code Reviews| Index: pkg/compiler/lib/src/cps_ir/insert_refinements.dart |
| diff --git a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart |
| index 6c5ec7014720e6f5417b1d4887f9ed15070c3df8..5ea7cdcd9ffce29ecf3d2e4f9b9f41f4acf3adca 100644 |
| --- a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart |
| +++ b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart |
| @@ -75,9 +75,12 @@ class InsertRefinements extends TrampolineRecursiveVisitor implements Pass { |
| return prim is Interceptor ? prim.input.definition : prim; |
| } |
| - /// Enqueues [cont] for processing in a context where [refined] is the |
| - /// current refinement for its value. |
| - void pushRefinement(Continuation cont, Refinement refined) { |
| + /// Sets [refined] to be the current current refinement for its value, |
|
sra1
2015/11/19 21:41:46
current current?
asgerf
2015/11/20 16:23:54
It is even more current than usual
|
| + /// and pushes an action that will restore the original scope again. |
| + /// |
| + /// The refinement is inserted as the child of [insertionParent] if it has |
| + /// at least one use after its scope has been processed. |
| + void applyRefinement(InteriorNode insertionParent, Refinement refined) { |
| Primitive value = refined.effectiveDefinition; |
| Primitive currentRefinement = refinementFor[value]; |
| pushAction(() { |
| @@ -87,18 +90,22 @@ class InsertRefinements extends TrampolineRecursiveVisitor implements Pass { |
| refined.destroy(); |
| } else { |
| LetPrim let = new LetPrim(refined); |
| - let.insertBelow(cont); |
| + let.insertBelow(insertionParent); |
| } |
| }); |
| - push(cont); |
| + refinementFor[value] = refined; |
|
sra1
2015/11/19 21:41:46
I think I prefer pushAction to be the last thing s
asgerf
2015/11/20 16:23:54
Done.
|
| + } |
| + |
| + /// Enqueues [cont] for processing in a context where [refined] is the |
| + /// current refinement for its value. |
| + void pushRefinement(Continuation cont, Refinement refined) { |
| pushAction(() { |
| - refinementFor[value] = refined; |
| + applyRefinement(cont, refined); |
| + push(cont); |
| }); |
| } |
| void visitInvokeMethod(InvokeMethod node) { |
| - Continuation cont = node.continuation.definition; |
| - |
| // Update references to their current refined values. |
| processReference(node.receiver); |
| node.arguments.forEach(processReference); |
| @@ -107,34 +114,29 @@ class InsertRefinements extends TrampolineRecursiveVisitor implements Pass { |
| // not the interceptor. |
| Primitive receiver = unfoldInterceptor(node.receiver.definition); |
| - // Sink the continuation to the call to ensure everything in scope |
| - // here is also in scope inside the continuations. |
| - sinkContinuationToUse(cont, node); |
| - |
| if (node.selector.isClosureCall) { |
| // Do not try to refine the receiver of closure calls; the class world |
| // does not know about closure classes. |
| - push(cont); |
| } else { |
| // Filter away receivers that throw on this selector. |
| TypeMask type = types.receiverTypeFor(node.selector, node.mask); |
| Refinement refinement = new Refinement(receiver, type); |
| - pushRefinement(cont, refinement); |
| + LetPrim letPrim = node.parent; |
| + applyRefinement(letPrim, refinement); |
| } |
| } |
| void visitTypeCast(TypeCast node) { |
| - Continuation cont = node.continuation.definition; |
| Primitive value = node.value.definition; |
| processReference(node.value); |
| node.typeArguments.forEach(processReference); |
| // Refine the type of the input. |
| - sinkContinuationToUse(cont, node); |
| TypeMask type = types.subtypesOf(node.dartType).nullable(); |
| Refinement refinement = new Refinement(value, type); |
| - pushRefinement(cont, refinement); |
| + LetPrim letPrim = node.parent; |
| + applyRefinement(letPrim, refinement); |
| } |
| void visitRefinement(Refinement node) { |
| @@ -151,16 +153,6 @@ class InsertRefinements extends TrampolineRecursiveVisitor implements Pass { |
| }); |
| } |
| - CallExpression getCallWithResult(Primitive prim) { |
| - if (prim is Parameter && prim.parent is Continuation) { |
| - Continuation cont = prim.parent; |
| - if (cont.hasExactlyOneUse && cont.firstRef.parent is CallExpression) { |
| - return cont.firstRef.parent; |
| - } |
| - } |
| - return null; |
| - } |
| - |
| bool isTrue(Primitive prim) { |
| return prim is Constant && prim.value.isTrue; |
| } |
| @@ -168,7 +160,6 @@ class InsertRefinements extends TrampolineRecursiveVisitor implements Pass { |
| void visitBranch(Branch node) { |
| processReference(node.condition); |
| Primitive condition = node.condition.definition; |
| - CallExpression call = getCallWithResult(condition); |
| Continuation trueCont = node.trueContinuation.definition; |
| Continuation falseCont = node.falseContinuation.definition; |
| @@ -212,9 +203,9 @@ class InsertRefinements extends TrampolineRecursiveVisitor implements Pass { |
| } |
| } |
| - if (call is InvokeMethod && call.selector == Selectors.equals) { |
| - refineEquality(call.arguments[0].definition, |
| - call.arguments[1].definition, |
| + if (condition is InvokeMethod && condition.selector == Selectors.equals) { |
| + refineEquality(condition.dartReceiver, |
| + condition.getDartArgument(0), |
| trueCont, |
| falseCont); |
| return; |
| @@ -236,12 +227,8 @@ class InsertRefinements extends TrampolineRecursiveVisitor implements Pass { |
| @override |
| Expression traverseLetCont(LetCont node) { |
| for (Continuation cont in node.continuations) { |
| - if (cont.hasExactlyOneUse && |
| - (cont.firstRef.parent is InvokeMethod || |
| - cont.firstRef.parent is TypeCast || |
| - cont.firstRef.parent is Branch)) { |
| - // Do not push the continuation here. |
| - // visitInvokeMethod, visitBranch, and visitTypeCast will do that. |
| + if (cont.hasExactlyOneUse && cont.firstRef.parent is Branch) { |
| + // Do not push the branch continuations here. visitBranch will do that. |
| } else { |
| push(cont); |
| } |