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

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

Issue 1291073002: dart2js cps: Add logical rewriter rules to favor null-aware operators. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix reference count Created 5 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 library tree_ir.optimization.logical_rewriter; 5 library tree_ir.optimization.logical_rewriter;
6 6
7 import '../tree_ir_nodes.dart'; 7 import '../tree_ir_nodes.dart';
8 import 'optimization.dart' show Pass; 8 import 'optimization.dart' show Pass;
9 import '../../constants/values.dart' as values; 9 import '../../constants/values.dart' as values;
10 10
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 node.condition = makeCondition(node.condition, true); 299 node.condition = makeCondition(node.condition, true);
300 300
301 // !x ? y : z ==> x ? z : y 301 // !x ? y : z ==> x ? z : y
302 if (node.condition is Not) { 302 if (node.condition is Not) {
303 node.condition = (node.condition as Not).operand; 303 node.condition = (node.condition as Not).operand;
304 Expression tmp = node.thenExpression; 304 Expression tmp = node.thenExpression;
305 node.thenExpression = node.elseExpression; 305 node.thenExpression = node.elseExpression;
306 node.elseExpression = tmp; 306 node.elseExpression = tmp;
307 } 307 }
308 308
309 // x ? y : x ==> x && y
310 if (isSameVariable(node.condition, node.elseExpression)) {
311 destroyVariableUse(node.elseExpression);
312 return new LogicalOperator.and(node.condition, node.thenExpression);
313 }
314 // x ? x : y ==> x || y
315 if (isSameVariable(node.condition, node.thenExpression)) {
316 destroyVariableUse(node.thenExpression);
317 return new LogicalOperator.or(node.condition, node.elseExpression);
318 }
319
309 return node; 320 return node;
310 } 321 }
311 322
312 Expression visitLogicalOperator(LogicalOperator node) { 323 Expression visitLogicalOperator(LogicalOperator node) {
313 node.left = visitExpression(node.left); 324 node.left = visitExpression(node.left);
314 node.right = visitExpression(node.right); 325 node.right = visitExpression(node.right);
315 return node; 326 return node;
316 } 327 }
317 328
318 /// True if the given expression is known to evaluate to a boolean. 329 /// True if the given expression is known to evaluate to a boolean.
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 Expression tmp = e.thenExpression; 472 Expression tmp = e.thenExpression;
462 e.thenExpression = e.elseExpression; 473 e.thenExpression = e.elseExpression;
463 e.elseExpression = tmp; 474 e.elseExpression = tmp;
464 } 475 }
465 // x ? !y : !z ==> !(x ? y : z) (only if lifting nots) 476 // x ? !y : !z ==> !(x ? y : z) (only if lifting nots)
466 if (e.thenExpression is Not && e.elseExpression is Not && liftNots) { 477 if (e.thenExpression is Not && e.elseExpression is Not && liftNots) {
467 e.thenExpression = (e.thenExpression as Not).operand; 478 e.thenExpression = (e.thenExpression as Not).operand;
468 e.elseExpression = (e.elseExpression as Not).operand; 479 e.elseExpression = (e.elseExpression as Not).operand;
469 return new Not(e); 480 return new Not(e);
470 } 481 }
482
483 // x ? y : x ==> x && y
484 if (isSameVariable(e.condition, e.elseExpression)) {
485 destroyVariableUse(e.elseExpression);
486 return new LogicalOperator.and(e.condition, e.thenExpression);
487 }
488 // x ? x : y ==> x || y
489 if (isSameVariable(e.condition, e.thenExpression)) {
490 destroyVariableUse(e.thenExpression);
491 return new LogicalOperator.or(e.condition, e.elseExpression);
492 }
493
471 return e; 494 return e;
472 } 495 }
473 if (e is Constant && e.value.isBool) { 496 if (e is Constant && e.value.isBool) {
474 // !true ==> false 497 // !true ==> false
475 if (!polarity) { 498 if (!polarity) {
476 values.BoolConstantValue value = e.value; 499 values.BoolConstantValue value = e.value;
477 return new Constant.bool(value.negate()); 500 return new Constant.bool(value.negate());
478 } 501 }
479 return e; 502 return e;
480 } 503 }
(...skipping 21 matching lines...) Expand all
502 } 525 }
503 } 526 }
504 527
505 Expression makeOr(Expression e1, Expression e2, {bool liftNots: true}) { 528 Expression makeOr(Expression e1, Expression e2, {bool liftNots: true}) {
506 if (e1 is Not && e2 is Not && liftNots) { 529 if (e1 is Not && e2 is Not && liftNots) {
507 return new Not(new LogicalOperator.and(e1.operand, e2.operand)); 530 return new Not(new LogicalOperator.and(e1.operand, e2.operand));
508 } else { 531 } else {
509 return new LogicalOperator.or(e1, e2); 532 return new LogicalOperator.or(e1, e2);
510 } 533 }
511 } 534 }
535
536 /// True if [e2] is known to return the same value as [e1]
537 /// (with no additional side effects) if evaluated immediately after [e1].
538 ///
539 /// Concretely, this is true if [e1] and [e2] are uses of the same variable,
540 /// or if [e2] is a use of a variable assigned by [e1].
541 bool isSameVariable(Expression e1, Expression e2) {
542 if (e1 is VariableUse) {
543 return e2 is VariableUse && e1.variable == e2.variable;
544 } else if (e1 is Assign) {
545 return e2 is VariableUse && e1.variable == e2.variable;
546 }
547 return false;
548 }
549
550 void destroyVariableUse(VariableUse node) {
551 --node.variable.readCount;
552 }
512 } 553 }
513 554
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698