| 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 | 10 |
| 10 /** | 11 /** |
| 11 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described | 12 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described |
| 12 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. | 13 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. |
| 13 */ | 14 */ |
| 14 class ShrinkingReducer extends Pass { | 15 class ShrinkingReducer extends Pass { |
| 15 String get passName => 'Shrinking reductions'; | 16 String get passName => 'Shrinking reductions'; |
| 16 | 17 |
| 17 List<_ReductionTask> _worklist; | 18 List<_ReductionTask> _worklist; |
| 18 | 19 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 assert(false); | 85 assert(false); |
| 85 } | 86 } |
| 86 } | 87 } |
| 87 | 88 |
| 88 /// Applies the dead-val reduction: | 89 /// Applies the dead-val reduction: |
| 89 /// letprim x = V in E -> E (x not free in E). | 90 /// letprim x = V in E -> E (x not free in E). |
| 90 void _reduceDeadVal(_ReductionTask task) { | 91 void _reduceDeadVal(_ReductionTask task) { |
| 91 assert(_isDeadVal(task.node)); | 92 assert(_isDeadVal(task.node)); |
| 92 | 93 |
| 93 // Remove dead primitive. | 94 // Remove dead primitive. |
| 94 LetPrim letPrim = task.node;; | 95 LetPrim letPrim = task.node; |
| 96 destroyRefinementsOfDeadPrimitive(letPrim.primitive); |
| 95 _removeNode(letPrim); | 97 _removeNode(letPrim); |
| 96 | 98 |
| 97 // Perform bookkeeping on removed body and scan for new redexes. | 99 // Perform bookkeeping on removed body and scan for new redexes. |
| 98 new _RemovalVisitor(_worklist).visit(letPrim.primitive); | 100 new _RemovalVisitor(_worklist).visit(letPrim.primitive); |
| 99 } | 101 } |
| 100 | 102 |
| 101 /// Applies the dead-cont reduction: | 103 /// Applies the dead-cont reduction: |
| 102 /// letcont k x = E0 in E1 -> E1 (k not free in E1). | 104 /// letcont k x = E0 in E1 -> E1 (k not free in E1). |
| 103 void _reduceDeadCont(_ReductionTask task) { | 105 void _reduceDeadCont(_ReductionTask task) { |
| 104 assert(_isDeadCont(task.node)); | 106 assert(_isDeadCont(task.node)); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 // Removing an unused parameter can create an eta-redex. | 237 // Removing an unused parameter can create an eta-redex. |
| 236 if (_isEtaCont(continuation)) { | 238 if (_isEtaCont(continuation)) { |
| 237 _worklist.add(new _ReductionTask(_ReductionKind.ETA_CONT, continuation)); | 239 _worklist.add(new _ReductionTask(_ReductionKind.ETA_CONT, continuation)); |
| 238 } | 240 } |
| 239 } | 241 } |
| 240 } | 242 } |
| 241 | 243 |
| 242 /// Returns true iff the bound primitive is unused, and has no effects | 244 /// Returns true iff the bound primitive is unused, and has no effects |
| 243 /// preventing it from being eliminated. | 245 /// preventing it from being eliminated. |
| 244 bool _isDeadVal(LetPrim node) { | 246 bool _isDeadVal(LetPrim node) { |
| 245 return node.primitive.hasNoUses && node.primitive.isSafeForElimination; | 247 return node.primitive.hasNoEffectiveUses && |
| 248 node.primitive.isSafeForElimination; |
| 246 } | 249 } |
| 247 | 250 |
| 248 /// Returns true iff the continuation is unused. | 251 /// Returns true iff the continuation is unused. |
| 249 bool _isDeadCont(Continuation cont) { | 252 bool _isDeadCont(Continuation cont) { |
| 250 return !cont.isReturnContinuation && !cont.hasAtLeastOneUse; | 253 return !cont.isReturnContinuation && !cont.hasAtLeastOneUse; |
| 251 } | 254 } |
| 252 | 255 |
| 253 /// Returns true iff the continuation has a body (i.e., it is not the return | 256 /// Returns true iff the continuation has a body (i.e., it is not the return |
| 254 /// continuation), it is used exactly once, and that use is as the continuation | 257 /// continuation), it is used exactly once, and that use is as the continuation |
| 255 /// of a continuation invocation. | 258 /// of a continuation invocation. |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 | 527 |
| 525 String toString() => "$kind: $node"; | 528 String toString() => "$kind: $node"; |
| 526 } | 529 } |
| 527 | 530 |
| 528 /// A dummy class used solely to mark nodes as deleted once they are removed | 531 /// A dummy class used solely to mark nodes as deleted once they are removed |
| 529 /// from a term. | 532 /// from a term. |
| 530 class _DeletedNode extends Node { | 533 class _DeletedNode extends Node { |
| 531 accept(_) {} | 534 accept(_) {} |
| 532 setParentPointers() {} | 535 setParentPointers() {} |
| 533 } | 536 } |
| OLD | NEW |