| OLD | NEW |
| 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.statement_rewriter; | 5 library tree_ir.optimization.statement_rewriter; |
| 6 | 6 |
| 7 import 'optimization.dart' show Pass; | 7 import 'optimization.dart' show Pass; |
| 8 import '../tree_ir_nodes.dart'; | 8 import '../tree_ir_nodes.dart'; |
| 9 import '../../io/source_information.dart'; | 9 import '../../io/source_information.dart'; |
| 10 import '../../elements/elements.dart'; | 10 import '../../elements/elements.dart'; |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 /// If the given expression always returns the value of one of its | 232 /// If the given expression always returns the value of one of its |
| 233 /// subexpressions, returns that subexpression, otherwise `null`. | 233 /// subexpressions, returns that subexpression, otherwise `null`. |
| 234 Expression getValueSubexpression(Expression e) { | 234 Expression getValueSubexpression(Expression e) { |
| 235 if (e is SetField) return e.value; | 235 if (e is SetField) return e.value; |
| 236 return null; | 236 return null; |
| 237 } | 237 } |
| 238 | 238 |
| 239 /// If the given expression always returns the value of one of its | 239 /// If the given expression always returns the value of one of its |
| 240 /// subexpressions, and that subexpression is a variable use, returns that | 240 /// subexpressions, and that subexpression is a variable use, returns that |
| 241 /// variable. Otherwise `null`. | 241 /// variable. Otherwise `null`. |
| 242 Variable getRightHand(Expression e) { | 242 Variable getRightHandVariable(Expression e) { |
| 243 Expression value = getValueSubexpression(e); | 243 Expression value = getValueSubexpression(e); |
| 244 return value is VariableUse ? value.variable : null; | 244 return value is VariableUse ? value.variable : null; |
| 245 } | 245 } |
| 246 | 246 |
| 247 Constant getRightHandConstant(Expression e) { |
| 248 Expression value = getValueSubexpression(e); |
| 249 return value is Constant ? value : null; |
| 250 } |
| 251 |
| 247 /// True if the given expression (taken from [constantEnvironment]) uses a | 252 /// True if the given expression (taken from [constantEnvironment]) uses a |
| 248 /// variable that might have been reassigned since [node] was evaluated. | 253 /// variable that might have been reassigned since [node] was evaluated. |
| 249 bool hasUnsafeVariableUse(Expression node) { | 254 bool hasUnsafeVariableUse(Expression node) { |
| 250 bool wasFound = false; | 255 bool wasFound = false; |
| 251 VariableUseVisitor.visit(node, (VariableUse use) { | 256 VariableUseVisitor.visit(node, (VariableUse use) { |
| 252 if (dominatingAssignments[use.variable] > 1) { | 257 if (dominatingAssignments[use.variable] > 1) { |
| 253 wasFound = true; | 258 wasFound = true; |
| 254 } | 259 } |
| 255 }); | 260 }); |
| 256 return wasFound; | 261 return wasFound; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 return visitExpression(binding); | 320 return visitExpression(binding); |
| 316 } | 321 } |
| 317 | 322 |
| 318 // Is the most recently evaluated impure expression known to have the | 323 // Is the most recently evaluated impure expression known to have the |
| 319 // value of this variable? | 324 // value of this variable? |
| 320 // | 325 // |
| 321 // If so, we can replace this use with the impure expression, e.g: | 326 // If so, we can replace this use with the impure expression, e.g: |
| 322 // | 327 // |
| 323 // { E.foo = x; bar(x) } ==> bar(E.foo = x) | 328 // { E.foo = x; bar(x) } ==> bar(E.foo = x) |
| 324 // | 329 // |
| 325 if (getRightHand(binding) == node.variable) { | 330 if (getRightHandVariable(binding) == node.variable) { |
| 326 environment.removeLast(); | 331 environment.removeLast(); |
| 327 --node.variable.readCount; | 332 --node.variable.readCount; |
| 328 return visitExpression(binding); | 333 return visitExpression(binding); |
| 329 } | 334 } |
| 330 } | 335 } |
| 331 | 336 |
| 332 // If the definition could not be propagated, leave the variable use. | 337 // If the definition could not be propagated, leave the variable use. |
| 333 return node; | 338 return node; |
| 334 } | 339 } |
| 335 | 340 |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 }); | 583 }); |
| 579 | 584 |
| 580 return node; | 585 return node; |
| 581 } | 586 } |
| 582 | 587 |
| 583 Expression visitNot(Not node) { | 588 Expression visitNot(Not node) { |
| 584 node.operand = visitExpression(node.operand); | 589 node.operand = visitExpression(node.operand); |
| 585 return node; | 590 return node; |
| 586 } | 591 } |
| 587 | 592 |
| 593 bool isNullConstant(Expression node) { |
| 594 return node is Constant && node.value.isNull; |
| 595 } |
| 596 |
| 588 Statement visitReturn(Return node) { | 597 Statement visitReturn(Return node) { |
| 589 node.value = visitExpression(node.value); | 598 if (!isNullConstant(node.value)) { |
| 599 // Do not chain assignments into a null return. |
| 600 node.value = visitExpression(node.value); |
| 601 } |
| 590 return node; | 602 return node; |
| 591 } | 603 } |
| 592 | 604 |
| 593 Statement visitThrow(Throw node) { | 605 Statement visitThrow(Throw node) { |
| 594 node.value = visitExpression(node.value); | 606 node.value = visitExpression(node.value); |
| 595 return node; | 607 return node; |
| 596 } | 608 } |
| 597 | 609 |
| 598 Statement visitRethrow(Rethrow node) { | 610 Statement visitRethrow(Rethrow node) { |
| 599 return node; | 611 return node; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 node.tryBody = visitStatement(node.tryBody); | 714 node.tryBody = visitStatement(node.tryBody); |
| 703 safeForInlining = saved; | 715 safeForInlining = saved; |
| 704 node.catchParameters.forEach(pushDominatingAssignment); | 716 node.catchParameters.forEach(pushDominatingAssignment); |
| 705 node.catchBody = visitStatement(node.catchBody); | 717 node.catchBody = visitStatement(node.catchBody); |
| 706 node.catchParameters.forEach(popDominatingAssignment); | 718 node.catchParameters.forEach(popDominatingAssignment); |
| 707 }); | 719 }); |
| 708 return node; | 720 return node; |
| 709 } | 721 } |
| 710 | 722 |
| 711 Expression visitConstant(Constant node) { | 723 Expression visitConstant(Constant node) { |
| 724 if (!environment.isEmpty) { |
| 725 Constant constant = getRightHandConstant(environment.last); |
| 726 if (constant != null && constant.value == node.value) { |
| 727 return visitExpression(environment.removeLast()); |
| 728 } |
| 729 } |
| 712 return node; | 730 return node; |
| 713 } | 731 } |
| 714 | 732 |
| 715 Expression visitThis(This node) { | 733 Expression visitThis(This node) { |
| 716 return node; | 734 return node; |
| 717 } | 735 } |
| 718 | 736 |
| 719 Expression visitLiteralList(LiteralList node) { | 737 Expression visitLiteralList(LiteralList node) { |
| 720 _rewriteList(node.values); | 738 _rewriteList(node.values); |
| 721 return node; | 739 return node; |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 VariableUseCallback callback; | 1308 VariableUseCallback callback; |
| 1291 | 1309 |
| 1292 VariableUseVisitor(this.callback); | 1310 VariableUseVisitor(this.callback); |
| 1293 | 1311 |
| 1294 visitVariableUse(VariableUse use) => callback(use); | 1312 visitVariableUse(VariableUse use) => callback(use); |
| 1295 | 1313 |
| 1296 static void visit(Expression node, VariableUseCallback callback) { | 1314 static void visit(Expression node, VariableUseCallback callback) { |
| 1297 new VariableUseVisitor(callback).visitExpression(node); | 1315 new VariableUseVisitor(callback).visitExpression(node); |
| 1298 } | 1316 } |
| 1299 } | 1317 } |
| OLD | NEW |