| 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 08ac6de347d5c7f2ea1b142bd2a6898013b641b5..a566396319feaa4ef5f96e6875d308ecfe330ec5 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| @@ -49,11 +49,12 @@ class ConstantPropagationLattice {
|
| final AbstractConstantValue anything;
|
| final AbstractConstantValue nullValue;
|
|
|
| - ConstantPropagationLattice(TypeMaskSystem typeSystem,
|
| - this.constantSystem,
|
| - this.dartTypes)
|
| - : this.typeSystem = typeSystem,
|
| - anything = new AbstractConstantValue.nonConstant(typeSystem.dynamicType),
|
| + ConstantPropagationLattice(CpsFunctionCompiler functionCompiler)
|
| + : typeSystem = functionCompiler.typeSystem,
|
| + constantSystem = functionCompiler.compiler.backend.constantSystem,
|
| + dartTypes = functionCompiler.compiler.types,
|
| + anything = new AbstractConstantValue.nonConstant(
|
| + functionCompiler.typeSystem.dynamicType),
|
| nullValue = new AbstractConstantValue.constantValue(
|
| new NullConstantValue(), new TypeMask.empty());
|
|
|
| @@ -711,25 +712,19 @@ class ConstantPropagationLattice {
|
| * by Wegman, Zadeck.
|
| */
|
| class TypePropagator extends Pass {
|
| - String get passName => 'Sparse constant propagation';
|
| + String get passName => 'Type propagation';
|
|
|
| - final dart2js.Compiler _compiler;
|
| final CpsFunctionCompiler _functionCompiler;
|
| + final Map<Variable, ConstantValue> _values= <Variable, ConstantValue>{};
|
| final ConstantPropagationLattice _lattice;
|
| - final InternalErrorFunction _internalError;
|
| - final Map<Variable, ConstantValue> _values = <Variable, ConstantValue>{};
|
| - final TypeMaskSystem _typeSystem;
|
| -
|
| - TypePropagator(dart2js.Compiler compiler,
|
| - TypeMaskSystem typeSystem,
|
| - this._functionCompiler)
|
| - : _compiler = compiler,
|
| - _internalError = compiler.reporter.internalError,
|
| - _typeSystem = typeSystem,
|
| - _lattice = new ConstantPropagationLattice(
|
| - typeSystem,
|
| - compiler.backend.constantSystem,
|
| - compiler.types);
|
| +
|
| + TypePropagator(CpsFunctionCompiler functionCompiler)
|
| + : _functionCompiler = functionCompiler,
|
| + _lattice = new ConstantPropagationLattice(functionCompiler);
|
| +
|
| + dart2js.Compiler get _compiler => _functionCompiler.compiler;
|
| + TypeMaskSystem get _typeSystem => _functionCompiler.typeSystem;
|
| + InternalErrorFunction get _internalError => _compiler.reporter.internalError;
|
|
|
| @override
|
| void rewrite(FunctionDefinition root) {
|
| @@ -2592,31 +2587,38 @@ class TypePropagationVisitor implements Visitor {
|
| void visit(Node node) { node.accept(this); }
|
|
|
| void visitFunctionDefinition(FunctionDefinition node) {
|
| - int firstActualParameter = 0;
|
| - if (backend.isInterceptedMethod(node.element)) {
|
| - if (typeSystem.methodUsesReceiverArgument(node.element)) {
|
| + bool isIntercepted = backend.isInterceptedMethod(node.element);
|
| +
|
| + // If the abstract value of the function parameters is Nothing, use the
|
| + // inferred parameter type. Otherwise (e.g., when inlining) do not
|
| + // change the abstract value.
|
| + if (node.thisParameter != null && getValue(node.thisParameter).isNothing) {
|
| + if (isIntercepted &&
|
| + typeSystem.methodUsesReceiverArgument(node.element)) {
|
| setValue(node.thisParameter, nonConstant(typeSystem.nonNullType));
|
| - setValue(node.parameters[0],
|
| - nonConstant(typeSystem.getReceiverType(node.element)));
|
| } else {
|
| setValue(node.thisParameter,
|
| - nonConstant(typeSystem.getReceiverType(node.element)));
|
| + nonConstant(typeSystem.getReceiverType(node.element)));
|
| + }
|
| + }
|
| + if (isIntercepted && getValue(node.parameters[0]).isNothing) {
|
| + if (typeSystem.methodUsesReceiverArgument(node.element)) {
|
| + setValue(node.parameters[0],
|
| + nonConstant(typeSystem.getReceiverType(node.element)));
|
| + } else {
|
| setValue(node.parameters[0], nonConstant());
|
| }
|
| - firstActualParameter = 1;
|
| - } else if (node.thisParameter != null) {
|
| - setValue(node.thisParameter,
|
| - nonConstant(typeSystem.getReceiverType(node.element)));
|
| }
|
| bool hasParameterWithoutValue = false;
|
| - for (Parameter param in node.parameters.skip(firstActualParameter)) {
|
| - // TODO(karlklose): remove reference to the element model.
|
| - TypeMask type = param.hint is ParameterElement
|
| - ? typeSystem.getParameterType(param.hint)
|
| - : typeSystem.dynamicType;
|
| - setValue(param, lattice.fromMask(type));
|
| - if (type.isEmpty && !type.isNullable) {
|
| - hasParameterWithoutValue = true;
|
| + for (Parameter param in node.parameters.skip(isIntercepted ? 1 : 0)) {
|
| + if (getValue(param).isNothing) {
|
| + TypeMask type = param.hint is ParameterElement
|
| + ? typeSystem.getParameterType(param.hint)
|
| + : typeSystem.dynamicType;
|
| + setValue(param, lattice.fromMask(type));
|
| + if (type.isEmpty && !type.isNullable) {
|
| + hasParameterWithoutValue = true;
|
| + }
|
| }
|
| }
|
| if (!hasParameterWithoutValue) { // Don't analyze unreachable code.
|
|
|