Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- InstIterator.h - Classes for inst iteration --------------*- 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. //
  9. // This file contains definitions of two iterators for iterating over the
  10. // instructions in a function.  This is effectively a wrapper around a two level
  11. // iterator that can probably be genericized later.
  12. //
  13. // Note that this iterator gets invalidated any time that basic blocks or
  14. // instructions are moved around.
  15. //
  16. //===----------------------------------------------------------------------===//
  17.  
  18. #ifndef LLVM_IR_INSTITERATOR_H
  19. #define LLVM_IR_INSTITERATOR_H
  20.  
  21. #include "llvm/ADT/iterator_range.h"
  22. #include "llvm/IR/BasicBlock.h"
  23. #include "llvm/IR/Function.h"
  24. #include "llvm/IR/SymbolTableListTraits.h"
  25. #include <iterator>
  26.  
  27. namespace llvm {
  28.  
  29. // This class implements inst_begin() & inst_end() for
  30. // inst_iterator and const_inst_iterator's.
  31. //
  32. template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator {
  33.   using BBty = BB_t;
  34.   using BBIty = BB_i_t;
  35.   using BIty = BI_t;
  36.   using IIty = II_t;
  37.   BB_t *BBs; // BasicBlocksType
  38.   BB_i_t BB; // BasicBlocksType::iterator
  39.   BI_t BI;   // BasicBlock::iterator
  40.  
  41. public:
  42.   using iterator_category = std::bidirectional_iterator_tag;
  43.   using value_type = IIty;
  44.   using difference_type = signed;
  45.   using pointer = IIty *;
  46.   using reference = IIty &;
  47.  
  48.   // Default constructor
  49.   InstIterator() = default;
  50.  
  51.   // Copy constructor...
  52.   template<typename A, typename B, typename C, typename D>
  53.   InstIterator(const InstIterator<A,B,C,D> &II)
  54.     : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
  55.  
  56.   template<typename A, typename B, typename C, typename D>
  57.   InstIterator(InstIterator<A,B,C,D> &II)
  58.     : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
  59.  
  60.   template<class M> InstIterator(M &m)
  61.     : BBs(&m.getBasicBlockList()), BB(BBs->begin()) {    // begin ctor
  62.     if (BB != BBs->end()) {
  63.       BI = BB->begin();
  64.       advanceToNextBB();
  65.     }
  66.   }
  67.  
  68.   template<class M> InstIterator(M &m, bool)
  69.     : BBs(&m.getBasicBlockList()), BB(BBs->end()) {    // end ctor
  70.   }
  71.  
  72.   // Accessors to get at the underlying iterators...
  73.   inline BBIty &getBasicBlockIterator()  { return BB; }
  74.   inline BIty  &getInstructionIterator() { return BI; }
  75.  
  76.   inline reference operator*()  const { return *BI; }
  77.   inline pointer operator->() const { return &operator*(); }
  78.  
  79.   inline bool operator==(const InstIterator &y) const {
  80.     return BB == y.BB && (BB == BBs->end() || BI == y.BI);
  81.   }
  82.   inline bool operator!=(const InstIterator& y) const {
  83.     return !operator==(y);
  84.   }
  85.  
  86.   InstIterator& operator++() {
  87.     ++BI;
  88.     advanceToNextBB();
  89.     return *this;
  90.   }
  91.   inline InstIterator operator++(int) {
  92.     InstIterator tmp = *this; ++*this; return tmp;
  93.   }
  94.  
  95.   InstIterator& operator--() {
  96.     while (BB == BBs->end() || BI == BB->begin()) {
  97.       --BB;
  98.       BI = BB->end();
  99.     }
  100.     --BI;
  101.     return *this;
  102.   }
  103.   inline InstIterator operator--(int) {
  104.     InstIterator tmp = *this; --*this; return tmp;
  105.   }
  106.  
  107.   inline bool atEnd() const { return BB == BBs->end(); }
  108.  
  109. private:
  110.   inline void advanceToNextBB() {
  111.     // The only way that the II could be broken is if it is now pointing to
  112.     // the end() of the current BasicBlock and there are successor BBs.
  113.     while (BI == BB->end()) {
  114.       ++BB;
  115.       if (BB == BBs->end()) break;
  116.       BI = BB->begin();
  117.     }
  118.   }
  119. };
  120.  
  121. using inst_iterator =
  122.     InstIterator<SymbolTableList<BasicBlock>, Function::iterator,
  123.                  BasicBlock::iterator, Instruction>;
  124. using const_inst_iterator =
  125.     InstIterator<const SymbolTableList<BasicBlock>,
  126.                  Function::const_iterator, BasicBlock::const_iterator,
  127.                  const Instruction>;
  128. using inst_range = iterator_range<inst_iterator>;
  129. using const_inst_range = iterator_range<const_inst_iterator>;
  130.  
  131. inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
  132. inline inst_iterator inst_end(Function *F)   { return inst_iterator(*F, true); }
  133. inline inst_range instructions(Function *F) {
  134.   return inst_range(inst_begin(F), inst_end(F));
  135. }
  136. inline const_inst_iterator inst_begin(const Function *F) {
  137.   return const_inst_iterator(*F);
  138. }
  139. inline const_inst_iterator inst_end(const Function *F) {
  140.   return const_inst_iterator(*F, true);
  141. }
  142. inline const_inst_range instructions(const Function *F) {
  143.   return const_inst_range(inst_begin(F), inst_end(F));
  144. }
  145. inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
  146. inline inst_iterator inst_end(Function &F)   { return inst_iterator(F, true); }
  147. inline inst_range instructions(Function &F) {
  148.   return inst_range(inst_begin(F), inst_end(F));
  149. }
  150. inline const_inst_iterator inst_begin(const Function &F) {
  151.   return const_inst_iterator(F);
  152. }
  153. inline const_inst_iterator inst_end(const Function &F) {
  154.   return const_inst_iterator(F, true);
  155. }
  156. inline const_inst_range instructions(const Function &F) {
  157.   return const_inst_range(inst_begin(F), inst_end(F));
  158. }
  159.  
  160. } // end namespace llvm
  161.  
  162. #endif // LLVM_IR_INSTITERATOR_H
  163.