diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/ADT/ilist.h | 18 | ||||
| -rw-r--r-- | llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h | 67 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDILCFGStructurizer.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/R600InstrInfo.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsConstantIslandPass.cpp | 3 | ||||
| -rw-r--r-- | llvm/unittests/CodeGen/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp | 94 |
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 |

