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

Unified Diff: src/data-flow.h

Issue 844006: Merge changes up to V8 version 2.1.3 into the partial snapshots (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/conversions-inl.h ('k') | src/data-flow.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/data-flow.h
===================================================================
--- src/data-flow.h (revision 3964)
+++ src/data-flow.h (working copy)
@@ -28,12 +28,403 @@
#ifndef V8_DATAFLOW_H_
#define V8_DATAFLOW_H_
+#include "v8.h"
+
#include "ast.h"
#include "compiler.h"
+#include "zone-inl.h"
namespace v8 {
namespace internal {
+class BitVector: public ZoneObject {
+ public:
+ explicit BitVector(int length)
+ : length_(length),
+ data_length_(SizeFor(length)),
+ data_(Zone::NewArray<uint32_t>(data_length_)) {
+ ASSERT(length > 0);
+ Clear();
+ }
+
+ BitVector(const BitVector& other)
+ : length_(other.length()),
+ data_length_(SizeFor(length_)),
+ data_(Zone::NewArray<uint32_t>(data_length_)) {
+ CopyFrom(other);
+ }
+
+ static int SizeFor(int length) {
+ return 1 + ((length - 1) / 32);
+ }
+
+ BitVector& operator=(const BitVector& rhs) {
+ if (this != &rhs) CopyFrom(rhs);
+ return *this;
+ }
+
+ void CopyFrom(const BitVector& other) {
+ ASSERT(other.length() == length());
+ for (int i = 0; i < data_length_; i++) {
+ data_[i] = other.data_[i];
+ }
+ }
+
+ bool Contains(int i) {
+ ASSERT(i >= 0 && i < length());
+ uint32_t block = data_[i / 32];
+ return (block & (1U << (i % 32))) != 0;
+ }
+
+ void Add(int i) {
+ ASSERT(i >= 0 && i < length());
+ data_[i / 32] |= (1U << (i % 32));
+ }
+
+ void Remove(int i) {
+ ASSERT(i >= 0 && i < length());
+ data_[i / 32] &= ~(1U << (i % 32));
+ }
+
+ void Union(const BitVector& other) {
+ ASSERT(other.length() == length());
+ for (int i = 0; i < data_length_; i++) {
+ data_[i] |= other.data_[i];
+ }
+ }
+
+ void Intersect(const BitVector& other) {
+ ASSERT(other.length() == length());
+ for (int i = 0; i < data_length_; i++) {
+ data_[i] &= other.data_[i];
+ }
+ }
+
+ void Clear() {
+ for (int i = 0; i < data_length_; i++) {
+ data_[i] = 0;
+ }
+ }
+
+ bool IsEmpty() const {
+ for (int i = 0; i < data_length_; i++) {
+ if (data_[i] != 0) return false;
+ }
+ return true;
+ }
+
+ int length() const { return length_; }
+
+ private:
+ int length_;
+ int data_length_;
+ uint32_t* data_;
+};
+
+
+// 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 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(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; }
+
+ // 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),
+ definitions_(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_;
+
+ // The flow graph builder collects a list of definitions (assignments and
+ // count operations) to stack-allocated variables to use for reaching
+ // definitions analysis.
+ ZoneList<AstNode*> 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 {
« no previous file with comments | « src/conversions-inl.h ('k') | src/data-flow.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698