MachineInstrBundleIterator.h revision 304240
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
20namespace llvm {
21
22/// MachineBasicBlock iterator that automatically skips over MIs that are
23/// inside bundles (i.e. walk top level MIs only).
24template <typename Ty>
25class MachineInstrBundleIterator
26    : public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> {
27  typedef ilist_iterator<Ty> instr_iterator;
28  instr_iterator MII;
29
30public:
31  MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {}
32
33  MachineInstrBundleIterator(Ty &MI) : MII(MI) {
34    assert(!MI.isBundledWithPred() && "It's not legal to initialize "
35                                      "MachineInstrBundleIterator with a "
36                                      "bundled MI");
37  }
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>
46  MachineInstrBundleIterator(const MachineInstrBundleIterator<OtherTy> &I)
47      : MII(I.getInstrIterator()) {}
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
87  instr_iterator getInstrIterator() const { return MII; }
88};
89
90} // end namespace llvm
91
92#endif
93