2016-02-21 22:05:50 +00:00
|
|
|
//===- llvm/CodeGen/MachineInstrBundleIterator.h ----------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Defines an iterator class that bundles MachineInstr.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
|
|
|
|
#define LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
|
|
|
|
|
|
|
|
#include "llvm/ADT/ilist.h"
|
2017-05-31 01:10:10 +00:00
|
|
|
#include "llvm/ADT/simple_ilist.h"
|
|
|
|
#include <cassert>
|
2016-02-21 22:05:50 +00:00
|
|
|
#include <iterator>
|
2017-05-31 01:10:10 +00:00
|
|
|
#include <type_traits>
|
2016-02-21 22:05:50 +00:00
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
2016-09-11 18:51:28 +00:00
|
|
|
template <class T, bool IsReverse> struct MachineInstrBundleIteratorTraits;
|
|
|
|
template <class T> struct MachineInstrBundleIteratorTraits<T, false> {
|
2017-05-31 01:10:10 +00:00
|
|
|
using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
|
|
|
|
using instr_iterator = typename list_type::iterator;
|
|
|
|
using nonconst_instr_iterator = typename list_type::iterator;
|
|
|
|
using const_instr_iterator = typename list_type::const_iterator;
|
2016-09-11 16:20:53 +00:00
|
|
|
};
|
2016-09-11 18:51:28 +00:00
|
|
|
template <class T> struct MachineInstrBundleIteratorTraits<T, true> {
|
2017-05-31 01:10:10 +00:00
|
|
|
using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
|
|
|
|
using instr_iterator = typename list_type::reverse_iterator;
|
|
|
|
using nonconst_instr_iterator = typename list_type::reverse_iterator;
|
|
|
|
using const_instr_iterator = typename list_type::const_reverse_iterator;
|
2016-09-11 18:51:28 +00:00
|
|
|
};
|
|
|
|
template <class T> struct MachineInstrBundleIteratorTraits<const T, false> {
|
2017-05-31 01:10:10 +00:00
|
|
|
using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
|
|
|
|
using instr_iterator = typename list_type::const_iterator;
|
|
|
|
using nonconst_instr_iterator = typename list_type::iterator;
|
|
|
|
using const_instr_iterator = typename list_type::const_iterator;
|
2016-09-11 16:20:53 +00:00
|
|
|
};
|
2016-09-11 18:51:28 +00:00
|
|
|
template <class T> struct MachineInstrBundleIteratorTraits<const T, true> {
|
2017-05-31 01:10:10 +00:00
|
|
|
using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
|
|
|
|
using instr_iterator = typename list_type::const_reverse_iterator;
|
|
|
|
using nonconst_instr_iterator = typename list_type::reverse_iterator;
|
|
|
|
using const_instr_iterator = typename list_type::const_reverse_iterator;
|
2016-09-11 18:51:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <bool IsReverse> struct MachineInstrBundleIteratorHelper;
|
|
|
|
template <> struct MachineInstrBundleIteratorHelper<false> {
|
|
|
|
/// Get the beginning of the current bundle.
|
|
|
|
template <class Iterator> static Iterator getBundleBegin(Iterator I) {
|
|
|
|
if (!I.isEnd())
|
|
|
|
while (I->isBundledWithPred())
|
|
|
|
--I;
|
|
|
|
return I;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the final node of the current bundle.
|
|
|
|
template <class Iterator> static Iterator getBundleFinal(Iterator I) {
|
|
|
|
if (!I.isEnd())
|
|
|
|
while (I->isBundledWithSucc())
|
|
|
|
++I;
|
|
|
|
return I;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Increment forward ilist iterator.
|
|
|
|
template <class Iterator> static void increment(Iterator &I) {
|
|
|
|
I = std::next(getBundleFinal(I));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Decrement forward ilist iterator.
|
|
|
|
template <class Iterator> static void decrement(Iterator &I) {
|
|
|
|
I = getBundleBegin(std::prev(I));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <> struct MachineInstrBundleIteratorHelper<true> {
|
|
|
|
/// Get the beginning of the current bundle.
|
|
|
|
template <class Iterator> static Iterator getBundleBegin(Iterator I) {
|
|
|
|
return MachineInstrBundleIteratorHelper<false>::getBundleBegin(
|
|
|
|
I.getReverse())
|
|
|
|
.getReverse();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the final node of the current bundle.
|
|
|
|
template <class Iterator> static Iterator getBundleFinal(Iterator I) {
|
|
|
|
return MachineInstrBundleIteratorHelper<false>::getBundleFinal(
|
|
|
|
I.getReverse())
|
|
|
|
.getReverse();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Increment reverse ilist iterator.
|
|
|
|
template <class Iterator> static void increment(Iterator &I) {
|
|
|
|
I = getBundleBegin(std::next(I));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Decrement reverse ilist iterator.
|
|
|
|
template <class Iterator> static void decrement(Iterator &I) {
|
|
|
|
I = std::prev(getBundleFinal(I));
|
|
|
|
}
|
|
|
|
};
|
2016-09-11 16:20:53 +00:00
|
|
|
|
2016-02-21 22:05:50 +00:00
|
|
|
/// MachineBasicBlock iterator that automatically skips over MIs that are
|
|
|
|
/// inside bundles (i.e. walk top level MIs only).
|
2016-09-11 18:51:28 +00:00
|
|
|
template <typename Ty, bool IsReverse = false>
|
|
|
|
class MachineInstrBundleIterator : MachineInstrBundleIteratorHelper<IsReverse> {
|
2017-05-31 01:10:10 +00:00
|
|
|
using Traits = MachineInstrBundleIteratorTraits<Ty, IsReverse>;
|
|
|
|
using instr_iterator = typename Traits::instr_iterator;
|
|
|
|
|
2016-02-21 22:05:50 +00:00
|
|
|
instr_iterator MII;
|
|
|
|
|
|
|
|
public:
|
2017-05-31 01:10:10 +00:00
|
|
|
using value_type = typename instr_iterator::value_type;
|
|
|
|
using difference_type = typename instr_iterator::difference_type;
|
|
|
|
using pointer = typename instr_iterator::pointer;
|
|
|
|
using reference = typename instr_iterator::reference;
|
|
|
|
using const_pointer = typename instr_iterator::const_pointer;
|
|
|
|
using const_reference = typename instr_iterator::const_reference;
|
|
|
|
using iterator_category = std::bidirectional_iterator_tag;
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
|
2016-08-16 23:34:07 +00:00
|
|
|
private:
|
2017-05-31 01:10:10 +00:00
|
|
|
using nonconst_instr_iterator = typename Traits::nonconst_instr_iterator;
|
|
|
|
using const_instr_iterator = typename Traits::const_instr_iterator;
|
|
|
|
using nonconst_iterator =
|
|
|
|
MachineInstrBundleIterator<typename nonconst_instr_iterator::value_type,
|
|
|
|
IsReverse>;
|
|
|
|
using reverse_iterator = MachineInstrBundleIterator<Ty, !IsReverse>;
|
2016-08-16 23:34:07 +00:00
|
|
|
|
|
|
|
public:
|
2016-09-11 17:12:28 +00:00
|
|
|
MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {
|
|
|
|
assert((!MI.getNodePtr() || MI.isEnd() || !MI->isBundledWithPred()) &&
|
|
|
|
"It's not legal to initialize MachineInstrBundleIterator with a "
|
|
|
|
"bundled MI");
|
|
|
|
}
|
2016-02-21 22:05:50 +00:00
|
|
|
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
MachineInstrBundleIterator(reference MI) : MII(MI) {
|
2016-02-21 22:05:50 +00:00
|
|
|
assert(!MI.isBundledWithPred() && "It's not legal to initialize "
|
|
|
|
"MachineInstrBundleIterator with a "
|
|
|
|
"bundled MI");
|
|
|
|
}
|
2017-05-31 01:10:10 +00:00
|
|
|
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
MachineInstrBundleIterator(pointer MI) : MII(MI) {
|
2016-02-21 22:05:50 +00:00
|
|
|
// FIXME: This conversion should be explicit.
|
|
|
|
assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize "
|
|
|
|
"MachineInstrBundleIterator "
|
|
|
|
"with a bundled MI");
|
|
|
|
}
|
2017-05-31 01:10:10 +00:00
|
|
|
|
2016-02-21 22:05:50 +00:00
|
|
|
// Template allows conversion from const to nonconst.
|
|
|
|
template <class OtherTy>
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
MachineInstrBundleIterator(
|
2016-09-11 18:51:28 +00:00
|
|
|
const MachineInstrBundleIterator<OtherTy, IsReverse> &I,
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
typename std::enable_if<std::is_convertible<OtherTy *, Ty *>::value,
|
|
|
|
void *>::type = nullptr)
|
2016-02-22 21:30:15 +00:00
|
|
|
: MII(I.getInstrIterator()) {}
|
2017-05-31 01:10:10 +00:00
|
|
|
|
2016-02-21 22:05:50 +00:00
|
|
|
MachineInstrBundleIterator() : MII(nullptr) {}
|
|
|
|
|
2017-02-07 21:03:50 +00:00
|
|
|
/// Explicit conversion between forward/reverse iterators.
|
|
|
|
///
|
|
|
|
/// Translate between forward and reverse iterators without changing range
|
|
|
|
/// boundaries. The resulting iterator will dereference (and have a handle)
|
|
|
|
/// to the previous node, which is somewhat unexpected; but converting the
|
|
|
|
/// two endpoints in a range will give the same range in reverse.
|
|
|
|
///
|
|
|
|
/// This matches std::reverse_iterator conversions.
|
|
|
|
explicit MachineInstrBundleIterator(
|
|
|
|
const MachineInstrBundleIterator<Ty, !IsReverse> &I)
|
|
|
|
: MachineInstrBundleIterator(++I.getReverse()) {}
|
|
|
|
|
2016-09-11 18:51:28 +00:00
|
|
|
/// Get the bundle iterator for the given instruction's bundle.
|
|
|
|
static MachineInstrBundleIterator getAtBundleBegin(instr_iterator MI) {
|
|
|
|
return MachineInstrBundleIteratorHelper<IsReverse>::getBundleBegin(MI);
|
|
|
|
}
|
|
|
|
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
reference operator*() const { return *MII; }
|
|
|
|
pointer operator->() const { return &operator*(); }
|
2016-02-21 22:05:50 +00:00
|
|
|
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
/// Check for null.
|
|
|
|
bool isValid() const { return MII.getNodePtr(); }
|
2016-02-21 22:05:50 +00:00
|
|
|
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
friend bool operator==(const MachineInstrBundleIterator &L,
|
|
|
|
const MachineInstrBundleIterator &R) {
|
|
|
|
return L.MII == R.MII;
|
|
|
|
}
|
2016-09-11 17:12:28 +00:00
|
|
|
friend bool operator==(const MachineInstrBundleIterator &L,
|
|
|
|
const const_instr_iterator &R) {
|
|
|
|
return L.MII == R; // Avoid assertion about validity of R.
|
|
|
|
}
|
|
|
|
friend bool operator==(const const_instr_iterator &L,
|
|
|
|
const MachineInstrBundleIterator &R) {
|
|
|
|
return L == R.MII; // Avoid assertion about validity of L.
|
|
|
|
}
|
|
|
|
friend bool operator==(const MachineInstrBundleIterator &L,
|
|
|
|
const nonconst_instr_iterator &R) {
|
|
|
|
return L.MII == R; // Avoid assertion about validity of R.
|
|
|
|
}
|
|
|
|
friend bool operator==(const nonconst_instr_iterator &L,
|
|
|
|
const MachineInstrBundleIterator &R) {
|
|
|
|
return L == R.MII; // Avoid assertion about validity of L.
|
|
|
|
}
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
friend bool operator==(const MachineInstrBundleIterator &L, const_pointer R) {
|
2016-09-11 17:12:28 +00:00
|
|
|
return L == const_instr_iterator(R); // Avoid assertion about validity of R.
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
}
|
|
|
|
friend bool operator==(const_pointer L, const MachineInstrBundleIterator &R) {
|
2016-09-11 17:12:28 +00:00
|
|
|
return const_instr_iterator(L) == R; // Avoid assertion about validity of L.
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
}
|
|
|
|
friend bool operator==(const MachineInstrBundleIterator &L,
|
|
|
|
const_reference R) {
|
|
|
|
return L == &R; // Avoid assertion about validity of R.
|
|
|
|
}
|
|
|
|
friend bool operator==(const_reference L,
|
|
|
|
const MachineInstrBundleIterator &R) {
|
|
|
|
return &L == R; // Avoid assertion about validity of L.
|
|
|
|
}
|
|
|
|
|
|
|
|
friend bool operator!=(const MachineInstrBundleIterator &L,
|
|
|
|
const MachineInstrBundleIterator &R) {
|
|
|
|
return !(L == R);
|
|
|
|
}
|
2016-09-11 17:12:28 +00:00
|
|
|
friend bool operator!=(const MachineInstrBundleIterator &L,
|
|
|
|
const const_instr_iterator &R) {
|
|
|
|
return !(L == R);
|
|
|
|
}
|
|
|
|
friend bool operator!=(const const_instr_iterator &L,
|
|
|
|
const MachineInstrBundleIterator &R) {
|
|
|
|
return !(L == R);
|
|
|
|
}
|
|
|
|
friend bool operator!=(const MachineInstrBundleIterator &L,
|
|
|
|
const nonconst_instr_iterator &R) {
|
|
|
|
return !(L == R);
|
|
|
|
}
|
|
|
|
friend bool operator!=(const nonconst_instr_iterator &L,
|
|
|
|
const MachineInstrBundleIterator &R) {
|
|
|
|
return !(L == R);
|
|
|
|
}
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
friend bool operator!=(const MachineInstrBundleIterator &L, const_pointer R) {
|
|
|
|
return !(L == R);
|
|
|
|
}
|
|
|
|
friend bool operator!=(const_pointer L, const MachineInstrBundleIterator &R) {
|
|
|
|
return !(L == R);
|
|
|
|
}
|
|
|
|
friend bool operator!=(const MachineInstrBundleIterator &L,
|
|
|
|
const_reference R) {
|
|
|
|
return !(L == R);
|
2016-02-21 22:05:50 +00:00
|
|
|
}
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 05:05:36 +00:00
|
|
|
friend bool operator!=(const_reference L,
|
|
|
|
const MachineInstrBundleIterator &R) {
|
|
|
|
return !(L == R);
|
2016-02-21 22:05:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Increment and decrement operators...
|
|
|
|
MachineInstrBundleIterator &operator--() {
|
2016-09-11 18:51:28 +00:00
|
|
|
this->decrement(MII);
|
2016-02-21 22:05:50 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
MachineInstrBundleIterator &operator++() {
|
2016-09-11 18:51:28 +00:00
|
|
|
this->increment(MII);
|
2016-02-21 22:05:50 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
MachineInstrBundleIterator operator--(int) {
|
|
|
|
MachineInstrBundleIterator Temp = *this;
|
|
|
|
--*this;
|
|
|
|
return Temp;
|
|
|
|
}
|
|
|
|
MachineInstrBundleIterator operator++(int) {
|
|
|
|
MachineInstrBundleIterator Temp = *this;
|
|
|
|
++*this;
|
|
|
|
return Temp;
|
|
|
|
}
|
|
|
|
|
2016-02-22 21:30:15 +00:00
|
|
|
instr_iterator getInstrIterator() const { return MII; }
|
2016-08-16 23:34:07 +00:00
|
|
|
|
2016-09-11 16:20:53 +00:00
|
|
|
nonconst_iterator getNonConstIterator() const { return MII.getNonConst(); }
|
2016-09-11 18:51:28 +00:00
|
|
|
|
2017-02-07 21:03:50 +00:00
|
|
|
/// Get a reverse iterator to the same node.
|
|
|
|
///
|
|
|
|
/// Gives a reverse iterator that will dereference (and have a handle) to the
|
|
|
|
/// same node. Converting the endpoint iterators in a range will give a
|
|
|
|
/// different range; for range operations, use the explicit conversions.
|
2016-09-11 18:51:28 +00:00
|
|
|
reverse_iterator getReverse() const { return MII.getReverse(); }
|
2016-02-21 22:05:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // end namespace llvm
|
|
|
|
|
2017-05-31 01:10:10 +00:00
|
|
|
#endif // LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
|