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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/conversions-inl.h ('k') | src/data-flow.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_DATAFLOW_H_ 28 #ifndef V8_DATAFLOW_H_
29 #define V8_DATAFLOW_H_ 29 #define V8_DATAFLOW_H_
30 30
31 #include "v8.h"
32
31 #include "ast.h" 33 #include "ast.h"
32 #include "compiler.h" 34 #include "compiler.h"
35 #include "zone-inl.h"
33 36
34 namespace v8 { 37 namespace v8 {
35 namespace internal { 38 namespace internal {
36 39
40 class BitVector: public ZoneObject {
41 public:
42 explicit BitVector(int length)
43 : length_(length),
44 data_length_(SizeFor(length)),
45 data_(Zone::NewArray<uint32_t>(data_length_)) {
46 ASSERT(length > 0);
47 Clear();
48 }
49
50 BitVector(const BitVector& other)
51 : length_(other.length()),
52 data_length_(SizeFor(length_)),
53 data_(Zone::NewArray<uint32_t>(data_length_)) {
54 CopyFrom(other);
55 }
56
57 static int SizeFor(int length) {
58 return 1 + ((length - 1) / 32);
59 }
60
61 BitVector& operator=(const BitVector& rhs) {
62 if (this != &rhs) CopyFrom(rhs);
63 return *this;
64 }
65
66 void CopyFrom(const BitVector& other) {
67 ASSERT(other.length() == length());
68 for (int i = 0; i < data_length_; i++) {
69 data_[i] = other.data_[i];
70 }
71 }
72
73 bool Contains(int i) {
74 ASSERT(i >= 0 && i < length());
75 uint32_t block = data_[i / 32];
76 return (block & (1U << (i % 32))) != 0;
77 }
78
79 void Add(int i) {
80 ASSERT(i >= 0 && i < length());
81 data_[i / 32] |= (1U << (i % 32));
82 }
83
84 void Remove(int i) {
85 ASSERT(i >= 0 && i < length());
86 data_[i / 32] &= ~(1U << (i % 32));
87 }
88
89 void Union(const BitVector& other) {
90 ASSERT(other.length() == length());
91 for (int i = 0; i < data_length_; i++) {
92 data_[i] |= other.data_[i];
93 }
94 }
95
96 void Intersect(const BitVector& other) {
97 ASSERT(other.length() == length());
98 for (int i = 0; i < data_length_; i++) {
99 data_[i] &= other.data_[i];
100 }
101 }
102
103 void Clear() {
104 for (int i = 0; i < data_length_; i++) {
105 data_[i] = 0;
106 }
107 }
108
109 bool IsEmpty() const {
110 for (int i = 0; i < data_length_; i++) {
111 if (data_[i] != 0) return false;
112 }
113 return true;
114 }
115
116 int length() const { return length_; }
117
118 private:
119 int length_;
120 int data_length_;
121 uint32_t* data_;
122 };
123
124
125 // Forward declarations of Node types.
126 class Node;
127 class BranchNode;
128 class JoinNode;
129
130 // Flow graphs have a single entry and single exit. The empty flowgraph is
131 // represented by both entry and exit being NULL.
132 class FlowGraph BASE_EMBEDDED {
133 public:
134 FlowGraph() : entry_(NULL), exit_(NULL) {}
135
136 static FlowGraph Empty() { return FlowGraph(); }
137
138 bool is_empty() const { return entry_ == NULL; }
139 Node* entry() const { return entry_; }
140 Node* exit() const { return exit_; }
141
142 // Add a single instruction to the end of this flowgraph.
143 void AppendInstruction(AstNode* instruction);
144
145 // Add a single node to the end of this flow graph.
146 void AppendNode(Node* node);
147
148 // Add a flow graph fragment to the end of this one.
149 void AppendGraph(FlowGraph* graph);
150
151 // Concatenate an if-then-else flow-graph to this one. Control is split
152 // and merged, so the graph remains single-entry, single-exit.
153 void Split(BranchNode* branch,
154 FlowGraph* left,
155 FlowGraph* right,
156 JoinNode* merge);
157
158 // Concatenate a forward loop (e.g., while or for loop) flow-graph to this
159 // one. Control is split by the condition and merged back from the back
160 // edge at end of the body to the beginning of the condition. The single
161 // (free) exit of the result graph is the right (false) arm of the branch
162 // node.
163 void Loop(JoinNode* merge,
164 FlowGraph* condition,
165 BranchNode* branch,
166 FlowGraph* body);
167
168 #ifdef DEBUG
169 void PrintText(ZoneList<Node*>* postorder);
170 #endif
171
172 private:
173 Node* entry_;
174 Node* exit_;
175 };
176
177
178 // Flow-graph nodes.
179 class Node: public ZoneObject {
180 public:
181 Node() : number_(-1), mark_(false) {}
182
183 virtual ~Node() {}
184
185 virtual bool IsBlockNode() { return false; }
186 virtual bool IsJoinNode() { return false; }
187
188 virtual void AddPredecessor(Node* predecessor) = 0;
189 virtual void AddSuccessor(Node* successor) = 0;
190
191 bool IsMarkedWith(bool mark) { return mark_ == mark; }
192 void MarkWith(bool mark) { mark_ = mark; }
193
194 // Perform a depth first search and record preorder and postorder
195 // traversal orders.
196 virtual void Traverse(bool mark,
197 ZoneList<Node*>* preorder,
198 ZoneList<Node*>* postorder) = 0;
199
200 int number() { return number_; }
201 void set_number(int number) { number_ = number; }
202
203 #ifdef DEBUG
204 virtual void AssignNumbers();
205 virtual void PrintText() = 0;
206 #endif
207
208 private:
209 int number_;
210 bool mark_;
211
212 DISALLOW_COPY_AND_ASSIGN(Node);
213 };
214
215
216 // An entry node has no predecessors and a single successor.
217 class EntryNode: public Node {
218 public:
219 EntryNode() : successor_(NULL) {}
220
221 void AddPredecessor(Node* predecessor) { UNREACHABLE(); }
222
223 void AddSuccessor(Node* successor) {
224 ASSERT(successor_ == NULL && successor != NULL);
225 successor_ = successor;
226 }
227
228 void Traverse(bool mark,
229 ZoneList<Node*>* preorder,
230 ZoneList<Node*>* postorder);
231
232 #ifdef DEBUG
233 void PrintText();
234 #endif
235
236 private:
237 Node* successor_;
238
239 DISALLOW_COPY_AND_ASSIGN(EntryNode);
240 };
241
242
243 // An exit node has a arbitrarily many predecessors and no successors.
244 class ExitNode: public Node {
245 public:
246 ExitNode() : predecessors_(4) {}
247
248 void AddPredecessor(Node* predecessor) {
249 ASSERT(predecessor != NULL);
250 predecessors_.Add(predecessor);
251 }
252
253 void AddSuccessor(Node* successor) { /* Do nothing. */ }
254
255 void Traverse(bool mark,
256 ZoneList<Node*>* preorder,
257 ZoneList<Node*>* postorder);
258
259 #ifdef DEBUG
260 void PrintText();
261 #endif
262
263 private:
264 ZoneList<Node*> predecessors_;
265
266 DISALLOW_COPY_AND_ASSIGN(ExitNode);
267 };
268
269
270 // Block nodes have a single successor and predecessor and a list of
271 // instructions.
272 class BlockNode: public Node {
273 public:
274 BlockNode() : predecessor_(NULL), successor_(NULL), instructions_(4) {}
275
276 static BlockNode* cast(Node* node) {
277 ASSERT(node->IsBlockNode());
278 return reinterpret_cast<BlockNode*>(node);
279 }
280
281 bool IsBlockNode() { return true; }
282
283 void AddPredecessor(Node* predecessor) {
284 ASSERT(predecessor_ == NULL && predecessor != NULL);
285 predecessor_ = predecessor;
286 }
287
288 void AddSuccessor(Node* successor) {
289 ASSERT(successor_ == NULL && successor != NULL);
290 successor_ = successor;
291 }
292
293 void AddInstruction(AstNode* instruction) {
294 instructions_.Add(instruction);
295 }
296
297 void Traverse(bool mark,
298 ZoneList<Node*>* preorder,
299 ZoneList<Node*>* postorder);
300
301 #ifdef DEBUG
302 void AssignNumbers();
303 void PrintText();
304 #endif
305
306 private:
307 Node* predecessor_;
308 Node* successor_;
309 ZoneList<AstNode*> instructions_;
310
311 DISALLOW_COPY_AND_ASSIGN(BlockNode);
312 };
313
314
315 // Branch nodes have a single predecessor and a pair of successors.
316 class BranchNode: public Node {
317 public:
318 BranchNode() : predecessor_(NULL), successor0_(NULL), successor1_(NULL) {}
319
320 void AddPredecessor(Node* predecessor) {
321 ASSERT(predecessor_ == NULL && predecessor != NULL);
322 predecessor_ = predecessor;
323 }
324
325 void AddSuccessor(Node* successor) {
326 ASSERT(successor1_ == NULL && successor != NULL);
327 if (successor0_ == NULL) {
328 successor0_ = successor;
329 } else {
330 successor1_ = successor;
331 }
332 }
333
334 void Traverse(bool mark,
335 ZoneList<Node*>* preorder,
336 ZoneList<Node*>* postorder);
337
338 #ifdef DEBUG
339 void PrintText();
340 #endif
341
342 private:
343 Node* predecessor_;
344 Node* successor0_;
345 Node* successor1_;
346
347 DISALLOW_COPY_AND_ASSIGN(BranchNode);
348 };
349
350
351 // Join nodes have arbitrarily many predecessors and a single successor.
352 class JoinNode: public Node {
353 public:
354 JoinNode() : predecessors_(2), successor_(NULL) {}
355
356 static JoinNode* cast(Node* node) {
357 ASSERT(node->IsJoinNode());
358 return reinterpret_cast<JoinNode*>(node);
359 }
360
361 bool IsJoinNode() { return true; }
362
363 void AddPredecessor(Node* predecessor) {
364 ASSERT(predecessor != NULL);
365 predecessors_.Add(predecessor);
366 }
367
368 void AddSuccessor(Node* successor) {
369 ASSERT(successor_ == NULL && successor != NULL);
370 successor_ = successor;
371 }
372
373 void Traverse(bool mark,
374 ZoneList<Node*>* preorder,
375 ZoneList<Node*>* postorder);
376
377 #ifdef DEBUG
378 void PrintText();
379 #endif
380
381 private:
382 ZoneList<Node*> predecessors_;
383 Node* successor_;
384
385 DISALLOW_COPY_AND_ASSIGN(JoinNode);
386 };
387
388
389 // Construct a flow graph from a function literal. Build pre- and postorder
390 // traversal orders as a byproduct.
391 class FlowGraphBuilder: public AstVisitor {
392 public:
393 FlowGraphBuilder()
394 : global_exit_(NULL),
395 preorder_(4),
396 postorder_(4),
397 definitions_(4) {
398 }
399
400 void Build(FunctionLiteral* lit);
401
402 FlowGraph* graph() { return &graph_; }
403
404 ZoneList<Node*>* postorder() { return &postorder_; }
405
406 private:
407 ExitNode* global_exit() { return global_exit_; }
408
409 // AST node visit functions.
410 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
411 AST_NODE_LIST(DECLARE_VISIT)
412 #undef DECLARE_VISIT
413
414 FlowGraph graph_;
415 ExitNode* global_exit_;
416 ZoneList<Node*> preorder_;
417 ZoneList<Node*> postorder_;
418
419 // The flow graph builder collects a list of definitions (assignments and
420 // count operations) to stack-allocated variables to use for reaching
421 // definitions analysis.
422 ZoneList<AstNode*> definitions_;
423
424 DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder);
425 };
426
427
37 // This class is used to number all expressions in the AST according to 428 // This class is used to number all expressions in the AST according to
38 // their evaluation order (post-order left-to-right traversal). 429 // their evaluation order (post-order left-to-right traversal).
39 class AstLabeler: public AstVisitor { 430 class AstLabeler: public AstVisitor {
40 public: 431 public:
41 AstLabeler() : next_number_(0) {} 432 AstLabeler() : next_number_(0) {}
42 433
43 void Label(CompilationInfo* info); 434 void Label(CompilationInfo* info);
44 435
45 private: 436 private:
46 CompilationInfo* info() { return info_; } 437 CompilationInfo* info() { return info_; }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 VarUseMap live_vars_; 499 VarUseMap live_vars_;
109 500
110 DISALLOW_COPY_AND_ASSIGN(LivenessAnalyzer); 501 DISALLOW_COPY_AND_ASSIGN(LivenessAnalyzer);
111 }; 502 };
112 503
113 504
114 } } // namespace v8::internal 505 } } // namespace v8::internal
115 506
116 507
117 #endif // V8_DATAFLOW_H_ 508 #endif // V8_DATAFLOW_H_
OLDNEW
« 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