• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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