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 bb458ce02ab0db24f7498360fc3c2b94d6521847..71efeba4f8499677bbc783fe6dccd7a9b09f2a50 100644 |
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
@@ -1155,37 +1155,16 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
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) { |
@@ -1198,7 +1177,6 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
return true; |
case '[]': |
- if (hasTooManyIndexAccesses(receiver)) return false; |
Primitive index = getDartArgument(node, 0); |
if (!lattice.isDefinitelyInt(getValue(index))) return false; |
CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo); |
@@ -1208,6 +1186,23 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
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; |
} |
@@ -1303,7 +1298,6 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
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); |
@@ -1313,22 +1307,6 @@ class TransformingVisitor extends DeepRecursiveVisitor { |
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); |