| 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 |