| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 | 172 |
| 173 // Build preorder and postorder traversal orders. All the nodes in | 173 // Build preorder and postorder traversal orders. All the nodes in |
| 174 // the graph have the same mark flag. For the traversal, use that | 174 // the graph have the same mark flag. For the traversal, use that |
| 175 // flag's negation. Traversal will flip all the flags. | 175 // flag's negation. Traversal will flip all the flags. |
| 176 bool mark = graph_.entry()->IsMarkedWith(false); | 176 bool mark = graph_.entry()->IsMarkedWith(false); |
| 177 graph_.entry()->MarkWith(mark); | 177 graph_.entry()->MarkWith(mark); |
| 178 graph_.entry()->Traverse(mark, &preorder_, &postorder_); | 178 graph_.entry()->Traverse(mark, &preorder_, &postorder_); |
| 179 } | 179 } |
| 180 | 180 |
| 181 | 181 |
| 182 // This function peels off one iteration of a for-loop. The return value |
| 183 // is either a block statement containing the peeled loop or NULL in case |
| 184 // there is a stack overflow. |
| 185 static Statement* PeelForLoop(ForStatement* stmt) { |
| 186 // Mark this for-statement as processed. |
| 187 stmt->set_peel_this_loop(false); |
| 188 |
| 189 // Create new block containing the init statement of the for-loop and |
| 190 // an if-statement containing the peeled iteration and the original |
| 191 // loop without the init-statement. |
| 192 Block* block = new Block(NULL, 2, false); |
| 193 if (stmt->init() != NULL) { |
| 194 Statement* init = stmt->init(); |
| 195 // The init statement gets the statement position of the for-loop |
| 196 // to make debugging of peeled loops possible. |
| 197 init->set_statement_pos(stmt->statement_pos()); |
| 198 block->AddStatement(init); |
| 199 } |
| 200 |
| 201 // Copy the condition. |
| 202 CopyAstVisitor copy_visitor; |
| 203 Expression* cond_copy = stmt->cond() != NULL |
| 204 ? copy_visitor.DeepCopyExpr(stmt->cond()) |
| 205 : new Literal(Factory::true_value()); |
| 206 if (copy_visitor.HasStackOverflow()) return NULL; |
| 207 |
| 208 // Construct a block with the peeled body and the rest of the for-loop. |
| 209 Statement* body_copy = copy_visitor.DeepCopyStmt(stmt->body()); |
| 210 if (copy_visitor.HasStackOverflow()) return NULL; |
| 211 |
| 212 Statement* next_copy = stmt->next() != NULL |
| 213 ? copy_visitor.DeepCopyStmt(stmt->next()) |
| 214 : new EmptyStatement(); |
| 215 if (copy_visitor.HasStackOverflow()) return NULL; |
| 216 |
| 217 Block* peeled_body = new Block(NULL, 3, false); |
| 218 peeled_body->AddStatement(body_copy); |
| 219 peeled_body->AddStatement(next_copy); |
| 220 peeled_body->AddStatement(stmt); |
| 221 |
| 222 // Remove the duplicated init statement from the for-statement. |
| 223 stmt->set_init(NULL); |
| 224 |
| 225 // Create new test at the top and add it to the newly created block. |
| 226 IfStatement* test = new IfStatement(cond_copy, |
| 227 peeled_body, |
| 228 new EmptyStatement()); |
| 229 block->AddStatement(test); |
| 230 return block; |
| 231 } |
| 232 |
| 233 |
| 234 void FlowGraphBuilder::VisitStatements(ZoneList<Statement*>* stmts) { |
| 235 for (int i = 0, len = stmts->length(); i < len; i++) { |
| 236 stmts->at(i) = ProcessStatement(stmts->at(i)); |
| 237 } |
| 238 } |
| 239 |
| 240 |
| 241 Statement* FlowGraphBuilder::ProcessStatement(Statement* stmt) { |
| 242 if (FLAG_loop_peeling && |
| 243 stmt->AsForStatement() != NULL && |
| 244 stmt->AsForStatement()->peel_this_loop()) { |
| 245 Statement* tmp_stmt = PeelForLoop(stmt->AsForStatement()); |
| 246 if (tmp_stmt == NULL) { |
| 247 SetStackOverflow(); |
| 248 } else { |
| 249 stmt = tmp_stmt; |
| 250 } |
| 251 } |
| 252 Visit(stmt); |
| 253 return stmt; |
| 254 } |
| 255 |
| 256 |
| 182 void FlowGraphBuilder::VisitDeclaration(Declaration* decl) { | 257 void FlowGraphBuilder::VisitDeclaration(Declaration* decl) { |
| 183 UNREACHABLE(); | 258 UNREACHABLE(); |
| 184 } | 259 } |
| 185 | 260 |
| 186 | 261 |
| 187 void FlowGraphBuilder::VisitBlock(Block* stmt) { | 262 void FlowGraphBuilder::VisitBlock(Block* stmt) { |
| 188 VisitStatements(stmt->statements()); | 263 VisitStatements(stmt->statements()); |
| 189 } | 264 } |
| 190 | 265 |
| 191 | 266 |
| 192 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { | 267 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { |
| 193 Visit(stmt->expression()); | 268 Visit(stmt->expression()); |
| 194 } | 269 } |
| 195 | 270 |
| 196 | 271 |
| 197 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { | 272 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { |
| 198 // Nothing to do. | 273 // Nothing to do. |
| 199 } | 274 } |
| 200 | 275 |
| 201 | 276 |
| 202 void FlowGraphBuilder::VisitIfStatement(IfStatement* stmt) { | 277 void FlowGraphBuilder::VisitIfStatement(IfStatement* stmt) { |
| 203 Visit(stmt->condition()); | 278 Visit(stmt->condition()); |
| 204 | 279 |
| 205 BranchNode* branch = new BranchNode(); | 280 BranchNode* branch = new BranchNode(); |
| 206 FlowGraph original = graph_; | 281 FlowGraph original = graph_; |
| 207 graph_ = FlowGraph::Empty(); | 282 graph_ = FlowGraph::Empty(); |
| 208 Visit(stmt->then_statement()); | 283 stmt->set_then_statement(ProcessStatement(stmt->then_statement())); |
| 209 | 284 |
| 210 FlowGraph left = graph_; | 285 FlowGraph left = graph_; |
| 211 graph_ = FlowGraph::Empty(); | 286 graph_ = FlowGraph::Empty(); |
| 212 Visit(stmt->else_statement()); | 287 stmt->set_else_statement(ProcessStatement(stmt->else_statement())); |
| 213 | 288 |
| 214 if (HasStackOverflow()) return; | 289 if (HasStackOverflow()) return; |
| 215 JoinNode* join = new JoinNode(); | 290 JoinNode* join = new JoinNode(); |
| 216 original.Split(branch, &left, &graph_, join); | 291 original.Split(branch, &left, &graph_, join); |
| 217 graph_ = original; | 292 graph_ = original; |
| 218 } | 293 } |
| 219 | 294 |
| 220 | 295 |
| 221 void FlowGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { | 296 void FlowGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { |
| 222 SetStackOverflow(); | 297 SetStackOverflow(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 252 SetStackOverflow(); | 327 SetStackOverflow(); |
| 253 } | 328 } |
| 254 | 329 |
| 255 | 330 |
| 256 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 331 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
| 257 SetStackOverflow(); | 332 SetStackOverflow(); |
| 258 } | 333 } |
| 259 | 334 |
| 260 | 335 |
| 261 void FlowGraphBuilder::VisitForStatement(ForStatement* stmt) { | 336 void FlowGraphBuilder::VisitForStatement(ForStatement* stmt) { |
| 262 if (stmt->init() != NULL) Visit(stmt->init()); | 337 if (stmt->init() != NULL) stmt->set_init(ProcessStatement(stmt->init())); |
| 263 | 338 |
| 264 JoinNode* join = new JoinNode(); | 339 JoinNode* join = new JoinNode(); |
| 265 FlowGraph original = graph_; | 340 FlowGraph original = graph_; |
| 266 graph_ = FlowGraph::Empty(); | 341 graph_ = FlowGraph::Empty(); |
| 267 if (stmt->cond() != NULL) Visit(stmt->cond()); | 342 if (stmt->cond() != NULL) Visit(stmt->cond()); |
| 268 | 343 |
| 269 BranchNode* branch = new BranchNode(); | 344 BranchNode* branch = new BranchNode(); |
| 270 FlowGraph condition = graph_; | 345 FlowGraph condition = graph_; |
| 271 graph_ = FlowGraph::Empty(); | 346 graph_ = FlowGraph::Empty(); |
| 272 Visit(stmt->body()); | 347 stmt->set_body(ProcessStatement(stmt->body())); |
| 273 | 348 |
| 274 if (stmt->next() != NULL) Visit(stmt->next()); | 349 if (stmt->next() != NULL) stmt->set_next(ProcessStatement(stmt->next())); |
| 275 | 350 |
| 276 if (HasStackOverflow()) return; | 351 if (HasStackOverflow()) return; |
| 277 original.Loop(join, &condition, branch, &graph_); | 352 original.Loop(join, &condition, branch, &graph_); |
| 278 graph_ = original; | 353 graph_ = original; |
| 279 } | 354 } |
| 280 | 355 |
| 281 | 356 |
| 282 void FlowGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 357 void FlowGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
| 283 SetStackOverflow(); | 358 SetStackOverflow(); |
| 284 } | 359 } |
| (...skipping 1581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 PrintReachingDefinitions(); | 1941 PrintReachingDefinitions(); |
| 1867 PrintF("L%d: Join(", number()); | 1942 PrintF("L%d: Join(", number()); |
| 1868 for (int i = 0, len = predecessors_.length(); i < len; i++) { | 1943 for (int i = 0, len = predecessors_.length(); i < len; i++) { |
| 1869 if (i != 0) PrintF(", "); | 1944 if (i != 0) PrintF(", "); |
| 1870 PrintF("L%d", predecessors_[i]->number()); | 1945 PrintF("L%d", predecessors_[i]->number()); |
| 1871 } | 1946 } |
| 1872 PrintF(")\ngoto L%d\n\n", successor_->number()); | 1947 PrintF(")\ngoto L%d\n\n", successor_->number()); |
| 1873 } | 1948 } |
| 1874 | 1949 |
| 1875 | 1950 |
| 1876 void FlowGraph::PrintText(ZoneList<Node*>* postorder) { | 1951 void FlowGraph::PrintText(FunctionLiteral* fun, ZoneList<Node*>* postorder) { |
| 1877 PrintF("\n========\n"); | 1952 PrintF("\n========\n"); |
| 1953 PrintF("name = %s\n", *fun->name()->ToCString()); |
| 1878 | 1954 |
| 1879 // Number nodes and instructions in reverse postorder. | 1955 // Number nodes and instructions in reverse postorder. |
| 1880 node_count = 0; | 1956 node_count = 0; |
| 1881 instruction_count = 0; | 1957 instruction_count = 0; |
| 1882 for (int i = postorder->length() - 1; i >= 0; i--) { | 1958 for (int i = postorder->length() - 1; i >= 0; i--) { |
| 1883 postorder->at(i)->AssignNodeNumber(); | 1959 postorder->at(i)->AssignNodeNumber(); |
| 1884 } | 1960 } |
| 1885 | 1961 |
| 1886 // Print basic blocks in reverse postorder. | 1962 // Print basic blocks in reverse postorder. |
| 1887 for (int i = postorder->length() - 1; i >= 0; i--) { | 1963 for (int i = postorder->length() - 1; i >= 0; i--) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2114 // all necessary successors to the worklist. | 2190 // all necessary successors to the worklist. |
| 2115 while (!worklist.is_empty()) { | 2191 while (!worklist.is_empty()) { |
| 2116 Node* node = worklist.Remove(); | 2192 Node* node = worklist.Remove(); |
| 2117 node->MarkWith(!mark); | 2193 node->MarkWith(!mark); |
| 2118 node->UpdateRDIn(&worklist, mark); | 2194 node->UpdateRDIn(&worklist, mark); |
| 2119 } | 2195 } |
| 2120 } | 2196 } |
| 2121 | 2197 |
| 2122 | 2198 |
| 2123 } } // namespace v8::internal | 2199 } } // namespace v8::internal |
| OLD | NEW |