// Copyright 2022 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_MAGLEV_MAGLEV_BASIC_BLOCK_H_ #define V8_MAGLEV_MAGLEV_BASIC_BLOCK_H_ #include #include "src/codegen/label.h" #include "src/maglev/maglev-interpreter-frame-state.h" #include "src/maglev/maglev-ir.h" #include "src/zone/zone.h" namespace v8 { namespace internal { namespace maglev { using NodeIterator = Node::List::Iterator; using NodeConstIterator = Node::List::Iterator; class BasicBlock { public: explicit BasicBlock(MergePointInterpreterFrameState* state) : control_node_(nullptr), state_(state) {} uint32_t first_id() const { if (has_phi()) return phis()->first()->id(); return nodes_.is_empty() ? control_node()->id() : nodes_.first()->id(); } uint32_t FirstNonGapMoveId() const { if (has_phi()) return phis()->first()->id(); if (!nodes_.is_empty()) { for (const Node* node : nodes_) { if (node->Is()) continue; return node->id(); } } return control_node()->id(); } Node::List& nodes() { return nodes_; } ControlNode* control_node() const { return control_node_; } void set_control_node(ControlNode* control_node) { DCHECK_NULL(control_node_); control_node_ = control_node; } bool has_phi() const { return has_state() && state_->has_phi(); } bool is_empty_block() const { return is_empty_block_; } BasicBlock* empty_block_predecessor() const { DCHECK(is_empty_block()); return empty_block_predecessor_; } void set_empty_block_predecessor(BasicBlock* predecessor) { DCHECK(nodes_.is_empty()); DCHECK(control_node()->Is()); DCHECK_NULL(state_); is_empty_block_ = true; empty_block_predecessor_ = predecessor; } Phi::List* phis() const { DCHECK(has_phi()); return state_->phis(); } BasicBlock* predecessor_at(int i) const { DCHECK_NOT_NULL(state_); return state_->predecessor_at(i); } int predecessor_id() const { return control_node()->Cast()->predecessor_id(); } void set_predecessor_id(int id) { control_node()->Cast()->set_predecessor_id(id); } Label* label() { return &label_; } MergePointInterpreterFrameState* state() const { DCHECK(has_state()); return state_; } bool has_state() const { return state_ != nullptr && !is_empty_block(); } private: bool is_empty_block_ = false; Node::List nodes_; ControlNode* control_node_; union { MergePointInterpreterFrameState* state_; BasicBlock* empty_block_predecessor_; }; Label label_; }; } // namespace maglev } // namespace internal } // namespace v8 #endif // V8_MAGLEV_MAGLEV_BASIC_BLOCK_H_