forked from OSchip/llvm-project
[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:
parent
3c92db7560
commit
5c0c063ad5
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue