| OLD | NEW |
| 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 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 optimizer.ApplyClassIds(); | 746 optimizer.ApplyClassIds(); |
| 747 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 747 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 748 } | 748 } |
| 749 | 749 |
| 750 // Propagate types for potentially newly added instructions by | 750 // Propagate types for potentially newly added instructions by |
| 751 // ApplyClassIds(). Must occur before canonicalization. | 751 // ApplyClassIds(). Must occur before canonicalization. |
| 752 FlowGraphTypePropagator::Propagate(flow_graph); | 752 FlowGraphTypePropagator::Propagate(flow_graph); |
| 753 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 753 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 754 | 754 |
| 755 // Do optimizations that depend on the propagated type information. | 755 // Do optimizations that depend on the propagated type information. |
| 756 if (optimizer.Canonicalize()) { | 756 if (flow_graph->Canonicalize()) { |
| 757 // Invoke Canonicalize twice in order to fully canonicalize patterns | 757 // Invoke Canonicalize twice in order to fully canonicalize patterns |
| 758 // like "if (a & const == 0) { }". | 758 // like "if (a & const == 0) { }". |
| 759 optimizer.Canonicalize(); | 759 flow_graph->Canonicalize(); |
| 760 } | 760 } |
| 761 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 761 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 762 | 762 |
| 763 { | 763 { |
| 764 #ifndef PRODUCT | 764 #ifndef PRODUCT |
| 765 TimelineDurationScope tds2(thread(), | 765 TimelineDurationScope tds2(thread(), |
| 766 compiler_timeline, | 766 compiler_timeline, |
| 767 "BranchSimplifier"); | 767 "BranchSimplifier"); |
| 768 #endif // !PRODUCT | 768 #endif // !PRODUCT |
| 769 BranchSimplifier::Simplify(flow_graph); | 769 BranchSimplifier::Simplify(flow_graph); |
| 770 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 770 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 771 | 771 |
| 772 IfConverter::Simplify(flow_graph); | 772 IfConverter::Simplify(flow_graph); |
| 773 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 773 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 774 } | 774 } |
| 775 | 775 |
| 776 if (FLAG_constant_propagation) { | 776 if (FLAG_constant_propagation) { |
| 777 #ifndef PRODUCT | 777 #ifndef PRODUCT |
| 778 TimelineDurationScope tds2(thread(), | 778 TimelineDurationScope tds2(thread(), |
| 779 compiler_timeline, | 779 compiler_timeline, |
| 780 "ConstantPropagation"); | 780 "ConstantPropagation"); |
| 781 #endif // !PRODUCT | 781 #endif // !PRODUCT |
| 782 ConstantPropagator::Optimize(flow_graph); | 782 ConstantPropagator::Optimize(flow_graph); |
| 783 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 783 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 784 // A canonicalization pass to remove e.g. smi checks on smi constants. | 784 // A canonicalization pass to remove e.g. smi checks on smi constants. |
| 785 optimizer.Canonicalize(); | 785 flow_graph->Canonicalize(); |
| 786 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 786 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 787 // Canonicalization introduced more opportunities for constant | 787 // Canonicalization introduced more opportunities for constant |
| 788 // propagation. | 788 // propagation. |
| 789 ConstantPropagator::Optimize(flow_graph); | 789 ConstantPropagator::Optimize(flow_graph); |
| 790 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 790 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 791 } | 791 } |
| 792 | 792 |
| 793 // Optimistically convert loop phis that have a single non-smi input | 793 // Optimistically convert loop phis that have a single non-smi input |
| 794 // coming from the loop pre-header into smi-phis. | 794 // coming from the loop pre-header into smi-phis. |
| 795 if (FLAG_loop_invariant_code_motion) { | 795 if (FLAG_loop_invariant_code_motion) { |
| 796 LICM licm(flow_graph); | 796 LICM licm(flow_graph); |
| 797 licm.OptimisticallySpecializeSmiPhis(); | 797 licm.OptimisticallySpecializeSmiPhis(); |
| 798 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 798 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 799 } | 799 } |
| 800 | 800 |
| 801 // Propagate types and eliminate even more type tests. | 801 // Propagate types and eliminate even more type tests. |
| 802 // Recompute types after constant propagation to infer more precise | 802 // Recompute types after constant propagation to infer more precise |
| 803 // types for uses that were previously reached by now eliminated phis. | 803 // types for uses that were previously reached by now eliminated phis. |
| 804 FlowGraphTypePropagator::Propagate(flow_graph); | 804 FlowGraphTypePropagator::Propagate(flow_graph); |
| 805 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 805 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 806 | 806 |
| 807 { | 807 { |
| 808 #ifndef PRODUCT | 808 #ifndef PRODUCT |
| 809 TimelineDurationScope tds2(thread(), | 809 TimelineDurationScope tds2(thread(), |
| 810 compiler_timeline, | 810 compiler_timeline, |
| 811 "SelectRepresentations"); | 811 "SelectRepresentations"); |
| 812 #endif // !PRODUCT | 812 #endif // !PRODUCT |
| 813 // Where beneficial convert Smi operations into Int32 operations. | 813 // Where beneficial convert Smi operations into Int32 operations. |
| 814 // Only meanigful for 32bit platforms right now. | 814 // Only meanigful for 32bit platforms right now. |
| 815 optimizer.WidenSmiToInt32(); | 815 flow_graph->WidenSmiToInt32(); |
| 816 | 816 |
| 817 // Unbox doubles. Performed after constant propagation to minimize | 817 // Unbox doubles. Performed after constant propagation to minimize |
| 818 // interference from phis merging double values and tagged | 818 // interference from phis merging double values and tagged |
| 819 // values coming from dead paths. | 819 // values coming from dead paths. |
| 820 optimizer.SelectRepresentations(); | 820 flow_graph->SelectRepresentations(); |
| 821 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 821 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 822 } | 822 } |
| 823 | 823 |
| 824 { | 824 { |
| 825 #ifndef PRODUCT | 825 #ifndef PRODUCT |
| 826 TimelineDurationScope tds2(thread(), | 826 TimelineDurationScope tds2(thread(), |
| 827 compiler_timeline, | 827 compiler_timeline, |
| 828 "CommonSubexpressionElinination"); | 828 "CommonSubexpressionElinination"); |
| 829 #endif // !PRODUCT | 829 #endif // !PRODUCT |
| 830 if (FLAG_common_subexpression_elimination || | 830 if (FLAG_common_subexpression_elimination || |
| 831 FLAG_loop_invariant_code_motion) { | 831 FLAG_loop_invariant_code_motion) { |
| 832 flow_graph->ComputeBlockEffects(); | 832 flow_graph->ComputeBlockEffects(); |
| 833 } | 833 } |
| 834 | 834 |
| 835 if (FLAG_common_subexpression_elimination) { | 835 if (FLAG_common_subexpression_elimination) { |
| 836 if (DominatorBasedCSE::Optimize(flow_graph)) { | 836 if (DominatorBasedCSE::Optimize(flow_graph)) { |
| 837 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 837 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 838 optimizer.Canonicalize(); | 838 flow_graph->Canonicalize(); |
| 839 // Do another round of CSE to take secondary effects into account: | 839 // Do another round of CSE to take secondary effects into account: |
| 840 // e.g. when eliminating dependent loads (a.x[0] + a.x[0]) | 840 // e.g. when eliminating dependent loads (a.x[0] + a.x[0]) |
| 841 // TODO(fschneider): Change to a one-pass optimization pass. | 841 // TODO(fschneider): Change to a one-pass optimization pass. |
| 842 if (DominatorBasedCSE::Optimize(flow_graph)) { | 842 if (DominatorBasedCSE::Optimize(flow_graph)) { |
| 843 optimizer.Canonicalize(); | 843 flow_graph->Canonicalize(); |
| 844 } | 844 } |
| 845 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 845 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 846 } | 846 } |
| 847 } | 847 } |
| 848 | 848 |
| 849 // Run loop-invariant code motion right after load elimination since | 849 // Run loop-invariant code motion right after load elimination since |
| 850 // it depends on the numbering of loads from the previous | 850 // it depends on the numbering of loads from the previous |
| 851 // load-elimination. | 851 // load-elimination. |
| 852 if (FLAG_loop_invariant_code_motion) { | 852 if (FLAG_loop_invariant_code_motion) { |
| 853 LICM licm(flow_graph); | 853 LICM licm(flow_graph); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 compiler_timeline, | 915 compiler_timeline, |
| 916 "TryCatchAnalyzer::Optimize"); | 916 "TryCatchAnalyzer::Optimize"); |
| 917 #endif // !PRODUCT | 917 #endif // !PRODUCT |
| 918 // Optimize try-blocks. | 918 // Optimize try-blocks. |
| 919 TryCatchAnalyzer::Optimize(flow_graph); | 919 TryCatchAnalyzer::Optimize(flow_graph); |
| 920 } | 920 } |
| 921 | 921 |
| 922 // Detach environments from the instructions that can't deoptimize. | 922 // Detach environments from the instructions that can't deoptimize. |
| 923 // Do it before we attempt to perform allocation sinking to minimize | 923 // Do it before we attempt to perform allocation sinking to minimize |
| 924 // amount of materializations it has to perform. | 924 // amount of materializations it has to perform. |
| 925 optimizer.EliminateEnvironments(); | 925 flow_graph->EliminateEnvironments(); |
| 926 | 926 |
| 927 { | 927 { |
| 928 #ifndef PRODUCT | 928 #ifndef PRODUCT |
| 929 TimelineDurationScope tds2(thread(), | 929 TimelineDurationScope tds2(thread(), |
| 930 compiler_timeline, | 930 compiler_timeline, |
| 931 "EliminateDeadPhis"); | 931 "EliminateDeadPhis"); |
| 932 #endif // !PRODUCT | 932 #endif // !PRODUCT |
| 933 DeadCodeElimination::EliminateDeadPhis(flow_graph); | 933 DeadCodeElimination::EliminateDeadPhis(flow_graph); |
| 934 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 934 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 935 } | 935 } |
| 936 | 936 |
| 937 if (optimizer.Canonicalize()) { | 937 if (flow_graph->Canonicalize()) { |
| 938 optimizer.Canonicalize(); | 938 flow_graph->Canonicalize(); |
| 939 } | 939 } |
| 940 | 940 |
| 941 // Attempt to sink allocations of temporary non-escaping objects to | 941 // Attempt to sink allocations of temporary non-escaping objects to |
| 942 // the deoptimization path. | 942 // the deoptimization path. |
| 943 AllocationSinking* sinking = NULL; | 943 AllocationSinking* sinking = NULL; |
| 944 if (FLAG_allocation_sinking && | 944 if (FLAG_allocation_sinking && |
| 945 (flow_graph->graph_entry()->SuccessorCount() == 1)) { | 945 (flow_graph->graph_entry()->SuccessorCount() == 1)) { |
| 946 #ifndef PRODUCT | 946 #ifndef PRODUCT |
| 947 TimelineDurationScope tds2(thread(), | 947 TimelineDurationScope tds2(thread(), |
| 948 compiler_timeline, | 948 compiler_timeline, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 961 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 961 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 962 | 962 |
| 963 { | 963 { |
| 964 #ifndef PRODUCT | 964 #ifndef PRODUCT |
| 965 TimelineDurationScope tds2(thread(), | 965 TimelineDurationScope tds2(thread(), |
| 966 compiler_timeline, | 966 compiler_timeline, |
| 967 "SelectRepresentations"); | 967 "SelectRepresentations"); |
| 968 #endif // !PRODUCT | 968 #endif // !PRODUCT |
| 969 // Ensure that all phis inserted by optimization passes have | 969 // Ensure that all phis inserted by optimization passes have |
| 970 // consistent representations. | 970 // consistent representations. |
| 971 optimizer.SelectRepresentations(); | 971 flow_graph->SelectRepresentations(); |
| 972 } | 972 } |
| 973 | 973 |
| 974 if (optimizer.Canonicalize()) { | 974 if (flow_graph->Canonicalize()) { |
| 975 // To fully remove redundant boxing (e.g. BoxDouble used only in | 975 // To fully remove redundant boxing (e.g. BoxDouble used only in |
| 976 // environments and UnboxDouble instructions) instruction we | 976 // environments and UnboxDouble instructions) instruction we |
| 977 // first need to replace all their uses and then fold them away. | 977 // first need to replace all their uses and then fold them away. |
| 978 // For now we just repeat Canonicalize twice to do that. | 978 // For now we just repeat Canonicalize twice to do that. |
| 979 // TODO(vegorov): implement a separate representation folding pass. | 979 // TODO(vegorov): implement a separate representation folding pass. |
| 980 optimizer.Canonicalize(); | 980 flow_graph->Canonicalize(); |
| 981 } | 981 } |
| 982 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 982 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 983 | 983 |
| 984 if (sinking != NULL) { | 984 if (sinking != NULL) { |
| 985 #ifndef PRODUCT | 985 #ifndef PRODUCT |
| 986 TimelineDurationScope tds2( | 986 TimelineDurationScope tds2( |
| 987 thread(), | 987 thread(), |
| 988 compiler_timeline, | 988 compiler_timeline, |
| 989 "AllocationSinking::DetachMaterializations"); | 989 "AllocationSinking::DetachMaterializations"); |
| 990 #endif // !PRODUCT | 990 #endif // !PRODUCT |
| (...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 } | 1888 } |
| 1889 | 1889 |
| 1890 | 1890 |
| 1891 void BackgroundCompiler::EnsureInit(Thread* thread) { | 1891 void BackgroundCompiler::EnsureInit(Thread* thread) { |
| 1892 UNREACHABLE(); | 1892 UNREACHABLE(); |
| 1893 } | 1893 } |
| 1894 | 1894 |
| 1895 #endif // DART_PRECOMPILED_RUNTIME | 1895 #endif // DART_PRECOMPILED_RUNTIME |
| 1896 | 1896 |
| 1897 } // namespace dart | 1897 } // namespace dart |
| OLD | NEW |