Skip to content

Commit

Permalink
[LPM] Conclude my immediate work by making the LoopVectorizer
Browse files Browse the repository at this point in the history
a FunctionPass. With this change the loop vectorizer no longer is a loop
pass and can readily depend on function analyses. In particular, with
this change we no longer have to form a loop pass manager to run the
loop vectorizer which simplifies the entire pass management of LLVM.

The next step here is to teach the loop vectorizer to leverage profile
information through the profile information providing analysis passes.

llvm-svn: 200074
  • Loading branch information
chandlerc committed Jan 25, 2014
1 parent ff974ab commit 3aebcb9
Showing 1 changed file with 37 additions and 8 deletions.
45 changes: 37 additions & 8 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -930,13 +930,21 @@ struct LoopVectorizeHints {
}
};

static void addInnerLoop(Loop *L, SmallVectorImpl<Loop *> &V) {
if (L->empty())
return V.push_back(L);

for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
addInnerLoop(*I, V);
}

/// The LoopVectorize Pass.
struct LoopVectorize : public LoopPass {
struct LoopVectorize : public FunctionPass {
/// Pass identification, replacement for typeid
static char ID;

explicit LoopVectorize(bool NoUnrolling = false, bool AlwaysVectorize = true)
: LoopPass(ID),
: FunctionPass(ID),
DisableUnrolling(NoUnrolling),
AlwaysVectorize(AlwaysVectorize) {
initializeLoopVectorizePass(*PassRegistry::getPassRegistry());
Expand All @@ -951,11 +959,7 @@ struct LoopVectorize : public LoopPass {
bool DisableUnrolling;
bool AlwaysVectorize;

virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
// We only vectorize innermost loops.
if (!L->empty())
return false;

virtual bool runOnFunction(Function &F) {
SE = &getAnalysis<ScalarEvolution>();
DL = getAnalysisIfAvailable<DataLayout>();
LI = &getAnalysis<LoopInfo>();
Expand All @@ -973,6 +977,32 @@ struct LoopVectorize : public LoopPass {
return false;
}

// Build up a worklist of inner-loops to vectorize. This is necessary as
// the act of vectorizing or partially unrolling a loop creates new loops
// and can invalidate iterators across the loops.
SmallVector<Loop *, 8> Worklist;

for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
addInnerLoop(*I, Worklist);

// Now walk the identified inner loops.
bool Changed = false;
while (!Worklist.empty())
Changed |= processLoop(Worklist.pop_back_val());

// Process each loop nest in the function.
return Changed;
}

bool processLoop(Loop *L) {
// We only handle inner loops, so if there are children just recurse.
if (!L->empty()) {
bool Changed = false;
for (Loop::iterator I = L->begin(), E = L->begin(); I != E; ++I)
Changed |= processLoop(*I);
return Changed;
}

DEBUG(dbgs() << "LV: Checking a loop in \"" <<
L->getHeader()->getParent()->getName() << "\"\n");

Expand Down Expand Up @@ -1052,7 +1082,6 @@ struct LoopVectorize : public LoopPass {
}

virtual void getAnalysisUsage(AnalysisUsage &AU) const {
LoopPass::getAnalysisUsage(AU);
AU.addRequiredID(LoopSimplifyID);
AU.addRequiredID(LCSSAID);
AU.addRequired<DominatorTreeWrapperPass>();
Expand Down

0 comments on commit 3aebcb9

Please sign in to comment.