| Index: src/data-flow.cc
|
| ===================================================================
|
| --- src/data-flow.cc (revision 4136)
|
| +++ src/data-flow.cc (working copy)
|
| @@ -179,6 +179,81 @@
|
| }
|
|
|
|
|
| +// This function peels off one iteration of a for-loop. The return value
|
| +// is either a block statement containing the peeled loop or NULL in case
|
| +// there is a stack overflow.
|
| +static Statement* PeelForLoop(ForStatement* stmt) {
|
| + // Mark this for-statement as processed.
|
| + stmt->set_peel_this_loop(false);
|
| +
|
| + // Create new block containing the init statement of the for-loop and
|
| + // an if-statement containing the peeled iteration and the original
|
| + // loop without the init-statement.
|
| + Block* block = new Block(NULL, 2, false);
|
| + if (stmt->init() != NULL) {
|
| + Statement* init = stmt->init();
|
| + // The init statement gets the statement position of the for-loop
|
| + // to make debugging of peeled loops possible.
|
| + init->set_statement_pos(stmt->statement_pos());
|
| + block->AddStatement(init);
|
| + }
|
| +
|
| + // Copy the condition.
|
| + CopyAstVisitor copy_visitor;
|
| + Expression* cond_copy = stmt->cond() != NULL
|
| + ? copy_visitor.DeepCopyExpr(stmt->cond())
|
| + : new Literal(Factory::true_value());
|
| + if (copy_visitor.HasStackOverflow()) return NULL;
|
| +
|
| + // Construct a block with the peeled body and the rest of the for-loop.
|
| + Statement* body_copy = copy_visitor.DeepCopyStmt(stmt->body());
|
| + if (copy_visitor.HasStackOverflow()) return NULL;
|
| +
|
| + Statement* next_copy = stmt->next() != NULL
|
| + ? copy_visitor.DeepCopyStmt(stmt->next())
|
| + : new EmptyStatement();
|
| + if (copy_visitor.HasStackOverflow()) return NULL;
|
| +
|
| + Block* peeled_body = new Block(NULL, 3, false);
|
| + peeled_body->AddStatement(body_copy);
|
| + peeled_body->AddStatement(next_copy);
|
| + peeled_body->AddStatement(stmt);
|
| +
|
| + // Remove the duplicated init statement from the for-statement.
|
| + stmt->set_init(NULL);
|
| +
|
| + // Create new test at the top and add it to the newly created block.
|
| + IfStatement* test = new IfStatement(cond_copy,
|
| + peeled_body,
|
| + new EmptyStatement());
|
| + block->AddStatement(test);
|
| + return block;
|
| +}
|
| +
|
| +
|
| +void FlowGraphBuilder::VisitStatements(ZoneList<Statement*>* stmts) {
|
| + for (int i = 0, len = stmts->length(); i < len; i++) {
|
| + stmts->at(i) = ProcessStatement(stmts->at(i));
|
| + }
|
| +}
|
| +
|
| +
|
| +Statement* FlowGraphBuilder::ProcessStatement(Statement* stmt) {
|
| + if (FLAG_loop_peeling &&
|
| + stmt->AsForStatement() != NULL &&
|
| + stmt->AsForStatement()->peel_this_loop()) {
|
| + Statement* tmp_stmt = PeelForLoop(stmt->AsForStatement());
|
| + if (tmp_stmt == NULL) {
|
| + SetStackOverflow();
|
| + } else {
|
| + stmt = tmp_stmt;
|
| + }
|
| + }
|
| + Visit(stmt);
|
| + return stmt;
|
| +}
|
| +
|
| +
|
| void FlowGraphBuilder::VisitDeclaration(Declaration* decl) {
|
| UNREACHABLE();
|
| }
|
| @@ -205,11 +280,11 @@
|
| BranchNode* branch = new BranchNode();
|
| FlowGraph original = graph_;
|
| graph_ = FlowGraph::Empty();
|
| - Visit(stmt->then_statement());
|
| + stmt->set_then_statement(ProcessStatement(stmt->then_statement()));
|
|
|
| FlowGraph left = graph_;
|
| graph_ = FlowGraph::Empty();
|
| - Visit(stmt->else_statement());
|
| + stmt->set_else_statement(ProcessStatement(stmt->else_statement()));
|
|
|
| if (HasStackOverflow()) return;
|
| JoinNode* join = new JoinNode();
|
| @@ -259,7 +334,7 @@
|
|
|
|
|
| void FlowGraphBuilder::VisitForStatement(ForStatement* stmt) {
|
| - if (stmt->init() != NULL) Visit(stmt->init());
|
| + if (stmt->init() != NULL) stmt->set_init(ProcessStatement(stmt->init()));
|
|
|
| JoinNode* join = new JoinNode();
|
| FlowGraph original = graph_;
|
| @@ -269,9 +344,9 @@
|
| BranchNode* branch = new BranchNode();
|
| FlowGraph condition = graph_;
|
| graph_ = FlowGraph::Empty();
|
| - Visit(stmt->body());
|
| + stmt->set_body(ProcessStatement(stmt->body()));
|
|
|
| - if (stmt->next() != NULL) Visit(stmt->next());
|
| + if (stmt->next() != NULL) stmt->set_next(ProcessStatement(stmt->next()));
|
|
|
| if (HasStackOverflow()) return;
|
| original.Loop(join, &condition, branch, &graph_);
|
| @@ -1873,8 +1948,9 @@
|
| }
|
|
|
|
|
| -void FlowGraph::PrintText(ZoneList<Node*>* postorder) {
|
| +void FlowGraph::PrintText(FunctionLiteral* fun, ZoneList<Node*>* postorder) {
|
| PrintF("\n========\n");
|
| + PrintF("name = %s\n", *fun->name()->ToCString());
|
|
|
| // Number nodes and instructions in reverse postorder.
|
| node_count = 0;
|
|
|