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

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: Updated docs regarding catch parameters 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 for (int i = node.arguments.length - 1; i >= 0; --i) { 158 for (int i = node.arguments.length - 1; i >= 0; --i) {
159 node.arguments[i] = visitStatement(node.arguments[i]); 159 node.arguments[i] = visitStatement(node.arguments[i]);
160 assert(environment.isEmpty); 160 assert(environment.isEmpty);
161 } 161 }
162 }); 162 });
163 return node; 163 return node;
164 } 164 }
165 165
166 Expression visitExpression(Expression e) => e.processed ? e : e.accept(this); 166 Expression visitExpression(Expression e) => e.processed ? e : e.accept(this);
167 167
168 Expression visitVariable(Variable node) { 168 @override
169 Expression visitVariableUse(VariableUse node) {
169 // Propagate constant to use site. 170 // Propagate constant to use site.
170 Expression constant = constantEnvironment[node]; 171 Expression constant = constantEnvironment[node.variable];
171 if (constant != null) return constant; 172 if (constant != null) return constant;
172 173
173 // Propagate a variable's definition to its use site if: 174 // Propagate a variable's definition to its use site if:
174 // 1. It has a single use, to avoid code growth and potential duplication 175 // 1. It has a single use, to avoid code growth and potential duplication
175 // of side effects, AND 176 // of side effects, AND
176 // 2. It was the most recent expression evaluated so that we do not 177 // 2. It was the most recent expression evaluated so that we do not
177 // reorder expressions with side effects. 178 // reorder expressions with side effects.
178 if (!environment.isEmpty && 179 if (!environment.isEmpty &&
179 environment.last.variable == node && 180 environment.last.variable == node.variable &&
180 environment.last.hasExactlyOneUse) { 181 environment.last.hasExactlyOneUse) {
181 return visitExpression(environment.removeLast().definition); 182 return visitExpression(environment.removeLast().definition);
182 } 183 }
184
183 // If the definition could not be propagated, leave the variable use. 185 // If the definition could not be propagated, leave the variable use.
184 return node; 186 return node;
185 } 187 }
186 188
187 /// Returns true if [exp] has no side effects and has a constant value within 189 /// Returns true if [exp] has no side effects and has a constant value within
188 /// any given activation of the enclosing method. 190 /// any given activation of the enclosing method.
189 bool isEffectivelyConstant(Expression exp) { 191 bool isEffectivelyConstant(Expression exp) {
190 // TODO(asgerf): Can be made more aggressive e.g. by checking conditional 192 // TODO(asgerf): Can be made more aggressive e.g. by checking conditional
191 // expressions recursively. Determine if that is a valuable optimization 193 // expressions recursively. Determine if that is a valuable optimization
192 // and/or if it is better handled at the CPS level. 194 // and/or if it is better handled at the CPS level.
193 return exp is Constant || 195 return exp is Constant ||
194 exp is This || 196 exp is This ||
195 exp is ReifyTypeVar || 197 exp is ReifyTypeVar ||
196 exp is Variable && constantEnvironment.containsKey(exp); 198 exp is VariableUse && constantEnvironment.containsKey(exp.variable);
197 } 199 }
198 200
199 Statement visitAssign(Assign node) { 201 Statement visitAssign(Assign node) {
200 if (isEffectivelyConstant(node.definition) && 202 if (isEffectivelyConstant(node.definition) &&
201 node.variable.writeCount == 1) { 203 node.variable.writeCount == 1) {
202 // Handle constant assignments specially. 204 // Handle constant assignments specially.
203 // They are always safe to propagate (though we should avoid duplication). 205 // They are always safe to propagate (though we should avoid duplication).
204 // Moreover, they should not prevent other expressions from propagating. 206 // Moreover, they should not prevent other expressions from propagating.
205 if (node.variable.readCount <= 1) { 207 if (node.variable.readCount <= 1) {
206 // A single-use constant should always be propagted to its use site. 208 // A single-use constant should always be propagted to its use site.
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 return new Return(e); 553 return new Return(e);
552 } 554 }
553 } 555 }
554 return null; 556 return null;
555 } 557 }
556 558
557 /// Returns an expression equivalent to both [e1] and [e2]. 559 /// Returns an expression equivalent to both [e1] and [e2].
558 /// If non-null is returned, the caller must discard [e1] and [e2] and use 560 /// If non-null is returned, the caller must discard [e1] and [e2] and use
559 /// the resulting expression in the tree. 561 /// the resulting expression in the tree.
560 static Expression combineExpressions(Expression e1, Expression e2) { 562 static Expression combineExpressions(Expression e1, Expression e2) {
561 if (e1 is Variable && e1 == e2) { 563 if (e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable) {
562 --e1.readCount; // Two references become one. 564 --e1.variable.readCount; // Two references become one.
563 return e1; 565 return e1;
564 } 566 }
565 if (e1 is Constant && e2 is Constant && e1.value == e2.value) { 567 if (e1 is Constant && e2 is Constant && e1.value == e2.value) {
566 return e1; 568 return e1;
567 } 569 }
568 return null; 570 return null;
569 } 571 }
570 572
571 /// Try to collapse nested ifs using && and || expressions. 573 /// Try to collapse nested ifs using && and || expressions.
572 /// For example: 574 /// For example:
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 } 648 }
647 649
648 Expression makeCondition(Expression e, bool polarity) { 650 Expression makeCondition(Expression e, bool polarity) {
649 return polarity ? e : new Not(e); 651 return polarity ? e : new Not(e);
650 } 652 }
651 653
652 Statement getBranch(If node, bool polarity) { 654 Statement getBranch(If node, bool polarity) {
653 return polarity ? node.thenStatement : node.elseStatement; 655 return polarity ? node.thenStatement : node.elseStatement;
654 } 656 }
655 } 657 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698