InstIterator.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- InstIterator.h - Classes for inst iteration --------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file contains definitions of two iterators for iterating over the
  15. // instructions in a function. This is effectively a wrapper around a two level
  16. // iterator that can probably be genericized later.
  17. //
  18. // Note that this iterator gets invalidated any time that basic blocks or
  19. // instructions are moved around.
  20. //
  21. //===----------------------------------------------------------------------===//
  22. #ifndef LLVM_IR_INSTITERATOR_H
  23. #define LLVM_IR_INSTITERATOR_H
  24. #include "llvm/ADT/iterator_range.h"
  25. #include "llvm/IR/BasicBlock.h"
  26. #include "llvm/IR/Function.h"
  27. #include "llvm/IR/SymbolTableListTraits.h"
  28. #include <iterator>
  29. namespace llvm {
  30. // This class implements inst_begin() & inst_end() for
  31. // inst_iterator and const_inst_iterator's.
  32. //
  33. template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator {
  34. using BBty = BB_t;
  35. using BBIty = BB_i_t;
  36. using BIty = BI_t;
  37. using IIty = II_t;
  38. BB_t *BBs; // BasicBlocksType
  39. BB_i_t BB; // BasicBlocksType::iterator
  40. BI_t BI; // BasicBlock::iterator
  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. // Default constructor
  48. InstIterator() = default;
  49. // Copy constructor...
  50. template<typename A, typename B, typename C, typename D>
  51. InstIterator(const InstIterator<A,B,C,D> &II)
  52. : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
  53. template<typename A, typename B, typename C, typename D>
  54. InstIterator(InstIterator<A,B,C,D> &II)
  55. : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
  56. template<class M> InstIterator(M &m)
  57. : BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor
  58. if (BB != BBs->end()) {
  59. BI = BB->begin();
  60. advanceToNextBB();
  61. }
  62. }
  63. template<class M> InstIterator(M &m, bool)
  64. : BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor
  65. }
  66. // Accessors to get at the underlying iterators...
  67. inline BBIty &getBasicBlockIterator() { return BB; }
  68. inline BIty &getInstructionIterator() { return BI; }
  69. inline reference operator*() const { return *BI; }
  70. inline pointer operator->() const { return &operator*(); }
  71. inline bool operator==(const InstIterator &y) const {
  72. return BB == y.BB && (BB == BBs->end() || BI == y.BI);
  73. }
  74. inline bool operator!=(const InstIterator& y) const {
  75. return !operator==(y);
  76. }
  77. InstIterator& operator++() {
  78. ++BI;
  79. advanceToNextBB();
  80. return *this;
  81. }
  82. inline InstIterator operator++(int) {
  83. InstIterator tmp = *this; ++*this; return tmp;
  84. }
  85. InstIterator& operator--() {
  86. while (BB == BBs->end() || BI == BB->begin()) {
  87. --BB;
  88. BI = BB->end();
  89. }
  90. --BI;
  91. return *this;
  92. }
  93. inline InstIterator operator--(int) {
  94. InstIterator tmp = *this; --*this; return tmp;
  95. }
  96. inline bool atEnd() const { return BB == BBs->end(); }
  97. private:
  98. inline void advanceToNextBB() {
  99. // The only way that the II could be broken is if it is now pointing to
  100. // the end() of the current BasicBlock and there are successor BBs.
  101. while (BI == BB->end()) {
  102. ++BB;
  103. if (BB == BBs->end()) break;
  104. BI = BB->begin();
  105. }
  106. }
  107. };
  108. using inst_iterator =
  109. InstIterator<SymbolTableList<BasicBlock>, Function::iterator,
  110. BasicBlock::iterator, Instruction>;
  111. using const_inst_iterator =
  112. InstIterator<const SymbolTableList<BasicBlock>,
  113. Function::const_iterator, BasicBlock::const_iterator,
  114. const Instruction>;
  115. using inst_range = iterator_range<inst_iterator>;
  116. using const_inst_range = iterator_range<const_inst_iterator>;
  117. inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
  118. inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
  119. inline inst_range instructions(Function *F) {
  120. return inst_range(inst_begin(F), inst_end(F));
  121. }
  122. inline const_inst_iterator inst_begin(const Function *F) {
  123. return const_inst_iterator(*F);
  124. }
  125. inline const_inst_iterator inst_end(const Function *F) {
  126. return const_inst_iterator(*F, true);
  127. }
  128. inline const_inst_range instructions(const Function *F) {
  129. return const_inst_range(inst_begin(F), inst_end(F));
  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. } // end namespace llvm
  146. #endif // LLVM_IR_INSTITERATOR_H
  147. #ifdef __GNUC__
  148. #pragma GCC diagnostic pop
  149. #endif