Chromium Code Reviews| 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 import 'cps_fragment.dart'; | 9 import 'cps_fragment.dart'; |
| 10 | 10 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 // Replace its invocation with the continuation body. | 134 // Replace its invocation with the continuation body. |
| 135 InvokeContinuation invoke = cont.firstRef.parent; | 135 InvokeContinuation invoke = cont.firstRef.parent; |
| 136 InteriorNode invokeParent = invoke.parent; | 136 InteriorNode invokeParent = invoke.parent; |
| 137 | 137 |
| 138 cont.body.parent = invokeParent; | 138 cont.body.parent = invokeParent; |
| 139 invokeParent.body = cont.body; | 139 invokeParent.body = cont.body; |
| 140 | 140 |
| 141 // Substitute the invocation argument for the continuation parameter. | 141 // Substitute the invocation argument for the continuation parameter. |
| 142 for (int i = 0; i < invoke.arguments.length; i++) { | 142 for (int i = 0; i < invoke.arguments.length; i++) { |
| 143 cont.parameters[i].replaceUsesWith(invoke.arguments[i].definition); | 143 cont.parameters[i].replaceUsesWith(invoke.arguments[i].definition); |
| 144 invoke.arguments[i].definition.useElementAsHint(cont.parameters[i].hint); | |
|
Kevin Millikin (Google)
2016/01/12 20:10:05
This would be clearer if the name useElementAsHint
asgerf
2016/01/12 20:21:31
Now that we have the ??= operator maybe we should
| |
| 144 } | 145 } |
| 145 | 146 |
| 146 // Perform bookkeeping on substituted body and scan for new redexes. | 147 // Perform bookkeeping on substituted body and scan for new redexes. |
| 147 new _RemovalVisitor(_worklist).visit(invoke); | 148 new _RemovalVisitor(_worklist).visit(invoke); |
| 148 } | 149 } |
| 149 | 150 |
| 150 /// Applies the eta-cont reduction: | 151 /// Applies the eta-cont reduction: |
| 151 /// letcont k x = j x in E -> E[j/k]. | 152 /// letcont k x = j x in E -> E[j/k]. |
| 152 /// If k is unused, degenerates to dead-cont. | 153 /// If k is unused, degenerates to dead-cont. |
| 153 void _reduceEtaCont(_ReductionTask task) { | 154 void _reduceEtaCont(_ReductionTask task) { |
| 154 // Might have been mutated, recheck if reduction is still valid. | 155 // Might have been mutated, recheck if reduction is still valid. |
| 155 // In the following example, the eta-cont reduction of k1 could have been | 156 // In the following example, the eta-cont reduction of k1 could have been |
| 156 // invalidated by an earlier beta-cont-lin reduction of k0. | 157 // invalidated by an earlier beta-cont-lin reduction of k0. |
| 157 // | 158 // |
| 158 // letcont k0 x0 = E0 in | 159 // letcont k0 x0 = E0 in |
| 159 // letcont k1 x1 = k0 x1 in E1 | 160 // letcont k1 x1 = k0 x1 in E1 |
| 160 if (!_isEtaCont(task.node)) { | 161 if (!_isEtaCont(task.node)) { |
| 161 return; | 162 return; |
| 162 } | 163 } |
| 163 | 164 |
| 164 // Remove the continuation. | 165 // Remove the continuation. |
| 165 Continuation cont = task.node; | 166 Continuation cont = task.node; |
| 166 _removeContinuation(cont); | 167 _removeContinuation(cont); |
| 167 | 168 |
| 168 InvokeContinuation invoke = cont.body; | 169 InvokeContinuation invoke = cont.body; |
| 169 Continuation wrappedCont = invoke.continuation.definition; | 170 Continuation wrappedCont = invoke.continuation.definition; |
| 170 | 171 |
| 172 for (int i = 0; i < cont.parameters.length; ++i) { | |
| 173 wrappedCont.parameters[i].useElementAsHint(cont.parameters[i].hint); | |
| 174 } | |
| 175 | |
| 171 // If the invocation of wrappedCont is escaping, then all invocations of | 176 // If the invocation of wrappedCont is escaping, then all invocations of |
| 172 // cont will be as well, after the reduction. | 177 // cont will be as well, after the reduction. |
| 173 if (invoke.isEscapingTry) { | 178 if (invoke.isEscapingTry) { |
| 174 Reference current = cont.firstRef; | 179 Reference current = cont.firstRef; |
| 175 while (current != null) { | 180 while (current != null) { |
| 176 InvokeContinuation owner = current.parent; | 181 InvokeContinuation owner = current.parent; |
| 177 owner.isEscapingTry = true; | 182 owner.isEscapingTry = true; |
| 178 current = current.next; | 183 current = current.next; |
| 179 } | 184 } |
| 180 } | 185 } |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 527 | 532 |
| 528 String toString() => "$kind: $node"; | 533 String toString() => "$kind: $node"; |
| 529 } | 534 } |
| 530 | 535 |
| 531 /// A dummy class used solely to mark nodes as deleted once they are removed | 536 /// A dummy class used solely to mark nodes as deleted once they are removed |
| 532 /// from a term. | 537 /// from a term. |
| 533 class _DeletedNode extends Node { | 538 class _DeletedNode extends Node { |
| 534 accept(_) {} | 539 accept(_) {} |
| 535 setParentPointers() {} | 540 setParentPointers() {} |
| 536 } | 541 } |
| OLD | NEW |