Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: runtime/vm/compiler.cc

Issue 1678203002: Remove more feature in product mode (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/dart.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #include "vm/compiler.h" 5 #include "vm/compiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 8
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/block_scheduler.h" 10 #include "vm/block_scheduler.h"
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 Thread* thread = Thread::Current(); 267 Thread* thread = Thread::Current();
268 Error& error = Error::Handle(thread->zone()); 268 Error& error = Error::Handle(thread->zone());
269 error = thread->sticky_error(); 269 error = thread->sticky_error();
270 thread->clear_sticky_error(); 270 thread->clear_sticky_error();
271 return error.raw(); 271 return error.raw();
272 } 272 }
273 } 273 }
274 274
275 Thread* const thread = Thread::Current(); 275 Thread* const thread = Thread::Current();
276 StackZone zone(thread); 276 StackZone zone(thread);
277 // We remember all the classes that are being compiled in these lists. This 277 #ifndef PRODUCT
278 // also allows us to reset the marked_for_parsing state in case we see an
279 // error.
280 VMTagScope tagScope(thread, VMTag::kCompileClassTagId); 278 VMTagScope tagScope(thread, VMTag::kCompileClassTagId);
281 TimelineDurationScope tds(thread, 279 TimelineDurationScope tds(thread,
282 thread->isolate()->GetCompilerStream(), 280 thread->isolate()->GetCompilerStream(),
283 "CompileClass"); 281 "CompileClass");
284 if (tds.enabled()) { 282 if (tds.enabled()) {
285 tds.SetNumArguments(1); 283 tds.SetNumArguments(1);
286 tds.CopyArgument(0, "class", cls.ToCString()); 284 tds.CopyArgument(0, "class", cls.ToCString());
287 } 285 }
286 #endif // !PRODUCT
288 287
288 // We remember all the classes that are being compiled in these lists. This
289 // also allows us to reset the marked_for_parsing state in case we see an
290 // error.
289 GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4); 291 GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4);
290 GrowableHandlePtrArray<const Class> patch_list(thread->zone(), 4); 292 GrowableHandlePtrArray<const Class> patch_list(thread->zone(), 4);
291 293
292 // Parse the class and all the interfaces it implements and super classes. 294 // Parse the class and all the interfaces it implements and super classes.
293 LongJumpScope jump; 295 LongJumpScope jump;
294 if (setjmp(*jump.Set()) == 0) { 296 if (setjmp(*jump.Set()) == 0) {
295 if (FLAG_trace_compiler) { 297 if (FLAG_trace_compiler) {
296 THR_Print("Compiling Class '%s'\n", cls.ToCString()); 298 THR_Print("Compiling Class '%s'\n", cls.ToCString());
297 } 299 }
298 300
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 // If optimized_result_code is not NULL then it is caller's responsibility 565 // If optimized_result_code is not NULL then it is caller's responsibility
564 // to install code. 566 // to install code.
565 bool CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { 567 bool CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
566 ASSERT(!FLAG_precompilation); 568 ASSERT(!FLAG_precompilation);
567 const Function& function = parsed_function()->function(); 569 const Function& function = parsed_function()->function();
568 if (optimized() && !function.IsOptimizable()) { 570 if (optimized() && !function.IsOptimizable()) {
569 return false; 571 return false;
570 } 572 }
571 bool is_compiled = false; 573 bool is_compiled = false;
572 Zone* const zone = thread()->zone(); 574 Zone* const zone = thread()->zone();
575 #ifndef PRODUCT
573 TimelineStream* compiler_timeline = isolate()->GetCompilerStream(); 576 TimelineStream* compiler_timeline = isolate()->GetCompilerStream();
577 #endif
574 CSTAT_TIMER_SCOPE(thread(), codegen_timer); 578 CSTAT_TIMER_SCOPE(thread(), codegen_timer);
575 HANDLESCOPE(thread()); 579 HANDLESCOPE(thread());
576 580
577 // We may reattempt compilation if the function needs to be assembled using 581 // We may reattempt compilation if the function needs to be assembled using
578 // far branches on ARM and MIPS. In the else branch of the setjmp call, 582 // far branches on ARM and MIPS. In the else branch of the setjmp call,
579 // done is set to false, and use_far_branches is set to true if there is a 583 // done is set to false, and use_far_branches is set to true if there is a
580 // longjmp from the ARM or MIPS assemblers. In all other paths through this 584 // longjmp from the ARM or MIPS assemblers. In all other paths through this
581 // while loop, done is set to true. use_far_branches is always false on ia32 585 // while loop, done is set to true. use_far_branches is always false on ia32
582 // and x64. 586 // and x64.
583 bool done = false; 587 bool done = false;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 if (FLAG_print_ic_data_map) { 625 if (FLAG_print_ic_data_map) {
622 for (intptr_t i = 0; i < ic_data_array->length(); i++) { 626 for (intptr_t i = 0; i < ic_data_array->length(); i++) {
623 if ((*ic_data_array)[i] != NULL) { 627 if ((*ic_data_array)[i] != NULL) {
624 THR_Print("%" Pd " ", i); 628 THR_Print("%" Pd " ", i);
625 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); 629 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]);
626 } 630 }
627 } 631 }
628 } 632 }
629 } 633 }
630 634
635 #ifndef PRODUCT
631 TimelineDurationScope tds(thread(), 636 TimelineDurationScope tds(thread(),
632 compiler_timeline, 637 compiler_timeline,
633 "BuildFlowGraph"); 638 "BuildFlowGraph");
639 #endif // !PRODUCT
634 flow_graph = pipeline->BuildFlowGraph(zone, 640 flow_graph = pipeline->BuildFlowGraph(zone,
635 parsed_function(), 641 parsed_function(),
636 *ic_data_array, 642 *ic_data_array,
637 osr_id()); 643 osr_id());
638 } 644 }
639 645
640 const bool print_flow_graph = 646 const bool print_flow_graph =
641 (FLAG_print_flow_graph || 647 (FLAG_print_flow_graph ||
642 (optimized() && FLAG_print_flow_graph_optimized)) && 648 (optimized() && FLAG_print_flow_graph_optimized)) &&
643 FlowGraphPrinter::ShouldPrint(function); 649 FlowGraphPrinter::ShouldPrint(function);
644 650
645 if (print_flow_graph) { 651 if (print_flow_graph) {
646 if (osr_id() == Compiler::kNoOSRDeoptId) { 652 if (osr_id() == Compiler::kNoOSRDeoptId) {
647 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 653 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
648 } else { 654 } else {
649 FlowGraphPrinter::PrintGraph("For OSR", flow_graph); 655 FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
650 } 656 }
651 } 657 }
652 658
653 BlockScheduler block_scheduler(flow_graph); 659 BlockScheduler block_scheduler(flow_graph);
654 const bool reorder_blocks = 660 const bool reorder_blocks =
655 FlowGraph::ShouldReorderBlocks(function, optimized()); 661 FlowGraph::ShouldReorderBlocks(function, optimized());
656 if (reorder_blocks) { 662 if (reorder_blocks) {
663 #ifndef PRODUCT
657 TimelineDurationScope tds(thread(), 664 TimelineDurationScope tds(thread(),
658 compiler_timeline, 665 compiler_timeline,
659 "BlockScheduler::AssignEdgeWeights"); 666 "BlockScheduler::AssignEdgeWeights");
667 #endif // !PRODUCT
660 block_scheduler.AssignEdgeWeights(); 668 block_scheduler.AssignEdgeWeights();
661 } 669 }
662 670
663 if (optimized()) { 671 if (optimized()) {
672 #ifndef PRODUCT
664 TimelineDurationScope tds(thread(), 673 TimelineDurationScope tds(thread(),
665 compiler_timeline, 674 compiler_timeline,
666 "ComputeSSA"); 675 "ComputeSSA");
676 #endif // !PRODUCT
667 CSTAT_TIMER_SCOPE(thread(), ssa_timer); 677 CSTAT_TIMER_SCOPE(thread(), ssa_timer);
668 // Transform to SSA (virtual register 0 and no inlining arguments). 678 // Transform to SSA (virtual register 0 and no inlining arguments).
669 flow_graph->ComputeSSA(0, NULL); 679 flow_graph->ComputeSSA(0, NULL);
670 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 680 DEBUG_ASSERT(flow_graph->VerifyUseLists());
671 if (print_flow_graph) { 681 if (print_flow_graph) {
672 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); 682 FlowGraphPrinter::PrintGraph("After SSA", flow_graph);
673 } 683 }
674 } 684 }
675 685
676 // Maps inline_id_to_function[inline_id] -> function. Top scope 686 // Maps inline_id_to_function[inline_id] -> function. Top scope
677 // function has inline_id 0. The map is populated by the inliner. 687 // function has inline_id 0. The map is populated by the inliner.
678 GrowableArray<const Function*> inline_id_to_function; 688 GrowableArray<const Function*> inline_id_to_function;
679 // For a given inlining-id(index) specifies the caller's inlining-id. 689 // For a given inlining-id(index) specifies the caller's inlining-id.
680 GrowableArray<intptr_t> caller_inline_id; 690 GrowableArray<intptr_t> caller_inline_id;
681 // Collect all instance fields that are loaded in the graph and 691 // Collect all instance fields that are loaded in the graph and
682 // have non-generic type feedback attached to them that can 692 // have non-generic type feedback attached to them that can
683 // potentially affect optimizations. 693 // potentially affect optimizations.
684 if (optimized()) { 694 if (optimized()) {
695 #ifndef PRODUCT
685 TimelineDurationScope tds(thread(), 696 TimelineDurationScope tds(thread(),
686 compiler_timeline, 697 compiler_timeline,
687 "OptimizationPasses"); 698 "OptimizationPasses");
699 #endif // !PRODUCT
688 inline_id_to_function.Add(&function); 700 inline_id_to_function.Add(&function);
689 // Top scope function has no caller (-1). 701 // Top scope function has no caller (-1).
690 caller_inline_id.Add(-1); 702 caller_inline_id.Add(-1);
691 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer); 703 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer);
692 704
693 FlowGraphOptimizer optimizer(flow_graph, 705 FlowGraphOptimizer optimizer(flow_graph,
694 use_speculative_inlining, 706 use_speculative_inlining,
695 NULL); 707 NULL);
696 optimizer.ApplyICData(); 708 optimizer.ApplyICData();
697 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 709 DEBUG_ASSERT(flow_graph->VerifyUseLists());
698 710
699 // Optimize (a << b) & c patterns, merge operations. 711 // Optimize (a << b) & c patterns, merge operations.
700 // Run early in order to have more opportunity to optimize left shifts. 712 // Run early in order to have more opportunity to optimize left shifts.
701 optimizer.TryOptimizePatterns(); 713 optimizer.TryOptimizePatterns();
702 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 714 DEBUG_ASSERT(flow_graph->VerifyUseLists());
703 715
704 FlowGraphInliner::SetInliningId(flow_graph, 0); 716 FlowGraphInliner::SetInliningId(flow_graph, 0);
705 717
706 // Inlining (mutates the flow graph) 718 // Inlining (mutates the flow graph)
707 if (FLAG_use_inlining) { 719 if (FLAG_use_inlining) {
720 #ifndef PRODUCT
708 TimelineDurationScope tds2(thread(), 721 TimelineDurationScope tds2(thread(),
709 compiler_timeline, 722 compiler_timeline,
710 "Inlining"); 723 "Inlining");
724 #endif // !PRODUCT
711 CSTAT_TIMER_SCOPE(thread(), graphinliner_timer); 725 CSTAT_TIMER_SCOPE(thread(), graphinliner_timer);
712 // Propagate types to create more inlining opportunities. 726 // Propagate types to create more inlining opportunities.
713 FlowGraphTypePropagator::Propagate(flow_graph); 727 FlowGraphTypePropagator::Propagate(flow_graph);
714 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 728 DEBUG_ASSERT(flow_graph->VerifyUseLists());
715 729
716 // Use propagated class-ids to create more inlining opportunities. 730 // Use propagated class-ids to create more inlining opportunities.
717 optimizer.ApplyClassIds(); 731 optimizer.ApplyClassIds();
718 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 732 DEBUG_ASSERT(flow_graph->VerifyUseLists());
719 733
720 FlowGraphInliner inliner(flow_graph, 734 FlowGraphInliner inliner(flow_graph,
721 &inline_id_to_function, 735 &inline_id_to_function,
722 &caller_inline_id, 736 &caller_inline_id,
723 use_speculative_inlining, 737 use_speculative_inlining,
724 NULL); 738 NULL);
725 inliner.Inline(); 739 inliner.Inline();
726 // Use lists are maintained and validated by the inliner. 740 // Use lists are maintained and validated by the inliner.
727 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 741 DEBUG_ASSERT(flow_graph->VerifyUseLists());
728 } 742 }
729 743
730 // Propagate types and eliminate more type tests. 744 // Propagate types and eliminate more type tests.
731 FlowGraphTypePropagator::Propagate(flow_graph); 745 FlowGraphTypePropagator::Propagate(flow_graph);
732 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 746 DEBUG_ASSERT(flow_graph->VerifyUseLists());
733 747
734 { 748 {
749 #ifndef PRODUCT
735 TimelineDurationScope tds2(thread(), 750 TimelineDurationScope tds2(thread(),
736 compiler_timeline, 751 compiler_timeline,
737 "ApplyClassIds"); 752 "ApplyClassIds");
753 #endif // !PRODUCT
738 // Use propagated class-ids to optimize further. 754 // Use propagated class-ids to optimize further.
739 optimizer.ApplyClassIds(); 755 optimizer.ApplyClassIds();
740 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 756 DEBUG_ASSERT(flow_graph->VerifyUseLists());
741 } 757 }
742 758
743 // Propagate types for potentially newly added instructions by 759 // Propagate types for potentially newly added instructions by
744 // ApplyClassIds(). Must occur before canonicalization. 760 // ApplyClassIds(). Must occur before canonicalization.
745 FlowGraphTypePropagator::Propagate(flow_graph); 761 FlowGraphTypePropagator::Propagate(flow_graph);
746 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 762 DEBUG_ASSERT(flow_graph->VerifyUseLists());
747 763
748 // Do optimizations that depend on the propagated type information. 764 // Do optimizations that depend on the propagated type information.
749 if (optimizer.Canonicalize()) { 765 if (optimizer.Canonicalize()) {
750 // Invoke Canonicalize twice in order to fully canonicalize patterns 766 // Invoke Canonicalize twice in order to fully canonicalize patterns
751 // like "if (a & const == 0) { }". 767 // like "if (a & const == 0) { }".
752 optimizer.Canonicalize(); 768 optimizer.Canonicalize();
753 } 769 }
754 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 770 DEBUG_ASSERT(flow_graph->VerifyUseLists());
755 771
756 { 772 {
773 #ifndef PRODUCT
757 TimelineDurationScope tds2(thread(), 774 TimelineDurationScope tds2(thread(),
758 compiler_timeline, 775 compiler_timeline,
759 "BranchSimplifier"); 776 "BranchSimplifier");
777 #endif // !PRODUCT
760 BranchSimplifier::Simplify(flow_graph); 778 BranchSimplifier::Simplify(flow_graph);
761 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 779 DEBUG_ASSERT(flow_graph->VerifyUseLists());
762 780
763 IfConverter::Simplify(flow_graph); 781 IfConverter::Simplify(flow_graph);
764 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 782 DEBUG_ASSERT(flow_graph->VerifyUseLists());
765 } 783 }
766 784
767 if (FLAG_constant_propagation) { 785 if (FLAG_constant_propagation) {
786 #ifndef PRODUCT
768 TimelineDurationScope tds2(thread(), 787 TimelineDurationScope tds2(thread(),
769 compiler_timeline, 788 compiler_timeline,
770 "ConstantPropagation"); 789 "ConstantPropagation");
790 #endif // !PRODUCT
771 ConstantPropagator::Optimize(flow_graph); 791 ConstantPropagator::Optimize(flow_graph);
772 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 792 DEBUG_ASSERT(flow_graph->VerifyUseLists());
773 // A canonicalization pass to remove e.g. smi checks on smi constants. 793 // A canonicalization pass to remove e.g. smi checks on smi constants.
774 optimizer.Canonicalize(); 794 optimizer.Canonicalize();
775 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 795 DEBUG_ASSERT(flow_graph->VerifyUseLists());
776 // Canonicalization introduced more opportunities for constant 796 // Canonicalization introduced more opportunities for constant
777 // propagation. 797 // propagation.
778 ConstantPropagator::Optimize(flow_graph); 798 ConstantPropagator::Optimize(flow_graph);
779 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 799 DEBUG_ASSERT(flow_graph->VerifyUseLists());
780 } 800 }
781 801
782 // Optimistically convert loop phis that have a single non-smi input 802 // Optimistically convert loop phis that have a single non-smi input
783 // coming from the loop pre-header into smi-phis. 803 // coming from the loop pre-header into smi-phis.
784 if (FLAG_loop_invariant_code_motion) { 804 if (FLAG_loop_invariant_code_motion) {
785 LICM licm(flow_graph); 805 LICM licm(flow_graph);
786 licm.OptimisticallySpecializeSmiPhis(); 806 licm.OptimisticallySpecializeSmiPhis();
787 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 807 DEBUG_ASSERT(flow_graph->VerifyUseLists());
788 } 808 }
789 809
790 // Propagate types and eliminate even more type tests. 810 // Propagate types and eliminate even more type tests.
791 // Recompute types after constant propagation to infer more precise 811 // Recompute types after constant propagation to infer more precise
792 // types for uses that were previously reached by now eliminated phis. 812 // types for uses that were previously reached by now eliminated phis.
793 FlowGraphTypePropagator::Propagate(flow_graph); 813 FlowGraphTypePropagator::Propagate(flow_graph);
794 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 814 DEBUG_ASSERT(flow_graph->VerifyUseLists());
795 815
796 { 816 {
817 #ifndef PRODUCT
797 TimelineDurationScope tds2(thread(), 818 TimelineDurationScope tds2(thread(),
798 compiler_timeline, 819 compiler_timeline,
799 "SelectRepresentations"); 820 "SelectRepresentations");
821 #endif // !PRODUCT
800 // Where beneficial convert Smi operations into Int32 operations. 822 // Where beneficial convert Smi operations into Int32 operations.
801 // Only meanigful for 32bit platforms right now. 823 // Only meanigful for 32bit platforms right now.
802 optimizer.WidenSmiToInt32(); 824 optimizer.WidenSmiToInt32();
803 825
804 // Unbox doubles. Performed after constant propagation to minimize 826 // Unbox doubles. Performed after constant propagation to minimize
805 // interference from phis merging double values and tagged 827 // interference from phis merging double values and tagged
806 // values coming from dead paths. 828 // values coming from dead paths.
807 optimizer.SelectRepresentations(); 829 optimizer.SelectRepresentations();
808 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 830 DEBUG_ASSERT(flow_graph->VerifyUseLists());
809 } 831 }
810 832
811 { 833 {
834 #ifndef PRODUCT
812 TimelineDurationScope tds2(thread(), 835 TimelineDurationScope tds2(thread(),
813 compiler_timeline, 836 compiler_timeline,
814 "CommonSubexpressionElinination"); 837 "CommonSubexpressionElinination");
838 #endif // !PRODUCT
815 if (FLAG_common_subexpression_elimination || 839 if (FLAG_common_subexpression_elimination ||
816 FLAG_loop_invariant_code_motion) { 840 FLAG_loop_invariant_code_motion) {
817 flow_graph->ComputeBlockEffects(); 841 flow_graph->ComputeBlockEffects();
818 } 842 }
819 843
820 if (FLAG_common_subexpression_elimination) { 844 if (FLAG_common_subexpression_elimination) {
821 if (DominatorBasedCSE::Optimize(flow_graph)) { 845 if (DominatorBasedCSE::Optimize(flow_graph)) {
822 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 846 DEBUG_ASSERT(flow_graph->VerifyUseLists());
823 optimizer.Canonicalize(); 847 optimizer.Canonicalize();
824 // Do another round of CSE to take secondary effects into account: 848 // Do another round of CSE to take secondary effects into account:
(...skipping 17 matching lines...) Expand all
842 flow_graph->RemoveRedefinitions(); 866 flow_graph->RemoveRedefinitions();
843 } 867 }
844 868
845 // Optimize (a << b) & c patterns, merge operations. 869 // Optimize (a << b) & c patterns, merge operations.
846 // Run after CSE in order to have more opportunity to merge 870 // Run after CSE in order to have more opportunity to merge
847 // instructions that have same inputs. 871 // instructions that have same inputs.
848 optimizer.TryOptimizePatterns(); 872 optimizer.TryOptimizePatterns();
849 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 873 DEBUG_ASSERT(flow_graph->VerifyUseLists());
850 874
851 { 875 {
876 #ifndef PRODUCT
852 TimelineDurationScope tds2(thread(), 877 TimelineDurationScope tds2(thread(),
853 compiler_timeline, 878 compiler_timeline,
854 "DeadStoreElimination"); 879 "DeadStoreElimination");
880 #endif // !PRODUCT
855 DeadStoreElimination::Optimize(flow_graph); 881 DeadStoreElimination::Optimize(flow_graph);
856 } 882 }
857 883
858 if (FLAG_range_analysis) { 884 if (FLAG_range_analysis) {
885 #ifndef PRODUCT
859 TimelineDurationScope tds2(thread(), 886 TimelineDurationScope tds2(thread(),
860 compiler_timeline, 887 compiler_timeline,
861 "RangeAnalysis"); 888 "RangeAnalysis");
889 #endif // !PRODUCT
862 // Propagate types after store-load-forwarding. Some phis may have 890 // Propagate types after store-load-forwarding. Some phis may have
863 // become smi phis that can be processed by range analysis. 891 // become smi phis that can be processed by range analysis.
864 FlowGraphTypePropagator::Propagate(flow_graph); 892 FlowGraphTypePropagator::Propagate(flow_graph);
865 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 893 DEBUG_ASSERT(flow_graph->VerifyUseLists());
866 894
867 // We have to perform range analysis after LICM because it 895 // We have to perform range analysis after LICM because it
868 // optimistically moves CheckSmi through phis into loop preheaders 896 // optimistically moves CheckSmi through phis into loop preheaders
869 // making some phis smi. 897 // making some phis smi.
870 optimizer.InferIntRanges(); 898 optimizer.InferIntRanges();
871 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 899 DEBUG_ASSERT(flow_graph->VerifyUseLists());
872 } 900 }
873 901
874 if (FLAG_constant_propagation) { 902 if (FLAG_constant_propagation) {
903 #ifndef PRODUCT
875 TimelineDurationScope tds2(thread(), 904 TimelineDurationScope tds2(thread(),
876 compiler_timeline, 905 compiler_timeline,
877 "ConstantPropagator::OptimizeBranches"); 906 "ConstantPropagator::OptimizeBranches");
907 #endif // !PRODUCT
878 // Constant propagation can use information from range analysis to 908 // Constant propagation can use information from range analysis to
879 // find unreachable branch targets and eliminate branches that have 909 // find unreachable branch targets and eliminate branches that have
880 // the same true- and false-target. 910 // the same true- and false-target.
881 ConstantPropagator::OptimizeBranches(flow_graph); 911 ConstantPropagator::OptimizeBranches(flow_graph);
882 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 912 DEBUG_ASSERT(flow_graph->VerifyUseLists());
883 } 913 }
884 914
885 // Recompute types after code movement was done to ensure correct 915 // Recompute types after code movement was done to ensure correct
886 // reaching types for hoisted values. 916 // reaching types for hoisted values.
887 FlowGraphTypePropagator::Propagate(flow_graph); 917 FlowGraphTypePropagator::Propagate(flow_graph);
888 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 918 DEBUG_ASSERT(flow_graph->VerifyUseLists());
889 919
890 { 920 {
921 #ifndef PRODUCT
891 TimelineDurationScope tds2(thread(), 922 TimelineDurationScope tds2(thread(),
892 compiler_timeline, 923 compiler_timeline,
893 "TryCatchAnalyzer::Optimize"); 924 "TryCatchAnalyzer::Optimize");
925 #endif // !PRODUCT
894 // Optimize try-blocks. 926 // Optimize try-blocks.
895 TryCatchAnalyzer::Optimize(flow_graph); 927 TryCatchAnalyzer::Optimize(flow_graph);
896 } 928 }
897 929
898 // Detach environments from the instructions that can't deoptimize. 930 // Detach environments from the instructions that can't deoptimize.
899 // Do it before we attempt to perform allocation sinking to minimize 931 // Do it before we attempt to perform allocation sinking to minimize
900 // amount of materializations it has to perform. 932 // amount of materializations it has to perform.
901 optimizer.EliminateEnvironments(); 933 optimizer.EliminateEnvironments();
902 934
903 { 935 {
936 #ifndef PRODUCT
904 TimelineDurationScope tds2(thread(), 937 TimelineDurationScope tds2(thread(),
905 compiler_timeline, 938 compiler_timeline,
906 "EliminateDeadPhis"); 939 "EliminateDeadPhis");
940 #endif // !PRODUCT
907 DeadCodeElimination::EliminateDeadPhis(flow_graph); 941 DeadCodeElimination::EliminateDeadPhis(flow_graph);
908 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 942 DEBUG_ASSERT(flow_graph->VerifyUseLists());
909 } 943 }
910 944
911 if (optimizer.Canonicalize()) { 945 if (optimizer.Canonicalize()) {
912 optimizer.Canonicalize(); 946 optimizer.Canonicalize();
913 } 947 }
914 948
915 // Attempt to sink allocations of temporary non-escaping objects to 949 // Attempt to sink allocations of temporary non-escaping objects to
916 // the deoptimization path. 950 // the deoptimization path.
917 AllocationSinking* sinking = NULL; 951 AllocationSinking* sinking = NULL;
918 if (FLAG_allocation_sinking && 952 if (FLAG_allocation_sinking &&
919 (flow_graph->graph_entry()->SuccessorCount() == 1)) { 953 (flow_graph->graph_entry()->SuccessorCount() == 1)) {
954 #ifndef PRODUCT
920 TimelineDurationScope tds2(thread(), 955 TimelineDurationScope tds2(thread(),
921 compiler_timeline, 956 compiler_timeline,
922 "AllocationSinking::Optimize"); 957 "AllocationSinking::Optimize");
958 #endif // !PRODUCT
923 // TODO(fschneider): Support allocation sinking with try-catch. 959 // TODO(fschneider): Support allocation sinking with try-catch.
924 sinking = new AllocationSinking(flow_graph); 960 sinking = new AllocationSinking(flow_graph);
925 sinking->Optimize(); 961 sinking->Optimize();
926 } 962 }
927 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 963 DEBUG_ASSERT(flow_graph->VerifyUseLists());
928 964
929 DeadCodeElimination::EliminateDeadPhis(flow_graph); 965 DeadCodeElimination::EliminateDeadPhis(flow_graph);
930 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 966 DEBUG_ASSERT(flow_graph->VerifyUseLists());
931 967
932 FlowGraphTypePropagator::Propagate(flow_graph); 968 FlowGraphTypePropagator::Propagate(flow_graph);
933 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 969 DEBUG_ASSERT(flow_graph->VerifyUseLists());
934 970
935 { 971 {
972 #ifndef PRODUCT
936 TimelineDurationScope tds2(thread(), 973 TimelineDurationScope tds2(thread(),
937 compiler_timeline, 974 compiler_timeline,
938 "SelectRepresentations"); 975 "SelectRepresentations");
976 #endif // !PRODUCT
939 // Ensure that all phis inserted by optimization passes have 977 // Ensure that all phis inserted by optimization passes have
940 // consistent representations. 978 // consistent representations.
941 optimizer.SelectRepresentations(); 979 optimizer.SelectRepresentations();
942 } 980 }
943 981
944 if (optimizer.Canonicalize()) { 982 if (optimizer.Canonicalize()) {
945 // To fully remove redundant boxing (e.g. BoxDouble used only in 983 // To fully remove redundant boxing (e.g. BoxDouble used only in
946 // environments and UnboxDouble instructions) instruction we 984 // environments and UnboxDouble instructions) instruction we
947 // first need to replace all their uses and then fold them away. 985 // first need to replace all their uses and then fold them away.
948 // For now we just repeat Canonicalize twice to do that. 986 // For now we just repeat Canonicalize twice to do that.
949 // TODO(vegorov): implement a separate representation folding pass. 987 // TODO(vegorov): implement a separate representation folding pass.
950 optimizer.Canonicalize(); 988 optimizer.Canonicalize();
951 } 989 }
952 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 990 DEBUG_ASSERT(flow_graph->VerifyUseLists());
953 991
954 if (sinking != NULL) { 992 if (sinking != NULL) {
993 #ifndef PRODUCT
955 TimelineDurationScope tds2( 994 TimelineDurationScope tds2(
956 thread(), 995 thread(),
957 compiler_timeline, 996 compiler_timeline,
958 "AllocationSinking::DetachMaterializations"); 997 "AllocationSinking::DetachMaterializations");
998 #endif // !PRODUCT
959 // Remove all MaterializeObject instructions inserted by allocation 999 // Remove all MaterializeObject instructions inserted by allocation
960 // sinking from the flow graph and let them float on the side 1000 // sinking from the flow graph and let them float on the side
961 // referenced only from environments. Register allocator will consider 1001 // referenced only from environments. Register allocator will consider
962 // them as part of a deoptimization environment. 1002 // them as part of a deoptimization environment.
963 sinking->DetachMaterializations(); 1003 sinking->DetachMaterializations();
964 } 1004 }
965 1005
966 // Compute and store graph informations (call & instruction counts) 1006 // Compute and store graph informations (call & instruction counts)
967 // to be later used by the inliner. 1007 // to be later used by the inliner.
968 FlowGraphInliner::CollectGraphInfo(flow_graph, true); 1008 FlowGraphInliner::CollectGraphInfo(flow_graph, true);
969 1009
970 { 1010 {
1011 #ifndef PRODUCT
971 TimelineDurationScope tds2(thread(), 1012 TimelineDurationScope tds2(thread(),
972 compiler_timeline, 1013 compiler_timeline,
973 "AllocateRegisters"); 1014 "AllocateRegisters");
1015 #endif // !PRODUCT
974 // Perform register allocation on the SSA graph. 1016 // Perform register allocation on the SSA graph.
975 FlowGraphAllocator allocator(*flow_graph); 1017 FlowGraphAllocator allocator(*flow_graph);
976 allocator.AllocateRegisters(); 1018 allocator.AllocateRegisters();
977 } 1019 }
978 1020
979 if (reorder_blocks) { 1021 if (reorder_blocks) {
1022 #ifndef PRODUCT
980 TimelineDurationScope tds(thread(), 1023 TimelineDurationScope tds(thread(),
981 compiler_timeline, 1024 compiler_timeline,
982 "BlockScheduler::ReorderBlocks"); 1025 "BlockScheduler::ReorderBlocks");
1026 #endif // !PRODUCT
983 block_scheduler.ReorderBlocks(); 1027 block_scheduler.ReorderBlocks();
984 } 1028 }
985 1029
986 if (print_flow_graph) { 1030 if (print_flow_graph) {
987 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); 1031 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
988 } 1032 }
989 } 1033 }
990 1034
991 ASSERT(inline_id_to_function.length() == caller_inline_id.length()); 1035 ASSERT(inline_id_to_function.length() == caller_inline_id.length());
992 Assembler assembler(use_far_branches); 1036 Assembler assembler(use_far_branches);
993 FlowGraphCompiler graph_compiler(&assembler, flow_graph, 1037 FlowGraphCompiler graph_compiler(&assembler, flow_graph,
994 *parsed_function(), optimized(), 1038 *parsed_function(), optimized(),
995 inline_id_to_function, 1039 inline_id_to_function,
996 caller_inline_id); 1040 caller_inline_id);
997 { 1041 {
998 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer); 1042 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer);
1043 #ifndef PRODUCT
999 TimelineDurationScope tds(thread(), 1044 TimelineDurationScope tds(thread(),
1000 compiler_timeline, 1045 compiler_timeline,
1001 "CompileGraph"); 1046 "CompileGraph");
1047 #endif // !PRODUCT
1002 graph_compiler.CompileGraph(); 1048 graph_compiler.CompileGraph();
1003 pipeline->FinalizeCompilation(); 1049 pipeline->FinalizeCompilation();
1004 } 1050 }
1005 { 1051 {
1052 #ifndef PRODUCT
1006 TimelineDurationScope tds(thread(), 1053 TimelineDurationScope tds(thread(),
1007 compiler_timeline, 1054 compiler_timeline,
1008 "FinalizeCompilation"); 1055 "FinalizeCompilation");
1056 #endif // !PRODUCT
1009 if (thread()->IsMutatorThread()) { 1057 if (thread()->IsMutatorThread()) {
1010 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); 1058 FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
1011 } else { 1059 } else {
1012 // This part of compilation must be at a safepoint. 1060 // This part of compilation must be at a safepoint.
1013 // Stop mutator thread before creating the instruction object and 1061 // Stop mutator thread before creating the instruction object and
1014 // installing code. 1062 // installing code.
1015 // Mutator thread may not run code while we are creating the 1063 // Mutator thread may not run code while we are creating the
1016 // instruction object, since the creation of instruction object 1064 // instruction object, since the creation of instruction object
1017 // changes code page access permissions (makes them temporary not 1065 // changes code page access permissions (makes them temporary not
1018 // executable). 1066 // executable).
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 #ifdef DART_PRECOMPILER 1461 #ifdef DART_PRECOMPILER
1414 if (FLAG_precompilation) { 1462 if (FLAG_precompilation) {
1415 return Precompiler::ExecuteOnce(fragment); 1463 return Precompiler::ExecuteOnce(fragment);
1416 } 1464 }
1417 #endif 1465 #endif
1418 LongJumpScope jump; 1466 LongJumpScope jump;
1419 if (setjmp(*jump.Set()) == 0) { 1467 if (setjmp(*jump.Set()) == 0) {
1420 Thread* const thread = Thread::Current(); 1468 Thread* const thread = Thread::Current();
1421 if (FLAG_trace_compiler) { 1469 if (FLAG_trace_compiler) {
1422 THR_Print("compiling expression: "); 1470 THR_Print("compiling expression: ");
1423 AstPrinter::PrintNode(fragment); 1471 if (FLAG_support_ast_printer) {
1472 AstPrinter::PrintNode(fragment);
1473 }
1424 } 1474 }
1425 1475
1426 // Create a dummy function object for the code generator. 1476 // Create a dummy function object for the code generator.
1427 // The function needs to be associated with a named Class: the interface 1477 // The function needs to be associated with a named Class: the interface
1428 // Function fits the bill. 1478 // Function fits the bill.
1429 const char* kEvalConst = "eval_const"; 1479 const char* kEvalConst = "eval_const";
1430 const Function& func = Function::ZoneHandle(Function::New( 1480 const Function& func = Function::ZoneHandle(Function::New(
1431 String::Handle(Symbols::New(kEvalConst)), 1481 String::Handle(Symbols::New(kEvalConst)),
1432 RawFunction::kRegularFunction, 1482 RawFunction::kRegularFunction,
1433 true, // static function 1483 true, // static function
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 } 1885 }
1836 1886
1837 1887
1838 void BackgroundCompiler::EnsureInit(Thread* thread) { 1888 void BackgroundCompiler::EnsureInit(Thread* thread) {
1839 UNREACHABLE(); 1889 UNREACHABLE();
1840 } 1890 }
1841 1891
1842 #endif // DART_PRECOMPILED_RUNTIME 1892 #endif // DART_PRECOMPILED_RUNTIME
1843 1893
1844 } // namespace dart 1894 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/dart.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698