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 |