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 61c92001b092648d45cca2ac759f1679e633227b..718804384fd8d58017f93363b11dba8e2997099e 100644 |
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
@@ -30,6 +30,8 @@ import '../resolution/operators.dart'; |
import '../resolution/send_structure.dart'; |
import '../tree/tree.dart' as ast; |
import '../types/types.dart'; |
+import '../types/abstract_value_domain.dart' show |
+ AbstractBool; |
import '../universe/selector.dart' show |
Selector; |
import '../world.dart' show World; |
@@ -41,31 +43,31 @@ class ConstantPropagationLattice { |
final TypeMaskSystem typeSystem; |
final ConstantSystem constantSystem; |
final types.DartTypes dartTypes; |
- final AbstractValue anything; |
- final AbstractValue nullValue; |
+ final AbstractConstantValue anything; |
sra1
2015/12/02 17:42:24
I find 'AbstractConstantValue' confusing. The abs
|
+ final AbstractConstantValue nullValue; |
ConstantPropagationLattice(TypeMaskSystem typeSystem, |
this.constantSystem, |
this.dartTypes) |
: this.typeSystem = typeSystem, |
- anything = new AbstractValue.nonConstant(typeSystem.dynamicType), |
- nullValue = new AbstractValue.constantValue( |
+ anything = new AbstractConstantValue.nonConstant(typeSystem.dynamicType), |
+ nullValue = new AbstractConstantValue.constantValue( |
new NullConstantValue(), new TypeMask.empty()); |
- final AbstractValue nothing = new AbstractValue.nothing(); |
+ final AbstractConstantValue nothing = new AbstractConstantValue.nothing(); |
- AbstractValue constant(ConstantValue value, [TypeMask type]) { |
+ AbstractConstantValue constant(ConstantValue value, [TypeMask type]) { |
if (type == null) type = typeSystem.getTypeOf(value); |
- return new AbstractValue.constantValue(value, type); |
+ return new AbstractConstantValue.constantValue(value, type); |
} |
- AbstractValue nonConstant([TypeMask type]) { |
+ AbstractConstantValue nonConstant([TypeMask type]) { |
if (type == null) type = typeSystem.dynamicType; |
- return new AbstractValue.nonConstant(type); |
+ return new AbstractConstantValue.nonConstant(type); |
} |
/// Compute the join of two values in the lattice. |
- AbstractValue join(AbstractValue x, AbstractValue y) { |
+ AbstractConstantValue join(AbstractConstantValue x, AbstractConstantValue y) { |
assert(x != null); |
assert(y != null); |
@@ -76,36 +78,39 @@ class ConstantPropagationLattice { |
} else if (x.isConstant && y.isConstant && x.constant == y.constant) { |
return x; |
} else { |
- return new AbstractValue.nonConstant(typeSystem.join(x.type, y.type)); |
+ return new AbstractConstantValue.nonConstant( |
+ typeSystem.join(x.type, y.type)); |
} |
} |
/// True if all members of this value are booleans. |
- bool isDefinitelyBool(AbstractValue value, {bool allowNull: false}) { |
+ bool isDefinitelyBool(AbstractConstantValue value, {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyBool(value.type, allowNull: allowNull); |
} |
/// True if all members of this value are numbers. |
- bool isDefinitelyNum(AbstractValue value, {bool allowNull: false}) { |
+ bool isDefinitelyNum(AbstractConstantValue value, {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyNum(value.type, allowNull: allowNull); |
} |
/// True if all members of this value are strings. |
- bool isDefinitelyString(AbstractValue value, {bool allowNull: false}) { |
+ bool isDefinitelyString(AbstractConstantValue value, |
+ {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyString(value.type, allowNull: allowNull); |
} |
/// True if all members of this value are numbers, strings, or booleans. |
- bool isDefinitelyNumStringBool(AbstractValue value, {bool allowNull: false}) { |
+ bool isDefinitelyNumStringBool(AbstractConstantValue value, |
+ {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyNumStringBool(value.type, allowNull: allowNull); |
} |
/// True if this value cannot be a string, number, or boolean. |
- bool isDefinitelyNotNumStringBool(AbstractValue value) { |
+ bool isDefinitelyNotNumStringBool(AbstractConstantValue value) { |
return value.isNothing || |
typeSystem.isDefinitelyNotNumStringBool(value.type); |
} |
@@ -114,71 +119,72 @@ class ConstantPropagationLattice { |
/// |
/// In other words, if true is returned, and the value is a number, then |
/// it is a whole number and is not NaN, Infinity, or minus Infinity. |
- bool isDefinitelyNotNonIntegerDouble(AbstractValue value) { |
+ bool isDefinitelyNotNonIntegerDouble(AbstractConstantValue value) { |
return value.isNothing || |
value.isConstant && !value.constant.isDouble || |
typeSystem.isDefinitelyNotNonIntegerDouble(value.type); |
} |
- bool isDefinitelyInt(AbstractValue value, |
+ bool isDefinitelyInt(AbstractConstantValue value, |
{bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyInt(value.type, allowNull: allowNull); |
} |
- bool isDefinitelyUint31(AbstractValue value, |
- {bool allowNull: false}) { |
+ bool isDefinitelyUint31(AbstractConstantValue value, |
+ {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyUint31(value.type, allowNull: allowNull); |
} |
- bool isDefinitelyUint32(AbstractValue value, |
- {bool allowNull: false}) { |
+ bool isDefinitelyUint32(AbstractConstantValue value, |
+ {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyUint32(value.type, allowNull: allowNull); |
} |
- bool isDefinitelyUint(AbstractValue value, |
+ bool isDefinitelyUint(AbstractConstantValue value, |
{bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyUint(value.type, allowNull: allowNull); |
} |
- bool isDefinitelyArray(AbstractValue value, |
+ bool isDefinitelyArray(AbstractConstantValue value, |
{bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyArray(value.type, allowNull: allowNull); |
} |
- bool isDefinitelyMutableArray(AbstractValue value, |
+ bool isDefinitelyMutableArray(AbstractConstantValue value, |
{bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyMutableArray(value.type, |
allowNull: allowNull); |
} |
- bool isDefinitelyFixedArray(AbstractValue value, |
- {bool allowNull: false}) { |
+ bool isDefinitelyFixedArray(AbstractConstantValue value, |
+ {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyFixedArray(value.type, |
- allowNull: allowNull); |
+ allowNull: allowNull); |
} |
- bool isDefinitelyExtendableArray(AbstractValue value, |
- {bool allowNull: false}) { |
+ bool isDefinitelyExtendableArray(AbstractConstantValue value, |
+ {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyExtendableArray(value.type, |
- allowNull: allowNull); |
+ allowNull: allowNull); |
} |
- bool isDefinitelyIndexable(AbstractValue value, {bool allowNull: false}) { |
+ bool isDefinitelyIndexable(AbstractConstantValue value, |
+ {bool allowNull: false}) { |
return value.isNothing || |
typeSystem.isDefinitelyIndexable(value.type, allowNull: allowNull); |
} |
/// Returns `true` if [value] represents an int value that must be in the |
/// inclusive range. |
- bool isDefinitelyIntInRange(AbstractValue value, {int min, int max}) { |
+ bool isDefinitelyIntInRange(AbstractConstantValue value, {int min, int max}) { |
if (value.isNothing) return true; |
if (!isDefinitelyInt(value)) return false; |
PrimitiveConstantValue constant = value.constant; |
@@ -199,7 +205,7 @@ class ConstantPropagationLattice { |
/// If [allowNull] is true, `null` is considered an instance of anything, |
/// otherwise it is only considered an instance of [Object], [dynamic], and |
/// [Null]. |
- AbstractBool isSubtypeOf(AbstractValue value, |
+ AbstractBool isSubtypeOf(AbstractConstantValue value, |
types.DartType type, |
{bool allowNull}) { |
assert(allowNull != null); |
@@ -245,7 +251,8 @@ class ConstantPropagationLattice { |
/// |
/// This method returns `null` if a good result could not be found. In that |
/// case, it is best to fall back on interprocedural type information. |
- AbstractValue unaryOp(UnaryOperator operator, AbstractValue value) { |
+ AbstractConstantValue unaryOp(UnaryOperator operator, |
+ AbstractConstantValue value) { |
switch (operator.kind) { |
case UnaryOperatorKind.COMPLEMENT: |
return bitNotSpecial(value); |
@@ -276,9 +283,9 @@ class ConstantPropagationLattice { |
/// |
/// This method returns `null` if a good result could not be found. In that |
/// case, it is best to fall back on interprocedural type information. |
- AbstractValue binaryOp(BinaryOperator operator, |
- AbstractValue left, |
- AbstractValue right) { |
+ AbstractConstantValue binaryOp(BinaryOperator operator, |
+ AbstractConstantValue left, |
+ AbstractConstantValue right) { |
switch (operator.kind) { |
case BinaryOperatorKind.ADD: |
return addSpecial(left, right); |
@@ -343,7 +350,8 @@ class ConstantPropagationLattice { |
return null; // The caller will use return type from type inference. |
} |
- AbstractValue foldUnary(UnaryOperation operation, AbstractValue value) { |
+ AbstractConstantValue foldUnary(UnaryOperation operation, |
+ AbstractConstantValue value) { |
if (value.isNothing) return nothing; |
if (value.isConstant) { |
ConstantValue result = operation.fold(value.constant); |
@@ -352,20 +360,20 @@ class ConstantPropagationLattice { |
return null; |
} |
- AbstractValue bitNotSpecial(AbstractValue value) { |
+ AbstractConstantValue bitNotSpecial(AbstractConstantValue value) { |
return foldUnary(constantSystem.bitNot, value); |
} |
- AbstractValue negateSpecial(AbstractValue value) { |
- AbstractValue folded = foldUnary(constantSystem.negate, value); |
+ AbstractConstantValue negateSpecial(AbstractConstantValue value) { |
+ AbstractConstantValue folded = foldUnary(constantSystem.negate, value); |
if (folded != null) return folded; |
if (isDefinitelyInt(value)) return nonConstant(typeSystem.intType); |
return null; |
} |
- AbstractValue foldBinary(BinaryOperation operation, |
- AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue foldBinary(BinaryOperation operation, |
+ AbstractConstantValue left, AbstractConstantValue right) { |
if (left.isNothing || right.isNothing) return nothing; |
if (left.isConstant && right.isConstant) { |
ConstantValue result = operation.fold(left.constant, right.constant); |
@@ -374,29 +382,33 @@ class ConstantPropagationLattice { |
return null; |
} |
- AbstractValue closedOnInt(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue closedOnInt(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
if (isDefinitelyInt(left) && isDefinitelyInt(right)) { |
return nonConstant(typeSystem.intType); |
} |
return null; |
} |
- AbstractValue closedOnUint(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue closedOnUint(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
if (isDefinitelyUint(left) && isDefinitelyUint(right)) { |
return nonConstant(typeSystem.uintType); |
} |
return null; |
} |
- AbstractValue closedOnUint31(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue closedOnUint31(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
if (isDefinitelyUint31(left) && isDefinitelyUint31(right)) { |
return nonConstant(typeSystem.uint31Type); |
} |
return null; |
} |
- AbstractValue addSpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.add, left, right); |
+ AbstractConstantValue addSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = foldBinary(constantSystem.add, left, right); |
if (folded != null) return folded; |
if (isDefinitelyNum(left)) { |
if (isDefinitelyUint31(left) && isDefinitelyUint31(right)) { |
@@ -407,23 +419,28 @@ class ConstantPropagationLattice { |
return null; |
} |
- AbstractValue subtractSpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.subtract, left, right); |
+ AbstractConstantValue subtractSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
+ foldBinary(constantSystem.subtract, left, right); |
return folded ?? closedOnInt(left, right); |
} |
- AbstractValue multiplySpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.multiply, left, right); |
+ AbstractConstantValue multiplySpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
+ foldBinary(constantSystem.multiply, left, right); |
return folded ?? closedOnUint(left, right) ?? closedOnInt(left, right); |
} |
- AbstractValue divideSpecial(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue divideSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
return foldBinary(constantSystem.divide, left, right); |
} |
- AbstractValue truncatingDivideSpecial( |
- AbstractValue left, AbstractValue right) { |
- AbstractValue folded = |
+ AbstractConstantValue truncatingDivideSpecial( |
+ AbstractConstantValue left, AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
foldBinary(constantSystem.truncatingDivide, left, right); |
if (folded != null) return folded; |
if (isDefinitelyNum(left)) { |
@@ -441,19 +458,24 @@ class ConstantPropagationLattice { |
return null; |
} |
- AbstractValue moduloSpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.modulo, left, right); |
+ AbstractConstantValue moduloSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
+ foldBinary(constantSystem.modulo, left, right); |
return folded ?? closedOnUint(left, right) ?? closedOnInt(left, right); |
} |
- AbstractValue remainderSpecial(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue remainderSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
if (left.isNothing || right.isNothing) return nothing; |
- AbstractValue folded = null; // Remainder not in constant system. |
+ AbstractConstantValue folded = null; // Remainder not in constant system. |
return folded ?? closedOnUint(left, right) ?? closedOnInt(left, right); |
} |
- AbstractValue equalSpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.equal, left, right); |
+ AbstractConstantValue equalSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
+ foldBinary(constantSystem.equal, left, right); |
if (folded != null) return folded; |
bool behavesLikeIdentity = |
isDefinitelyNumStringBool(left, allowNull: true) || |
@@ -465,8 +487,10 @@ class ConstantPropagationLattice { |
return null; |
} |
- AbstractValue andSpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.bitAnd, left, right); |
+ AbstractConstantValue andSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
+ foldBinary(constantSystem.bitAnd, left, right); |
if (folded != null) return folded; |
if (isDefinitelyNum(left)) { |
if (isDefinitelyUint31(left) || isDefinitelyUint31(right)) { |
@@ -477,22 +501,29 @@ class ConstantPropagationLattice { |
return null; |
} |
- AbstractValue orSpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.bitOr, left, right); |
+ AbstractConstantValue orSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
+ foldBinary(constantSystem.bitOr, left, right); |
return folded ?? closedOnUint31(left, right); |
} |
- AbstractValue xorSpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.bitXor, left, right); |
+ AbstractConstantValue xorSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
+ foldBinary(constantSystem.bitXor, left, right); |
return folded ?? closedOnUint31(left, right); |
} |
- AbstractValue shiftLeftSpecial(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue shiftLeftSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
return foldBinary(constantSystem.shiftLeft, left, right); |
} |
- AbstractValue shiftRightSpecial(AbstractValue left, AbstractValue right) { |
- AbstractValue folded = foldBinary(constantSystem.shiftRight, left, right); |
+ AbstractConstantValue shiftRightSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
+ AbstractConstantValue folded = |
+ foldBinary(constantSystem.shiftRight, left, right); |
if (folded != null) return folded; |
if (isDefinitelyUint31(left)) { |
return nonConstant(typeSystem.uint31Type); |
@@ -506,27 +537,31 @@ class ConstantPropagationLattice { |
return null; |
} |
- AbstractValue lessSpecial(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue lessSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
return foldBinary(constantSystem.less, left, right); |
} |
- AbstractValue lessEqualSpecial(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue lessEqualSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
return foldBinary(constantSystem.lessEqual, left, right); |
} |
- AbstractValue greaterSpecial(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue greaterSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
return foldBinary(constantSystem.greater, left, right); |
} |
- AbstractValue greaterEqualSpecial(AbstractValue left, AbstractValue right) { |
+ AbstractConstantValue greaterEqualSpecial(AbstractConstantValue left, |
+ AbstractConstantValue right) { |
return foldBinary(constantSystem.greaterEqual, left, right); |
} |
- AbstractValue intConstant(int value) { |
+ AbstractConstantValue intConstant(int value) { |
return constant(new IntConstantValue(value)); |
} |
- AbstractValue lengthSpecial(AbstractValue input) { |
+ AbstractConstantValue lengthSpecial(AbstractConstantValue input) { |
if (input.isConstant) { |
ConstantValue constant = input.constant; |
if (constant is StringConstantValue) { |
@@ -542,11 +577,11 @@ class ConstantPropagationLattice { |
return null; // The caller will use return type from type inference. |
} |
- AbstractValue stringConstant(String value) { |
+ AbstractConstantValue stringConstant(String value) { |
return constant(new StringConstantValue(new ast.DartString.literal(value))); |
} |
- AbstractValue stringify(AbstractValue value) { |
+ AbstractConstantValue stringify(AbstractConstantValue value) { |
if (value.isNothing) return nothing; |
if (value.isNonConst) return nonConstant(typeSystem.stringType); |
ConstantValue constantValue = value.constant; |
@@ -564,7 +599,7 @@ class ConstantPropagationLattice { |
/// Returns whether [value] is one of the falsy values: false, 0, -0, NaN, |
/// the empty string, or null. |
- AbstractBool boolify(AbstractValue value) { |
+ AbstractBool boolify(AbstractConstantValue value) { |
if (value.isNothing) return AbstractBool.Nothing; |
if (value.isConstant) { |
ConstantValue constantValue = value.constant; |
@@ -578,7 +613,7 @@ class ConstantPropagationLattice { |
} |
/// Returns whether [value] is the value `true`. |
- AbstractBool strictBoolify(AbstractValue value) { |
+ AbstractBool strictBoolify(AbstractConstantValue value) { |
if (value.isNothing) return AbstractBool.Nothing; |
if (value.isConstant) { |
return value.constant.isTrue ? AbstractBool.True : AbstractBool.False; |
@@ -589,11 +624,11 @@ class ConstantPropagationLattice { |
/// The possible return types of a method that may be targeted by |
/// [typedSelector]. If the given selector is not a [TypedSelector], any |
/// reachable method matching the selector may be targeted. |
- AbstractValue getInvokeReturnType(Selector selector, TypeMask mask) { |
+ AbstractConstantValue getInvokeReturnType(Selector selector, TypeMask mask) { |
return fromMask(typeSystem.getInvokeReturnType(selector, mask)); |
} |
- AbstractValue fromMask(TypeMask mask) { |
+ AbstractConstantValue fromMask(TypeMask mask) { |
ConstantValue constantValue = typeSystem.getConstantOf(mask); |
if (constantValue != null) return constant(constantValue, mask); |
return nonConstant(mask); |
@@ -745,7 +780,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
// Try to constant-fold the primitive. |
if (prim is! Constant && prim is! Refinement && prim.isSafeForElimination) { |
- AbstractValue value = getValue(prim); |
+ AbstractConstantValue value = getValue(prim); |
if (value.isConstant) { |
prim.replaceWith(makeConstantPrimitive(value.constant)); |
push(node.body); |
@@ -911,7 +946,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
Continuation trueCont = node.trueContinuation.definition; |
Continuation falseCont = node.falseContinuation.definition; |
Primitive condition = node.condition.definition; |
- AbstractValue conditionValue = getValue(condition); |
+ AbstractConstantValue conditionValue = getValue(condition); |
// Change to non-strict check if the condition is a boolean or null. |
if (lattice.isDefinitelyBool(conditionValue, allowNull: true)) { |
@@ -942,8 +977,8 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
condition.operator == BuiltinOperator.StrictEq)) { |
Primitive leftArg = condition.arguments[0].definition; |
Primitive rightArg = condition.arguments[1].definition; |
- AbstractValue left = getValue(leftArg); |
- AbstractValue right = getValue(rightArg); |
+ AbstractConstantValue left = getValue(leftArg); |
+ AbstractConstantValue right = getValue(rightArg); |
if (right.isNullConstant && |
lattice.isDefinitelyNotNumStringBool(left)) { |
// Rewrite: |
@@ -1033,8 +1068,8 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
if (node.selector.isOperator && node.arguments.length == 2) { |
Primitive leftArg = node.dartReceiver; |
Primitive rightArg = node.dartArgument(0); |
- AbstractValue left = getValue(leftArg); |
- AbstractValue right = getValue(rightArg); |
+ AbstractConstantValue left = getValue(leftArg); |
+ AbstractConstantValue right = getValue(rightArg); |
String opname = node.selector.name; |
if (opname == '==') { |
@@ -1114,7 +1149,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
} |
if (node.selector.isOperator && node.arguments.length == 1) { |
Primitive argument = node.dartReceiver; |
- AbstractValue value = getValue(argument); |
+ AbstractConstantValue value = getValue(argument); |
if (lattice.isDefinitelyNum(value, allowNull: false)) { |
String opname = node.selector.name; |
@@ -1129,11 +1164,11 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
if (node.selector.isCall) { |
String name = node.selector.name; |
Primitive receiver = node.dartReceiver; |
- AbstractValue receiverValue = getValue(receiver); |
+ AbstractConstantValue receiverValue = getValue(receiver); |
if (name == 'remainder') { |
if (node.arguments.length == 2) { |
Primitive arg = node.dartArgument(0); |
- AbstractValue argValue = getValue(arg); |
+ AbstractConstantValue argValue = getValue(arg); |
if (lattice.isDefinitelyInt(receiverValue) && |
lattice.isDefinitelyInt(argValue) && |
isIntNotZero(argValue)) { |
@@ -1147,7 +1182,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
} |
/// Returns `true` if [value] represents an int value that cannot be zero. |
- bool isIntNotZero(AbstractValue value) { |
+ bool isIntNotZero(AbstractConstantValue value) { |
return lattice.isDefinitelyIntInRange(value, min: 1) || |
lattice.isDefinitelyIntInRange(value, max: -1); |
} |
@@ -1162,7 +1197,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
/// Returns `true` if the node was replaced. |
Primitive specializeFieldAccess(InvokeMethod node) { |
if (!node.selector.isGetter && !node.selector.isSetter) return null; |
- AbstractValue receiver = getValue(node.dartReceiver); |
+ AbstractConstantValue receiver = getValue(node.dartReceiver); |
Element target = |
typeSystem.locateSingleElement(receiver.type, node.selector); |
if (target is! FieldElement) return null; |
@@ -1233,7 +1268,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
/// Returns `true` if the node was replaced. |
specializeIndexableAccess(InvokeMethod node) { |
Primitive receiver = node.dartReceiver; |
- AbstractValue receiverValue = getValue(receiver); |
+ AbstractConstantValue receiverValue = getValue(receiver); |
if (!typeSystem.isDefinitelyIndexable(receiverValue.type, |
allowNull: true)) { |
return null; |
@@ -1250,7 +1285,8 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo); |
GetIndex get = cps.letPrim(new GetIndex(receiver, index)); |
node.replaceUsesWith(get); |
- get.hint = node.hint; // TODO(asgerf): Make replaceUsesWith set the hint? |
+ // TODO(asgerf): Make replaceUsesWith set the hint? |
+ get.hint = node.hint; |
return cps; |
case '[]=': |
@@ -1276,7 +1312,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
/// Returns `true` if the node was replaced. |
CpsFragment specializeArrayAccess(InvokeMethod node) { |
Primitive list = node.dartReceiver; |
- AbstractValue listValue = getValue(list); |
+ AbstractConstantValue listValue = getValue(list); |
// Ensure that the object is a native list or null. |
if (!lattice.isDefinitelyArray(listValue, allowNull: true)) { |
return null; |
@@ -1745,7 +1781,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
node.mask = |
typeSystem.intersection(node.mask, getValue(node.dartReceiver).type); |
- AbstractValue receiver = getValue(node.receiver.definition); |
+ AbstractConstantValue receiver = getValue(node.receiver.definition); |
if (node.callingConvention == CallingConvention.Intercepted && |
node.receiver.definition.sameValue(node.arguments[0].definition)) { |
@@ -1775,7 +1811,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
} |
CpsFragment visitTypeCast(TypeCast node) { |
- AbstractValue value = getValue(node.value.definition); |
+ AbstractConstantValue value = getValue(node.value.definition); |
switch (lattice.isSubtypeOf(value, node.dartType, allowNull: true)) { |
case AbstractBool.Maybe: |
case AbstractBool.Nothing: |
@@ -1796,7 +1832,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
/// Specialize calls to internal static methods. |
specializeInternalMethodCall(InvokeStatic node) { |
if (node.target == backend.helpers.stringInterpolationHelper) { |
- AbstractValue value = getValue(node.arguments[0].definition); |
+ AbstractConstantValue value = getValue(node.arguments[0].definition); |
if (lattice.isDefinitelyString(value)) { |
node.replaceUsesWith(node.arguments[0].definition); |
return new CpsFragment(); |
@@ -1901,13 +1937,13 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
return specializeInternalMethodCall(node) ?? inlineInvokeStatic(node); |
} |
- AbstractValue getValue(Variable node) { |
+ AbstractConstantValue getValue(Variable node) { |
ConstantValue constant = values[node]; |
if (constant != null) { |
- return new AbstractValue.constantValue(constant, node.type); |
+ return new AbstractConstantValue.constantValue(constant, node.type); |
} |
if (node.type != null) { |
- return new AbstractValue.nonConstant(node.type); |
+ return new AbstractConstantValue.nonConstant(node.type); |
} |
return lattice.nothing; |
} |
@@ -1927,7 +1963,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
// |
void visitApplyBuiltinOperator(ApplyBuiltinOperator node) { |
- ast.DartString getString(AbstractValue value) { |
+ ast.DartString getString(AbstractConstantValue value) { |
StringConstantValue constant = value.constant; |
return constant.primitiveValue; |
} |
@@ -1938,9 +1974,11 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
int i = 0; |
while (i < node.arguments.length - 1) { |
int startOfSequence = i; |
- AbstractValue firstValue = getValue(node.arguments[i++].definition); |
+ AbstractConstantValue firstValue = |
+ getValue(node.arguments[i++].definition); |
if (!firstValue.isConstant) continue; |
- AbstractValue secondValue = getValue(node.arguments[i++].definition); |
+ AbstractConstantValue secondValue = |
+ getValue(node.arguments[i++].definition); |
if (!secondValue.isConstant) continue; |
ast.DartString string = |
@@ -1950,7 +1988,8 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
// We found a sequence of at least two constants. |
// Look for the end of the sequence. |
while (i < node.arguments.length) { |
- AbstractValue value = getValue(node.arguments[i].definition); |
+ AbstractConstantValue value = |
+ getValue(node.arguments[i].definition); |
if (!value.isConstant) break; |
string = new ast.ConsDartString(string, getString(value)); |
++i; |
@@ -1976,8 +2015,8 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
case BuiltinOperator.Identical: |
Primitive leftArg = node.arguments[0].definition; |
Primitive rightArg = node.arguments[1].definition; |
- AbstractValue left = getValue(leftArg); |
- AbstractValue right = getValue(rightArg); |
+ AbstractConstantValue left = getValue(leftArg); |
+ AbstractConstantValue right = getValue(rightArg); |
if (lattice.isDefinitelyBool(left) && |
right.isConstant && |
right.constant.isTrue) { |
@@ -2033,7 +2072,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
} |
} |
- AbstractValue value = getValue(prim); |
+ AbstractConstantValue value = getValue(prim); |
types.DartType dartType = node.dartType; |
if (!(dartType.isInterfaceType && dartType.isRaw)) { |
@@ -2126,7 +2165,7 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
} |
Primitive visitInterceptor(Interceptor node) { |
- AbstractValue value = getValue(node.input.definition); |
+ AbstractConstantValue value = getValue(node.input.definition); |
TypeMask interceptedInputs = value.type.intersection( |
typeSystem.interceptorType.nullable(), classWorld); |
bool interceptNull = |
@@ -2311,11 +2350,13 @@ class TypePropagationVisitor implements Visitor { |
World get classWorld => typeSystem.classWorld; |
- AbstractValue get nothing => lattice.nothing; |
+ AbstractConstantValue get nothing => lattice.nothing; |
- AbstractValue nonConstant([TypeMask type]) => lattice.nonConstant(type); |
+ AbstractConstantValue nonConstant([TypeMask type]) { |
+ return lattice.nonConstant(type); |
+ } |
- AbstractValue constantValue(ConstantValue constant, [TypeMask type]) { |
+ AbstractConstantValue constantValue(ConstantValue constant, [TypeMask type]) { |
return lattice.constant(constant, type); |
} |
@@ -2380,13 +2421,13 @@ class TypePropagationVisitor implements Visitor { |
/// Returns the lattice value corresponding to [node], defaulting to nothing. |
/// |
/// Never returns null. |
- AbstractValue getValue(Variable node) { |
+ AbstractConstantValue getValue(Variable node) { |
ConstantValue constant = values[node]; |
if (constant != null) { |
- return new AbstractValue.constantValue(constant, node.type); |
+ return new AbstractConstantValue.constantValue(constant, node.type); |
} |
if (node.type != null) { |
- return new AbstractValue.nonConstant(node.type); |
+ return new AbstractConstantValue.nonConstant(node.type); |
} |
return lattice.nothing; |
} |
@@ -2394,9 +2435,9 @@ class TypePropagationVisitor implements Visitor { |
/// Joins the passed lattice [updateValue] to the current value of [node], |
/// and adds it to the definition work set if it has changed and [node] is |
/// a definition. |
- void setValue(Variable node, AbstractValue updateValue) { |
- AbstractValue oldValue = getValue(node); |
- AbstractValue newValue = lattice.join(oldValue, updateValue); |
+ void setValue(Variable node, AbstractConstantValue updateValue) { |
+ AbstractConstantValue oldValue = getValue(node); |
+ AbstractConstantValue newValue = lattice.join(oldValue, updateValue); |
node.type = newValue.type; // Ensure type is initialized even if bottom. |
if (oldValue == newValue) { |
return; |
@@ -2414,7 +2455,7 @@ class TypePropagationVisitor implements Visitor { |
/// If [updateValue] is a constant and [canReplace] is true, the primitive |
/// is also marked as safe for elimination, so it can be constant-folded. |
void setResult(UnsafePrimitive prim, |
- AbstractValue updateValue, |
+ AbstractConstantValue updateValue, |
{bool canReplace: false}) { |
// TODO(asgerf): Separate constant folding from side effect analysis. |
setValue(prim, updateValue); |
@@ -2488,7 +2529,7 @@ class TypePropagationVisitor implements Visitor { |
void visitInvokeStatic(InvokeStatic node) { |
if (node.target == backend.helpers.stringInterpolationHelper) { |
- AbstractValue argValue = getValue(node.arguments[0].definition); |
+ AbstractConstantValue argValue = getValue(node.arguments[0].definition); |
setResult(node, lattice.stringify(argValue), canReplace: true); |
return; |
} |
@@ -2505,13 +2546,13 @@ class TypePropagationVisitor implements Visitor { |
// continuation. Note that this is effectively a phi node in SSA terms. |
for (int i = 0; i < node.arguments.length; i++) { |
Primitive def = node.arguments[i].definition; |
- AbstractValue cell = getValue(def); |
+ AbstractConstantValue cell = getValue(def); |
setValue(cont.parameters[i], cell); |
} |
} |
void visitInvokeMethod(InvokeMethod node) { |
- AbstractValue receiver = getValue(node.receiver.definition); |
+ AbstractConstantValue receiver = getValue(node.receiver.definition); |
node.receiverIsNotNull = receiver.isDefinitelyNotNull; |
if (receiver.isNothing) { |
setResult(node, lattice.nothing); |
@@ -2520,9 +2561,9 @@ class TypePropagationVisitor implements Visitor { |
// Constant fold known length of containers. |
if (node.selector == Selectors.length) { |
- AbstractValue object = getValue(node.dartReceiver); |
+ AbstractConstantValue object = getValue(node.dartReceiver); |
if (typeSystem.isDefinitelyIndexable(object.type, allowNull: true)) { |
- AbstractValue length = lattice.lengthSpecial(object); |
+ AbstractConstantValue length = lattice.lengthSpecial(object); |
if (length != null) { |
setResult(node, length, canReplace: !object.isNullable); |
} |
@@ -2535,10 +2576,10 @@ class TypePropagationVisitor implements Visitor { |
} |
// Calculate the resulting constant if possible. |
- AbstractValue result; |
+ AbstractConstantValue result; |
String opname = node.selector.name; |
if (node.arguments.length == 1) { |
- AbstractValue argument = getValue(node.dartReceiver); |
+ AbstractConstantValue argument = getValue(node.dartReceiver); |
// Unary operator. |
if (opname == "unary-") { |
opname = "-"; |
@@ -2547,8 +2588,8 @@ class TypePropagationVisitor implements Visitor { |
result = lattice.unaryOp(operator, argument); |
} else if (node.arguments.length == 2) { |
// Binary operator. |
- AbstractValue left = getValue(node.dartReceiver); |
- AbstractValue right = getValue(node.dartArgument(0)); |
+ AbstractConstantValue left = getValue(node.dartReceiver); |
+ AbstractConstantValue right = getValue(node.dartArgument(0)); |
BinaryOperator operator = BinaryOperator.parse(opname); |
result = lattice.binaryOp(operator, left, right); |
} |
@@ -2564,32 +2605,37 @@ class TypePropagationVisitor implements Visitor { |
void visitApplyBuiltinOperator(ApplyBuiltinOperator node) { |
- void unaryOp(AbstractValue operation(AbstractValue argument), |
- TypeMask defaultType) { |
- AbstractValue value = getValue(node.arguments[0].definition); |
+ void unaryOp( |
+ AbstractConstantValue operation(AbstractConstantValue argument), |
+ TypeMask defaultType) { |
+ AbstractConstantValue value = getValue(node.arguments[0].definition); |
setValue(node, operation(value) ?? nonConstant(defaultType)); |
} |
void binaryOp( |
- AbstractValue operation(AbstractValue left, AbstractValue right), |
+ AbstractConstantValue operation(AbstractConstantValue left, |
+ AbstractConstantValue right), |
TypeMask defaultType) { |
- AbstractValue left = getValue(node.arguments[0].definition); |
- AbstractValue right = getValue(node.arguments[1].definition); |
+ AbstractConstantValue left = getValue(node.arguments[0].definition); |
+ AbstractConstantValue right = getValue(node.arguments[1].definition); |
setValue(node, operation(left, right) ?? nonConstant(defaultType)); |
} |
void binaryNumOp( |
- AbstractValue operation(AbstractValue left, AbstractValue right)) { |
+ AbstractConstantValue operation(AbstractConstantValue left, |
+ AbstractConstantValue right)) { |
binaryOp(operation, typeSystem.numType); |
} |
void binaryUint32Op( |
- AbstractValue operation(AbstractValue left, AbstractValue right)) { |
+ AbstractConstantValue operation(AbstractConstantValue left, |
+ AbstractConstantValue right)) { |
binaryOp(operation, typeSystem.uint32Type); |
} |
void binaryBoolOp( |
- AbstractValue operation(AbstractValue left, AbstractValue right)) { |
+ AbstractConstantValue operation(AbstractConstantValue left, |
+ AbstractConstantValue right)) { |
binaryOp(operation, typeSystem.boolType); |
} |
@@ -2597,7 +2643,7 @@ class TypePropagationVisitor implements Visitor { |
case BuiltinOperator.StringConcatenate: |
ast.DartString stringValue = const ast.LiteralDartString(''); |
for (Reference<Primitive> arg in node.arguments) { |
- AbstractValue value = getValue(arg.definition); |
+ AbstractConstantValue value = getValue(arg.definition); |
if (value.isNothing) { |
setValue(node, lattice.nothing); |
return; // And come back later |
@@ -2622,8 +2668,10 @@ class TypePropagationVisitor implements Visitor { |
case BuiltinOperator.Identical: |
case BuiltinOperator.StrictEq: |
case BuiltinOperator.LooseEq: |
- AbstractValue leftConst = getValue(node.arguments[0].definition); |
- AbstractValue rightConst = getValue(node.arguments[1].definition); |
+ AbstractConstantValue leftConst = |
+ getValue(node.arguments[0].definition); |
+ AbstractConstantValue rightConst = |
+ getValue(node.arguments[1].definition); |
ConstantValue leftValue = leftConst.constant; |
ConstantValue rightValue = rightConst.constant; |
if (leftConst.isNothing || rightConst.isNothing) { |
@@ -2740,7 +2788,7 @@ class TypePropagationVisitor implements Visitor { |
} |
void visitApplyBuiltinMethod(ApplyBuiltinMethod node) { |
- AbstractValue receiver = getValue(node.receiver.definition); |
+ AbstractConstantValue receiver = getValue(node.receiver.definition); |
if (node.method == BuiltinMethod.Pop) { |
setValue(node, nonConstant( |
typeSystem.elementTypeOfIndexable(receiver.type))); |
@@ -2772,7 +2820,7 @@ class TypePropagationVisitor implements Visitor { |
} |
void visitBranch(Branch node) { |
- AbstractValue conditionCell = getValue(node.condition.definition); |
+ AbstractConstantValue conditionCell = getValue(node.condition.definition); |
AbstractBool boolifiedValue = node.isStrictCheck |
? lattice.strictBoolify(conditionCell) |
: lattice.boolify(conditionCell); |
@@ -2805,7 +2853,7 @@ class TypePropagationVisitor implements Visitor { |
} |
void handleTypeTest( |
- Primitive node, AbstractValue input, types.DartType dartType) { |
+ Primitive node, AbstractConstantValue input, types.DartType dartType) { |
TypeMask boolType = typeSystem.boolType; |
switch(lattice.isSubtypeOf(input, dartType, allowNull: false)) { |
case AbstractBool.Nothing: |
@@ -2826,7 +2874,7 @@ class TypePropagationVisitor implements Visitor { |
} |
void visitTypeCast(TypeCast node) { |
- AbstractValue input = getValue(node.value.definition); |
+ AbstractConstantValue input = getValue(node.value.definition); |
switch (lattice.isSubtypeOf(input, node.dartType, allowNull: true)) { |
case AbstractBool.Nothing: |
setValue(node, lattice.nothing); |
@@ -2916,7 +2964,7 @@ class TypePropagationVisitor implements Visitor { |
void visitInterceptor(Interceptor node) { |
push(node.input.definition); |
- AbstractValue value = getValue(node.input.definition); |
+ AbstractConstantValue value = getValue(node.input.definition); |
if (value.isNothing) { |
setValue(node, nothing); |
} else if (value.isNullable && |
@@ -2943,7 +2991,8 @@ class TypePropagationVisitor implements Visitor { |
} |
void visitCreateInstance(CreateInstance node) { |
- setValue(node, nonConstant(typeSystem.nonNullExact(node.classElement.declaration))); |
+ setValue(node, |
+ nonConstant(typeSystem.nonNullExact(node.classElement.declaration))); |
} |
void visitReifyRuntimeType(ReifyRuntimeType node) { |
@@ -2975,9 +3024,9 @@ class TypePropagationVisitor implements Visitor { |
@override |
void visitGetLength(GetLength node) { |
- AbstractValue input = getValue(node.object.definition); |
+ AbstractConstantValue input = getValue(node.object.definition); |
node.objectIsNotNull = input.isDefinitelyNotNull; |
- AbstractValue length = lattice.lengthSpecial(input); |
+ AbstractConstantValue length = lattice.lengthSpecial(input); |
if (length != null) { |
// TODO(asgerf): Constant-folding the length might degrade the VM's |
// own bounds-check elimination? |
@@ -2989,7 +3038,7 @@ class TypePropagationVisitor implements Visitor { |
@override |
void visitGetIndex(GetIndex node) { |
- AbstractValue input = getValue(node.object.definition); |
+ AbstractConstantValue input = getValue(node.object.definition); |
node.objectIsNotNull = input.isDefinitelyNotNull; |
setValue(node, nonConstant(typeSystem.elementTypeOfIndexable(input.type))); |
} |
@@ -3011,7 +3060,7 @@ class TypePropagationVisitor implements Visitor { |
@override |
void visitRefinement(Refinement node) { |
- AbstractValue value = getValue(node.value.definition); |
+ AbstractConstantValue value = getValue(node.value.definition); |
if (value.isNothing || |
typeSystem.areDisjoint(value.type, node.refineType)) { |
setValue(node, nothing); |
@@ -3033,7 +3082,7 @@ class TypePropagationVisitor implements Visitor { |
/// CONSTANT: is a constant. The value is stored in the [constant] field, |
/// and the type of the constant is in the [type] field. |
/// NONCONST: not a constant, but [type] may hold some information. |
-class AbstractValue { |
+class AbstractConstantValue { |
static const int NOTHING = 0; |
static const int CONSTANT = 1; |
static const int NONCONST = 2; |
@@ -3042,25 +3091,26 @@ class AbstractValue { |
final ConstantValue constant; |
final TypeMask type; |
- AbstractValue._internal(this.kind, this.constant, this.type) { |
+ AbstractConstantValue._internal(this.kind, this.constant, this.type) { |
assert(kind != CONSTANT || constant != null); |
assert(constant is! SyntheticConstantValue); |
} |
- AbstractValue.nothing() |
+ AbstractConstantValue.nothing() |
: this._internal(NOTHING, null, new TypeMask.nonNullEmpty()); |
- AbstractValue.constantValue(ConstantValue constant, TypeMask type) |
+ AbstractConstantValue.constantValue(ConstantValue constant, TypeMask type) |
: this._internal(CONSTANT, constant, type); |
- factory AbstractValue.nonConstant(TypeMask type) { |
+ factory AbstractConstantValue.nonConstant(TypeMask type) { |
if (type.isEmpty) { |
if (type.isNullable) |
- return new AbstractValue.constantValue(new NullConstantValue(), type); |
+ return new AbstractConstantValue.constantValue( |
+ new NullConstantValue(), type); |
else |
- return new AbstractValue.nothing(); |
+ return new AbstractConstantValue.nothing(); |
} else { |
- return new AbstractValue._internal(NONCONST, null, type); |
+ return new AbstractConstantValue._internal(NONCONST, null, type); |
} |
} |
@@ -3079,7 +3129,7 @@ class AbstractValue { |
return hash & 0x3fffffff; |
} |
- bool operator ==(AbstractValue that) { |
+ bool operator ==(AbstractConstantValue that) { |
return that.kind == this.kind && |
that.constant == this.constant && |
that.type == this.type; |