1 //===- llvm/CodeGen/MachineInstrBundleIterator.h ----------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Defines an iterator class that bundles MachineInstr. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H 15 #define LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H 16 17 #include "llvm/ADT/ilist.h" 18 #include <iterator> 19 20 namespace llvm { 21 22 /// MachineBasicBlock iterator that automatically skips over MIs that are 23 /// inside bundles (i.e. walk top level MIs only). 24 template <typename Ty> 25 class MachineInstrBundleIterator 26 : public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> { 27 typedef std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> super; 28 typedef ilist_iterator<Ty> instr_iterator; 29 instr_iterator MII; 30 31 public: 32 typedef typename super::value_type value_type; 33 typedef typename super::difference_type difference_type; 34 typedef typename super::pointer pointer; 35 typedef typename super::reference reference; 36 37 typedef typename instr_iterator::const_pointer const_pointer; 38 typedef typename instr_iterator::const_reference const_reference; 39 40 private: 41 typedef typename std::remove_const<value_type>::type nonconst_value_type; 42 typedef ilist_node<nonconst_value_type> node_type; 43 typedef ilist_iterator<nonconst_value_type> nonconst_instr_iterator; 44 typedef MachineInstrBundleIterator<nonconst_value_type> nonconst_iterator; 45 46 public: 47 MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {} 48 49 MachineInstrBundleIterator(reference MI) : MII(MI) { 50 assert(!MI.isBundledWithPred() && "It's not legal to initialize " 51 "MachineInstrBundleIterator with a " 52 "bundled MI"); 53 } 54 MachineInstrBundleIterator(pointer MI) : MII(MI) { 55 // FIXME: This conversion should be explicit. 56 assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize " 57 "MachineInstrBundleIterator " 58 "with a bundled MI"); 59 } 60 // Template allows conversion from const to nonconst. 61 template <class OtherTy> 62 MachineInstrBundleIterator( 63 const MachineInstrBundleIterator<OtherTy> &I, 64 typename std::enable_if<std::is_convertible<OtherTy *, Ty *>::value, 65 void *>::type = nullptr) 66 : MII(I.getInstrIterator()) {} 67 MachineInstrBundleIterator() : MII(nullptr) {} 68 69 reference operator*() const { return *MII; } 70 pointer operator->() const { return &operator*(); } 71 72 /// Check for null. 73 bool isValid() const { return MII.getNodePtr(); } 74 75 friend bool operator==(const MachineInstrBundleIterator &L, 76 const MachineInstrBundleIterator &R) { 77 return L.MII == R.MII; 78 } 79 friend bool operator==(const MachineInstrBundleIterator &L, const_pointer R) { 80 // Avoid assertion about validity of R. 81 return L.MII == instr_iterator(const_cast<pointer>(R)); 82 } 83 friend bool operator==(const_pointer L, const MachineInstrBundleIterator &R) { 84 // Avoid assertion about validity of L. 85 return instr_iterator(const_cast<pointer>(L)) == R.MII; 86 } 87 friend bool operator==(const MachineInstrBundleIterator &L, 88 const_reference R) { 89 return L == &R; // Avoid assertion about validity of R. 90 } 91 friend bool operator==(const_reference L, 92 const MachineInstrBundleIterator &R) { 93 return &L == R; // Avoid assertion about validity of L. 94 } 95 96 friend bool operator!=(const MachineInstrBundleIterator &L, 97 const MachineInstrBundleIterator &R) { 98 return !(L == R); 99 } 100 friend bool operator!=(const MachineInstrBundleIterator &L, const_pointer R) { 101 return !(L == R); 102 } 103 friend bool operator!=(const_pointer L, const MachineInstrBundleIterator &R) { 104 return !(L == R); 105 } 106 friend bool operator!=(const MachineInstrBundleIterator &L, 107 const_reference R) { 108 return !(L == R); 109 } 110 friend bool operator!=(const_reference L, 111 const MachineInstrBundleIterator &R) { 112 return !(L == R); 113 } 114 115 // Increment and decrement operators... 116 MachineInstrBundleIterator &operator--() { 117 do 118 --MII; 119 while (MII->isBundledWithPred()); 120 return *this; 121 } 122 MachineInstrBundleIterator &operator++() { 123 while (MII->isBundledWithSucc()) 124 ++MII; 125 ++MII; 126 return *this; 127 } 128 MachineInstrBundleIterator operator--(int) { 129 MachineInstrBundleIterator Temp = *this; 130 --*this; 131 return Temp; 132 } 133 MachineInstrBundleIterator operator++(int) { 134 MachineInstrBundleIterator Temp = *this; 135 ++*this; 136 return Temp; 137 } 138 139 instr_iterator getInstrIterator() const { return MII; } 140 141 nonconst_iterator getNonConstIterator() const { 142 if (auto *N = const_cast<node_type *>(MII.getNodePtr())) 143 return nonconst_iterator(nonconst_instr_iterator(*N)); 144 return nonconst_iterator(); 145 } 146 }; 147 148 } // end namespace llvm 149 150 #endif 151