| 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 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 // position of the inlined call until later. A side effect of this | 828 // position of the inlined call until later. A side effect of this |
| 829 // is that the length of |inline_id_to_function| is always larger | 829 // is that the length of |inline_id_to_function| is always larger |
| 830 // than the length of |inline_id_to_token_pos| by one. | 830 // than the length of |inline_id_to_token_pos| by one. |
| 831 // Top scope function has no caller (-1). We do this because we expect | 831 // Top scope function has no caller (-1). We do this because we expect |
| 832 // all token positions to be at an inlined call. | 832 // all token positions to be at an inlined call. |
| 833 caller_inline_id.Add(-1); | 833 caller_inline_id.Add(-1); |
| 834 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer); | 834 CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer); |
| 835 | 835 |
| 836 JitOptimizer optimizer(flow_graph); | 836 JitOptimizer optimizer(flow_graph); |
| 837 | 837 |
| 838 optimizer.ApplyICData(); | 838 { |
| 839 NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline, |
| 840 "ApplyICData")); |
| 841 optimizer.ApplyICData(); |
| 842 thread()->CheckForSafepoint(); |
| 843 } |
| 839 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 844 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 840 | 845 |
| 841 // Optimize (a << b) & c patterns, merge operations. | 846 // Optimize (a << b) & c patterns, merge operations. |
| 842 // Run early in order to have more opportunity to optimize left shifts. | 847 // Run early in order to have more opportunity to optimize left shifts. |
| 843 flow_graph->TryOptimizePatterns(); | 848 flow_graph->TryOptimizePatterns(); |
| 844 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 849 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 845 | 850 |
| 846 FlowGraphInliner::SetInliningId(flow_graph, 0); | 851 FlowGraphInliner::SetInliningId(flow_graph, 0); |
| 847 | 852 |
| 848 // Inlining (mutates the flow graph) | 853 // Inlining (mutates the flow graph) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 859 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 864 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 860 | 865 |
| 861 FlowGraphInliner inliner(flow_graph, &inline_id_to_function, | 866 FlowGraphInliner inliner(flow_graph, &inline_id_to_function, |
| 862 &inline_id_to_token_pos, &caller_inline_id, | 867 &inline_id_to_token_pos, &caller_inline_id, |
| 863 use_speculative_inlining, | 868 use_speculative_inlining, |
| 864 /*inlining_black_list=*/NULL, | 869 /*inlining_black_list=*/NULL, |
| 865 /*precompiler=*/NULL); | 870 /*precompiler=*/NULL); |
| 866 inliner.Inline(); | 871 inliner.Inline(); |
| 867 // Use lists are maintained and validated by the inliner. | 872 // Use lists are maintained and validated by the inliner. |
| 868 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 873 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 874 thread()->CheckForSafepoint(); |
| 869 } | 875 } |
| 870 | 876 |
| 871 // Propagate types and eliminate more type tests. | 877 // Propagate types and eliminate more type tests. |
| 872 FlowGraphTypePropagator::Propagate(flow_graph); | 878 FlowGraphTypePropagator::Propagate(flow_graph); |
| 873 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 879 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 874 | 880 |
| 875 { | 881 { |
| 876 NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(), compiler_timeline, | 882 NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(), compiler_timeline, |
| 877 "ApplyClassIds")); | 883 "ApplyClassIds")); |
| 878 // Use propagated class-ids to optimize further. | 884 // Use propagated class-ids to optimize further. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 908 "ConstantPropagation"); | 914 "ConstantPropagation"); |
| 909 ConstantPropagator::Optimize(flow_graph)); | 915 ConstantPropagator::Optimize(flow_graph)); |
| 910 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 916 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 911 // A canonicalization pass to remove e.g. smi checks on smi constants. | 917 // A canonicalization pass to remove e.g. smi checks on smi constants. |
| 912 flow_graph->Canonicalize(); | 918 flow_graph->Canonicalize(); |
| 913 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 919 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 914 // Canonicalization introduced more opportunities for constant | 920 // Canonicalization introduced more opportunities for constant |
| 915 // propagation. | 921 // propagation. |
| 916 ConstantPropagator::Optimize(flow_graph); | 922 ConstantPropagator::Optimize(flow_graph); |
| 917 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 923 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 924 thread()->CheckForSafepoint(); |
| 918 } | 925 } |
| 919 | 926 |
| 920 // Optimistically convert loop phis that have a single non-smi input | 927 // Optimistically convert loop phis that have a single non-smi input |
| 921 // coming from the loop pre-header into smi-phis. | 928 // coming from the loop pre-header into smi-phis. |
| 922 if (FLAG_loop_invariant_code_motion) { | 929 if (FLAG_loop_invariant_code_motion) { |
| 923 LICM licm(flow_graph); | 930 LICM licm(flow_graph); |
| 924 licm.OptimisticallySpecializeSmiPhis(); | 931 licm.OptimisticallySpecializeSmiPhis(); |
| 925 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 932 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 926 } | 933 } |
| 927 | 934 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 // it depends on the numbering of loads from the previous | 978 // it depends on the numbering of loads from the previous |
| 972 // load-elimination. | 979 // load-elimination. |
| 973 if (FLAG_loop_invariant_code_motion) { | 980 if (FLAG_loop_invariant_code_motion) { |
| 974 flow_graph->RenameUsesDominatedByRedefinitions(); | 981 flow_graph->RenameUsesDominatedByRedefinitions(); |
| 975 DEBUG_ASSERT(flow_graph->VerifyRedefinitions()); | 982 DEBUG_ASSERT(flow_graph->VerifyRedefinitions()); |
| 976 LICM licm(flow_graph); | 983 LICM licm(flow_graph); |
| 977 licm.Optimize(); | 984 licm.Optimize(); |
| 978 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 985 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 979 } | 986 } |
| 980 flow_graph->RemoveRedefinitions(); | 987 flow_graph->RemoveRedefinitions(); |
| 988 thread()->CheckForSafepoint(); |
| 981 } | 989 } |
| 982 | 990 |
| 983 // Optimize (a << b) & c patterns, merge operations. | 991 // Optimize (a << b) & c patterns, merge operations. |
| 984 // Run after CSE in order to have more opportunity to merge | 992 // Run after CSE in order to have more opportunity to merge |
| 985 // instructions that have same inputs. | 993 // instructions that have same inputs. |
| 986 flow_graph->TryOptimizePatterns(); | 994 flow_graph->TryOptimizePatterns(); |
| 987 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 995 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 988 | 996 |
| 989 { | 997 { |
| 990 NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(), compiler_timeline, | 998 NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(), compiler_timeline, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 // Attempt to sink allocations of temporary non-escaping objects to | 1058 // Attempt to sink allocations of temporary non-escaping objects to |
| 1051 // the deoptimization path. | 1059 // the deoptimization path. |
| 1052 AllocationSinking* sinking = NULL; | 1060 AllocationSinking* sinking = NULL; |
| 1053 if (FLAG_allocation_sinking && | 1061 if (FLAG_allocation_sinking && |
| 1054 (flow_graph->graph_entry()->SuccessorCount() == 1)) { | 1062 (flow_graph->graph_entry()->SuccessorCount() == 1)) { |
| 1055 NOT_IN_PRODUCT(TimelineDurationScope tds2( | 1063 NOT_IN_PRODUCT(TimelineDurationScope tds2( |
| 1056 thread(), compiler_timeline, "AllocationSinking::Optimize")); | 1064 thread(), compiler_timeline, "AllocationSinking::Optimize")); |
| 1057 // TODO(fschneider): Support allocation sinking with try-catch. | 1065 // TODO(fschneider): Support allocation sinking with try-catch. |
| 1058 sinking = new AllocationSinking(flow_graph); | 1066 sinking = new AllocationSinking(flow_graph); |
| 1059 sinking->Optimize(); | 1067 sinking->Optimize(); |
| 1068 thread()->CheckForSafepoint(); |
| 1060 } | 1069 } |
| 1061 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 1070 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 1062 | 1071 |
| 1063 DeadCodeElimination::EliminateDeadPhis(flow_graph); | 1072 DeadCodeElimination::EliminateDeadPhis(flow_graph); |
| 1064 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 1073 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 1065 | 1074 |
| 1066 FlowGraphTypePropagator::Propagate(flow_graph); | 1075 FlowGraphTypePropagator::Propagate(flow_graph); |
| 1067 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 1076 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 1068 | 1077 |
| 1069 { | 1078 { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1099 // to be later used by the inliner. | 1108 // to be later used by the inliner. |
| 1100 FlowGraphInliner::CollectGraphInfo(flow_graph, true); | 1109 FlowGraphInliner::CollectGraphInfo(flow_graph, true); |
| 1101 | 1110 |
| 1102 flow_graph->RemoveRedefinitions(); | 1111 flow_graph->RemoveRedefinitions(); |
| 1103 { | 1112 { |
| 1104 NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(), compiler_timeline, | 1113 NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(), compiler_timeline, |
| 1105 "AllocateRegisters")); | 1114 "AllocateRegisters")); |
| 1106 // Perform register allocation on the SSA graph. | 1115 // Perform register allocation on the SSA graph. |
| 1107 FlowGraphAllocator allocator(*flow_graph); | 1116 FlowGraphAllocator allocator(*flow_graph); |
| 1108 allocator.AllocateRegisters(); | 1117 allocator.AllocateRegisters(); |
| 1118 thread()->CheckForSafepoint(); |
| 1109 } | 1119 } |
| 1110 | 1120 |
| 1111 if (reorder_blocks) { | 1121 if (reorder_blocks) { |
| 1112 NOT_IN_PRODUCT(TimelineDurationScope tds( | 1122 NOT_IN_PRODUCT(TimelineDurationScope tds( |
| 1113 thread(), compiler_timeline, "BlockScheduler::ReorderBlocks")); | 1123 thread(), compiler_timeline, "BlockScheduler::ReorderBlocks")); |
| 1114 block_scheduler.ReorderBlocks(); | 1124 block_scheduler.ReorderBlocks(); |
| 1115 } | 1125 } |
| 1116 | 1126 |
| 1117 if (print_flow_graph) { | 1127 if (print_flow_graph) { |
| 1118 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); | 1128 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); |
| (...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2297 | 2307 |
| 2298 | 2308 |
| 2299 bool BackgroundCompiler::IsDisabled() { | 2309 bool BackgroundCompiler::IsDisabled() { |
| 2300 UNREACHABLE(); | 2310 UNREACHABLE(); |
| 2301 return true; | 2311 return true; |
| 2302 } | 2312 } |
| 2303 | 2313 |
| 2304 #endif // DART_PRECOMPILED_RUNTIME | 2314 #endif // DART_PRECOMPILED_RUNTIME |
| 2305 | 2315 |
| 2306 } // namespace dart | 2316 } // namespace dart |
| OLD | NEW |