blob: 540db162f648def7407fbb9a6d3910122d3c7cf4 [file] [log] [blame]
Leon Clarke4515c472010-02-03 11:58:03 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_DATAFLOW_H_
29#define V8_DATAFLOW_H_
30
Steve Block6ded16b2010-05-10 14:33:55 +010031#include "v8.h"
32
Leon Clarke4515c472010-02-03 11:58:03 +000033#include "ast.h"
Andrei Popescu31002712010-02-23 13:46:05 +000034#include "compiler.h"
Steve Block6ded16b2010-05-10 14:33:55 +010035#include "zone-inl.h"
Leon Clarke4515c472010-02-03 11:58:03 +000036
37namespace v8 {
38namespace internal {
39
Steve Block6ded16b2010-05-10 14:33:55 +010040// Forward declarations.
41class Node;
42
43class BitVector: public ZoneObject {
44 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +010045 BitVector() : length_(0), data_length_(0), data_(NULL) { }
46
47 explicit BitVector(int length) {
48 ExpandTo(length);
Steve Block6ded16b2010-05-10 14:33:55 +010049 }
50
51 BitVector(const BitVector& other)
52 : length_(other.length()),
53 data_length_(SizeFor(length_)),
54 data_(Zone::NewArray<uint32_t>(data_length_)) {
55 CopyFrom(other);
56 }
57
Kristian Monsen80d68ea2010-09-08 11:05:35 +010058 void ExpandTo(int length) {
59 ASSERT(length > 0);
60 length_ = length;
61 data_length_ = SizeFor(length);
62 data_ = Zone::NewArray<uint32_t>(data_length_);
63 Clear();
Steve Block6ded16b2010-05-10 14:33:55 +010064 }
65
66 BitVector& operator=(const BitVector& rhs) {
67 if (this != &rhs) CopyFrom(rhs);
68 return *this;
69 }
70
71 void CopyFrom(const BitVector& other) {
72 ASSERT(other.length() == length());
73 for (int i = 0; i < data_length_; i++) {
74 data_[i] = other.data_[i];
75 }
76 }
77
78 bool Contains(int i) {
79 ASSERT(i >= 0 && i < length());
80 uint32_t block = data_[i / 32];
81 return (block & (1U << (i % 32))) != 0;
82 }
83
84 void Add(int i) {
85 ASSERT(i >= 0 && i < length());
86 data_[i / 32] |= (1U << (i % 32));
87 }
88
89 void Remove(int i) {
90 ASSERT(i >= 0 && i < length());
91 data_[i / 32] &= ~(1U << (i % 32));
92 }
93
94 void Union(const BitVector& other) {
95 ASSERT(other.length() == length());
96 for (int i = 0; i < data_length_; i++) {
97 data_[i] |= other.data_[i];
98 }
99 }
100
101 void Intersect(const BitVector& other) {
102 ASSERT(other.length() == length());
103 for (int i = 0; i < data_length_; i++) {
104 data_[i] &= other.data_[i];
105 }
106 }
107
108 void Subtract(const BitVector& other) {
109 ASSERT(other.length() == length());
110 for (int i = 0; i < data_length_; i++) {
111 data_[i] &= ~other.data_[i];
112 }
113 }
114
115 void Clear() {
116 for (int i = 0; i < data_length_; i++) {
117 data_[i] = 0;
118 }
119 }
120
121 bool IsEmpty() const {
122 for (int i = 0; i < data_length_; i++) {
123 if (data_[i] != 0) return false;
124 }
125 return true;
126 }
127
128 bool Equals(const BitVector& other) {
129 for (int i = 0; i < data_length_; i++) {
130 if (data_[i] != other.data_[i]) return false;
131 }
132 return true;
133 }
134
135 int length() const { return length_; }
136
137#ifdef DEBUG
138 void Print();
139#endif
140
141 private:
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100142 static int SizeFor(int length) {
143 return 1 + ((length - 1) / 32);
144 }
145
Steve Block6ded16b2010-05-10 14:33:55 +0100146 int length_;
147 int data_length_;
148 uint32_t* data_;
149};
150
151
152// Simple fixed-capacity list-based worklist (managed as a queue) of
153// pointers to T.
154template<typename T>
155class WorkList BASE_EMBEDDED {
156 public:
157 // The worklist cannot grow bigger than size. We keep one item empty to
158 // distinguish between empty and full.
159 explicit WorkList(int size)
160 : capacity_(size + 1), head_(0), tail_(0), queue_(capacity_) {
161 for (int i = 0; i < capacity_; i++) queue_.Add(NULL);
162 }
163
164 bool is_empty() { return head_ == tail_; }
165
166 bool is_full() {
167 // The worklist is full if head is at 0 and tail is at capacity - 1:
168 // head == 0 && tail == capacity-1 ==> tail - head == capacity - 1
169 // or if tail is immediately to the left of head:
170 // tail+1 == head ==> tail - head == -1
171 int diff = tail_ - head_;
172 return (diff == -1 || diff == capacity_ - 1);
173 }
174
175 void Insert(T* item) {
176 ASSERT(!is_full());
177 queue_[tail_++] = item;
178 if (tail_ == capacity_) tail_ = 0;
179 }
180
181 T* Remove() {
182 ASSERT(!is_empty());
183 T* item = queue_[head_++];
184 if (head_ == capacity_) head_ = 0;
185 return item;
186 }
187
188 private:
189 int capacity_; // Including one empty slot.
190 int head_; // Where the first item is.
191 int tail_; // Where the next inserted item will go.
192 List<T*> queue_;
193};
194
195
Steve Block6ded16b2010-05-10 14:33:55 +0100196// Computes the set of assigned variables and annotates variables proxies
197// that are trivial sub-expressions and for-loops where the loop variable
198// is guaranteed to be a smi.
199class AssignedVariablesAnalyzer : public AstVisitor {
Andrei Popescu402d9372010-02-26 13:31:12 +0000200 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100201 explicit AssignedVariablesAnalyzer(FunctionLiteral* fun) : fun_(fun) { }
202 bool Analyze();
Andrei Popescu402d9372010-02-26 13:31:12 +0000203
204 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100205 Variable* FindSmiLoopVariable(ForStatement* stmt);
Andrei Popescu402d9372010-02-26 13:31:12 +0000206
Steve Block6ded16b2010-05-10 14:33:55 +0100207 int BitIndex(Variable* var);
Andrei Popescu402d9372010-02-26 13:31:12 +0000208
Steve Block6ded16b2010-05-10 14:33:55 +0100209 void RecordAssignedVar(Variable* var);
Andrei Popescu402d9372010-02-26 13:31:12 +0000210
Steve Block6ded16b2010-05-10 14:33:55 +0100211 void MarkIfTrivial(Expression* expr);
Andrei Popescu402d9372010-02-26 13:31:12 +0000212
Steve Block6ded16b2010-05-10 14:33:55 +0100213 // Visits an expression saving the accumulator before, clearing
214 // it before visting and restoring it after visiting.
215 void ProcessExpression(Expression* expr);
Andrei Popescu402d9372010-02-26 13:31:12 +0000216
217 // AST node visit functions.
218#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
219 AST_NODE_LIST(DECLARE_VISIT)
220#undef DECLARE_VISIT
221
Steve Block6ded16b2010-05-10 14:33:55 +0100222 FunctionLiteral* fun_;
Andrei Popescu402d9372010-02-26 13:31:12 +0000223
Steve Block6ded16b2010-05-10 14:33:55 +0100224 // Accumulator for assigned variables set.
225 BitVector av_;
226
227 DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer);
Andrei Popescu402d9372010-02-26 13:31:12 +0000228};
229
230
Leon Clarke4515c472010-02-03 11:58:03 +0000231} } // namespace v8::internal
232
Andrei Popescu402d9372010-02-26 13:31:12 +0000233
Leon Clarke4515c472010-02-03 11:58:03 +0000234#endif // V8_DATAFLOW_H_