OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/precompiler.h" | 5 #include "vm/precompiler.h" |
6 | 6 |
7 #include "vm/aot_optimizer.h" | 7 #include "vm/aot_optimizer.h" |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
10 #include "vm/branch_optimizer.h" | 10 #include "vm/branch_optimizer.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 | 53 |
54 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); | 54 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); |
55 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); | 55 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); |
56 DEFINE_FLAG( | 56 DEFINE_FLAG( |
57 int, | 57 int, |
58 max_speculative_inlining_attempts, | 58 max_speculative_inlining_attempts, |
59 1, | 59 1, |
60 "Max number of attempts with speculative inlining (precompilation only)"); | 60 "Max number of attempts with speculative inlining (precompilation only)"); |
61 DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations"); | 61 DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations"); |
62 | 62 |
| 63 |
63 DECLARE_FLAG(bool, allocation_sinking); | 64 DECLARE_FLAG(bool, allocation_sinking); |
64 DECLARE_FLAG(bool, common_subexpression_elimination); | 65 DECLARE_FLAG(bool, common_subexpression_elimination); |
65 DECLARE_FLAG(bool, constant_propagation); | 66 DECLARE_FLAG(bool, constant_propagation); |
66 DECLARE_FLAG(bool, loop_invariant_code_motion); | 67 DECLARE_FLAG(bool, loop_invariant_code_motion); |
67 DECLARE_FLAG(bool, print_flow_graph); | 68 DECLARE_FLAG(bool, print_flow_graph); |
68 DECLARE_FLAG(bool, print_flow_graph_optimized); | 69 DECLARE_FLAG(bool, print_flow_graph_optimized); |
69 DECLARE_FLAG(bool, range_analysis); | 70 DECLARE_FLAG(bool, range_analysis); |
70 DECLARE_FLAG(bool, trace_compiler); | 71 DECLARE_FLAG(bool, trace_compiler); |
71 DECLARE_FLAG(bool, trace_optimizing_compiler); | 72 DECLARE_FLAG(bool, trace_optimizing_compiler); |
72 DECLARE_FLAG(bool, trace_bailout); | 73 DECLARE_FLAG(bool, trace_bailout); |
73 DECLARE_FLAG(bool, use_inlining); | 74 DECLARE_FLAG(bool, use_inlining); |
74 DECLARE_FLAG(bool, verify_compiler); | 75 DECLARE_FLAG(bool, verify_compiler); |
75 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); | 76 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); |
76 DECLARE_FLAG(bool, trace_failed_optimization_attempts); | 77 DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
77 DECLARE_FLAG(bool, trace_inlining_intervals); | 78 DECLARE_FLAG(bool, trace_inlining_intervals); |
78 DECLARE_FLAG(bool, trace_irregexp); | 79 DECLARE_FLAG(bool, trace_irregexp); |
| 80 DECLARE_FLAG(bool, print_instruction_stats); |
79 | 81 |
80 #ifdef DART_PRECOMPILER | 82 #ifdef DART_PRECOMPILER |
81 | 83 |
82 class DartPrecompilationPipeline : public DartCompilationPipeline { | 84 class DartPrecompilationPipeline : public DartCompilationPipeline { |
83 public: | 85 public: |
84 explicit DartPrecompilationPipeline(Zone* zone, | 86 explicit DartPrecompilationPipeline(Zone* zone, |
85 FieldTypeMap* field_map = NULL) | 87 FieldTypeMap* field_map = NULL) |
86 : zone_(zone), result_type_(CompileType::None()), field_map_(field_map) {} | 88 : zone_(zone), result_type_(CompileType::None()), field_map_(field_map) {} |
87 | 89 |
88 virtual void FinalizeCompilation(FlowGraph* flow_graph) { | 90 virtual void FinalizeCompilation(FlowGraph* flow_graph) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 bool Compile(CompilationPipeline* pipeline); | 164 bool Compile(CompilationPipeline* pipeline); |
163 | 165 |
164 private: | 166 private: |
165 ParsedFunction* parsed_function() const { return parsed_function_; } | 167 ParsedFunction* parsed_function() const { return parsed_function_; } |
166 bool optimized() const { return optimized_; } | 168 bool optimized() const { return optimized_; } |
167 Thread* thread() const { return thread_; } | 169 Thread* thread() const { return thread_; } |
168 Isolate* isolate() const { return thread_->isolate(); } | 170 Isolate* isolate() const { return thread_->isolate(); } |
169 | 171 |
170 void FinalizeCompilation(Assembler* assembler, | 172 void FinalizeCompilation(Assembler* assembler, |
171 FlowGraphCompiler* graph_compiler, | 173 FlowGraphCompiler* graph_compiler, |
172 FlowGraph* flow_graph); | 174 FlowGraph* flow_graph, |
| 175 CodeStatistics* stats); |
173 | 176 |
174 Precompiler* precompiler_; | 177 Precompiler* precompiler_; |
175 ParsedFunction* parsed_function_; | 178 ParsedFunction* parsed_function_; |
176 const bool optimized_; | 179 const bool optimized_; |
177 Thread* const thread_; | 180 Thread* const thread_; |
178 | 181 |
179 DISALLOW_COPY_AND_ASSIGN(PrecompileParsedFunctionHelper); | 182 DISALLOW_COPY_AND_ASSIGN(PrecompileParsedFunctionHelper); |
180 }; | 183 }; |
181 | 184 |
182 | 185 |
(...skipping 2438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2621 } | 2624 } |
2622 cls.set_is_allocated(false); | 2625 cls.set_is_allocated(false); |
2623 } | 2626 } |
2624 } | 2627 } |
2625 } | 2628 } |
2626 | 2629 |
2627 | 2630 |
2628 void PrecompileParsedFunctionHelper::FinalizeCompilation( | 2631 void PrecompileParsedFunctionHelper::FinalizeCompilation( |
2629 Assembler* assembler, | 2632 Assembler* assembler, |
2630 FlowGraphCompiler* graph_compiler, | 2633 FlowGraphCompiler* graph_compiler, |
2631 FlowGraph* flow_graph) { | 2634 FlowGraph* flow_graph, |
| 2635 CodeStatistics* stats) { |
2632 const Function& function = parsed_function()->function(); | 2636 const Function& function = parsed_function()->function(); |
2633 Zone* const zone = thread()->zone(); | 2637 Zone* const zone = thread()->zone(); |
2634 | 2638 |
2635 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); | 2639 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); |
2636 // CreateDeoptInfo uses the object pool and needs to be done before | 2640 // CreateDeoptInfo uses the object pool and needs to be done before |
2637 // FinalizeCode. | 2641 // FinalizeCode. |
2638 const Array& deopt_info_array = | 2642 const Array& deopt_info_array = |
2639 Array::Handle(zone, graph_compiler->CreateDeoptInfo(assembler)); | 2643 Array::Handle(zone, graph_compiler->CreateDeoptInfo(assembler)); |
2640 INC_STAT(thread(), total_code_size, | 2644 INC_STAT(thread(), total_code_size, |
2641 deopt_info_array.Length() * sizeof(uword)); | 2645 deopt_info_array.Length() * sizeof(uword)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2678 if (optimized()) { | 2682 if (optimized()) { |
2679 // Installs code while at safepoint. | 2683 // Installs code while at safepoint. |
2680 ASSERT(thread()->IsMutatorThread()); | 2684 ASSERT(thread()->IsMutatorThread()); |
2681 function.InstallOptimizedCode(code, /* is_osr = */ false); | 2685 function.InstallOptimizedCode(code, /* is_osr = */ false); |
2682 } else { // not optimized. | 2686 } else { // not optimized. |
2683 function.set_unoptimized_code(code); | 2687 function.set_unoptimized_code(code); |
2684 function.AttachCode(code); | 2688 function.AttachCode(code); |
2685 } | 2689 } |
2686 ASSERT(!parsed_function()->HasDeferredPrefixes()); | 2690 ASSERT(!parsed_function()->HasDeferredPrefixes()); |
2687 ASSERT(FLAG_load_deferred_eagerly); | 2691 ASSERT(FLAG_load_deferred_eagerly); |
| 2692 |
| 2693 if (stats != NULL) { |
| 2694 stats->Finalize(); |
| 2695 code.set_stats(stats); |
| 2696 } |
2688 } | 2697 } |
2689 | 2698 |
2690 | 2699 |
2691 // Return false if bailed out. | 2700 // Return false if bailed out. |
2692 // If optimized_result_code is not NULL then it is caller's responsibility | 2701 // If optimized_result_code is not NULL then it is caller's responsibility |
2693 // to install code. | 2702 // to install code. |
2694 bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { | 2703 bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { |
2695 ASSERT(FLAG_precompiled_mode); | 2704 ASSERT(FLAG_precompiled_mode); |
2696 const Function& function = parsed_function()->function(); | 2705 const Function& function = parsed_function()->function(); |
2697 if (optimized() && !function.IsOptimizable()) { | 2706 if (optimized() && !function.IsOptimizable()) { |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3104 allocator.AllocateRegisters(); | 3113 allocator.AllocateRegisters(); |
3105 } | 3114 } |
3106 | 3115 |
3107 if (print_flow_graph) { | 3116 if (print_flow_graph) { |
3108 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); | 3117 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); |
3109 } | 3118 } |
3110 } | 3119 } |
3111 | 3120 |
3112 ASSERT(inline_id_to_function.length() == caller_inline_id.length()); | 3121 ASSERT(inline_id_to_function.length() == caller_inline_id.length()); |
3113 Assembler assembler(use_far_branches); | 3122 Assembler assembler(use_far_branches); |
| 3123 |
| 3124 CodeStatistics* function_stats = NULL; |
| 3125 if (FLAG_print_instruction_stats) { |
| 3126 function_stats = new CodeStatistics(&assembler); |
| 3127 } |
| 3128 |
3114 FlowGraphCompiler graph_compiler( | 3129 FlowGraphCompiler graph_compiler( |
3115 &assembler, flow_graph, *parsed_function(), optimized(), | 3130 &assembler, flow_graph, *parsed_function(), optimized(), |
3116 inline_id_to_function, inline_id_to_token_pos, caller_inline_id); | 3131 inline_id_to_function, inline_id_to_token_pos, caller_inline_id, |
| 3132 function_stats); |
3117 { | 3133 { |
3118 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer); | 3134 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer); |
3119 #ifndef PRODUCT | 3135 #ifndef PRODUCT |
3120 TimelineDurationScope tds(thread(), compiler_timeline, "CompileGraph"); | 3136 TimelineDurationScope tds(thread(), compiler_timeline, "CompileGraph"); |
3121 #endif // !PRODUCT | 3137 #endif // !PRODUCT |
3122 graph_compiler.CompileGraph(); | 3138 graph_compiler.CompileGraph(); |
3123 pipeline->FinalizeCompilation(flow_graph); | 3139 pipeline->FinalizeCompilation(flow_graph); |
3124 } | 3140 } |
3125 { | 3141 { |
3126 #ifndef PRODUCT | 3142 #ifndef PRODUCT |
3127 TimelineDurationScope tds(thread(), compiler_timeline, | 3143 TimelineDurationScope tds(thread(), compiler_timeline, |
3128 "FinalizeCompilation"); | 3144 "FinalizeCompilation"); |
3129 #endif // !PRODUCT | 3145 #endif // !PRODUCT |
3130 ASSERT(thread()->IsMutatorThread()); | 3146 ASSERT(thread()->IsMutatorThread()); |
3131 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); | 3147 FinalizeCompilation( |
| 3148 &assembler, &graph_compiler, flow_graph, function_stats); |
3132 } | 3149 } |
3133 // Mark that this isolate now has compiled code. | 3150 // Mark that this isolate now has compiled code. |
3134 isolate()->set_has_compiled_code(true); | 3151 isolate()->set_has_compiled_code(true); |
3135 // Exit the loop and the function with the correct result value. | 3152 // Exit the loop and the function with the correct result value. |
3136 is_compiled = true; | 3153 is_compiled = true; |
3137 done = true; | 3154 done = true; |
3138 } else { | 3155 } else { |
3139 // We bailed out or we encountered an error. | 3156 // We bailed out or we encountered an error. |
3140 const Error& error = Error::Handle(thread()->sticky_error()); | 3157 const Error& error = Error::Handle(thread()->sticky_error()); |
3141 | 3158 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3180 // Clear the error if it was not a real error, but just a bailout. | 3197 // Clear the error if it was not a real error, but just a bailout. |
3181 if (error.IsLanguageError() && | 3198 if (error.IsLanguageError() && |
3182 (LanguageError::Cast(error).kind() == Report::kBailout)) { | 3199 (LanguageError::Cast(error).kind() == Report::kBailout)) { |
3183 thread()->clear_sticky_error(); | 3200 thread()->clear_sticky_error(); |
3184 } | 3201 } |
3185 is_compiled = false; | 3202 is_compiled = false; |
3186 } | 3203 } |
3187 // Reset global isolate state. | 3204 // Reset global isolate state. |
3188 thread()->set_deopt_id(prev_deopt_id); | 3205 thread()->set_deopt_id(prev_deopt_id); |
3189 } | 3206 } |
| 3207 |
3190 return is_compiled; | 3208 return is_compiled; |
3191 } | 3209 } |
3192 | 3210 |
3193 | 3211 |
3194 static RawError* PrecompileFunctionHelper(Precompiler* precompiler, | 3212 static RawError* PrecompileFunctionHelper(Precompiler* precompiler, |
3195 CompilationPipeline* pipeline, | 3213 CompilationPipeline* pipeline, |
3196 const Function& function, | 3214 const Function& function, |
3197 bool optimized) { | 3215 bool optimized) { |
3198 // Check that we optimize, except if the function is not optimizable. | 3216 // Check that we optimize, except if the function is not optimizable. |
3199 ASSERT(FLAG_precompiled_mode); | 3217 ASSERT(FLAG_precompiled_mode); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3288 | 3306 |
3289 ASSERT(FLAG_precompiled_mode); | 3307 ASSERT(FLAG_precompiled_mode); |
3290 const bool optimized = function.IsOptimizable(); // False for natives. | 3308 const bool optimized = function.IsOptimizable(); // False for natives. |
3291 DartPrecompilationPipeline pipeline(zone, field_type_map); | 3309 DartPrecompilationPipeline pipeline(zone, field_type_map); |
3292 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); | 3310 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); |
3293 } | 3311 } |
3294 | 3312 |
3295 #endif // DART_PRECOMPILER | 3313 #endif // DART_PRECOMPILER |
3296 | 3314 |
3297 } // namespace dart | 3315 } // namespace dart |
OLD | NEW |