Chromium Code Reviews| Index: runtime/vm/flow_graph_inliner.cc |
| diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc |
| index dff260d538c8b0ecc7e38350391225c6b75fc85b..7733426155305ef3697ac6958670de4335d3bdf7 100644 |
| --- a/runtime/vm/flow_graph_inliner.cc |
| +++ b/runtime/vm/flow_graph_inliner.cc |
| @@ -4,9 +4,12 @@ |
| #include "vm/flow_graph_inliner.h" |
| +#include "vm/compiler.h" |
| #include "vm/flags.h" |
| #include "vm/flow_graph.h" |
| #include "vm/flow_graph_builder.h" |
| +#include "vm/flow_graph_optimizer.h" |
| +#include "vm/intrinsifier.h" |
|
Kevin Millikin (Google)
2012/09/18 11:01:55
I think we try to keep these sorted according to M
zerny-google
2012/09/18 11:53:07
Thanks again.
|
| #include "vm/il_printer.h" |
| #include "vm/longjump.h" |
| #include "vm/object.h" |
| @@ -17,6 +20,7 @@ namespace dart { |
| DEFINE_FLAG(bool, trace_inlining, false, "Trace inlining"); |
| DEFINE_FLAG(charp, inlining_filter, NULL, "Inline only in named function"); |
| DECLARE_FLAG(bool, print_flow_graph); |
| +DECLARE_FLAG(bool, deoptimization_counter_threshold); |
| #define TRACE_INLINING(statement) \ |
| do { \ |
| @@ -46,10 +50,19 @@ class CallSiteInliner : public FlowGraphVisitor { |
| // Assuming no optional parameters the actual/formal count should match. |
| ASSERT(arguments->length() == function.num_fixed_parameters()); |
| + // Abort if the callee has an intrinsic translation. |
| + if (Intrinsifier::CanIntrinsify(function)) { |
| + TRACE_INLINING(OS::Print(" Bailout: can intrinsify\n")); |
| + return false; |
| + } |
| + |
| Isolate* isolate = Isolate::Current(); |
| // Save and clear IC data. |
| const Array& old_ic_data = Array::Handle(isolate->ic_data_array()); |
| isolate->set_ic_data_array(Array::null()); |
| + // Save and clear deopt id. |
| + const intptr_t prev_deopt_id = isolate->deopt_id(); |
|
Kevin Millikin (Google)
2012/09/18 11:01:55
It distracts me that we have old_ic_data and prev_
zerny-google
2012/09/18 11:53:07
Done.
|
| + isolate->set_deopt_id(0); |
| // Install bailout jump. |
| LongJump* base = isolate->long_jump_base(); |
| LongJump jump; |
| @@ -59,9 +72,19 @@ class CallSiteInliner : public FlowGraphVisitor { |
| ParsedFunction parsed_function(function); |
| Parser::ParseFunction(&parsed_function); |
| parsed_function.AllocateVariables(); |
| - FlowGraphBuilder builder(parsed_function); |
| + |
| + // Load IC data for the callee. |
| + if ((function.deoptimization_counter() < |
| + FLAG_deoptimization_counter_threshold) && |
| + function.HasCode()) { |
| + const Code& unoptimized_code = |
| + Code::Handle(function.unoptimized_code()); |
| + isolate->set_ic_data_array( |
| + Compiler::ExtractTypeFeedbackArray(unoptimized_code)); |
| + } |
| // Build the callee graph. |
| + FlowGraphBuilder builder(parsed_function); |
| FlowGraph* callee_graph = |
| builder.BuildGraph(FlowGraphBuilder::kValueContext); |
| @@ -73,27 +96,22 @@ class CallSiteInliner : public FlowGraphVisitor { |
| return false; |
| } |
| - if (FLAG_trace_inlining && FLAG_print_flow_graph) { |
| - OS::Print("Callee graph before SSA %s\n", |
| - parsed_function.function().ToFullyQualifiedCString()); |
| - FlowGraphPrinter printer(*callee_graph); |
| - printer.PrintBlocks(); |
| - } |
| - |
| // Compute SSA on the callee graph. (catching bailouts) |
|
Kevin Millikin (Google)
2012/09/18 11:01:55
Format as a complete sentence: "Compute SSA on the
zerny-google
2012/09/18 11:53:07
Done.
|
| callee_graph->ComputeSSA(next_ssa_temp_index_); |
| + callee_graph->ComputeUseLists(); |
| + |
| + // TODO(zerny): Do optimization passes on the callee graph. |
|
Kevin Millikin (Google)
2012/09/18 11:01:55
"Do more optimization...."
zerny-google
2012/09/18 11:53:07
Done.
|
| + FlowGraphOptimizer optimizer(callee_graph); |
| + optimizer.ApplyICData(); |
| + callee_graph->ComputeUseLists(); |
| if (FLAG_trace_inlining && FLAG_print_flow_graph) { |
| - OS::Print("Callee graph after SSA %s\n", |
| + OS::Print("Callee graph for inlining %s\n", |
| parsed_function.function().ToFullyQualifiedCString()); |
| FlowGraphPrinter printer(*callee_graph); |
| printer.PrintBlocks(); |
| } |
| - callee_graph->ComputeUseLists(); |
| - |
| - // TODO(zerny): Do optimization passes on the callee graph. |
| - |
| // TODO(zerny): If result is more than size threshold then abort. |
| // TODO(zerny): If effort is less than threshold then inline recursively. |
| @@ -102,14 +120,17 @@ class CallSiteInliner : public FlowGraphVisitor { |
| caller_graph_->InlineCall(call, callee_graph); |
| next_ssa_temp_index_ = caller_graph_->max_virtual_register_number(); |
| - // Remove (all) push arguments of the call. |
| + // Check that inlining maintains use lists. |
| + DEBUG_ASSERT(caller_graph_->ValidateUseLists()); |
| + |
| + // Remove push arguments of the call. |
| for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| PushArgumentInstr* push = call->ArgumentAt(i); |
| push->ReplaceUsesWith(push->value()->definition()); |
| push->RemoveFromGraph(); |
| } |
| - // Replace all the formal parameters with the actuals. |
| + // Replace formal parameters with actuals. |
| for (intptr_t i = 0; i < arguments->length(); ++i) { |
| Value* val = callee_graph->graph_entry()->start_env()->ValueAt(i); |
| ParameterInstr* param = val->definition()->AsParameter(); |
| @@ -126,6 +147,7 @@ class CallSiteInliner : public FlowGraphVisitor { |
| // Build succeeded so we restore the bailout jump. |
| inlined_ = true; |
| isolate->set_long_jump_base(base); |
| + isolate->set_deopt_id(prev_deopt_id); |
| isolate->set_ic_data_array(old_ic_data.raw()); |
| return true; |
| } else { |
| @@ -133,6 +155,7 @@ class CallSiteInliner : public FlowGraphVisitor { |
| error = isolate->object_store()->sticky_error(); |
| isolate->object_store()->clear_sticky_error(); |
| isolate->set_long_jump_base(base); |
| + isolate->set_deopt_id(prev_deopt_id); |
| isolate->set_ic_data_array(old_ic_data.raw()); |
| TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString())); |
| return false; |
| @@ -199,6 +222,10 @@ void FlowGraphInliner::Inline() { |
| return; |
| } |
| + TRACE_INLINING(OS::Print( |
| + "Inlining calls in %s\n", |
| + flow_graph_->parsed_function().function().ToCString())); |
| + |
| if (FLAG_trace_inlining && FLAG_print_flow_graph) { |
| OS::Print("Before Inlining of %s\n", flow_graph_-> |
| parsed_function().function().ToFullyQualifiedCString()); |
| @@ -206,9 +233,6 @@ void FlowGraphInliner::Inline() { |
| printer.PrintBlocks(); |
| } |
| - TRACE_INLINING(OS::Print( |
| - "Inlining calls in %s\n", |
| - flow_graph_->parsed_function().function().ToCString())); |
| CallSiteInliner inliner(flow_graph_); |
| inliner.VisitBlocks(); |