xref: /netbsd-src/external/apache2/llvm/dist/llvm/include/llvm/IR/CFG.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 //===- CFG.h ----------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file provides various utilities for inspecting and working with the
11 /// control flow graph in LLVM IR. This includes generic facilities for
12 /// iterating successors and predecessors of basic blocks, the successors of
13 /// specific terminator instructions, etc. It also defines specializations of
14 /// GraphTraits that allow Function and BasicBlock graphs to be treated as
15 /// proper graphs for generic algorithms.
16 ///
17 //===----------------------------------------------------------------------===//
18 
19 #ifndef LLVM_IR_CFG_H
20 #define LLVM_IR_CFG_H
21 
22 #include "llvm/ADT/GraphTraits.h"
23 #include "llvm/ADT/iterator.h"
24 #include "llvm/ADT/iterator_range.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/Value.h"
27 #include "llvm/Support/Casting.h"
28 #include <cassert>
29 #include <cstddef>
30 #include <iterator>
31 
32 namespace llvm {
33 
34 class BasicBlock;
35 class Instruction;
36 class Use;
37 
38 //===----------------------------------------------------------------------===//
39 // BasicBlock pred_iterator definition
40 //===----------------------------------------------------------------------===//
41 
42 template <class Ptr, class USE_iterator> // Predecessor Iterator
43 class PredIterator {
44 public:
45   using iterator_category = std::forward_iterator_tag;
46   using value_type = Ptr;
47   using difference_type = std::ptrdiff_t;
48   using pointer = Ptr *;
49   using reference = Ptr *;
50 
51 private:
52   using Self = PredIterator<Ptr, USE_iterator>;
53   USE_iterator It;
54 
advancePastNonTerminators()55   inline void advancePastNonTerminators() {
56     // Loop to ignore non-terminator uses (for example BlockAddresses).
57     while (!It.atEnd()) {
58       if (auto *Inst = dyn_cast<Instruction>(*It))
59         if (Inst->isTerminator())
60           break;
61 
62       ++It;
63     }
64   }
65 
66 public:
67   PredIterator() = default;
PredIterator(Ptr * bb)68   explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
69     advancePastNonTerminators();
70   }
PredIterator(Ptr * bb,bool)71   inline PredIterator(Ptr *bb, bool) : It(bb->user_end()) {}
72 
73   inline bool operator==(const Self& x) const { return It == x.It; }
74   inline bool operator!=(const Self& x) const { return !operator==(x); }
75 
76   inline reference operator*() const {
77     assert(!It.atEnd() && "pred_iterator out of range!");
78     return cast<Instruction>(*It)->getParent();
79   }
80   inline pointer *operator->() const { return &operator*(); }
81 
82   inline Self& operator++() {   // Preincrement
83     assert(!It.atEnd() && "pred_iterator out of range!");
84     ++It; advancePastNonTerminators();
85     return *this;
86   }
87 
88   inline Self operator++(int) { // Postincrement
89     Self tmp = *this; ++*this; return tmp;
90   }
91 
92   /// getOperandNo - Return the operand number in the predecessor's
93   /// terminator of the successor.
getOperandNo()94   unsigned getOperandNo() const {
95     return It.getOperandNo();
96   }
97 
98   /// getUse - Return the operand Use in the predecessor's terminator
99   /// of the successor.
getUse()100   Use &getUse() const {
101     return It.getUse();
102   }
103 };
104 
105 using pred_iterator = PredIterator<BasicBlock, Value::user_iterator>;
106 using const_pred_iterator =
107     PredIterator<const BasicBlock, Value::const_user_iterator>;
108 using pred_range = iterator_range<pred_iterator>;
109 using const_pred_range = iterator_range<const_pred_iterator>;
110 
pred_begin(BasicBlock * BB)111 inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
pred_begin(const BasicBlock * BB)112 inline const_pred_iterator pred_begin(const BasicBlock *BB) {
113   return const_pred_iterator(BB);
114 }
pred_end(BasicBlock * BB)115 inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
pred_end(const BasicBlock * BB)116 inline const_pred_iterator pred_end(const BasicBlock *BB) {
117   return const_pred_iterator(BB, true);
118 }
pred_empty(const BasicBlock * BB)119 inline bool pred_empty(const BasicBlock *BB) {
120   return pred_begin(BB) == pred_end(BB);
121 }
122 /// Get the number of predecessors of \p BB. This is a linear time operation.
123 /// Use \ref BasicBlock::hasNPredecessors() or hasNPredecessorsOrMore if able.
pred_size(const BasicBlock * BB)124 inline unsigned pred_size(const BasicBlock *BB) {
125   return std::distance(pred_begin(BB), pred_end(BB));
126 }
predecessors(BasicBlock * BB)127 inline pred_range predecessors(BasicBlock *BB) {
128   return pred_range(pred_begin(BB), pred_end(BB));
129 }
predecessors(const BasicBlock * BB)130 inline const_pred_range predecessors(const BasicBlock *BB) {
131   return const_pred_range(pred_begin(BB), pred_end(BB));
132 }
133 
134 //===----------------------------------------------------------------------===//
135 // Instruction and BasicBlock succ_iterator helpers
136 //===----------------------------------------------------------------------===//
137 
138 template <class InstructionT, class BlockT>
139 class SuccIterator
140     : public iterator_facade_base<SuccIterator<InstructionT, BlockT>,
141                                   std::random_access_iterator_tag, BlockT, int,
142                                   BlockT *, BlockT *> {
143 public:
144   using difference_type = int;
145   using pointer = BlockT *;
146   using reference = BlockT *;
147 
148 private:
149   InstructionT *Inst;
150   int Idx;
151   using Self = SuccIterator<InstructionT, BlockT>;
152 
index_is_valid(int Idx)153   inline bool index_is_valid(int Idx) {
154     // Note that we specially support the index of zero being valid even in the
155     // face of a null instruction.
156     return Idx >= 0 && (Idx == 0 || Idx <= (int)Inst->getNumSuccessors());
157   }
158 
159   /// Proxy object to allow write access in operator[]
160   class SuccessorProxy {
161     Self It;
162 
163   public:
SuccessorProxy(const Self & It)164     explicit SuccessorProxy(const Self &It) : It(It) {}
165 
166     SuccessorProxy(const SuccessorProxy &) = default;
167 
168     SuccessorProxy &operator=(SuccessorProxy RHS) {
169       *this = reference(RHS);
170       return *this;
171     }
172 
173     SuccessorProxy &operator=(reference RHS) {
174       It.Inst->setSuccessor(It.Idx, RHS);
175       return *this;
176     }
177 
reference()178     operator reference() const { return *It; }
179   };
180 
181 public:
182   // begin iterator
SuccIterator(InstructionT * Inst)183   explicit inline SuccIterator(InstructionT *Inst) : Inst(Inst), Idx(0) {}
184   // end iterator
SuccIterator(InstructionT * Inst,bool)185   inline SuccIterator(InstructionT *Inst, bool) : Inst(Inst) {
186     if (Inst)
187       Idx = Inst->getNumSuccessors();
188     else
189       // Inst == NULL happens, if a basic block is not fully constructed and
190       // consequently getTerminator() returns NULL. In this case we construct
191       // a SuccIterator which describes a basic block that has zero
192       // successors.
193       // Defining SuccIterator for incomplete and malformed CFGs is especially
194       // useful for debugging.
195       Idx = 0;
196   }
197 
198   /// This is used to interface between code that wants to
199   /// operate on terminator instructions directly.
getSuccessorIndex()200   int getSuccessorIndex() const { return Idx; }
201 
202   inline bool operator==(const Self &x) const { return Idx == x.Idx; }
203 
204   inline BlockT *operator*() const { return Inst->getSuccessor(Idx); }
205 
206   // We use the basic block pointer directly for operator->.
207   inline BlockT *operator->() const { return operator*(); }
208 
209   inline bool operator<(const Self &RHS) const {
210     assert(Inst == RHS.Inst && "Cannot compare iterators of different blocks!");
211     return Idx < RHS.Idx;
212   }
213 
214   int operator-(const Self &RHS) const {
215     assert(Inst == RHS.Inst && "Cannot compare iterators of different blocks!");
216     return Idx - RHS.Idx;
217   }
218 
219   inline Self &operator+=(int RHS) {
220     int NewIdx = Idx + RHS;
221     assert(index_is_valid(NewIdx) && "Iterator index out of bound");
222     Idx = NewIdx;
223     return *this;
224   }
225 
226   inline Self &operator-=(int RHS) { return operator+=(-RHS); }
227 
228   // Specially implement the [] operation using a proxy object to support
229   // assignment.
230   inline SuccessorProxy operator[](int Offset) {
231     Self TmpIt = *this;
232     TmpIt += Offset;
233     return SuccessorProxy(TmpIt);
234   }
235 
236   /// Get the source BlockT of this iterator.
getSource()237   inline BlockT *getSource() {
238     assert(Inst && "Source not available, if basic block was malformed");
239     return Inst->getParent();
240   }
241 };
242 
243 using succ_iterator = SuccIterator<Instruction, BasicBlock>;
244 using const_succ_iterator = SuccIterator<const Instruction, const BasicBlock>;
245 using succ_range = iterator_range<succ_iterator>;
246 using const_succ_range = iterator_range<const_succ_iterator>;
247 
succ_begin(Instruction * I)248 inline succ_iterator succ_begin(Instruction *I) { return succ_iterator(I); }
succ_begin(const Instruction * I)249 inline const_succ_iterator succ_begin(const Instruction *I) {
250   return const_succ_iterator(I);
251 }
succ_end(Instruction * I)252 inline succ_iterator succ_end(Instruction *I) { return succ_iterator(I, true); }
succ_end(const Instruction * I)253 inline const_succ_iterator succ_end(const Instruction *I) {
254   return const_succ_iterator(I, true);
255 }
succ_empty(const Instruction * I)256 inline bool succ_empty(const Instruction *I) {
257   return succ_begin(I) == succ_end(I);
258 }
succ_size(const Instruction * I)259 inline unsigned succ_size(const Instruction *I) {
260   return std::distance(succ_begin(I), succ_end(I));
261 }
successors(Instruction * I)262 inline succ_range successors(Instruction *I) {
263   return succ_range(succ_begin(I), succ_end(I));
264 }
successors(const Instruction * I)265 inline const_succ_range successors(const Instruction *I) {
266   return const_succ_range(succ_begin(I), succ_end(I));
267 }
268 
succ_begin(BasicBlock * BB)269 inline succ_iterator succ_begin(BasicBlock *BB) {
270   return succ_iterator(BB->getTerminator());
271 }
succ_begin(const BasicBlock * BB)272 inline const_succ_iterator succ_begin(const BasicBlock *BB) {
273   return const_succ_iterator(BB->getTerminator());
274 }
succ_end(BasicBlock * BB)275 inline succ_iterator succ_end(BasicBlock *BB) {
276   return succ_iterator(BB->getTerminator(), true);
277 }
succ_end(const BasicBlock * BB)278 inline const_succ_iterator succ_end(const BasicBlock *BB) {
279   return const_succ_iterator(BB->getTerminator(), true);
280 }
succ_empty(const BasicBlock * BB)281 inline bool succ_empty(const BasicBlock *BB) {
282   return succ_begin(BB) == succ_end(BB);
283 }
succ_size(const BasicBlock * BB)284 inline unsigned succ_size(const BasicBlock *BB) {
285   return std::distance(succ_begin(BB), succ_end(BB));
286 }
successors(BasicBlock * BB)287 inline succ_range successors(BasicBlock *BB) {
288   return succ_range(succ_begin(BB), succ_end(BB));
289 }
successors(const BasicBlock * BB)290 inline const_succ_range successors(const BasicBlock *BB) {
291   return const_succ_range(succ_begin(BB), succ_end(BB));
292 }
293 
294 //===--------------------------------------------------------------------===//
295 // GraphTraits specializations for basic block graphs (CFGs)
296 //===--------------------------------------------------------------------===//
297 
298 // Provide specializations of GraphTraits to be able to treat a function as a
299 // graph of basic blocks...
300 
301 template <> struct GraphTraits<BasicBlock*> {
302   using NodeRef = BasicBlock *;
303   using ChildIteratorType = succ_iterator;
304 
305   static NodeRef getEntryNode(BasicBlock *BB) { return BB; }
306   static ChildIteratorType child_begin(NodeRef N) { return succ_begin(N); }
307   static ChildIteratorType child_end(NodeRef N) { return succ_end(N); }
308 };
309 
310 template <> struct GraphTraits<const BasicBlock*> {
311   using NodeRef = const BasicBlock *;
312   using ChildIteratorType = const_succ_iterator;
313 
314   static NodeRef getEntryNode(const BasicBlock *BB) { return BB; }
315 
316   static ChildIteratorType child_begin(NodeRef N) { return succ_begin(N); }
317   static ChildIteratorType child_end(NodeRef N) { return succ_end(N); }
318 };
319 
320 // Provide specializations of GraphTraits to be able to treat a function as a
321 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
322 // a function is considered to be when traversing the predecessor edges of a BB
323 // instead of the successor edges.
324 //
325 template <> struct GraphTraits<Inverse<BasicBlock*>> {
326   using NodeRef = BasicBlock *;
327   using ChildIteratorType = pred_iterator;
328 
329   static NodeRef getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
330   static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); }
331   static ChildIteratorType child_end(NodeRef N) { return pred_end(N); }
332 };
333 
334 template <> struct GraphTraits<Inverse<const BasicBlock*>> {
335   using NodeRef = const BasicBlock *;
336   using ChildIteratorType = const_pred_iterator;
337 
338   static NodeRef getEntryNode(Inverse<const BasicBlock *> G) { return G.Graph; }
339   static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); }
340   static ChildIteratorType child_end(NodeRef N) { return pred_end(N); }
341 };
342 
343 //===--------------------------------------------------------------------===//
344 // GraphTraits specializations for function basic block graphs (CFGs)
345 //===--------------------------------------------------------------------===//
346 
347 // Provide specializations of GraphTraits to be able to treat a function as a
348 // graph of basic blocks... these are the same as the basic block iterators,
349 // except that the root node is implicitly the first node of the function.
350 //
351 template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
352   static NodeRef getEntryNode(Function *F) { return &F->getEntryBlock(); }
353 
354   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
355   using nodes_iterator = pointer_iterator<Function::iterator>;
356 
357   static nodes_iterator nodes_begin(Function *F) {
358     return nodes_iterator(F->begin());
359   }
360 
361   static nodes_iterator nodes_end(Function *F) {
362     return nodes_iterator(F->end());
363   }
364 
365   static size_t size(Function *F) { return F->size(); }
366 };
367 template <> struct GraphTraits<const Function*> :
368   public GraphTraits<const BasicBlock*> {
369   static NodeRef getEntryNode(const Function *F) { return &F->getEntryBlock(); }
370 
371   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
372   using nodes_iterator = pointer_iterator<Function::const_iterator>;
373 
374   static nodes_iterator nodes_begin(const Function *F) {
375     return nodes_iterator(F->begin());
376   }
377 
378   static nodes_iterator nodes_end(const Function *F) {
379     return nodes_iterator(F->end());
380   }
381 
382   static size_t size(const Function *F) { return F->size(); }
383 };
384 
385 // Provide specializations of GraphTraits to be able to treat a function as a
386 // graph of basic blocks... and to walk it in inverse order.  Inverse order for
387 // a function is considered to be when traversing the predecessor edges of a BB
388 // instead of the successor edges.
389 //
390 template <> struct GraphTraits<Inverse<Function*>> :
391   public GraphTraits<Inverse<BasicBlock*>> {
392   static NodeRef getEntryNode(Inverse<Function *> G) {
393     return &G.Graph->getEntryBlock();
394   }
395 };
396 template <> struct GraphTraits<Inverse<const Function*>> :
397   public GraphTraits<Inverse<const BasicBlock*>> {
398   static NodeRef getEntryNode(Inverse<const Function *> G) {
399     return &G.Graph->getEntryBlock();
400   }
401 };
402 
403 } // end namespace llvm
404 
405 #endif // LLVM_IR_CFG_H
406