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 15namespace v8 { 16namespace internal { 17namespace maglev { 18 19using NodeIterator = Node::List::Iterator; 20using NodeConstIterator = Node::List::Iterator; 21 22class BasicBlock { 23 public: 24 explicit BasicBlock(MergePointInterpreterFrameState* state) 25 : control_node_(nullptr), state_(state) {} 26 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 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 43 Node::List& nodes() { return nodes_; } 44 45 ControlNode* control_node() const { return control_node_; } 46 void set_control_node(ControlNode* control_node) { 47 DCHECK_NULL(control_node_); 48 control_node_ = control_node; 49 } 50 51 bool has_phi() const { return has_state() && state_->has_phi(); } 52 53 bool is_empty_block() const { return is_empty_block_; } 54 55 BasicBlock* empty_block_predecessor() const { 56 DCHECK(is_empty_block()); 57 return empty_block_predecessor_; 58 } 59 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 68 Phi::List* phis() const { 69 DCHECK(has_phi()); 70 return state_->phis(); 71 } 72 73 BasicBlock* predecessor_at(int i) const { 74 DCHECK_NOT_NULL(state_); 75 return state_->predecessor_at(i); 76 } 77 78 int predecessor_id() const { 79 return control_node()->Cast<UnconditionalControlNode>()->predecessor_id(); 80 } 81 void set_predecessor_id(int id) { 82 control_node()->Cast<UnconditionalControlNode>()->set_predecessor_id(id); 83 } 84 85 Label* label() { return &label_; } 86 MergePointInterpreterFrameState* state() const { 87 DCHECK(has_state()); 88 return state_; 89 } 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