| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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.variable_merger; | 5 library tree_ir.optimization.variable_merger; |
| 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 | 9 |
| 10 /// Merges variables based on liveness and source variable information. | 10 /// Merges variables based on liveness and source variable information. |
| 11 /// | 11 /// |
| 12 /// This phase cleans up artifacts introduced by the translation through CPS, | 12 /// This phase cleans up artifacts introduced by the translation through CPS, |
| 13 /// where each source variable is translated into several copies. The copies | 13 /// where each source variable is translated into several copies. The copies |
| 14 /// are merged again when they are not live simultaneously. | 14 /// are merged again when they are not live simultaneously. |
| 15 class VariableMerger extends RecursiveVisitor implements Pass { | 15 class VariableMerger extends RecursiveVisitor implements Pass { |
| 16 String get passName => 'Variable merger'; | 16 String get passName => 'Variable merger'; |
| 17 | 17 |
| 18 void rewrite(FunctionDefinition node) { | 18 void rewrite(FunctionDefinition node) { |
| 19 rewriteFunction(node); | 19 rewriteFunction(node); |
| 20 visitStatement(node.body); | 20 visitStatement(node.body); |
| 21 } | 21 } |
| 22 | 22 |
| 23 @override | |
| 24 void visitInnerFunction(FunctionDefinition node) { | |
| 25 rewriteFunction(node); | |
| 26 } | |
| 27 | |
| 28 /// Rewrites the given function. | 23 /// Rewrites the given function. |
| 29 /// This is called for the outermost function and inner functions. | 24 /// This is called for the outermost function and inner functions. |
| 30 void rewriteFunction(FunctionDefinition node) { | 25 void rewriteFunction(FunctionDefinition node) { |
| 31 BlockGraphBuilder builder = new BlockGraphBuilder(); | 26 BlockGraphBuilder builder = new BlockGraphBuilder(); |
| 32 builder.build(node); | 27 builder.build(node); |
| 33 _computeLiveness(builder.blocks); | 28 _computeLiveness(builder.blocks); |
| 34 Map<Variable, Variable> subst = | 29 Map<Variable, Variable> subst = |
| 35 _computeRegisterAllocation(builder.blocks, node.parameters); | 30 _computeRegisterAllocation(builder.blocks, node.parameters); |
| 36 new SubstituteVariables(subst).apply(node); | 31 new SubstituteVariables(subst).apply(node); |
| 37 } | 32 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 /// Such variables cannot be merged with any other variables, so we exclude | 100 /// Such variables cannot be merged with any other variables, so we exclude |
| 106 /// them from the control-flow graph entirely. | 101 /// them from the control-flow graph entirely. |
| 107 Set<Variable> _ignoredVariables = new Set<Variable>(); | 102 Set<Variable> _ignoredVariables = new Set<Variable>(); |
| 108 | 103 |
| 109 void build(FunctionDefinition node) { | 104 void build(FunctionDefinition node) { |
| 110 _currentBlock = newBlock(); | 105 _currentBlock = newBlock(); |
| 111 node.parameters.forEach(write); | 106 node.parameters.forEach(write); |
| 112 visitStatement(node.body); | 107 visitStatement(node.body); |
| 113 } | 108 } |
| 114 | 109 |
| 115 @override | |
| 116 void visitInnerFunction(FunctionDefinition node) { | |
| 117 // Do nothing. Inner functions are traversed in VariableMerger. | |
| 118 } | |
| 119 | |
| 120 /// Creates a new block with the current exception handler or [catchBlock] | 110 /// Creates a new block with the current exception handler or [catchBlock] |
| 121 /// if provided. | 111 /// if provided. |
| 122 Block newBlock({Block catchBlock}) { | 112 Block newBlock({Block catchBlock}) { |
| 123 if (catchBlock == null && _currentBlock != null) { | 113 if (catchBlock == null && _currentBlock != null) { |
| 124 catchBlock = _currentBlock.catchBlock; | 114 catchBlock = _currentBlock.catchBlock; |
| 125 } | 115 } |
| 126 Block block = new Block(catchBlock); | 116 Block block = new Block(catchBlock); |
| 127 blocks.add(block); | 117 blocks.add(block); |
| 128 return block; | 118 return block; |
| 129 } | 119 } |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 return w; | 489 return w; |
| 500 } | 490 } |
| 501 | 491 |
| 502 void apply(FunctionDefinition node) { | 492 void apply(FunctionDefinition node) { |
| 503 for (int i = 0; i < node.parameters.length; ++i) { | 493 for (int i = 0; i < node.parameters.length; ++i) { |
| 504 node.parameters[i] = replaceWrite(node.parameters[i]); | 494 node.parameters[i] = replaceWrite(node.parameters[i]); |
| 505 } | 495 } |
| 506 node.body = visitStatement(node.body); | 496 node.body = visitStatement(node.body); |
| 507 } | 497 } |
| 508 | 498 |
| 509 @override | |
| 510 void visitInnerFunction(FunctionDefinition node) { | |
| 511 // Do nothing. Inner functions are traversed in VariableMerger. | |
| 512 } | |
| 513 | |
| 514 Expression visitVariableUse(VariableUse node) { | 499 Expression visitVariableUse(VariableUse node) { |
| 515 node.variable = replaceRead(node.variable); | 500 node.variable = replaceRead(node.variable); |
| 516 return node; | 501 return node; |
| 517 } | 502 } |
| 518 | 503 |
| 519 Expression visitAssign(Assign node) { | 504 Expression visitAssign(Assign node) { |
| 520 node.variable = replaceWrite(node.variable); | 505 node.variable = replaceWrite(node.variable); |
| 521 node.value = visitExpression(node.value); | 506 node.value = visitExpression(node.value); |
| 522 | 507 |
| 523 // Remove assignments of form "x := x" | 508 // Remove assignments of form "x := x" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 536 node.expression = visitExpression(node.expression); | 521 node.expression = visitExpression(node.expression); |
| 537 node.next = visitStatement(node.next); | 522 node.next = visitStatement(node.next); |
| 538 if (node.expression is VariableUse) { | 523 if (node.expression is VariableUse) { |
| 539 VariableUse use = node.expression; | 524 VariableUse use = node.expression; |
| 540 --use.variable.readCount; | 525 --use.variable.readCount; |
| 541 return node.next; | 526 return node.next; |
| 542 } | 527 } |
| 543 return node; | 528 return node; |
| 544 } | 529 } |
| 545 } | 530 } |
| OLD | NEW |