| 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.cps_ir.optimizers; | 5 library dart2js.cps_ir.shrinking_reductions; |
| 6 |
| 7 import 'cps_ir_nodes.dart'; |
| 8 import 'optimizers.dart'; |
| 6 | 9 |
| 7 /** | 10 /** |
| 8 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described | 11 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described |
| 9 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. | 12 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. |
| 10 */ | 13 */ |
| 11 class ShrinkingReducer extends Pass { | 14 class ShrinkingReducer extends Pass { |
| 12 String get passName => 'Shrinking reductions'; | 15 String get passName => 'Shrinking reductions'; |
| 13 | 16 |
| 14 Set<_ReductionTask> _worklist; | 17 Set<_ReductionTask> _worklist; |
| 15 | 18 |
| 16 static final _DeletedNode _DELETED = new _DeletedNode(); | 19 static final _DeletedNode _DELETED = new _DeletedNode(); |
| 17 | 20 |
| 18 /// Applies shrinking reductions to root, mutating root in the process. | 21 /// Applies shrinking reductions to root, mutating root in the process. |
| 19 @override | 22 @override |
| 20 void rewrite(RootNode root) { | 23 void rewrite(FunctionDefinition root) { |
| 21 if (root.isEmpty) return; | |
| 22 | |
| 23 _worklist = new Set<_ReductionTask>(); | 24 _worklist = new Set<_ReductionTask>(); |
| 24 _RedexVisitor redexVisitor = new _RedexVisitor(_worklist); | 25 _RedexVisitor redexVisitor = new _RedexVisitor(_worklist); |
| 25 | 26 |
| 26 // Set all parent pointers. | 27 // Set all parent pointers. |
| 27 new ParentVisitor().visit(root); | 28 new ParentVisitor().visit(root); |
| 28 | 29 |
| 29 // Sweep over the term, collecting redexes into the worklist. | 30 // Sweep over the term, collecting redexes into the worklist. |
| 30 redexVisitor.visit(root); | 31 redexVisitor.visit(root); |
| 31 | 32 |
| 32 // Process the worklist. | 33 // Process the worklist. |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 /// Traverses the CPS term and sets node.parent for each visited node. | 488 /// Traverses the CPS term and sets node.parent for each visited node. |
| 488 class ParentVisitor extends RecursiveVisitor { | 489 class ParentVisitor extends RecursiveVisitor { |
| 489 processFunctionDefinition(FunctionDefinition node) { | 490 processFunctionDefinition(FunctionDefinition node) { |
| 490 node.body.parent = node; | 491 node.body.parent = node; |
| 491 if (node.thisParameter != null) node.thisParameter.parent = node; | 492 if (node.thisParameter != null) node.thisParameter.parent = node; |
| 492 int index = 0; | 493 int index = 0; |
| 493 node.parameters.forEach((Definition parameter) { | 494 node.parameters.forEach((Definition parameter) { |
| 494 parameter.parent = node; | 495 parameter.parent = node; |
| 495 if (parameter is Parameter) parameter.parentIndex = index++; | 496 if (parameter is Parameter) parameter.parentIndex = index++; |
| 496 }); | 497 }); |
| 497 } | |
| 498 | |
| 499 processBody(Body node) { | |
| 500 node.returnContinuation.parent = node; | 498 node.returnContinuation.parent = node; |
| 501 node.body.parent = node; | 499 node.body.parent = node; |
| 502 } | 500 } |
| 503 | 501 |
| 504 processConstructorDefinition(ConstructorDefinition node) { | |
| 505 node.body.parent = node; | |
| 506 int index = 0; | |
| 507 node.parameters.forEach((Definition parameter) { | |
| 508 parameter.parent = node; | |
| 509 if (parameter is Parameter) parameter.parentIndex = index++; | |
| 510 }); | |
| 511 node.initializers.forEach((Initializer i) => i.parent = node); | |
| 512 } | |
| 513 | |
| 514 // Expressions. | |
| 515 | |
| 516 processFieldInitializer(FieldInitializer node) { | |
| 517 node.body.parent = node; | |
| 518 } | |
| 519 | |
| 520 processSuperInitializer(SuperInitializer node) { | |
| 521 node.arguments.forEach((Body argument) => argument.parent = node); | |
| 522 } | |
| 523 | |
| 524 processLetPrim(LetPrim node) { | 502 processLetPrim(LetPrim node) { |
| 525 node.primitive.parent = node; | 503 node.primitive.parent = node; |
| 526 node.body.parent = node; | 504 node.body.parent = node; |
| 527 } | 505 } |
| 528 | 506 |
| 529 processLetCont(LetCont node) { | 507 processLetCont(LetCont node) { |
| 530 int index = 0; | 508 int index = 0; |
| 531 node.continuations.forEach((Continuation continuation) { | 509 node.continuations.forEach((Continuation continuation) { |
| 532 continuation.parent = node; | 510 continuation.parent = node; |
| 533 continuation.parent_index = index++; | 511 continuation.parent_index = index++; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 node.continuation.parent = node; | 567 node.continuation.parent = node; |
| 590 node.value.parent = node; | 568 node.value.parent = node; |
| 591 } | 569 } |
| 592 | 570 |
| 593 processSetMutableVariable(SetMutableVariable node) { | 571 processSetMutableVariable(SetMutableVariable node) { |
| 594 node.variable.parent = node; | 572 node.variable.parent = node; |
| 595 node.body.parent = node; | 573 node.body.parent = node; |
| 596 node.value.parent = node; | 574 node.value.parent = node; |
| 597 } | 575 } |
| 598 | 576 |
| 599 processDeclareFunction(DeclareFunction node) { | |
| 600 node.variable.parent = node; | |
| 601 node.definition.parent = node; | |
| 602 node.body.parent = node; | |
| 603 } | |
| 604 | |
| 605 processThrow(Throw node) { | 577 processThrow(Throw node) { |
| 606 node.value.parent = node; | 578 node.value.parent = node; |
| 607 } | 579 } |
| 608 | 580 |
| 609 processGetLazyStatic(GetLazyStatic node) { | 581 processGetLazyStatic(GetLazyStatic node) { |
| 610 node.continuation.parent = node; | 582 node.continuation.parent = node; |
| 611 } | 583 } |
| 612 | 584 |
| 613 // Definitions. | |
| 614 | |
| 615 processLiteralList(LiteralList node) { | 585 processLiteralList(LiteralList node) { |
| 616 node.values.forEach((Reference ref) => ref.parent = node); | 586 node.values.forEach((Reference ref) => ref.parent = node); |
| 617 } | 587 } |
| 618 | 588 |
| 619 processLiteralMap(LiteralMap node) { | 589 processLiteralMap(LiteralMap node) { |
| 620 node.entries.forEach((LiteralMapEntry entry) { | 590 node.entries.forEach((LiteralMapEntry entry) { |
| 621 entry.key.parent = node; | 591 entry.key.parent = node; |
| 622 entry.value.parent = node; | 592 entry.value.parent = node; |
| 623 }); | 593 }); |
| 624 } | 594 } |
| 625 | 595 |
| 626 processCreateFunction(CreateFunction node) { | 596 processCreateFunction(CreateFunction node) { |
| 627 node.definition.parent = node; | 597 node.definition.parent = node; |
| 628 } | 598 } |
| 629 | 599 |
| 630 processContinuation(Continuation node) { | 600 processContinuation(Continuation node) { |
| 631 if (node.body != null) node.body.parent = node; | 601 if (node.body != null) node.body.parent = node; |
| 632 int index = 0; | 602 int index = 0; |
| 633 node.parameters.forEach((Parameter parameter) { | 603 node.parameters.forEach((Parameter parameter) { |
| 634 parameter.parent = node; | 604 parameter.parent = node; |
| 635 parameter.parentIndex = index++; | 605 parameter.parentIndex = index++; |
| 636 }); | 606 }); |
| 637 } | 607 } |
| 638 | 608 |
| 639 // Conditions. | |
| 640 | |
| 641 processIsTrue(IsTrue node) { | 609 processIsTrue(IsTrue node) { |
| 642 node.value.parent = node; | 610 node.value.parent = node; |
| 643 } | 611 } |
| 644 | 612 |
| 645 // JavaScript specific nodes. | |
| 646 | |
| 647 processIdentical(Identical node) { | 613 processIdentical(Identical node) { |
| 648 node.left.parent = node; | 614 node.left.parent = node; |
| 649 node.right.parent = node; | 615 node.right.parent = node; |
| 650 } | 616 } |
| 651 | 617 |
| 652 processInterceptor(Interceptor node) { | 618 processInterceptor(Interceptor node) { |
| 653 node.input.parent = node; | 619 node.input.parent = node; |
| 654 } | 620 } |
| 655 | 621 |
| 656 processSetField(SetField node) { | 622 processSetField(SetField node) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 } | 703 } |
| 738 | 704 |
| 739 String toString() => "$kind: $node"; | 705 String toString() => "$kind: $node"; |
| 740 } | 706 } |
| 741 | 707 |
| 742 /// A dummy class used solely to mark nodes as deleted once they are removed | 708 /// A dummy class used solely to mark nodes as deleted once they are removed |
| 743 /// from a term. | 709 /// from a term. |
| 744 class _DeletedNode extends Node { | 710 class _DeletedNode extends Node { |
| 745 accept(_) => null; | 711 accept(_) => null; |
| 746 } | 712 } |
| OLD | NEW |