From: kmillikin@chromium.org Date: Wed, 2 Mar 2011 11:09:25 +0000 (+0000) Subject: Translate loops without using subgraphs. X-Git-Tag: upstream/4.7.83~20035 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=043a876e93bf6cee6deacdedf636c5bdaa26f1b7;p=platform%2Fupstream%2Fv8.git 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 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7017 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/flag-definitions.h b/src/flag-definitions.h index 0147d48..ea245a4 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -110,7 +110,6 @@ DEFINE_bool(use_lithium, true, "use lithium code generator") 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") diff --git a/src/hydrogen.cc b/src/hydrogen.cc index c4eae9a..e40685c 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -535,24 +535,15 @@ HBasicBlock* HGraphBuilder::CreateDoWhile(IterationStatement* statement, 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::CreateBranchSubgraph(HEnvironment* env) { } -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::PreProcessOsrEntry(IterationStatement* statement) { void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { ASSERT(current_block() != NULL); PreProcessOsrEntry(stmt); + HBasicBlock* loop_entry = CreateLoopHeader(); + current_block()->Goto(loop_entry, false); + set_current_block(loop_entry); - HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment()); - current_block()->Goto(body_graph->entry_block(), false); 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); + HBasicBlock* loop_entry = CreateLoopHeader(); + current_block()->Goto(loop_entry, false); + set_current_block(loop_entry); - 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()); - } + // 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 { - // 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())); + Visit(stmt->body()); + CHECK_BAILOUT; } -} - - -HBasicBlock* HGraphBuilder::CreatePeeledWhile(IterationStatement* stmt, - HBasicBlock* condition_entry, - HBasicBlock* exit_block, - HBasicBlock* body_exit, - HBasicBlock* break_block) { - HBasicBlock* loop_entry = NULL; + HBasicBlock* body_exit = + JoinContinue(stmt, current_block(), break_info.continue_block()); 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(); + if (stmt->cond()->ToBooleanIsTrue()) { + // TODO(fschneider): Implement peeling for endless loops as well. + 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()); } - return CreateWhile(stmt, - condition_entry, - exit_block, - body_exit, - break_block, - loop_entry, - loop_exit); + set_current_block(loop_exit); } @@ -2806,59 +2755,49 @@ void HGraphBuilder::VisitForStatement(ForStatement* stmt) { } ASSERT(current_block() != NULL); PreProcessOsrEntry(stmt); + HBasicBlock* loop_entry = CreateLoopHeader(); + current_block()->Goto(loop_entry, false); + set_current_block(loop_entry); - HSubgraph* cond_graph = NULL; - HSubgraph* body_graph = NULL; - HSubgraph* exit_graph = NULL; + 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()); - } - - 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())); + 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(); + } + + 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); } diff --git a/src/hydrogen.h b/src/hydrogen.h index bd222f4..1ac4fc4 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -677,12 +677,10 @@ class HGraphBuilder: public AstVisitor { 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 @@ class HGraphBuilder: public AstVisitor { 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 @@ class HGraphBuilder: public AstVisitor { HSubgraph* CreateEmptySubgraph(); HSubgraph* CreateGotoSubgraph(HEnvironment* env); HSubgraph* CreateBranchSubgraph(HEnvironment* env); - HSubgraph* CreateLoopHeaderSubgraph(HEnvironment* env); + HBasicBlock* CreateLoopHeader(); HSubgraph* CreateInlinedSubgraph(HEnvironment* outer, Handle target, FunctionLiteral* function);