| 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/growable_array.h" | 10 #include "vm/growable_array.h" |
| 11 #include "vm/report.h" | 11 #include "vm/report.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 DECLARE_FLAG(bool, reorder_basic_blocks); | 15 DECLARE_FLAG(bool, reorder_basic_blocks); |
| 16 DECLARE_FLAG(bool, trace_optimization); | 16 DECLARE_FLAG(bool, trace_optimization); |
| 17 DECLARE_FLAG(bool, verify_compiler); | 17 DECLARE_FLAG(bool, verify_compiler); |
| 18 DEFINE_FLAG(bool, optimize_try_catch, true, "Optimization of try-catch"); | |
| 19 | 18 |
| 20 | 19 |
| 21 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, | 20 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, |
| 22 GraphEntryInstr* graph_entry, | 21 GraphEntryInstr* graph_entry, |
| 23 intptr_t max_block_id) | 22 intptr_t max_block_id) |
| 24 : isolate_(Isolate::Current()), | 23 : isolate_(Isolate::Current()), |
| 25 parent_(), | 24 parent_(), |
| 26 current_ssa_temp_index_(0), | 25 current_ssa_temp_index_(0), |
| 27 max_block_id_(max_block_id), | 26 max_block_id_(max_block_id), |
| 28 builder_(builder), | 27 builder_(builder), |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 reverse_postorder_.Add(postorder_[block_count - i - 1]); | 173 reverse_postorder_.Add(postorder_[block_count - i - 1]); |
| 175 } | 174 } |
| 176 | 175 |
| 177 // Block effects are using postorder numbering. Discard computed information. | 176 // Block effects are using postorder numbering. Discard computed information. |
| 178 block_effects_ = NULL; | 177 block_effects_ = NULL; |
| 179 loop_headers_ = NULL; | 178 loop_headers_ = NULL; |
| 180 loop_invariant_loads_ = NULL; | 179 loop_invariant_loads_ = NULL; |
| 181 } | 180 } |
| 182 | 181 |
| 183 | 182 |
| 184 #ifdef DEBUG | |
| 185 // Debugging code to verify the construction of use lists. | 183 // Debugging code to verify the construction of use lists. |
| 186 | |
| 187 static intptr_t MembershipCount(Value* use, Value* list) { | 184 static intptr_t MembershipCount(Value* use, Value* list) { |
| 188 intptr_t count = 0; | 185 intptr_t count = 0; |
| 189 while (list != NULL) { | 186 while (list != NULL) { |
| 190 if (list == use) ++count; | 187 if (list == use) ++count; |
| 191 list = list->next_use(); | 188 list = list->next_use(); |
| 192 } | 189 } |
| 193 return count; | 190 return count; |
| 194 } | 191 } |
| 195 | 192 |
| 196 | 193 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 ASSERT(phi != NULL); | 271 ASSERT(phi != NULL); |
| 275 VerifyUseListsInInstruction(phi); | 272 VerifyUseListsInInstruction(phi); |
| 276 } | 273 } |
| 277 } | 274 } |
| 278 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 275 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 279 VerifyUseListsInInstruction(it.Current()); | 276 VerifyUseListsInInstruction(it.Current()); |
| 280 } | 277 } |
| 281 } | 278 } |
| 282 return true; // Return true so we can ASSERT validation. | 279 return true; // Return true so we can ASSERT validation. |
| 283 } | 280 } |
| 284 #endif // DEBUG | |
| 285 | 281 |
| 286 | 282 |
| 287 LivenessAnalysis::LivenessAnalysis( | 283 LivenessAnalysis::LivenessAnalysis( |
| 288 intptr_t variable_count, | 284 intptr_t variable_count, |
| 289 const GrowableArray<BlockEntryInstr*>& postorder) | 285 const GrowableArray<BlockEntryInstr*>& postorder) |
| 290 : isolate_(Isolate::Current()), | 286 : isolate_(Isolate::Current()), |
| 291 variable_count_(variable_count), | 287 variable_count_(variable_count), |
| 292 postorder_(postorder), | 288 postorder_(postorder), |
| 293 live_out_(postorder.length()), | 289 live_out_(postorder.length()), |
| 294 kill_(postorder.length()), | 290 kill_(postorder.length()), |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 } | 707 } |
| 712 } | 708 } |
| 713 } | 709 } |
| 714 } | 710 } |
| 715 | 711 |
| 716 | 712 |
| 717 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, | 713 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, |
| 718 VariableLivenessAnalysis* variable_liveness, | 714 VariableLivenessAnalysis* variable_liveness, |
| 719 ZoneGrowableArray<Definition*>* inlining_parameters) { | 715 ZoneGrowableArray<Definition*>* inlining_parameters) { |
| 720 GraphEntryInstr* entry = graph_entry(); | 716 GraphEntryInstr* entry = graph_entry(); |
| 721 if (!FLAG_optimize_try_catch && (entry->SuccessorCount() > 1)) { | |
| 722 Bailout("Catch-entry support in SSA."); | |
| 723 } | |
| 724 | 717 |
| 725 // Initial renaming environment. | 718 // Initial renaming environment. |
| 726 GrowableArray<Definition*> env(variable_count()); | 719 GrowableArray<Definition*> env(variable_count()); |
| 727 | 720 |
| 728 // Add global constants to the initial definitions. | 721 // Add global constants to the initial definitions. |
| 729 constant_null_ = GetConstant(Object::ZoneHandle()); | 722 constant_null_ = GetConstant(Object::ZoneHandle()); |
| 730 constant_dead_ = GetConstant(Symbols::OptimizedOut()); | 723 constant_dead_ = GetConstant(Symbols::OptimizedOut()); |
| 731 | 724 |
| 732 // Add parameters to the initial definitions and renaming environment. | 725 // Add parameters to the initial definitions and renaming environment. |
| 733 if (inlining_parameters != NULL) { | 726 if (inlining_parameters != NULL) { |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 !it.Done(); | 1131 !it.Done(); |
| 1139 it.Advance()) { | 1132 it.Advance()) { |
| 1140 OS::Print(" B%" Pd "\n", preorder_[it.Current()]->block_id()); | 1133 OS::Print(" B%" Pd "\n", preorder_[it.Current()]->block_id()); |
| 1141 } | 1134 } |
| 1142 } | 1135 } |
| 1143 } | 1136 } |
| 1144 return loop_headers; | 1137 return loop_headers; |
| 1145 } | 1138 } |
| 1146 | 1139 |
| 1147 | 1140 |
| 1148 void FlowGraph::Bailout(const char* reason) const { | |
| 1149 const Function& function = parsed_function_.function(); | |
| 1150 Report::MessageF(Report::kBailout, | |
| 1151 Script::Handle(function.script()), | |
| 1152 function.token_pos(), | |
| 1153 "FlowGraph Bailout: %s %s", | |
| 1154 String::Handle(function.name()).ToCString(), | |
| 1155 reason); | |
| 1156 UNREACHABLE(); | |
| 1157 } | |
| 1158 | |
| 1159 | |
| 1160 intptr_t FlowGraph::InstructionCount() const { | 1141 intptr_t FlowGraph::InstructionCount() const { |
| 1161 intptr_t size = 0; | 1142 intptr_t size = 0; |
| 1162 // Iterate each block, skipping the graph entry. | 1143 // Iterate each block, skipping the graph entry. |
| 1163 for (intptr_t i = 1; i < preorder_.length(); ++i) { | 1144 for (intptr_t i = 1; i < preorder_.length(); ++i) { |
| 1164 for (ForwardInstructionIterator it(preorder_[i]); | 1145 for (ForwardInstructionIterator it(preorder_[i]); |
| 1165 !it.Done(); | 1146 !it.Done(); |
| 1166 it.Advance()) { | 1147 it.Advance()) { |
| 1167 ++size; | 1148 ++size; |
| 1168 } | 1149 } |
| 1169 } | 1150 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 } | 1257 } |
| 1277 | 1258 |
| 1278 | 1259 |
| 1279 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1260 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1280 BlockEntryInstr* to) const { | 1261 BlockEntryInstr* to) const { |
| 1281 return available_at_[to->postorder_number()]->Contains( | 1262 return available_at_[to->postorder_number()]->Contains( |
| 1282 from->postorder_number()); | 1263 from->postorder_number()); |
| 1283 } | 1264 } |
| 1284 | 1265 |
| 1285 } // namespace dart | 1266 } // namespace dart |
| OLD | NEW |