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; |