| 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 /** |
| 11 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described | 11 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described |
| 12 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. | 12 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. |
| 13 */ | 13 */ |
| 14 class ShrinkingReducer extends Pass { | 14 class ShrinkingReducer extends Pass { |
| 15 String get passName => 'Shrinking reductions'; | 15 String get passName => 'Shrinking reductions'; |
| 16 | 16 |
| 17 Set<_ReductionTask> _worklist; | 17 List<_ReductionTask> _worklist; |
| 18 | 18 |
| 19 static final _DeletedNode _DELETED = new _DeletedNode(); | 19 static final _DeletedNode _DELETED = new _DeletedNode(); |
| 20 | 20 |
| 21 /// Applies shrinking reductions to root, mutating root in the process. | 21 /// Applies shrinking reductions to root, mutating root in the process. |
| 22 @override | 22 @override |
| 23 void rewrite(FunctionDefinition root) { | 23 void rewrite(FunctionDefinition root) { |
| 24 _worklist = new Set<_ReductionTask>(); | 24 _worklist = new List<_ReductionTask>(); |
| 25 _RedexVisitor redexVisitor = new _RedexVisitor(_worklist); | 25 _RedexVisitor redexVisitor = new _RedexVisitor(_worklist); |
| 26 | 26 |
| 27 // Set all parent pointers. | 27 // Set all parent pointers. |
| 28 new ParentVisitor().visit(root); | 28 new ParentVisitor().visit(root); |
| 29 | 29 |
| 30 // Sweep over the term, collecting redexes into the worklist. | 30 // Sweep over the term, collecting redexes into the worklist. |
| 31 redexVisitor.visit(root); | 31 redexVisitor.visit(root); |
| 32 | 32 |
| 33 // Process the worklist. | 33 // Process the worklist. |
| 34 while (_worklist.isNotEmpty) { | 34 while (_worklist.isNotEmpty) { |
| 35 _ReductionTask task = _worklist.first; | 35 _ReductionTask task = _worklist.removeLast(); |
| 36 _worklist.remove(task); | |
| 37 _processTask(task); | 36 _processTask(task); |
| 38 } | 37 } |
| 39 } | 38 } |
| 40 | 39 |
| 41 /// Removes the given node from the CPS graph, replacing it with its body | 40 /// Removes the given node from the CPS graph, replacing it with its body |
| 42 /// and marking it as deleted. The node's parent must be a [[InteriorNode]]. | 41 /// and marking it as deleted. The node's parent must be a [[InteriorNode]]. |
| 43 void _removeNode(InteriorNode node) { | 42 void _removeNode(InteriorNode node) { |
| 44 Node body = node.body; | 43 Node body = node.body; |
| 45 InteriorNode parent = node.parent; | 44 InteriorNode parent = node.parent; |
| 46 assert(parent.body == node); | 45 assert(parent.body == node); |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 if (current.parent is! InvokeContinuation) return false; | 392 if (current.parent is! InvokeContinuation) return false; |
| 394 InvokeContinuation invoke = current.parent; | 393 InvokeContinuation invoke = current.parent; |
| 395 if (invoke.continuation.definition != continuation) return false; | 394 if (invoke.continuation.definition != continuation) return false; |
| 396 current = current.next; | 395 current = current.next; |
| 397 } | 396 } |
| 398 return true; | 397 return true; |
| 399 } | 398 } |
| 400 | 399 |
| 401 /// Traverses a term and adds any found redexes to the worklist. | 400 /// Traverses a term and adds any found redexes to the worklist. |
| 402 class _RedexVisitor extends RecursiveVisitor { | 401 class _RedexVisitor extends RecursiveVisitor { |
| 403 final Set<_ReductionTask> worklist; | 402 final List<_ReductionTask> worklist; |
| 404 | 403 |
| 405 _RedexVisitor(this.worklist); | 404 _RedexVisitor(this.worklist); |
| 406 | 405 |
| 407 void processLetPrim(LetPrim node) { | 406 void processLetPrim(LetPrim node) { |
| 408 if (_isDeadVal(node)) { | 407 if (_isDeadVal(node)) { |
| 409 worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, node)); | 408 worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, node)); |
| 410 } | 409 } |
| 411 } | 410 } |
| 412 | 411 |
| 413 void processContinuation(Continuation node) { | 412 void processContinuation(Continuation node) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 439 } | 438 } |
| 440 } | 439 } |
| 441 | 440 |
| 442 /// Traverses a deleted CPS term, marking nodes that might participate in a | 441 /// Traverses a deleted CPS term, marking nodes that might participate in a |
| 443 /// redex as deleted and adding newly created redexes to the worklist. | 442 /// redex as deleted and adding newly created redexes to the worklist. |
| 444 /// | 443 /// |
| 445 /// Deleted nodes that might participate in a reduction task are marked so that | 444 /// Deleted nodes that might participate in a reduction task are marked so that |
| 446 /// any corresponding tasks can be skipped. Nodes are marked so by setting | 445 /// any corresponding tasks can be skipped. Nodes are marked so by setting |
| 447 /// their parent to the deleted sentinel. | 446 /// their parent to the deleted sentinel. |
| 448 class _RemovalVisitor extends RecursiveVisitor { | 447 class _RemovalVisitor extends RecursiveVisitor { |
| 449 final Set<_ReductionTask> worklist; | 448 final List<_ReductionTask> worklist; |
| 450 | 449 |
| 451 _RemovalVisitor(this.worklist); | 450 _RemovalVisitor(this.worklist); |
| 452 | 451 |
| 453 void processLetPrim(LetPrim node) { | 452 void processLetPrim(LetPrim node) { |
| 454 node.parent = ShrinkingReducer._DELETED; | 453 node.parent = ShrinkingReducer._DELETED; |
| 455 } | 454 } |
| 456 | 455 |
| 457 void processContinuation(Continuation node) { | 456 void processContinuation(Continuation node) { |
| 458 node.parent = ShrinkingReducer._DELETED; | 457 node.parent = ShrinkingReducer._DELETED; |
| 459 } | 458 } |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 } | 726 } |
| 728 | 727 |
| 729 String toString() => "$kind: $node"; | 728 String toString() => "$kind: $node"; |
| 730 } | 729 } |
| 731 | 730 |
| 732 /// A dummy class used solely to mark nodes as deleted once they are removed | 731 /// A dummy class used solely to mark nodes as deleted once they are removed |
| 733 /// from a term. | 732 /// from a term. |
| 734 class _DeletedNode extends Node { | 733 class _DeletedNode extends Node { |
| 735 accept(_) => null; | 734 accept(_) => null; |
| 736 } | 735 } |
| OLD | NEW |