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

Unified Diff: runtime/vm/flow_graph.cc

Issue 11856010: Change the inlining context from an enum to a class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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.cc
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 0ead0a280ec731cea8804166a4277d14c6031487..224adb3044d9c9d708039a827f2814cb8363fe51 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -30,7 +30,6 @@ FlowGraph::FlowGraph(const FlowGraphBuilder& builder,
preorder_(),
postorder_(),
reverse_postorder_(),
- exits_(NULL),
invalid_dominator_tree_(true) {
DiscoverBlocks();
}
@@ -209,8 +208,7 @@ bool FlowGraph::ValidateUseLists() {
static void ClearUseLists(Definition* defn) {
ASSERT(defn != NULL);
- ASSERT(defn->input_use_list() == NULL);
- ASSERT(defn->env_use_list() == NULL);
+ ASSERT(!defn->HasUses());
defn->set_input_use_list(NULL);
defn->set_env_use_list(NULL);
}
@@ -827,13 +825,6 @@ void FlowGraph::ReplacePredecessor(BlockEntryInstr* old_block,
}
-// Helper to sort a list of blocks.
-static int LowestBlockIdFirst(BlockEntryInstr* const* a,
- BlockEntryInstr* const* b) {
- return (*a)->block_id() - (*b)->block_id();
-}
-
-
// Inline a flow graph at a call site.
//
// Assumes the callee graph was computed by BuildGraph with an inlining context
@@ -842,10 +833,11 @@ static int LowestBlockIdFirst(BlockEntryInstr* const* a,
//
// After inlining the caller graph will correctly have adjusted the pre/post
// orders, the dominator tree and the use lists.
-void FlowGraph::InlineCall(Definition* call, FlowGraph* callee_graph) {
+void FlowGraph::InlineCall(Definition* call,
+ FlowGraph* callee_graph,
+ ValueInliningContext* inlining_context) {
ASSERT(call->previous() != NULL);
ASSERT(call->next() != NULL);
- ASSERT(callee_graph->exits() != NULL);
ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
ASSERT(callee_graph->max_block_id() > max_block_id());
ASSERT(callee_graph->max_virtual_register_number() >
@@ -859,7 +851,6 @@ void FlowGraph::InlineCall(Definition* call, FlowGraph* callee_graph) {
BlockEntryInstr* caller_entry = call->GetBlock();
TargetEntryInstr* callee_entry = callee_graph->graph_entry()->normal_entry();
- ZoneGrowableArray<ReturnInstr*>* callee_exits = callee_graph->exits();
// Attach the outer environment on each instruction in the callee graph.
for (BlockIterator block_it = callee_graph->postorder_iterator();
@@ -876,23 +867,23 @@ void FlowGraph::InlineCall(Definition* call, FlowGraph* callee_graph) {
}
}
- // Insert the callee graph into the caller graph.
- if (callee_exits->is_empty()) {
+ // Insert the callee graph into the caller graph. First sort the list of
+ // exits by block id (recording block entries as a side effect).
+ inlining_context->SortExits();
+ if (inlining_context->NumExits() == 0) {
// TODO(zerny): Add support for non-local exits, such as throw.
UNREACHABLE();
- } else if (callee_exits->length() == 1) {
- ReturnInstr* exit = (*callee_exits)[0];
- ASSERT(exit->previous() != NULL);
+ } else if (inlining_context->NumExits() == 1) {
// For just one exit, replace the uses and remove the call from the graph.
- call->ReplaceUsesWith(exit->value()->definition());
+ call->ReplaceUsesWith(inlining_context->ValueAt(0)->definition());
call->previous()->LinkTo(callee_entry->next());
- exit->previous()->LinkTo(call->next());
+ inlining_context->LastInstructionAt(0)->LinkTo(call->next());
// In case of control flow, locally update the predecessors, phis and
// dominator tree.
// TODO(zerny): should we leave the dominator tree since we recompute it
// after a full inlining pass?
if (callee_graph->preorder().length() > 2) {
- BlockEntryInstr* exit_block = exit->GetBlock();
+ BlockEntryInstr* exit_block = inlining_context->ExitBlockAt(0);
// Pictorially, the graph structure is:
//
// Bc : caller_entry Bi : callee_entry
@@ -932,27 +923,19 @@ void FlowGraph::InlineCall(Definition* call, FlowGraph* callee_graph) {
}
}
} else {
- // Sort the list of exits by block id.
- GrowableArray<BlockEntryInstr*> exits(callee_exits->length());
- for (intptr_t i = 0; i < callee_exits->length(); ++i) {
- exits.Add((*callee_exits)[i]->GetBlock());
- }
- exits.Sort(LowestBlockIdFirst);
// Create a join of the returns.
JoinEntryInstr* join =
new JoinEntryInstr(++max_block_id_,
CatchClauseNode::kInvalidTryIndex,
caller_entry->loop_depth());
- for (intptr_t i = 0; i < exits.length(); ++i) {
- ReturnInstr* exit_instr = exits[i]->last_instruction()->AsReturn();
- ASSERT(exit_instr != NULL);
- exit_instr->previous()->Goto(join);
+ intptr_t count = inlining_context->NumExits();
+ for (intptr_t i = 0; i < count; ++i) {
+ inlining_context->LastInstructionAt(i)->Goto(join);
// Directly add the predecessors of the join in ascending block id order.
- join->predecessors_.Add(exits[i]);
+ join->predecessors_.Add(inlining_context->ExitBlockAt(i));
}
// If the call has uses, create a phi of the returns.
- if ((call->input_use_list() != NULL) ||
- (call->env_use_list() != NULL)) {
+ if (call->HasUses()) {
// Environment count: length before call - argument count (+ return)
intptr_t env_count = call->env()->Length() - call->ArgumentCount();
// Add a phi of the return values.
@@ -960,13 +943,11 @@ void FlowGraph::InlineCall(Definition* call, FlowGraph* callee_graph) {
PhiInstr* phi = join->phis()->Last();
phi->set_ssa_temp_index(alloc_ssa_temp_index());
phi->mark_alive();
- for (intptr_t i = 0; i < exits.length(); ++i) {
- ReturnInstr* exit_instr = exits[i]->last_instruction()->AsReturn();
- ASSERT(exit_instr != NULL);
- Value* use = exit_instr->value();
- phi->SetInputAt(i, use);
- use->set_instruction(phi);
- use->set_use_index(i);
+ for (intptr_t i = 0; i < count; ++i) {
+ Value* value = inlining_context->ValueAt(i);
+ phi->SetInputAt(i, value);
+ value->set_instruction(phi);
+ value->set_use_index(i);
}
// Replace uses of the call with the phi.
call->ReplaceUsesWith(phi);
@@ -977,10 +958,10 @@ void FlowGraph::InlineCall(Definition* call, FlowGraph* callee_graph) {
// Replace the blocks after splitting (see comment in the len=1 case above).
ReplacePredecessor(caller_entry, join);
ReplacePredecessor(callee_entry, caller_entry);
- // Update the last instruction pointers on each exit (ie, to the new goto).
- for (intptr_t i = 0; i < exits.length(); ++i) {
- exits[i]->set_last_instruction(
- exits[i]->last_instruction()->previous()->next());
+ // Update the last instruction pointers on each exit block to the new goto.
+ for (intptr_t i = 0; i < count; ++i) {
+ inlining_context->ExitBlockAt(i)->set_last_instruction(
+ inlining_context->LastInstructionAt(i)->next());
}
// Mark that the dominator tree is invalid.
// TODO(zerny): Compute the dominator frontier locally.

Powered by Google App Engine
This is Rietveld 408576698