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

Unified Diff: src/hydrogen.cc

Issue 6604002: Remove some more uses of subgraphs and more cleanup of the graph builder. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build/ia32
Patch Set: 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
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.cc » ('j') | 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 e40685cd697acb2b44b0d4484af10421f9fc5858..1ddd17cb14959d1b68ef9fd9716f1fc87db1cabc 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -503,48 +503,27 @@ HBasicBlock* HGraphBuilder::JoinContinue(IterationStatement* statement,
HBasicBlock* exit_block,
HBasicBlock* continue_block) {
if (continue_block != NULL) {
+ if (exit_block != NULL) exit_block->Goto(continue_block);
continue_block->SetJoinId(statement->ContinueId());
+ return continue_block;
}
- return CreateJoin(exit_block, continue_block, statement->ContinueId());
+ return exit_block;
}
-HBasicBlock* HGraphBuilder::CreateEndless(IterationStatement* statement,
- HBasicBlock* body_entry,
- HBasicBlock* body_exit,
- HBasicBlock* break_block) {
- if (body_exit != NULL) body_exit->Goto(body_entry, true);
- if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
- body_entry->PostProcessLoopHeader(statement);
- return break_block;
-}
-
-
-HBasicBlock* HGraphBuilder::CreateDoWhile(IterationStatement* statement,
- HBasicBlock* body_entry,
- HBasicBlock* go_back,
- HBasicBlock* exit_block,
- HBasicBlock* break_block) {
- if (go_back != NULL) go_back->Goto(body_entry, true);
- if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
- HBasicBlock* new_exit =
- CreateJoin(exit_block, break_block, statement->ExitId());
- body_entry->PostProcessLoopHeader(statement);
- return new_exit;
-}
-
-
-HBasicBlock* HGraphBuilder::CreateWhile(IterationStatement* statement,
- HBasicBlock* loop_entry,
- HBasicBlock* cond_false,
- HBasicBlock* body_exit,
- HBasicBlock* break_block) {
- if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
- HBasicBlock* new_exit =
- CreateJoin(cond_false, break_block, statement->ExitId());
+HBasicBlock* HGraphBuilder::CreateLoop(IterationStatement* statement,
+ HBasicBlock* loop_entry,
+ HBasicBlock* body_exit,
+ HBasicBlock* loop_successor,
+ HBasicBlock* break_block) {
if (body_exit != NULL) body_exit->Goto(loop_entry, true);
loop_entry->PostProcessLoopHeader(statement);
- return new_exit;
+ if (break_block != NULL) {
+ if (loop_successor != NULL) loop_successor->Goto(break_block);
+ break_block->SetJoinId(statement->ExitId());
+ return break_block;
+ }
+ return loop_successor;
}
@@ -621,20 +600,14 @@ HBasicBlock* HGraph::CreateBasicBlock() {
void HGraph::Canonicalize() {
+ if (!FLAG_use_canonicalizing) return;
HPhase phase("Canonicalize", this);
- if (FLAG_use_canonicalizing) {
- for (int i = 0; i < blocks()->length(); ++i) {
- HBasicBlock* b = blocks()->at(i);
- for (HInstruction* insn = b->first(); insn != NULL; insn = insn->next()) {
- HValue* value = insn->Canonicalize();
- if (value != insn) {
- if (value != NULL) {
- insn->ReplaceAndDelete(value);
- } else {
- insn->Delete();
- }
- }
- }
+ for (int i = 0; i < blocks()->length(); ++i) {
+ HInstruction* instr = blocks()->at(i)->first();
+ while (instr != NULL) {
+ HValue* value = instr->Canonicalize();
+ if (value != instr) instr->ReplaceAndDelete(value);
+ instr = instr->next();
}
}
}
@@ -1390,8 +1363,7 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) {
instr->Mnemonic(),
other->id(),
other->Mnemonic());
- instr->ReplaceValue(other);
- instr->Delete();
+ instr->ReplaceAndDelete(other);
} else {
map->Add(instr);
}
@@ -2096,68 +2068,86 @@ void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) {
HGraph* HGraphBuilder::CreateGraph(CompilationInfo* info) {
- ASSERT(current_subgraph_ == NULL);
+ ASSERT(subgraph() == NULL);
graph_ = new HGraph(info);
{
HPhase phase("Block building");
- graph_->Initialize(CreateBasicBlock(graph_->start_environment()));
- current_subgraph_ = graph_;
+ graph()->Initialize(CreateBasicBlock(graph()->start_environment()));
+ current_subgraph_ = graph();
Scope* scope = info->scope();
+ if (scope->HasIllegalRedeclaration()) {
+ Bailout("function with illegal redeclaration");
+ return NULL;
+ }
SetupScope(scope);
VisitDeclarations(scope->declarations());
-
AddInstruction(new HStackCheck());
- ZoneList<Statement*>* stmts = info->function()->body();
- HSubgraph* body = CreateGotoSubgraph(environment());
- current_block()->Goto(body->entry_block());
- AddToSubgraph(body, stmts);
+ // Add an edge to the body entry. This is warty: the graph's start
+ // environment will be used by the Lithium translation as the initial
+ // environment on graph entry, but it has now been mutated by the
+ // Hydrogen translation of the instructions in the start block. This
+ // environment uses values which have not been defined yet. These
+ // Hydrogen instructions will then be replayed by the Lithium
+ // translation, so they cannot have an environment effect. The edge to
+ // the body's entry block (along with some special logic for the start
+ // block in HInstruction::InsertAfter) seals the start block from
+ // getting unwanted instructions inserted.
+ //
+ // TODO(kmillikin): Fix this. Stop mutating the initial environment.
+ // Make the Hydrogen instructions in the initial block into Hydrogen
+ // values (but not instructions), present in the initial environment and
+ // not replayed by the Lithium translation.
+ HEnvironment* initial_env = environment()->CopyWithoutHistory();
+ HBasicBlock* body_entry = CreateBasicBlock(initial_env);
+ current_block()->Goto(body_entry);
+ body_entry->SetJoinId(info->function()->id());
+ set_current_block(body_entry);
+ VisitStatements(info->function()->body());
if (HasStackOverflow()) return NULL;
- body->entry_block()->SetJoinId(info->function()->id());
- set_current_block(body->exit_block());
- if (graph()->exit_block() != NULL) {
+ if (current_block() != NULL) {
HReturn* instr = new HReturn(graph()->GetConstantUndefined());
- graph()->exit_block()->FinishExit(instr);
- graph()->set_exit_block(NULL);
+ current_block()->FinishExit(instr);
+ set_current_block(NULL);
}
}
- graph_->OrderBlocks();
- graph_->AssignDominators();
- graph_->EliminateRedundantPhis();
- if (!graph_->CollectPhis()) {
+ graph()->OrderBlocks();
+ graph()->AssignDominators();
+ graph()->EliminateRedundantPhis();
+ if (!graph()->CollectPhis()) {
Bailout("Phi-use of arguments object");
return NULL;
}
- HInferRepresentation rep(graph_);
+ HInferRepresentation rep(graph());
rep.Analyze();
if (FLAG_use_range) {
- HRangeAnalysis rangeAnalysis(graph_);
+ HRangeAnalysis rangeAnalysis(graph());
rangeAnalysis.Analyze();
}
- graph_->InitializeInferredTypes();
- graph_->Canonicalize();
- graph_->InsertRepresentationChanges();
- graph_->ComputeMinusZeroChecks();
+ graph()->InitializeInferredTypes();
+ graph()->Canonicalize();
+ graph()->InsertRepresentationChanges();
+ graph()->ComputeMinusZeroChecks();
// Eliminate redundant stack checks on backwards branches.
- HStackCheckEliminator sce(graph_);
+ HStackCheckEliminator sce(graph());
sce.Process();
// Perform common subexpression elimination and loop-invariant code motion.
if (FLAG_use_gvn) {
- HPhase phase("Global value numbering", graph_);
- HGlobalValueNumberer gvn(graph_);
+ HPhase phase("Global value numbering", graph());
+ HGlobalValueNumberer gvn(graph());
gvn.Analyze();
}
- return graph_;
+ return graph();
}
@@ -2285,14 +2275,6 @@ HSubgraph* HGraphBuilder::CreateInlinedSubgraph(HEnvironment* outer,
}
-HSubgraph* HGraphBuilder::CreateGotoSubgraph(HEnvironment* env) {
- HSubgraph* subgraph = new HSubgraph(graph());
- HEnvironment* new_env = env->CopyWithoutHistory();
- subgraph->Initialize(CreateBasicBlock(new_env));
- return subgraph;
-}
-
-
HSubgraph* HGraphBuilder::CreateEmptySubgraph() {
HSubgraph* subgraph = new HSubgraph(graph());
subgraph->Initialize(graph()->CreateBasicBlock());
@@ -2308,7 +2290,7 @@ HSubgraph* HGraphBuilder::CreateBranchSubgraph(HEnvironment* env) {
}
-HBasicBlock* HGraphBuilder::CreateLoopHeader() {
+HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
HBasicBlock* header = graph()->CreateBasicBlock();
HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
header->SetInitialEnvironment(entry_env);
@@ -2318,21 +2300,16 @@ HBasicBlock* HGraphBuilder::CreateLoopHeader() {
void HGraphBuilder::VisitBlock(Block* stmt) {
- if (stmt->labels() != NULL) {
- HSubgraph* block_graph = CreateGotoSubgraph(environment());
- current_block()->Goto(block_graph->entry_block());
- block_graph->entry_block()->SetJoinId(stmt->EntryId());
- BreakAndContinueInfo break_info(stmt);
- { BreakAndContinueScope push(&break_info, this);
- ADD_TO_SUBGRAPH(block_graph, stmt->statements());
- }
- HBasicBlock* break_block = break_info.break_block();
- if (break_block != NULL) break_block->SetJoinId(stmt->EntryId());
- set_current_block(CreateJoin(block_graph->exit_block(),
- break_block,
- stmt->ExitId()));
- } else {
+ BreakAndContinueInfo break_info(stmt);
+ { BreakAndContinueScope push(&break_info, this);
VisitStatements(stmt->statements());
+ CHECK_BAILOUT;
+ }
+ HBasicBlock* break_block = break_info.break_block();
+ if (break_block != NULL) {
+ if (current_block() != NULL) current_block()->Goto(break_block);
+ break_block->SetJoinId(stmt->ExitId());
+ set_current_block(break_block);
}
}
@@ -2354,21 +2331,23 @@ void HGraphBuilder::VisitIfStatement(IfStatement* stmt) {
AddSimulate(stmt->ElseId());
Visit(stmt->else_statement());
} else {
- HSubgraph* then_graph = CreateEmptySubgraph();
- HSubgraph* else_graph = CreateEmptySubgraph();
- VISIT_FOR_CONTROL(stmt->condition(),
- then_graph->entry_block(),
- else_graph->entry_block());
+ HBasicBlock* cond_true = graph()->CreateBasicBlock();
+ HBasicBlock* cond_false = graph()->CreateBasicBlock();
+ VISIT_FOR_CONTROL(stmt->condition(), cond_true, cond_false);
+ cond_true->SetJoinId(stmt->ThenId());
+ cond_false->SetJoinId(stmt->ElseId());
- then_graph->entry_block()->SetJoinId(stmt->ThenId());
- ADD_TO_SUBGRAPH(then_graph, stmt->then_statement());
+ set_current_block(cond_true);
+ Visit(stmt->then_statement());
+ CHECK_BAILOUT;
+ HBasicBlock* other = current_block();
- else_graph->entry_block()->SetJoinId(stmt->ElseId());
- ADD_TO_SUBGRAPH(else_graph, stmt->else_statement());
+ set_current_block(cond_false);
+ Visit(stmt->else_statement());
+ CHECK_BAILOUT;
- set_current_block(CreateJoin(then_graph->exit_block(),
- else_graph->exit_block(),
- stmt->id()));
+ HBasicBlock* join = CreateJoin(other, current_block(), stmt->id());
+ set_current_block(join);
}
}
@@ -2670,7 +2649,7 @@ void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
- HBasicBlock* loop_entry = CreateLoopHeader();
+ HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry, false);
set_current_block(loop_entry);
@@ -2681,25 +2660,22 @@ void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
}
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 {
+ HBasicBlock* loop_successor = NULL;
+ if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) {
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());
- }
+ // The block for a true condition, the actual predecessor block of the
+ // back edge.
+ body_exit = graph()->CreateBasicBlock();
+ loop_successor = graph()->CreateBasicBlock();
+ VISIT_FOR_CONTROL(stmt->cond(), body_exit, loop_successor);
+ body_exit->SetJoinId(stmt->BackEdgeId());
+ loop_successor->SetJoinId(stmt->ExitId());
+ }
+ HBasicBlock* loop_exit = CreateLoop(stmt,
+ loop_entry,
+ body_exit,
+ loop_successor,
+ break_info.break_block());
set_current_block(loop_exit);
}
@@ -2707,19 +2683,19 @@ void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
- HBasicBlock* loop_entry = CreateLoopHeader();
+ HBasicBlock* loop_entry = CreateLoopHeaderBlock();
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;
+ HBasicBlock* loop_successor = 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);
+ HBasicBlock* body_entry = graph()->CreateBasicBlock();
+ loop_successor = graph()->CreateBasicBlock();
+ VISIT_FOR_CONTROL(stmt->cond(), body_entry, loop_successor);
+ body_entry->SetJoinId(stmt->BodyId());
+ loop_successor->SetJoinId(stmt->ExitId());
+ set_current_block(body_entry);
}
BreakAndContinueInfo break_info(stmt);
@@ -2729,44 +2705,34 @@ void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
}
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.
- 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());
- }
+ HBasicBlock* loop_exit = CreateLoop(stmt,
+ loop_entry,
+ body_exit,
+ loop_successor,
+ break_info.break_block());
set_current_block(loop_exit);
}
void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
- // Only visit the init statement in the peeled part of the loop.
- if (stmt->init() != NULL && peeled_statement_ != stmt) {
+ if (stmt->init() != NULL) {
Visit(stmt->init());
CHECK_BAILOUT;
}
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
- HBasicBlock* loop_entry = CreateLoopHeader();
+ HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry, false);
set_current_block(loop_entry);
- HBasicBlock* cond_false = NULL;
+ HBasicBlock* loop_successor = NULL;
if (stmt->cond() != NULL) {
- 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);
+ HBasicBlock* body_entry = graph()->CreateBasicBlock();
+ loop_successor = graph()->CreateBasicBlock();
+ VISIT_FOR_CONTROL(stmt->cond(), body_entry, loop_successor);
+ body_entry->SetJoinId(stmt->BodyId());
+ loop_successor->SetJoinId(stmt->ExitId());
+ set_current_block(body_entry);
}
BreakAndContinueInfo break_info(stmt);
@@ -2784,19 +2750,11 @@ void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
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 {
- loop_exit = CreateWhile(stmt,
- loop_entry,
- cond_false,
- body_exit,
- break_info.break_block());
- }
+ HBasicBlock* loop_exit = CreateLoop(stmt,
+ loop_entry,
+ body_exit,
+ loop_successor,
+ break_info.break_block());
set_current_block(loop_exit);
}
@@ -2838,21 +2796,23 @@ void HGraphBuilder::VisitSharedFunctionInfoLiteral(
void HGraphBuilder::VisitConditional(Conditional* expr) {
- HSubgraph* then_graph = CreateEmptySubgraph();
- HSubgraph* else_graph = CreateEmptySubgraph();
- VISIT_FOR_CONTROL(expr->condition(),
- then_graph->entry_block(),
- else_graph->entry_block());
-
- then_graph->entry_block()->SetJoinId(expr->ThenId());
- ADD_TO_SUBGRAPH(then_graph, expr->then_expression());
-
- else_graph->entry_block()->SetJoinId(expr->ElseId());
- ADD_TO_SUBGRAPH(else_graph, expr->else_expression());
-
- set_current_block(CreateJoin(then_graph->exit_block(),
- else_graph->exit_block(),
- expr->id()));
+ HBasicBlock* cond_true = graph()->CreateBasicBlock();
+ HBasicBlock* cond_false = graph()->CreateBasicBlock();
+ VISIT_FOR_CONTROL(expr->condition(), cond_true, cond_false);
+ cond_true->SetJoinId(expr->ThenId());
+ cond_false->SetJoinId(expr->ElseId());
+
+ // TOOD(kmillikin): Visit the subexpressions in the same AST context as
+ // the whole expression.
+ set_current_block(cond_true);
+ VISIT_FOR_VALUE(expr->then_expression());
+ HBasicBlock* other = current_block();
+
+ set_current_block(cond_false);
+ VISIT_FOR_VALUE(expr->else_expression());
+
+ HBasicBlock* join = CreateJoin(other, current_block(), expr->id());
+ set_current_block(join);
ast_context()->ReturnValue(Pop());
}
@@ -4638,26 +4598,26 @@ void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
context->if_false(),
context->if_true());
} else if (ast_context()->IsValue()) {
- HSubgraph* true_graph = CreateEmptySubgraph();
- HSubgraph* false_graph = CreateEmptySubgraph();
+ HBasicBlock* materialize_false = graph()->CreateBasicBlock();
+ HBasicBlock* materialize_true = graph()->CreateBasicBlock();
VISIT_FOR_CONTROL(expr->expression(),
- false_graph->entry_block(),
- true_graph->entry_block());
- true_graph->entry_block()->SetJoinId(expr->expression()->id());
- true_graph->exit_block()->last_environment()->Push(
- graph_->GetConstantTrue());
-
- false_graph->entry_block()->SetJoinId(expr->expression()->id());
- false_graph->exit_block()->last_environment()->Push(
- graph_->GetConstantFalse());
-
- set_current_block(CreateJoin(true_graph->exit_block(),
- false_graph->exit_block(),
- expr->id()));
+ materialize_false,
+ materialize_true);
+ materialize_false->SetJoinId(expr->expression()->id());
+ materialize_true->SetJoinId(expr->expression()->id());
+
+ set_current_block(materialize_false);
+ Push(graph()->GetConstantFalse());
+ set_current_block(materialize_true);
+ Push(graph()->GetConstantTrue());
+
+ HBasicBlock* join =
+ CreateJoin(materialize_false, materialize_true, expr->id());
+ set_current_block(join);
ast_context()->ReturnValue(Pop());
} else {
ASSERT(ast_context()->IsEffect());
- VISIT_FOR_EFFECT(expr->expression());
+ VisitForEffect(expr->expression());
}
} else if (op == Token::BIT_NOT || op == Token::SUB) {
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698