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

Side by Side Diff: src/data-flow.h

Issue 1148007: Merge bleeding_edge from version 2.1.3 up to revision 4205... (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
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 } 93 }
94 } 94 }
95 95
96 void Intersect(const BitVector& other) { 96 void Intersect(const BitVector& other) {
97 ASSERT(other.length() == length()); 97 ASSERT(other.length() == length());
98 for (int i = 0; i < data_length_; i++) { 98 for (int i = 0; i < data_length_; i++) {
99 data_[i] &= other.data_[i]; 99 data_[i] &= other.data_[i];
100 } 100 }
101 } 101 }
102 102
103 void Subtract(const BitVector& other) {
104 ASSERT(other.length() == length());
105 for (int i = 0; i < data_length_; i++) {
106 data_[i] &= ~other.data_[i];
107 }
108 }
109
103 void Clear() { 110 void Clear() {
104 for (int i = 0; i < data_length_; i++) { 111 for (int i = 0; i < data_length_; i++) {
105 data_[i] = 0; 112 data_[i] = 0;
106 } 113 }
107 } 114 }
108 115
109 bool IsEmpty() const { 116 bool IsEmpty() const {
110 for (int i = 0; i < data_length_; i++) { 117 for (int i = 0; i < data_length_; i++) {
111 if (data_[i] != 0) return false; 118 if (data_[i] != 0) return false;
112 } 119 }
113 return true; 120 return true;
114 } 121 }
115 122
123 bool Equals(const BitVector& other) {
124 for (int i = 0; i < data_length_; i++) {
125 if (data_[i] != other.data_[i]) return false;
126 }
127 return true;
128 }
129
116 int length() const { return length_; } 130 int length() const { return length_; }
117 131
132 #ifdef DEBUG
133 void Print();
134 #endif
135
118 private: 136 private:
119 int length_; 137 int length_;
120 int data_length_; 138 int data_length_;
121 uint32_t* data_; 139 uint32_t* data_;
122 }; 140 };
123 141
124 142
125 // Forward declarations of Node types. 143 // Simple fixed-capacity list-based worklist (managed as a queue) of
126 class Node; 144 // pointers to T.
127 class BranchNode; 145 template<typename T>
128 class JoinNode; 146 class WorkList BASE_EMBEDDED {
147 public:
148 // The worklist cannot grow bigger than size. We keep one item empty to
149 // distinguish between empty and full.
150 explicit WorkList(int size)
151 : capacity_(size + 1), head_(0), tail_(0), queue_(capacity_) {
152 for (int i = 0; i < capacity_; i++) queue_.Add(NULL);
153 }
129 154
130 // Flow graphs have a single entry and single exit. The empty flowgraph is 155 bool is_empty() { return head_ == tail_; }
131 // represented by both entry and exit being NULL.
132 class FlowGraph BASE_EMBEDDED {
133 public:
134 FlowGraph() : entry_(NULL), exit_(NULL) {}
135 156
136 static FlowGraph Empty() { return FlowGraph(); } 157 bool is_full() {
158 // The worklist is full if head is at 0 and tail is at capacity - 1:
159 // head == 0 && tail == capacity-1 ==> tail - head == capacity - 1
160 // or if tail is immediately to the left of head:
161 // tail+1 == head ==> tail - head == -1
162 int diff = tail_ - head_;
163 return (diff == -1 || diff == capacity_ - 1);
164 }
137 165
138 bool is_empty() const { return entry_ == NULL; } 166 void Insert(T* item) {
139 Node* entry() const { return entry_; } 167 ASSERT(!is_full());
140 Node* exit() const { return exit_; } 168 queue_[tail_++] = item;
169 if (tail_ == capacity_) tail_ = 0;
170 }
141 171
142 // Add a single instruction to the end of this flowgraph. 172 T* Remove() {
143 void AppendInstruction(AstNode* instruction); 173 ASSERT(!is_empty());
144 174 T* item = queue_[head_++];
145 // Add a single node to the end of this flow graph. 175 if (head_ == capacity_) head_ = 0;
146 void AppendNode(Node* node); 176 return item;
147 177 }
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 178
172 private: 179 private:
173 Node* entry_; 180 int capacity_; // Including one empty slot.
174 Node* exit_; 181 int head_; // Where the first item is.
182 int tail_; // Where the next inserted item will go.
183 List<T*> queue_;
175 }; 184 };
176 185
177 186
187 struct ReachingDefinitionsData BASE_EMBEDDED {
188 public:
189 ReachingDefinitionsData() : rd_in_(NULL), kill_(NULL), gen_(NULL) {}
190
191 void Initialize(int definition_count) {
192 rd_in_ = new BitVector(definition_count);
193 kill_ = new BitVector(definition_count);
194 gen_ = new BitVector(definition_count);
195 }
196
197 BitVector* rd_in() { return rd_in_; }
198 BitVector* kill() { return kill_; }
199 BitVector* gen() { return gen_; }
200
201 private:
202 BitVector* rd_in_;
203 BitVector* kill_;
204 BitVector* gen_;
205 };
206
207
178 // Flow-graph nodes. 208 // Flow-graph nodes.
179 class Node: public ZoneObject { 209 class Node: public ZoneObject {
180 public: 210 public:
181 Node() : number_(-1), mark_(false) {} 211 Node() : number_(-1), mark_(false) {}
182 212
183 virtual ~Node() {} 213 virtual ~Node() {}
184 214
215 virtual bool IsExitNode() { return false; }
185 virtual bool IsBlockNode() { return false; } 216 virtual bool IsBlockNode() { return false; }
217 virtual bool IsBranchNode() { return false; }
186 virtual bool IsJoinNode() { return false; } 218 virtual bool IsJoinNode() { return false; }
187 219
188 virtual void AddPredecessor(Node* predecessor) = 0; 220 virtual void AddPredecessor(Node* predecessor) = 0;
189 virtual void AddSuccessor(Node* successor) = 0; 221 virtual void AddSuccessor(Node* successor) = 0;
190 222
191 bool IsMarkedWith(bool mark) { return mark_ == mark; } 223 bool IsMarkedWith(bool mark) { return mark_ == mark; }
192 void MarkWith(bool mark) { mark_ = mark; } 224 void MarkWith(bool mark) { mark_ = mark; }
193 225
194 // Perform a depth first search and record preorder and postorder 226 // Perform a depth first search and record preorder and postorder
195 // traversal orders. 227 // traversal orders.
196 virtual void Traverse(bool mark, 228 virtual void Traverse(bool mark,
197 ZoneList<Node*>* preorder, 229 ZoneList<Node*>* preorder,
198 ZoneList<Node*>* postorder) = 0; 230 ZoneList<Node*>* postorder) = 0;
199 231
200 int number() { return number_; } 232 int number() { return number_; }
201 void set_number(int number) { number_ = number; } 233 void set_number(int number) { number_ = number; }
202 234
235 // Functions used by data-flow analyses.
236 virtual void InitializeReachingDefinitions(int definition_count,
237 List<BitVector*>* variables,
238 WorkList<Node>* worklist,
239 bool mark);
240 virtual void ComputeRDOut(BitVector* result) = 0;
241 virtual void UpdateRDIn(WorkList<Node>* worklist, bool mark) = 0;
242 virtual void PropagateReachingDefinitions(List<BitVector*>* variables);
243
203 #ifdef DEBUG 244 #ifdef DEBUG
204 virtual void AssignNumbers(); 245 void AssignNodeNumber();
246 void PrintReachingDefinitions();
205 virtual void PrintText() = 0; 247 virtual void PrintText() = 0;
206 #endif 248 #endif
207 249
250 protected:
251 ReachingDefinitionsData rd_;
252
208 private: 253 private:
209 int number_; 254 int number_;
210 bool mark_; 255 bool mark_;
211 256
212 DISALLOW_COPY_AND_ASSIGN(Node); 257 DISALLOW_COPY_AND_ASSIGN(Node);
213 }; 258 };
214 259
215 260
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. 261 // An exit node has a arbitrarily many predecessors and no successors.
244 class ExitNode: public Node { 262 class ExitNode: public Node {
245 public: 263 public:
246 ExitNode() : predecessors_(4) {} 264 ExitNode() : predecessors_(4) {}
247 265
266 bool IsExitNode() { return true; }
267
248 void AddPredecessor(Node* predecessor) { 268 void AddPredecessor(Node* predecessor) {
249 ASSERT(predecessor != NULL); 269 ASSERT(predecessor != NULL);
250 predecessors_.Add(predecessor); 270 predecessors_.Add(predecessor);
251 } 271 }
252 272
253 void AddSuccessor(Node* successor) { /* Do nothing. */ } 273 void AddSuccessor(Node* successor) { UNREACHABLE(); }
254 274
255 void Traverse(bool mark, 275 void Traverse(bool mark,
256 ZoneList<Node*>* preorder, 276 ZoneList<Node*>* preorder,
257 ZoneList<Node*>* postorder); 277 ZoneList<Node*>* postorder);
258 278
279 void ComputeRDOut(BitVector* result);
280 void UpdateRDIn(WorkList<Node>* worklist, bool mark);
281
259 #ifdef DEBUG 282 #ifdef DEBUG
260 void PrintText(); 283 void PrintText();
261 #endif 284 #endif
262 285
263 private: 286 private:
264 ZoneList<Node*> predecessors_; 287 ZoneList<Node*> predecessors_;
265 288
266 DISALLOW_COPY_AND_ASSIGN(ExitNode); 289 DISALLOW_COPY_AND_ASSIGN(ExitNode);
267 }; 290 };
268 291
269 292
270 // Block nodes have a single successor and predecessor and a list of 293 // Block nodes have a single successor and predecessor and a list of
271 // instructions. 294 // instructions.
272 class BlockNode: public Node { 295 class BlockNode: public Node {
273 public: 296 public:
274 BlockNode() : predecessor_(NULL), successor_(NULL), instructions_(4) {} 297 BlockNode() : predecessor_(NULL), successor_(NULL), instructions_(4) {}
275 298
276 static BlockNode* cast(Node* node) { 299 static BlockNode* cast(Node* node) {
277 ASSERT(node->IsBlockNode()); 300 ASSERT(node->IsBlockNode());
278 return reinterpret_cast<BlockNode*>(node); 301 return reinterpret_cast<BlockNode*>(node);
279 } 302 }
280 303
281 bool IsBlockNode() { return true; } 304 bool IsBlockNode() { return true; }
282 305
306 bool is_empty() { return instructions_.is_empty(); }
307
283 void AddPredecessor(Node* predecessor) { 308 void AddPredecessor(Node* predecessor) {
284 ASSERT(predecessor_ == NULL && predecessor != NULL); 309 ASSERT(predecessor_ == NULL && predecessor != NULL);
285 predecessor_ = predecessor; 310 predecessor_ = predecessor;
286 } 311 }
287 312
288 void AddSuccessor(Node* successor) { 313 void AddSuccessor(Node* successor) {
289 ASSERT(successor_ == NULL && successor != NULL); 314 ASSERT(successor_ == NULL && successor != NULL);
290 successor_ = successor; 315 successor_ = successor;
291 } 316 }
292 317
293 void AddInstruction(AstNode* instruction) { 318 void AddInstruction(AstNode* instruction) {
294 instructions_.Add(instruction); 319 instructions_.Add(instruction);
295 } 320 }
296 321
297 void Traverse(bool mark, 322 void Traverse(bool mark,
298 ZoneList<Node*>* preorder, 323 ZoneList<Node*>* preorder,
299 ZoneList<Node*>* postorder); 324 ZoneList<Node*>* postorder);
300 325
326 void InitializeReachingDefinitions(int definition_count,
327 List<BitVector*>* variables,
328 WorkList<Node>* worklist,
329 bool mark);
330 void ComputeRDOut(BitVector* result);
331 void UpdateRDIn(WorkList<Node>* worklist, bool mark);
332 void PropagateReachingDefinitions(List<BitVector*>* variables);
333
301 #ifdef DEBUG 334 #ifdef DEBUG
302 void AssignNumbers();
303 void PrintText(); 335 void PrintText();
304 #endif 336 #endif
305 337
306 private: 338 private:
307 Node* predecessor_; 339 Node* predecessor_;
308 Node* successor_; 340 Node* successor_;
309 ZoneList<AstNode*> instructions_; 341 ZoneList<AstNode*> instructions_;
310 342
311 DISALLOW_COPY_AND_ASSIGN(BlockNode); 343 DISALLOW_COPY_AND_ASSIGN(BlockNode);
312 }; 344 };
313 345
314 346
315 // Branch nodes have a single predecessor and a pair of successors. 347 // Branch nodes have a single predecessor and a pair of successors.
316 class BranchNode: public Node { 348 class BranchNode: public Node {
317 public: 349 public:
318 BranchNode() : predecessor_(NULL), successor0_(NULL), successor1_(NULL) {} 350 BranchNode() : predecessor_(NULL), successor0_(NULL), successor1_(NULL) {}
319 351
352 bool IsBranchNode() { return true; }
353
320 void AddPredecessor(Node* predecessor) { 354 void AddPredecessor(Node* predecessor) {
321 ASSERT(predecessor_ == NULL && predecessor != NULL); 355 ASSERT(predecessor_ == NULL && predecessor != NULL);
322 predecessor_ = predecessor; 356 predecessor_ = predecessor;
323 } 357 }
324 358
325 void AddSuccessor(Node* successor) { 359 void AddSuccessor(Node* successor) {
326 ASSERT(successor1_ == NULL && successor != NULL); 360 ASSERT(successor1_ == NULL && successor != NULL);
327 if (successor0_ == NULL) { 361 if (successor0_ == NULL) {
328 successor0_ = successor; 362 successor0_ = successor;
329 } else { 363 } else {
330 successor1_ = successor; 364 successor1_ = successor;
331 } 365 }
332 } 366 }
333 367
334 void Traverse(bool mark, 368 void Traverse(bool mark,
335 ZoneList<Node*>* preorder, 369 ZoneList<Node*>* preorder,
336 ZoneList<Node*>* postorder); 370 ZoneList<Node*>* postorder);
337 371
372 void ComputeRDOut(BitVector* result);
373 void UpdateRDIn(WorkList<Node>* worklist, bool mark);
374
338 #ifdef DEBUG 375 #ifdef DEBUG
339 void PrintText(); 376 void PrintText();
340 #endif 377 #endif
341 378
342 private: 379 private:
343 Node* predecessor_; 380 Node* predecessor_;
344 Node* successor0_; 381 Node* successor0_;
345 Node* successor1_; 382 Node* successor1_;
346 383
347 DISALLOW_COPY_AND_ASSIGN(BranchNode); 384 DISALLOW_COPY_AND_ASSIGN(BranchNode);
(...skipping 19 matching lines...) Expand all
367 404
368 void AddSuccessor(Node* successor) { 405 void AddSuccessor(Node* successor) {
369 ASSERT(successor_ == NULL && successor != NULL); 406 ASSERT(successor_ == NULL && successor != NULL);
370 successor_ = successor; 407 successor_ = successor;
371 } 408 }
372 409
373 void Traverse(bool mark, 410 void Traverse(bool mark,
374 ZoneList<Node*>* preorder, 411 ZoneList<Node*>* preorder,
375 ZoneList<Node*>* postorder); 412 ZoneList<Node*>* postorder);
376 413
414 void ComputeRDOut(BitVector* result);
415 void UpdateRDIn(WorkList<Node>* worklist, bool mark);
416
377 #ifdef DEBUG 417 #ifdef DEBUG
378 void PrintText(); 418 void PrintText();
379 #endif 419 #endif
380 420
381 private: 421 private:
382 ZoneList<Node*> predecessors_; 422 ZoneList<Node*> predecessors_;
383 Node* successor_; 423 Node* successor_;
384 424
385 DISALLOW_COPY_AND_ASSIGN(JoinNode); 425 DISALLOW_COPY_AND_ASSIGN(JoinNode);
386 }; 426 };
387 427
388 428
429 // Flow graphs have a single entry and single exit. The empty flowgraph is
430 // represented by both entry and exit being NULL.
431 class FlowGraph BASE_EMBEDDED {
432 public:
433 static FlowGraph Empty() {
434 FlowGraph graph;
435 graph.entry_ = new BlockNode();
436 graph.exit_ = graph.entry_;
437 return graph;
438 }
439
440 bool is_empty() const {
441 return entry_ == exit_ && BlockNode::cast(entry_)->is_empty();
442 }
443 Node* entry() const { return entry_; }
444 Node* exit() const { return exit_; }
445
446 // Add a single instruction to the end of this flowgraph.
447 void AppendInstruction(AstNode* instruction);
448
449 // Add a single node to the end of this flow graph.
450 void AppendNode(Node* node);
451
452 // Add a flow graph fragment to the end of this one.
453 void AppendGraph(FlowGraph* graph);
454
455 // Concatenate an if-then-else flow-graph to this one. Control is split
456 // and merged, so the graph remains single-entry, single-exit.
457 void Split(BranchNode* branch,
458 FlowGraph* left,
459 FlowGraph* right,
460 JoinNode* merge);
461
462 // Concatenate a forward loop (e.g., while or for loop) flow-graph to this
463 // one. Control is split by the condition and merged back from the back
464 // edge at end of the body to the beginning of the condition. The single
465 // (free) exit of the result graph is the right (false) arm of the branch
466 // node.
467 void Loop(JoinNode* merge,
468 FlowGraph* condition,
469 BranchNode* branch,
470 FlowGraph* body);
471
472 #ifdef DEBUG
473 void PrintText(FunctionLiteral* fun, ZoneList<Node*>* postorder);
474 #endif
475
476 private:
477 FlowGraph() : entry_(NULL), exit_(NULL) {}
478
479 Node* entry_;
480 Node* exit_;
481 };
482
483
389 // Construct a flow graph from a function literal. Build pre- and postorder 484 // Construct a flow graph from a function literal. Build pre- and postorder
390 // traversal orders as a byproduct. 485 // traversal orders as a byproduct.
391 class FlowGraphBuilder: public AstVisitor { 486 class FlowGraphBuilder: public AstVisitor {
392 public: 487 public:
393 FlowGraphBuilder() 488 FlowGraphBuilder()
394 : global_exit_(NULL), 489 : graph_(FlowGraph::Empty()),
490 global_exit_(NULL),
395 preorder_(4), 491 preorder_(4),
396 postorder_(4), 492 postorder_(4),
397 definitions_(4) { 493 definitions_(4) {}
398 }
399 494
400 void Build(FunctionLiteral* lit); 495 void Build(FunctionLiteral* lit);
401 496
402 FlowGraph* graph() { return &graph_; } 497 FlowGraph* graph() { return &graph_; }
403
404 ZoneList<Node*>* postorder() { return &postorder_; } 498 ZoneList<Node*>* postorder() { return &postorder_; }
499 ZoneList<Expression*>* definitions() { return &definitions_; }
405 500
406 private: 501 private:
407 ExitNode* global_exit() { return global_exit_; } 502 ExitNode* global_exit() { return global_exit_; }
408 503
504 // Helpers to allow tranforming the ast during flow graph construction.
505 void VisitStatements(ZoneList<Statement*>* stmts);
506 Statement* ProcessStatement(Statement* stmt);
507
409 // AST node visit functions. 508 // AST node visit functions.
410 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); 509 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
411 AST_NODE_LIST(DECLARE_VISIT) 510 AST_NODE_LIST(DECLARE_VISIT)
412 #undef DECLARE_VISIT 511 #undef DECLARE_VISIT
413 512
414 FlowGraph graph_; 513 FlowGraph graph_;
415 ExitNode* global_exit_; 514 ExitNode* global_exit_;
416 ZoneList<Node*> preorder_; 515 ZoneList<Node*> preorder_;
417 ZoneList<Node*> postorder_; 516 ZoneList<Node*> postorder_;
418 517
419 // The flow graph builder collects a list of definitions (assignments and 518 // The flow graph builder collects a list of definitions (assignments and
420 // count operations) to stack-allocated variables to use for reaching 519 // count operations) to stack-allocated variables to use for reaching
421 // definitions analysis. 520 // definitions analysis. AST node numbers in the AST are used to refer
422 ZoneList<AstNode*> definitions_; 521 // into this list.
522 ZoneList<Expression*> definitions_;
423 523
424 DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder); 524 DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder);
425 }; 525 };
426 526
427 527
428 // This class is used to number all expressions in the AST according to 528 // This class is used to number all expressions in the AST according to
429 // their evaluation order (post-order left-to-right traversal). 529 // their evaluation order (post-order left-to-right traversal).
430 class AstLabeler: public AstVisitor { 530 class AstLabeler: public AstVisitor {
431 public: 531 public:
432 AstLabeler() : next_number_(0) {} 532 AstLabeler() : next_number_(0) {}
(...skipping 13 matching lines...) Expand all
446 546
447 // Traversal number for labelling AST nodes. 547 // Traversal number for labelling AST nodes.
448 int next_number_; 548 int next_number_;
449 549
450 CompilationInfo* info_; 550 CompilationInfo* info_;
451 551
452 DISALLOW_COPY_AND_ASSIGN(AstLabeler); 552 DISALLOW_COPY_AND_ASSIGN(AstLabeler);
453 }; 553 };
454 554
455 555
456 class VarUseMap : public HashMap { 556 // Computes the set of assigned variables and annotates variables proxies
557 // that are trivial sub-expressions and for-loops where the loop variable
558 // is guaranteed to be a smi.
559 class AssignedVariablesAnalyzer : public AstVisitor {
457 public: 560 public:
458 VarUseMap() : HashMap(VarMatch) {} 561 explicit AssignedVariablesAnalyzer(FunctionLiteral* fun);
459 562
460 ZoneList<Expression*>* Lookup(Variable* var); 563 void Analyze();
461 564
462 private: 565 private:
463 static bool VarMatch(void* key1, void* key2) { return key1 == key2; } 566 Variable* FindSmiLoopVariable(ForStatement* stmt);
464 };
465 567
568 int BitIndex(Variable* var);
466 569
467 class DefinitionInfo : public ZoneObject { 570 void RecordAssignedVar(Variable* var);
468 public:
469 explicit DefinitionInfo() : last_use_(NULL) {}
470 571
471 Expression* last_use() { return last_use_; } 572 void MarkIfTrivial(Expression* expr);
472 void set_last_use(Expression* expr) { last_use_ = expr; }
473 573
474 private: 574 // Visits an expression saving the accumulator before, clearing
475 Expression* last_use_; 575 // it before visting and restoring it after visiting.
476 Register location_; 576 void ProcessExpression(Expression* expr);
477 };
478
479
480 class LivenessAnalyzer : public AstVisitor {
481 public:
482 LivenessAnalyzer() {}
483
484 void Analyze(FunctionLiteral* fun);
485
486 private:
487 void VisitStatements(ZoneList<Statement*>* stmts);
488
489 void RecordUse(Variable* var, Expression* expr);
490 void RecordDef(Variable* var, Expression* expr);
491
492 577
493 // AST node visit functions. 578 // AST node visit functions.
494 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); 579 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
495 AST_NODE_LIST(DECLARE_VISIT) 580 AST_NODE_LIST(DECLARE_VISIT)
496 #undef DECLARE_VISIT 581 #undef DECLARE_VISIT
497 582
498 // Map for tracking the live variables. 583 FunctionLiteral* fun_;
499 VarUseMap live_vars_;
500 584
501 DISALLOW_COPY_AND_ASSIGN(LivenessAnalyzer); 585 // Accumulator for assigned variables set.
586 BitVector av_;
587
588 DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer);
502 }; 589 };
503 590
504 591
592 class ReachingDefinitions BASE_EMBEDDED {
593 public:
594 ReachingDefinitions(ZoneList<Node*>* postorder,
595 ZoneList<Expression*>* definitions,
596 int variable_count)
597 : postorder_(postorder),
598 definitions_(definitions),
599 variables_(variable_count) {
600 int definition_count = definitions->length();
601 for (int i = 0; i < variable_count; i++) {
602 variables_.Add(new BitVector(definition_count));
603 }
604 }
605
606 static int IndexFor(Variable* var, int variable_count);
607
608 void Compute();
609
610 private:
611 // A (postorder) list of flow-graph nodes in the body.
612 ZoneList<Node*>* postorder_;
613
614 // A list of all the definitions in the body.
615 ZoneList<Expression*>* definitions_;
616
617 // For each variable, the set of all its definitions.
618 List<BitVector*> variables_;
619
620 DISALLOW_COPY_AND_ASSIGN(ReachingDefinitions);
621 };
622
623
505 } } // namespace v8::internal 624 } } // namespace v8::internal
506 625
507 626
508 #endif // V8_DATAFLOW_H_ 627 #endif // V8_DATAFLOW_H_
OLDNEW
« no previous file with comments | « src/cpu-profiler-inl.h ('k') | src/data-flow.cc » ('j') | src/heap.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698