| Index: src/data-flow.h
|
| diff --git a/src/data-flow.h b/src/data-flow.h
|
| index 8046e4228c04090256b8b32011c3f220a26c3917..66df63514ecf811aefe6bf3ab88e346d81c7a6b6 100644
|
| --- a/src/data-flow.h
|
| +++ b/src/data-flow.h
|
| @@ -37,6 +37,9 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| +// Forward declarations.
|
| +class Node;
|
| +
|
| class BitVector: public ZoneObject {
|
| public:
|
| explicit BitVector(int length)
|
| @@ -205,344 +208,6 @@ struct ReachingDefinitionsData BASE_EMBEDDED {
|
| };
|
|
|
|
|
| -// Flow-graph nodes.
|
| -class Node: public ZoneObject {
|
| - public:
|
| - Node() : number_(-1), mark_(false) {}
|
| -
|
| - virtual ~Node() {}
|
| -
|
| - virtual bool IsExitNode() { return false; }
|
| - virtual bool IsBlockNode() { return false; }
|
| - virtual bool IsBranchNode() { 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; }
|
| -
|
| - // 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; }
|
| -
|
| - // Functions used by data-flow analyses.
|
| - virtual void InitializeReachingDefinitions(int definition_count,
|
| - List<BitVector*>* variables,
|
| - WorkList<Node>* worklist,
|
| - bool mark);
|
| - virtual void ComputeRDOut(BitVector* result) = 0;
|
| - virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark) = 0;
|
| - virtual void PropagateReachingDefinitions(List<BitVector*>* variables);
|
| -
|
| - // Functions used by dead-code elimination.
|
| - virtual void MarkCriticalInstructions(
|
| - List<AstNode*>* stack,
|
| - ZoneList<Expression*>* body_definitions,
|
| - int variable_count);
|
| -
|
| -#ifdef DEBUG
|
| - void AssignNodeNumber();
|
| - void PrintReachingDefinitions();
|
| - virtual void PrintText() = 0;
|
| -#endif
|
| -
|
| - protected:
|
| - ReachingDefinitionsData rd_;
|
| -
|
| - private:
|
| - int number_;
|
| - bool mark_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(Node);
|
| -};
|
| -
|
| -
|
| -// An exit node has a arbitrarily many predecessors and no successors.
|
| -class ExitNode: public Node {
|
| - public:
|
| - ExitNode() : predecessors_(4) {}
|
| -
|
| - virtual bool IsExitNode() { return true; }
|
| -
|
| - virtual void AddPredecessor(Node* predecessor) {
|
| - ASSERT(predecessor != NULL);
|
| - predecessors_.Add(predecessor);
|
| - }
|
| -
|
| - virtual void AddSuccessor(Node* successor) { UNREACHABLE(); }
|
| -
|
| - virtual void Traverse(bool mark,
|
| - ZoneList<Node*>* preorder,
|
| - ZoneList<Node*>* postorder);
|
| -
|
| - virtual void ComputeRDOut(BitVector* result);
|
| - virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark);
|
| -
|
| -#ifdef DEBUG
|
| - virtual 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);
|
| - }
|
| -
|
| - virtual bool IsBlockNode() { return true; }
|
| -
|
| - bool is_empty() { return instructions_.is_empty(); }
|
| -
|
| - ZoneList<AstNode*>* instructions() { return &instructions_; }
|
| -
|
| - virtual void AddPredecessor(Node* predecessor) {
|
| - ASSERT(predecessor_ == NULL && predecessor != NULL);
|
| - predecessor_ = predecessor;
|
| - }
|
| -
|
| - virtual void AddSuccessor(Node* successor) {
|
| - ASSERT(successor_ == NULL && successor != NULL);
|
| - successor_ = successor;
|
| - }
|
| -
|
| - void AddInstruction(AstNode* instruction) {
|
| - instructions_.Add(instruction);
|
| - }
|
| -
|
| - virtual void Traverse(bool mark,
|
| - ZoneList<Node*>* preorder,
|
| - ZoneList<Node*>* postorder);
|
| -
|
| - virtual void InitializeReachingDefinitions(int definition_count,
|
| - List<BitVector*>* variables,
|
| - WorkList<Node>* worklist,
|
| - bool mark);
|
| - virtual void ComputeRDOut(BitVector* result);
|
| - virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark);
|
| - virtual void PropagateReachingDefinitions(List<BitVector*>* variables);
|
| -
|
| - virtual void MarkCriticalInstructions(
|
| - List<AstNode*>* stack,
|
| - ZoneList<Expression*>* body_definitions,
|
| - int variable_count);
|
| -
|
| -#ifdef DEBUG
|
| - virtual 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) {}
|
| -
|
| - virtual bool IsBranchNode() { return true; }
|
| -
|
| - virtual void AddPredecessor(Node* predecessor) {
|
| - ASSERT(predecessor_ == NULL && predecessor != NULL);
|
| - predecessor_ = predecessor;
|
| - }
|
| -
|
| - virtual void AddSuccessor(Node* successor) {
|
| - ASSERT(successor1_ == NULL && successor != NULL);
|
| - if (successor0_ == NULL) {
|
| - successor0_ = successor;
|
| - } else {
|
| - successor1_ = successor;
|
| - }
|
| - }
|
| -
|
| - virtual void Traverse(bool mark,
|
| - ZoneList<Node*>* preorder,
|
| - ZoneList<Node*>* postorder);
|
| -
|
| - virtual void ComputeRDOut(BitVector* result);
|
| - virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark);
|
| -
|
| -#ifdef DEBUG
|
| - virtual 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);
|
| - }
|
| -
|
| - virtual bool IsJoinNode() { return true; }
|
| -
|
| - virtual void AddPredecessor(Node* predecessor) {
|
| - ASSERT(predecessor != NULL);
|
| - predecessors_.Add(predecessor);
|
| - }
|
| -
|
| - virtual void AddSuccessor(Node* successor) {
|
| - ASSERT(successor_ == NULL && successor != NULL);
|
| - successor_ = successor;
|
| - }
|
| -
|
| - virtual void Traverse(bool mark,
|
| - ZoneList<Node*>* preorder,
|
| - ZoneList<Node*>* postorder);
|
| -
|
| - virtual void ComputeRDOut(BitVector* result);
|
| - virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark);
|
| -
|
| -#ifdef DEBUG
|
| - virtual void PrintText();
|
| -#endif
|
| -
|
| - private:
|
| - ZoneList<Node*> predecessors_;
|
| - Node* successor_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(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:
|
| - static FlowGraph Empty() {
|
| - FlowGraph graph;
|
| - graph.entry_ = new BlockNode();
|
| - graph.exit_ = graph.entry_;
|
| - return graph;
|
| - }
|
| -
|
| - bool is_empty() const {
|
| - return entry_ == exit_ && BlockNode::cast(entry_)->is_empty();
|
| - }
|
| - Node* entry() const { return entry_; }
|
| - Node* exit() const { return exit_; }
|
| -
|
| - // Add a single instruction to the end of this flowgraph.
|
| - void AppendInstruction(AstNode* instruction);
|
| -
|
| - // Add a single node to the end of this flow graph.
|
| - void AppendNode(Node* node);
|
| -
|
| - // Add a flow graph fragment to the end of this one.
|
| - void AppendGraph(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.
|
| - 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(FunctionLiteral* fun, ZoneList<Node*>* postorder);
|
| -#endif
|
| -
|
| - private:
|
| - FlowGraph() : entry_(NULL), exit_(NULL) {}
|
| -
|
| - Node* entry_;
|
| - Node* exit_;
|
| -};
|
| -
|
| -
|
| -// Construct a flow graph from a function literal. Build pre- and postorder
|
| -// traversal orders as a byproduct.
|
| -class FlowGraphBuilder: public AstVisitor {
|
| - public:
|
| - explicit FlowGraphBuilder(int variable_count)
|
| - : graph_(FlowGraph::Empty()),
|
| - global_exit_(NULL),
|
| - preorder_(4),
|
| - postorder_(4),
|
| - variable_count_(variable_count),
|
| - body_definitions_(4) {
|
| - }
|
| -
|
| - void Build(FunctionLiteral* lit);
|
| -
|
| - FlowGraph* graph() { return &graph_; }
|
| - ZoneList<Node*>* preorder() { return &preorder_; }
|
| - ZoneList<Node*>* postorder() { return &postorder_; }
|
| - ZoneList<Expression*>* body_definitions() { return &body_definitions_; }
|
| -
|
| - private:
|
| - ExitNode* global_exit() { return global_exit_; }
|
| -
|
| - // Helpers to allow tranforming the ast during flow graph construction.
|
| - void VisitStatements(ZoneList<Statement*>* stmts);
|
| - Statement* ProcessStatement(Statement* stmt);
|
| -
|
| - // 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_;
|
| -
|
| - // The flow graph builder collects a list of explicit definitions
|
| - // (assignments and count operations) to stack-allocated variables to use
|
| - // for reaching definitions analysis. It does not count the implicit
|
| - // definition at function entry. AST node numbers in the AST are used to
|
| - // refer into this list.
|
| - int variable_count_;
|
| - ZoneList<Expression*> body_definitions_;
|
| -
|
| - 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 {
|
|
|