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 631aaf2d4529da1be85c90e0c82c7f331c10e84e..506e07bef15206b09183fca4bd30123079bf16ca 100644 |
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
@@ -112,6 +112,13 @@ class ConstantPropagationLattice { |
typeSystem.isDefinitelyNotNonIntegerDouble(value.type); |
} |
+ bool isDefinitelyUInt32(AbstractValue value, |
+ {bool allowNull: false}) { |
+ return value.isNothing || |
+ typeSystem.isDefinitelyUInt32(value.type, allowNull: allowNull); |
+ } |
+ |
+ |
bool isDefinitelyInt(AbstractValue value, |
{bool allowNull: false}) { |
return value.isNothing || |
@@ -145,11 +152,6 @@ class ConstantPropagationLattice { |
allowNull: allowNull); |
} |
- bool isDefinitelyIndexable(AbstractValue value, {bool allowNull: false}) { |
- return value.isNothing || |
- typeSystem.isDefinitelyIndexable(value.type, allowNull: allowNull); |
- } |
- |
/// Returns whether the given [value] is an instance of [type]. |
/// |
/// Since [value] and [type] are not always known, [AbstractBool.Maybe] is |
@@ -252,6 +254,16 @@ class ConstantPropagationLattice { |
} |
return null; |
+ case BinaryOperatorKind.SHL: |
+ case BinaryOperatorKind.SHR: |
+ case BinaryOperatorKind.AND: |
+ case BinaryOperatorKind.OR: |
+ case BinaryOperatorKind.XOR: |
+ if (isDefinitelyNum(left) && isDefinitelyNum(right)) { |
+ return nonConstant(typeSystem.uint32Type); |
+ } |
+ return null; |
+ |
case BinaryOperatorKind.EQ: |
bool behavesLikeIdentity = |
isDefinitelyNumStringBool(left, allowNull: true) || |
@@ -890,37 +902,16 @@ class TransformingVisitor extends LeafVisitor { |
return cps; |
} |
- /// Counts number of index accesses on [receiver] and determines based on |
- /// that number if we should try to inline them. |
- /// |
- /// This is a short-term solution to avoid inserting a lot of bounds checks, |
- /// since there is currently no optimization for eliminating them. |
- bool hasTooManyIndexAccesses(Primitive receiver) { |
- receiver = receiver.effectiveDefinition; |
- int count = 0; |
- for (Reference ref in receiver.effectiveUses) { |
- Node use = ref.parent; |
- if (use is InvokeMethod && |
- (use.selector.isIndex || use.selector.isIndexSet) && |
- getDartReceiver(use).sameValue(receiver)) { |
- ++count; |
- } else if (use is GetIndex && use.object.definition.sameValue(receiver)) { |
- ++count; |
- } else if (use is SetIndex && use.object.definition.sameValue(receiver)) { |
- ++count; |
- } |
- if (count > 2) return true; |
- } |
- return false; |
- } |
- |
/// Tries to replace [node] with a direct `length` or index access. |
/// |
/// Returns `true` if the node was replaced. |
bool specializeIndexableAccess(InvokeMethod node) { |
Primitive receiver = getDartReceiver(node); |
AbstractValue receiverValue = getValue(receiver); |
- if (!lattice.isDefinitelyIndexable(receiverValue)) return false; |
+ if (!typeSystem.isDefinitelyIndexable(receiverValue.type, |
+ allowNull: true)) { |
+ return false; |
+ } |
SourceInformation sourceInfo = node.sourceInformation; |
Continuation cont = node.continuation.definition; |
switch (node.selector.name) { |
@@ -933,7 +924,7 @@ class TransformingVisitor extends LeafVisitor { |
return true; |
case '[]': |
- if (hasTooManyIndexAccesses(receiver)) return false; |
+ if (receiverValue.isNullable) return false; |
sra1
2015/09/30 21:54:20
Since a.length and a[i] throw when a==null, do we
asgerf
2015/10/01 09:49:34
I guess not. Removed.
|
Primitive index = getDartArgument(node, 0); |
if (!lattice.isDefinitelyInt(getValue(index))) return false; |
CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo); |
@@ -943,6 +934,23 @@ class TransformingVisitor extends LeafVisitor { |
push(cps.result); |
return true; |
+ case '[]=': |
+ if (receiverValue.isNullable) return false; |
+ if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type)) { |
+ return false; |
+ } |
+ Primitive index = getDartArgument(node, 0); |
+ Primitive value = getDartArgument(node, 1); |
+ if (!lattice.isDefinitelyInt(getValue(index))) return false; |
+ CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo); |
+ cps.letPrim(new SetIndex(receiver, index, value)); |
+ assert(cont.parameters.single.hasNoUses); |
+ cont.parameters.clear(); |
+ cps.invokeContinuation(cont, []); |
+ replaceSubtree(node, cps.result); |
+ push(cps.result); |
+ return true; |
+ |
default: |
return false; |
} |
@@ -1041,7 +1049,6 @@ class TransformingVisitor extends LeafVisitor { |
return false; |
} |
if (listValue.isNullable) return false; |
- if (hasTooManyIndexAccesses(list)) return false; |
Primitive index = getDartArgument(node, 0); |
if (!lattice.isDefinitelyInt(getValue(index))) return false; |
CpsFragment cps = makeBoundsCheck(list, index, sourceInfo); |
@@ -1051,22 +1058,6 @@ class TransformingVisitor extends LeafVisitor { |
push(cps.result); |
return true; |
- case '[]=': |
- if (listValue.isNullable) return false; |
- if (hasTooManyIndexAccesses(list)) return false; |
- Primitive index = getDartArgument(node, 0); |
- Primitive value = getDartArgument(node, 1); |
- if (!isMutable) return false; |
- if (!lattice.isDefinitelyInt(getValue(index))) return false; |
- CpsFragment cps = makeBoundsCheck(list, index, sourceInfo); |
- cps.letPrim(new SetIndex(list, index, value)); |
- assert(cont.parameters.single.hasNoUses); |
- cont.parameters.clear(); |
- cps.invokeContinuation(cont, []); |
- replaceSubtree(node, cps.result); |
- push(cps.result); |
- return true; |
- |
case 'forEach': |
Element element = |
compiler.world.locateSingleElement(node.selector, listValue.type); |