summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/ADT/ilist.h18
-rw-r--r--llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h67
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp4
-rw-r--r--llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp16
-rw-r--r--llvm/lib/Target/AMDGPU/R600InstrInfo.cpp5
-rw-r--r--llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsConstantIslandPass.cpp3
-rw-r--r--llvm/unittests/CodeGen/CMakeLists.txt1
-rw-r--r--llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp94
9 files changed, 175 insertions, 35 deletions
diff --git a/llvm/include/llvm/ADT/ilist.h b/llvm/include/llvm/ADT/ilist.h
index a7c72e86ced..6744ddd6c9b 100644
--- a/llvm/include/llvm/ADT/ilist.h
+++ b/llvm/include/llvm/ADT/ilist.h
@@ -43,6 +43,7 @@
#include <cassert>
#include <cstddef>
#include <iterator>
+#include <type_traits>
namespace llvm {
@@ -210,6 +211,9 @@ public:
typedef typename super::pointer pointer;
typedef typename super::reference reference;
+ typedef typename std::add_const<value_type>::type *const_pointer;
+ typedef typename std::add_const<value_type>::type &const_reference;
+
typedef typename ilist_detail::ConstCorrectNodeType<NodeTy>::type node_type;
typedef node_type *node_pointer;
typedef node_type &node_reference;
@@ -229,7 +233,10 @@ public:
// This is templated so that we can allow constructing a const iterator from
// a nonconst iterator...
template <class node_ty>
- ilist_iterator(const ilist_iterator<node_ty> &RHS)
+ ilist_iterator(
+ const ilist_iterator<node_ty> &RHS,
+ typename std::enable_if<std::is_convertible<node_ty *, NodeTy *>::value,
+ void *>::type = nullptr)
: NodePtr(RHS.getNodePtrUnchecked()) {}
// This is templated so that we can allow assigning to a const iterator from
@@ -243,16 +250,15 @@ public:
void reset(pointer NP) { NodePtr = NP; }
// Accessors...
- explicit operator pointer() const { return NodePtr; }
reference operator*() const { return *NodePtr; }
pointer operator->() const { return &operator*(); }
// Comparison operators
- template <class Y> bool operator==(const ilist_iterator<Y> &RHS) const {
- return NodePtr == RHS.getNodePtrUnchecked();
+ friend bool operator==(const ilist_iterator &LHS, const ilist_iterator &RHS) {
+ return LHS.NodePtr == RHS.NodePtr;
}
- template <class Y> bool operator!=(const ilist_iterator<Y> &RHS) const {
- return NodePtr != RHS.getNodePtrUnchecked();
+ friend bool operator!=(const ilist_iterator &LHS, const ilist_iterator &RHS) {
+ return LHS.NodePtr != RHS.NodePtr;
}
// Increment and decrement operators...
diff --git a/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h b/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
index c24fee8493e..8ee3a16b36a 100644
--- a/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
+++ b/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
@@ -24,18 +24,27 @@ namespace llvm {
template <typename Ty>
class MachineInstrBundleIterator
: public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> {
+ typedef std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> super;
typedef ilist_iterator<Ty> instr_iterator;
instr_iterator MII;
public:
+ typedef typename super::value_type value_type;
+ typedef typename super::difference_type difference_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+
+ typedef typename instr_iterator::const_pointer const_pointer;
+ typedef typename instr_iterator::const_reference const_reference;
+
MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {}
- MachineInstrBundleIterator(Ty &MI) : MII(MI) {
+ MachineInstrBundleIterator(reference MI) : MII(MI) {
assert(!MI.isBundledWithPred() && "It's not legal to initialize "
"MachineInstrBundleIterator with a "
"bundled MI");
}
- MachineInstrBundleIterator(Ty *MI) : MII(MI) {
+ MachineInstrBundleIterator(pointer MI) : MII(MI) {
// FIXME: This conversion should be explicit.
assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize "
"MachineInstrBundleIterator "
@@ -43,21 +52,57 @@ public:
}
// Template allows conversion from const to nonconst.
template <class OtherTy>
- MachineInstrBundleIterator(const MachineInstrBundleIterator<OtherTy> &I)
+ MachineInstrBundleIterator(
+ const MachineInstrBundleIterator<OtherTy> &I,
+ typename std::enable_if<std::is_convertible<OtherTy *, Ty *>::value,
+ void *>::type = nullptr)
: MII(I.getInstrIterator()) {}
MachineInstrBundleIterator() : MII(nullptr) {}
- Ty &operator*() const { return *MII; }
- Ty *operator->() const { return &operator*(); }
+ reference operator*() const { return *MII; }
+ pointer operator->() const { return &operator*(); }
- // FIXME: This should be implemented as "return &operator*()" (or removed).
- explicit operator Ty *() const { return MII.getNodePtrUnchecked(); }
+ /// Check for null.
+ bool isValid() const { return MII.getNodePtr(); }
- bool operator==(const MachineInstrBundleIterator &X) const {
- return MII == X.MII;
+ friend bool operator==(const MachineInstrBundleIterator &L,
+ const MachineInstrBundleIterator &R) {
+ return L.MII == R.MII;
+ }
+ friend bool operator==(const MachineInstrBundleIterator &L, const_pointer R) {
+ // Avoid assertion about validity of R.
+ return L.MII == instr_iterator(const_cast<pointer>(R));
+ }
+ friend bool operator==(const_pointer L, const MachineInstrBundleIterator &R) {
+ // Avoid assertion about validity of L.
+ return instr_iterator(const_cast<pointer>(L)) == R.MII;
+ }
+ 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);
+ }
+ 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);
}
- bool operator!=(const MachineInstrBundleIterator &X) const {
- return !operator==(X);
+ friend bool operator!=(const_reference L,
+ const MachineInstrBundleIterator &R) {
+ return !(L == R);
}
// Increment and decrement operators...
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 0fd5bb5897c..1d961af70de 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -353,8 +353,8 @@ void FastISel::recomputeInsertPt() {
void FastISel::removeDeadCode(MachineBasicBlock::iterator I,
MachineBasicBlock::iterator E) {
- assert(static_cast<MachineInstr *>(I) && static_cast<MachineInstr *>(E) &&
- std::distance(I, E) > 0 && "Invalid iterator!");
+ assert(I.isValid() && E.isValid() && std::distance(I, E) > 0 &&
+ "Invalid iterator!");
while (I != E) {
MachineInstr *Dead = &*I;
++I;
diff --git a/llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp b/llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp
index 21de76396b1..94a5355c916 100644
--- a/llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp
@@ -423,25 +423,21 @@ bool AMDGPUCFGStructurizer::needMigrateBlock(MachineBasicBlock *MBB) const {
void AMDGPUCFGStructurizer::reversePredicateSetter(
MachineBasicBlock::iterator I) {
- assert(static_cast<MachineInstr *>(I) && "Expected valid iterator");
+ assert(I.isValid() && "Expected valid iterator");
for (;; --I) {
if (I->getOpcode() == AMDGPU::PRED_X) {
- switch (static_cast<MachineInstr *>(I)->getOperand(2).getImm()) {
+ switch (I->getOperand(2).getImm()) {
case OPCODE_IS_ZERO_INT:
- static_cast<MachineInstr *>(I)->getOperand(2)
- .setImm(OPCODE_IS_NOT_ZERO_INT);
+ I->getOperand(2).setImm(OPCODE_IS_NOT_ZERO_INT);
return;
case OPCODE_IS_NOT_ZERO_INT:
- static_cast<MachineInstr *>(I)->getOperand(2)
- .setImm(OPCODE_IS_ZERO_INT);
+ I->getOperand(2).setImm(OPCODE_IS_ZERO_INT);
return;
case OPCODE_IS_ZERO:
- static_cast<MachineInstr *>(I)->getOperand(2)
- .setImm(OPCODE_IS_NOT_ZERO);
+ I->getOperand(2).setImm(OPCODE_IS_NOT_ZERO);
return;
case OPCODE_IS_NOT_ZERO:
- static_cast<MachineInstr *>(I)->getOperand(2)
- .setImm(OPCODE_IS_ZERO);
+ I->getOperand(2).setImm(OPCODE_IS_ZERO);
return;
default:
llvm_unreachable("PRED_X Opcode invalid!");
diff --git a/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp b/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp
index 08b95a5be64..573b18744ba 100644
--- a/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp
@@ -665,7 +665,7 @@ bool R600InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
// handled
if (isBranch(I->getOpcode()))
return true;
- if (!isJump(static_cast<MachineInstr *>(I)->getOpcode())) {
+ if (!isJump(I->getOpcode())) {
return false;
}
@@ -680,8 +680,7 @@ bool R600InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
// If there is only one terminator instruction, process it.
unsigned LastOpc = LastInst.getOpcode();
- if (I == MBB.begin() ||
- !isJump(static_cast<MachineInstr *>(--I)->getOpcode())) {
+ if (I == MBB.begin() || !isJump((--I)->getOpcode())) {
if (LastOpc == AMDGPU::JUMP) {
TBB = LastInst.getOperand(0).getMBB();
return false;
diff --git a/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
index bcebf5d034c..361bba7f878 100644
--- a/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
@@ -606,7 +606,7 @@ void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,
for (auto NewMI : DbgMItoMove) {
// If iterator MI is pointing to DEBUG_VAL, make sure
// MI now points to next relevant instruction.
- if (NewMI == (MachineInstr*)MI)
+ if (NewMI == MI)
++MI;
BB->splice(InsertPt, BB, NewMI);
}
diff --git a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
index 6531b32594f..cbc5e4bdd4e 100644
--- a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
+++ b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
@@ -1301,8 +1301,7 @@ void MipsConstantIslands::createNewWater(unsigned CPUserIndex,
Offset < BaseInsertOffset;
Offset += TII->getInstSizeInBytes(*MI), MI = std::next(MI)) {
assert(MI != UserMBB->end() && "Fell off end of block");
- if (CPUIndex < NumCPUsers &&
- CPUsers[CPUIndex].MI == static_cast<MachineInstr *>(MI)) {
+ if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) {
CPUser &U = CPUsers[CPUIndex];
if (!isOffsetInRange(Offset, EndInsertOffset, U)) {
// Shift intertion point by one unit of alignment so it is within reach.
diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt
index 56b7b0099a1..240734dc6b1 100644
--- a/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/llvm/unittests/CodeGen/CMakeLists.txt
@@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
set(CodeGenSources
DIEHashTest.cpp
LowLevelTypeTest.cpp
+ MachineInstrBundleIteratorTest.cpp
)
add_llvm_unittest(CodeGenTests
diff --git a/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp b/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp
new file mode 100644
index 00000000000..857994a3b29
--- /dev/null
+++ b/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp
@@ -0,0 +1,94 @@
+//===- MachineInstrBundleIteratorTest.cpp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/CodeGen/MachineInstrBundleIterator.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+struct MyBundledInstr : public ilist_node<MyBundledInstr> {
+ bool isBundledWithPred() const { return true; }
+ bool isBundledWithSucc() const { return true; }
+};
+typedef MachineInstrBundleIterator<MyBundledInstr> bundled_iterator;
+typedef MachineInstrBundleIterator<const MyBundledInstr> const_bundled_iterator;
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+TEST(MachineInstrBundleIteratorTest, CheckForBundles) {
+ MyBundledInstr MBI;
+
+ // Confirm that MBI is always considered bundled.
+ EXPECT_TRUE(MBI.isBundledWithPred());
+ EXPECT_TRUE(MBI.isBundledWithSucc());
+
+ // Confirm that iterators check in their constructor for bundled iterators.
+ EXPECT_DEATH((void)static_cast<bundled_iterator>(MBI),
+ "not legal to initialize");
+ EXPECT_DEATH((void)static_cast<bundled_iterator>(&MBI),
+ "not legal to initialize");
+ EXPECT_DEATH((void)static_cast<const_bundled_iterator>(MBI),
+ "not legal to initialize");
+ EXPECT_DEATH((void)static_cast<const_bundled_iterator>(&MBI),
+ "not legal to initialize");
+}
+#endif
+#endif
+
+TEST(MachineInstrBundleIteratorTest, CompareToBundledMI) {
+ MyBundledInstr MBI;
+ const MyBundledInstr &CMBI = MBI;
+ bundled_iterator I;
+ const_bundled_iterator CI;
+
+ // Confirm that MBI is always considered bundled.
+ EXPECT_TRUE(MBI.isBundledWithPred());
+ EXPECT_TRUE(MBI.isBundledWithSucc());
+
+ // These invocations will crash when !NDEBUG if a conversion is taking place.
+ // These checks confirm that comparison operators don't use any conversion
+ // operators.
+ ASSERT_FALSE(MBI == I);
+ ASSERT_FALSE(&MBI == I);
+ ASSERT_FALSE(CMBI == I);
+ ASSERT_FALSE(&CMBI == I);
+ ASSERT_FALSE(I == MBI);
+ ASSERT_FALSE(I == &MBI);
+ ASSERT_FALSE(I == CMBI);
+ ASSERT_FALSE(I == &CMBI);
+ ASSERT_FALSE(MBI == CI);
+ ASSERT_FALSE(&MBI == CI);
+ ASSERT_FALSE(CMBI == CI);
+ ASSERT_FALSE(&CMBI == CI);
+ ASSERT_FALSE(CI == MBI);
+ ASSERT_FALSE(CI == &MBI);
+ ASSERT_FALSE(CI == CMBI);
+ ASSERT_FALSE(CI == &CMBI);
+ ASSERT_TRUE(MBI != I);
+ ASSERT_TRUE(&MBI != I);
+ ASSERT_TRUE(CMBI != I);
+ ASSERT_TRUE(&CMBI != I);
+ ASSERT_TRUE(I != MBI);
+ ASSERT_TRUE(I != &MBI);
+ ASSERT_TRUE(I != CMBI);
+ ASSERT_TRUE(I != &CMBI);
+ ASSERT_TRUE(MBI != CI);
+ ASSERT_TRUE(&MBI != CI);
+ ASSERT_TRUE(CMBI != CI);
+ ASSERT_TRUE(&CMBI != CI);
+ ASSERT_TRUE(CI != MBI);
+ ASSERT_TRUE(CI != &MBI);
+ ASSERT_TRUE(CI != CMBI);
+ ASSERT_TRUE(CI != &CMBI);
+}
+
+} // end namespace
OpenPOWER on IntegriCloud