1 // Copyright 2022 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_MAGLEV_MAGLEV_BASIC_BLOCK_H_ 6 #define V8_MAGLEV_MAGLEV_BASIC_BLOCK_H_ 7 8 #include <vector> 9 10 #include "src/codegen/label.h" 11 #include "src/maglev/maglev-interpreter-frame-state.h" 12 #include "src/maglev/maglev-ir.h" 13 #include "src/zone/zone.h" 14 15 namespace v8 { 16 namespace internal { 17 namespace maglev { 18 19 using NodeIterator = Node::List::Iterator; 20 using NodeConstIterator = Node::List::Iterator; 21 22 class BasicBlock { 23 public: BasicBlock(MergePointInterpreterFrameState * state)24 explicit BasicBlock(MergePointInterpreterFrameState* state) 25 : control_node_(nullptr), state_(state) {} 26 first_id()27 uint32_t first_id() const { 28 if (has_phi()) return phis()->first()->id(); 29 return nodes_.is_empty() ? control_node()->id() : nodes_.first()->id(); 30 } 31 FirstNonGapMoveId()32 uint32_t FirstNonGapMoveId() const { 33 if (has_phi()) return phis()->first()->id(); 34 if (!nodes_.is_empty()) { 35 for (const Node* node : nodes_) { 36 if (node->Is<GapMove>()) continue; 37 return node->id(); 38 } 39 } 40 return control_node()->id(); 41 } 42 nodes()43 Node::List& nodes() { return nodes_; } 44 control_node()45 ControlNode* control_node() const { return control_node_; } set_control_node(ControlNode * control_node)46 void set_control_node(ControlNode* control_node) { 47 DCHECK_NULL(control_node_); 48 control_node_ = control_node; 49 } 50 has_phi()51 bool has_phi() const { return has_state() && state_->has_phi(); } 52 is_empty_block()53 bool is_empty_block() const { return is_empty_block_; } 54 empty_block_predecessor()55 BasicBlock* empty_block_predecessor() const { 56 DCHECK(is_empty_block()); 57 return empty_block_predecessor_; 58 } 59 set_empty_block_predecessor(BasicBlock * predecessor)60 void set_empty_block_predecessor(BasicBlock* predecessor) { 61 DCHECK(nodes_.is_empty()); 62 DCHECK(control_node()->Is<Jump>()); 63 DCHECK_NULL(state_); 64 is_empty_block_ = true; 65 empty_block_predecessor_ = predecessor; 66 } 67 phis()68 Phi::List* phis() const { 69 DCHECK(has_phi()); 70 return state_->phis(); 71 } 72 predecessor_at(int i)73 BasicBlock* predecessor_at(int i) const { 74 DCHECK_NOT_NULL(state_); 75 return state_->predecessor_at(i); 76 } 77 predecessor_id()78 int predecessor_id() const { 79 return control_node()->Cast<UnconditionalControlNode>()->predecessor_id(); 80 } set_predecessor_id(int id)81 void set_predecessor_id(int id) { 82 control_node()->Cast<UnconditionalControlNode>()->set_predecessor_id(id); 83 } 84 label()85 Label* label() { return &label_; } state()86 MergePointInterpreterFrameState* state() const { 87 DCHECK(has_state()); 88 return state_; 89 } has_state()90 bool has_state() const { return state_ != nullptr && !is_empty_block(); } 91 92 private: 93 bool is_empty_block_ = false; 94 Node::List nodes_; 95 ControlNode* control_node_; 96 union { 97 MergePointInterpreterFrameState* state_; 98 BasicBlock* empty_block_predecessor_; 99 }; 100 Label label_; 101 }; 102 103 } // namespace maglev 104 } // namespace internal 105 } // namespace v8 106 107 #endif // V8_MAGLEV_MAGLEV_BASIC_BLOCK_H_ 108