• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <utility>
19 #include <vector>
20 
21 namespace spvtools {
22 namespace val {
23 
BasicBlock(uint32_t label_id)24 BasicBlock::BasicBlock(uint32_t label_id)
25     : id_(label_id),
26       immediate_dominator_(nullptr),
27       immediate_structural_dominator_(nullptr),
28       immediate_structural_post_dominator_(nullptr),
29       predecessors_(),
30       successors_(),
31       type_(0),
32       reachable_(false),
33       structurally_reachable_(false),
34       label_(nullptr),
35       terminator_(nullptr) {}
36 
SetImmediateDominator(BasicBlock * dom_block)37 void BasicBlock::SetImmediateDominator(BasicBlock* dom_block) {
38   immediate_dominator_ = dom_block;
39 }
40 
SetImmediateStructuralDominator(BasicBlock * dom_block)41 void BasicBlock::SetImmediateStructuralDominator(BasicBlock* dom_block) {
42   immediate_structural_dominator_ = dom_block;
43 }
44 
SetImmediateStructuralPostDominator(BasicBlock * pdom_block)45 void BasicBlock::SetImmediateStructuralPostDominator(BasicBlock* pdom_block) {
46   immediate_structural_post_dominator_ = pdom_block;
47 }
48 
immediate_dominator() const49 const BasicBlock* BasicBlock::immediate_dominator() const {
50   return immediate_dominator_;
51 }
52 
immediate_structural_dominator() const53 const BasicBlock* BasicBlock::immediate_structural_dominator() const {
54   return immediate_structural_dominator_;
55 }
56 
immediate_structural_post_dominator() const57 const BasicBlock* BasicBlock::immediate_structural_post_dominator() const {
58   return immediate_structural_post_dominator_;
59 }
60 
immediate_dominator()61 BasicBlock* BasicBlock::immediate_dominator() { return immediate_dominator_; }
immediate_structural_dominator()62 BasicBlock* BasicBlock::immediate_structural_dominator() {
63   return immediate_structural_dominator_;
64 }
immediate_structural_post_dominator()65 BasicBlock* BasicBlock::immediate_structural_post_dominator() {
66   return immediate_structural_post_dominator_;
67 }
68 
RegisterSuccessors(const std::vector<BasicBlock * > & next_blocks)69 void BasicBlock::RegisterSuccessors(
70     const std::vector<BasicBlock*>& next_blocks) {
71   for (auto& block : next_blocks) {
72     block->predecessors_.push_back(this);
73     successors_.push_back(block);
74 
75     // Register structural successors/predecessors too.
76     block->structural_predecessors_.push_back(this);
77     structural_successors_.push_back(block);
78   }
79 }
80 
dominates(const BasicBlock & other) const81 bool BasicBlock::dominates(const BasicBlock& other) const {
82   return (this == &other) ||
83          !(other.dom_end() ==
84            std::find(other.dom_begin(), other.dom_end(), this));
85 }
86 
structurally_dominates(const BasicBlock & other) const87 bool BasicBlock::structurally_dominates(const BasicBlock& other) const {
88   return (this == &other) || !(other.structural_dom_end() ==
89                                std::find(other.structural_dom_begin(),
90                                          other.structural_dom_end(), this));
91 }
92 
structurally_postdominates(const BasicBlock & other) const93 bool BasicBlock::structurally_postdominates(const BasicBlock& other) const {
94   return (this == &other) || !(other.structural_pdom_end() ==
95                                std::find(other.structural_pdom_begin(),
96                                          other.structural_pdom_end(), this));
97 }
98 
DominatorIterator()99 BasicBlock::DominatorIterator::DominatorIterator() : current_(nullptr) {}
100 
DominatorIterator(const BasicBlock * block,std::function<const BasicBlock * (const BasicBlock *)> dominator_func)101 BasicBlock::DominatorIterator::DominatorIterator(
102     const BasicBlock* block,
103     std::function<const BasicBlock*(const BasicBlock*)> dominator_func)
104     : current_(block), dom_func_(dominator_func) {}
105 
operator ++()106 BasicBlock::DominatorIterator& BasicBlock::DominatorIterator::operator++() {
107   if (current_ == dom_func_(current_)) {
108     current_ = nullptr;
109   } else {
110     current_ = dom_func_(current_);
111   }
112   return *this;
113 }
114 
dom_begin() const115 const BasicBlock::DominatorIterator BasicBlock::dom_begin() const {
116   return DominatorIterator(
117       this, [](const BasicBlock* b) { return b->immediate_dominator(); });
118 }
119 
dom_begin()120 BasicBlock::DominatorIterator BasicBlock::dom_begin() {
121   return DominatorIterator(
122       this, [](const BasicBlock* b) { return b->immediate_dominator(); });
123 }
124 
dom_end() const125 const BasicBlock::DominatorIterator BasicBlock::dom_end() const {
126   return DominatorIterator();
127 }
128 
dom_end()129 BasicBlock::DominatorIterator BasicBlock::dom_end() {
130   return DominatorIterator();
131 }
132 
structural_dom_begin() const133 const BasicBlock::DominatorIterator BasicBlock::structural_dom_begin() const {
134   return DominatorIterator(this, [](const BasicBlock* b) {
135     return b->immediate_structural_dominator();
136   });
137 }
138 
structural_dom_begin()139 BasicBlock::DominatorIterator BasicBlock::structural_dom_begin() {
140   return DominatorIterator(this, [](const BasicBlock* b) {
141     return b->immediate_structural_dominator();
142   });
143 }
144 
structural_dom_end() const145 const BasicBlock::DominatorIterator BasicBlock::structural_dom_end() const {
146   return DominatorIterator();
147 }
148 
structural_dom_end()149 BasicBlock::DominatorIterator BasicBlock::structural_dom_end() {
150   return DominatorIterator();
151 }
152 
structural_pdom_begin() const153 const BasicBlock::DominatorIterator BasicBlock::structural_pdom_begin() const {
154   return DominatorIterator(this, [](const BasicBlock* b) {
155     return b->immediate_structural_post_dominator();
156   });
157 }
158 
structural_pdom_begin()159 BasicBlock::DominatorIterator BasicBlock::structural_pdom_begin() {
160   return DominatorIterator(this, [](const BasicBlock* b) {
161     return b->immediate_structural_post_dominator();
162   });
163 }
164 
structural_pdom_end() const165 const BasicBlock::DominatorIterator BasicBlock::structural_pdom_end() const {
166   return DominatorIterator();
167 }
168 
structural_pdom_end()169 BasicBlock::DominatorIterator BasicBlock::structural_pdom_end() {
170   return DominatorIterator();
171 }
172 
operator ==(const BasicBlock::DominatorIterator & lhs,const BasicBlock::DominatorIterator & rhs)173 bool operator==(const BasicBlock::DominatorIterator& lhs,
174                 const BasicBlock::DominatorIterator& rhs) {
175   return lhs.current_ == rhs.current_;
176 }
177 
operator !=(const BasicBlock::DominatorIterator & lhs,const BasicBlock::DominatorIterator & rhs)178 bool operator!=(const BasicBlock::DominatorIterator& lhs,
179                 const BasicBlock::DominatorIterator& rhs) {
180   return !(lhs == rhs);
181 }
182 
operator *()183 const BasicBlock*& BasicBlock::DominatorIterator::operator*() {
184   return current_;
185 }
186 
187 }  // namespace val
188 }  // namespace spvtools
189