Professional Documents
Culture Documents
cpp Page 1 of 17
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/IVDescriptors.h"
#include "llvm/Analysis/LoopInfoImpl.h"
#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/LoopNestAnalysis.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PrintPasses.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// Loop implementation
//
// Hoist.
I->moveBefore(InsertPt);
if (MSSAU)
if (auto *MUD = MSSAU->getMemorySSA()->getMemoryAccess(I))
MSSAU->moveToPlace(MUD, InsertPt->getParent(),
MemorySSA::BeforeTerminator);
Changed = true;
return true;
}
Incoming = nullptr;
Backedge = nullptr;
pred_iterator PI = pred_begin(H);
assert(PI != pred_end(H) && "Loop must have at least one backedge!");
Backedge = *PI++;
if (PI == pred_end(H))
return false; // dead loop
Incoming = *PI++;
if (PI != pred_end(H))
return false; // multiple backedges?
if (contains(Incoming)) {
if (contains(Backedge))
return false;
std::swap(Incoming, Backedge);
} else if (!contains(Backedge))
return false;
// Loop over all of the PHI nodes, looking for a canonical indvar.
for (BasicBlock::iterator I = H->begin(); isa<PHINode>(I); ++I) {
PHINode *PN = cast<PHINode>(I);
if (ConstantInt *CI =
dyn_cast<ConstantInt>(PN->getIncomingValueForBlock(Incoming)))
if (CI->isZero())
if (Instruction *Inc =
dyn_cast<Instruction>(PN->getIncomingValueForBlock(Backedge)))
if (Inc->getOpcode() == Instruction::Add && Inc->getOperand(0) == PN)
if (ConstantInt *CI = dyn_cast<ConstantInt>(Inc->getOperand(1)))
if (CI->isOne())
return PN;
}
return nullptr;
}
return nullptr;
}
/// Return the final value of the loop induction variable if found.
static Value *findFinalIVValue(const Loop &L, const PHINode &IndVar,
const Instruction &StepInst) {
ICmpInst *LatchCmpInst = L.getLatchCmpInst();
if (!LatchCmpInst)
return nullptr;
return nullptr;
}
// Need to inverse the predicate when first successor is not the loop
// header
ICmpInst::Predicate Pred = (BI->getSuccessor(0) == L.getHeader())
? LatchCmpInst->getPredicate()
: LatchCmpInst->getInversePredicate();
if (LatchCmpInst->getOperand(0) == &getFinalIVValue())
Pred = ICmpInst::getSwappedPredicate(Pred);
// Need to flip strictness of the predicate when the latch compare instruction
// is not using StepInst
if (LatchCmpInst->getOperand(0) == &getStepInst() ||
LatchCmpInst->getOperand(1) == &getStepInst())
return Pred;
Direction D = getDirection();
if (D == Direction::Increasing)
return ICmpInst::ICMP_SLT;
if (D == Direction::Decreasing)
return ICmpInst::ICMP_SGT;
return Direction::Unknown;
}
return None;
}
File: /home/satanu/llvm-project/llvm/lib/Analysis/LoopInfo.cpp Page 5 of 17
// case 1:
// IndVar = phi[{InitialValue, preheader}, {StepInst, latch}]
// StepInst = IndVar + step
// cmp = StepInst < FinalValue
if (StepInst == LatchCmpOp0 || StepInst == LatchCmpOp1)
return &IndVar;
// case 2:
// IndVar = phi[{InitialValue, preheader}, {StepInst, latch}]
// StepInst = IndVar + step
// cmp = IndVar < FinalValue
if (&IndVar == LatchCmpOp0 || &IndVar == LatchCmpOp1)
return &IndVar;
}
return nullptr;
}
return false;
}
InductionDescriptor IndDesc;
if (!InductionDescriptor::isInductionPHI(&AuxIndVar, this, &SE, IndDesc))
return false;
// Disallow loops with more than one unique exit block, as we do not verify
// that GuardOtherSucc post dominates all exit blocks.
BasicBlock *ExitFromLatch = getUniqueExitBlock();
if (!ExitFromLatch)
return nullptr;
if (IndDesc.getInductionOpcode() != Instruction::Add)
return false;
return true;
}
// Check that 'BB' doesn't have any uses outside of the 'L'
static bool isBlockInLCSSAForm(const Loop &L, const BasicBlock &BB,
const DominatorTree &DT, bool IgnoreTokens) {
for (const Instruction &I : BB) {
// Tokens can't be used in PHI nodes and live-out tokens prevent loop
// optimizations, so for the purposes of considered LCSSA form, we
// can ignore them.
File: /home/satanu/llvm-project/llvm/lib/Analysis/LoopInfo.cpp Page 7 of 17
// Routines that reform the loop CFG and split edges often fail on indirectbr.
bool Loop::isSafeToClone() const {
// Return false if any loop blocks contain indirectbrs, or there are any calls
// to noduplicate functions.
for (BasicBlock *BB : this->blocks()) {
if (isa<IndirectBrInst>(BB->getTerminator()))
return false;
// Go through the latch blocks and check the terminator for the metadata.
SmallVector<BasicBlock *, 4> LatchesBlocks;
getLoopLatches(LatchesBlocks);
for (BasicBlock *BB : LatchesBlocks) {
Instruction *TI = BB->getTerminator();
File: /home/satanu/llvm-project/llvm/lib/Analysis/LoopInfo.cpp Page 8 of 17
if (!MD)
return nullptr;
if (!LoopID)
LoopID = MD;
else if (MD != LoopID)
return nullptr;
}
if (!LoopID || LoopID->getNumOperands() == 0 ||
LoopID->getOperand(0) != LoopID)
return nullptr;
return LoopID;
}
void Loop::setLoopAlreadyUnrolled() {
LLVMContext &Context = getHeader()->getContext();
MDNode *DisableUnrollMD =
MDNode::get(Context, MDString::get(Context, "llvm.loop.unroll.disable"));
MDNode *LoopID = getLoopID();
MDNode *NewLoopID = makePostTransformationMetadata(
Context, LoopID, {"llvm.loop.unroll."}, {DisableUnrollMD});
setLoopID(NewLoopID);
}
void Loop::setLoopMustProgress() {
LLVMContext &Context = getHeader()->getContext();
if (MustProgress)
return;
MDNode *MustProgressMD =
MDNode::get(Context, MDString::get(Context, "llvm.loop.mustprogress"));
MDNode *LoopID = getLoopID();
MDNode *NewLoopID =
makePostTransformationMetadata(Context, LoopID, {}, {MustProgressMD});
setLoopID(NewLoopID);
}
if (!DesiredLoopIdMetadata)
return false;
MDNode *ParallelAccesses =
findOptionMDForLoop(this, "llvm.loop.parallel_accesses");
SmallPtrSet<MDNode *, 4>
ParallelAccessGroups; // For scalable 'contains' check.
if (ParallelAccesses) {
for (const MDOperand &MD : drop_begin(ParallelAccesses->operands())) {
MDNode *AccGroup = cast<MDNode>(MD.get());
assert(isValidAsAccessGroup(AccGroup) &&
"List item must be an access group");
ParallelAccessGroups.insert(AccGroup);
}
File: /home/satanu/llvm-project/llvm/lib/Analysis/LoopInfo.cpp Page 9 of 17
// The loop branch contains the parallel loop metadata. In order to ensure
// that any parallel-loop-unaware optimization pass hasn't added loop-carried
// dependencies (thus converted the loop back to a sequential loop), check
// that all the memory instructions in the loop belong to an access group that
// is parallel to this loop.
for (BasicBlock *BB : this->blocks()) {
for (Instruction &I : *BB) {
if (!I.mayReadOrWriteMemory())
continue;
if (ContainsAccessGroup(AccessGroup))
continue;
}
if (!LoopIdMD)
return false;
if (!llvm::is_contained(LoopIdMD->operands(), DesiredLoopIdMetadata))
return false;
}
}
return true;
}
if (Start)
return LocRange(Start);
}
File: /home/satanu/llvm-project/llvm/lib/Analysis/LoopInfo.cpp Page 10 of 17
return LocRange();
}
//===----------------------------------------------------------------------===//
// UnloopUpdater implementation
//
namespace {
/// Find the new parent loop for all blocks within the "unloop" whose last
/// backedges has just been removed.
class UnloopUpdater {
Loop &Unloop;
LoopInfo *LI;
LoopBlocksDFS DFS;
public:
UnloopUpdater(Loop *UL, LoopInfo *LInfo) : Unloop(*UL), LI(LInfo), DFS(UL) {}
void updateBlockParents();
void removeBlocksFromAncestors();
void updateSubloopParents();
protected:
Loop *getNearestLoop(BasicBlock *BB, Loop *BBLoop);
};
} // end anonymous namespace
/// Update the parent loop for all blocks that are directly contained within the
/// original "unloop".
void UnloopUpdater::updateBlockParents() {
if (Unloop.getNumBlocks()) {
// Perform a post order CFG traversal of all blocks within this loop,
// propagating the nearest loop from successors to predecessors.
LoopBlocksTraversal Traversal(DFS, LI);
for (BasicBlock *POI : Traversal) {
Loop *L = LI->getLoopFor(POI);
Loop *NL = getNearestLoop(POI, L);
if (NL != L) {
// For reducible loops, NL is now an ancestor of Unloop.
File: /home/satanu/llvm-project/llvm/lib/Analysis/LoopInfo.cpp Page 11 of 17
// Iterate over the postorder list of blocks, propagating the nearest loop
// from successors to predecessors as before.
Changed = false;
for (LoopBlocksDFS::POIterator POI = DFS.beginPostorder(),
POE = DFS.endPostorder();
POI != POE; ++POI) {
Loop *L = LI->getLoopFor(*POI);
Loop *NL = getNearestLoop(*POI, L);
if (NL != L) {
assert(NL != &Unloop && (!NL || NL->contains(&Unloop)) &&
"uninitialized successor");
LI->changeLoopFor(*POI, NL);
Changed = true;
}
}
}
}
/// Remove unloop's blocks from all ancestors below their new parents.
void UnloopUpdater::removeBlocksFromAncestors() {
// Remove all unloop's blocks (including those in nested subloops) from
// ancestors below the new parent loop.
for (BasicBlock *BB : Unloop.blocks()) {
Loop *OuterParent = LI->getLoopFor(BB);
if (Unloop.contains(OuterParent)) {
while (OuterParent->getParentLoop() != &Unloop)
OuterParent = OuterParent->getParentLoop();
OuterParent = SubloopParents[OuterParent];
}
// Remove blocks from former Ancestors except Unloop itself which will be
// deleted.
for (Loop *OldParent = Unloop.getParentLoop(); OldParent != OuterParent;
OldParent = OldParent->getParentLoop()) {
assert(OldParent && "new loop is not an ancestor of the original");
OldParent->removeBlockFromLoop(BB);
}
}
}
/// Update the parent loop for all subloops directly nested within unloop.
void UnloopUpdater::updateSubloopParents() {
while (!Unloop.isInnermost()) {
Loop *Subloop = *std::prev(Unloop.end());
Unloop.removeChildLoop(std::prev(Unloop.end()));
/// Return the nearest parent loop among this block's successors. If a successor
File: /home/satanu/llvm-project/llvm/lib/Analysis/LoopInfo.cpp Page 12 of 17
/// is a subloop header, consider its parent to be the nearest parent of the
/// subloop's exits.
///
/// For subloop blocks, simply update SubloopParents and return NULL.
Loop *UnloopUpdater::getNearestLoop(BasicBlock *BB, Loop *BBLoop) {
Loop *L = LI->getLoopFor(*I);
if (L == &Unloop) {
// This successor has not been processed. This path must lead to an
// irreducible backedge.
assert((FoundIB || !DFS.hasPostorder(*I)) && "should have seen IB");
FoundIB = true;
}
if (L != &Unloop && Unloop.contains(L)) {
// Successor is in a subloop.
if (Subloop)
continue; // Branching within subloops. Ignore it.
// First handle the special case of no parent loop to simplify the algorithm.
if (Unloop->isOutermost()) {
// Since BBLoop had no parent, Unloop blocks are no longer in a loop.
for (BasicBlock *BB : Unloop->blocks()) {
// Don't reparent blocks in subloops.
if (getLoopFor(BB) != Unloop)
continue;
// Blocks no longer have a parent but are still referenced by Unloop until
// the Unloop object is deleted.
changeLoopFor(BB, nullptr);
}
return;
}
// Update the parent loop for all blocks within the loop. Blocks within
// subloops will not change parents.
UnloopUpdater Updater(Unloop, this);
Updater.updateBlockParents();
bool
LoopInfo::wouldBeOutOfLoopUseRequiringLCSSA(const Value *V,
const BasicBlock *ExitBB) const {
if (V->getType()->isTokenTy())
// We can't form PHIs of token type, so the definition of LCSSA excludes
// values of that type.
return false;
if (!I)
return false;
const Loop *L = getLoopFor(I->getParent());
if (!L)
return false;
if (L->contains(ExitBB))
// Could be an exit bb of a subloop and contained in defining loop
return false;
AnalysisKey LoopAnalysis::Key;
if (forcePrintModuleIR()) {
// handling -print-module-scope
OS << Banner << " (loop: ";
L.getHeader()->printAsOperand(OS, false);
OS << ")\n";
OS << Banner;
// First operand should refer to the metadata node itself, for legacy reasons.
assert(LoopID->getNumOperands() > 0 && "requires at least one operand");
assert(LoopID->getOperand(0) == LoopID && "invalid loop id");
// Iterate over the metdata node operands and look for MDString metadata.
for (unsigned i = 1, e = LoopID->getNumOperands(); i < e; ++i) {
MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i));
if (!MD || MD->getNumOperands() < 1)
continue;
MDString *S = dyn_cast<MDString>(MD->getOperand(0));
if (!S)
continue;
// Return the operand node if MDString holds expected metadata.
if (Name.equals(S->getString()))
return MD;
}
return IntMD->getSExtValue();
}
// Reserve first location for self reference to the LoopID metadata node.
MDs.push_back(nullptr);
// Remove metadata for the transformation that has been applied or that became
// outdated.
if (OrigLoopID) {
for (unsigned i = 1, ie = OrigLoopID->getNumOperands(); i < ie; ++i) {
bool IsVectorMetadata = false;
Metadata *Op = OrigLoopID->getOperand(i);
if (MDNode *MD = dyn_cast<MDNode>(Op)) {
const MDString *S = dyn_cast<MDString>(MD->getOperand(0));
if (S)
IsVectorMetadata =
llvm::any_of(RemovePrefixes, [S](StringRef Prefix) -> bool {
return S->getString().startswith(Prefix);
});
}
if (!IsVectorMetadata)
MDs.push_back(Op);
}
}
MDs.append(AddAttrs.begin(), AddAttrs.end());
//===----------------------------------------------------------------------===//
// LoopInfo implementation
//
LoopInfoWrapperPass::LoopInfoWrapperPass() : FunctionPass(ID) {
initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
}
char LoopInfoWrapperPass::ID = 0;
INITIALIZE_PASS_BEGIN(LoopInfoWrapperPass, "loops", "Natural Loop Information",
true, true)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(LoopInfoWrapperPass, "loops", "Natural Loop Information",
true, true)
//===----------------------------------------------------------------------===//
// LoopBlocksDFS implementation
//
/// Traverse the loop blocks and store the DFS result.
/// Useful for clients that just want the final DFS result and don't need to
/// visit blocks during the initial traversal.
void LoopBlocksDFS::perform(LoopInfo *LI) {
LoopBlocksTraversal Traversal(*this, LI);
for (LoopBlocksTraversal::POTIterator POI = Traversal.begin(),
POE = Traversal.end();
POI != POE; ++POI)
;
}