diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-09-11 18:51:28 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-09-11 18:51:28 +0000 |
commit | d546df8daf879ae9d9a8a3492cfcd9cfedb81d9e (patch) | |
tree | 85b1c7bffcf0febb8091a7a64e9c2c74eac121a6 /unittests/CodeGen | |
parent | ce85c7eb57a0a867896afc521d2c3eadabe36bc1 (diff) |
CodeGen: Give MachineBasicBlock::reverse_iterator a handle to the current MI
Now that MachineBasicBlock::reverse_instr_iterator knows when it's at
the end (since r281168 and r281170), implement
MachineBasicBlock::reverse_iterator directly on top of an
ilist::reverse_iterator by adding an IsReverse template parameter to
MachineInstrBundleIterator. This replaces another hard-to-reason-about
use of std::reverse_iterator on list iterators, matching the changes for
ilist::reverse_iterator from r280032 (see the "out of scope" section at
the end of that commit message). MachineBasicBlock::reverse_iterator
now has a handle to the current node and has obvious invalidation
semantics.
r280032 has a more detailed explanation of how list-style reverse
iterators (invalidated when the pointed-at node is deleted) are
different from vector-style reverse iterators like std::reverse_iterator
(invalidated on every operation). A great motivating example is this
commit's changes to lib/CodeGen/DeadMachineInstructionElim.cpp.
Note: If your out-of-tree backend deletes instructions while iterating
on a MachineBasicBlock::reverse_iterator or converts between
MachineBasicBlock::iterator and MachineBasicBlock::reverse_iterator,
you'll need to update your code in similar ways to r280032. The
following table might help:
[Old] ==> [New]
delete &*RI, RE = end() delete &*RI++
RI->erase(), RE = end() RI++->erase()
reverse_iterator(I) std::prev(I).getReverse()
reverse_iterator(I) ++I.getReverse()
--reverse_iterator(I) I.getReverse()
reverse_iterator(std::next(I)) I.getReverse()
RI.base() std::prev(RI).getReverse()
RI.base() ++RI.getReverse()
--RI.base() RI.getReverse()
std::next(RI).base() RI.getReverse()
(For more details, have a look at r280032.)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281172 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/CodeGen')
-rw-r--r-- | unittests/CodeGen/MachineInstrBundleIteratorTest.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp b/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp index ca61fcbe59f..416f5774f4c 100644 --- a/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp +++ b/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp @@ -22,25 +22,47 @@ struct MyBundledInstr }; typedef MachineInstrBundleIterator<MyBundledInstr> bundled_iterator; typedef MachineInstrBundleIterator<const MyBundledInstr> const_bundled_iterator; +typedef MachineInstrBundleIterator<MyBundledInstr, true> + reverse_bundled_iterator; +typedef MachineInstrBundleIterator<const MyBundledInstr, true> + const_reverse_bundled_iterator; #ifdef GTEST_HAS_DEATH_TEST #ifndef NDEBUG TEST(MachineInstrBundleIteratorTest, CheckForBundles) { MyBundledInstr MBI; + auto I = MBI.getIterator(); + auto RI = I.getReverse(); // 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>(I), + "not legal to initialize"); 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>(I), + "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"); + EXPECT_DEATH((void)static_cast<reverse_bundled_iterator>(RI), + "not legal to initialize"); + EXPECT_DEATH((void)static_cast<reverse_bundled_iterator>(MBI), + "not legal to initialize"); + EXPECT_DEATH((void)static_cast<reverse_bundled_iterator>(&MBI), + "not legal to initialize"); + EXPECT_DEATH((void)static_cast<const_reverse_bundled_iterator>(RI), + "not legal to initialize"); + EXPECT_DEATH((void)static_cast<const_reverse_bundled_iterator>(MBI), + "not legal to initialize"); + EXPECT_DEATH((void)static_cast<const_reverse_bundled_iterator>(&MBI), + "not legal to initialize"); } #endif #endif |