| 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);
|
|
|