blob: 079da65b4d9aaa9c328799288a3559d6e397cd74 [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:
45 explicit BitVector(int length)
46 : length_(length),
47 data_length_(SizeFor(length)),
48 data_(Zone::NewArray<uint32_t>(data_length_)) {
49 ASSERT(length > 0);
50 Clear();
51 }
52
53 BitVector(const BitVector& other)
54 : length_(other.length()),
55 data_length_(SizeFor(length_)),
56 data_(Zone::NewArray<uint32_t>(data_length_)) {
57 CopyFrom(other);
58 }
59
60 static int SizeFor(int length) {
61 return 1 + ((length - 1) / 32);
62 }
63
64 BitVector& operator=(const BitVector& rhs) {
65 if (this != &rhs) CopyFrom(rhs);
66 return *this;
67 }
68
69 void CopyFrom(const BitVector& other) {
70 ASSERT(other.length() == length());
71 for (int i = 0; i < data_length_; i++) {
72 data_[i] = other.data_[i];
73 }
74 }
75
76 bool Contains(int i) {
77 ASSERT(i >= 0 && i < length());
78 uint32_t block = data_[i / 32];
79 return (block & (1U << (i % 32))) != 0;
80 }
81
82 void Add(int i) {
83 ASSERT(i >= 0 && i < length());
84 data_[i / 32] |= (1U << (i % 32));
85 }
86
87 void Remove(int i) {
88 ASSERT(i >= 0 && i < length());
89 data_[i / 32] &= ~(1U << (i % 32));
90 }
91
92 void Union(const BitVector& other) {
93 ASSERT(other.length() == length());
94 for (int i = 0; i < data_length_; i++) {
95 data_[i] |= other.data_[i];
96 }
97 }
98
99 void Intersect(const BitVector& other) {
100 ASSERT(other.length() == length());
101 for (int i = 0; i < data_length_; i++) {
102 data_[i] &= other.data_[i];
103 }
104 }
105
106 void Subtract(const BitVector& other) {
107 ASSERT(other.length() == length());
108 for (int i = 0; i < data_length_; i++) {
109 data_[i] &= ~other.data_[i];
110 }
111 }
112
113 void Clear() {
114 for (int i = 0; i < data_length_; i++) {
115 data_[i] = 0;
116 }
117 }
118
119 bool IsEmpty() const {
120 for (int i = 0; i < data_length_; i++) {
121 if (data_[i] != 0) return false;
122 }
123 return true;
124 }
125
126 bool Equals(const BitVector& other) {
127 for (int i = 0; i < data_length_; i++) {
128 if (data_[i] != other.data_[i]) return false;
129 }
130 return true;
131 }
132
133 int length() const { return length_; }
134
135#ifdef DEBUG
136 void Print();
137#endif
138
139 private:
140 int length_;
141 int data_length_;
142 uint32_t* data_;
143};
144
145
146// Simple fixed-capacity list-based worklist (managed as a queue) of
147// pointers to T.
148template<typename T>
149class WorkList BASE_EMBEDDED {
150 public:
151 // The worklist cannot grow bigger than size. We keep one item empty to
152 // distinguish between empty and full.
153 explicit WorkList(int size)
154 : capacity_(size + 1), head_(0), tail_(0), queue_(capacity_) {
155 for (int i = 0; i < capacity_; i++) queue_.Add(NULL);
156 }
157
158 bool is_empty() { return head_ == tail_; }
159
160 bool is_full() {
161 // The worklist is full if head is at 0 and tail is at capacity - 1:
162 // head == 0 && tail == capacity-1 ==> tail - head == capacity - 1
163 // or if tail is immediately to the left of head:
164 // tail+1 == head ==> tail - head == -1
165 int diff = tail_ - head_;
166 return (diff == -1 || diff == capacity_ - 1);
167 }
168
169 void Insert(T* item) {
170 ASSERT(!is_full());
171 queue_[tail_++] = item;
172 if (tail_ == capacity_) tail_ = 0;
173 }
174
175 T* Remove() {
176 ASSERT(!is_empty());
177 T* item = queue_[head_++];
178 if (head_ == capacity_) head_ = 0;
179 return item;
180 }
181
182 private:
183 int capacity_; // Including one empty slot.
184 int head_; // Where the first item is.
185 int tail_; // Where the next inserted item will go.
186 List<T*> queue_;
187};
188
189
190struct ReachingDefinitionsData BASE_EMBEDDED {
191 public:
192 ReachingDefinitionsData() : rd_in_(NULL), kill_(NULL), gen_(NULL) {}
193
194 void Initialize(int definition_count) {
195 rd_in_ = new BitVector(definition_count);
196 kill_ = new BitVector(definition_count);
197 gen_ = new BitVector(definition_count);
198 }
199
200 BitVector* rd_in() { return rd_in_; }
201 BitVector* kill() { return kill_; }
202 BitVector* gen() { return gen_; }
203
204 private:
205 BitVector* rd_in_;
206 BitVector* kill_;
207 BitVector* gen_;
208};
209
210
Leon Clarke4515c472010-02-03 11:58:03 +0000211// This class is used to number all expressions in the AST according to
212// their evaluation order (post-order left-to-right traversal).
213class AstLabeler: public AstVisitor {
214 public:
Andrei Popescu31002712010-02-23 13:46:05 +0000215 AstLabeler() : next_number_(0) {}
Leon Clarke4515c472010-02-03 11:58:03 +0000216
Andrei Popescu31002712010-02-23 13:46:05 +0000217 void Label(CompilationInfo* info);
Leon Clarke4515c472010-02-03 11:58:03 +0000218
219 private:
Andrei Popescu31002712010-02-23 13:46:05 +0000220 CompilationInfo* info() { return info_; }
221
Leon Clarke4515c472010-02-03 11:58:03 +0000222 void VisitDeclarations(ZoneList<Declaration*>* decls);
223 void VisitStatements(ZoneList<Statement*>* stmts);
224
225 // AST node visit functions.
226#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
227 AST_NODE_LIST(DECLARE_VISIT)
228#undef DECLARE_VISIT
229
230 // Traversal number for labelling AST nodes.
231 int next_number_;
232
Andrei Popescu31002712010-02-23 13:46:05 +0000233 CompilationInfo* info_;
Leon Clarke4515c472010-02-03 11:58:03 +0000234
235 DISALLOW_COPY_AND_ASSIGN(AstLabeler);
236};
237
238
Steve Block6ded16b2010-05-10 14:33:55 +0100239// Computes the set of assigned variables and annotates variables proxies
240// that are trivial sub-expressions and for-loops where the loop variable
241// is guaranteed to be a smi.
242class AssignedVariablesAnalyzer : public AstVisitor {
Andrei Popescu402d9372010-02-26 13:31:12 +0000243 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100244 explicit AssignedVariablesAnalyzer(FunctionLiteral* fun);
Andrei Popescu402d9372010-02-26 13:31:12 +0000245
Steve Block6ded16b2010-05-10 14:33:55 +0100246 void Analyze();
Andrei Popescu402d9372010-02-26 13:31:12 +0000247
248 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100249 Variable* FindSmiLoopVariable(ForStatement* stmt);
Andrei Popescu402d9372010-02-26 13:31:12 +0000250
Steve Block6ded16b2010-05-10 14:33:55 +0100251 int BitIndex(Variable* var);
Andrei Popescu402d9372010-02-26 13:31:12 +0000252
Steve Block6ded16b2010-05-10 14:33:55 +0100253 void RecordAssignedVar(Variable* var);
Andrei Popescu402d9372010-02-26 13:31:12 +0000254
Steve Block6ded16b2010-05-10 14:33:55 +0100255 void MarkIfTrivial(Expression* expr);
Andrei Popescu402d9372010-02-26 13:31:12 +0000256
Steve Block6ded16b2010-05-10 14:33:55 +0100257 // Visits an expression saving the accumulator before, clearing
258 // it before visting and restoring it after visiting.
259 void ProcessExpression(Expression* expr);
Andrei Popescu402d9372010-02-26 13:31:12 +0000260
261 // AST node visit functions.
262#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
263 AST_NODE_LIST(DECLARE_VISIT)
264#undef DECLARE_VISIT
265
Steve Block6ded16b2010-05-10 14:33:55 +0100266 FunctionLiteral* fun_;
Andrei Popescu402d9372010-02-26 13:31:12 +0000267
Steve Block6ded16b2010-05-10 14:33:55 +0100268 // Accumulator for assigned variables set.
269 BitVector av_;
270
271 DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer);
Andrei Popescu402d9372010-02-26 13:31:12 +0000272};
273
274
Leon Clarke4515c472010-02-03 11:58:03 +0000275} } // namespace v8::internal
276
Andrei Popescu402d9372010-02-26 13:31:12 +0000277
Leon Clarke4515c472010-02-03 11:58:03 +0000278#endif // V8_DATAFLOW_H_