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

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

Issue 1294353002: dart2js CPS: Inline list.forEach. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Merge in tip of tree. 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 fa036aa59c0c67f0c2337225897327cb6d03117e..d93f05154e3baff2b274c9ff9ab737d14b9abd1f 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -14,6 +14,7 @@ import '../diagnostics/invariant.dart' as dart2js show
import '../elements/elements.dart';
import '../io/source_information.dart' show SourceInformation;
import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../js_backend/codegen/task.dart' show CpsFunctionCompiler;
import '../resolution/operators.dart';
import '../tree/tree.dart' show DartString, ConsDartString, LiteralDartString;
import '../types/types.dart';
@@ -58,7 +59,7 @@ class TypeMaskSystem {
// Build the number+string+bool type. To make containment tests more
// inclusive, we use the num, String, bool types for this, not
// the JSNumber, JSString, JSBool subclasses.
- TypeMask anyNum =
+ TypeMask anyNum =
new TypeMask.nonNullSubtype(classWorld.numClass, classWorld);
TypeMask anyString =
new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
@@ -179,7 +180,7 @@ class TypeMaskSystem {
bool isDefinitelyExtendableNativeList(TypeMask t, {bool allowNull: false}) {
if (!allowNull && t.isNullable) return false;
- return t.nonNullable().satisfies(backend.jsExtendableArrayClass,
+ return t.nonNullable().satisfies(backend.jsExtendableArrayClass,
classWorld);
}
@@ -458,9 +459,9 @@ class ConstantPropagationLattice {
case BinaryOperatorKind.EQ:
bool behavesLikeIdentity =
- isDefinitelyNumStringBool(left, allowNull: true) ||
+ isDefinitelyNumStringBool(left, allowNull: true) ||
right.isNullConstant;
- if (behavesLikeIdentity &&
+ if (behavesLikeIdentity &&
typeSystem.areDisjoint(left.type, right.type)) {
return constant(new FalseConstantValue());
}
@@ -528,13 +529,14 @@ class TypePropagator extends Pass {
String get passName => 'Sparse constant propagation';
final dart2js.Compiler _compiler;
+ final CpsFunctionCompiler _functionCompiler;
// The constant system is used for evaluation of expressions with constant
// arguments.
final ConstantPropagationLattice _lattice;
final dart2js.InternalErrorFunction _internalError;
final Map<Definition, AbstractValue> _values = <Definition, AbstractValue>{};
- TypePropagator(dart2js.Compiler compiler)
+ TypePropagator(dart2js.Compiler compiler, this._functionCompiler)
: _compiler = compiler,
_internalError = compiler.internalError,
_lattice = new ConstantPropagationLattice(
@@ -564,6 +566,7 @@ class TypePropagator extends Pass {
// with constant results or existing values that are in scope.
TransformingVisitor transformer = new TransformingVisitor(
_compiler,
+ _functionCompiler,
_lattice,
analyzer,
replacements,
@@ -597,6 +600,7 @@ class TransformingVisitor extends LeafVisitor {
final Map<Expression, ConstantValue> replacements;
final ConstantPropagationLattice lattice;
final dart2js.Compiler compiler;
+ final CpsFunctionCompiler functionCompiler;
JavaScriptBackend get backend => compiler.backend;
TypeMaskSystem get typeSystem => lattice.typeSystem;
@@ -608,6 +612,7 @@ class TransformingVisitor extends LeafVisitor {
final List<Node> stack = <Node>[];
TransformingVisitor(this.compiler,
+ this.functionCompiler,
this.lattice,
this.analyzer,
this.replacements,
@@ -835,7 +840,7 @@ class TransformingVisitor extends LeafVisitor {
// Rewrite:
// if (x == true) S1 else S2
// =>
- // if (x) S1 else S2
+ // if (x) S1 else S2
Branch branch = new Branch(new IsTrue(leftArg), trueCont, falseCont);
replaceSubtree(node, branch);
return;
@@ -914,7 +919,7 @@ class TransformingVisitor extends LeafVisitor {
// fact that Dart-null corresponds to both JS-null and JS-undefined.
// Please see documentation for IsFalsy, StrictEq, and LooseEq.
if (left.isNullConstant || right.isNullConstant) {
- return replaceWithBinary(BuiltinOperator.Identical,
+ return replaceWithBinary(BuiltinOperator.Identical,
leftArg, rightArg);
}
// There are several implementations of == that behave like identical.
@@ -922,15 +927,15 @@ class TransformingVisitor extends LeafVisitor {
bool behavesLikeIdentical = true;
for (Element target in getAllTargets(left.type, node.selector)) {
ClassElement clazz = target.enclosingClass.declaration;
- if (clazz != compiler.world.objectClass &&
- clazz != backend.jsInterceptorClass &&
+ if (clazz != compiler.world.objectClass &&
+ clazz != backend.jsInterceptorClass &&
clazz != backend.jsNullClass) {
behavesLikeIdentical = false;
break;
}
}
if (behavesLikeIdentical) {
- return replaceWithBinary(BuiltinOperator.Identical,
+ return replaceWithBinary(BuiltinOperator.Identical,
leftArg, rightArg);
}
} else {
@@ -1154,8 +1159,8 @@ class TransformingVisitor extends LeafVisitor {
if (!isExtendable) return false;
Primitive addedItem = getDartArgument(node, 0);
CpsFragment cps = new CpsFragment(sourceInfo);
- cps.invokeBuiltin(BuiltinMethod.Push,
- list,
+ cps.invokeBuiltin(BuiltinMethod.Push,
+ list,
<Primitive>[addedItem],
receiverIsNotNull: listValue.isDefinitelyNotNull);
cps.invokeContinuation(cont, [cps.makeNull()]);
@@ -1171,7 +1176,7 @@ class TransformingVisitor extends LeafVisitor {
if (!isExtendable) return false;
CpsFragment cps = new CpsFragment(sourceInfo);
Primitive removedItem = cps.invokeBuiltin(BuiltinMethod.Pop,
- list,
+ list,
<Primitive>[],
receiverIsNotNull: listValue.isDefinitelyNotNull);
cps.invokeContinuation(cont, [removedItem]);
@@ -1188,15 +1193,15 @@ class TransformingVisitor extends LeafVisitor {
Primitive addedList = getDartArgument(node, 0);
// Rewrite addAll([x1, ..., xN]) to push(x1, ..., xN).
// Ensure that the list is not mutated between creation and use.
- // We aim for the common case where this is the only use of the list,
+ // We aim for the common case where this is the only use of the list,
// which also guarantees that this list is not mutated before use.
if (addedList is! LiteralList || !addedList.hasExactlyOneUse) {
return false;
}
LiteralList addedLiteral = addedList;
CpsFragment cps = new CpsFragment(sourceInfo);
- cps.invokeBuiltin(BuiltinMethod.Push,
- list,
+ cps.invokeBuiltin(BuiltinMethod.Push,
+ list,
addedLiteral.values.map((ref) => ref.definition).toList(),
receiverIsNotNull: listValue.isDefinitelyNotNull);
cps.invokeContinuation(cont, [cps.makeNull()]);
@@ -1238,56 +1243,23 @@ class TransformingVisitor extends LeafVisitor {
return true;
case 'forEach':
- if (!node.selector.isCall ||
- node.selector.positionalArgumentCount != 1 ||
- node.selector.namedArgumentCount != 0) {
- return false;
+ Element element =
+ compiler.world.locateSingleElement(node.selector, listValue.type);
+ if (element == null ||
+ !element.isFunction ||
+ !node.selector.isCall) return false;
+ assert(node.selector.positionalArgumentCount == 1);
+ assert(node.selector.namedArgumentCount == 0);
+ FunctionDefinition target = functionCompiler.compileToCpsIR(element);
+
+ node.receiver.definition.substituteFor(target.thisParameter);
+ for (int i = 0; i < node.arguments.length; ++i) {
+ node.arguments[i].definition.substituteFor(target.parameters[i]);
}
- Primitive callback = getDartArgument(node, 0);
- // Rewrite to:
- // var originalLength = array.length, i = 0;
- // while (i < array.length) {
- // callback(array[i]);
- // if (array.length !== originalLength) throw;
- // i = i + 1;
- // }
- CpsFragment cps = new CpsFragment(sourceInfo);
- Primitive originalLength = cps.letPrim(new GetLength(list));
- originalLength.hint = new OriginalLengthEntity();
+ node.continuation.definition.substituteFor(target.returnContinuation);
- // Build a loop.
- Parameter loopIndex = new Parameter(new LoopIndexEntity());
- Continuation loop = cps.beginLoop(
- <Parameter>[loopIndex], [cps.makeZero()]);
-
- // Check for loop exit.
- Primitive loopCondition = cps.applyBuiltin(
- BuiltinOperator.NumLt,
- [loopIndex, cps.letPrim(new GetLength(list))]);
- CpsFragment exitBranch = cps.ifFalse(loopCondition);
- exitBranch.invokeContinuation(cont, [exitBranch.makeNull()]);
-
- // Invoke the callback.
- Primitive arrayItem = cps.letPrim(new GetIndex(list, loopIndex));
- cps.invokeMethod(callback,
- new Selector.callClosure(1),
- getValue(callback).type,
- [arrayItem]);
-
- // Check for concurrent modification, unless the list is fixed-length.
- if (!isFixedLength) {
- cps.append(
- makeConcurrentModificationCheck(list, originalLength, sourceInfo));
- }
-
- // Increment i and continue the loop.
- Primitive addOne = cps.applyBuiltin(
- BuiltinOperator.NumAdd,
- [loopIndex, cps.makeOne()]);
- cps.continueLoop(loop, [addOne]);
-
- replaceSubtree(node, cps.result);
- push(cps.result);
+ replaceSubtree(node, target.body);
+ push(target.body);
return true;
case 'iterator':
@@ -1767,9 +1739,9 @@ class TransformingVisitor extends LeafVisitor {
InteriorNode parent = getEffectiveParent(node.parent);
if (parent is LetPrim && parent.primitive is ApplyBuiltinMethod) {
ApplyBuiltinMethod previous = parent.primitive;
- if (previous.method == BuiltinMethod.Push &&
+ if (previous.method == BuiltinMethod.Push &&
previous.receiver.definition == node.receiver.definition) {
- // We found two consecutive pushes.
+ // We found two consecutive pushes.
// Move all arguments from the first push onto the second one.
List<Reference<Primitive>> arguments = previous.arguments;
for (Reference ref in arguments) {
@@ -1973,7 +1945,7 @@ class TypePropagationVisitor implements Visitor {
int firstActualParameter = 0;
if (backend.isInterceptedMethod(node.element)) {
setValue(node.thisParameter, nonConstant(typeSystem.nonNullType));
- setValue(node.parameters[0],
+ setValue(node.parameters[0],
nonConstant(typeSystem.getReceiverType(node.element)));
firstActualParameter = 1;
} else if (node.thisParameter != null) {
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698