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