[LV] Move LoopBodyTraits to a better place, and add comment for simplifying LoopBlocksTraversal. NFC.

Summary: I later (after r278573) found that LoopIterator.h has some overlapping with LoopBodyTraits. It's good to use LoopBodyTraits because a *Traits struct is algorithm independent.

Reviewers: anemet, nadav, mkuper

Subscribers: mzolotukhin, llvm-commits

Differential Revision: https://reviews.llvm.org/D23529

llvm-svn: 278996
This commit is contained in:
Tim Shen 2016-08-17 22:20:07 +00:00
parent 3c92db7560
commit 5c0c063ad5
2 changed files with 60 additions and 57 deletions

View File

@ -31,6 +31,66 @@ namespace llvm {
class LoopBlocksTraversal;
// A traits type that is intended to be used in graph algorithms. The graph
// traits starts at the loop header, and traverses the BasicBlocks that are in
// the loop body, but not the loop header. Since the loop header is skipped,
// the back edges are excluded.
//
// TODO: Explore the possibility to implement LoopBlocksTraversal in terms of
// LoopBodyTraits, so that insertEdge doesn't have to be specialized.
struct LoopBodyTraits {
using NodeRef = std::pair<const Loop *, BasicBlock *>;
// This wraps a const Loop * into the iterator, so we know which edges to
// filter out.
class WrappedSuccIterator
: public iterator_adaptor_base<
WrappedSuccIterator, succ_iterator,
typename std::iterator_traits<succ_iterator>::iterator_category,
NodeRef, std::ptrdiff_t, NodeRef *, NodeRef> {
using BaseT = iterator_adaptor_base<
WrappedSuccIterator, succ_iterator,
typename std::iterator_traits<succ_iterator>::iterator_category,
NodeRef, std::ptrdiff_t, NodeRef *, NodeRef>;
const Loop *L;
public:
WrappedSuccIterator(succ_iterator Begin, const Loop *L)
: BaseT(Begin), L(L) {}
NodeRef operator*() const { return {L, *I}; }
};
struct LoopBodyFilter {
bool operator()(NodeRef N) const {
const Loop *L = N.first;
return N.second != L->getHeader() && L->contains(N.second);
}
};
using ChildIteratorType =
filter_iterator<WrappedSuccIterator, LoopBodyFilter>;
static NodeRef getEntryNode(const Loop &G) { return {&G, G.getHeader()}; }
static ChildIteratorType child_begin(NodeRef Node) {
return make_filter_range(make_range<WrappedSuccIterator>(
{succ_begin(Node.second), Node.first},
{succ_end(Node.second), Node.first}),
LoopBodyFilter{})
.begin();
}
static ChildIteratorType child_end(NodeRef Node) {
return make_filter_range(make_range<WrappedSuccIterator>(
{succ_begin(Node.second), Node.first},
{succ_end(Node.second), Node.first}),
LoopBodyFilter{})
.end();
}
};
/// Store the result of a depth first search within basic blocks contained by a
/// single loop.
///

View File

@ -221,63 +221,6 @@ class LoopVectorizationLegality;
class LoopVectorizationCostModel;
class LoopVectorizationRequirements;
// A traits type that is intended to be used in graph algorithms. The graph it
// models starts at the loop header, and traverses the BasicBlocks that are in
// the loop body, but not the loop header. Since the loop header is skipped,
// the back edges are excluded.
struct LoopBodyTraits {
using NodeRef = std::pair<const Loop *, BasicBlock *>;
// This wraps a const Loop * into the iterator, so we know which edges to
// filter out.
class WrappedSuccIterator
: public iterator_adaptor_base<
WrappedSuccIterator, succ_iterator,
typename std::iterator_traits<succ_iterator>::iterator_category,
NodeRef, std::ptrdiff_t, NodeRef *, NodeRef> {
using BaseT = iterator_adaptor_base<
WrappedSuccIterator, succ_iterator,
typename std::iterator_traits<succ_iterator>::iterator_category,
NodeRef, std::ptrdiff_t, NodeRef *, NodeRef>;
const Loop *L;
public:
WrappedSuccIterator(succ_iterator Begin, const Loop *L)
: BaseT(Begin), L(L) {}
NodeRef operator*() const { return {L, *I}; }
};
struct LoopBodyFilter {
bool operator()(NodeRef N) const {
const Loop *L = N.first;
return N.second != L->getHeader() && L->contains(N.second);
}
};
using ChildIteratorType =
filter_iterator<WrappedSuccIterator, LoopBodyFilter>;
static NodeRef getEntryNode(const Loop &G) { return {&G, G.getHeader()}; }
static ChildIteratorType child_begin(NodeRef Node) {
return make_filter_range(make_range<WrappedSuccIterator>(
{succ_begin(Node.second), Node.first},
{succ_end(Node.second), Node.first}),
LoopBodyFilter{})
.begin();
}
static ChildIteratorType child_end(NodeRef Node) {
return make_filter_range(make_range<WrappedSuccIterator>(
{succ_begin(Node.second), Node.first},
{succ_end(Node.second), Node.first}),
LoopBodyFilter{})
.end();
}
};
/// Returns true if the given loop body has a cycle, excluding the loop
/// itself.
static bool hasCyclesInLoopBody(const Loop &L) {