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

Unified Diff: src/hydrogen.cc

Issue 6541060: Change the translation of break/continue into Hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build/ia32
Patch Set: Simplify a bit. Created 9 years, 10 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
« src/hydrogen.h ('K') | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index fd5ad728ecb8fef338dda36e378251bfe68dd911..309335879ba4643a69cdb70047b4e055b2d943b3 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -502,47 +502,13 @@ void HSubgraph::AppendJoin(HSubgraph* then_graph,
}
-void HSubgraph::ResolveContinue(IterationStatement* statement) {
- HBasicBlock* continue_block = BundleContinue(statement);
+void HSubgraph::ResolveContinue(IterationStatement* statement,
Kevin Millikin (Chromium) 2011/02/21 15:41:07 I have tried to keep these helpers and their use a
+ HBasicBlock* continue_block) {
if (continue_block != NULL) {
- exit_block_ = JoinBlocks(exit_block(),
- continue_block,
- statement->ContinueId());
+ continue_block->SetJoinId(statement->ContinueId());
}
-}
-
-
-HBasicBlock* HSubgraph::BundleBreak(BreakableStatement* statement) {
- return BundleBreakContinue(statement, false, statement->ExitId());
-}
-
-
-HBasicBlock* HSubgraph::BundleContinue(IterationStatement* statement) {
- return BundleBreakContinue(statement, true, statement->ContinueId());
-}
-
-
-HBasicBlock* HSubgraph::BundleBreakContinue(BreakableStatement* statement,
- bool is_continue,
- int join_id) {
- HBasicBlock* result = NULL;
- const ZoneList<BreakContinueInfo*>* infos = break_continue_info();
Kevin Millikin (Chromium) 2011/02/21 15:41:07 Before, we kept this zone-allocated list of blocks
- for (int i = 0; i < infos->length(); ++i) {
- BreakContinueInfo* info = infos->at(i);
- if (info->is_continue() == is_continue &&
- info->target() == statement &&
- !info->IsResolved()) {
- if (result == NULL) {
- result = graph_->CreateBasicBlock();
- }
- info->block()->Goto(result);
- info->Resolve();
- }
- }
-
- if (result != NULL) result->SetJoinId(join_id);
-
- return result;
+ exit_block_ =
+ JoinBlocks(exit_block(), continue_block, statement->ContinueId());
}
@@ -557,11 +523,13 @@ HBasicBlock* HSubgraph::JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id) {
}
-void HSubgraph::AppendEndless(HSubgraph* body, IterationStatement* statement) {
+void HSubgraph::AppendEndless(HSubgraph* body,
Kevin Millikin (Chromium) 2011/02/21 15:41:07 Everywhere we used to call ResolveContinue or Bund
+ IterationStatement* statement,
+ HBasicBlock* break_block) {
ConnectExitTo(body->entry_block());
- body->ResolveContinue(statement);
Kevin Millikin (Chromium) 2011/02/21 15:41:07 This call was actually unnecessary, because all th
body->ConnectExitTo(body->entry_block(), true);
- exit_block_ = body->BundleBreak(statement);
+ if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
+ exit_block_ = break_block;
body->entry_block()->PostProcessLoopHeader(statement);
}
@@ -569,11 +537,11 @@ void HSubgraph::AppendEndless(HSubgraph* body, IterationStatement* statement) {
void HSubgraph::AppendDoWhile(HSubgraph* body,
IterationStatement* statement,
HSubgraph* go_back,
- HSubgraph* exit) {
+ HSubgraph* exit,
+ HBasicBlock* break_block) {
ConnectExitTo(body->entry_block());
go_back->ConnectExitTo(body->entry_block(), true);
-
- HBasicBlock* break_block = body->BundleBreak(statement);
+ if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
exit_block_ =
JoinBlocks(exit->exit_block(), break_block, statement->ExitId());
body->entry_block()->PostProcessLoopHeader(statement);
@@ -584,10 +552,11 @@ void HSubgraph::AppendWhile(HSubgraph* condition,
HSubgraph* body,
IterationStatement* statement,
HSubgraph* continue_subgraph,
- HSubgraph* exit) {
+ HSubgraph* exit,
+ HBasicBlock* break_block) {
ConnectExitTo(condition->entry_block());
- HBasicBlock* break_block = body->BundleBreak(statement);
+ if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
exit_block_ =
JoinBlocks(exit->exit_block(), break_block, statement->ExitId());
@@ -604,13 +573,15 @@ void HSubgraph::AppendWhile(HSubgraph* condition,
}
-void HSubgraph::Append(HSubgraph* next, BreakableStatement* stmt) {
+void HSubgraph::Append(HSubgraph* next,
+ BreakableStatement* stmt,
+ HBasicBlock* break_block) {
exit_block_->Goto(next->entry_block());
exit_block_ = next->exit_block_;
if (stmt != NULL) {
next->entry_block()->SetJoinId(stmt->EntryId());
- HBasicBlock* break_block = next->BundleBreak(stmt);
+ if (break_block != NULL) break_block->SetJoinId(stmt->EntryId());
exit_block_ = JoinBlocks(exit_block(), break_block, stmt->ExitId());
}
}
@@ -624,16 +595,6 @@ void HSubgraph::FinishExit(HControlInstruction* instruction) {
}
-void HSubgraph::FinishBreakContinue(BreakableStatement* target,
- bool is_continue) {
- ASSERT(!exit_block_->IsFinished());
- BreakContinueInfo* info = new BreakContinueInfo(target, exit_block_,
- is_continue);
- break_continue_info_.Add(info);
- exit_block_ = NULL;
-}
-
-
HGraph::HGraph(CompilationInfo* info)
: HSubgraph(this),
next_block_id_(0),
@@ -2113,7 +2074,6 @@ class HGraphBuilder::SubgraphScope BASE_EMBEDDED {
}
~SubgraphScope() {
- old_subgraph_->AddBreakContinueInfo(subgraph_);
Kevin Millikin (Chromium) 2011/02/21 15:41:07 Here we copied all the unhandled breaks and contin
builder_->current_subgraph_ = old_subgraph_;
}
@@ -2187,7 +2147,7 @@ HGraph* HGraphBuilder::CreateGraph(CompilationInfo* info) {
HSubgraph* body = CreateGotoSubgraph(environment());
AddToSubgraph(body, stmts);
if (HasStackOverflow()) return NULL;
- current_subgraph_->Append(body, NULL);
+ current_subgraph_->Append(body, NULL, NULL);
body->entry_block()->SetJoinId(info->function()->id());
if (graph_->HasExit()) {
@@ -2389,8 +2349,11 @@ HSubgraph* HGraphBuilder::CreateLoopHeaderSubgraph(HEnvironment* env) {
void HGraphBuilder::VisitBlock(Block* stmt) {
if (stmt->labels() != NULL) {
HSubgraph* block_graph = CreateGotoSubgraph(environment());
- ADD_TO_SUBGRAPH(block_graph, stmt->statements());
- current_subgraph_->Append(block_graph, stmt);
+ BreakAndContinueInfo break_info(stmt);
+ { BreakStackEntry push(&break_info, this);
+ ADD_TO_SUBGRAPH(block_graph, stmt->statements());
+ }
+ subgraph()->Append(block_graph, stmt, break_info.break_block());
} else {
VisitStatements(stmt->statements());
}
@@ -2431,13 +2394,47 @@ void HGraphBuilder::VisitIfStatement(IfStatement* stmt) {
}
+HBasicBlock* HGraphBuilder::BreakStackEntry::Get(BreakableStatement* stmt,
+ BreakType type) {
+ BreakStackEntry* current = this;
+ while (current != NULL && current->info()->target() != stmt) {
+ current = current->next();
+ }
+ ASSERT(current != NULL); // Always found (unless stack is malformed).
+ HBasicBlock* block = NULL;
+ switch (type) {
+ case BREAK:
+ block = current->info()->break_block();
+ if (block == NULL) {
+ block = current->owner()->graph()->CreateBasicBlock();
+ current->info()->set_break_block(block);
+ }
+ break;
+
+ case CONTINUE:
+ block = current->info()->continue_block();
+ if (block == NULL) {
+ block = current->owner()->graph()->CreateBasicBlock();
+ current->info()->set_continue_block(block);
+ }
+ break;
+ }
+
+ return block;
+}
+
+
void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
- current_subgraph_->FinishBreakContinue(stmt->target(), true);
+ HBasicBlock* continue_block = break_stack()->Get(stmt->target(), CONTINUE);
+ subgraph()->exit_block()->Goto(continue_block);
+ subgraph()->set_exit_block(NULL);
}
void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
- current_subgraph_->FinishBreakContinue(stmt->target(), false);
+ HBasicBlock* break_block = break_stack()->Get(stmt->target(), BREAK);
+ subgraph()->exit_block()->Goto(break_block);
+ subgraph()->set_exit_block(NULL);
}
@@ -2620,10 +2617,13 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
}
if (subgraph != NULL) {
- ADD_TO_SUBGRAPH(subgraph, clause->statements());
- HBasicBlock* break_block = subgraph->BundleBreak(stmt);
- if (break_block != NULL) {
- break_block->Finish(new HGoto(single_exit_block));
+ BreakAndContinueInfo break_info(stmt);
+ { BreakStackEntry push(&break_info, this);
+ ADD_TO_SUBGRAPH(subgraph, clause->statements());
+ }
+ if (break_info.break_block() != NULL) {
+ break_info.break_block()->SetJoinId(stmt->ExitId());
+ break_info.break_block()->Finish(new HGoto(single_exit_block));
}
}
@@ -2690,11 +2690,14 @@ void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
subgraph()->PreProcessOsrEntry(stmt);
HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment());
- ADD_TO_SUBGRAPH(body_graph, stmt->body());
- body_graph->ResolveContinue(stmt);
+ BreakAndContinueInfo break_info(stmt);
+ { BreakStackEntry push(&break_info, this);
+ ADD_TO_SUBGRAPH(body_graph, stmt->body());
+ }
+ body_graph->ResolveContinue(stmt, break_info.continue_block());
if (!body_graph->HasExit() || stmt->cond()->ToBooleanIsTrue()) {
- current_subgraph_->AppendEndless(body_graph, stmt);
+ subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
} else {
HSubgraph* go_back = CreateEmptySubgraph();
HSubgraph* exit = CreateEmptySubgraph();
@@ -2706,7 +2709,8 @@ void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
go_back->entry_block()->SetJoinId(stmt->BackEdgeId());
exit->entry_block()->SetJoinId(stmt->ExitId());
}
- current_subgraph_->AppendDoWhile(body_graph, stmt, go_back, exit);
+ subgraph()->AppendDoWhile(body_graph, stmt, go_back, exit,
+ break_info.break_block());
}
}
@@ -2727,7 +2731,6 @@ void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
// If the condition is constant true, do not generate a condition subgraph.
if (stmt->cond()->ToBooleanIsTrue()) {
body_graph = CreateLoopHeaderSubgraph(environment());
- ADD_TO_SUBGRAPH(body_graph, stmt->body());
} else {
cond_graph = CreateLoopHeaderSubgraph(environment());
body_graph = CreateEmptySubgraph();
@@ -2740,16 +2743,20 @@ void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
body_graph->entry_block()->SetJoinId(stmt->BodyId());
exit_graph->entry_block()->SetJoinId(stmt->ExitId());
}
- ADD_TO_SUBGRAPH(body_graph, stmt->body());
}
- body_graph->ResolveContinue(stmt);
+ BreakAndContinueInfo break_info(stmt);
+ { BreakStackEntry push(&break_info, this);
+ ADD_TO_SUBGRAPH(body_graph, stmt->body());
+ }
+ body_graph->ResolveContinue(stmt, break_info.continue_block());
if (cond_graph != NULL) {
- AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph);
+ AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
+ break_info.break_block());
} else {
// TODO(fschneider): Implement peeling for endless loops as well.
- current_subgraph_->AppendEndless(body_graph, stmt);
+ subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
}
}
@@ -2757,7 +2764,8 @@ void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt,
HSubgraph* cond_graph,
HSubgraph* body_graph,
- HSubgraph* exit_graph) {
+ HSubgraph* exit_graph,
+ HBasicBlock* break_block) {
HSubgraph* loop = NULL;
if (body_graph->HasExit() && stmt != peeled_statement_ &&
ShouldPeel(cond_graph, body_graph)) {
@@ -2768,8 +2776,8 @@ void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt,
ADD_TO_SUBGRAPH(loop, stmt);
peeled_statement_ = outer_peeled_statement;
}
- current_subgraph_->AppendWhile(cond_graph, body_graph, stmt, loop,
- exit_graph);
+ subgraph()->AppendWhile(cond_graph, body_graph, stmt, loop, exit_graph,
+ break_block);
}
@@ -2800,22 +2808,26 @@ void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
} else {
body_graph = CreateLoopHeaderSubgraph(environment());
}
- ADD_TO_SUBGRAPH(body_graph, stmt->body());
+ BreakAndContinueInfo break_info(stmt);
+ { BreakStackEntry push(&break_info, this);
+ ADD_TO_SUBGRAPH(body_graph, stmt->body());
+ }
HSubgraph* next_graph = NULL;
- body_graph->ResolveContinue(stmt);
+ body_graph->ResolveContinue(stmt, break_info.continue_block());
if (stmt->next() != NULL && body_graph->HasExit()) {
next_graph = CreateGotoSubgraph(body_graph->environment());
ADD_TO_SUBGRAPH(next_graph, stmt->next());
- body_graph->Append(next_graph, NULL);
+ body_graph->Append(next_graph, NULL, NULL);
next_graph->entry_block()->SetJoinId(stmt->ContinueId());
}
if (cond_graph != NULL) {
- AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph);
+ AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
+ break_info.break_block());
} else {
- current_subgraph_->AppendEndless(body_graph, stmt);
+ subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
}
}
« src/hydrogen.h ('K') | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698