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

Unified Diff: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart

Issue 1526333002: dart2js cps: Clone small constants to use site. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Update tests Created 5 years 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 | « no previous file | tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index c36a394fa77728ca74c897c41f76bff613d5c370..1dda41d5cbdf7a6147843892bb9db0fd38a0dcb5 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -53,6 +53,7 @@ class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
<cps_ir.Primitive, Variable>{};
final Map<cps_ir.MutableVariable, Variable> mutable2variable =
<cps_ir.MutableVariable, Variable>{};
+ final Set<cps_ir.Constant> inlinedConstants = new Set<cps_ir.Constant>();
// Continuations with more than one use are replaced with Tree labels. This
// is the mapping from continuations to labels.
@@ -109,6 +110,9 @@ class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
/// returned expression must be used in the tree.
Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) {
cps_ir.Primitive prim = reference.definition.effectiveDefinition;
+ if (prim is cps_ir.Constant && inlinedConstants.contains(prim)) {
+ return new Constant(prim.value);
+ }
if (thisParameter != null && prim == thisParameter) {
return new This();
}
@@ -279,6 +283,54 @@ class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
return prim.accept(this);
}
+ /************************ CONSTANT COPYING *****************************/
+
+ /// Estimate of the number of characters needed to emit a use of the given
+ /// constant.
+ int constantSize(PrimitiveConstantValue value) {
+ if (value is StringConstantValue) {
+ // Account for the quotes, but ignore the cost of escape sequences to
+ // avoid traversing the string.
sra1 2015/12/16 18:40:12 Note. The size will depend on the output encoding
asgerf 2015/12/17 15:51:52 Updated the comment to reflect this.
+ return value.length + 2;
+ } else {
+ return '${value.primitiveValue}'.length;
sra1 2015/12/16 18:40:12 We generate true and false as !0 and !1 in minifie
asgerf 2015/12/17 15:51:52 Bools -> done. Added a TODO for the rest. We coul
+ }
+ }
+
+ /// The number of uses [prim] has, or `-1` if it is used in a phi assignment
+ /// which is likely to be eliminated after liveness analysis.
+ int countNonPhiUses(cps_ir.Primitive prim) {
+ int count = 0;
+ for (cps_ir.Reference ref = prim.firstRef; ref != null; ref = ref.next) {
+ cps_ir.Node use = ref.parent;
+ if (use is cps_ir.InvokeContinuation) {
+ cps_ir.Continuation cont = use.continuation.definition;
+ int index = use.arguments.indexOf(ref);
+ if (cont.parameters[index].hint == prim.hint) {
sra1 2015/12/16 18:40:12 Is this because they are both null or both somethi
asgerf 2015/12/17 15:51:52 (this is also in response to the comment below) T
+ return -1;
+ }
+ }
+ count++;
+ }
+ return count;
+ }
+
+ /// True if the given [constant] should be copied to every use site.
+ bool shouldCopyToUses(cps_ir.Constant constant) {
+ if (!constant.value.isPrimitive) return false;
+ if (constant.hasAtMostOneUse) return true;
+ int uses = countNonPhiUses(constant);
+ if (uses == -1) return false; // Copying might prevent elimination of a phi.
+ int size = constantSize(constant.value);
+ // Compare the expected code size output of copying vs sharing.
+ const int USE = 2; // Minified locals usually have length 2.
sra1 2015/12/16 18:40:12 Only in 'large' functions. Can we estimate the nu
asgerf 2015/12/17 15:51:52 Changed to 1. I just wanted to use the common cas
+ const int ASSIGN = USE + 2; // Variable and '=' and ';'
+ const int BIAS = 2; // Artificial bias to slightly favor copying.
+ int costOfSharing = USE * uses + size + ASSIGN + BIAS;
+ int costOfCopying = size * uses;
+ return costOfCopying <= costOfSharing;
+ }
+
/************************ INTERIOR EXPRESSIONS ************************/
//
// Visit methods for interior expressions must return a function:
@@ -287,6 +339,10 @@ class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
//
NodeCallback visitLetPrim(cps_ir.LetPrim node) {
+ if (node.primitive is cps_ir.Constant && shouldCopyToUses(node.primitive)) {
+ inlinedConstants.add(node.primitive);
+ return (Statement next) => next;
+ }
Variable variable = getVariable(node.primitive);
var value = translatePrimitive(node.primitive);
if (value is Expression) {
« no previous file with comments | « no previous file | tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698