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 const Object& value = Object::ZoneHandle(base[-i]); |
| 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()); |
| 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 // Initialize parameters and locals in the order they appear in the |
| 729 // environment (left-to-right, parameters first). |
| 730 intptr_t count = num_non_copied_params(); |
| 731 RawObject** base = reinterpret_cast<RawObject**>(frame->fp()) |
| 732 + kParamEndSlotFromFp // One past the last parameter. |
| 733 + count; |
| 734 InitializeOsrLocalRange(env, base, count); |
| 735 |
| 736 count = num_copied_params() + num_stack_locals(); |
| 737 base = reinterpret_cast<RawObject**>(frame->fp()) + kFirstLocalSlotFromFp; |
| 738 InitializeOsrLocalRange(env, base, count); |
| 739 } |
| 740 |
| 741 |
698 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, | 742 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, |
699 VariableLivenessAnalysis* variable_liveness, | 743 VariableLivenessAnalysis* variable_liveness, |
700 ZoneGrowableArray<Definition*>* inlining_parameters) { | 744 ZoneGrowableArray<Definition*>* inlining_parameters) { |
701 GraphEntryInstr* entry = graph_entry(); | 745 GraphEntryInstr* entry = graph_entry(); |
702 if (!FLAG_optimize_try_catch && (entry->SuccessorCount() > 1)) { | 746 if (!FLAG_optimize_try_catch && (entry->SuccessorCount() > 1)) { |
703 Bailout("Catch-entry support in SSA."); | 747 Bailout("Catch-entry support in SSA."); |
704 } | 748 } |
705 | 749 |
706 // Initial renaming environment. | 750 // Initial renaming environment. |
707 GrowableArray<Definition*> env(variable_count()); | 751 GrowableArray<Definition*> env(variable_count()); |
708 | 752 |
709 // Add global constants to the initial definitions. | 753 // Add global constants to the initial definitions. |
710 constant_null_ = GetConstant(Object::ZoneHandle()); | 754 constant_null_ = GetConstant(Object::ZoneHandle()); |
711 constant_dead_ = GetConstant(Symbols::OptimizedOut()); | 755 constant_dead_ = GetConstant(Symbols::OptimizedOut()); |
712 | 756 |
713 // Add parameters to the initial definitions and renaming environment. | 757 // Add parameters to the initial definitions and renaming environment. |
714 if (inlining_parameters != NULL) { | 758 if (inlining_parameters != NULL) { |
715 // Use known parameters. | 759 // When inlining, use the known parameter definitions. |
716 ASSERT(parameter_count() == inlining_parameters->length()); | 760 ASSERT(parameter_count() == inlining_parameters->length()); |
717 for (intptr_t i = 0; i < parameter_count(); ++i) { | 761 for (intptr_t i = 0; i < parameter_count(); ++i) { |
718 Definition* defn = (*inlining_parameters)[i]; | 762 Definition* defn = (*inlining_parameters)[i]; |
719 defn->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 763 defn->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
720 AddToInitialDefinitions(defn); | 764 AddToInitialDefinitions(defn); |
721 env.Add(defn); | 765 env.Add(defn); |
722 } | 766 } |
| 767 } else if (IsCompiledForOsr()) { |
| 768 // For functions compiled for OSR, use the constants found in the |
| 769 // unoptimized frame. |
| 770 InitializeOsrLocals(&env); |
723 } else { | 771 } else { |
724 // Create new parameters. For functions compiled for OSR, the locals | 772 // Create fresh (unknown) parameters. |
725 // are unknown and so treated like parameters. | 773 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); | 774 ParameterInstr* param = new ParameterInstr(i, entry); |
729 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 775 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
730 AddToInitialDefinitions(param); | 776 AddToInitialDefinitions(param); |
731 env.Add(param); | 777 env.Add(param); |
732 } | 778 } |
733 } | 779 } |
734 | 780 |
735 // Initialize all locals with #null in the renaming environment. For OSR, | 781 // Initialize all locals with #null in the renaming environment. For OSR, |
736 // the locals have already been handled as parameters. | 782 // the locals have already been handled as parameters. |
737 if (!IsCompiledForOsr()) { | 783 if (!IsCompiledForOsr()) { |
738 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { | 784 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { |
739 env.Add(constant_null()); | 785 env.Add(constant_null()); |
740 } | 786 } |
741 } | 787 } |
742 | 788 |
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); | 789 RenameRecursive(entry, &env, live_phis, variable_liveness); |
750 } | 790 } |
751 | 791 |
752 | 792 |
753 void FlowGraph::AttachEnvironment(Instruction* instr, | 793 void FlowGraph::AttachEnvironment(Instruction* instr, |
754 GrowableArray<Definition*>* env) { | 794 GrowableArray<Definition*>* env) { |
755 Environment* deopt_env = | 795 Environment* deopt_env = |
756 Environment::From(*env, | 796 Environment::From(*env, |
757 num_non_copied_params_, | 797 num_non_copied_params_, |
758 Code::Handle(parsed_function_.code())); | 798 Code::Handle(parsed_function_.code())); |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 } | 1238 } |
1199 | 1239 |
1200 | 1240 |
1201 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1241 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
1202 BlockEntryInstr* to) const { | 1242 BlockEntryInstr* to) const { |
1203 return available_at_[to->postorder_number()]->Contains( | 1243 return available_at_[to->postorder_number()]->Contains( |
1204 from->postorder_number()); | 1244 from->postorder_number()); |
1205 } | 1245 } |
1206 | 1246 |
1207 } // namespace dart | 1247 } // namespace dart |
OLD | NEW |