xref: /aosp_15_r20/external/angle/third_party/spirv-tools/src/source/val/basic_block.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 // Copyright (c) 2015-2016 The Khronos Group Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "source/val/basic_block.h"
16 
17 #include <algorithm>
18 #include <vector>
19 
20 namespace spvtools {
21 namespace val {
22 
BasicBlock(uint32_t label_id)23 BasicBlock::BasicBlock(uint32_t label_id)
24     : id_(label_id),
25       immediate_dominator_(nullptr),
26       immediate_structural_dominator_(nullptr),
27       immediate_structural_post_dominator_(nullptr),
28       predecessors_(),
29       successors_(),
30       type_(0),
31       reachable_(false),
32       structurally_reachable_(false),
33       label_(nullptr),
34       terminator_(nullptr) {}
35 
SetImmediateDominator(BasicBlock * dom_block)36 void BasicBlock::SetImmediateDominator(BasicBlock* dom_block) {
37   immediate_dominator_ = dom_block;
38 }
39 
SetImmediateStructuralDominator(BasicBlock * dom_block)40 void BasicBlock::SetImmediateStructuralDominator(BasicBlock* dom_block) {
41   immediate_structural_dominator_ = dom_block;
42 }
43 
SetImmediateStructuralPostDominator(BasicBlock * pdom_block)44 void BasicBlock::SetImmediateStructuralPostDominator(BasicBlock* pdom_block) {
45   immediate_structural_post_dominator_ = pdom_block;
46 }
47 
immediate_dominator() const48 const BasicBlock* BasicBlock::immediate_dominator() const {
49   return immediate_dominator_;
50 }
51 
immediate_structural_dominator() const52 const BasicBlock* BasicBlock::immediate_structural_dominator() const {
53   return immediate_structural_dominator_;
54 }
55 
immediate_structural_post_dominator() const56 const BasicBlock* BasicBlock::immediate_structural_post_dominator() const {
57   return immediate_structural_post_dominator_;
58 }
59 
immediate_dominator()60 BasicBlock* BasicBlock::immediate_dominator() { return immediate_dominator_; }
immediate_structural_dominator()61 BasicBlock* BasicBlock::immediate_structural_dominator() {
62   return immediate_structural_dominator_;
63 }
immediate_structural_post_dominator()64 BasicBlock* BasicBlock::immediate_structural_post_dominator() {
65   return immediate_structural_post_dominator_;
66 }
67 
RegisterSuccessors(const std::vector<BasicBlock * > & next_blocks)68 void BasicBlock::RegisterSuccessors(
69     const std::vector<BasicBlock*>& next_blocks) {
70   for (auto& block : next_blocks) {
71     block->predecessors_.push_back(this);
72     successors_.push_back(block);
73 
74     // Register structural successors/predecessors too.
75     block->structural_predecessors_.push_back(this);
76     structural_successors_.push_back(block);
77   }
78 }
79 
dominates(const BasicBlock & other) const80 bool BasicBlock::dominates(const BasicBlock& other) const {
81   return (this == &other) ||
82          !(other.dom_end() ==
83            std::find(other.dom_begin(), other.dom_end(), this));
84 }
85 
structurally_dominates(const BasicBlock & other) const86 bool BasicBlock::structurally_dominates(const BasicBlock& other) const {
87   return (this == &other) || !(other.structural_dom_end() ==
88                                std::find(other.structural_dom_begin(),
89                                          other.structural_dom_end(), this));
90 }
91 
structurally_postdominates(const BasicBlock & other) const92 bool BasicBlock::structurally_postdominates(const BasicBlock& other) const {
93   return (this == &other) || !(other.structural_pdom_end() ==
94                                std::find(other.structural_pdom_begin(),
95                                          other.structural_pdom_end(), this));
96 }
97 
DominatorIterator()98 BasicBlock::DominatorIterator::DominatorIterator() : current_(nullptr) {}
99 
DominatorIterator(const BasicBlock * block,std::function<const BasicBlock * (const BasicBlock *)> dominator_func)100 BasicBlock::DominatorIterator::DominatorIterator(
101     const BasicBlock* block,
102     std::function<const BasicBlock*(const BasicBlock*)> dominator_func)
103     : current_(block), dom_func_(dominator_func) {}
104 
operator ++()105 BasicBlock::DominatorIterator& BasicBlock::DominatorIterator::operator++() {
106   if (current_ == dom_func_(current_)) {
107     current_ = nullptr;
108   } else {
109     current_ = dom_func_(current_);
110   }
111   return *this;
112 }
113 
dom_begin() const114 const BasicBlock::DominatorIterator BasicBlock::dom_begin() const {
115   return DominatorIterator(
116       this, [](const BasicBlock* b) { return b->immediate_dominator(); });
117 }
118 
dom_begin()119 BasicBlock::DominatorIterator BasicBlock::dom_begin() {
120   return DominatorIterator(
121       this, [](const BasicBlock* b) { return b->immediate_dominator(); });
122 }
123 
dom_end() const124 const BasicBlock::DominatorIterator BasicBlock::dom_end() const {
125   return DominatorIterator();
126 }
127 
dom_end()128 BasicBlock::DominatorIterator BasicBlock::dom_end() {
129   return DominatorIterator();
130 }
131 
structural_dom_begin() const132 const BasicBlock::DominatorIterator BasicBlock::structural_dom_begin() const {
133   return DominatorIterator(this, [](const BasicBlock* b) {
134     return b->immediate_structural_dominator();
135   });
136 }
137 
structural_dom_begin()138 BasicBlock::DominatorIterator BasicBlock::structural_dom_begin() {
139   return DominatorIterator(this, [](const BasicBlock* b) {
140     return b->immediate_structural_dominator();
141   });
142 }
143 
structural_dom_end() const144 const BasicBlock::DominatorIterator BasicBlock::structural_dom_end() const {
145   return DominatorIterator();
146 }
147 
structural_dom_end()148 BasicBlock::DominatorIterator BasicBlock::structural_dom_end() {
149   return DominatorIterator();
150 }
151 
structural_pdom_begin() const152 const BasicBlock::DominatorIterator BasicBlock::structural_pdom_begin() const {
153   return DominatorIterator(this, [](const BasicBlock* b) {
154     return b->immediate_structural_post_dominator();
155   });
156 }
157 
structural_pdom_begin()158 BasicBlock::DominatorIterator BasicBlock::structural_pdom_begin() {
159   return DominatorIterator(this, [](const BasicBlock* b) {
160     return b->immediate_structural_post_dominator();
161   });
162 }
163 
structural_pdom_end() const164 const BasicBlock::DominatorIterator BasicBlock::structural_pdom_end() const {
165   return DominatorIterator();
166 }
167 
structural_pdom_end()168 BasicBlock::DominatorIterator BasicBlock::structural_pdom_end() {
169   return DominatorIterator();
170 }
171 
operator ==(const BasicBlock::DominatorIterator & lhs,const BasicBlock::DominatorIterator & rhs)172 bool operator==(const BasicBlock::DominatorIterator& lhs,
173                 const BasicBlock::DominatorIterator& rhs) {
174   return lhs.current_ == rhs.current_;
175 }
176 
operator !=(const BasicBlock::DominatorIterator & lhs,const BasicBlock::DominatorIterator & rhs)177 bool operator!=(const BasicBlock::DominatorIterator& lhs,
178                 const BasicBlock::DominatorIterator& rhs) {
179   return !(lhs == rhs);
180 }
181 
operator *()182 const BasicBlock*& BasicBlock::DominatorIterator::operator*() {
183   return current_;
184 }
185 
186 }  // namespace val
187 }  // namespace spvtools
188