LLVM 19.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;
25template <class T> struct MachineInstrBundleIteratorTraits<T, false> {
30};
31template <class T> struct MachineInstrBundleIteratorTraits<T, true> {
36};
37template <class T> struct MachineInstrBundleIteratorTraits<const T, false> {
42};
43template <class T> struct MachineInstrBundleIteratorTraits<const T, true> {
48};
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>;
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.
176 }
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
aarch64 promote const
basic Basic Alias true
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i....
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)
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
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)
nonconst_iterator getNonConstIterator() const
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)
typename instr_iterator::value_type value_type
MachineInstrBundleIterator & operator++()
friend bool operator!=(const MachineInstrBundleIterator &L, const nonconst_instr_iterator &R)
friend bool operator!=(const MachineInstrBundleIterator &L, const_pointer R)
typename instr_iterator::pointer pointer
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)
std::bidirectional_iterator_tag iterator_category
friend bool operator!=(const MachineInstrBundleIterator &L, const_reference R)
typename instr_iterator::const_pointer const_pointer
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::reference reference
typename instr_iterator::const_reference const_reference
MachineInstrBundleIterator operator++(int)
A simple intrusive list implementation.
Definition: simple_ilist.h:81
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, true, false >::type reverse_iterator
Definition: simple_ilist.h:103
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, true, true >::type const_reverse_iterator
Definition: simple_ilist.h:106
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, false, false >::type iterator
Definition: simple_ilist.h:97
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, false, true >::type const_iterator
Definition: simple_ilist.h:100
This file defines classes to implement an intrusive doubly linked list class (i.e.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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.
typename list_type::reverse_iterator nonconst_instr_iterator
typename list_type::const_reverse_iterator const_instr_iterator
typename list_type::const_reverse_iterator instr_iterator
typename list_type::const_reverse_iterator const_instr_iterator