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 ilist_iterator<Ty> instr_iterator; 28 instr_iterator MII; 29 30 public: MachineInstrBundleIterator(instr_iterator MI)31 MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {} 32 MachineInstrBundleIterator(Ty & MI)33 MachineInstrBundleIterator(Ty &MI) : MII(MI) { 34 assert(!MI.isBundledWithPred() && "It's not legal to initialize " 35 "MachineInstrBundleIterator with a " 36 "bundled MI"); 37 } MachineInstrBundleIterator(Ty * MI)38 MachineInstrBundleIterator(Ty *MI) : MII(MI) { 39 // FIXME: This conversion should be explicit. 40 assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize " 41 "MachineInstrBundleIterator " 42 "with a bundled MI"); 43 } 44 // Template allows conversion from const to nonconst. 45 template <class OtherTy> MachineInstrBundleIterator(const MachineInstrBundleIterator<OtherTy> & I)46 MachineInstrBundleIterator(const MachineInstrBundleIterator<OtherTy> &I) 47 : MII(I.getInstrIterator()) {} MachineInstrBundleIterator()48 MachineInstrBundleIterator() : MII(nullptr) {} 49 50 Ty &operator*() const { return *MII; } 51 Ty *operator->() const { return &operator*(); } 52 53 // FIXME: This conversion should be explicit. 54 operator Ty *() const { return MII.getNodePtrUnchecked(); } 55 56 bool operator==(const MachineInstrBundleIterator &X) const { 57 return MII == X.MII; 58 } 59 bool operator!=(const MachineInstrBundleIterator &X) const { 60 return !operator==(X); 61 } 62 63 // Increment and decrement operators... 64 MachineInstrBundleIterator &operator--() { 65 do 66 --MII; 67 while (MII->isBundledWithPred()); 68 return *this; 69 } 70 MachineInstrBundleIterator &operator++() { 71 while (MII->isBundledWithSucc()) 72 ++MII; 73 ++MII; 74 return *this; 75 } 76 MachineInstrBundleIterator operator--(int) { 77 MachineInstrBundleIterator Temp = *this; 78 --*this; 79 return Temp; 80 } 81 MachineInstrBundleIterator operator++(int) { 82 MachineInstrBundleIterator Temp = *this; 83 ++*this; 84 return Temp; 85 } 86 getInstrIterator()87 instr_iterator getInstrIterator() const { return MII; } 88 }; 89 90 } // end namespace llvm 91 92 #endif 93