| 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 part of dart2js.optimizers; | 5 part of dart2js.cps_ir.optimizers; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described | 8 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described |
| 9 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. | 9 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. |
| 10 */ | 10 */ |
| 11 class ShrinkingReducer extends Pass { | 11 class ShrinkingReducer extends PassMixin { |
| 12 _RedexVisitor _redexVisitor; | 12 _RedexVisitor _redexVisitor; |
| 13 Set<_ReductionTask> _worklist; | 13 Set<_ReductionTask> _worklist; |
| 14 | 14 |
| 15 static final _DeletedNode _DELETED = new _DeletedNode(); | 15 static final _DeletedNode _DELETED = new _DeletedNode(); |
| 16 | 16 |
| 17 /// Applies shrinking reductions to root, mutating root in the process. |
| 18 @override |
| 17 void rewriteExecutableDefinition(ExecutableDefinition root) { | 19 void rewriteExecutableDefinition(ExecutableDefinition root) { |
| 18 _worklist = new Set<_ReductionTask>(); | 20 _worklist = new Set<_ReductionTask>(); |
| 19 _redexVisitor = new _RedexVisitor(_worklist); | 21 _redexVisitor = new _RedexVisitor(_worklist); |
| 20 | 22 |
| 21 // Set all parent pointers. | 23 // Set all parent pointers. |
| 22 new ParentVisitor().visit(root); | 24 new ParentVisitor().visit(root); |
| 23 | 25 |
| 24 // Sweep over the term, collecting redexes into the worklist. | 26 // Sweep over the term, collecting redexes into the worklist. |
| 25 _redexVisitor.visit(root); | 27 _redexVisitor.visit(root); |
| 26 | 28 |
| 27 // Process the worklist. | 29 // Process the worklist. |
| 28 while (_worklist.isNotEmpty) { | 30 while (_worklist.isNotEmpty) { |
| 29 _ReductionTask task = _worklist.first; | 31 _ReductionTask task = _worklist.first; |
| 30 _worklist.remove(task); | 32 _worklist.remove(task); |
| 31 _processTask(task); | 33 _processTask(task); |
| 32 } | 34 } |
| 33 } | 35 } |
| 34 | 36 |
| 35 /// Applies shrinking reductions to root, mutating root in the process. | |
| 36 void rewriteFieldDefinition(FieldDefinition root) { | |
| 37 if (!root.hasInitializer) return; | |
| 38 rewriteExecutableDefinition(root); | |
| 39 } | |
| 40 | |
| 41 /// Applies shrinking reductions to root, mutating root in the process. | |
| 42 void rewriteFunctionDefinition(FunctionDefinition root) { | |
| 43 if (root.isAbstract) return; | |
| 44 rewriteExecutableDefinition(root); | |
| 45 } | |
| 46 | |
| 47 /// Removes the given node from the CPS graph, replacing it with its body | 37 /// Removes the given node from the CPS graph, replacing it with its body |
| 48 /// and marking it as deleted. The node's parent must be a [[InteriorNode]]. | 38 /// and marking it as deleted. The node's parent must be a [[InteriorNode]]. |
| 49 void _removeNode(InteriorNode node) { | 39 void _removeNode(InteriorNode node) { |
| 50 Node body = node.body; | 40 Node body = node.body; |
| 51 InteriorNode parent = node.parent; | 41 InteriorNode parent = node.parent; |
| 52 assert(parent.body == node); | 42 assert(parent.body == node); |
| 53 | 43 |
| 54 body.parent = parent; | 44 body.parent = parent; |
| 55 parent.body = body; | 45 parent.body = body; |
| 56 node.parent = _DELETED; | 46 node.parent = _DELETED; |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 if (parent is LetCont && _isDeadCont(parent)) { | 287 if (parent is LetCont && _isDeadCont(parent)) { |
| 298 worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, parent)); | 288 worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, parent)); |
| 299 } | 289 } |
| 300 } | 290 } |
| 301 } | 291 } |
| 302 } | 292 } |
| 303 | 293 |
| 304 /// Traverses the CPS term and sets node.parent for each visited node. | 294 /// Traverses the CPS term and sets node.parent for each visited node. |
| 305 class ParentVisitor extends RecursiveVisitor { | 295 class ParentVisitor extends RecursiveVisitor { |
| 306 | 296 |
| 307 processFieldDefinition(FieldDefinition node) { | |
| 308 node.body.parent = node; | |
| 309 } | |
| 310 | |
| 311 processFunctionDefinition(FunctionDefinition node) { | 297 processFunctionDefinition(FunctionDefinition node) { |
| 312 node.body.parent = node; | 298 node.body.parent = node; |
| 313 node.parameters.forEach((Definition p) => p.parent = node); | 299 node.parameters.forEach((Definition p) => p.parent = node); |
| 314 } | 300 } |
| 315 | 301 |
| 302 processRunnableBody(RunnableBody node) { |
| 303 node.body.parent = node; |
| 304 } |
| 305 |
| 306 processConstructorDefinition(ConstructorDefinition node) { |
| 307 node.body.parent = node; |
| 308 node.parameters.forEach((Definition p) => p.parent = node); |
| 309 node.initializers.forEach((Initializer i) => i.parent = node); |
| 310 } |
| 311 |
| 316 // Expressions. | 312 // Expressions. |
| 317 | 313 |
| 314 processFieldInitializer(FieldInitializer node) { |
| 315 node.body.body.parent = node; |
| 316 } |
| 317 |
| 318 processSuperInitializer(SuperInitializer node) { |
| 319 node.arguments.forEach( |
| 320 (RunnableBody argument) => argument.body.parent = node); |
| 321 } |
| 322 |
| 318 processLetPrim(LetPrim node) { | 323 processLetPrim(LetPrim node) { |
| 319 node.primitive.parent = node; | 324 node.primitive.parent = node; |
| 320 node.body.parent = node; | 325 node.body.parent = node; |
| 321 } | 326 } |
| 322 | 327 |
| 323 processLetCont(LetCont node) { | 328 processLetCont(LetCont node) { |
| 324 node.continuation.parent = node; | 329 node.continuation.parent = node; |
| 325 node.body.parent = node; | 330 node.body.parent = node; |
| 326 } | 331 } |
| 327 | 332 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 } | 455 } |
| 451 | 456 |
| 452 String toString() => "$kind: $node"; | 457 String toString() => "$kind: $node"; |
| 453 } | 458 } |
| 454 | 459 |
| 455 /// A dummy class used solely to mark nodes as deleted once they are removed | 460 /// A dummy class used solely to mark nodes as deleted once they are removed |
| 456 /// from a term. | 461 /// from a term. |
| 457 class _DeletedNode extends Node { | 462 class _DeletedNode extends Node { |
| 458 accept(_) => null; | 463 accept(_) => null; |
| 459 } | 464 } |
| OLD | NEW |