| 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/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 max_block_id_(max_block_id), | 29 max_block_id_(max_block_id), |
| 30 parsed_function_(builder.parsed_function()), | 30 parsed_function_(builder.parsed_function()), |
| 31 num_copied_params_(builder.num_copied_params()), | 31 num_copied_params_(builder.num_copied_params()), |
| 32 num_non_copied_params_(builder.num_non_copied_params()), | 32 num_non_copied_params_(builder.num_non_copied_params()), |
| 33 num_stack_locals_(builder.num_stack_locals()), | 33 num_stack_locals_(builder.num_stack_locals()), |
| 34 graph_entry_(graph_entry), | 34 graph_entry_(graph_entry), |
| 35 preorder_(), | 35 preorder_(), |
| 36 postorder_(), | 36 postorder_(), |
| 37 reverse_postorder_(), | 37 reverse_postorder_(), |
| 38 block_effects_(NULL), | 38 block_effects_(NULL), |
| 39 licm_allowed_(true) { | 39 licm_allowed_(true), |
| 40 loop_headers_(NULL), |
| 41 loop_invariant_loads_(NULL) { |
| 40 DiscoverBlocks(); | 42 DiscoverBlocks(); |
| 41 } | 43 } |
| 42 | 44 |
| 43 | 45 |
| 44 ConstantInstr* FlowGraph::GetConstant(const Object& object) { | 46 ConstantInstr* FlowGraph::GetConstant(const Object& object) { |
| 45 // Check if the constant is already in the pool. | 47 // Check if the constant is already in the pool. |
| 46 GrowableArray<Definition*>* pool = graph_entry_->initial_definitions(); | 48 GrowableArray<Definition*>* pool = graph_entry_->initial_definitions(); |
| 47 for (intptr_t i = 0; i < pool->length(); ++i) { | 49 for (intptr_t i = 0; i < pool->length(); ++i) { |
| 48 ConstantInstr* constant = (*pool)[i]->AsConstant(); | 50 ConstantInstr* constant = (*pool)[i]->AsConstant(); |
| 49 if ((constant != NULL) && (constant->value().raw() == object.raw())) { | 51 if ((constant != NULL) && (constant->value().raw() == object.raw())) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 variable_count(), | 105 variable_count(), |
| 104 num_non_copied_params()); | 106 num_non_copied_params()); |
| 105 // Create an array of blocks in reverse postorder. | 107 // Create an array of blocks in reverse postorder. |
| 106 intptr_t block_count = postorder_.length(); | 108 intptr_t block_count = postorder_.length(); |
| 107 for (intptr_t i = 0; i < block_count; ++i) { | 109 for (intptr_t i = 0; i < block_count; ++i) { |
| 108 reverse_postorder_.Add(postorder_[block_count - i - 1]); | 110 reverse_postorder_.Add(postorder_[block_count - i - 1]); |
| 109 } | 111 } |
| 110 | 112 |
| 111 // Block effects are using postorder numbering. Discard computed information. | 113 // Block effects are using postorder numbering. Discard computed information. |
| 112 block_effects_ = NULL; | 114 block_effects_ = NULL; |
| 115 loop_headers_ = NULL; |
| 116 loop_invariant_loads_ = NULL; |
| 113 } | 117 } |
| 114 | 118 |
| 115 | 119 |
| 116 #ifdef DEBUG | 120 #ifdef DEBUG |
| 117 // Debugging code to verify the construction of use lists. | 121 // Debugging code to verify the construction of use lists. |
| 118 | 122 |
| 119 static intptr_t MembershipCount(Value* use, Value* list) { | 123 static intptr_t MembershipCount(Value* use, Value* list) { |
| 120 intptr_t count = 0; | 124 intptr_t count = 0; |
| 121 while (list != NULL) { | 125 while (list != NULL) { |
| 122 if (list == use) ++count; | 126 if (list == use) ++count; |
| (...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 } | 954 } |
| 951 n->set_loop_info(loop); | 955 n->set_loop_info(loop); |
| 952 if (FLAG_trace_optimization) { | 956 if (FLAG_trace_optimization) { |
| 953 for (BitVector::Iterator it(loop); !it.Done(); it.Advance()) { | 957 for (BitVector::Iterator it(loop); !it.Done(); it.Advance()) { |
| 954 OS::Print(" B%"Pd"\n", it.Current()); | 958 OS::Print(" B%"Pd"\n", it.Current()); |
| 955 } | 959 } |
| 956 } | 960 } |
| 957 } | 961 } |
| 958 | 962 |
| 959 | 963 |
| 960 void FlowGraph::ComputeLoops(GrowableArray<BlockEntryInstr*>* loop_headers) { | 964 ZoneGrowableArray<BlockEntryInstr*>* FlowGraph::ComputeLoops() { |
| 961 ASSERT(loop_headers->is_empty()); | 965 ZoneGrowableArray<BlockEntryInstr*>* loop_headers = |
| 966 new ZoneGrowableArray<BlockEntryInstr*>(); |
| 967 |
| 962 for (BlockIterator it = postorder_iterator(); | 968 for (BlockIterator it = postorder_iterator(); |
| 963 !it.Done(); | 969 !it.Done(); |
| 964 it.Advance()) { | 970 it.Advance()) { |
| 965 BlockEntryInstr* block = it.Current(); | 971 BlockEntryInstr* block = it.Current(); |
| 966 for (intptr_t i = 0; i < block->PredecessorCount(); ++i) { | 972 for (intptr_t i = 0; i < block->PredecessorCount(); ++i) { |
| 967 BlockEntryInstr* pred = block->PredecessorAt(i); | 973 BlockEntryInstr* pred = block->PredecessorAt(i); |
| 968 if (block->Dominates(pred)) { | 974 if (block->Dominates(pred)) { |
| 969 if (FLAG_trace_optimization) { | 975 if (FLAG_trace_optimization) { |
| 970 OS::Print("Back edge B%"Pd" -> B%"Pd"\n", pred->block_id(), | 976 OS::Print("Back edge B%"Pd" -> B%"Pd"\n", pred->block_id(), |
| 971 block->block_id()); | 977 block->block_id()); |
| 972 } | 978 } |
| 973 FindLoop(pred, block, preorder_.length()); | 979 FindLoop(pred, block, preorder_.length()); |
| 974 loop_headers->Add(block); | 980 loop_headers->Add(block); |
| 975 } | 981 } |
| 976 } | 982 } |
| 977 } | 983 } |
| 984 |
| 985 return loop_headers; |
| 978 } | 986 } |
| 979 | 987 |
| 980 | 988 |
| 981 void FlowGraph::Bailout(const char* reason) const { | 989 void FlowGraph::Bailout(const char* reason) const { |
| 982 const char* kFormat = "FlowGraph Bailout: %s %s"; | 990 const char* kFormat = "FlowGraph Bailout: %s %s"; |
| 983 const char* function_name = parsed_function_.function().ToCString(); | 991 const char* function_name = parsed_function_.function().ToCString(); |
| 984 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 992 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 985 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 993 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 986 OS::SNPrint(chars, len, kFormat, function_name, reason); | 994 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 987 const Error& error = Error::Handle( | 995 const Error& error = Error::Handle( |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 } | 1115 } |
| 1108 | 1116 |
| 1109 | 1117 |
| 1110 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1118 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1111 BlockEntryInstr* to) const { | 1119 BlockEntryInstr* to) const { |
| 1112 return available_at_[to->postorder_number()]->Contains( | 1120 return available_at_[to->postorder_number()]->Contains( |
| 1113 from->postorder_number()); | 1121 from->postorder_number()); |
| 1114 } | 1122 } |
| 1115 | 1123 |
| 1116 } // namespace dart | 1124 } // namespace dart |
| OLD | NEW |