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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart

Issue 958603002: Added VariableUse expression to tree IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Comments Created 5 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of tree_ir.optimization; 5 part of tree_ir.optimization;
6 6
7 /** 7 /**
8 * Performs the following transformations on the tree: 8 * Performs the following transformations on the tree:
9 * - Assignment propagation 9 * - Assignment propagation
10 * - If-to-conditional conversion 10 * - If-to-conditional conversion
(...skipping 19 matching lines...) Expand all
30 * seen, but are only processed once to keep this transformation linear in 30 * seen, but are only processed once to keep this transformation linear in
31 * the size of the tree. 31 * the size of the tree.
32 * 32 *
33 * The transformation builds an environment containing [Assign] bindings that 33 * The transformation builds an environment containing [Assign] bindings that
34 * are in scope. These bindings have yet-untranslated definitions. When a use 34 * are in scope. These bindings have yet-untranslated definitions. When a use
35 * is encountered the transformation determines if it is safe and profitable 35 * is encountered the transformation determines if it is safe and profitable
36 * to propagate the definition to its use. If so, it is removed from the 36 * to propagate the definition to its use. If so, it is removed from the
37 * environment and the definition is recursively processed (in the 37 * environment and the definition is recursively processed (in the
38 * new environment at the use site) before being propagated. 38 * new environment at the use site) before being propagated.
39 * 39 *
40 * See [visitVariable] for the implementation of the heuristic for propagating 40 * See [visitVariableUse] for the implementation of the heuristic for
41 * a definition. 41 * propagating a definition.
42 * 42 *
43 * 43 *
44 * IF-TO-CONDITIONAL CONVERSION: 44 * IF-TO-CONDITIONAL CONVERSION:
45 * If-statement are converted to conditional expressions when possible. 45 * If-statement are converted to conditional expressions when possible.
46 * For example: 46 * For example:
47 * 47 *
48 * if (v0) { v1 = foo(); break L } else { v1 = bar(); break L } 48 * if (v0) { v1 = foo(); break L } else { v1 = bar(); break L }
49 * ==> 49 * ==>
50 * { v1 = v0 ? foo() : bar(); break L } 50 * { v1 = v0 ? foo() : bar(); break L }
51 * 51 *
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 for (int i = node.arguments.length - 1; i >= 0; --i) { 150 for (int i = node.arguments.length - 1; i >= 0; --i) {
151 node.arguments[i] = visitStatement(node.arguments[i]); 151 node.arguments[i] = visitStatement(node.arguments[i]);
152 assert(environment.isEmpty); 152 assert(environment.isEmpty);
153 } 153 }
154 }); 154 });
155 return node; 155 return node;
156 } 156 }
157 157
158 Expression visitExpression(Expression e) => e.processed ? e : e.accept(this); 158 Expression visitExpression(Expression e) => e.processed ? e : e.accept(this);
159 159
160 Expression visitVariable(Variable node) { 160 @override
161 Expression visitVariableUse(VariableUse node) {
161 // Propagate constant to use site. 162 // Propagate constant to use site.
162 Expression constant = constantEnvironment[node]; 163 Expression constant = constantEnvironment[node.variable];
163 if (constant != null) return constant; 164 if (constant != null) return constant;
164 165
165 // Propagate a variable's definition to its use site if: 166 // Propagate a variable's definition to its use site if:
166 // 1. It has a single use, to avoid code growth and potential duplication 167 // 1. It has a single use, to avoid code growth and potential duplication
167 // of side effects, AND 168 // of side effects, AND
168 // 2. It was the most recent expression evaluated so that we do not 169 // 2. It was the most recent expression evaluated so that we do not
169 // reorder expressions with side effects. 170 // reorder expressions with side effects.
170 if (!environment.isEmpty && 171 if (!environment.isEmpty &&
171 environment.last.variable == node && 172 environment.last.variable == node.variable &&
172 environment.last.hasExactlyOneUse) { 173 environment.last.hasExactlyOneUse) {
173 return visitExpression(environment.removeLast().definition); 174 return visitExpression(environment.removeLast().definition);
174 } 175 }
176
175 // If the definition could not be propagated, leave the variable use. 177 // If the definition could not be propagated, leave the variable use.
176 return node; 178 return node;
177 } 179 }
178 180
179 /// Returns true if [exp] has no side effects and has a constant value within 181 /// Returns true if [exp] has no side effects and has a constant value within
180 /// any given activation of the enclosing method. 182 /// any given activation of the enclosing method.
181 bool isEffectivelyConstant(Expression exp) { 183 bool isEffectivelyConstant(Expression exp) {
182 // TODO(asgerf): Can be made more aggressive e.g. by checking conditional 184 // TODO(asgerf): Can be made more aggressive e.g. by checking conditional
183 // expressions recursively. Determine if that is a valuable optimization 185 // expressions recursively. Determine if that is a valuable optimization
184 // and/or if it is better handled at the CPS level. 186 // and/or if it is better handled at the CPS level.
185 return exp is Constant || 187 return exp is Constant ||
186 exp is This || 188 exp is This ||
187 exp is ReifyTypeVar || 189 exp is ReifyTypeVar ||
188 exp is Variable && constantEnvironment.containsKey(exp); 190 exp is VariableUse && constantEnvironment.containsKey(exp.variable);
189 } 191 }
190 192
191 Statement visitAssign(Assign node) { 193 Statement visitAssign(Assign node) {
192 if (isEffectivelyConstant(node.definition) && 194 if (isEffectivelyConstant(node.definition) &&
193 node.variable.writeCount == 1) { 195 node.variable.writeCount == 1) {
194 // Handle constant assignments specially. 196 // Handle constant assignments specially.
195 // They are always safe to propagate (though we should avoid duplication). 197 // They are always safe to propagate (though we should avoid duplication).
196 // Moreover, they should not prevent other expressions from propagating. 198 // Moreover, they should not prevent other expressions from propagating.
197 if (node.variable.readCount <= 1) { 199 if (node.variable.readCount <= 1) {
198 // A single-use constant should always be propagted to its use site. 200 // A single-use constant should always be propagted to its use site.
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 return new Return(e); 532 return new Return(e);
531 } 533 }
532 } 534 }
533 return null; 535 return null;
534 } 536 }
535 537
536 /// Returns an expression equivalent to both [e1] and [e2]. 538 /// Returns an expression equivalent to both [e1] and [e2].
537 /// If non-null is returned, the caller must discard [e1] and [e2] and use 539 /// If non-null is returned, the caller must discard [e1] and [e2] and use
538 /// the resulting expression in the tree. 540 /// the resulting expression in the tree.
539 static Expression combineExpressions(Expression e1, Expression e2) { 541 static Expression combineExpressions(Expression e1, Expression e2) {
540 if (e1 is Variable && e1 == e2) { 542 if (e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable) {
541 --e1.readCount; // Two references become one. 543 --e1.variable.readCount; // Two references become one.
542 return e1; 544 return e1;
543 } 545 }
544 if (e1 is Constant && e2 is Constant && e1.value == e2.value) { 546 if (e1 is Constant && e2 is Constant && e1.value == e2.value) {
545 return e1; 547 return e1;
546 } 548 }
547 return null; 549 return null;
548 } 550 }
549 551
550 /// Try to collapse nested ifs using && and || expressions. 552 /// Try to collapse nested ifs using && and || expressions.
551 /// For example: 553 /// For example:
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 } 627 }
626 628
627 Expression makeCondition(Expression e, bool polarity) { 629 Expression makeCondition(Expression e, bool polarity) {
628 return polarity ? e : new Not(e); 630 return polarity ? e : new Not(e);
629 } 631 }
630 632
631 Statement getBranch(If node, bool polarity) { 633 Statement getBranch(If node, bool polarity) {
632 return polarity ? node.thenStatement : node.elseStatement; 634 return polarity ? node.thenStatement : node.elseStatement;
633 } 635 }
634 } 636 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698