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

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

Issue 1285173002: dart2js cps: Rewrite more List operations into JS array operations. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: receiverIsNotNull -> optional param 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
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 411cb82b9daaea333804549e7703c40f2af50f15..4e8d40d03a345ae14eb4343b771037e216a70316 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -177,6 +177,12 @@ class TypeMaskSystem {
return t.nonNullable().satisfies(backend.jsFixedArrayClass, classWorld);
}
+ bool isDefinitelyExtendableNativeList(TypeMask t, {bool allowNull: false}) {
+ if (!allowNull && t.isNullable) return false;
+ return t.nonNullable().satisfies(backend.jsExtendableArrayClass,
+ classWorld);
+ }
+
bool areDisjoint(TypeMask leftType, TypeMask rightType) {
TypeMask intersection = leftType.intersection(rightType, classWorld);
return intersection.isEmpty && !intersection.isNullable;
@@ -331,6 +337,13 @@ class ConstantPropagationLattice {
allowNull: allowNull);
}
+ bool isDefinitelyExtendableNativeList(AbstractValue value,
+ {bool allowNull: false}) {
+ return value.isNothing ||
+ typeSystem.isDefinitelyExtendableNativeList(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
@@ -1083,6 +1096,8 @@ class TransformingVisitor extends LeafVisitor {
lattice.isDefinitelyFixedNativeList(listValue, allowNull: true);
bool isMutable =
lattice.isDefinitelyMutableNativeList(listValue, allowNull: true);
+ bool isExtendable =
+ lattice.isDefinitelyExtendableNativeList(listValue, allowNull: true);
SourceInformation sourceInfo = node.sourceInformation;
Continuation cont = node.continuation.definition;
switch (node.selector.name) {
@@ -1094,7 +1109,67 @@ class TransformingVisitor extends LeafVisitor {
push(cps.result);
return true;
+ case 'add':
+ if (!node.selector.isCall ||
+ node.selector.positionalArgumentCount != 1 ||
+ node.selector.namedArgumentCount != 0) {
+ return false;
+ }
+ if (!isExtendable) return false;
+ Primitive addedItem = getDartArgument(node, 0);
+ CpsFragment cps = new CpsFragment(sourceInfo);
+ cps.invokeBuiltin(BuiltinMethod.Push,
+ list,
+ <Primitive>[addedItem],
+ receiverIsNotNull: listValue.isDefinitelyNotNull);
+ cps.invokeContinuation(cont, [cps.makeNull()]);
+ replaceSubtree(node, cps.result);
+ push(cps.result);
+ return true;
+
+ case 'removeLast':
+ if (!node.selector.isCall ||
+ node.selector.argumentCount != 0) {
+ return false;
+ }
+ if (!isExtendable) return false;
+ CpsFragment cps = new CpsFragment(sourceInfo);
+ Primitive removedItem = cps.invokeBuiltin(BuiltinMethod.Pop,
+ list,
+ <Primitive>[],
+ receiverIsNotNull: listValue.isDefinitelyNotNull);
+ cps.invokeContinuation(cont, [removedItem]);
+ replaceSubtree(node, cps.result);
+ push(cps.result);
+ return true;
+
+ case 'addAll':
+ if (!node.selector.isCall ||
+ node.selector.argumentCount != 1) {
+ return false;
+ }
+ if (!isExtendable) return false;
+ Primitive addedList = getDartArgument(node, 0);
+ if (addedList is! LiteralList) return false;
+ LiteralList addedLiteral = addedList;
+ CpsFragment cps = new CpsFragment(sourceInfo);
+ cps.invokeBuiltin(BuiltinMethod.Push,
+ list,
+ addedLiteral.values.map((ref) => ref.definition).toList(),
+ receiverIsNotNull: listValue.isDefinitelyNotNull);
+ cps.invokeContinuation(cont, [cps.makeNull()]);
+ replaceSubtree(node, cps.result);
+ push(cps.result);
+ return true;
+
case '[]':
+ case 'elementAt':
+ if (node.selector.name == 'elementAt' &&
+ (!node.selector.isCall ||
+ node.selector.positionalArgumentCount != 1 ||
+ node.selector.namedArgumentCount != 0)) {
+ return false;
+ }
if (listValue.isNullable) return false;
if (hasTooManyIndexAccesses(list)) return false;
Primitive index = getDartArgument(node, 0);
@@ -1326,8 +1401,6 @@ class TransformingVisitor extends LeafVisitor {
push(invoke);
return true;
- // TODO(asgerf): Rewrite 'add', 'removeLast', ...
-
default:
return false;
}
@@ -1647,6 +1720,27 @@ class TransformingVisitor extends LeafVisitor {
}
}
+ Primitive visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
+ if (node.method == BuiltinMethod.Push) {
+ // Convert consecutive pushes into a single push.
+ InteriorNode parent = getEffectiveParent(node.parent);
+ if (parent is LetPrim && parent.primitive is ApplyBuiltinMethod) {
+ ApplyBuiltinMethod previous = parent.primitive;
+ if (previous.method == BuiltinMethod.Push &&
+ previous.receiver.definition == node.receiver.definition) {
+ for (Reference ref in node.arguments) {
+ previous.arguments.add(ref);
Kevin Millikin (Google) 2015/08/14 07:56:55 This doesn't look safe. I think it can lift an ar
asgerf 2015/08/14 08:47:17 Oof! You're right.
+ ref.parent = previous;
+ }
+ node.arguments.clear(); // Avoid unlinking adopted references.
+ // Replace the old push by a dummy that will get removed.
+ return makeConstantPrimitive(new NullConstantValue());
+ }
+ }
+ }
+ return null;
+ }
+
Primitive visitTypeTest(TypeTest node) {
Primitive prim = node.value.definition;
AbstractValue value = getValue(prim);
@@ -2059,6 +2153,11 @@ class TypePropagationVisitor implements Visitor {
}
}
+ void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
+ // TODO(asgerf): For pop(), use the container type from the TypeMask.
+ setValue(node, nonConstant());
+ }
+
void visitInvokeMethodDirectly(InvokeMethodDirectly node) {
Continuation cont = node.continuation.definition;
setReachable(cont);
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698