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

Side by Side Diff: src/data-flow.cc

Issue 998001: Loop peeling for inner loops.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/data-flow.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/data-flow.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698