94 #define DEBUG_TYPE "loop-versioning-licm"
103 cl::desc(
"LoopVersioningLICM's minimum allowed percentage"
104 "of possible invariant instructions per loop"),
109 "licm-versioning-max-depth-threshold",
111 "LoopVersioningLICM's threshold for maximum allowed loop nest/depth"),
146 struct LoopVersioningLICM :
public LoopPass {
165 :
LoopPass(
ID), AA(nullptr), SE(nullptr), LAA(nullptr), LAI(nullptr),
168 InvariantCounter(0), IsReadOnlyLoop(
true) {
171 StringRef getPassName()
const override {
return "Loop Versioning for LICM"; }
178 LoadAndStoreCounter = 0;
179 InvariantCounter = 0;
180 IsReadOnlyLoop =
true;
186 AutoResetter(LoopVersioningLICM &LVLICM) : LVLICM(LVLICM) {}
187 ~AutoResetter() { LVLICM.reset(); }
190 LoopVersioningLICM &LVLICM;
200 std::unique_ptr<AliasSetTracker>
203 unsigned LoopDepthThreshold;
204 float InvariantThreshold;
205 unsigned LoadAndStoreCounter;
206 unsigned InvariantCounter;
209 bool isLegalForVersioning();
210 bool legalLoopStructure();
211 bool legalLoopInstructions();
212 bool legalLoopMemoryAccesses();
213 bool isLoopAlreadyVisited();
214 void setNoAliasToLoop(
Loop *);
220 bool LoopVersioningLICM::legalLoopStructure() {
222 if (!CurLoop->isLoopSimplifyForm()) {
224 dbgs() <<
" loop is not in loop-simplify form.\n");
228 if (CurLoop->getSubLoops().size()) {
229 DEBUG(
dbgs() <<
" loop is not innermost\n");
233 if (CurLoop->getNumBackEdges() != 1) {
234 DEBUG(
dbgs() <<
" loop has multiple backedges\n");
238 if (!CurLoop->getExitingBlock()) {
239 DEBUG(
dbgs() <<
" loop has multiple exiting block\n");
245 if (CurLoop->getExitingBlock() != CurLoop->getLoopLatch()) {
246 DEBUG(
dbgs() <<
" loop is not bottom tested\n");
251 if (CurLoop->isAnnotatedParallel()) {
252 DEBUG(
dbgs() <<
" Parallel loop is not worth versioning\n");
256 if (CurLoop->getLoopDepth() > LoopDepthThreshold) {
257 DEBUG(
dbgs() <<
" loop depth is more then threshold\n");
262 const SCEV *ExitCount = SE->getBackedgeTakenCount(CurLoop);
263 if (ExitCount == SE->getCouldNotCompute()) {
264 DEBUG(
dbgs() <<
" loop does not has trip count\n");
272 bool LoopVersioningLICM::legalLoopMemoryAccesses() {
273 bool HasMayAlias =
false;
274 bool TypeSafety =
false;
288 for (
const auto &
I : *CurAST) {
298 bool TypeCheck =
true;
301 HasMod |= AS.
isMod();
302 for (
const auto &
A : AS) {
305 TypeCheck = (TypeCheck && (SomePtr->
getType() == Ptr->
getType()));
308 TypeSafety |= TypeCheck;
312 DEBUG(
dbgs() <<
" Alias tracker type safety failed!\n");
317 DEBUG(
dbgs() <<
" No memory modified in loop body\n");
323 DEBUG(
dbgs() <<
" No ambiguity in memory access.\n");
335 bool LoopVersioningLICM::instructionSafeForVersioning(
Instruction *
I) {
336 assert(I !=
nullptr &&
"Null instruction found!");
338 if (isa<CallInst>(I) && !AA->doesNotAccessMemory(
CallSite(I))) {
339 DEBUG(
dbgs() <<
" Unsafe call site found.\n");
344 DEBUG(
dbgs() <<
" May throw instruction found in loop body\n");
352 DEBUG(
dbgs() <<
" Found a non-simple load.\n");
355 LoadAndStoreCounter++;
358 if (SE->isLoopInvariant(SE->getSCEV(Ptr), CurLoop))
366 DEBUG(
dbgs() <<
" Found a non-simple store.\n");
369 LoadAndStoreCounter++;
372 if (SE->isLoopInvariant(SE->getSCEV(Ptr), CurLoop))
375 IsReadOnlyLoop =
false;
382 bool LoopVersioningLICM::legalLoopInstructions() {
384 LoadAndStoreCounter = 0;
385 InvariantCounter = 0;
386 IsReadOnlyLoop =
true;
389 for (
auto *Block : CurLoop->getBlocks())
390 for (
auto &Inst : *Block) {
392 if (!instructionSafeForVersioning(&Inst))
396 LAI = &LAA->getInfo(CurLoop);
398 if (LAI->getRuntimePointerChecking()->getChecks().empty()) {
399 DEBUG(
dbgs() <<
" LAA: Runtime check not found !!\n");
403 if (LAI->getNumRuntimePointerChecks() >
405 DEBUG(
dbgs() <<
" LAA: Runtime checks are more than threshold !!\n");
409 if (!InvariantCounter) {
410 DEBUG(
dbgs() <<
" Invariant not found !!\n");
414 if (IsReadOnlyLoop) {
415 DEBUG(
dbgs() <<
" Found a read-only loop!\n");
420 if (InvariantCounter * 100 < InvariantThreshold * LoadAndStoreCounter) {
422 <<
" Invariant load & store are less then defined threshold\n");
423 DEBUG(
dbgs() <<
" Invariant loads & stores: "
424 << ((InvariantCounter * 100) / LoadAndStoreCounter) <<
"%\n");
425 DEBUG(
dbgs() <<
" Invariant loads & store threshold: "
426 << InvariantThreshold <<
"%\n");
435 bool LoopVersioningLICM::isLoopAlreadyVisited() {
447 bool LoopVersioningLICM::isLegalForVersioning() {
450 if (isLoopAlreadyVisited()) {
452 dbgs() <<
" Revisiting loop in LoopVersioningLICM not allowed.\n\n");
456 if (!legalLoopStructure()) {
458 dbgs() <<
" Loop structure not suitable for LoopVersioningLICM\n\n");
462 if (!legalLoopInstructions()) {
464 <<
" Loop instructions not suitable for LoopVersioningLICM\n\n");
468 if (!legalLoopMemoryAccesses()) {
470 <<
" Loop memory access not suitable for LoopVersioningLICM\n\n");
474 DEBUG(
dbgs() <<
" Loop Versioning found to be beneficial\n\n");
483 void LoopVersioningLICM::setNoAliasToLoop(
Loop *VerLoop) {
488 MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain(
"LVDomain");
491 MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain, Name);
494 for (
auto *Block : CurLoop->getBlocks()) {
495 for (
auto &Inst : *Block) {
497 if (!Inst.mayReadFromMemory() && !Inst.mayWriteToMemory())
518 AutoResetter Resetter(*
this);
523 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
524 SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
525 LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
532 LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
538 bool Changed =
false;
543 if (isLegalForVersioning()) {
547 DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
556 "llvm.mem.parallel_loop_access");
558 setNoAliasToLoop(LVer.getVersionedLoop());
566 "Loop Versioning For LICM",
false,
false)
Legacy wrapper pass to provide the GlobalsAAResult object.
Pass interface - Implemented by all 'passes'.
static unsigned RuntimeMemoryCheckThreshold
\brief When performing memory disambiguation checks at runtime do not make more than this number of c...
void push_back(const T &Elt)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isForwardingAliasSet() const
Return true if this alias set should be ignored as part of the AliasSetTracker object.
This is the interface for a simple mod/ref and alias analysis over globals.
void replaceOperandWith(unsigned I, Metadata *New)
Replace a specific operand.
static MDString * get(LLVMContext &Context, StringRef Str)
unsigned getNumOperands() const
Return number of MDNode operands.
The main scalar evolution driver.
An instruction for reading from memory.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
const std::vector< BlockT * > & getBlocks() const
Get a list of the basic blocks which make up this loop.
BlockT * getHeader() const
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static const char * LICMVersioningMetaData
bool mayReadFromMemory() const
Return true if this instruction may read memory.
static cl::opt< float > LVInvarThreshold("licm-versioning-invariant-threshold", cl::desc("LoopVersioningLICM's minimum allowed percentage""of possible invariant instructions per loop"), cl::init(25), cl::Hidden)
Threshold minimum allowed percentage for possible invariant instructions in a loop.
An instruction for storing to memory.
void addStringMetadataToLoop(Loop *TheLoop, const char *MDString, unsigned V=0)
Set input string into loop metadata by keeping other values intact.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
initializer< Ty > init(const Ty &Val)
This is an important class for using LLVM in a threaded context.
This analysis provides dependence information for the memory accesses of a loop.
MDNode * getLoopID() const
Return the llvm.loop loop id metadata node for this loop if it is present.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
Value * getPointerOperand()
static cl::opt< unsigned > LVLoopDepthThreshold("licm-versioning-max-depth-threshold", cl::desc("LoopVersioningLICM's threshold for maximum allowed loop nest/depth"), cl::init(2), cl::Hidden)
Threshold for maximum allowed loop nest/depth.
Pass * createLoopVersioningLICMPass()
LLVMContext & getContext() const
All values hold a context through their type.
Optional< const MDOperand * > findStringMetadataForLoop(Loop *TheLoop, StringRef Name)
Find string metadata for loop.
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
void initializeLoopVersioningLICMPass(PassRegistry &)
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
const MDOperand & getOperand(unsigned I) const
AnalysisUsage & addRequiredID(const void *ID)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
Drive the analysis of memory accesses in the loop.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool mayThrow() const
Return true if this instruction may throw an exception.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This class represents an analyzed expression in the program.
static IntegerType * getInt32Ty(LLVMContext &C)
Represents a single loop in the control flow graph.
static MDNode * concatenate(MDNode *A, MDNode *B)
Methods for metadata merging.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MDNode * createStringMetadata(Loop *TheLoop, StringRef Name, unsigned V)
Create MDNode for input string.
LLVM Value Representation.
INITIALIZE_PASS_BEGIN(LoopVersioningLICM,"loop-versioning-licm","Loop Versioning For LICM", false, false) INITIALIZE_PASS_END(LoopVersioningLICM
The legacy pass manager's analysis pass to compute loop information.
StringRef - Represent a constant reference to a string, i.e.
Legacy analysis pass which computes a DominatorTree.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
Value * getPointerOperand()
loop versioning Loop Versioning For false
loop versioning Loop Versioning For LICM