OLD | NEW |
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 Loading... |
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 |
116 int length() const { return length_; } | 123 int length() const { return length_; } |
117 | 124 |
118 private: | 125 private: |
119 int length_; | 126 int length_; |
120 int data_length_; | 127 int data_length_; |
121 uint32_t* data_; | 128 uint32_t* data_; |
122 }; | 129 }; |
123 | 130 |
124 | 131 |
| 132 class ReachingDefinitionsData BASE_EMBEDDED { |
| 133 public: |
| 134 ReachingDefinitionsData() : rd_in_(NULL), kill_(NULL), gen_(NULL) {} |
| 135 |
| 136 void Initialize(int definition_count) { |
| 137 rd_in_ = new BitVector(definition_count); |
| 138 kill_ = new BitVector(definition_count); |
| 139 gen_ = new BitVector(definition_count); |
| 140 } |
| 141 |
| 142 BitVector* rd_in() { return rd_in_; } |
| 143 BitVector* kill() { return kill_; } |
| 144 BitVector* gen() { return gen_; } |
| 145 |
| 146 private: |
| 147 BitVector* rd_in_; |
| 148 BitVector* kill_; |
| 149 BitVector* gen_; |
| 150 }; |
| 151 |
| 152 |
125 // Flow-graph nodes. | 153 // Flow-graph nodes. |
126 class Node: public ZoneObject { | 154 class Node: public ZoneObject { |
127 public: | 155 public: |
128 Node() : number_(-1), mark_(false) {} | 156 Node() : number_(-1), mark_(false) {} |
129 | 157 |
130 virtual ~Node() {} | 158 virtual ~Node() {} |
131 | 159 |
132 virtual bool IsExitNode() { return false; } | 160 virtual bool IsExitNode() { return false; } |
133 virtual bool IsBlockNode() { return false; } | 161 virtual bool IsBlockNode() { return false; } |
134 virtual bool IsBranchNode() { return false; } | 162 virtual bool IsBranchNode() { return false; } |
135 virtual bool IsJoinNode() { return false; } | 163 virtual bool IsJoinNode() { return false; } |
136 | 164 |
137 virtual void AddPredecessor(Node* predecessor) = 0; | 165 virtual void AddPredecessor(Node* predecessor) = 0; |
138 virtual void AddSuccessor(Node* successor) = 0; | 166 virtual void AddSuccessor(Node* successor) = 0; |
139 | 167 |
140 bool IsMarkedWith(bool mark) { return mark_ == mark; } | 168 bool IsMarkedWith(bool mark) { return mark_ == mark; } |
141 void MarkWith(bool mark) { mark_ = mark; } | 169 void MarkWith(bool mark) { mark_ = mark; } |
142 | 170 |
143 // Perform a depth first search and record preorder and postorder | 171 // Perform a depth first search and record preorder and postorder |
144 // traversal orders. | 172 // traversal orders. |
145 virtual void Traverse(bool mark, | 173 virtual void Traverse(bool mark, |
146 ZoneList<Node*>* preorder, | 174 ZoneList<Node*>* preorder, |
147 ZoneList<Node*>* postorder) = 0; | 175 ZoneList<Node*>* postorder) = 0; |
148 | 176 |
149 int number() { return number_; } | 177 int number() { return number_; } |
150 void set_number(int number) { number_ = number; } | 178 void set_number(int number) { number_ = number; } |
151 | 179 |
| 180 // Functions used by data-flow analyses. |
| 181 virtual void InitializeReachingDefinitions(int definition_count, |
| 182 List<BitVector*>* variables); |
| 183 |
152 #ifdef DEBUG | 184 #ifdef DEBUG |
153 virtual void AssignNumbers(); | 185 void AssignNodeNumber(); |
| 186 void PrintReachingDefinitions(); |
154 virtual void PrintText() = 0; | 187 virtual void PrintText() = 0; |
155 #endif | 188 #endif |
156 | 189 |
| 190 protected: |
| 191 ReachingDefinitionsData rd_; |
| 192 |
157 private: | 193 private: |
158 int number_; | 194 int number_; |
159 bool mark_; | 195 bool mark_; |
160 | 196 |
161 DISALLOW_COPY_AND_ASSIGN(Node); | 197 DISALLOW_COPY_AND_ASSIGN(Node); |
162 }; | 198 }; |
163 | 199 |
164 | 200 |
165 // An exit node has a arbitrarily many predecessors and no successors. | 201 // An exit node has a arbitrarily many predecessors and no successors. |
166 class ExitNode: public Node { | 202 class ExitNode: public Node { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 } | 253 } |
218 | 254 |
219 void AddInstruction(AstNode* instruction) { | 255 void AddInstruction(AstNode* instruction) { |
220 instructions_.Add(instruction); | 256 instructions_.Add(instruction); |
221 } | 257 } |
222 | 258 |
223 void Traverse(bool mark, | 259 void Traverse(bool mark, |
224 ZoneList<Node*>* preorder, | 260 ZoneList<Node*>* preorder, |
225 ZoneList<Node*>* postorder); | 261 ZoneList<Node*>* postorder); |
226 | 262 |
| 263 void InitializeReachingDefinitions(int definition_count, |
| 264 List<BitVector*>* variables); |
| 265 |
227 #ifdef DEBUG | 266 #ifdef DEBUG |
228 void AssignNumbers(); | |
229 void PrintText(); | 267 void PrintText(); |
230 #endif | 268 #endif |
231 | 269 |
232 private: | 270 private: |
233 Node* predecessor_; | 271 Node* predecessor_; |
234 Node* successor_; | 272 Node* successor_; |
235 ZoneList<AstNode*> instructions_; | 273 ZoneList<AstNode*> instructions_; |
236 | 274 |
237 DISALLOW_COPY_AND_ASSIGN(BlockNode); | 275 DISALLOW_COPY_AND_ASSIGN(BlockNode); |
238 }; | 276 }; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 : graph_(FlowGraph::Empty()), | 415 : graph_(FlowGraph::Empty()), |
378 global_exit_(NULL), | 416 global_exit_(NULL), |
379 preorder_(4), | 417 preorder_(4), |
380 postorder_(4), | 418 postorder_(4), |
381 definitions_(4) { | 419 definitions_(4) { |
382 } | 420 } |
383 | 421 |
384 void Build(FunctionLiteral* lit); | 422 void Build(FunctionLiteral* lit); |
385 | 423 |
386 FlowGraph* graph() { return &graph_; } | 424 FlowGraph* graph() { return &graph_; } |
387 | |
388 ZoneList<Node*>* postorder() { return &postorder_; } | 425 ZoneList<Node*>* postorder() { return &postorder_; } |
| 426 ZoneList<Expression*>* definitions() { return &definitions_; } |
389 | 427 |
390 private: | 428 private: |
391 ExitNode* global_exit() { return global_exit_; } | 429 ExitNode* global_exit() { return global_exit_; } |
392 | 430 |
393 // AST node visit functions. | 431 // AST node visit functions. |
394 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | 432 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); |
395 AST_NODE_LIST(DECLARE_VISIT) | 433 AST_NODE_LIST(DECLARE_VISIT) |
396 #undef DECLARE_VISIT | 434 #undef DECLARE_VISIT |
397 | 435 |
398 FlowGraph graph_; | 436 FlowGraph graph_; |
399 ExitNode* global_exit_; | 437 ExitNode* global_exit_; |
400 ZoneList<Node*> preorder_; | 438 ZoneList<Node*> preorder_; |
401 ZoneList<Node*> postorder_; | 439 ZoneList<Node*> postorder_; |
402 | 440 |
403 // The flow graph builder collects a list of definitions (assignments and | 441 // The flow graph builder collects a list of definitions (assignments and |
404 // count operations) to stack-allocated variables to use for reaching | 442 // count operations) to stack-allocated variables to use for reaching |
405 // definitions analysis. | 443 // definitions analysis. AST node numbers in the AST are used to refer |
406 ZoneList<AstNode*> definitions_; | 444 // into this list. |
| 445 ZoneList<Expression*> definitions_; |
407 | 446 |
408 DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder); | 447 DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder); |
409 }; | 448 }; |
410 | 449 |
411 | 450 |
412 // This class is used to number all expressions in the AST according to | 451 // This class is used to number all expressions in the AST according to |
413 // their evaluation order (post-order left-to-right traversal). | 452 // their evaluation order (post-order left-to-right traversal). |
414 class AstLabeler: public AstVisitor { | 453 class AstLabeler: public AstVisitor { |
415 public: | 454 public: |
416 AstLabeler() : next_number_(0) {} | 455 AstLabeler() : next_number_(0) {} |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 #undef DECLARE_VISIT | 553 #undef DECLARE_VISIT |
515 | 554 |
516 FunctionLiteral* fun_; | 555 FunctionLiteral* fun_; |
517 | 556 |
518 // Accumulator for assigned variables set. | 557 // Accumulator for assigned variables set. |
519 BitVector av_; | 558 BitVector av_; |
520 | 559 |
521 DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer); | 560 DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer); |
522 }; | 561 }; |
523 | 562 |
| 563 |
| 564 class ReachingDefinitions BASE_EMBEDDED { |
| 565 public: |
| 566 ReachingDefinitions(ZoneList<Node*>* postorder, |
| 567 ZoneList<Expression*>* definitions, |
| 568 int variable_count) |
| 569 : postorder_(postorder), |
| 570 definitions_(definitions), |
| 571 variables_(variable_count) { |
| 572 int definition_count = definitions->length(); |
| 573 for (int i = 0; i < variable_count; i++) { |
| 574 variables_.Add(new BitVector(definition_count)); |
| 575 } |
| 576 } |
| 577 |
| 578 static int IndexFor(Variable* var, int variable_count); |
| 579 |
| 580 void Compute(); |
| 581 |
| 582 private: |
| 583 // A (postorder) list of flow-graph nodes in the body. |
| 584 ZoneList<Node*>* postorder_; |
| 585 |
| 586 // A list of all the definitions in the body. |
| 587 ZoneList<Expression*>* definitions_; |
| 588 |
| 589 // For each variable, the set of all its definitions. |
| 590 List<BitVector*> variables_; |
| 591 |
| 592 DISALLOW_COPY_AND_ASSIGN(ReachingDefinitions); |
| 593 }; |
| 594 |
| 595 |
524 } } // namespace v8::internal | 596 } } // namespace v8::internal |
525 | 597 |
526 | 598 |
527 #endif // V8_DATAFLOW_H_ | 599 #endif // V8_DATAFLOW_H_ |
OLD | NEW |