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

Unified Diff: src/data-flow.h

Issue 660449: Initial implementation of an edge-labeled instruction flow graph. (Closed)
Patch Set: Remove unused depth-first search function. Created 10 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler.cc ('k') | src/data-flow.cc » ('j') | src/data-flow.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/data-flow.h
diff --git a/src/data-flow.h b/src/data-flow.h
index f6767e0a462f475365b4fc930408ca35bbfa81c0..905256e6faf9a00c47746dd96aa5de1f09a23a13 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -95,6 +95,299 @@ class BitVector {
};
+// Forward declarations of Node types.
+class Node;
+class BranchNode;
+class JoinNode;
+
+// Flow graphs have a single entry and single exit. The empty flowgraph is
+// represented by both entry and exit being NULL.
+class FlowGraph BASE_EMBEDDED {
+ public:
+ FlowGraph() : entry_(NULL), exit_(NULL) {}
+
+ static FlowGraph Empty() { return FlowGraph(); }
+
+ bool is_empty() const { return entry_ == NULL; }
+ Node* entry() const { return entry_; }
+ Node* exit() const { return exit_; }
+
+ // Add a single instruction to the end of this flowgraph.
+ void Append(AstNode* instruction);
fschneider 2010/03/08 12:14:27 I'm not sure if overloading the name Append helps
+
+ // Add a single node to the end of this flow graph.
+ void Append(Node* node);
+
+ // Add a flow graph fragment to the end of this one.
+ void Append(FlowGraph* graph);
+
+ // Concatenate an if-then-else flow-graph to this one. Control is split
+ // and merged, so the graph remains single-entry, single-exit.
fschneider 2010/03/08 12:14:27 Maybe mentions that left is always the true-branch
+ void Split(BranchNode* branch,
+ FlowGraph* left,
+ FlowGraph* right,
+ JoinNode* merge);
+
+ // Concatenate a forward loop (e.g., while or for loop) flow-graph to this
+ // one. Control is split by the condition and merged back from the back
+ // edge at end of the body to the beginning of the condition. The single
+ // (free) exit of the result graph is the right (false) arm of the branch
+ // node.
+ void Loop(JoinNode* merge,
+ FlowGraph* condition,
+ BranchNode* branch,
+ FlowGraph* body);
+
+#ifdef DEBUG
+ void PrintText(ZoneList<Node*>* postorder);
+#endif
+
+ private:
+ Node* entry_;
+ Node* exit_;
+};
+
+
+// Flow-graph nodes.
+class Node: public ZoneObject {
+ public:
+ Node() : number_(-1), mark_(false) {}
+
+ virtual ~Node() {}
+
+ virtual bool IsBlockNode() { return false; }
+ virtual bool IsJoinNode() { return false; }
+
+ virtual void AddPredecessor(Node* predecessor) = 0;
+ virtual void AddSuccessor(Node* successor) = 0;
+
+ bool IsMarkedWith(bool mark) { return mark_ == mark; }
+ void MarkWith(bool mark) { mark_ = mark; }
fschneider 2010/03/08 12:14:27 Name this functions consistently with other access
+
+ // Perform a depth first search and record preorder and postorder
+ // traversal orders.
+ virtual void Traverse(bool mark,
+ ZoneList<Node*>* preorder,
+ ZoneList<Node*>* postorder) = 0;
+
+ int number() { return number_; }
+ void set_number(int number) { number_ = number; }
+
+#ifdef DEBUG
+ virtual void AssignNumbers();
+ virtual void PrintText() = 0;
+#endif
+
+ private:
+ int number_;
+ bool mark_;
+
+ DISALLOW_COPY_AND_ASSIGN(Node);
+};
+
+
+// An entry node has no predecessors and a single successor.
+class EntryNode: public Node {
+ public:
+ EntryNode() : successor_(NULL) {}
+
+ void AddPredecessor(Node* predecessor) { UNREACHABLE(); }
+
+ void AddSuccessor(Node* successor) {
+ ASSERT(successor_ == NULL && successor != NULL);
+ successor_ = successor;
+ }
+
+ void Traverse(bool mark,
+ ZoneList<Node*>* preorder,
+ ZoneList<Node*>* postorder);
+
+#ifdef DEBUG
+ void PrintText();
+#endif
+
+ private:
+ Node* successor_;
+
+ DISALLOW_COPY_AND_ASSIGN(EntryNode);
+};
+
+
+// An exit node has a arbitrarily many predecessors and no successors.
+class ExitNode: public Node {
+ public:
+ ExitNode() : predecessors_(4) {}
+
+ void AddPredecessor(Node* predecessor) {
+ ASSERT(predecessor != NULL);
+ predecessors_.Add(predecessor);
+ }
+
+ void AddSuccessor(Node* successor) { /* Do nothing. */ }
+
+ void Traverse(bool mark,
+ ZoneList<Node*>* preorder,
+ ZoneList<Node*>* postorder);
+
+#ifdef DEBUG
+ void PrintText();
+#endif
+
+ private:
+ ZoneList<Node*> predecessors_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExitNode);
+};
+
+
+// Block nodes have a single successor and predecessor and a list of
+// instructions.
+class BlockNode: public Node {
+ public:
+ BlockNode() : predecessor_(NULL), successor_(NULL), instructions_(4) {}
+
+ static BlockNode* cast(Node* node) {
+ ASSERT(node->IsBlockNode());
+ return reinterpret_cast<BlockNode*>(node);
+ }
+
+ bool IsBlockNode() { return true; }
+
+ void AddPredecessor(Node* predecessor) {
+ ASSERT(predecessor_ == NULL && predecessor != NULL);
+ predecessor_ = predecessor;
+ }
+
+ void AddSuccessor(Node* successor) {
+ ASSERT(successor_ == NULL && successor != NULL);
+ successor_ = successor;
+ }
+
+ void AddInstruction(AstNode* instruction) {
+ instructions_.Add(instruction);
+ }
+
+ void Traverse(bool mark,
+ ZoneList<Node*>* preorder,
+ ZoneList<Node*>* postorder);
+
+#ifdef DEBUG
+ void AssignNumbers();
+ void PrintText();
+#endif
+
+ private:
+ Node* predecessor_;
+ Node* successor_;
+ ZoneList<AstNode*> instructions_;
+
+ DISALLOW_COPY_AND_ASSIGN(BlockNode);
+};
+
+
+// Branch nodes have a single predecessor and a pair of successors.
+class BranchNode: public Node {
+ public:
+ BranchNode() : predecessor_(NULL), successor0_(NULL), successor1_(NULL) {}
+
+ void AddPredecessor(Node* predecessor) {
+ ASSERT(predecessor_ == NULL && predecessor != NULL);
+ predecessor_ = predecessor;
+ }
+
+ void AddSuccessor(Node* successor) {
+ ASSERT(successor1_ == NULL && successor != NULL);
+ if (successor0_ == NULL) {
+ successor0_ = successor;
+ } else {
+ successor1_ = successor;
+ }
+ }
+
+ void Traverse(bool mark,
+ ZoneList<Node*>* preorder,
+ ZoneList<Node*>* postorder);
+
+#ifdef DEBUG
+ void PrintText();
+#endif
+
+ private:
+ Node* predecessor_;
+ Node* successor0_;
+ Node* successor1_;
+
+ DISALLOW_COPY_AND_ASSIGN(BranchNode);
+};
+
+
+// Join nodes have arbitrarily many predecessors and a single successor.
+class JoinNode: public Node {
+ public:
+ JoinNode() : predecessors_(2), successor_(NULL) {}
+
+ static JoinNode* cast(Node* node) {
+ ASSERT(node->IsJoinNode());
+ return reinterpret_cast<JoinNode*>(node);
+ }
+
+ bool IsJoinNode() { return true; }
+
+ void AddPredecessor(Node* predecessor) {
+ ASSERT(predecessor != NULL);
+ predecessors_.Add(predecessor);
+ }
+
+ void AddSuccessor(Node* successor) {
+ ASSERT(successor_ == NULL && successor != NULL);
+ successor_ = successor;
+ }
+
+ void Traverse(bool mark,
+ ZoneList<Node*>* preorder,
+ ZoneList<Node*>* postorder);
+
+#ifdef DEBUG
+ void PrintText();
+#endif
+
+ private:
+ ZoneList<Node*> predecessors_;
+ Node* successor_;
+
+ DISALLOW_COPY_AND_ASSIGN(JoinNode);
+};
+
+
+// Construct a flow graph from a function literal. Build pre- and postorder
+// traversal orders as a byproduct.
+class FlowGraphBuilder: public AstVisitor {
+ public:
+ FlowGraphBuilder() : global_exit_(NULL), preorder_(4), postorder_(4) {}
+
+ void Build(FunctionLiteral* lit);
+
+ FlowGraph* graph() { return &graph_; }
+
+ ZoneList<Node*>* postorder() { return &postorder_; }
+
+ private:
+ ExitNode* global_exit() { return global_exit_; }
+
+ // AST node visit functions.
+#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+ AST_NODE_LIST(DECLARE_VISIT)
+#undef DECLARE_VISIT
+
+ FlowGraph graph_;
+ ExitNode* global_exit_;
+ ZoneList<Node*> preorder_;
+ ZoneList<Node*> postorder_;
+
+ DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder);
+};
+
+
// This class is used to number all expressions in the AST according to
// their evaluation order (post-order left-to-right traversal).
class AstLabeler: public AstVisitor {
« no previous file with comments | « src/compiler.cc ('k') | src/data-flow.cc » ('j') | src/data-flow.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698