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

Unified Diff: vm/flow_graph_builder.cc

Issue 10665022: Make IL instructions a doubly-linked list within basic blocks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 6 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
« no previous file with comments | « vm/flow_graph_allocator.cc ('k') | vm/flow_graph_compiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: vm/flow_graph_builder.cc
===================================================================
--- vm/flow_graph_builder.cc (revision 9281)
+++ vm/flow_graph_builder.cc (working copy)
@@ -51,7 +51,7 @@
entry_ = other_fragment.entry();
exit_ = other_fragment.exit();
} else {
- exit()->SetSuccessor(other_fragment.entry());
+ exit()->set_successor(other_fragment.entry());
exit_ = other_fragment.exit();
}
temp_index_ = other_fragment.temp_index();
@@ -67,12 +67,22 @@
if (is_empty()) {
entry_ = exit_ = instruction;
} else {
- exit()->SetSuccessor(instruction);
+ exit()->set_successor(instruction);
exit_ = instruction;
}
}
+// Appends a graph fragment to a block entry instruction and returns the exit
+// of the resulting graph fragment.
+static Instruction* AppendFragment(BlockEntryInstr* entry,
+ const EffectGraphVisitor& fragment) {
+ if (fragment.is_empty()) return entry;
+ entry->set_successor(fragment.entry());
+ return fragment.exit();
+}
+
+
void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
const EffectGraphVisitor& true_fragment,
const EffectGraphVisitor& false_fragment) {
@@ -87,17 +97,13 @@
// 2. Connect the true and false bodies to the test and record their exits
// (if any).
- Instruction* true_exit = NULL;
- Instruction* false_exit = NULL;
TargetEntryInstr* true_entry = new TargetEntryInstr();
*test_fragment.true_successor_address() = true_entry;
- true_entry->SetSuccessor(true_fragment.entry());
- true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit();
+ Instruction* true_exit = AppendFragment(true_entry, true_fragment);
TargetEntryInstr* false_entry = new TargetEntryInstr();
*test_fragment.false_successor_address() = false_entry;
- false_entry->SetSuccessor(false_fragment.entry());
- false_exit = false_fragment.is_empty() ? false_entry : false_fragment.exit();
+ Instruction* false_exit = AppendFragment(false_entry, false_fragment);
// 3. Add a join or select one (or neither) of the arms as exit.
if (true_exit == NULL) {
@@ -108,8 +114,8 @@
temp_index_ = true_fragment.temp_index();
} else {
exit_ = new JoinEntryInstr();
- true_exit->SetSuccessor(exit_);
- false_exit->SetSuccessor(exit_);
+ true_exit->set_successor(exit_);
+ false_exit->set_successor(exit_);
ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
temp_index_ = true_fragment.temp_index();
}
@@ -126,11 +132,9 @@
// 1. Connect the body to the test if it is reachable, and if so record
// its exit (if any).
- Instruction* body_exit = NULL;
TargetEntryInstr* body_entry = new TargetEntryInstr();
*test_fragment.true_successor_address() = body_entry;
- body_entry->SetSuccessor(body_fragment.entry());
- body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit();
+ Instruction* body_exit = AppendFragment(body_entry, body_fragment);
// 2. Connect the test to this graph, including the body if reachable and
// using a fresh join node if the body is reachable and has an open exit.
@@ -139,8 +143,8 @@
} else {
JoinEntryInstr* join = new JoinEntryInstr();
AddInstruction(join);
- join->SetSuccessor(test_fragment.entry());
- body_exit->SetSuccessor(join);
+ join->set_successor(test_fragment.entry());
+ body_exit->set_successor(join);
}
// 3. Set the exit to the graph to be the false successor of the test, a
@@ -1058,7 +1062,7 @@
*case_false_addresses[i] = case_entries[i + 1];
TargetEntryInstr* true_target = new TargetEntryInstr();
*case_true_addresses[i] = true_target;
- true_target->SetSuccessor(statement_start);
+ true_target->set_successor(statement_start);
}
BlockEntryInstr* exit_instruction = NULL;
@@ -1070,25 +1074,25 @@
} else {
TargetEntryInstr* true_target = new TargetEntryInstr();
*case_true_addresses[len - 1] = true_target;
- true_target->SetSuccessor(statement_start);
+ true_target->set_successor(statement_start);
}
TargetEntryInstr* false_target = new TargetEntryInstr();
*case_false_addresses[len - 1] = false_target;
if (node->contains_default()) {
// True and false go to statement start.
- false_target->SetSuccessor(statement_start);
+ false_target->set_successor(statement_start);
if (for_case_statements.is_open()) {
exit_instruction = new TargetEntryInstr();
- for_case_statements.exit()->SetSuccessor(exit_instruction);
+ for_case_statements.exit()->set_successor(exit_instruction);
}
} else {
if (for_case_statements.is_open()) {
exit_instruction = new JoinEntryInstr();
- for_case_statements.exit()->SetSuccessor(exit_instruction);
+ for_case_statements.exit()->set_successor(exit_instruction);
} else {
exit_instruction = new TargetEntryInstr();
}
- false_target->SetSuccessor(exit_instruction);
+ false_target->set_successor(exit_instruction);
}
} else {
// A CaseNode without case expressions must contain default.
@@ -1163,9 +1167,7 @@
// Tie do-while loop (test is after the body).
JoinEntryInstr* body_entry_join = new JoinEntryInstr();
AddInstruction(body_entry_join);
- body_entry_join->SetSuccessor(for_body.entry());
- Instruction* body_exit =
- for_body.is_empty() ? body_entry_join : for_body.exit();
+ Instruction* body_exit = AppendFragment(body_entry_join, for_body);
if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) {
BlockEntryInstr* test_entry = NULL;
@@ -1174,21 +1176,21 @@
} else {
test_entry = node->label()->join_for_continue();
}
- test_entry->SetSuccessor(for_test.entry());
+ test_entry->set_successor(for_test.entry());
if (body_exit != NULL) {
- body_exit->SetSuccessor(test_entry);
+ body_exit->set_successor(test_entry);
}
}
TargetEntryInstr* back_target_entry = new TargetEntryInstr();
*for_test.true_successor_address() = back_target_entry;
- back_target_entry->SetSuccessor(body_entry_join);
+ back_target_entry->set_successor(body_entry_join);
TargetEntryInstr* loop_exit_target = new TargetEntryInstr();
*for_test.false_successor_address() = loop_exit_target;
if (node->label()->join_for_break() == NULL) {
exit_ = loop_exit_target;
} else {
- loop_exit_target->SetSuccessor(node->label()->join_for_break());
+ loop_exit_target->set_successor(node->label()->join_for_break());
exit_ = node->label()->join_for_break();
}
}
@@ -1235,7 +1237,7 @@
} else if (node->label()->join_for_continue() != NULL) {
// Insert join between body and increment.
if (for_body.is_open()) {
- for_body.exit()->SetSuccessor(node->label()->join_for_continue());
+ for_body.exit()->set_successor(node->label()->join_for_continue());
}
for_increment.AddInstruction(node->label()->join_for_continue());
node->increment()->Visit(&for_increment);
@@ -1251,7 +1253,7 @@
if (loop_increment_end != NULL) {
JoinEntryInstr* loop_start = new JoinEntryInstr();
AddInstruction(loop_start);
- loop_increment_end->SetSuccessor(loop_start);
+ loop_increment_end->set_successor(loop_start);
}
if (node->condition() == NULL) {
@@ -1275,7 +1277,7 @@
if (node->label()->join_for_break() == NULL) {
exit_ = loop_exit;
} else {
- loop_exit->SetSuccessor(node->label()->join_for_break());
+ loop_exit->set_successor(node->label()->join_for_break());
exit_ = node->label()->join_for_break();
}
}
@@ -2388,6 +2390,16 @@
postorder_block_entries_[i]->set_block_id(block_count - i - 1);
}
if (for_optimized && use_ssa) {
+ // Link instructions backwards for optimized compilation.
+ for (intptr_t i = 0; i < block_count; ++i) {
+ Instruction* prev = postorder_block_entries_[i];
+ Instruction* current = prev->successor();
+ while (current != NULL && !current->IsBlockEntry()) {
+ current->set_previous(prev);
+ prev = current;
+ current = current->successor();
+ }
+ }
GrowableArray<BitVector*> dominance_frontier;
ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier);
InsertPhis(preorder_block_entries_,
@@ -2655,8 +2667,7 @@
}
// 2. Process normal instructions.
- Instruction* current = block_entry->StraightLineSuccessor();
- Instruction* prev = block_entry;
+ Instruction* current = block_entry->successor();
while ((current != NULL) && !current->IsBlockEntry()) {
// 2a. Handle uses of LoadLocal / StoreLocal
// For each use of a LoadLocal or StoreLocal: Replace it with the value
@@ -2712,20 +2723,16 @@
if (load != NULL) {
// Remove instruction.
- prev->SetSuccessor(current->StraightLineSuccessor());
+ current->RemoveFromGraph();
} else if (store != NULL) {
// Remove instruction and update renaming environment.
- prev->SetSuccessor(current->StraightLineSuccessor());
+ current->RemoveFromGraph();
(*env)[store->local().BitIndexIn(var_count)] = store->value();
- } else {
+ } else if (current->IsBind()) {
// Assign new SSA temporary.
- if (current->IsBind()) {
- current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++);
- }
- // Update previous only if no instruction was removed from the graph.
- prev = current;
+ current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++);
}
- current = current->StraightLineSuccessor();
+ current = current->successor();
}
// 3. Process dominated blocks.
« no previous file with comments | « vm/flow_graph_allocator.cc ('k') | vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698