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 |