summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/IR/BasicBlockTest.cpp
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2018-04-25 21:50:09 +0000
committerVedant Kumar <vsk@apple.com>2018-04-25 21:50:09 +0000
commit75fda2e0a5530b72443712bd9606bbd48f884817 (patch)
tree1013f47f87ff72d11d7cd3a53b14ed888614938d /llvm/unittests/IR/BasicBlockTest.cpp
parent1eeb26293d76039094406f43c7339986a622cfb0 (diff)
downloadbcm5719-llvm-75fda2e0a5530b72443712bd9606bbd48f884817.tar.gz
bcm5719-llvm-75fda2e0a5530b72443712bd9606bbd48f884817.zip
[ADT] Make filter_iterator support bidirectional iteration
This makes it possible to reverse a filtered range. For example, here's a way to visit memory accesses in a BasicBlock in reverse order: auto MemInsts = reverse(make_filter_range(BB, [](Instruction &I) { return isa<StoreInst>(&I) || isa<LoadInst>(&I); })); for (auto &MI : MemInsts) ... To implement this functionality, I factored out forward iteration functionality into filter_iterator_base, and added a specialization of filter_iterator_impl which supports bidirectional iteration. Thanks to Tim Shen, Zachary Turner, and others for suggesting this design and providing feedback! This version of the patch supersedes the original (https://reviews.llvm.org/D45792). This was motivated by a problem we encountered in D45657: we'd like to visit the non-debug-info instructions in a BasicBlock in reverse order. Testing: check-llvm, check-clang Differential Revision: https://reviews.llvm.org/D45853 llvm-svn: 330875
Diffstat (limited to 'llvm/unittests/IR/BasicBlockTest.cpp')
-rw-r--r--llvm/unittests/IR/BasicBlockTest.cpp9
1 files changed, 9 insertions, 0 deletions
diff --git a/llvm/unittests/IR/BasicBlockTest.cpp b/llvm/unittests/IR/BasicBlockTest.cpp
index 5e3b11e434b..07ed997f638 100644
--- a/llvm/unittests/IR/BasicBlockTest.cpp
+++ b/llvm/unittests/IR/BasicBlockTest.cpp
@@ -69,6 +69,15 @@ TEST(BasicBlockTest, PhiRange) {
CI = BB->phis().begin();
EXPECT_NE(CI, BB->phis().end());
+ // Test that filtering iterators work with basic blocks.
+ auto isPhi = [](Instruction &I) { return isa<PHINode>(&I); };
+ auto Phis = make_filter_range(*BB, isPhi);
+ auto ReversedPhis = reverse(make_filter_range(*BB, isPhi));
+ EXPECT_EQ(std::distance(Phis.begin(), Phis.end()), 3);
+ EXPECT_EQ(&*Phis.begin(), P1);
+ EXPECT_EQ(std::distance(ReversedPhis.begin(), ReversedPhis.end()), 3);
+ EXPECT_EQ(&*ReversedPhis.begin(), P3);
+
// And iterate a const range.
for (const auto &PN : const_cast<const BasicBlock *>(BB.get())->phis()) {
EXPECT_EQ(BB.get(), PN.getIncomingBlock(0));
OpenPOWER on IntegriCloud