| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index e9e3926a3c9751cb06d4d6c87b86d9a2544ef966..f0f8e33cbfd03634a94ce05c8b4988fae9c2d31f 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -482,23 +482,19 @@ HConstant* HGraph::GetConstantFalse() {
|
| }
|
|
|
|
|
| -void HSubgraph::AppendJoin(HSubgraph* then_graph,
|
| - HSubgraph* else_graph,
|
| - AstNode* node) {
|
| - if (then_graph->exit_block() != NULL &&
|
| - else_graph->exit_block() != NULL) {
|
| - // We need to merge, create new merge block.
|
| +void HSubgraph::AppendJoin(HBasicBlock* first,
|
| + HBasicBlock* second,
|
| + int join_id) {
|
| + if (first == NULL) {
|
| + exit_block_ = second;
|
| + } else if (second == NULL) {
|
| + exit_block_ = first;
|
| + } else {
|
| HBasicBlock* join_block = graph_->CreateBasicBlock();
|
| - then_graph->exit_block()->Goto(join_block);
|
| - else_graph->exit_block()->Goto(join_block);
|
| - join_block->SetJoinId(node->id());
|
| + first->Goto(join_block);
|
| + second->Goto(join_block);
|
| + join_block->SetJoinId(join_id);
|
| exit_block_ = join_block;
|
| - } else if (then_graph->exit_block() != NULL) {
|
| - exit_block_ = then_graph->exit_block_;
|
| - } else if (else_graph->exit_block() != NULL) {
|
| - exit_block_ = else_graph->exit_block_;
|
| - } else {
|
| - exit_block_ = NULL;
|
| }
|
| }
|
|
|
| @@ -524,80 +520,81 @@ HBasicBlock* HSubgraph::JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id) {
|
| }
|
|
|
|
|
| -void HSubgraph::AppendEndless(HSubgraph* body,
|
| - IterationStatement* statement,
|
| +void HSubgraph::AppendEndless(IterationStatement* statement,
|
| + HBasicBlock* body_entry,
|
| + HBasicBlock* body_exit,
|
| HBasicBlock* break_block) {
|
| if (exit_block() != NULL) {
|
| - exit_block()->Goto(body->entry_block(), false);
|
| + exit_block()->Goto(body_entry, false);
|
| }
|
| - if (body->exit_block() != NULL) {
|
| - body->exit_block()->Goto(body->entry_block(), true);
|
| + if (body_exit != NULL) {
|
| + body_exit->Goto(body_entry, true);
|
| }
|
| if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
|
| exit_block_ = break_block;
|
| - body->entry_block()->PostProcessLoopHeader(statement);
|
| + body_entry->PostProcessLoopHeader(statement);
|
| }
|
|
|
|
|
| -void HSubgraph::AppendDoWhile(HSubgraph* body,
|
| - IterationStatement* statement,
|
| - HSubgraph* go_back,
|
| - HSubgraph* exit,
|
| +void HSubgraph::AppendDoWhile(IterationStatement* statement,
|
| + HBasicBlock* body_entry,
|
| + HBasicBlock* go_back,
|
| + HBasicBlock* exit_block,
|
| HBasicBlock* break_block) {
|
| - if (exit_block() != NULL) {
|
| - exit_block()->Goto(body->entry_block(), false);
|
| + if (this->exit_block() != NULL) {
|
| + this->exit_block()->Goto(body_entry, false);
|
| }
|
| - if (go_back->exit_block() != NULL) {
|
| - go_back->exit_block()->Goto(body->entry_block(), true);
|
| + if (go_back != NULL) {
|
| + go_back->Goto(body_entry, true);
|
| }
|
| if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
|
| exit_block_ =
|
| - JoinBlocks(exit->exit_block(), break_block, statement->ExitId());
|
| - body->entry_block()->PostProcessLoopHeader(statement);
|
| + JoinBlocks(exit_block, break_block, statement->ExitId());
|
| + body_entry->PostProcessLoopHeader(statement);
|
| }
|
|
|
|
|
| -void HSubgraph::AppendWhile(HSubgraph* condition,
|
| - HSubgraph* body,
|
| - IterationStatement* statement,
|
| - HSubgraph* continue_subgraph,
|
| - HSubgraph* exit,
|
| - HBasicBlock* break_block) {
|
| - if (exit_block() != NULL) {
|
| - exit_block()->Goto(condition->entry_block(), false);
|
| +void HSubgraph::AppendWhile(IterationStatement* statement,
|
| + HBasicBlock* condition_entry,
|
| + HBasicBlock* exit_block,
|
| + HBasicBlock* body_exit,
|
| + HBasicBlock* break_block,
|
| + HBasicBlock* loop_entry,
|
| + HBasicBlock* loop_exit) {
|
| + if (this->exit_block() != NULL) {
|
| + this->exit_block()->Goto(condition_entry, false);
|
| }
|
|
|
| if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
|
| exit_block_ =
|
| - JoinBlocks(exit->exit_block(), break_block, statement->ExitId());
|
| + JoinBlocks(exit_block, break_block, statement->ExitId());
|
|
|
| - if (continue_subgraph != NULL) {
|
| - if (body->exit_block() != NULL) {
|
| - body->exit_block()->Goto(continue_subgraph->entry_block(), true);
|
| + if (loop_entry != NULL) {
|
| + if (body_exit != NULL) {
|
| + body_exit->Goto(loop_entry, true);
|
| }
|
| - continue_subgraph->entry_block()->SetJoinId(statement->EntryId());
|
| - exit_block_ = JoinBlocks(exit_block_,
|
| - continue_subgraph->exit_block(),
|
| - statement->ExitId());
|
| + loop_entry->SetJoinId(statement->EntryId());
|
| + exit_block_ = JoinBlocks(exit_block_, loop_exit, statement->ExitId());
|
| } else {
|
| - if (body->exit_block() != NULL) {
|
| - body->exit_block()->Goto(condition->entry_block(), true);
|
| + if (body_exit != NULL) {
|
| + body_exit->Goto(condition_entry, true);
|
| }
|
| }
|
| - condition->entry_block()->PostProcessLoopHeader(statement);
|
| + condition_entry->PostProcessLoopHeader(statement);
|
| }
|
|
|
|
|
| -void HSubgraph::Append(HSubgraph* next,
|
| - BreakableStatement* stmt,
|
| +void HSubgraph::Append(BreakableStatement* stmt,
|
| + HBasicBlock* entry_block,
|
| + HBasicBlock* exit_block,
|
| HBasicBlock* break_block) {
|
| - exit_block_->Goto(next->entry_block());
|
| - exit_block_ = next->exit_block_;
|
| + exit_block_->Goto(entry_block);
|
| + exit_block_ = exit_block;
|
|
|
| if (stmt != NULL) {
|
| - next->entry_block()->SetJoinId(stmt->EntryId());
|
| + entry_block->SetJoinId(stmt->EntryId());
|
| if (break_block != NULL) break_block->SetJoinId(stmt->EntryId());
|
| - exit_block_ = JoinBlocks(exit_block(), break_block, stmt->ExitId());
|
| + exit_block_ = JoinBlocks(exit_block, break_block, stmt->ExitId());
|
| }
|
| }
|
|
|
| @@ -2170,7 +2167,10 @@ HGraph* HGraphBuilder::CreateGraph(CompilationInfo* info) {
|
| HSubgraph* body = CreateGotoSubgraph(environment());
|
| AddToSubgraph(body, stmts);
|
| if (HasStackOverflow()) return NULL;
|
| - current_subgraph_->Append(body, NULL, NULL);
|
| + current_subgraph_->Append(NULL,
|
| + body->entry_block(),
|
| + body->exit_block(),
|
| + NULL);
|
| body->entry_block()->SetJoinId(info->function()->id());
|
|
|
| if (graph()->exit_block() != NULL) {
|
| @@ -2377,7 +2377,10 @@ void HGraphBuilder::VisitBlock(Block* stmt) {
|
| { BreakAndContinueScope push(&break_info, this);
|
| ADD_TO_SUBGRAPH(block_graph, stmt->statements());
|
| }
|
| - subgraph()->Append(block_graph, stmt, break_info.break_block());
|
| + subgraph()->Append(stmt,
|
| + block_graph->entry_block(),
|
| + block_graph->exit_block(),
|
| + break_info.break_block());
|
| } else {
|
| VisitStatements(stmt->statements());
|
| }
|
| @@ -2413,7 +2416,9 @@ void HGraphBuilder::VisitIfStatement(IfStatement* stmt) {
|
| else_graph->entry_block()->SetJoinId(stmt->ElseId());
|
| ADD_TO_SUBGRAPH(else_graph, stmt->else_statement());
|
|
|
| - current_subgraph_->AppendJoin(then_graph, else_graph, stmt);
|
| + current_subgraph_->AppendJoin(then_graph->exit_block(),
|
| + else_graph->exit_block(),
|
| + stmt->id());
|
| }
|
| }
|
|
|
| @@ -2722,7 +2727,10 @@ void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
| body_graph->ResolveContinue(stmt, break_info.continue_block());
|
|
|
| if (body_graph->exit_block() == NULL || stmt->cond()->ToBooleanIsTrue()) {
|
| - subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
|
| + subgraph()->AppendEndless(stmt,
|
| + body_graph->entry_block(),
|
| + body_graph->exit_block(),
|
| + break_info.break_block());
|
| } else {
|
| HSubgraph* go_back = CreateEmptySubgraph();
|
| HSubgraph* exit = CreateEmptySubgraph();
|
| @@ -2734,17 +2742,15 @@ void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
| go_back->entry_block()->SetJoinId(stmt->BackEdgeId());
|
| exit->entry_block()->SetJoinId(stmt->ExitId());
|
| }
|
| - subgraph()->AppendDoWhile(body_graph, stmt, go_back, exit,
|
| + subgraph()->AppendDoWhile(stmt,
|
| + body_graph->entry_block(),
|
| + go_back->exit_block(),
|
| + exit->exit_block(),
|
| break_info.break_block());
|
| }
|
| }
|
|
|
|
|
| -bool HGraphBuilder::ShouldPeel(HSubgraph* cond, HSubgraph* body) {
|
| - return FLAG_use_peeling;
|
| -}
|
| -
|
| -
|
| void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
|
| ASSERT(current_block() != NULL);
|
| subgraph()->PreProcessOsrEntry(stmt);
|
| @@ -2777,32 +2783,45 @@ void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
|
| body_graph->ResolveContinue(stmt, break_info.continue_block());
|
|
|
| if (cond_graph != NULL) {
|
| - AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
|
| + AppendPeeledWhile(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.
|
| - subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
|
| + subgraph()->AppendEndless(stmt,
|
| + body_graph->entry_block(),
|
| + body_graph->exit_block(),
|
| + break_info.break_block());
|
| }
|
| }
|
|
|
|
|
| void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt,
|
| - HSubgraph* cond_graph,
|
| - HSubgraph* body_graph,
|
| - HSubgraph* exit_graph,
|
| + HBasicBlock* condition_entry,
|
| + HBasicBlock* exit_block,
|
| + HBasicBlock* body_exit,
|
| HBasicBlock* break_block) {
|
| - HSubgraph* loop = NULL;
|
| - if (body_graph->exit_block() != NULL && stmt != peeled_statement_ &&
|
| - ShouldPeel(cond_graph, body_graph)) {
|
| + 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;
|
| - loop = CreateGotoSubgraph(body_graph->exit_block()->last_environment());
|
| + HSubgraph* loop = CreateGotoSubgraph(body_exit->last_environment());
|
| ADD_TO_SUBGRAPH(loop, stmt);
|
| peeled_statement_ = outer_peeled_statement;
|
| + loop_entry = loop->entry_block();
|
| + loop_exit = loop->exit_block();
|
| }
|
| - subgraph()->AppendWhile(cond_graph, body_graph, stmt, loop, exit_graph,
|
| - break_block);
|
| + subgraph()->AppendWhile(stmt,
|
| + condition_entry,
|
| + exit_block,
|
| + body_exit,
|
| + break_block,
|
| + loop_entry,
|
| + loop_exit);
|
| }
|
|
|
|
|
| @@ -2845,15 +2864,24 @@ void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
|
| next_graph =
|
| CreateGotoSubgraph(body_graph->exit_block()->last_environment());
|
| ADD_TO_SUBGRAPH(next_graph, stmt->next());
|
| - body_graph->Append(next_graph, NULL, NULL);
|
| + body_graph->Append(NULL,
|
| + next_graph->entry_block(),
|
| + next_graph->exit_block(),
|
| + NULL);
|
| next_graph->entry_block()->SetJoinId(stmt->ContinueId());
|
| }
|
|
|
| if (cond_graph != NULL) {
|
| - AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
|
| + AppendPeeledWhile(stmt,
|
| + cond_graph->entry_block(),
|
| + exit_graph->exit_block(),
|
| + body_graph->exit_block(),
|
| break_info.break_block());
|
| } else {
|
| - subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
|
| + subgraph()->AppendEndless(stmt,
|
| + body_graph->entry_block(),
|
| + body_graph->exit_block(),
|
| + break_info.break_block());
|
| }
|
| }
|
|
|
| @@ -2907,7 +2935,9 @@ void HGraphBuilder::VisitConditional(Conditional* expr) {
|
| else_graph->entry_block()->SetJoinId(expr->ElseId());
|
| ADD_TO_SUBGRAPH(else_graph, expr->else_expression());
|
|
|
| - current_subgraph_->AppendJoin(then_graph, else_graph, expr);
|
| + current_subgraph_->AppendJoin(then_graph->exit_block(),
|
| + else_graph->exit_block(),
|
| + expr->id());
|
| ast_context()->ReturnValue(Pop());
|
| }
|
|
|
| @@ -4695,7 +4725,9 @@ void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
|
| false_graph->exit_block()->last_environment()->Push(
|
| graph_->GetConstantFalse());
|
|
|
| - current_subgraph_->AppendJoin(true_graph, false_graph, expr);
|
| + current_subgraph_->AppendJoin(true_graph->exit_block(),
|
| + false_graph->exit_block(),
|
| + expr->id());
|
| ast_context()->ReturnValue(Pop());
|
| } else {
|
| ASSERT(ast_context()->IsEffect());
|
|
|