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

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

Issue 1068243002: Overhaul tree IR visitor and rename IR classes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add dummy use for RootVisitor and InitializerVisitor without arguments Created 5 years, 8 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 /// Rewrites logical expressions to be more compact in the Tree IR. 7 /// Rewrites logical expressions to be more compact in the Tree IR.
8 /// 8 ///
9 /// In this class an expression is said to occur in "boolean context" if 9 /// In this class an expression is said to occur in "boolean context" if
10 /// its result is immediately applied to boolean conversion. 10 /// its result is immediately applied to boolean conversion.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 /// 47 ///
48 /// x ? y : false ==> x && y (if y is known to be a boolean) 48 /// x ? y : false ==> x && y (if y is known to be a boolean)
49 /// 49 ///
50 /// The following sequence of rewrites demonstrates the merit of these rules: 50 /// The following sequence of rewrites demonstrates the merit of these rules:
51 /// 51 ///
52 /// x ? (y ? true : false) : false 52 /// x ? (y ? true : false) : false
53 /// x ? !!y : false (double negation introduced by [toBoolean]) 53 /// x ? !!y : false (double negation introduced by [toBoolean])
54 /// x && !!y (!!y validated by [isBooleanValued]) 54 /// x && !!y (!!y validated by [isBooleanValued])
55 /// x && y (double negation removed by [putInBooleanContext]) 55 /// x && y (double negation removed by [putInBooleanContext])
56 /// 56 ///
57 class LogicalRewriter extends Visitor<Statement, Expression> with PassMixin { 57 class LogicalRewriter extends RecursiveTransformer
58 implements Pass {
58 String get passName => 'Logical rewriter'; 59 String get passName => 'Logical rewriter';
59 60
61 @override
62 void rewrite(RootNode node) {
63 node.replaceEachBody(visitStatement);
64 }
65
60 /// Statement to be executed next by natural fallthrough. Although fallthrough 66 /// Statement to be executed next by natural fallthrough. Although fallthrough
61 /// is not introduced in this phase, we need to reason about fallthrough when 67 /// is not introduced in this phase, we need to reason about fallthrough when
62 /// evaluating the benefit of swapping the branches of an [If]. 68 /// evaluating the benefit of swapping the branches of an [If].
63 Statement fallthrough; 69 Statement fallthrough;
64 70
65 void rewriteExecutableDefinition(ExecutableDefinition root) { 71 @override
66 root.body = visitStatement(root.body); 72 void visitInnerFunction(FunctionDefinition node) {
67 } 73 new LogicalRewriter().rewrite(node);
68
69 void rewriteConstructorDefinition(ConstructorDefinition root) {
70 if (root.isAbstract) return;
71 List<Initializer> initializers = root.initializers;
72 for (int i = 0; i < initializers.length; ++i) {
73 initializers[i] = visitExpression(initializers[i]);
74 }
75 root.body = visitStatement(root.body);
76 }
77
78 Expression visitFieldInitializer(FieldInitializer node) {
79 node.body = visitStatement(node.body);
80 return node;
81 }
82
83 visitSuperInitializer(SuperInitializer node) {
84 List<Statement> arguments = node.arguments;
85 for (int i = 0; i < arguments.length; ++i) {
86 arguments[i] = visitStatement(arguments[i]);
87 }
88 return node;
89 } 74 }
90 75
91 Statement visitLabeledStatement(LabeledStatement node) { 76 Statement visitLabeledStatement(LabeledStatement node) {
92 Statement savedFallthrough = fallthrough; 77 Statement savedFallthrough = fallthrough;
93 fallthrough = node.next; 78 fallthrough = node.next;
94 node.body = visitStatement(node.body); 79 node.body = visitStatement(node.body);
95 fallthrough = savedFallthrough; 80 fallthrough = savedFallthrough;
96 node.next = visitStatement(node.next); 81 node.next = visitStatement(node.next);
97 return node; 82 return node;
98 } 83 }
99 84
100 Statement visitAssign(Assign node) {
101 node.value = visitExpression(node.value);
102 node.next = visitStatement(node.next);
103 return node;
104 }
105
106 Statement visitReturn(Return node) {
107 node.value = visitExpression(node.value);
108 return node;
109 }
110
111 Statement visitBreak(Break node) {
112 return node;
113 }
114
115 Statement visitContinue(Continue node) {
116 return node;
117 }
118
119 bool isFallthroughBreak(Statement node) { 85 bool isFallthroughBreak(Statement node) {
120 return node is Break && node.target.binding.next == fallthrough; 86 return node is Break && node.target.binding.next == fallthrough;
121 } 87 }
122 88
123 Statement visitIf(If node) { 89 Statement visitIf(If node) {
124 // If one of the branches is empty (i.e. just a fallthrough), then that 90 // If one of the branches is empty (i.e. just a fallthrough), then that
125 // branch should preferrably be the 'else' so we won't have to print it. 91 // branch should preferrably be the 'else' so we won't have to print it.
126 // In other words, we wish to perform this rewrite: 92 // In other words, we wish to perform this rewrite:
127 // if (E) {} else {S} 93 // if (E) {} else {S}
128 // ==> 94 // ==>
(...skipping 24 matching lines...) Expand all
153 if (!emptyElse && node.condition is Not) { 119 if (!emptyElse && node.condition is Not) {
154 node.condition = (node.condition as Not).operand; 120 node.condition = (node.condition as Not).operand;
155 Statement tmp = node.thenStatement; 121 Statement tmp = node.thenStatement;
156 node.thenStatement = node.elseStatement; 122 node.thenStatement = node.elseStatement;
157 node.elseStatement = tmp; 123 node.elseStatement = tmp;
158 } 124 }
159 125
160 return node; 126 return node;
161 } 127 }
162 128
163 Statement visitWhileTrue(WhileTrue node) {
164 node.body = visitStatement(node.body);
165 return node;
166 }
167
168 Statement visitWhileCondition(WhileCondition node) { 129 Statement visitWhileCondition(WhileCondition node) {
169 node.condition = makeCondition(node.condition, true, liftNots: false); 130 node.condition = makeCondition(node.condition, true, liftNots: false);
170 node.body = visitStatement(node.body); 131 node.body = visitStatement(node.body);
171 node.next = visitStatement(node.next); 132 node.next = visitStatement(node.next);
172 return node; 133 return node;
173 } 134 }
174 135
175 Statement visitTry(Try node) {
176 node.tryBody = visitStatement(node.tryBody);
177 node.catchBody = visitStatement(node.catchBody);
178 return node;
179 }
180
181 Statement visitExpressionStatement(ExpressionStatement node) {
182 node.expression = visitExpression(node.expression);
183 node.next = visitStatement(node.next);
184 return node;
185 }
186
187 Expression visitVariableUse(VariableUse node) {
188 return node;
189 }
190
191 Expression visitInvokeStatic(InvokeStatic node) {
192 _rewriteList(node.arguments);
193 return node;
194 }
195
196 Expression visitInvokeMethod(InvokeMethod node) {
197 node.receiver = visitExpression(node.receiver);
198 _rewriteList(node.arguments);
199 return node;
200 }
201
202 Expression visitInvokeMethodDirectly(InvokeMethodDirectly node) {
203 node.receiver = visitExpression(node.receiver);
204 _rewriteList(node.arguments);
205 return node;
206 }
207
208 Expression visitInvokeConstructor(InvokeConstructor node) {
209 _rewriteList(node.arguments);
210 return node;
211 }
212
213 Expression visitConcatenateStrings(ConcatenateStrings node) {
214 _rewriteList(node.arguments);
215 return node;
216 }
217
218 Expression visitLiteralList(LiteralList node) {
219 _rewriteList(node.values);
220 return node;
221 }
222
223 Expression visitLiteralMap(LiteralMap node) {
224 node.entries.forEach((LiteralMapEntry entry) {
225 entry.key = visitExpression(entry.key);
226 entry.value = visitExpression(entry.value);
227 });
228 return node;
229 }
230
231 Expression visitTypeOperator(TypeOperator node) {
232 node.receiver = visitExpression(node.receiver);
233 return node;
234 }
235
236 Expression visitConstant(Constant node) {
237 return node;
238 }
239
240 Expression visitThis(This node) {
241 return node;
242 }
243
244 Expression visitReifyTypeVar(ReifyTypeVar node) {
245 return node;
246 }
247
248 Expression visitFunctionExpression(FunctionExpression node) {
249 new LogicalRewriter().rewrite(node.definition);
250 return node;
251 }
252
253 Statement visitFunctionDeclaration(FunctionDeclaration node) {
254 new LogicalRewriter().rewrite(node.definition);
255 node.next = visitStatement(node.next);
256 return node;
257 }
258
259 Expression visitNot(Not node) { 136 Expression visitNot(Not node) {
260 return toBoolean(makeCondition(node.operand, false, liftNots: false)); 137 return toBoolean(makeCondition(node.operand, false, liftNots: false));
261 } 138 }
262 139
263 Expression visitConditional(Conditional node) { 140 Expression visitConditional(Conditional node) {
264 // node.condition will be visited after the then and else parts, because its 141 // node.condition will be visited after the then and else parts, because its
265 // polarity depends on what rewrite we use. 142 // polarity depends on what rewrite we use.
266 node.thenExpression = visitExpression(node.thenExpression); 143 node.thenExpression = visitExpression(node.thenExpression);
267 node.elseExpression = visitExpression(node.elseExpression); 144 node.elseExpression = visitExpression(node.elseExpression);
268 145
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 192
316 return node; 193 return node;
317 } 194 }
318 195
319 Expression visitLogicalOperator(LogicalOperator node) { 196 Expression visitLogicalOperator(LogicalOperator node) {
320 node.left = makeCondition(node.left, true); 197 node.left = makeCondition(node.left, true);
321 node.right = makeCondition(node.right, true); 198 node.right = makeCondition(node.right, true);
322 return node; 199 return node;
323 } 200 }
324 201
325 Statement visitSetField(SetField node) {
326 node.object = visitExpression(node.object);
327 node.value = visitExpression(node.value);
328 node.next = visitStatement(node.next);
329 return node;
330 }
331
332 Expression visitGetField(GetField node) {
333 node.object = visitExpression(node.object);
334 return node;
335 }
336
337 Expression visitCreateBox(CreateBox node) {
338 return node;
339 }
340
341 Expression visitCreateInstance(CreateInstance node) {
342 _rewriteList(node.arguments);
343 return node;
344 }
345
346 Expression visitReifyRuntimeType(ReifyRuntimeType node) {
347 node.value = visitExpression(node.value);
348 return node;
349 }
350
351 Expression visitReadTypeVariable(ReadTypeVariable node) {
352 node.target = visitExpression(node.target);
353 return node;
354 }
355
356 /// True if the given expression is known to evaluate to a boolean. 202 /// True if the given expression is known to evaluate to a boolean.
357 /// This will not recursively traverse [Conditional] expressions, but if 203 /// This will not recursively traverse [Conditional] expressions, but if
358 /// applied to the result of [visitExpression] conditionals will have been 204 /// applied to the result of [visitExpression] conditionals will have been
359 /// rewritten anyway. 205 /// rewritten anyway.
360 bool isBooleanValued(Expression e) { 206 bool isBooleanValued(Expression e) {
361 return isTrue(e) || isFalse(e) || e is Not || e is LogicalOperator; 207 return isTrue(e) || isFalse(e) || e is Not || e is LogicalOperator;
362 } 208 }
363 209
364 /// Rewrite an expression that was originally processed in a non-boolean 210 /// Rewrite an expression that was originally processed in a non-boolean
365 /// context. 211 /// context.
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 } 337 }
492 338
493 Expression makeOr(Expression e1, Expression e2, {bool liftNots: true}) { 339 Expression makeOr(Expression e1, Expression e2, {bool liftNots: true}) {
494 if (e1 is Not && e2 is Not && liftNots) { 340 if (e1 is Not && e2 is Not && liftNots) {
495 return new Not(new LogicalOperator.and(e1.operand, e2.operand)); 341 return new Not(new LogicalOperator.and(e1.operand, e2.operand));
496 } else { 342 } else {
497 return new LogicalOperator.or(e1, e2); 343 return new LogicalOperator.or(e1, e2);
498 } 344 }
499 } 345 }
500 346
501 /// Destructively updates each entry of [l] with the result of visiting it.
502 void _rewriteList(List<Expression> l) {
503 for (int i = 0; i < l.length; i++) {
504 l[i] = visitExpression(l[i]);
505 }
506 }
507
508 @override
509 Expression visitTypeExpression(TypeExpression node) {
510 _rewriteList(node.arguments);
511 return node;
512 }
513 } 347 }
514 348
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/tracer.dart ('k') | pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698