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/flow_graph.h" | 5 #include "vm/flow_graph.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
9 #include "vm/growable_array.h" | |
9 #include "vm/intermediate_language.h" | 10 #include "vm/intermediate_language.h" |
10 #include "vm/longjump.h" | 11 #include "vm/longjump.h" |
11 #include "vm/growable_array.h" | 12 #include "vm/stack_frame.h" |
12 | 13 |
13 namespace dart { | 14 namespace dart { |
14 | 15 |
15 DECLARE_FLAG(bool, reorder_basic_blocks); | 16 DECLARE_FLAG(bool, reorder_basic_blocks); |
16 DECLARE_FLAG(bool, trace_optimization); | 17 DECLARE_FLAG(bool, trace_optimization); |
17 DECLARE_FLAG(bool, verify_compiler); | 18 DECLARE_FLAG(bool, verify_compiler); |
18 DEFINE_FLAG(bool, optimize_try_catch, true, "Optimization of try-catch"); | 19 DEFINE_FLAG(bool, optimize_try_catch, true, "Optimization of try-catch"); |
19 | 20 |
20 | 21 |
21 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, | 22 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 | 71 |
71 GrowableArray<BlockEntryInstr*>* FlowGraph::CodegenBlockOrder( | 72 GrowableArray<BlockEntryInstr*>* FlowGraph::CodegenBlockOrder( |
72 bool is_optimized) { | 73 bool is_optimized) { |
73 return ShouldReorderBlocks(parsed_function().function(), is_optimized) | 74 return ShouldReorderBlocks(parsed_function().function(), is_optimized) |
74 ? &optimized_block_order_ | 75 ? &optimized_block_order_ |
75 : &reverse_postorder_; | 76 : &reverse_postorder_; |
76 } | 77 } |
77 | 78 |
78 | 79 |
79 ConstantInstr* FlowGraph::GetConstant(const Object& object) { | 80 ConstantInstr* FlowGraph::GetConstant(const Object& object) { |
81 // Not all objects can be embedded in code. | |
82 ASSERT(object.IsSmi() || object.InVMHeap() || object.IsOld()); | |
80 // Check if the constant is already in the pool. | 83 // Check if the constant is already in the pool. |
81 GrowableArray<Definition*>* pool = graph_entry_->initial_definitions(); | 84 GrowableArray<Definition*>* pool = graph_entry_->initial_definitions(); |
82 for (intptr_t i = 0; i < pool->length(); ++i) { | 85 for (intptr_t i = 0; i < pool->length(); ++i) { |
83 ConstantInstr* constant = (*pool)[i]->AsConstant(); | 86 ConstantInstr* constant = (*pool)[i]->AsConstant(); |
84 if ((constant != NULL) && (constant->value().raw() == object.raw())) { | 87 if ((constant != NULL) && (constant->value().raw() == object.raw())) { |
85 return constant; | 88 return constant; |
86 } | 89 } |
87 } | 90 } |
88 // Otherwise, allocate and add it to the pool. | 91 // Otherwise, allocate and add it to the pool. |
89 ConstantInstr* constant = new ConstantInstr(object); | 92 ConstantInstr* constant = new ConstantInstr(object); |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
688 work[index] = var_index; | 691 work[index] = var_index; |
689 worklist.Add(block); | 692 worklist.Add(block); |
690 } | 693 } |
691 } | 694 } |
692 } | 695 } |
693 } | 696 } |
694 } | 697 } |
695 } | 698 } |
696 | 699 |
697 | 700 |
701 void FlowGraph::InitializeOsrLocalRange(GrowableArray<Definition*>* env, | |
702 RawObject** base, | |
703 intptr_t count) { | |
704 for (intptr_t i = 0; i < count; ++i) { | |
705 // Variables go from high to low addresses as they go from left to | |
706 // right. | |
707 Object& value = Object::ZoneHandle(base[-i]); | |
srdjan
2014/01/07 18:51:20
const Object&
Florian Schneider
2014/01/08 10:48:03
Done.
| |
708 Definition* definition = NULL; | |
709 if (value.IsSmi() || value.InVMHeap() || value.IsOld()) { | |
710 definition = GetConstant(value); | |
711 } else { | |
712 definition = new ParameterInstr(env->length(), graph_entry()); | |
Kevin Millikin (Google)
2014/01/07 14:09:19
I know you've already thought of this, but here yo
Florian Schneider
2014/01/08 10:48:03
Good point. I'll do this in a separate CL since ad
| |
713 definition->set_ssa_temp_index(alloc_ssa_temp_index()); | |
714 AddToInitialDefinitions(definition); | |
715 } | |
716 env->Add(definition); | |
717 } | |
718 } | |
719 | |
720 | |
721 void FlowGraph::InitializeOsrLocals(GrowableArray<Definition*>* env) { | |
722 DartFrameIterator iterator; | |
723 StackFrame* frame = iterator.NextFrame(); | |
724 const Code& code = Code::Handle(frame->LookupDartCode()); | |
725 ASSERT(!code.is_optimized()); | |
726 ASSERT(frame->LookupDartFunction() == parsed_function().function().raw()); | |
727 | |
728 intptr_t count = num_non_copied_params(); | |
Kevin Millikin (Google)
2014/01/07 14:09:19
I guess there should be a comment here that it's i
Florian Schneider
2014/01/08 10:48:03
Done.
| |
729 RawObject** base = reinterpret_cast<RawObject**>(frame->fp()) | |
730 + kParamEndSlotFromFp // One past the last parameter. | |
731 + count; | |
732 InitializeOsrLocalRange(env, base, count); | |
733 | |
734 count = num_copied_params() + num_stack_locals(); | |
735 base = reinterpret_cast<RawObject**>(frame->fp()) + kFirstLocalSlotFromFp; | |
736 InitializeOsrLocalRange(env, base, count); | |
737 } | |
738 | |
739 | |
698 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, | 740 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, |
699 VariableLivenessAnalysis* variable_liveness, | 741 VariableLivenessAnalysis* variable_liveness, |
700 ZoneGrowableArray<Definition*>* inlining_parameters) { | 742 ZoneGrowableArray<Definition*>* inlining_parameters) { |
701 GraphEntryInstr* entry = graph_entry(); | 743 GraphEntryInstr* entry = graph_entry(); |
702 if (!FLAG_optimize_try_catch && (entry->SuccessorCount() > 1)) { | 744 if (!FLAG_optimize_try_catch && (entry->SuccessorCount() > 1)) { |
703 Bailout("Catch-entry support in SSA."); | 745 Bailout("Catch-entry support in SSA."); |
704 } | 746 } |
705 | 747 |
706 // Initial renaming environment. | 748 // Initial renaming environment. |
707 GrowableArray<Definition*> env(variable_count()); | 749 GrowableArray<Definition*> env(variable_count()); |
708 | 750 |
709 // Add global constants to the initial definitions. | 751 // Add global constants to the initial definitions. |
710 constant_null_ = GetConstant(Object::ZoneHandle()); | 752 constant_null_ = GetConstant(Object::ZoneHandle()); |
711 constant_dead_ = GetConstant(Symbols::OptimizedOut()); | 753 constant_dead_ = GetConstant(Symbols::OptimizedOut()); |
712 | 754 |
713 // Add parameters to the initial definitions and renaming environment. | 755 // Add parameters to the initial definitions and renaming environment. |
714 if (inlining_parameters != NULL) { | 756 if (inlining_parameters != NULL) { |
715 // Use known parameters. | 757 // When inlining, use the known parameter definitions. |
716 ASSERT(parameter_count() == inlining_parameters->length()); | 758 ASSERT(parameter_count() == inlining_parameters->length()); |
717 for (intptr_t i = 0; i < parameter_count(); ++i) { | 759 for (intptr_t i = 0; i < parameter_count(); ++i) { |
718 Definition* defn = (*inlining_parameters)[i]; | 760 Definition* defn = (*inlining_parameters)[i]; |
719 defn->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 761 defn->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
720 AddToInitialDefinitions(defn); | 762 AddToInitialDefinitions(defn); |
721 env.Add(defn); | 763 env.Add(defn); |
722 } | 764 } |
765 } else if (IsCompiledForOsr()) { | |
766 // For functions compiled for OSR, use the constants found in the | |
767 // unoptimized frame. | |
768 InitializeOsrLocals(&env); | |
723 } else { | 769 } else { |
724 // Create new parameters. For functions compiled for OSR, the locals | 770 // Create fresh (unknown) parameters. |
725 // are unknown and so treated like parameters. | 771 for (intptr_t i = 0; i < parameter_count(); ++i) { |
726 intptr_t count = IsCompiledForOsr() ? variable_count() : parameter_count(); | |
727 for (intptr_t i = 0; i < count; ++i) { | |
728 ParameterInstr* param = new ParameterInstr(i, entry); | 772 ParameterInstr* param = new ParameterInstr(i, entry); |
729 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 773 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
730 AddToInitialDefinitions(param); | 774 AddToInitialDefinitions(param); |
731 env.Add(param); | 775 env.Add(param); |
732 } | 776 } |
733 } | 777 } |
734 | 778 |
735 // Initialize all locals with #null in the renaming environment. For OSR, | 779 // Initialize all locals with #null in the renaming environment. For OSR, |
736 // the locals have already been handled as parameters. | 780 // the locals have already been handled as parameters. |
737 if (!IsCompiledForOsr()) { | 781 if (!IsCompiledForOsr()) { |
738 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { | 782 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { |
739 env.Add(constant_null()); | 783 env.Add(constant_null()); |
740 } | 784 } |
741 } | 785 } |
742 | 786 |
743 if (entry->SuccessorCount() > 1) { | |
744 // Functions with try-catch have a fixed area of stack slots reserved | |
745 // so that all local variables are stored at a known location when | |
746 // on entry to the catch. | |
747 entry->set_fixed_slot_count(num_stack_locals() + num_copied_params()); | |
748 } | |
749 RenameRecursive(entry, &env, live_phis, variable_liveness); | 787 RenameRecursive(entry, &env, live_phis, variable_liveness); |
750 } | 788 } |
751 | 789 |
752 | 790 |
753 void FlowGraph::AttachEnvironment(Instruction* instr, | 791 void FlowGraph::AttachEnvironment(Instruction* instr, |
754 GrowableArray<Definition*>* env) { | 792 GrowableArray<Definition*>* env) { |
755 Environment* deopt_env = | 793 Environment* deopt_env = |
756 Environment::From(*env, | 794 Environment::From(*env, |
757 num_non_copied_params_, | 795 num_non_copied_params_, |
758 Code::Handle(parsed_function_.code())); | 796 Code::Handle(parsed_function_.code())); |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1198 } | 1236 } |
1199 | 1237 |
1200 | 1238 |
1201 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1239 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
1202 BlockEntryInstr* to) const { | 1240 BlockEntryInstr* to) const { |
1203 return available_at_[to->postorder_number()]->Contains( | 1241 return available_at_[to->postorder_number()]->Contains( |
1204 from->postorder_number()); | 1242 from->postorder_number()); |
1205 } | 1243 } |
1206 | 1244 |
1207 } // namespace dart | 1245 } // namespace dart |
OLD | NEW |