From 703a7fcc6dfd4ebc056a5d1118dccbc8ece110f8 Mon Sep 17 00:00:00 2001 From: Asger Feldthaus Date: Fri, 5 Feb 2016 12:10:23 +0100 Subject: [PATCH] dart2js cps: More type rules in type propagation. BUG= R=kmillikin@google.com Review URL: https://codereview.chromium.org/1657613004 . --- pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart | 3 + .../lib/src/cps_ir/type_mask_system.dart | 7 +- .../lib/src/cps_ir/type_propagation.dart | 71 +++++++++++++------ .../dart2js/cps_ir/expected/operators_4.js | 6 +- 4 files changed, 56 insertions(+), 31 deletions(-) diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart index e73dd846c67..b0af0b99253 100644 --- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart @@ -699,6 +699,9 @@ class InvokeMethodDirectly extends InvocationPrimitive { receiver.parent = this; _setParentsOnList(arguments, this); } + + bool get isConstructorBodyCall => target is ConstructorBodyElement; + bool get isTearOff => selector.isGetter && !target.isGetter; } /// Non-const call to a constructor. diff --git a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart index 0a21c3f6571..5b30cafa0f9 100644 --- a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart +++ b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart @@ -559,11 +559,8 @@ class TypeMaskSystem implements AbstractValueDomain { if (isDefinitelyString(type)) { return stringType; } - if (type.satisfies(helpers.typedArrayClass, classWorld)) { - if (type.satisfies(helpers.typedArrayOfIntClass, classWorld)) { - return intType; - } - return numType; + if (type.satisfies(helpers.jsIndexingBehaviorInterface, classWorld)) { + return getInvokeReturnType(new Selector.index(), type); } return dynamicType; } diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart index f1944ce5a88..6c896e1cf8e 100644 --- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart +++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart @@ -368,7 +368,9 @@ class ConstantPropagationLattice { AbstractConstantValue negateSpecial(AbstractConstantValue value) { AbstractConstantValue folded = foldUnary(constantSystem.negate, value); if (folded != null) return folded; - if (isDefinitelyInt(value)) return nonConstant(typeSystem.intType); + if (isDefinitelyInt(value, allowNull: true)) { + return nonConstant(typeSystem.intType); + } return null; } @@ -385,7 +387,8 @@ class ConstantPropagationLattice { AbstractConstantValue closedOnInt(AbstractConstantValue left, AbstractConstantValue right) { - if (isDefinitelyInt(left) && isDefinitelyInt(right, allowNull: true)) { + if (isDefinitelyInt(left, allowNull: true) && + isDefinitelyInt(right, allowNull: true)) { return nonConstant(typeSystem.intType); } return null; @@ -393,7 +396,8 @@ class ConstantPropagationLattice { AbstractConstantValue closedOnUint(AbstractConstantValue left, AbstractConstantValue right) { - if (isDefinitelyUint(left) && isDefinitelyUint(right, allowNull: true)) { + if (isDefinitelyUint(left, allowNull: true) && + isDefinitelyUint(right, allowNull: true)) { return nonConstant(typeSystem.uintType); } return null; @@ -401,7 +405,8 @@ class ConstantPropagationLattice { AbstractConstantValue closedOnUint31(AbstractConstantValue left, AbstractConstantValue right) { - if (isDefinitelyUint31(left) && isDefinitelyUint31(right, allowNull: true)) { + if (isDefinitelyUint31(left, allowNull: true) && + isDefinitelyUint31(right, allowNull: true)) { return nonConstant(typeSystem.uint31Type); } return null; @@ -411,8 +416,8 @@ class ConstantPropagationLattice { AbstractConstantValue right) { AbstractConstantValue folded = foldBinary(constantSystem.add, left, right); if (folded != null) return folded; - if (isDefinitelyNum(left)) { - if (isDefinitelyUint31(left) && + if (isDefinitelyNum(left, allowNull: true)) { + if (isDefinitelyUint31(left, allowNull: true) && isDefinitelyUint31(right, allowNull: true)) { return nonConstant(typeSystem.uint32Type); } @@ -445,15 +450,22 @@ class ConstantPropagationLattice { AbstractConstantValue folded = foldBinary(constantSystem.truncatingDivide, left, right); if (folded != null) return folded; - if (isDefinitelyNum(left)) { - if (isDefinitelyUint32(left) && isDefinitelyIntInRange(right, min: 2)) { + if (isDefinitelyNum(left, allowNull: true)) { + if (isDefinitelyUint32(left, allowNull: true) && + isDefinitelyIntInRange(right, min: 2)) { return nonConstant(typeSystem.uint31Type); } if (isDefinitelyUint(right, allowNull: true)) { // `0` will be an exception, other values will shrink the result. - if (isDefinitelyUint31(left)) return nonConstant(typeSystem.uint31Type); - if (isDefinitelyUint32(left)) return nonConstant(typeSystem.uint32Type); - if (isDefinitelyUint(left)) return nonConstant(typeSystem.uintType); + if (isDefinitelyUint31(left, allowNull: true)) { + return nonConstant(typeSystem.uint31Type); + } + if (isDefinitelyUint32(left, allowNull: true)) { + return nonConstant(typeSystem.uint32Type); + } + if (isDefinitelyUint(left, allowNull: true)) { + return nonConstant(typeSystem.uintType); + } } return nonConstant(typeSystem.intType); } @@ -499,8 +511,8 @@ class ConstantPropagationLattice { AbstractConstantValue folded = foldBinary(constantSystem.bitAnd, left, right); if (folded != null) return folded; - if (isDefinitelyNum(left)) { - if (isDefinitelyUint31(left) || + if (isDefinitelyNum(left, allowNull: true)) { + if (isDefinitelyUint31(left, allowNull: true) || isDefinitelyUint31(right, allowNull: true)) { // Either 31-bit argument will truncate the other. return nonConstant(typeSystem.uint31Type); @@ -533,9 +545,9 @@ class ConstantPropagationLattice { AbstractConstantValue folded = foldBinary(constantSystem.shiftRight, left, right); if (folded != null) return folded; - if (isDefinitelyUint31(left)) { + if (isDefinitelyUint31(left, allowNull: true)) { return nonConstant(typeSystem.uint31Type); - } else if (isDefinitelyUint32(left)) { + } else if (isDefinitelyUint32(left, allowNull: true)) { if (isDefinitelyIntInRange(right, min: 1, max: 31)) { // A zero will be shifted into the 'sign' bit. return nonConstant(typeSystem.uint31Type); @@ -626,6 +638,8 @@ class ConstantPropagationLattice { TypeMask type = typeSystem.indexWithConstant(left.type, index); if (type != null) return nonConstant(type); } + // TODO(asgerf): Handle case where 'left' is a List or Map constant but + // the index is unknown. return null; // The caller will use return type from type inference. } @@ -2828,8 +2842,13 @@ class TypePropagationVisitor implements Visitor { } void visitInvokeMethodDirectly(InvokeMethodDirectly node) { - // TODO(karlklose): lookup the function and get ites return type. - setResult(node, nonConstant()); + if (node.isConstructorBodyCall) { + setResult(node, lattice.nullValue); + } else if (node.isTearOff) { + setResult(node, nonConstant(typeSystem.functionType)); + } else { + setResult(node, nonConstant(typeSystem.getReturnType(node.target))); + } } void visitInvokeConstructor(InvokeConstructor node) { @@ -3227,18 +3246,26 @@ class ResetAnalysisInfo extends TrampolineRecursiveVisitor { ResetAnalysisInfo(this.reachableContinuations, this.values); + void clear(Variable variable) { + variable.type = null; + values[variable] = null; + } + + processFunctionDefinition(FunctionDefinition node) { + clear(node.returnContinuation.parameters.single); + node.parameters.forEach(clear); + } + processContinuation(Continuation cont) { reachableContinuations.remove(cont); - cont.parameters.forEach(values.remove); + cont.parameters.forEach(clear); } processLetPrim(LetPrim node) { - node.primitive.type = null; - values[node.primitive] = null; + clear(node.primitive); } processLetMutable(LetMutable node) { - node.variable.type = null; - values[node.variable] = null; + clear(node.variable); } } diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_4.js b/tests/compiler/dart2js/cps_ir/expected/operators_4.js index ccfc0a828df..837c082b3b2 100644 --- a/tests/compiler/dart2js/cps_ir/expected/operators_4.js +++ b/tests/compiler/dart2js/cps_ir/expected/operators_4.js @@ -13,10 +13,8 @@ function() { line = "true"; break L0; } - v0 = false; - } else - v0 = false; - line = v0 ? String(v0) : "false"; + } + line = "false"; } if (typeof dartPrint == "function") dartPrint(line);