| Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| index 0b7122ad19b2beca527c5a687f787d776a836029..85388f53e2eb7d7abf184ade0434b64830b76e54 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| @@ -495,6 +495,9 @@ class TransformingVisitor extends LeafVisitor {
|
|
|
| void visitContinuation(Continuation node) {
|
| if (node.isReturnContinuation) return;
|
| + if (!analyzer.reachableContinuations.contains(node)) {
|
| + replaceSubtree(node.body, new Unreachable());
|
| + }
|
| // Process the continuation body.
|
| // Note that the continuation body may have changed since the continuation
|
| // was put on the stack (e.g. [visitInvokeContinuation] may do this).
|
| @@ -2008,6 +2011,24 @@ class TypePropagationVisitor implements Visitor {
|
| defWorklist.add(node);
|
| }
|
|
|
| + /// Updates the value of a [CallExpression]'s continuation parameter.
|
| + void setResult(CallExpression call,
|
| + AbstractValue updateValue,
|
| + {bool canReplace: false}) {
|
| + Continuation cont = call.continuation.definition;
|
| + setValue(cont.parameters.single, updateValue);
|
| + if (!updateValue.isNothing) {
|
| + setReachable(cont);
|
| +
|
| + if (updateValue.isConstant && canReplace) {
|
| + replacements[call] = updateValue.constant;
|
| + } else {
|
| + // A replacement might have been set in a previous iteration.
|
| + replacements.remove(call);
|
| + }
|
| + }
|
| + }
|
| +
|
| bool isInterceptedSelector(Selector selector) {
|
| return backend.isInterceptedSelector(selector);
|
| }
|
| @@ -2090,35 +2111,17 @@ class TypePropagationVisitor implements Visitor {
|
| }
|
|
|
| void visitInvokeStatic(InvokeStatic node) {
|
| - Continuation cont = node.continuation.definition;
|
| - setReachable(cont);
|
| -
|
| - assert(cont.parameters.length == 1);
|
| - Parameter returnValue = cont.parameters[0];
|
| -
|
| - /// Sets the value of the target continuation parameter, and possibly
|
| - /// try to replace the whole invocation with a constant.
|
| - void setResult(AbstractValue updateValue, {bool canReplace: false}) {
|
| - setValue(returnValue, updateValue);
|
| - if (canReplace && updateValue.isConstant) {
|
| - replacements[node] = updateValue.constant;
|
| - } else {
|
| - // A previous iteration might have tried to replace this.
|
| - replacements.remove(node);
|
| - }
|
| - }
|
| -
|
| if (node.target.library.isInternalLibrary) {
|
| switch (node.target.name) {
|
| case InternalMethod.Stringify:
|
| AbstractValue argValue = getValue(node.arguments[0].definition);
|
| - setResult(lattice.stringify(argValue), canReplace: true);
|
| + setResult(node, lattice.stringify(argValue), canReplace: true);
|
| return;
|
| }
|
| }
|
|
|
| TypeMask returnType = typeSystem.getReturnType(node.target);
|
| - setResult(nonConstant(returnType));
|
| + setResult(node, nonConstant(returnType));
|
| }
|
|
|
| void visitInvokeContinuation(InvokeContinuation node) {
|
| @@ -2135,29 +2138,13 @@ class TypePropagationVisitor implements Visitor {
|
| }
|
|
|
| void visitInvokeMethod(InvokeMethod node) {
|
| - Continuation cont = node.continuation.definition;
|
| - setReachable(cont);
|
| -
|
| - /// Sets the value of the target continuation parameter, and possibly
|
| - /// try to replace the whole invocation with a constant.
|
| - void setResult(AbstractValue updateValue, {bool canReplace: false}) {
|
| - Parameter returnValue = cont.parameters[0];
|
| - setValue(returnValue, updateValue);
|
| - if (canReplace && updateValue.isConstant) {
|
| - replacements[node] = updateValue.constant;
|
| - } else {
|
| - // A previous iteration might have tried to replace this.
|
| - replacements.remove(node);
|
| - }
|
| - }
|
| -
|
| AbstractValue receiver = getValue(node.receiver.definition);
|
| if (receiver.isNothing) {
|
| return; // And come back later.
|
| }
|
| if (!node.selector.isOperator) {
|
| // TODO(jgruber): Handle known methods on constants such as String.length.
|
| - setResult(lattice.getInvokeReturnType(node.selector, node.mask));
|
| + setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
|
| return;
|
| }
|
|
|
| @@ -2183,9 +2170,9 @@ class TypePropagationVisitor implements Visitor {
|
| // Update value of the continuation parameter. Again, this is effectively
|
| // a phi.
|
| if (result == null) {
|
| - setResult(lattice.getInvokeReturnType(node.selector, node.mask));
|
| + setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
|
| } else {
|
| - setResult(result, canReplace: true);
|
| + setResult(node, result, canReplace: true);
|
| }
|
| }
|
|
|
| @@ -2286,22 +2273,12 @@ class TypePropagationVisitor implements Visitor {
|
| }
|
|
|
| void visitInvokeMethodDirectly(InvokeMethodDirectly node) {
|
| - Continuation cont = node.continuation.definition;
|
| - setReachable(cont);
|
| -
|
| - assert(cont.parameters.length == 1);
|
| - Parameter returnValue = cont.parameters[0];
|
| // TODO(karlklose): lookup the function and get ites return type.
|
| - setValue(returnValue, nonConstant());
|
| + setResult(node, nonConstant());
|
| }
|
|
|
| void visitInvokeConstructor(InvokeConstructor node) {
|
| - Continuation cont = node.continuation.definition;
|
| - setReachable(cont);
|
| -
|
| - assert(cont.parameters.length == 1);
|
| - Parameter returnValue = cont.parameters[0];
|
| - setValue(returnValue, nonConstant(typeSystem.getReturnType(node.target)));
|
| + setResult(node, nonConstant(typeSystem.getReturnType(node.target)));
|
| }
|
|
|
| void visitThrow(Throw node) {
|
| @@ -2440,12 +2417,7 @@ class TypePropagationVisitor implements Visitor {
|
| void visitSetStatic(SetStatic node) {}
|
|
|
| void visitGetLazyStatic(GetLazyStatic node) {
|
| - Continuation cont = node.continuation.definition;
|
| - setReachable(cont);
|
| -
|
| - assert(cont.parameters.length == 1);
|
| - Parameter returnValue = cont.parameters[0];
|
| - setValue(returnValue, nonConstant(typeSystem.getFieldType(node.element)));
|
| + setResult(node, nonConstant(typeSystem.getFieldType(node.element)));
|
| }
|
|
|
| void visitInterceptor(Interceptor node) {
|
| @@ -2504,12 +2476,7 @@ class TypePropagationVisitor implements Visitor {
|
| @override
|
| void visitForeignCode(ForeignCode node) {
|
| if (node.continuation != null) {
|
| - Continuation continuation = node.continuation.definition;
|
| - setReachable(continuation);
|
| -
|
| - assert(continuation.parameters.length == 1);
|
| - Parameter returnValue = continuation.parameters.first;
|
| - setValue(returnValue, nonConstant(node.type));
|
| + setResult(node, nonConstant(node.type));
|
| }
|
| }
|
|
|
|
|