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

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

Issue 1253009: Move flow graph and helper classes to their own file. (Closed)
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
« no previous file with comments | « src/compiler.cc ('k') | src/data-flow.cc » ('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 19 matching lines...) Expand all
30 30
31 #include "v8.h" 31 #include "v8.h"
32 32
33 #include "ast.h" 33 #include "ast.h"
34 #include "compiler.h" 34 #include "compiler.h"
35 #include "zone-inl.h" 35 #include "zone-inl.h"
36 36
37 namespace v8 { 37 namespace v8 {
38 namespace internal { 38 namespace internal {
39 39
40 // Forward declarations.
41 class Node;
42
40 class BitVector: public ZoneObject { 43 class BitVector: public ZoneObject {
41 public: 44 public:
42 explicit BitVector(int length) 45 explicit BitVector(int length)
43 : length_(length), 46 : length_(length),
44 data_length_(SizeFor(length)), 47 data_length_(SizeFor(length)),
45 data_(Zone::NewArray<uint32_t>(data_length_)) { 48 data_(Zone::NewArray<uint32_t>(data_length_)) {
46 ASSERT(length > 0); 49 ASSERT(length > 0);
47 Clear(); 50 Clear();
48 } 51 }
49 52
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 BitVector* kill() { return kill_; } 201 BitVector* kill() { return kill_; }
199 BitVector* gen() { return gen_; } 202 BitVector* gen() { return gen_; }
200 203
201 private: 204 private:
202 BitVector* rd_in_; 205 BitVector* rd_in_;
203 BitVector* kill_; 206 BitVector* kill_;
204 BitVector* gen_; 207 BitVector* gen_;
205 }; 208 };
206 209
207 210
208 // Flow-graph nodes.
209 class Node: public ZoneObject {
210 public:
211 Node() : number_(-1), mark_(false) {}
212
213 virtual ~Node() {}
214
215 virtual bool IsExitNode() { return false; }
216 virtual bool IsBlockNode() { return false; }
217 virtual bool IsBranchNode() { return false; }
218 virtual bool IsJoinNode() { return false; }
219
220 virtual void AddPredecessor(Node* predecessor) = 0;
221 virtual void AddSuccessor(Node* successor) = 0;
222
223 bool IsMarkedWith(bool mark) { return mark_ == mark; }
224 void MarkWith(bool mark) { mark_ = mark; }
225
226 // Perform a depth first search and record preorder and postorder
227 // traversal orders.
228 virtual void Traverse(bool mark,
229 ZoneList<Node*>* preorder,
230 ZoneList<Node*>* postorder) = 0;
231
232 int number() { return number_; }
233 void set_number(int number) { number_ = number; }
234
235 // Functions used by data-flow analyses.
236 virtual void InitializeReachingDefinitions(int definition_count,
237 List<BitVector*>* variables,
238 WorkList<Node>* worklist,
239 bool mark);
240 virtual void ComputeRDOut(BitVector* result) = 0;
241 virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark) = 0;
242 virtual void PropagateReachingDefinitions(List<BitVector*>* variables);
243
244 // Functions used by dead-code elimination.
245 virtual void MarkCriticalInstructions(
246 List<AstNode*>* stack,
247 ZoneList<Expression*>* body_definitions,
248 int variable_count);
249
250 #ifdef DEBUG
251 void AssignNodeNumber();
252 void PrintReachingDefinitions();
253 virtual void PrintText() = 0;
254 #endif
255
256 protected:
257 ReachingDefinitionsData rd_;
258
259 private:
260 int number_;
261 bool mark_;
262
263 DISALLOW_COPY_AND_ASSIGN(Node);
264 };
265
266
267 // An exit node has a arbitrarily many predecessors and no successors.
268 class ExitNode: public Node {
269 public:
270 ExitNode() : predecessors_(4) {}
271
272 virtual bool IsExitNode() { return true; }
273
274 virtual void AddPredecessor(Node* predecessor) {
275 ASSERT(predecessor != NULL);
276 predecessors_.Add(predecessor);
277 }
278
279 virtual void AddSuccessor(Node* successor) { UNREACHABLE(); }
280
281 virtual void Traverse(bool mark,
282 ZoneList<Node*>* preorder,
283 ZoneList<Node*>* postorder);
284
285 virtual void ComputeRDOut(BitVector* result);
286 virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark);
287
288 #ifdef DEBUG
289 virtual void PrintText();
290 #endif
291
292 private:
293 ZoneList<Node*> predecessors_;
294
295 DISALLOW_COPY_AND_ASSIGN(ExitNode);
296 };
297
298
299 // Block nodes have a single successor and predecessor and a list of
300 // instructions.
301 class BlockNode: public Node {
302 public:
303 BlockNode() : predecessor_(NULL), successor_(NULL), instructions_(4) {}
304
305 static BlockNode* cast(Node* node) {
306 ASSERT(node->IsBlockNode());
307 return reinterpret_cast<BlockNode*>(node);
308 }
309
310 virtual bool IsBlockNode() { return true; }
311
312 bool is_empty() { return instructions_.is_empty(); }
313
314 ZoneList<AstNode*>* instructions() { return &instructions_; }
315
316 virtual void AddPredecessor(Node* predecessor) {
317 ASSERT(predecessor_ == NULL && predecessor != NULL);
318 predecessor_ = predecessor;
319 }
320
321 virtual void AddSuccessor(Node* successor) {
322 ASSERT(successor_ == NULL && successor != NULL);
323 successor_ = successor;
324 }
325
326 void AddInstruction(AstNode* instruction) {
327 instructions_.Add(instruction);
328 }
329
330 virtual void Traverse(bool mark,
331 ZoneList<Node*>* preorder,
332 ZoneList<Node*>* postorder);
333
334 virtual void InitializeReachingDefinitions(int definition_count,
335 List<BitVector*>* variables,
336 WorkList<Node>* worklist,
337 bool mark);
338 virtual void ComputeRDOut(BitVector* result);
339 virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark);
340 virtual void PropagateReachingDefinitions(List<BitVector*>* variables);
341
342 virtual void MarkCriticalInstructions(
343 List<AstNode*>* stack,
344 ZoneList<Expression*>* body_definitions,
345 int variable_count);
346
347 #ifdef DEBUG
348 virtual void PrintText();
349 #endif
350
351 private:
352 Node* predecessor_;
353 Node* successor_;
354 ZoneList<AstNode*> instructions_;
355
356 DISALLOW_COPY_AND_ASSIGN(BlockNode);
357 };
358
359
360 // Branch nodes have a single predecessor and a pair of successors.
361 class BranchNode: public Node {
362 public:
363 BranchNode() : predecessor_(NULL), successor0_(NULL), successor1_(NULL) {}
364
365 virtual bool IsBranchNode() { return true; }
366
367 virtual void AddPredecessor(Node* predecessor) {
368 ASSERT(predecessor_ == NULL && predecessor != NULL);
369 predecessor_ = predecessor;
370 }
371
372 virtual void AddSuccessor(Node* successor) {
373 ASSERT(successor1_ == NULL && successor != NULL);
374 if (successor0_ == NULL) {
375 successor0_ = successor;
376 } else {
377 successor1_ = successor;
378 }
379 }
380
381 virtual void Traverse(bool mark,
382 ZoneList<Node*>* preorder,
383 ZoneList<Node*>* postorder);
384
385 virtual void ComputeRDOut(BitVector* result);
386 virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark);
387
388 #ifdef DEBUG
389 virtual void PrintText();
390 #endif
391
392 private:
393 Node* predecessor_;
394 Node* successor0_;
395 Node* successor1_;
396
397 DISALLOW_COPY_AND_ASSIGN(BranchNode);
398 };
399
400
401 // Join nodes have arbitrarily many predecessors and a single successor.
402 class JoinNode: public Node {
403 public:
404 JoinNode() : predecessors_(2), successor_(NULL) {}
405
406 static JoinNode* cast(Node* node) {
407 ASSERT(node->IsJoinNode());
408 return reinterpret_cast<JoinNode*>(node);
409 }
410
411 virtual bool IsJoinNode() { return true; }
412
413 virtual void AddPredecessor(Node* predecessor) {
414 ASSERT(predecessor != NULL);
415 predecessors_.Add(predecessor);
416 }
417
418 virtual void AddSuccessor(Node* successor) {
419 ASSERT(successor_ == NULL && successor != NULL);
420 successor_ = successor;
421 }
422
423 virtual void Traverse(bool mark,
424 ZoneList<Node*>* preorder,
425 ZoneList<Node*>* postorder);
426
427 virtual void ComputeRDOut(BitVector* result);
428 virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark);
429
430 #ifdef DEBUG
431 virtual void PrintText();
432 #endif
433
434 private:
435 ZoneList<Node*> predecessors_;
436 Node* successor_;
437
438 DISALLOW_COPY_AND_ASSIGN(JoinNode);
439 };
440
441
442 // Flow graphs have a single entry and single exit. The empty flowgraph is
443 // represented by both entry and exit being NULL.
444 class FlowGraph BASE_EMBEDDED {
445 public:
446 static FlowGraph Empty() {
447 FlowGraph graph;
448 graph.entry_ = new BlockNode();
449 graph.exit_ = graph.entry_;
450 return graph;
451 }
452
453 bool is_empty() const {
454 return entry_ == exit_ && BlockNode::cast(entry_)->is_empty();
455 }
456 Node* entry() const { return entry_; }
457 Node* exit() const { return exit_; }
458
459 // Add a single instruction to the end of this flowgraph.
460 void AppendInstruction(AstNode* instruction);
461
462 // Add a single node to the end of this flow graph.
463 void AppendNode(Node* node);
464
465 // Add a flow graph fragment to the end of this one.
466 void AppendGraph(FlowGraph* graph);
467
468 // Concatenate an if-then-else flow-graph to this one. Control is split
469 // and merged, so the graph remains single-entry, single-exit.
470 void Split(BranchNode* branch,
471 FlowGraph* left,
472 FlowGraph* right,
473 JoinNode* merge);
474
475 // Concatenate a forward loop (e.g., while or for loop) flow-graph to this
476 // one. Control is split by the condition and merged back from the back
477 // edge at end of the body to the beginning of the condition. The single
478 // (free) exit of the result graph is the right (false) arm of the branch
479 // node.
480 void Loop(JoinNode* merge,
481 FlowGraph* condition,
482 BranchNode* branch,
483 FlowGraph* body);
484
485 #ifdef DEBUG
486 void PrintText(FunctionLiteral* fun, ZoneList<Node*>* postorder);
487 #endif
488
489 private:
490 FlowGraph() : entry_(NULL), exit_(NULL) {}
491
492 Node* entry_;
493 Node* exit_;
494 };
495
496
497 // Construct a flow graph from a function literal. Build pre- and postorder
498 // traversal orders as a byproduct.
499 class FlowGraphBuilder: public AstVisitor {
500 public:
501 explicit FlowGraphBuilder(int variable_count)
502 : graph_(FlowGraph::Empty()),
503 global_exit_(NULL),
504 preorder_(4),
505 postorder_(4),
506 variable_count_(variable_count),
507 body_definitions_(4) {
508 }
509
510 void Build(FunctionLiteral* lit);
511
512 FlowGraph* graph() { return &graph_; }
513 ZoneList<Node*>* preorder() { return &preorder_; }
514 ZoneList<Node*>* postorder() { return &postorder_; }
515 ZoneList<Expression*>* body_definitions() { return &body_definitions_; }
516
517 private:
518 ExitNode* global_exit() { return global_exit_; }
519
520 // Helpers to allow tranforming the ast during flow graph construction.
521 void VisitStatements(ZoneList<Statement*>* stmts);
522 Statement* ProcessStatement(Statement* stmt);
523
524 // AST node visit functions.
525 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
526 AST_NODE_LIST(DECLARE_VISIT)
527 #undef DECLARE_VISIT
528
529 FlowGraph graph_;
530 ExitNode* global_exit_;
531 ZoneList<Node*> preorder_;
532 ZoneList<Node*> postorder_;
533
534 // The flow graph builder collects a list of explicit definitions
535 // (assignments and count operations) to stack-allocated variables to use
536 // for reaching definitions analysis. It does not count the implicit
537 // definition at function entry. AST node numbers in the AST are used to
538 // refer into this list.
539 int variable_count_;
540 ZoneList<Expression*> body_definitions_;
541
542 DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder);
543 };
544
545
546 // This class is used to number all expressions in the AST according to 211 // This class is used to number all expressions in the AST according to
547 // their evaluation order (post-order left-to-right traversal). 212 // their evaluation order (post-order left-to-right traversal).
548 class AstLabeler: public AstVisitor { 213 class AstLabeler: public AstVisitor {
549 public: 214 public:
550 AstLabeler() : next_number_(0) {} 215 AstLabeler() : next_number_(0) {}
551 216
552 void Label(CompilationInfo* info); 217 void Label(CompilationInfo* info);
553 218
554 private: 219 private:
555 CompilationInfo* info() { return info_; } 220 CompilationInfo* info() { return info_; }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 328
664 void MarkLiveCode(ZoneList<Node*>* nodes, 329 void MarkLiveCode(ZoneList<Node*>* nodes,
665 ZoneList<Expression*>* body_definitions, 330 ZoneList<Expression*>* body_definitions,
666 int variable_count); 331 int variable_count);
667 332
668 333
669 } } // namespace v8::internal 334 } } // namespace v8::internal
670 335
671 336
672 #endif // V8_DATAFLOW_H_ 337 #endif // V8_DATAFLOW_H_
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/data-flow.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698