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

Unified Diff: vm/flow_graph_builder.cc

Issue 10700034: Add a goto instruction to the IL use it to terminate 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
Index: vm/flow_graph_builder.cc
===================================================================
--- vm/flow_graph_builder.cc (revision 9101)
+++ vm/flow_graph_builder.cc (working copy)
@@ -51,7 +51,10 @@
entry_ = other_fragment.entry();
exit_ = other_fragment.exit();
} else {
- exit()->SetSuccessor(other_fragment.entry());
+ Instruction* successor = other_fragment.entry();
+ exit()->SetSuccessor(successor->IsBlockEntry()
+ ? new GotoInstr(successor->AsBlockEntry())
+ : successor);
exit_ = other_fragment.exit();
}
temp_index_ = other_fragment.temp_index();
@@ -60,6 +63,7 @@
void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
ASSERT(is_open());
+ ASSERT(!instruction->IsBlockEntry());
DeallocateTempIndex(instruction->InputCount());
if (instruction->IsDefinition()) {
instruction->AsDefinition()->set_temp_index(AllocateTempIndex());
@@ -73,6 +77,19 @@
}
+void EffectGraphVisitor::AddBlockEntry(BlockEntryInstr* instruction) {
+ ASSERT(is_open());
+ if (is_empty()) {
Vyacheslav Egorov (Google) 2012/06/29 16:06:03 I find a bit confusing that a lot of code is dupli
+ entry_ = exit_ = instruction;
+ } else {
+ ASSERT(exit()->IsGraphEntry() ||
+ exit()->IsGoto());
+ exit()->SetSuccessor(instruction);
+ exit_ = instruction;
+ }
+}
+
+
void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
const EffectGraphVisitor& true_fragment,
const EffectGraphVisitor& false_fragment) {
@@ -108,8 +125,8 @@
temp_index_ = true_fragment.temp_index();
} else {
exit_ = new JoinEntryInstr();
- true_exit->SetSuccessor(exit_);
- false_exit->SetSuccessor(exit_);
+ true_exit->SetSuccessor(new GotoInstr(exit_->AsBlockEntry()));
+ false_exit->SetSuccessor(new GotoInstr(exit_->AsBlockEntry()));
ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
temp_index_ = true_fragment.temp_index();
}
@@ -138,9 +155,10 @@
Append(test_fragment);
} else {
JoinEntryInstr* join = new JoinEntryInstr();
- AddInstruction(join);
+ AddInstruction(new GotoInstr(join));
+ AddBlockEntry(join);
join->SetSuccessor(test_fragment.entry());
- body_exit->SetSuccessor(join);
+ body_exit->SetSuccessor(new GotoInstr(join));
}
// 3. Set the exit to the graph to be the false successor of the test, a
@@ -963,7 +981,8 @@
Append(switch_body);
if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) {
if (is_open()) {
- AddInstruction(node->label()->join_for_break());
+ AddInstruction(new GotoInstr(node->label()->join_for_break()));
+ AddBlockEntry(node->label()->join_for_break());
} else {
exit_ = node->label()->join_for_break();
}
@@ -1015,7 +1034,7 @@
} else {
statement_start = new TargetEntryInstr();
}
- for_case_statements.AddInstruction(statement_start);
+ for_case_statements.AddBlockEntry(statement_start);
node->statements()->Visit(&for_case_statements);
if (is_open() && (len == 0)) {
ASSERT(node->contains_default());
@@ -1042,7 +1061,7 @@
} else {
TargetEntryInstr* case_entry_target = new TargetEntryInstr();
case_entries.Add(case_entry_target);
- for_case_expression.AddInstruction(case_entry_target);
+ for_case_expression.AddBlockEntry(case_entry_target);
case_expr->Visit(&for_case_expression);
}
case_true_addresses.Add(for_case_expression.true_successor_address());
@@ -1058,7 +1077,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->SetSuccessor(new GotoInstr(statement_start));
}
BlockEntryInstr* exit_instruction = NULL;
@@ -1070,30 +1089,33 @@
} else {
TargetEntryInstr* true_target = new TargetEntryInstr();
*case_true_addresses[len - 1] = true_target;
- true_target->SetSuccessor(statement_start);
+ true_target->SetSuccessor(new GotoInstr(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->SetSuccessor(new GotoInstr(statement_start));
if (for_case_statements.is_open()) {
exit_instruction = new TargetEntryInstr();
- for_case_statements.exit()->SetSuccessor(exit_instruction);
+ for_case_statements.exit()->SetSuccessor(
+ new GotoInstr(exit_instruction));
}
} else {
if (for_case_statements.is_open()) {
exit_instruction = new JoinEntryInstr();
- for_case_statements.exit()->SetSuccessor(exit_instruction);
+ for_case_statements.exit()->SetSuccessor(
+ new GotoInstr(exit_instruction));
} else {
exit_instruction = new TargetEntryInstr();
}
- false_target->SetSuccessor(exit_instruction);
+ false_target->SetSuccessor(new GotoInstr(exit_instruction));
}
} else {
// A CaseNode without case expressions must contain default.
ASSERT(node->contains_default());
- AddInstruction(statement_start);
+ AddInstruction(new GotoInstr(statement_start));
+ AddBlockEntry(statement_start);
}
ASSERT(!is_open());
@@ -1129,11 +1151,13 @@
SourceLabel* lbl = node->label();
ASSERT(lbl != NULL);
if (lbl->join_for_continue() != NULL) {
- AddInstruction(lbl->join_for_continue());
+ AddInstruction(new GotoInstr(lbl->join_for_continue()));
+ AddBlockEntry(lbl->join_for_continue());
}
TieLoop(for_test, for_body);
if (lbl->join_for_break() != NULL) {
- AddInstruction(lbl->join_for_break());
+ AddInstruction(new GotoInstr(lbl->join_for_break()));
+ AddBlockEntry(lbl->join_for_break());
}
}
@@ -1162,7 +1186,8 @@
// Tie do-while loop (test is after the body).
JoinEntryInstr* body_entry_join = new JoinEntryInstr();
- AddInstruction(body_entry_join);
+ AddInstruction(new GotoInstr(body_entry_join));
+ AddBlockEntry(body_entry_join);
body_entry_join->SetSuccessor(for_body.entry());
Instruction* body_exit =
for_body.is_empty() ? body_entry_join : for_body.exit();
@@ -1176,19 +1201,20 @@
}
test_entry->SetSuccessor(for_test.entry());
if (body_exit != NULL) {
- body_exit->SetSuccessor(test_entry);
+ body_exit->SetSuccessor(new GotoInstr(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->SetSuccessor(new GotoInstr(body_entry_join));
Vyacheslav Egorov (Google) 2012/06/29 16:06:03 SetSuccessor(new GotoInstr()) could have been turn
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->SetSuccessor(
+ new GotoInstr(node->label()->join_for_break()));
exit_ = node->label()->join_for_break();
}
}
@@ -1215,7 +1241,7 @@
// Compose body to set any jump labels.
EffectGraphVisitor for_body(owner(), temp_index());
TargetEntryInstr* body_entry = new TargetEntryInstr();
- for_body.AddInstruction(body_entry);
+ for_body.AddBlockEntry(body_entry);
CheckStackOverflowComp* comp =
new CheckStackOverflowComp(node->token_pos(), owner()->try_index());
for_body.AddInstruction(new DoInstr(comp));
@@ -1235,9 +1261,10 @@
} 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()->SetSuccessor(
+ new GotoInstr(node->label()->join_for_continue()));
}
- for_increment.AddInstruction(node->label()->join_for_continue());
+ for_increment.AddBlockEntry(node->label()->join_for_continue());
node->increment()->Visit(&for_increment);
loop_increment_end = for_increment.exit();
ASSERT(loop_increment_end != NULL);
@@ -1250,8 +1277,9 @@
// body is not open, i.e., no backward branch exists.
if (loop_increment_end != NULL) {
JoinEntryInstr* loop_start = new JoinEntryInstr();
- AddInstruction(loop_start);
- loop_increment_end->SetSuccessor(loop_start);
+ AddInstruction(new GotoInstr(loop_start));
+ AddBlockEntry(loop_start);
+ loop_increment_end->SetSuccessor(new GotoInstr(loop_start));
}
if (node->condition() == NULL) {
@@ -1275,7 +1303,7 @@
if (node->label()->join_for_break() == NULL) {
exit_ = loop_exit;
} else {
- loop_exit->SetSuccessor(node->label()->join_for_break());
+ loop_exit->SetSuccessor(new GotoInstr(node->label()->join_for_break()));
exit_ = node->label()->join_for_break();
}
}
@@ -1318,7 +1346,7 @@
UnchainContext();
}
- Instruction* jump_target = NULL;
+ BlockEntryInstr* jump_target = NULL;
if (node->kind() == Token::kBREAK) {
if (node->label()->join_for_break() == NULL) {
node->label()->set_join_for_break(new JoinEntryInstr());
@@ -1330,7 +1358,8 @@
}
jump_target = node->label()->join_for_continue();
}
- AddInstruction(jump_target);
+ AddInstruction(new GotoInstr(jump_target));
+ AddBlockEntry(jump_target);
CloseFragment();
}
@@ -2226,7 +2255,8 @@
if ((node->label() != NULL) &&
(node->label()->join_for_break() != NULL)) {
if (is_open()) {
- AddInstruction(node->label()->join_for_break());
+ AddInstruction(new GotoInstr(node->label()->join_for_break()));
+ AddBlockEntry(node->label()->join_for_break());
} else {
exit_ = node->label()->join_for_break();
}
@@ -2277,14 +2307,16 @@
catch_block->set_try_index(try_index);
EffectGraphVisitor for_catch_block(owner(), temp_index());
TargetEntryInstr* catch_entry = new TargetEntryInstr(try_index);
- for_catch_block.AddInstruction(catch_entry);
+ for_catch_block.AddBlockEntry(catch_entry);
catch_block->Visit(&for_catch_block);
owner()->AddCatchEntry(catch_entry);
ASSERT(!for_catch_block.is_open());
if ((node->end_catch_label() != NULL) &&
(node->end_catch_label()->join_for_continue() != NULL)) {
if (is_open()) {
- AddInstruction(node->end_catch_label()->join_for_continue());
+ AddInstruction(
+ new GotoInstr(node->end_catch_label()->join_for_continue()));
+ AddBlockEntry(node->end_catch_label()->join_for_continue());
} else {
exit_ = node->end_catch_label()->join_for_continue();
}
@@ -2365,7 +2397,7 @@
TargetEntryInstr* normal_entry = new TargetEntryInstr();
graph_entry_ = new GraphEntryInstr(normal_entry);
EffectGraphVisitor for_effect(this, 0);
- for_effect.AddInstruction(normal_entry);
+ for_effect.AddBlockEntry(normal_entry);
parsed_function().node_sequence()->Visit(&for_effect);
// Check that the graph is properly terminated.
ASSERT(!for_effect.is_open());
« no previous file with comments | « vm/flow_graph_builder.h ('k') | vm/flow_graph_compiler.cc » ('j') | vm/intermediate_language.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698