LLVM 22.0.0git
MachineInstrBundleIterator.h
Go to the documentation of this file.
1//===- llvm/CodeGen/MachineInstrBundleIterator.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//
9// Defines an iterator class that bundles MachineInstr.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
14#define LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
15
16#include "llvm/ADT/ilist.h"
18#include <cassert>
19#include <iterator>
20#include <type_traits>
21
22namespace llvm {
23
24template <class T, bool IsReverse> struct MachineInstrBundleIteratorTraits;
49
50template <bool IsReverse> struct MachineInstrBundleIteratorHelper;
52 /// Get the beginning of the current bundle.
53 template <class Iterator> static Iterator getBundleBegin(Iterator I) {
54 if (!I.isEnd())
55 while (I->isBundledWithPred())
56 --I;
57 return I;
58 }
59
60 /// Get the final node of the current bundle.
61 template <class Iterator> static Iterator getBundleFinal(Iterator I) {
62 if (!I.isEnd())
63 while (I->isBundledWithSucc())
64 ++I;
65 return I;
66 }
67
68 /// Increment forward ilist iterator.
69 template <class Iterator> static void increment(Iterator &I) {
70 I = std::next(getBundleFinal(I));
71 }
72
73 /// Decrement forward ilist iterator.
74 template <class Iterator> static void decrement(Iterator &I) {
75 I = getBundleBegin(std::prev(I));
76 }
77};
78
80 /// Get the beginning of the current bundle.
81 template <class Iterator> static Iterator getBundleBegin(Iterator I) {
83 I.getReverse())
84 .getReverse();
85 }
86
87 /// Get the final node of the current bundle.
88 template <class Iterator> static Iterator getBundleFinal(Iterator I) {
90 I.getReverse())
91 .getReverse();
92 }
93
94 /// Increment reverse ilist iterator.
95 template <class Iterator> static void increment(Iterator &I) {
96 I = getBundleBegin(std::next(I));
97 }
98
99 /// Decrement reverse ilist iterator.
100 template <class Iterator> static void decrement(Iterator &I) {
101 I = std::prev(getBundleFinal(I));
102 }
103};
104
105/// MachineBasicBlock iterator that automatically skips over MIs that are
106/// inside bundles (i.e. walk top level MIs only).
107template <typename Ty, bool IsReverse = false>
110 using instr_iterator = typename Traits::instr_iterator;
111
112 instr_iterator MII;
113
114public:
115 using value_type = typename instr_iterator::value_type;
116 using difference_type = typename instr_iterator::difference_type;
117 using pointer = typename instr_iterator::pointer;
118 using reference = typename instr_iterator::reference;
119 using const_pointer = typename instr_iterator::const_pointer;
120 using const_reference = typename instr_iterator::const_reference;
121 using iterator_category = std::bidirectional_iterator_tag;
122
123private:
124 using nonconst_instr_iterator = typename Traits::nonconst_instr_iterator;
125 using const_instr_iterator = typename Traits::const_instr_iterator;
126 using nonconst_iterator =
127 MachineInstrBundleIterator<typename nonconst_instr_iterator::value_type,
128 IsReverse>;
129 using reverse_iterator = MachineInstrBundleIterator<Ty, !IsReverse>;
130
131public:
132 MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {
133 assert((!MI.getNodePtr() || MI.isEnd() || !MI->isBundledWithPred()) &&
134 "It's not legal to initialize MachineInstrBundleIterator with a "
135 "bundled MI");
136 }
137
139 assert(!MI.isBundledWithPred() && "It's not legal to initialize "
140 "MachineInstrBundleIterator with a "
141 "bundled MI");
142 }
143
145 // FIXME: This conversion should be explicit.
146 assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize "
147 "MachineInstrBundleIterator "
148 "with a bundled MI");
149 }
150
151 // Template allows conversion from const to nonconst.
152 template <class OtherTy>
155 std::enable_if_t<std::is_convertible<OtherTy *, Ty *>::value, void *> =
156 nullptr)
157 : MII(I.getInstrIterator()) {}
158
159 MachineInstrBundleIterator() : MII(nullptr) {}
160
161 /// Explicit conversion between forward/reverse iterators.
162 ///
163 /// Translate between forward and reverse iterators without changing range
164 /// boundaries. The resulting iterator will dereference (and have a handle)
165 /// to the previous node, which is somewhat unexpected; but converting the
166 /// two endpoints in a range will give the same range in reverse.
167 ///
168 /// This matches std::reverse_iterator conversions.
172
173 /// Get the bundle iterator for the given instruction's bundle.
177
178 reference operator*() const { return *MII; }
179 pointer operator->() const { return &operator*(); }
180
181 /// Check for null.
182 bool isValid() const { return MII.getNodePtr(); }
183
186 return L.MII == R.MII;
187 }
189 const const_instr_iterator &R) {
190 return L.MII == R; // Avoid assertion about validity of R.
191 }
192 friend bool operator==(const const_instr_iterator &L,
194 return L == R.MII; // Avoid assertion about validity of L.
195 }
197 const nonconst_instr_iterator &R) {
198 return L.MII == R; // Avoid assertion about validity of R.
199 }
200 friend bool operator==(const nonconst_instr_iterator &L,
202 return L == R.MII; // Avoid assertion about validity of L.
203 }
205 return L == const_instr_iterator(R); // Avoid assertion about validity of R.
206 }
208 return const_instr_iterator(L) == R; // Avoid assertion about validity of L.
209 }
211 const_reference R) {
212 return L == &R; // Avoid assertion about validity of R.
213 }
216 return &L == R; // Avoid assertion about validity of L.
217 }
218
221 return !(L == R);
222 }
224 const const_instr_iterator &R) {
225 return !(L == R);
226 }
227 friend bool operator!=(const const_instr_iterator &L,
229 return !(L == R);
230 }
232 const nonconst_instr_iterator &R) {
233 return !(L == R);
234 }
235 friend bool operator!=(const nonconst_instr_iterator &L,
237 return !(L == R);
238 }
240 return !(L == R);
241 }
243 return !(L == R);
244 }
246 const_reference R) {
247 return !(L == R);
248 }
251 return !(L == R);
252 }
253
254 // Increment and decrement operators...
256 this->decrement(MII);
257 return *this;
258 }
260 this->increment(MII);
261 return *this;
262 }
264 MachineInstrBundleIterator Temp = *this;
265 --*this;
266 return Temp;
267 }
269 MachineInstrBundleIterator Temp = *this;
270 ++*this;
271 return Temp;
272 }
273
274 instr_iterator getInstrIterator() const { return MII; }
275
276 nonconst_iterator getNonConstIterator() const { return MII.getNonConst(); }
277
278 /// Get a reverse iterator to the same node.
279 ///
280 /// Gives a reverse iterator that will dereference (and have a handle) to the
281 /// same node. Converting the endpoint iterators in a range will give a
282 /// different range; for range operations, use the explicit conversions.
283 reverse_iterator getReverse() const { return MII.getReverse(); }
284};
285
286} // end namespace llvm
287
288#endif // LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:58
#define T
friend bool operator!=(const MachineInstrBundleIterator &L, const MachineInstrBundleIterator &R)
friend bool operator!=(const MachineInstrBundleIterator &L, const const_instr_iterator &R)
friend bool operator==(const nonconst_instr_iterator &L, const MachineInstrBundleIterator &R)
friend bool operator==(const const_instr_iterator &L, const MachineInstrBundleIterator &R)
typename instr_iterator::difference_type difference_type
friend bool operator!=(const_reference L, const MachineInstrBundleIterator &R)
friend bool operator==(const MachineInstrBundleIterator &L, const nonconst_instr_iterator &R)
friend bool operator==(const MachineInstrBundleIterator &L, const_pointer R)
friend bool operator!=(const const_instr_iterator &L, const MachineInstrBundleIterator &R)
friend bool operator!=(const_pointer L, const MachineInstrBundleIterator &R)
MachineInstrBundleIterator(const MachineInstrBundleIterator< OtherTy, IsReverse > &I, std::enable_if_t< std::is_convertible< OtherTy *, Ty * >::value, void * >=nullptr)
friend bool operator==(const MachineInstrBundleIterator &L, const MachineInstrBundleIterator &R)
friend bool operator==(const MachineInstrBundleIterator &L, const const_instr_iterator &R)
friend bool operator==(const MachineInstrBundleIterator &L, const_reference R)
MachineInstrBundleIterator & operator++()
friend bool operator!=(const MachineInstrBundleIterator &L, const nonconst_instr_iterator &R)
friend bool operator!=(const MachineInstrBundleIterator &L, const_pointer R)
MachineInstrBundleIterator & operator--()
friend bool operator==(const_reference L, const MachineInstrBundleIterator &R)
friend bool operator!=(const nonconst_instr_iterator &L, const MachineInstrBundleIterator &R)
MachineInstrBundleIterator operator--(int)
friend bool operator!=(const MachineInstrBundleIterator &L, const_reference R)
static MachineInstrBundleIterator getAtBundleBegin(instr_iterator MI)
Get the bundle iterator for the given instruction's bundle.
MachineInstrBundleIterator(const MachineInstrBundleIterator< Ty, !IsReverse > &I)
Explicit conversion between forward/reverse iterators.
friend bool operator==(const_pointer L, const MachineInstrBundleIterator &R)
typename instr_iterator::const_reference const_reference
MachineInstrBundleIterator operator++(int)
A simple intrusive list implementation.
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, true, true >::type const_reverse_iterator
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, true, false >::type reverse_iterator
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, false, false >::type iterator
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, false, true >::type const_iterator
This file defines classes to implement an intrusive doubly linked list class (i.e.
This is an optimization pass for GlobalISel generic memory operations.
static Iterator getBundleBegin(Iterator I)
Get the beginning of the current bundle.
static void increment(Iterator &I)
Increment forward ilist iterator.
static Iterator getBundleFinal(Iterator I)
Get the final node of the current bundle.
static void decrement(Iterator &I)
Decrement forward ilist iterator.
static Iterator getBundleFinal(Iterator I)
Get the final node of the current bundle.
static Iterator getBundleBegin(Iterator I)
Get the beginning of the current bundle.
static void decrement(Iterator &I)
Decrement reverse ilist iterator.
static void increment(Iterator &I)
Increment reverse ilist iterator.
simple_ilist< T, ilist_sentinel_tracking< true > > list_type
typename list_type::reverse_iterator nonconst_instr_iterator
typename list_type::const_reverse_iterator const_instr_iterator
simple_ilist< T, ilist_sentinel_tracking< true > > list_type
simple_ilist< T, ilist_sentinel_tracking< true > > list_type
simple_ilist< T, ilist_sentinel_tracking< true > > list_type
typename list_type::const_reverse_iterator instr_iterator
typename list_type::const_reverse_iterator const_instr_iterator