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 |