class LoopIdiomRecognize : public LoopPass {
Loop *CurLoop;
DominatorTree *DT;
+ LoopInfo *LI;
ScalarEvolution *SE;
TargetLibraryInfo *TLI;
const TargetTransformInfo *TTI;
static char ID;
explicit LoopIdiomRecognize() : LoopPass(ID) {
initializeLoopIdiomRecognizePass(*PassRegistry::getPassRegistry());
- DT = nullptr;
- SE = nullptr;
- TLI = nullptr;
- TTI = nullptr;
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
AU.addRequired<TargetTransformInfoWrapperPass>();
}
- DominatorTree *getDominatorTree() {
- return DT ? DT
- : (DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree());
- }
-
- ScalarEvolution *getScalarEvolution() {
- return SE ? SE : (SE = &getAnalysis<ScalarEvolution>());
- }
-
- TargetLibraryInfo *getTargetLibraryInfo() {
- if (!TLI)
- TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
-
- return TLI;
- }
-
- const TargetTransformInfo *getTargetTransformInfo() {
- return TTI ? TTI
- : (TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
- *CurLoop->getHeader()->getParent()));
- }
-
- Loop *getLoop() const { return CurLoop; }
-
private:
/// \name Countable Loop Idiom Handling
/// @{
return false;
CurLoop = L;
-
// If the loop could not be converted to canonical form, it must have an
// indirectbr in it, just give up.
if (!L->getLoopPreheader())
if (Name == "memset" || Name == "memcpy")
return false;
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
SE = &getAnalysis<ScalarEvolution>();
+ TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
+ TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
+ *CurLoop->getHeader()->getParent());
+
if (SE->hasLoopInvariantBackedgeTakenCount(L))
return runOnCountableLoop();
+
return runOnNoncountableLoop();
}
if (BECst->getValue()->getValue() == 0)
return false;
- // set DT
- (void)getDominatorTree();
-
- LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
-
- // set TLI
- (void)getTargetLibraryInfo();
-
SmallVector<BasicBlock *, 8> ExitBlocks;
CurLoop->getUniqueExitBlocks(ExitBlocks);
// Scan all the blocks in the loop that are not in subloops.
for (auto *BB : CurLoop->getBlocks()) {
// Ignore blocks in subloops.
- if (LI.getLoopFor(BB) != CurLoop)
+ if (LI->getLoopFor(BB) != CurLoop)
continue;
MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
/// If detected, transforms the relevant code to issue the popcount intrinsic
/// function call, and returns true; otherwise, returns false.
bool LoopIdiomRecognize::recognizePopcount() {
- (void)getScalarEvolution();
- (void)getTargetLibraryInfo();
- (void)getTargetTransformInfo();
-
if (TTI->getPopcntSupport(32) != TargetTransformInfo::PSK_FastHardware)
return false;
// non-compact loop. Therefore, recognizing popcount idiom only makes sense
// in a compact loop.
- // Give up if the loop has multiple blocks or multiple backedges.
- if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 1)
+ assert(CurLoop->isLoopSimplifyForm() &&
+ "Loop passes require simplified form!");
+
+ // Give up if the loop has multiple blocks.
+ if (CurLoop->getNumBlocks() != 1)
return false;
- BasicBlock *LoopBody = *(CurLoop->block_begin());
- if (LoopBody->size() >= 20) {
- // The loop is too big, bail out.
+ // If the loop is too big, bail out.
+ BasicBlock &LoopBB = *CurLoop->getHeader();
+ if (LoopBB.size() >= 20)
return false;
- }
// It should have a preheader containing nothing but an unconditional branch.
- BasicBlock *PH = CurLoop->getLoopPreheader();
- if (!PH)
- return false;
- if (&PH->front() != PH->getTerminator())
+ BasicBlock &PH = *CurLoop->getLoopPreheader();
+ if (&PH.front() != PH.getTerminator())
return false;
- auto *EntryBI = dyn_cast<BranchInst>(PH->getTerminator());
+ // FIXME: Technically, it shouldn't matter what instruction we use as
+ // a terminator, the only property needed is the definition of a preheader:
+ // a single loop predecessor whose only successor is the loop header.
+ auto *EntryBI = dyn_cast<BranchInst>(PH.getTerminator());
if (!EntryBI || EntryBI->isConditional())
return false;
// It should have a precondition block where the generated popcount instrinsic
// function can be inserted.
- auto *PreCondBB = PH->getSinglePredecessor();
+ auto *PreCondBB = PH.getSinglePredecessor();
if (!PreCondBB)
return false;
auto *PreCondBI = dyn_cast<BranchInst>(PreCondBB->getTerminator());