| 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.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 implements Pass { | 11 class ShrinkingReducer implements Pass { |
| 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. | 17 /// Applies shrinking reductions to root, mutating root in the process. |
| 18 void rewrite(FunctionDefinition root) { | 18 void rewrite(FunctionDefinition root) { |
| 19 if (root.isAbstract) return; | 19 if (root.isAbstract) return; |
| 20 | 20 |
| 21 _worklist = new Set<_ReductionTask>(); | 21 _worklist = new Set<_ReductionTask>(); |
| 22 _redexVisitor = new _RedexVisitor(_worklist); | 22 _redexVisitor = new _RedexVisitor(_worklist); |
| 23 | 23 |
| 24 // Set all parent pointers. | 24 // Set all parent pointers. |
| 25 new _ParentVisitor().visit(root); | 25 new ParentVisitor().visit(root); |
| 26 | 26 |
| 27 // Sweep over the term, collecting redexes into the worklist. | 27 // Sweep over the term, collecting redexes into the worklist. |
| 28 _redexVisitor.visitFunctionDefinition(root); | 28 _redexVisitor.visitFunctionDefinition(root); |
| 29 | 29 |
| 30 // Process the worklist. | 30 // Process the worklist. |
| 31 while (_worklist.isNotEmpty) { | 31 while (_worklist.isNotEmpty) { |
| 32 _ReductionTask task = _worklist.first; | 32 _ReductionTask task = _worklist.first; |
| 33 _worklist.remove(task); | 33 _worklist.remove(task); |
| 34 _processTask(task); | 34 _processTask(task); |
| 35 } | 35 } |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 } | 286 } |
| 287 Node parent = cont.parent; | 287 Node parent = cont.parent; |
| 288 if (parent is LetCont && _isDeadCont(parent)) { | 288 if (parent is LetCont && _isDeadCont(parent)) { |
| 289 worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, parent)); | 289 worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, parent)); |
| 290 } | 290 } |
| 291 } | 291 } |
| 292 } | 292 } |
| 293 } | 293 } |
| 294 | 294 |
| 295 /// Traverses the CPS term and sets node.parent for each visited node. | 295 /// Traverses the CPS term and sets node.parent for each visited node. |
| 296 class _ParentVisitor extends RecursiveVisitor { | 296 class ParentVisitor extends RecursiveVisitor { |
| 297 | 297 |
| 298 processFunctionDefinition(FunctionDefinition node) { | 298 processFunctionDefinition(FunctionDefinition node) { |
| 299 node.body.parent = node; | 299 node.body.parent = node; |
| 300 node.parameters.forEach((Parameter p) => p.parent = node); | 300 node.parameters.forEach((Parameter p) => p.parent = node); |
| 301 } | 301 } |
| 302 | 302 |
| 303 // Expressions. | 303 // Expressions. |
| 304 | 304 |
| 305 processLetPrim(LetPrim node) { | 305 processLetPrim(LetPrim node) { |
| 306 node.primitive.parent = node; | 306 node.primitive.parent = node; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 processContinuation(Continuation node) { | 384 processContinuation(Continuation node) { |
| 385 node.body.parent = node; | 385 node.body.parent = node; |
| 386 node.parameters.forEach((Parameter param) => param.parent = node); | 386 node.parameters.forEach((Parameter param) => param.parent = node); |
| 387 } | 387 } |
| 388 | 388 |
| 389 // Conditions. | 389 // Conditions. |
| 390 | 390 |
| 391 processIsTrue(IsTrue node) { | 391 processIsTrue(IsTrue node) { |
| 392 node.value.parent = node; | 392 node.value.parent = node; |
| 393 } | 393 } |
| 394 |
| 395 // JavaScript specific nodes. |
| 396 |
| 397 processIdentical(Identical node) { |
| 398 node.left.parent = node; |
| 399 node.right.parent = node; |
| 400 } |
| 394 } | 401 } |
| 395 | 402 |
| 396 class _ReductionKind { | 403 class _ReductionKind { |
| 397 final String name; | 404 final String name; |
| 398 final int hashCode; | 405 final int hashCode; |
| 399 | 406 |
| 400 const _ReductionKind(this.name, this.hashCode); | 407 const _ReductionKind(this.name, this.hashCode); |
| 401 | 408 |
| 402 static const _ReductionKind DEAD_VAL = const _ReductionKind('dead-val', 0); | 409 static const _ReductionKind DEAD_VAL = const _ReductionKind('dead-val', 0); |
| 403 static const _ReductionKind DEAD_CONT = const _ReductionKind('dead-cont', 1); | 410 static const _ReductionKind DEAD_CONT = const _ReductionKind('dead-cont', 1); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 430 } | 437 } |
| 431 | 438 |
| 432 String toString() => "$kind: $node"; | 439 String toString() => "$kind: $node"; |
| 433 } | 440 } |
| 434 | 441 |
| 435 /// A dummy class used solely to mark nodes as deleted once they are removed | 442 /// A dummy class used solely to mark nodes as deleted once they are removed |
| 436 /// from a term. | 443 /// from a term. |
| 437 class _DeletedNode extends Node { | 444 class _DeletedNode extends Node { |
| 438 accept(_) => null; | 445 accept(_) => null; |
| 439 } | 446 } |
| OLD | NEW |