Revision: 7017
Author: [email protected]
Date: Wed Mar 2 03:09:25 2011
Log: Translate loops without using subgraphs.
Build all loop graphs without using class HSubgraph. This also eliminates a
silly goto for the update expression of a for loop.
Support for peeling loops is removed because it's currently untested.
Review URL: http://codereview.chromium.org/6602031
http://code.google.com/p/v8/source/detail?r=7017
Modified:
/branches/bleeding_edge/src/flag-definitions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Wed Mar 2 01:16:05 2011
+++ /branches/bleeding_edge/src/flag-definitions.h Wed Mar 2 03:09:25 2011
@@ -110,7 +110,6 @@
DEFINE_bool(use_range, true, "use hydrogen range analysis")
DEFINE_bool(eliminate_dead_phis, true, "eliminate dead phis")
DEFINE_bool(use_gvn, true, "use hydrogen global value numbering")
-DEFINE_bool(use_peeling, false, "use loop peeling")
DEFINE_bool(use_canonicalizing, true, "use hydrogen instruction
canonicalizing")
DEFINE_bool(use_inlining, true, "use function inlining")
DEFINE_bool(limit_inlining, true, "limit code size growth from inlining")
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Tue Mar 1 01:32:45 2011
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Mar 2 03:09:25 2011
@@ -535,24 +535,15 @@
HBasicBlock* HGraphBuilder::CreateWhile(IterationStatement* statement,
- HBasicBlock* condition_entry,
- HBasicBlock* exit_block,
- HBasicBlock* body_exit,
- HBasicBlock* break_block,
HBasicBlock* loop_entry,
- HBasicBlock* loop_exit) {
+ HBasicBlock* cond_false,
+ HBasicBlock* body_exit,
+ HBasicBlock* break_block) {
if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
HBasicBlock* new_exit =
- CreateJoin(exit_block, break_block, statement->ExitId());
-
- if (loop_entry != NULL) {
- if (body_exit != NULL) body_exit->Goto(loop_entry, true);
- loop_entry->SetJoinId(statement->EntryId());
- new_exit = CreateJoin(new_exit, loop_exit, statement->ExitId());
- } else {
- if (body_exit != NULL) body_exit->Goto(condition_entry, true);
- }
- condition_entry->PostProcessLoopHeader(statement);
+ CreateJoin(cond_false, break_block, statement->ExitId());
+ if (body_exit != NULL) body_exit->Goto(loop_entry, true);
+ loop_entry->PostProcessLoopHeader(statement);
return new_exit;
}
@@ -2317,14 +2308,12 @@
}
-HSubgraph* HGraphBuilder::CreateLoopHeaderSubgraph(HEnvironment* env) {
- HSubgraph* subgraph = new HSubgraph(graph());
- HBasicBlock* block = graph()->CreateBasicBlock();
- HEnvironment* new_env = env->CopyAsLoopHeader(block);
- block->SetInitialEnvironment(new_env);
- subgraph->Initialize(block);
- subgraph->entry_block()->AttachLoopInformation();
- return subgraph;
+HBasicBlock* HGraphBuilder::CreateLoopHeader() {
+ HBasicBlock* header = graph()->CreateBasicBlock();
+ HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
+ header->SetInitialEnvironment(entry_env);
+ header->AttachLoopInformation();
+ return header;
}
@@ -2681,120 +2670,80 @@
void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
-
- HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment());
- current_block()->Goto(body_graph->entry_block(), false);
+ HBasicBlock* loop_entry = CreateLoopHeader();
+ current_block()->Goto(loop_entry, false);
+ set_current_block(loop_entry);
+
BreakAndContinueInfo break_info(stmt);
{ BreakAndContinueScope push(&break_info, this);
- ADD_TO_SUBGRAPH(body_graph, stmt->body());
- }
- HBasicBlock* body_exit = JoinContinue(stmt,
- body_graph->exit_block(),
- break_info.continue_block());
- body_graph->set_exit_block(body_exit);
-
- if (body_graph->exit_block() == NULL || stmt->cond()->ToBooleanIsTrue())
{
- set_current_block(CreateEndless(stmt,
- body_graph->entry_block(),
- body_graph->exit_block(),
- break_info.break_block()));
+ Visit(stmt->body());
+ CHECK_BAILOUT;
+ }
+ HBasicBlock* body_exit =
+ JoinContinue(stmt, current_block(), break_info.continue_block());
+ HBasicBlock* loop_exit = NULL;
+ if (body_exit == NULL || stmt->cond()->ToBooleanIsTrue()) {
+ loop_exit = CreateEndless(stmt,
+ loop_entry,
+ body_exit,
+ break_info.break_block());
} else {
- HSubgraph* go_back = CreateEmptySubgraph();
- HSubgraph* exit = CreateEmptySubgraph();
- {
- SubgraphScope scope(this, body_graph);
- VISIT_FOR_CONTROL(stmt->cond(),
- go_back->entry_block(),
- exit->entry_block());
- go_back->entry_block()->SetJoinId(stmt->BackEdgeId());
- exit->entry_block()->SetJoinId(stmt->ExitId());
- }
- set_current_block(CreateDoWhile(stmt,
- body_graph->entry_block(),
- go_back->exit_block(),
- exit->exit_block(),
- break_info.break_block()));
- }
+ set_current_block(body_exit);
+ HBasicBlock* cond_true = graph()->CreateBasicBlock();
+ HBasicBlock* cond_false = graph()->CreateBasicBlock();
+ VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false);
+ cond_true->SetJoinId(stmt->BackEdgeId());
+ cond_false->SetJoinId(stmt->ExitId());
+ loop_exit = CreateDoWhile(stmt,
+ loop_entry,
+ cond_true,
+ cond_false,
+ break_info.break_block());
+ }
+ set_current_block(loop_exit);
}
void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
-
- HSubgraph* cond_graph = NULL;
- HSubgraph* body_graph = NULL;
- HSubgraph* exit_graph = NULL;
-
- // If the condition is constant true, do not generate a condition
subgraph.
- if (stmt->cond()->ToBooleanIsTrue()) {
- body_graph = CreateLoopHeaderSubgraph(environment());
- current_block()->Goto(body_graph->entry_block(), false);
- } else {
- cond_graph = CreateLoopHeaderSubgraph(environment());
- current_block()->Goto(cond_graph->entry_block(), false);
- body_graph = CreateEmptySubgraph();
- exit_graph = CreateEmptySubgraph();
- {
- SubgraphScope scope(this, cond_graph);
- VISIT_FOR_CONTROL(stmt->cond(),
- body_graph->entry_block(),
- exit_graph->entry_block());
- body_graph->entry_block()->SetJoinId(stmt->BodyId());
- exit_graph->entry_block()->SetJoinId(stmt->ExitId());
- }
+ HBasicBlock* loop_entry = CreateLoopHeader();
+ current_block()->Goto(loop_entry, false);
+ set_current_block(loop_entry);
+
+ // If the condition is constant true, do not generate a branch.
+ HBasicBlock* cond_false = NULL;
+ if (!stmt->cond()->ToBooleanIsTrue()) {
+ HBasicBlock* cond_true = graph()->CreateBasicBlock();
+ cond_false = graph()->CreateBasicBlock();
+ VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false);
+ cond_true->SetJoinId(stmt->BodyId());
+ cond_false->SetJoinId(stmt->ExitId());
+ set_current_block(cond_true);
}
BreakAndContinueInfo break_info(stmt);
{ BreakAndContinueScope push(&break_info, this);
- ADD_TO_SUBGRAPH(body_graph, stmt->body());
- }
- HBasicBlock* body_exit = JoinContinue(stmt,
- body_graph->exit_block(),
- break_info.continue_block());
- body_graph->set_exit_block(body_exit);
-
- if (cond_graph != NULL) {
- set_current_block(CreatePeeledWhile(stmt,
- cond_graph->entry_block(),
- exit_graph->exit_block(),
- body_graph->exit_block(),
- break_info.break_block()));
- } else {
+ Visit(stmt->body());
+ CHECK_BAILOUT;
+ }
+ HBasicBlock* body_exit =
+ JoinContinue(stmt, current_block(), break_info.continue_block());
+ HBasicBlock* loop_exit = NULL;
+ if (stmt->cond()->ToBooleanIsTrue()) {
// TODO(fschneider): Implement peeling for endless loops as well.
- set_current_block(CreateEndless(stmt,
- body_graph->entry_block(),
- body_graph->exit_block(),
- break_info.break_block()));
- }
-}
-
-
-HBasicBlock* HGraphBuilder::CreatePeeledWhile(IterationStatement* stmt,
- HBasicBlock* condition_entry,
- HBasicBlock* exit_block,
- HBasicBlock* body_exit,
- HBasicBlock* break_block) {
- HBasicBlock* loop_entry = NULL;
- HBasicBlock* loop_exit = NULL;
- if (FLAG_use_peeling && body_exit != NULL && stmt != peeled_statement_) {
- // Save the last peeled iteration statement to prevent infinite
recursion.
- IterationStatement* outer_peeled_statement = peeled_statement_;
- peeled_statement_ = stmt;
- HSubgraph* loop = CreateGotoSubgraph(body_exit->last_environment());
- AddToSubgraph(loop, stmt);
- peeled_statement_ = outer_peeled_statement;
- if (HasStackOverflow()) return NULL;
- loop_entry = loop->entry_block();
- loop_exit = loop->exit_block();
- }
- return CreateWhile(stmt,
- condition_entry,
- exit_block,
- body_exit,
- break_block,
- loop_entry,
- loop_exit);
+ loop_exit = CreateEndless(stmt,
+ loop_entry,
+ body_exit,
+ break_info.break_block());
+ } else {
+ loop_exit = CreateWhile(stmt,
+ loop_entry,
+ cond_false,
+ body_exit,
+ break_info.break_block());
+ }
+ set_current_block(loop_exit);
}
@@ -2806,59 +2755,49 @@
}
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
-
- HSubgraph* cond_graph = NULL;
- HSubgraph* body_graph = NULL;
- HSubgraph* exit_graph = NULL;
+ HBasicBlock* loop_entry = CreateLoopHeader();
+ current_block()->Goto(loop_entry, false);
+ set_current_block(loop_entry);
+
+ HBasicBlock* cond_false = NULL;
if (stmt->cond() != NULL) {
- cond_graph = CreateLoopHeaderSubgraph(environment());
- current_block()->Goto(cond_graph->entry_block(), false);
- body_graph = CreateEmptySubgraph();
- exit_graph = CreateEmptySubgraph();
- {
- SubgraphScope scope(this, cond_graph);
- VISIT_FOR_CONTROL(stmt->cond(),
- body_graph->entry_block(),
- exit_graph->entry_block());
- body_graph->entry_block()->SetJoinId(stmt->BodyId());
- exit_graph->entry_block()->SetJoinId(stmt->ExitId());
- }
- } else {
- body_graph = CreateLoopHeaderSubgraph(environment());
- current_block()->Goto(body_graph->entry_block(), false);
- }
+ HBasicBlock* cond_true = graph()->CreateBasicBlock();
+ cond_false = graph()->CreateBasicBlock();
+ VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false);
+ cond_true->SetJoinId(stmt->BodyId());
+ cond_false->SetJoinId(stmt->ExitId());
+ set_current_block(cond_true);
+ }
+
BreakAndContinueInfo break_info(stmt);
{ BreakAndContinueScope push(&break_info, this);
- ADD_TO_SUBGRAPH(body_graph, stmt->body());
- }
-
- HSubgraph* next_graph = NULL;
- HBasicBlock* body_exit = JoinContinue(stmt,
- body_graph->exit_block(),
- break_info.continue_block());
- body_graph->set_exit_block(body_exit);
-
- if (stmt->next() != NULL && body_graph->exit_block() != NULL) {
- next_graph =
- CreateGotoSubgraph(body_graph->exit_block()->last_environment());
- body_graph->exit_block()->Goto(next_graph->entry_block());
- next_graph->entry_block()->SetJoinId(stmt->ContinueId());
- ADD_TO_SUBGRAPH(next_graph, stmt->next());
- body_graph->set_exit_block(next_graph->exit_block());
+ Visit(stmt->body());
+ CHECK_BAILOUT;
+ }
+ HBasicBlock* body_exit =
+ JoinContinue(stmt, current_block(), break_info.continue_block());
+
+ if (stmt->next() != NULL && body_exit != NULL) {
+ set_current_block(body_exit);
+ Visit(stmt->next());
+ CHECK_BAILOUT;
+ body_exit = current_block();
}
- if (cond_graph != NULL) {
- set_current_block(CreatePeeledWhile(stmt,
- cond_graph->entry_block(),
- exit_graph->exit_block(),
- body_graph->exit_block(),
- break_info.break_block()));
+ HBasicBlock* loop_exit = NULL;
+ if (stmt->cond() == NULL) {
+ loop_exit = CreateEndless(stmt,
+ loop_entry,
+ body_exit,
+ break_info.break_block());
} else {
- set_current_block(CreateEndless(stmt,
- body_graph->entry_block(),
- body_graph->exit_block(),
- break_info.break_block()));
- }
+ loop_exit = CreateWhile(stmt,
+ loop_entry,
+ cond_false,
+ body_exit,
+ break_info.break_block());
+ }
+ set_current_block(loop_exit);
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Mon Feb 28 00:52:00 2011
+++ /branches/bleeding_edge/src/hydrogen.h Wed Mar 2 03:09:25 2011
@@ -677,12 +677,10 @@
HBasicBlock* second,
int join_id);
HBasicBlock* CreateWhile(IterationStatement* statement,
- HBasicBlock* condition_entry,
- HBasicBlock* exit_block,
- HBasicBlock* body_exit,
- HBasicBlock* break_block,
HBasicBlock* loop_entry,
- HBasicBlock* loop_exit);
+ HBasicBlock* cond_false,
+ HBasicBlock* body_exit,
+ HBasicBlock* break_block);
HBasicBlock* CreateDoWhile(IterationStatement* statement,
HBasicBlock* body_entry,
HBasicBlock* go_back,
@@ -692,11 +690,6 @@
HBasicBlock* body_entry,
HBasicBlock* body_exit,
HBasicBlock* break_block);
- HBasicBlock* CreatePeeledWhile(IterationStatement* stmt,
- HBasicBlock* condition_entry,
- HBasicBlock* exit_block,
- HBasicBlock* body_exit,
- HBasicBlock* break_block);
HBasicBlock* JoinContinue(IterationStatement* statement,
HBasicBlock* exit_block,
HBasicBlock* continue_block);
@@ -746,7 +739,7 @@
HSubgraph* CreateEmptySubgraph();
HSubgraph* CreateGotoSubgraph(HEnvironment* env);
HSubgraph* CreateBranchSubgraph(HEnvironment* env);
- HSubgraph* CreateLoopHeaderSubgraph(HEnvironment* env);
+ HBasicBlock* CreateLoopHeader();
HSubgraph* CreateInlinedSubgraph(HEnvironment* outer,
Handle<JSFunction> target,
FunctionLiteral* function);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev