Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Unified Diff: pkg/compiler/lib/src/cps_ir/type_propagation.dart

Issue 1293803003: dart2js cps: Use direct length and index access on strings. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 c86b28ce3e389b78d02b44173ba14449c6899ee5..fa036aa59c0c67f0c2337225897327cb6d03117e 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -183,6 +183,11 @@ class TypeMaskSystem {
classWorld);
}
+ bool isDefinitelyIndexable(TypeMask t, {bool allowNull: false}) {
+ if (!allowNull && t.isNullable) return false;
+ return t.nonNullable().satisfies(backend.jsIndexableClass, classWorld);
+ }
+
bool areDisjoint(TypeMask leftType, TypeMask rightType) {
TypeMask intersection = leftType.intersection(rightType, classWorld);
return intersection.isEmpty && !intersection.isNullable;
@@ -344,6 +349,11 @@ 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
@@ -1059,22 +1069,22 @@ class TransformingVisitor extends LeafVisitor {
return cps;
}
- /// Counts number of index accesses on [list] and determines based on
+ /// 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 list) {
+ bool hasTooManyIndexAccesses(Primitive receiver) {
int count = 0;
- for (Reference ref = list.firstRef; ref != null; ref = ref.next) {
+ for (Reference ref = receiver.firstRef; ref != null; ref = ref.next) {
Node use = ref.parent;
if (use is InvokeMethod &&
(use.selector.isIndex || use.selector.isIndexSet) &&
- getDartReceiver(use) == list) {
+ getDartReceiver(use) == receiver) {
++count;
- } else if (use is GetIndex && use.object.definition == list) {
+ } else if (use is GetIndex && use.object.definition == receiver) {
++count;
- } else if (use is SetIndex && use.object.definition == list) {
+ } else if (use is SetIndex && use.object.definition == receiver) {
++count;
}
if (count > 2) return true;
@@ -1082,6 +1092,40 @@ class TransformingVisitor extends LeafVisitor {
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;
+ SourceInformation sourceInfo = node.sourceInformation;
+ Continuation cont = node.continuation.definition;
+ switch (node.selector.name) {
+ case 'length':
+ if (!node.selector.isGetter) return false;
+ CpsFragment cps = new CpsFragment(sourceInfo);
+ cps.invokeContinuation(cont, [cps.letPrim(new GetLength(receiver))]);
+ replaceSubtree(node, cps.result);
+ push(cps.result);
+ 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);
+ GetIndex get = cps.letPrim(new GetIndex(receiver, index));
+ cps.invokeContinuation(cont, [get]);
+ replaceSubtree(node, cps.result);
+ push(cps.result);
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
/// Tries to replace [node] with one or more direct array access operations.
///
/// Returns `true` if the node was replaced.
@@ -1101,14 +1145,6 @@ class TransformingVisitor extends LeafVisitor {
SourceInformation sourceInfo = node.sourceInformation;
Continuation cont = node.continuation.definition;
switch (node.selector.name) {
- case 'length':
- if (!node.selector.isGetter) return false;
- CpsFragment cps = new CpsFragment(sourceInfo);
- cps.invokeContinuation(cont, [cps.letPrim(new GetLength(list))]);
- replaceSubtree(node, cps.result);
- push(cps.result);
- return true;
-
case 'add':
if (!node.selector.isCall ||
node.selector.positionalArgumentCount != 1 ||
@@ -1168,12 +1204,10 @@ class TransformingVisitor extends LeafVisitor {
push(cps.result);
return true;
- case '[]':
case 'elementAt':
- if (node.selector.name == 'elementAt' &&
- (!node.selector.isCall ||
- node.selector.positionalArgumentCount != 1 ||
- node.selector.namedArgumentCount != 0)) {
+ if (!node.selector.isCall ||
+ node.selector.positionalArgumentCount != 1 ||
+ node.selector.namedArgumentCount != 0) {
return false;
}
if (listValue.isNullable) return false;
@@ -1563,6 +1597,7 @@ class TransformingVisitor extends LeafVisitor {
if (constifyExpression(node)) return;
if (specializeOperatorCall(node)) return;
if (specializeFieldAccess(node)) return;
+ if (specializeIndexableAccess(node)) return;
if (specializeArrayAccess(node)) return;
if (specializeClosureCall(node)) return;
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698