Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1247)

Unified Diff: runtime/vm/flow_graph_inliner.cc

Issue 10967007: Inlining functions with control flow. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_inliner.cc
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index c60ee6d788403975ea86a1d4619d8604e09abac1..b38347f762d2a7ce80ccbb2ad5ed4be4e2ba1708 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -34,8 +34,36 @@ class CallSiteInliner : public FlowGraphVisitor {
: FlowGraphVisitor(flow_graph->postorder()),
caller_graph_(flow_graph),
next_ssa_temp_index_(flow_graph->max_virtual_register_number()),
- inlined_(false) { }
+ inlined_(false),
+ static_calls_(),
+ closure_calls_(),
+ instance_calls_() { }
+ void VisitClosureCall(ClosureCallInstr* call) {
+ closure_calls_.Add(call);
+ }
+
+ void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr* call) {
+ instance_calls_.Add(call);
+ }
+
+ void VisitStaticCall(StaticCallInstr* call) {
+ static_calls_.Add(call);
+ }
+
+ void FindCallSites() {
+ VisitBlocks();
+ }
+
+ void InlineCalls() {
+ InlineStaticCalls();
+ InlineClosureCalls();
+ InlineInstanceCalls();
+ }
+
+ bool inlined() const { return inlined_; }
+
+ private:
bool TryInlining(const Function& function,
GrowableArray<Value*>* arguments,
Definition* call) {
@@ -84,17 +112,10 @@ class CallSiteInliner : public FlowGraphVisitor {
// Build the callee graph.
FlowGraphBuilder builder(parsed_function);
+ builder.SetInitialBlockId(caller_graph_->max_block_id());
FlowGraph* callee_graph =
builder.BuildGraph(FlowGraphBuilder::kValueContext);
- // Abort if the callee graph contains control flow.
- if (callee_graph->preorder().length() != 2) {
- isolate->set_long_jump_base(base);
- isolate->set_ic_data_array(prev_ic_data.raw());
- TRACE_INLINING(OS::Print(" Bailout: control flow\n"));
- return false;
- }
-
// Compute SSA on the callee graph, catching bailouts.
callee_graph->ComputeSSA(next_ssa_temp_index_);
callee_graph->ComputeUseLists();
@@ -119,9 +140,6 @@ class CallSiteInliner : public FlowGraphVisitor {
caller_graph_->InlineCall(call, callee_graph);
next_ssa_temp_index_ = caller_graph_->max_virtual_register_number();
- // 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);
@@ -147,6 +165,9 @@ class CallSiteInliner : public FlowGraphVisitor {
TRACE_INLINING(OS::Print(" Success\n"));
+ // Check that inlining maintains use lists.
+ DEBUG_ASSERT(caller_graph_->ValidateUseLists());
+
// Build succeeded so we restore the bailout jump.
inlined_ = true;
isolate->set_long_jump_base(base);
@@ -165,55 +186,66 @@ class CallSiteInliner : public FlowGraphVisitor {
}
}
- void VisitClosureCall(ClosureCallInstr* call) {
- TRACE_INLINING(OS::Print(" ClosureCall\n"));
- // Find the closure of the callee.
- ASSERT(call->ArgumentCount() > 0);
- const CreateClosureInstr* closure =
- call->ArgumentAt(0)->value()->definition()->AsCreateClosure();
- if (closure == NULL) {
- TRACE_INLINING(OS::Print(" Bailout: non-closure operator\n"));
- return;
- }
- GrowableArray<Value*> arguments(call->ArgumentCount() - 1);
- for (int i = 1; i < call->ArgumentCount(); ++i) {
- arguments.Add(call->ArgumentAt(i)->value());
+ void InlineStaticCalls() {
+ TRACE_INLINING(OS::Print(" Static Calls (%d)\n",
+ static_calls_.length()));
+ for (intptr_t i = 0; i < static_calls_.length(); ++i) {
+ StaticCallInstr* call = static_calls_[i];
+ GrowableArray<Value*> arguments(call->ArgumentCount());
+ for (int i = 0; i < call->ArgumentCount(); ++i) {
+ arguments.Add(call->ArgumentAt(i)->value());
+ }
+ TryInlining(call->function(), &arguments, call);
}
- TryInlining(closure->function(), &arguments, call);
}
- void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr* instr) {
- TRACE_INLINING(OS::Print(" PolymorphicInstanceCall\n"));
- if (instr->with_checks()) {
- TRACE_INLINING(OS::Print(" Bailout: checks\n"));
- return;
- }
- const ICData& ic_data = instr->ic_data();
- const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
-
- GrowableArray<Value*> arguments(instr->ArgumentCount());
- for (int i = 0; i < instr->ArgumentCount(); ++i) {
- arguments.Add(instr->ArgumentAt(i)->value());
+ void InlineClosureCalls() {
+ TRACE_INLINING(OS::Print(" Closure Calls (%d)\n",
+ closure_calls_.length()));
+ for (intptr_t i = 0; i < closure_calls_.length(); ++i) {
+ ClosureCallInstr* call = closure_calls_[i];
+ // Find the closure of the callee.
+ ASSERT(call->ArgumentCount() > 0);
+ const CreateClosureInstr* closure =
+ call->ArgumentAt(0)->value()->definition()->AsCreateClosure();
+ if (closure == NULL) {
+ TRACE_INLINING(OS::Print(" Bailout: non-closure operator\n"));
+ return;
+ }
+ GrowableArray<Value*> arguments(call->ArgumentCount() - 1);
+ for (int i = 1; i < call->ArgumentCount(); ++i) {
+ arguments.Add(call->ArgumentAt(i)->value());
+ }
+ TryInlining(closure->function(), &arguments, call);
}
-
- TryInlining(target, &arguments, instr);
}
- void VisitStaticCall(StaticCallInstr* call) {
- TRACE_INLINING(OS::Print(" StaticCall\n"));
- GrowableArray<Value*> arguments(call->ArgumentCount());
- for (int i = 0; i < call->ArgumentCount(); ++i) {
- arguments.Add(call->ArgumentAt(i)->value());
+ void InlineInstanceCalls() {
+ TRACE_INLINING(OS::Print(" Polymorphic Instance Calls (%d)\n",
+ instance_calls_.length()));
+ for (intptr_t i = 0; i < instance_calls_.length(); ++i) {
+ PolymorphicInstanceCallInstr* instr = instance_calls_[i];
+ if (instr->with_checks()) {
+ TRACE_INLINING(OS::Print(" Bailout: checks\n"));
+ continue;
+ }
+ const ICData& ic_data = instr->ic_data();
+ const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
+ GrowableArray<Value*> arguments(instr->ArgumentCount());
+ for (int i = 0; i < instr->ArgumentCount(); ++i) {
+ arguments.Add(instr->ArgumentAt(i)->value());
+ }
+ TryInlining(target, &arguments, instr);
}
- TryInlining(call->function(), &arguments, call);
}
- bool inlined() const { return inlined_; }
-
- private:
FlowGraph* caller_graph_;
intptr_t next_ssa_temp_index_;
bool inlined_;
+
+ GrowableArray<StaticCallInstr*> static_calls_;
+ GrowableArray<ClosureCallInstr*> closure_calls_;
+ GrowableArray<PolymorphicInstanceCallInstr*> instance_calls_;
};
@@ -237,7 +269,8 @@ void FlowGraphInliner::Inline() {
}
CallSiteInliner inliner(flow_graph_);
- inliner.VisitBlocks();
+ inliner.FindCallSites();
+ inliner.InlineCalls();
if (inliner.inlined()) {
if (FLAG_trace_inlining && FLAG_print_flow_graph) {

Powered by Google App Engine
This is Rietveld 408576698