File indexing completed on 2026-05-10 08:43:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
0014 #define LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
0015
0016 #include "llvm/ADT/ilist.h"
0017 #include "llvm/ADT/simple_ilist.h"
0018 #include <cassert>
0019 #include <iterator>
0020 #include <type_traits>
0021
0022 namespace llvm {
0023
0024 template <class T, bool IsReverse> struct MachineInstrBundleIteratorTraits;
0025 template <class T> struct MachineInstrBundleIteratorTraits<T, false> {
0026 using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
0027 using instr_iterator = typename list_type::iterator;
0028 using nonconst_instr_iterator = typename list_type::iterator;
0029 using const_instr_iterator = typename list_type::const_iterator;
0030 };
0031 template <class T> struct MachineInstrBundleIteratorTraits<T, true> {
0032 using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
0033 using instr_iterator = typename list_type::reverse_iterator;
0034 using nonconst_instr_iterator = typename list_type::reverse_iterator;
0035 using const_instr_iterator = typename list_type::const_reverse_iterator;
0036 };
0037 template <class T> struct MachineInstrBundleIteratorTraits<const T, false> {
0038 using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
0039 using instr_iterator = typename list_type::const_iterator;
0040 using nonconst_instr_iterator = typename list_type::iterator;
0041 using const_instr_iterator = typename list_type::const_iterator;
0042 };
0043 template <class T> struct MachineInstrBundleIteratorTraits<const T, true> {
0044 using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
0045 using instr_iterator = typename list_type::const_reverse_iterator;
0046 using nonconst_instr_iterator = typename list_type::reverse_iterator;
0047 using const_instr_iterator = typename list_type::const_reverse_iterator;
0048 };
0049
0050 template <bool IsReverse> struct MachineInstrBundleIteratorHelper;
0051 template <> struct MachineInstrBundleIteratorHelper<false> {
0052
0053 template <class Iterator> static Iterator getBundleBegin(Iterator I) {
0054 if (!I.isEnd())
0055 while (I->isBundledWithPred())
0056 --I;
0057 return I;
0058 }
0059
0060
0061 template <class Iterator> static Iterator getBundleFinal(Iterator I) {
0062 if (!I.isEnd())
0063 while (I->isBundledWithSucc())
0064 ++I;
0065 return I;
0066 }
0067
0068
0069 template <class Iterator> static void increment(Iterator &I) {
0070 I = std::next(getBundleFinal(I));
0071 }
0072
0073
0074 template <class Iterator> static void decrement(Iterator &I) {
0075 I = getBundleBegin(std::prev(I));
0076 }
0077 };
0078
0079 template <> struct MachineInstrBundleIteratorHelper<true> {
0080
0081 template <class Iterator> static Iterator getBundleBegin(Iterator I) {
0082 return MachineInstrBundleIteratorHelper<false>::getBundleBegin(
0083 I.getReverse())
0084 .getReverse();
0085 }
0086
0087
0088 template <class Iterator> static Iterator getBundleFinal(Iterator I) {
0089 return MachineInstrBundleIteratorHelper<false>::getBundleFinal(
0090 I.getReverse())
0091 .getReverse();
0092 }
0093
0094
0095 template <class Iterator> static void increment(Iterator &I) {
0096 I = getBundleBegin(std::next(I));
0097 }
0098
0099
0100 template <class Iterator> static void decrement(Iterator &I) {
0101 I = std::prev(getBundleFinal(I));
0102 }
0103 };
0104
0105
0106
0107 template <typename Ty, bool IsReverse = false>
0108 class MachineInstrBundleIterator : MachineInstrBundleIteratorHelper<IsReverse> {
0109 using Traits = MachineInstrBundleIteratorTraits<Ty, IsReverse>;
0110 using instr_iterator = typename Traits::instr_iterator;
0111
0112 instr_iterator MII;
0113
0114 public:
0115 using value_type = typename instr_iterator::value_type;
0116 using difference_type = typename instr_iterator::difference_type;
0117 using pointer = typename instr_iterator::pointer;
0118 using reference = typename instr_iterator::reference;
0119 using const_pointer = typename instr_iterator::const_pointer;
0120 using const_reference = typename instr_iterator::const_reference;
0121 using iterator_category = std::bidirectional_iterator_tag;
0122
0123 private:
0124 using nonconst_instr_iterator = typename Traits::nonconst_instr_iterator;
0125 using const_instr_iterator = typename Traits::const_instr_iterator;
0126 using nonconst_iterator =
0127 MachineInstrBundleIterator<typename nonconst_instr_iterator::value_type,
0128 IsReverse>;
0129 using reverse_iterator = MachineInstrBundleIterator<Ty, !IsReverse>;
0130
0131 public:
0132 MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {
0133 assert((!MI.getNodePtr() || MI.isEnd() || !MI->isBundledWithPred()) &&
0134 "It's not legal to initialize MachineInstrBundleIterator with a "
0135 "bundled MI");
0136 }
0137
0138 MachineInstrBundleIterator(reference MI) : MII(MI) {
0139 assert(!MI.isBundledWithPred() && "It's not legal to initialize "
0140 "MachineInstrBundleIterator with a "
0141 "bundled MI");
0142 }
0143
0144 MachineInstrBundleIterator(pointer MI) : MII(MI) {
0145
0146 assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize "
0147 "MachineInstrBundleIterator "
0148 "with a bundled MI");
0149 }
0150
0151
0152 template <class OtherTy>
0153 MachineInstrBundleIterator(
0154 const MachineInstrBundleIterator<OtherTy, IsReverse> &I,
0155 std::enable_if_t<std::is_convertible<OtherTy *, Ty *>::value, void *> =
0156 nullptr)
0157 : MII(I.getInstrIterator()) {}
0158
0159 MachineInstrBundleIterator() : MII(nullptr) {}
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 explicit MachineInstrBundleIterator(
0170 const MachineInstrBundleIterator<Ty, !IsReverse> &I)
0171 : MachineInstrBundleIterator(++I.getReverse()) {}
0172
0173
0174 static MachineInstrBundleIterator getAtBundleBegin(instr_iterator MI) {
0175 return MachineInstrBundleIteratorHelper<IsReverse>::getBundleBegin(MI);
0176 }
0177
0178 reference operator*() const { return *MII; }
0179 pointer operator->() const { return &operator*(); }
0180
0181
0182 bool isValid() const { return MII.getNodePtr(); }
0183
0184 friend bool operator==(const MachineInstrBundleIterator &L,
0185 const MachineInstrBundleIterator &R) {
0186 return L.MII == R.MII;
0187 }
0188 friend bool operator==(const MachineInstrBundleIterator &L,
0189 const const_instr_iterator &R) {
0190 return L.MII == R;
0191 }
0192 friend bool operator==(const const_instr_iterator &L,
0193 const MachineInstrBundleIterator &R) {
0194 return L == R.MII;
0195 }
0196 friend bool operator==(const MachineInstrBundleIterator &L,
0197 const nonconst_instr_iterator &R) {
0198 return L.MII == R;
0199 }
0200 friend bool operator==(const nonconst_instr_iterator &L,
0201 const MachineInstrBundleIterator &R) {
0202 return L == R.MII;
0203 }
0204 friend bool operator==(const MachineInstrBundleIterator &L, const_pointer R) {
0205 return L == const_instr_iterator(R);
0206 }
0207 friend bool operator==(const_pointer L, const MachineInstrBundleIterator &R) {
0208 return const_instr_iterator(L) == R;
0209 }
0210 friend bool operator==(const MachineInstrBundleIterator &L,
0211 const_reference R) {
0212 return L == &R;
0213 }
0214 friend bool operator==(const_reference L,
0215 const MachineInstrBundleIterator &R) {
0216 return &L == R;
0217 }
0218
0219 friend bool operator!=(const MachineInstrBundleIterator &L,
0220 const MachineInstrBundleIterator &R) {
0221 return !(L == R);
0222 }
0223 friend bool operator!=(const MachineInstrBundleIterator &L,
0224 const const_instr_iterator &R) {
0225 return !(L == R);
0226 }
0227 friend bool operator!=(const const_instr_iterator &L,
0228 const MachineInstrBundleIterator &R) {
0229 return !(L == R);
0230 }
0231 friend bool operator!=(const MachineInstrBundleIterator &L,
0232 const nonconst_instr_iterator &R) {
0233 return !(L == R);
0234 }
0235 friend bool operator!=(const nonconst_instr_iterator &L,
0236 const MachineInstrBundleIterator &R) {
0237 return !(L == R);
0238 }
0239 friend bool operator!=(const MachineInstrBundleIterator &L, const_pointer R) {
0240 return !(L == R);
0241 }
0242 friend bool operator!=(const_pointer L, const MachineInstrBundleIterator &R) {
0243 return !(L == R);
0244 }
0245 friend bool operator!=(const MachineInstrBundleIterator &L,
0246 const_reference R) {
0247 return !(L == R);
0248 }
0249 friend bool operator!=(const_reference L,
0250 const MachineInstrBundleIterator &R) {
0251 return !(L == R);
0252 }
0253
0254
0255 MachineInstrBundleIterator &operator--() {
0256 this->decrement(MII);
0257 return *this;
0258 }
0259 MachineInstrBundleIterator &operator++() {
0260 this->increment(MII);
0261 return *this;
0262 }
0263 MachineInstrBundleIterator operator--(int) {
0264 MachineInstrBundleIterator Temp = *this;
0265 --*this;
0266 return Temp;
0267 }
0268 MachineInstrBundleIterator operator++(int) {
0269 MachineInstrBundleIterator Temp = *this;
0270 ++*this;
0271 return Temp;
0272 }
0273
0274 instr_iterator getInstrIterator() const { return MII; }
0275
0276 nonconst_iterator getNonConstIterator() const { return MII.getNonConst(); }
0277
0278
0279
0280
0281
0282
0283 reverse_iterator getReverse() const { return MII.getReverse(); }
0284 };
0285
0286 }
0287
0288 #endif