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 |