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;
|
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
|
/// Store the result of a depth first search within basic blocks contained by a
|
||||||
/// single loop.
|
/// single loop.
|
||||||
///
|
///
|
||||||
|
|
|
@ -221,63 +221,6 @@ class LoopVectorizationLegality;
|
||||||
class LoopVectorizationCostModel;
|
class LoopVectorizationCostModel;
|
||||||
class LoopVectorizationRequirements;
|
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
|
/// Returns true if the given loop body has a cycle, excluding the loop
|
||||||
/// itself.
|
/// itself.
|
||||||
static bool hasCyclesInLoopBody(const Loop &L) {
|
static bool hasCyclesInLoopBody(const Loop &L) {
|
||||||
|
|
Loading…
Reference in New Issue