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

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

Issue 1201753004: Revert "dart2js cps: Refactor and optimize string concatenations." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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 d9e4d47c5de469edda65af9fb48d50645424679b..e5368785336f0b9d4f4bfec139a25e5630dff29f 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -5,11 +5,12 @@
import 'optimizers.dart' show Pass, ParentVisitor;
import '../constants/constant_system.dart';
+import '../constants/expressions.dart';
import '../resolution/operators.dart';
import '../constants/values.dart';
import '../dart_types.dart' as types;
import '../dart2jslib.dart' as dart2js;
-import '../tree/tree.dart' show DartString, ConsDartString, LiteralDartString;
+import '../tree/tree.dart' show LiteralDartString;
import 'cps_ir_nodes.dart';
import '../types/types.dart';
import '../types/constants.dart' show computeTypeMask;
@@ -466,7 +467,9 @@ class TransformingVisitor extends RecursiveVisitor {
/// Make a constant primitive for [constant] and set its entry in [values].
Constant makeConstantPrimitive(ConstantValue constant) {
- Constant primitive = new Constant(constant);
+ ConstantExpression constExp =
+ const ConstantExpressionCreator().convert(constant);
+ Constant primitive = new Constant(constExp, constant);
values[primitive] = new AbstractValue.constantValue(constant,
typeSystem.getTypeOf(constant));
return primitive;
@@ -635,11 +638,6 @@ class TransformingVisitor extends RecursiveVisitor {
return replaceWithBinary(operator, leftArg, rightArg);
}
}
- else if (lattice.isDefinitelyString(left, allowNull: false) &&
- lattice.isDefinitelyString(right, allowNull: false)) {
- return replaceWithBinary(BuiltinOperator.StringConcatenate,
- leftArg, rightArg);
- }
}
}
// We should only get here if the node was not specialized.
@@ -714,6 +712,12 @@ class TransformingVisitor extends RecursiveVisitor {
super.visitInvokeMethod(node);
}
+ void visitConcatenateStrings(ConcatenateStrings node) {
+ Continuation cont = node.continuation.definition;
+ if (constifyExpression(node, cont)) return;
+ super.visitConcatenateStrings(node);
+ }
+
void visitTypeCast(TypeCast node) {
Continuation cont = node.continuation.definition;
@@ -741,27 +745,6 @@ class TransformingVisitor extends RecursiveVisitor {
super.visitTypeCast(node);
}
- void visitInvokeStatic(InvokeStatic node) {
- // Specialize calls to static methods.
- // TODO(asgerf): This is written to easily scale to more cases,
- // either add more cases or clean up.
- Continuation cont = node.continuation.definition;
- Primitive arg(int n) => node.arguments[n].definition;
- AbstractValue argType(int n) => getValue(arg(n));
- if (node.target.library.isInternalLibrary) {
- switch(node.target.name) {
- case InternalMethod.Stringify:
- if (lattice.isDefinitelyString(argType(0))) {
- InvokeContinuation invoke =
- new InvokeContinuation(cont, <Primitive>[arg(0)]);
- replaceSubtree(node, invoke);
- visitInvokeContinuation(invoke);
- }
- break;
- }
- }
- }
-
AbstractValue getValue(Primitive primitive) {
AbstractValue value = values[primitive];
return value == null ? new AbstractValue.nothing() : value;
@@ -780,64 +763,6 @@ class TransformingVisitor extends RecursiveVisitor {
}
}
- void insertLetPrim(Expression node, Primitive prim) {
- InteriorNode parent = node.parent;
- LetPrim let = new LetPrim(prim);
- parent.body = let;
- let.body = node;
- node.parent = let;
- let.parent = parent;
- }
-
- void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
- DartString getString(AbstractValue value) {
- StringConstantValue constant = value.constant;
- return constant.primitiveValue;
- }
- switch (node.operator) {
- case BuiltinOperator.StringConcatenate:
- // Concatenate consecutive constants.
- bool argumentsWereRemoved = false;
- int i = 0;
- while (i < node.arguments.length - 1) {
- int startOfSequence = i;
- AbstractValue firstValue = getValue(node.arguments[i++].definition);
- if (!firstValue.isConstant) continue;
- AbstractValue secondValue = getValue(node.arguments[i++].definition);
- if (!secondValue.isConstant) continue;
-
- DartString string =
- new ConsDartString(getString(firstValue), getString(secondValue));
-
- // We found a sequence of at least two constants.
- // Look for the end of the sequence.
- while (i < node.arguments.length) {
- AbstractValue value = getValue(node.arguments[i].definition);
- if (!value.isConstant) break;
- string = new ConsDartString(string, getString(value));
- ++i;
- }
- Constant prim =
- makeConstantPrimitive(new StringConstantValue(string));
- insertLetPrim(node.parent, prim);
- for (int k = startOfSequence; k < i; ++k) {
- node.arguments[k].unlink();
- node.arguments[k] = null; // Remove the argument after the loop.
- }
- node.arguments[startOfSequence] = new Reference<Primitive>(prim);
- argumentsWereRemoved = true;
- }
- if (argumentsWereRemoved) {
- node.arguments.removeWhere((ref) => ref == null);
- }
- // TODO(asgerf): Rebalance nested StringConcats that arise from
- // rewriting the + operator to StringConcat.
- break;
-
- default:
- }
- }
-
Primitive visitTypeTest(TypeTest node) {
Primitive prim = node.value.definition;
AbstractValue value = getValue(prim);
@@ -878,10 +803,6 @@ class TransformingVisitor extends RecursiveVisitor {
} else {
Primitive newPrim = visit(node.primitive);
if (newPrim != null) {
- if (!values.containsKey(newPrim)) {
- // If the type was not set, default to the same type as before.
- values[newPrim] = values[node.primitive];
- }
newPrim.substituteFor(node.primitive);
RemovalVisitor.remove(node.primitive);
node.primitive = newPrim;
@@ -1054,22 +975,10 @@ class TypePropagationVisitor implements Visitor {
assert(cont.parameters.length == 1);
Parameter returnValue = cont.parameters[0];
-
- if (node.target.library.isInternalLibrary) {
- switch (node.target.name) {
- case InternalMethod.Stringify:
- AbstractValue argValue = getValue(node.arguments[0].definition);
- if (argValue.isNothing) return; // And come back later.
- if (lattice.isDefinitelyString(argValue)) {
- setValue(returnValue, argValue);
- } else {
- setValue(returnValue, nonConstant(typeSystem.stringType));
- }
- return;
- }
- }
-
- TypeMask returnType = typeSystem.getReturnType(node.target);
+ Entity target = node.target;
+ TypeMask returnType = target is FieldElement
+ ? typeSystem.dynamicType
+ : typeSystem.getReturnType(node.target);
setValue(returnValue, nonConstant(returnType));
}
@@ -1143,34 +1052,8 @@ class TypePropagationVisitor implements Visitor {
}
void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
- // Note that most built-in operators do not exist before the transformation
- // pass after this analysis has finished.
- switch (node.operator) {
- case BuiltinOperator.StringConcatenate:
- DartString stringValue = const LiteralDartString('');
- for (Reference<Primitive> arg in node.arguments) {
- AbstractValue value = getValue(arg.definition);
- if (value.isNothing) {
- return; // And come back later
- } else if (value.isConstant &&
- value.constant.isString &&
- stringValue != null) {
- StringConstantValue constant = value.constant;
- stringValue =
- new ConsDartString(stringValue, constant.primitiveValue);
- } else {
- stringValue = null;
- break;
- }
- }
- if (stringValue == null) {
- setValue(node, nonConstant(typeSystem.stringType));
- } else {
- setValue(node, constantValue(new StringConstantValue(stringValue)));
- }
- break;
- default:
- }
+ // Not actually reachable yet.
+ // TODO(asgerf): Implement type propagation for builtin operators.
setValue(node, nonConstant());
}
@@ -1193,6 +1076,50 @@ class TypePropagationVisitor implements Visitor {
setValue(returnValue, nonConstant(typeSystem.getReturnType(node.target)));
}
+ void visitConcatenateStrings(ConcatenateStrings node) {
+ Continuation cont = node.continuation.definition;
+ setReachable(cont);
+
+ /// Sets the value of the target continuation parameter, and possibly
+ /// try to replace the whole invocation with a constant.
+ void setResult(AbstractValue updateValue, {bool canReplace: false}) {
+ Parameter returnValue = cont.parameters[0];
+ setValue(returnValue, updateValue);
+ if (canReplace && updateValue.isConstant) {
+ replacements[node] = updateValue.constant;
+ } else {
+ // A previous iteration might have tried to replace this.
+ replacements.remove(node);
+ }
+ }
+
+ // TODO(jgruber): Currently we only optimize if all arguments are string
+ // constants, but we could also handle cases such as "foo${42}".
+ bool allStringConstants = node.arguments.every((Reference ref) {
+ if (!(ref.definition is Constant)) {
+ return false;
+ }
+ Constant constant = ref.definition;
+ return constant != null && constant.value.isString;
+ });
+
+ TypeMask type = typeSystem.stringType;
+ assert(cont.parameters.length == 1);
+ if (allStringConstants) {
+ // All constant, we can concatenate ourselves.
+ Iterable<String> allStrings = node.arguments.map((Reference ref) {
+ Constant constant = ref.definition;
+ StringConstantValue stringConstant = constant.value;
+ return stringConstant.primitiveValue.slowToString();
+ });
+ LiteralDartString dartString = new LiteralDartString(allStrings.join());
+ ConstantValue constant = new StringConstantValue(dartString);
+ setResult(constantValue(constant, type), canReplace: true);
+ } else {
+ setResult(nonConstant(type));
+ }
+ }
+
void visitThrow(Throw node) {
}
@@ -1523,7 +1450,76 @@ class AbstractValue {
}
}
-/// Enum-like class with the names of internal methods we care about.
-abstract class InternalMethod {
- static const String Stringify = 'S';
-}
+class ConstantExpressionCreator
+ implements ConstantValueVisitor<ConstantExpression, dynamic> {
+
+ const ConstantExpressionCreator();
+
+ ConstantExpression convert(ConstantValue value) => value.accept(this, null);
+
+ @override
+ ConstantExpression visitBool(BoolConstantValue constant, _) {
+ return new BoolConstantExpression(constant.primitiveValue);
+ }
+
+ @override
+ ConstantExpression visitConstructed(ConstructedConstantValue constant, arg) {
+ throw new UnsupportedError("ConstantExpressionCreator.visitConstructed");
+ }
+
+ @override
+ ConstantExpression visitDeferred(DeferredConstantValue constant, arg) {
+ throw new UnsupportedError("ConstantExpressionCreator.visitDeferred");
+ }
+
+ @override
+ ConstantExpression visitDouble(DoubleConstantValue constant, arg) {
+ return new DoubleConstantExpression(constant.primitiveValue);
+ }
+
+ @override
+ ConstantExpression visitSynthetic(SyntheticConstantValue constant, arg) {
+ throw new UnsupportedError("ConstantExpressionCreator.visitSynthetic");
+ }
+
+ @override
+ ConstantExpression visitFunction(FunctionConstantValue constant, arg) {
+ throw new UnsupportedError("ConstantExpressionCreator.visitFunction");
+ }
+
+ @override
+ ConstantExpression visitInt(IntConstantValue constant, arg) {
+ return new IntConstantExpression(constant.primitiveValue);
+ }
+
+ @override
+ ConstantExpression visitInterceptor(InterceptorConstantValue constant, arg) {
+ throw new UnsupportedError("ConstantExpressionCreator.visitInterceptor");
+ }
+
+ @override
+ ConstantExpression visitList(ListConstantValue constant, arg) {
+ throw new UnsupportedError("ConstantExpressionCreator.visitList");
+ }
+
+ @override
+ ConstantExpression visitMap(MapConstantValue constant, arg) {
+ throw new UnsupportedError("ConstantExpressionCreator.visitMap");
+ }
+
+ @override
+ ConstantExpression visitNull(NullConstantValue constant, arg) {
+ return new NullConstantExpression();
+ }
+
+ @override
+ ConstantExpression visitString(StringConstantValue constant, arg) {
+ return new StringConstantExpression(
+ constant.primitiveValue.slowToString());
+ }
+
+ @override
+ ConstantExpression visitType(TypeConstantValue constant, arg) {
+ throw new UnsupportedError("ConstantExpressionCreator.visitType");
+ }
+}
« 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