| 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 dart2js.cps_ir.shrinking_reductions; | 5 library dart2js.cps_ir.shrinking_reductions; |
| 6 | 6 |
| 7 import 'cps_ir_nodes.dart'; | 7 import 'cps_ir_nodes.dart'; |
| 8 import 'optimizers.dart'; | 8 import 'optimizers.dart'; |
| 9 | 9 |
| 10 /** | 10 /** |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 131 |
| 132 // Replace its invocation with the continuation body. | 132 // Replace its invocation with the continuation body. |
| 133 InvokeContinuation invoke = cont.firstRef.parent; | 133 InvokeContinuation invoke = cont.firstRef.parent; |
| 134 InteriorNode invokeParent = invoke.parent; | 134 InteriorNode invokeParent = invoke.parent; |
| 135 | 135 |
| 136 cont.body.parent = invokeParent; | 136 cont.body.parent = invokeParent; |
| 137 invokeParent.body = cont.body; | 137 invokeParent.body = cont.body; |
| 138 | 138 |
| 139 // Substitute the invocation argument for the continuation parameter. | 139 // Substitute the invocation argument for the continuation parameter. |
| 140 for (int i = 0; i < invoke.arguments.length; i++) { | 140 for (int i = 0; i < invoke.arguments.length; i++) { |
| 141 Reference argRef = invoke.arguments[i]; | 141 cont.parameters[i].replaceUsesWith(invoke.arguments[i].definition); |
| 142 argRef.definition.substituteFor(cont.parameters[i]); | |
| 143 } | 142 } |
| 144 | 143 |
| 145 // Perform bookkeeping on substituted body and scan for new redexes. | 144 // Perform bookkeeping on substituted body and scan for new redexes. |
| 146 new _RemovalVisitor(_worklist).visit(invoke); | 145 new _RemovalVisitor(_worklist).visit(invoke); |
| 147 } | 146 } |
| 148 | 147 |
| 149 /// Applies the eta-cont reduction: | 148 /// Applies the eta-cont reduction: |
| 150 /// letcont k x = j x in E -> E[j/k]. | 149 /// letcont k x = j x in E -> E[j/k]. |
| 151 /// If k is unused, degenerates to dead-cont. | 150 /// If k is unused, degenerates to dead-cont. |
| 152 void _reduceEtaCont(_ReductionTask task) { | 151 void _reduceEtaCont(_ReductionTask task) { |
| 153 // Might have been mutated, recheck if reduction is still valid. | 152 // Might have been mutated, recheck if reduction is still valid. |
| 154 // In the following example, the eta-cont reduction of k1 could have been | 153 // In the following example, the eta-cont reduction of k1 could have been |
| 155 // invalidated by an earlier beta-cont-lin reduction of k0. | 154 // invalidated by an earlier beta-cont-lin reduction of k0. |
| 156 // | 155 // |
| 157 // letcont k0 x0 = E0 in | 156 // letcont k0 x0 = E0 in |
| 158 // letcont k1 x1 = k0 x1 in E1 | 157 // letcont k1 x1 = k0 x1 in E1 |
| 159 if (!_isEtaCont(task.node)) { | 158 if (!_isEtaCont(task.node)) { |
| 160 return; | 159 return; |
| 161 } | 160 } |
| 162 | 161 |
| 163 // Remove the continuation. | 162 // Remove the continuation. |
| 164 Continuation cont = task.node; | 163 Continuation cont = task.node; |
| 165 _removeContinuation(cont); | 164 _removeContinuation(cont); |
| 166 | 165 |
| 167 InvokeContinuation invoke = cont.body; | 166 InvokeContinuation invoke = cont.body; |
| 168 Continuation wrappedCont = invoke.continuation.definition; | 167 Continuation wrappedCont = invoke.continuation.definition; |
| 169 | 168 |
| 170 // Replace all occurrences with the wrapped continuation. | 169 // Replace all occurrences with the wrapped continuation. |
| 171 wrappedCont.substituteFor(cont); | 170 cont.replaceUsesWith(wrappedCont); |
| 172 | 171 |
| 173 // Perform bookkeeping on removed body and scan for new redexes. | 172 // Perform bookkeeping on removed body and scan for new redexes. |
| 174 new _RemovalVisitor(_worklist).visit(cont); | 173 new _RemovalVisitor(_worklist).visit(cont); |
| 175 } | 174 } |
| 176 | 175 |
| 177 void _reduceDeadParameter(_ReductionTask task) { | 176 void _reduceDeadParameter(_ReductionTask task) { |
| 178 // Continuation eta-reduction can destroy a dead parameter redex. For | 177 // Continuation eta-reduction can destroy a dead parameter redex. For |
| 179 // example, in the term: | 178 // example, in the term: |
| 180 // | 179 // |
| 181 // let cont k0(v0) = /* v0 is not used */ in | 180 // let cont k0(v0) = /* v0 is not used */ in |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 513 |
| 515 String toString() => "$kind: $node"; | 514 String toString() => "$kind: $node"; |
| 516 } | 515 } |
| 517 | 516 |
| 518 /// A dummy class used solely to mark nodes as deleted once they are removed | 517 /// A dummy class used solely to mark nodes as deleted once they are removed |
| 519 /// from a term. | 518 /// from a term. |
| 520 class _DeletedNode extends Node { | 519 class _DeletedNode extends Node { |
| 521 accept(_) {} | 520 accept(_) {} |
| 522 setParentPointers() {} | 521 setParentPointers() {} |
| 523 } | 522 } |
| OLD | NEW |