| 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 |