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 added an overload of reverse() which
is enabled just for filter_iterator ranges. The overload invalidates the
original range and creates a new filter_iterator range using reverse
iterators.
I'd appreciate any comments about how to make this cleaner. The only
alternative approach I considered was to get filter_iterator to adopt
bidirectional_iterator_tag and define an operator-- conditionally, but I
couldn't get this to work out.
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
Can we use std::rbegin() and std::rend() instead of C.rbegin() and C.rend()? This way it works for arrays too.