LLVM  10.0.0svn
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"
17 #include "llvm/ADT/simple_ilist.h"
18 #include <cassert>
19 #include <iterator>
20 #include <type_traits>
21 
22 namespace llvm {
23 
24 template <class T, bool IsReverse> struct MachineInstrBundleIteratorTraits;
25 template <class T> struct MachineInstrBundleIteratorTraits<T, false> {
30 };
31 template <class T> struct MachineInstrBundleIteratorTraits<T, true> {
36 };
37 template <class T> struct MachineInstrBundleIteratorTraits<const T, false> {
42 };
43 template <class T> struct MachineInstrBundleIteratorTraits<const T, true> {
48 };
49 
50 template <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).
107 template <typename Ty, bool IsReverse = false>
110  using instr_iterator = typename Traits::instr_iterator;
111 
112  instr_iterator MII;
113 
114 public:
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 
123 private:
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 
131 public:
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  typename std::enable_if<std::is_convertible<OtherTy *, Ty *>::value,
156  void *>::type = 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.
171  : MachineInstrBundleIterator(++I.getReverse()) {}
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 
185  const MachineInstrBundleIterator &R) {
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,
193  const MachineInstrBundleIterator &R) {
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,
201  const MachineInstrBundleIterator &R) {
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  }
215  const MachineInstrBundleIterator &R) {
216  return &L == R; // Avoid assertion about validity of L.
217  }
218 
220  const MachineInstrBundleIterator &R) {
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,
228  const MachineInstrBundleIterator &R) {
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,
236  const MachineInstrBundleIterator &R) {
237  return !(L == R);
238  }
240  return !(L == R);
241  }
243  return !(L == R);
244  }
246  const_reference R) {
247  return !(L == R);
248  }
250  const MachineInstrBundleIterator &R) {
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
MachineInstrBundleIterator & operator--()
static void decrement(Iterator &I)
Decrement reverse ilist iterator.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
typename list_type::reverse_iterator nonconst_instr_iterator
friend bool operator!=(const MachineInstrBundleIterator &L, const nonconst_instr_iterator &R)
MachineInstrBundleIterator(const MachineInstrBundleIterator< Ty, !IsReverse > &I)
Explicit conversion between forward/reverse iterators.
block Block Frequency true
friend bool operator!=(const_reference L, const MachineInstrBundleIterator &R)
static Iterator getBundleFinal(Iterator I)
Get the final node of the current bundle.
typename list_type::const_reverse_iterator instr_iterator
friend bool operator==(const MachineInstrBundleIterator &L, const_pointer R)
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i...
friend bool operator!=(const MachineInstrBundleIterator &L, const_reference R)
static void increment(Iterator &I)
Increment forward ilist iterator.
friend bool operator==(const MachineInstrBundleIterator &L, const const_instr_iterator &R)
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2099
friend bool operator==(const_pointer L, const MachineInstrBundleIterator &R)
A simple intrusive list implementation.
Definition: simple_ilist.h:78
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
friend bool operator==(const MachineInstrBundleIterator &L, const_reference R)
friend bool operator!=(const const_instr_iterator &L, const MachineInstrBundleIterator &R)
friend bool operator!=(const_pointer L, const MachineInstrBundleIterator &R)
friend bool operator!=(const MachineInstrBundleIterator &L, const_pointer R)
typename list_type::const_reverse_iterator const_instr_iterator
static MachineInstrBundleIterator getAtBundleBegin(instr_iterator MI)
Get the bundle iterator for the given instruction&#39;s bundle.
friend bool operator!=(const nonconst_instr_iterator &L, const MachineInstrBundleIterator &R)
static Iterator getBundleFinal(Iterator I)
Get the final node of the current bundle.
Iterator for intrusive lists based on ilist_node.
MachineInstrBundleIterator operator++(int)
friend bool operator==(const_reference L, const MachineInstrBundleIterator &R)
MachineInstrBundleIterator & operator++()
static Iterator getBundleBegin(Iterator I)
Get the beginning of the current bundle.
typename list_type::const_reverse_iterator const_instr_iterator
friend bool operator==(const MachineInstrBundleIterator &L, const MachineInstrBundleIterator &R)
#define I(x, y, z)
Definition: MD5.cpp:58
MachineInstrBundleIterator(const MachineInstrBundleIterator< OtherTy, IsReverse > &I, typename std::enable_if< std::is_convertible< OtherTy *, Ty *>::value, void *>::type=nullptr)
static void increment(Iterator &I)
Increment reverse ilist iterator.
friend bool operator==(const const_instr_iterator &L, const MachineInstrBundleIterator &R)
MachineInstrBundleIterator operator--(int)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void decrement(Iterator &I)
Decrement forward ilist iterator.
aarch64 promote const
nonconst_iterator getNonConstIterator() const
friend bool operator==(const MachineInstrBundleIterator &L, const nonconst_instr_iterator &R)
friend bool operator!=(const MachineInstrBundleIterator &L, const MachineInstrBundleIterator &R)
IRTranslator LLVM IR MI
friend bool operator!=(const MachineInstrBundleIterator &L, const const_instr_iterator &R)
friend bool operator==(const nonconst_instr_iterator &L, const MachineInstrBundleIterator &R)
static Iterator getBundleBegin(Iterator I)
Get the beginning of the current bundle.