Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: runtime/vm/precompiler.cc

Issue 1973553003: VM precompiler: Compute and use result type of static initializers of final fields. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rebased Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/precompiler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 #define T (thread()) 48 #define T (thread())
49 #define I (isolate()) 49 #define I (isolate())
50 #define Z (zone()) 50 #define Z (zone())
51 51
52 52
53 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); 53 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets");
54 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); 54 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");
55 DEFINE_FLAG(int, max_speculative_inlining_attempts, 1, 55 DEFINE_FLAG(int, max_speculative_inlining_attempts, 1,
56 "Max number of attempts with speculative inlining (precompilation only)"); 56 "Max number of attempts with speculative inlining (precompilation only)");
57 DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations"); 57 DEFINE_FLAG(int, precompiler_rounds, 2, "Number of precompiler iterations");
Vyacheslav Egorov (Google) 2016/05/12 11:18:55 We should check that this does not slow down Flutt
Florian Schneider 2016/05/12 11:37:17 Agree. Current measurements shows 60% increase in
58 58
59 DECLARE_FLAG(bool, allocation_sinking); 59 DECLARE_FLAG(bool, allocation_sinking);
60 DECLARE_FLAG(bool, common_subexpression_elimination); 60 DECLARE_FLAG(bool, common_subexpression_elimination);
61 DECLARE_FLAG(bool, constant_propagation); 61 DECLARE_FLAG(bool, constant_propagation);
62 DECLARE_FLAG(bool, loop_invariant_code_motion); 62 DECLARE_FLAG(bool, loop_invariant_code_motion);
63 DECLARE_FLAG(bool, print_flow_graph); 63 DECLARE_FLAG(bool, print_flow_graph);
64 DECLARE_FLAG(bool, print_flow_graph_optimized); 64 DECLARE_FLAG(bool, print_flow_graph_optimized);
65 DECLARE_FLAG(bool, range_analysis); 65 DECLARE_FLAG(bool, range_analysis);
66 DECLARE_FLAG(bool, trace_compiler); 66 DECLARE_FLAG(bool, trace_compiler);
67 DECLARE_FLAG(bool, trace_optimizing_compiler); 67 DECLARE_FLAG(bool, trace_optimizing_compiler);
68 DECLARE_FLAG(bool, trace_bailout); 68 DECLARE_FLAG(bool, trace_bailout);
69 DECLARE_FLAG(bool, use_inlining); 69 DECLARE_FLAG(bool, use_inlining);
70 DECLARE_FLAG(bool, verify_compiler); 70 DECLARE_FLAG(bool, verify_compiler);
71 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); 71 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
72 DECLARE_FLAG(bool, trace_failed_optimization_attempts); 72 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
73 DECLARE_FLAG(bool, trace_inlining_intervals); 73 DECLARE_FLAG(bool, trace_inlining_intervals);
74 DECLARE_FLAG(bool, trace_irregexp); 74 DECLARE_FLAG(bool, trace_irregexp);
75 75
76 #ifdef DART_PRECOMPILER 76 #ifdef DART_PRECOMPILER
77 77
78 class DartPrecompilationPipeline : public DartCompilationPipeline {
79 public:
80 DartPrecompilationPipeline() : result_type_(CompileType::None()) { }
81
82 virtual void FinalizeCompilation(FlowGraph* flow_graph) {
83 CompileType result_type = CompileType::None();
84 for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
85 !block_it.Done();
86 block_it.Advance()) {
87 ForwardInstructionIterator it(block_it.Current());
88 for (; !it.Done(); it.Advance()) {
89 ReturnInstr* return_instr = it.Current()->AsReturn();
90 if (return_instr != NULL) {
91 result_type.Union(return_instr->InputAt(0)->Type());
92 }
93 }
94 }
95 result_type_ = result_type;
96 }
97
98 CompileType result_type() { return result_type_; }
99
100 private:
101 CompileType result_type_;
102 };
103
104
78 class PrecompileParsedFunctionHelper : public ValueObject { 105 class PrecompileParsedFunctionHelper : public ValueObject {
79 public: 106 public:
80 PrecompileParsedFunctionHelper(ParsedFunction* parsed_function, 107 PrecompileParsedFunctionHelper(ParsedFunction* parsed_function,
81 bool optimized) 108 bool optimized)
82 : parsed_function_(parsed_function), 109 : parsed_function_(parsed_function),
83 optimized_(optimized), 110 optimized_(optimized),
84 thread_(Thread::Current()) { 111 thread_(Thread::Current()) {
85 } 112 }
86 113
87 bool Compile(CompilationPipeline* pipeline); 114 bool Compile(CompilationPipeline* pipeline);
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 788
762 const bool is_initialized = value.raw() != Object::sentinel().raw(); 789 const bool is_initialized = value.raw() != Object::sentinel().raw();
763 if (is_initialized && !reset_fields_) return; 790 if (is_initialized && !reset_fields_) return;
764 791
765 if (!field.HasPrecompiledInitializer() || 792 if (!field.HasPrecompiledInitializer() ||
766 !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) { 793 !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) {
767 if (FLAG_trace_precompiler) { 794 if (FLAG_trace_precompiler) {
768 THR_Print("Precompiling initializer for %s\n", field.ToCString()); 795 THR_Print("Precompiling initializer for %s\n", field.ToCString());
769 } 796 }
770 ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT); 797 ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT);
771 const Function& initializer = 798 const Function& initializer = Function::Handle(Z,
772 Function::Handle(Z, CompileStaticInitializer(field)); 799 CompileStaticInitializer(field, /* compute_type = */ true));
773 ASSERT(!initializer.IsNull()); 800 ASSERT(!initializer.IsNull());
774 field.SetPrecompiledInitializer(initializer); 801 field.SetPrecompiledInitializer(initializer);
775 AddCalleesOf(initializer); 802 AddCalleesOf(initializer);
776 } 803 }
777 } 804 }
778 } 805 }
779 } 806 }
780 807
781 808
782 RawFunction* Precompiler::CompileStaticInitializer(const Field& field) { 809 RawFunction* Precompiler::CompileStaticInitializer(const Field& field,
810 bool compute_type) {
783 ASSERT(field.is_static()); 811 ASSERT(field.is_static());
784 Thread* thread = Thread::Current(); 812 Thread* thread = Thread::Current();
785 StackZone zone(thread); 813 StackZone zone(thread);
786 814
787 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); 815 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field);
788 816
789 parsed_function->AllocateVariables(); 817 parsed_function->AllocateVariables();
790 DartCompilationPipeline pipeline; 818 DartPrecompilationPipeline pipeline;
791 PrecompileParsedFunctionHelper helper(parsed_function, 819 PrecompileParsedFunctionHelper helper(parsed_function,
792 /* optimized = */ true); 820 /* optimized = */ true);
793 bool success = helper.Compile(&pipeline); 821 bool success = helper.Compile(&pipeline);
794 ASSERT(success); 822 ASSERT(success);
795 823
824 if (compute_type && field.is_final()) {
825 intptr_t result_cid = pipeline.result_type().ToCid();
826 if (result_cid != kDynamicCid) {
827 if (FLAG_trace_precompiler) {
828 THR_Print("Setting guarded_cid of %s to %s\n", field.ToCString(),
829 pipeline.result_type().ToCString());
830 }
831 field.set_guarded_cid(result_cid);
832 }
833 }
834
796 if ((FLAG_disassemble || FLAG_disassemble_optimized) && 835 if ((FLAG_disassemble || FLAG_disassemble_optimized) &&
797 FlowGraphPrinter::ShouldPrint(parsed_function->function())) { 836 FlowGraphPrinter::ShouldPrint(parsed_function->function())) {
798 Disassembler::DisassembleCode(parsed_function->function(), 837 Disassembler::DisassembleCode(parsed_function->function(),
799 /* optimized = */ true); 838 /* optimized = */ true);
800 } 839 }
801 return parsed_function->function().raw(); 840 return parsed_function->function().raw();
802 } 841 }
803 842
804 843
805 RawObject* Precompiler::EvaluateStaticInitializer(const Field& field) { 844 RawObject* Precompiler::EvaluateStaticInitializer(const Field& field) {
806 ASSERT(field.is_static()); 845 ASSERT(field.is_static());
807 // The VM sets the field's value to transiton_sentinel prior to 846 // The VM sets the field's value to transiton_sentinel prior to
808 // evaluating the initializer value. 847 // evaluating the initializer value.
809 ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); 848 ASSERT(field.StaticValue() == Object::transition_sentinel().raw());
810 LongJumpScope jump; 849 LongJumpScope jump;
811 if (setjmp(*jump.Set()) == 0) { 850 if (setjmp(*jump.Set()) == 0) {
812 // Under precompilation, the initializer may have already been compiled, in 851 // Under precompilation, the initializer may have already been compiled, in
813 // which case use it. Under lazy compilation or early in precompilation, the 852 // which case use it. Under lazy compilation or early in precompilation, the
814 // initializer has not yet been created, so create it now, but don't bother 853 // initializer has not yet been created, so create it now, but don't bother
815 // remembering it because it won't be used again. 854 // remembering it because it won't be used again.
816 Function& initializer = Function::Handle(); 855 Function& initializer = Function::Handle();
817 if (!field.HasPrecompiledInitializer()) { 856 if (!field.HasPrecompiledInitializer()) {
818 initializer = CompileStaticInitializer(field); 857 initializer = CompileStaticInitializer(field, /* compute_type = */ false);
819 } else { 858 } else {
820 initializer ^= field.PrecompiledInitializer(); 859 initializer ^= field.PrecompiledInitializer();
821 } 860 }
822 // Invoke the function to evaluate the expression. 861 // Invoke the function to evaluate the expression.
823 return DartEntry::InvokeFunction(initializer, Object::empty_array()); 862 return DartEntry::InvokeFunction(initializer, Object::empty_array());
824 } else { 863 } else {
825 Thread* const thread = Thread::Current(); 864 Thread* const thread = Thread::Current();
826 StackZone zone(thread); 865 StackZone zone(thread);
827 const Error& error = 866 const Error& error =
828 Error::Handle(thread->zone(), thread->sticky_error()); 867 Error::Handle(thread->zone(), thread->sticky_error());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 // would compile func automatically. We are checking fewer invariants 908 // would compile func automatically. We are checking fewer invariants
870 // here. 909 // here.
871 ParsedFunction* parsed_function = new ParsedFunction(thread, func); 910 ParsedFunction* parsed_function = new ParsedFunction(thread, func);
872 parsed_function->SetNodeSequence(fragment); 911 parsed_function->SetNodeSequence(fragment);
873 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp()); 912 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp());
874 fragment->scope()->AddVariable( 913 fragment->scope()->AddVariable(
875 parsed_function->current_context_var()); 914 parsed_function->current_context_var());
876 parsed_function->AllocateVariables(); 915 parsed_function->AllocateVariables();
877 916
878 // Non-optimized code generator. 917 // Non-optimized code generator.
879 DartCompilationPipeline pipeline; 918 DartPrecompilationPipeline pipeline;
880 PrecompileParsedFunctionHelper helper(parsed_function, 919 PrecompileParsedFunctionHelper helper(parsed_function,
881 /* optimized = */ false); 920 /* optimized = */ false);
882 helper.Compile(&pipeline); 921 helper.Compile(&pipeline);
883 Code::Handle(func.unoptimized_code()).set_var_descriptors( 922 Code::Handle(func.unoptimized_code()).set_var_descriptors(
884 Object::empty_var_descriptors()); 923 Object::empty_var_descriptors());
885 924
886 const Object& result = PassiveObject::Handle( 925 const Object& result = PassiveObject::Handle(
887 DartEntry::InvokeFunction(func, Object::empty_array())); 926 DartEntry::InvokeFunction(func, Object::empty_array()));
888 return result.raw(); 927 return result.raw();
889 } else { 928 } else {
(...skipping 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after
2572 inline_id_to_token_pos, 2611 inline_id_to_token_pos,
2573 caller_inline_id); 2612 caller_inline_id);
2574 { 2613 {
2575 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer); 2614 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer);
2576 #ifndef PRODUCT 2615 #ifndef PRODUCT
2577 TimelineDurationScope tds(thread(), 2616 TimelineDurationScope tds(thread(),
2578 compiler_timeline, 2617 compiler_timeline,
2579 "CompileGraph"); 2618 "CompileGraph");
2580 #endif // !PRODUCT 2619 #endif // !PRODUCT
2581 graph_compiler.CompileGraph(); 2620 graph_compiler.CompileGraph();
2582 pipeline->FinalizeCompilation(); 2621 pipeline->FinalizeCompilation(flow_graph);
2583 } 2622 }
2584 { 2623 {
2585 #ifndef PRODUCT 2624 #ifndef PRODUCT
2586 TimelineDurationScope tds(thread(), 2625 TimelineDurationScope tds(thread(),
2587 compiler_timeline, 2626 compiler_timeline,
2588 "FinalizeCompilation"); 2627 "FinalizeCompilation");
2589 #endif // !PRODUCT 2628 #endif // !PRODUCT
2590 ASSERT(thread()->IsMutatorThread()); 2629 ASSERT(thread()->IsMutatorThread());
2591 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); 2630 FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
2592 } 2631 }
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2747 CompilationPipeline::New(thread->zone(), function); 2786 CompilationPipeline::New(thread->zone(), function);
2748 2787
2749 ASSERT(FLAG_precompiled_mode); 2788 ASSERT(FLAG_precompiled_mode);
2750 const bool optimized = function.IsOptimizable(); // False for natives. 2789 const bool optimized = function.IsOptimizable(); // False for natives.
2751 return PrecompileFunctionHelper(pipeline, function, optimized); 2790 return PrecompileFunctionHelper(pipeline, function, optimized);
2752 } 2791 }
2753 2792
2754 #endif // DART_PRECOMPILER 2793 #endif // DART_PRECOMPILER
2755 2794
2756 } // namespace dart 2795 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/precompiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698