| Index: src/data-flow.h
|
| diff --git a/src/data-flow.h b/src/data-flow.h
|
| index ea603ecb6191ce83c85fe7eeda3a46138004aa9f..404b3b337e792606ddc202ad37adebae5613b623 100644
|
| --- a/src/data-flow.h
|
| +++ b/src/data-flow.h
|
| @@ -120,6 +120,13 @@ class BitVector: public ZoneObject {
|
| return true;
|
| }
|
|
|
| + bool Equals(const BitVector& other) {
|
| + for (int i = 0; i < data_length_; i++) {
|
| + if (data_[i] != other.data_[i]) return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| int length() const { return length_; }
|
|
|
| private:
|
| @@ -129,7 +136,51 @@ class BitVector: public ZoneObject {
|
| };
|
|
|
|
|
| -class ReachingDefinitionsData BASE_EMBEDDED {
|
| +// Simple fixed-capacity list-based worklist (managed as a queue) of
|
| +// pointers to T.
|
| +template<typename T>
|
| +class WorkList BASE_EMBEDDED {
|
| + public:
|
| + // The worklist cannot grow bigger than size. We keep one item empty to
|
| + // distinguish between empty and full.
|
| + WorkList(int size)
|
| + : capacity_(size + 1), head_(0), tail_(0), queue_(capacity_) {
|
| + for (int i = 0; i < capacity_; i++) queue_.Add(NULL);
|
| + }
|
| +
|
| + bool is_empty() { return head_ == tail_; }
|
| +
|
| + bool is_full() {
|
| + // The worklist is full if head is at 0 and tail is at capacity - 1:
|
| + // head == 0 && tail == capacity-1 ==> tail - head == capacity - 1
|
| + // or if tail is immediately to the left of head:
|
| + // tail+1 == head ==> tail - head == -1
|
| + int diff = tail_ - head_;
|
| + return (diff == -1 || diff == capacity_ - 1);
|
| + }
|
| +
|
| + void Insert(T* item) {
|
| + ASSERT(!is_full());
|
| + queue_[tail_++] = item;
|
| + if (tail_ == capacity_) tail_ = 0;
|
| + }
|
| +
|
| + T* Remove() {
|
| + ASSERT(!is_empty());
|
| + T* item = queue_[head_++];
|
| + if (head_ == capacity_) head_ = 0;
|
| + return item;
|
| + }
|
| +
|
| + private:
|
| + int capacity_; // Including one empty slot.
|
| + int head_; // Where the first item is.
|
| + int tail_; // Where the next inserted item will go.
|
| + List<T*> queue_;
|
| +};
|
| +
|
| +
|
| +struct ReachingDefinitionsData BASE_EMBEDDED {
|
| public:
|
| ReachingDefinitionsData() : rd_in_(NULL), kill_(NULL), gen_(NULL) {}
|
|
|
| @@ -179,7 +230,11 @@ class Node: public ZoneObject {
|
|
|
| // Functions used by data-flow analyses.
|
| virtual void InitializeReachingDefinitions(int definition_count,
|
| - List<BitVector*>* variables);
|
| + List<BitVector*>* variables,
|
| + WorkList<Node>* worklist,
|
| + bool mark);
|
| + virtual void ComputeRDOut(BitVector* result) = 0;
|
| + virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark) = 0;
|
|
|
| #ifdef DEBUG
|
| void AssignNodeNumber();
|
| @@ -216,6 +271,9 @@ class ExitNode: public Node {
|
| ZoneList<Node*>* preorder,
|
| ZoneList<Node*>* postorder);
|
|
|
| + void ComputeRDOut(BitVector* result);
|
| + void UpdateRDIn(WorkList<Node>* worklist, bool mark);
|
| +
|
| #ifdef DEBUG
|
| void PrintText();
|
| #endif
|
| @@ -261,7 +319,11 @@ class BlockNode: public Node {
|
| ZoneList<Node*>* postorder);
|
|
|
| void InitializeReachingDefinitions(int definition_count,
|
| - List<BitVector*>* variables);
|
| + List<BitVector*>* variables,
|
| + WorkList<Node>* worklist,
|
| + bool mark);
|
| + void ComputeRDOut(BitVector* result);
|
| + void UpdateRDIn(WorkList<Node>* worklist, bool mark);
|
|
|
| #ifdef DEBUG
|
| void PrintText();
|
| @@ -301,6 +363,9 @@ class BranchNode: public Node {
|
| ZoneList<Node*>* preorder,
|
| ZoneList<Node*>* postorder);
|
|
|
| + void ComputeRDOut(BitVector* result);
|
| + void UpdateRDIn(WorkList<Node>* worklist, bool mark);
|
| +
|
| #ifdef DEBUG
|
| void PrintText();
|
| #endif
|
| @@ -340,6 +405,9 @@ class JoinNode: public Node {
|
| ZoneList<Node*>* preorder,
|
| ZoneList<Node*>* postorder);
|
|
|
| + void ComputeRDOut(BitVector* result);
|
| + void UpdateRDIn(WorkList<Node>* worklist, bool mark);
|
| +
|
| #ifdef DEBUG
|
| void PrintText();
|
| #endif
|
|
|