| 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_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
| 6 | 6 |
| 7 #include "vm/assert.h" | 7 #include "vm/assert.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/flow_graph.h" | 10 #include "vm/flow_graph.h" |
| 11 #include "vm/flow_graph_builder.h" | 11 #include "vm/flow_graph_builder.h" |
| 12 #include "vm/flow_graph_optimizer.h" | 12 #include "vm/flow_graph_optimizer.h" |
| 13 #include "vm/il_printer.h" | 13 #include "vm/il_printer.h" |
| 14 #include "vm/intrinsifier.h" | 14 #include "vm/intrinsifier.h" |
| 15 #include "vm/longjump.h" | 15 #include "vm/longjump.h" |
| 16 #include "vm/object.h" | 16 #include "vm/object.h" |
| 17 #include "vm/object_store.h" | 17 #include "vm/object_store.h" |
| 18 | 18 |
| 19 namespace dart { | 19 namespace dart { |
| 20 | 20 |
| 21 DEFINE_FLAG(bool, trace_inlining, false, "Trace inlining"); | 21 DEFINE_FLAG(bool, trace_inlining, false, "Trace inlining"); |
| 22 DEFINE_FLAG(charp, inlining_filter, NULL, "Inline only in named function"); | 22 DEFINE_FLAG(charp, inlining_filter, NULL, "Inline only in named function"); |
| 23 DEFINE_FLAG(int, inlining_size_threshold, 250, | 23 DEFINE_FLAG(int, inlining_size_threshold, 250, |
| 24 "Inline only functions with up to threshold instructions"); | 24 "Inline only functions with up to threshold instructions"); |
| 25 DEFINE_FLAG(int, inlining_growth_factor, 3, | |
| 26 "Stop inlining when a function grows by the factor"); | |
| 27 DEFINE_FLAG(bool, inline_control_flow, true, | 25 DEFINE_FLAG(bool, inline_control_flow, true, |
| 28 "Inline functions with control flow."); | 26 "Inline functions with control flow."); |
| 29 DECLARE_FLAG(bool, print_flow_graph); | 27 DECLARE_FLAG(bool, print_flow_graph); |
| 30 DECLARE_FLAG(int, deoptimization_counter_threshold); | 28 DECLARE_FLAG(int, deoptimization_counter_threshold); |
| 31 | 29 |
| 32 #define TRACE_INLINING(statement) \ | 30 #define TRACE_INLINING(statement) \ |
| 33 do { \ | 31 do { \ |
| 34 if (FLAG_trace_inlining) statement; \ | 32 if (FLAG_trace_inlining) statement; \ |
| 35 } while (false) | 33 } while (false) |
| 36 | 34 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 intptr_t size = callee_graph->InstructionCount(); | 184 intptr_t size = callee_graph->InstructionCount(); |
| 187 if (size > FLAG_inlining_size_threshold) { | 185 if (size > FLAG_inlining_size_threshold) { |
| 188 function.set_is_inlinable(false); | 186 function.set_is_inlinable(false); |
| 189 isolate->set_long_jump_base(base); | 187 isolate->set_long_jump_base(base); |
| 190 isolate->set_deopt_id(prev_deopt_id); | 188 isolate->set_deopt_id(prev_deopt_id); |
| 191 isolate->set_ic_data_array(prev_ic_data.raw()); | 189 isolate->set_ic_data_array(prev_ic_data.raw()); |
| 192 TRACE_INLINING(OS::Print(" Bailout: graph size %"Pd"\n", size)); | 190 TRACE_INLINING(OS::Print(" Bailout: graph size %"Pd"\n", size)); |
| 193 return false; | 191 return false; |
| 194 } | 192 } |
| 195 | 193 |
| 196 // If the growth factor is more than threshold abort. | |
| 197 double growth = | |
| 198 static_cast<double>(inlined_size_ + size) / | |
| 199 static_cast<double>(initial_size_); | |
| 200 if (growth > static_cast<double>(FLAG_inlining_growth_factor)) { | |
| 201 function.set_is_inlinable(false); | |
| 202 isolate->set_long_jump_base(base); | |
| 203 isolate->set_deopt_id(prev_deopt_id); | |
| 204 isolate->set_ic_data_array(prev_ic_data.raw()); | |
| 205 TRACE_INLINING(OS::Print(" Bailout: growth factor %f\n", | |
| 206 growth)); | |
| 207 return false; | |
| 208 } | |
| 209 | |
| 210 // TODO(zerny): If effort is less than threshold then inline recursively. | 194 // TODO(zerny): If effort is less than threshold then inline recursively. |
| 211 | 195 |
| 212 // Plug result in the caller graph. | 196 // Plug result in the caller graph. |
| 213 caller_graph_->InlineCall(call, callee_graph); | 197 caller_graph_->InlineCall(call, callee_graph); |
| 214 next_ssa_temp_index_ = caller_graph_->max_virtual_register_number(); | 198 next_ssa_temp_index_ = caller_graph_->max_virtual_register_number(); |
| 215 | 199 |
| 216 // Remove push arguments of the call. | 200 // Remove push arguments of the call. |
| 217 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 201 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 218 PushArgumentInstr* push = call->ArgumentAt(i); | 202 PushArgumentInstr* push = call->ArgumentAt(i); |
| 219 push->ReplaceUsesWith(push->value()->definition()); | 203 push->ReplaceUsesWith(push->value()->definition()); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 OS::Print("After Inlining of %s\n", flow_graph_-> | 341 OS::Print("After Inlining of %s\n", flow_graph_-> |
| 358 parsed_function().function().ToFullyQualifiedCString()); | 342 parsed_function().function().ToFullyQualifiedCString()); |
| 359 FlowGraphPrinter printer(*flow_graph_); | 343 FlowGraphPrinter printer(*flow_graph_); |
| 360 printer.PrintBlocks(); | 344 printer.PrintBlocks(); |
| 361 } | 345 } |
| 362 } | 346 } |
| 363 } | 347 } |
| 364 } | 348 } |
| 365 | 349 |
| 366 } // namespace dart | 350 } // namespace dart |
| OLD | NEW |