92#define DEBUG_TYPE "loop-versioning-licm"
100 cl::desc(
"LoopVersioningLICM's minimum allowed percentage"
101 "of possible invariant instructions per loop"),
106 "licm-versioning-max-depth-threshold",
108 "LoopVersioningLICM's threshold for maximum allowed loop nest/depth"),
113struct LoopVersioningLICM {
122 : AA(AA), SE(SE), LAIs(LAIs), LI(LI), CurLoop(CurLoop),
147 unsigned LoopDepthThreshold;
150 float InvariantThreshold;
153 unsigned LoadAndStoreCounter = 0;
156 unsigned InvariantCounter = 0;
159 bool IsReadOnlyLoop =
true;
164 bool isLegalForVersioning();
165 bool legalLoopStructure();
166 bool legalLoopInstructions();
167 bool legalLoopMemoryAccesses();
168 bool isLoopAlreadyVisited();
169 void setNoAliasToLoop(
Loop *VerLoop);
176bool LoopVersioningLICM::legalLoopStructure() {
178 if (!CurLoop->isLoopSimplifyForm()) {
183 if (!CurLoop->getSubLoops().empty()) {
188 if (CurLoop->getNumBackEdges() != 1) {
193 if (!CurLoop->getExitingBlock()) {
200 if (CurLoop->getExitingBlock() != CurLoop->getLoopLatch()) {
206 if (CurLoop->isAnnotatedParallel()) {
211 if (CurLoop->getLoopDepth() > LoopDepthThreshold) {
217 const SCEV *ExitCount = SE->getBackedgeTakenCount(CurLoop);
218 if (isa<SCEVCouldNotCompute>(ExitCount)) {
227bool LoopVersioningLICM::legalLoopMemoryAccesses() {
231 for (
auto *
Block : CurLoop->getBlocks()) {
233 if (LI.getLoopFor(
Block) == CurLoop)
249 bool HasMayAlias =
false;
250 bool TypeSafety =
false;
252 for (
const auto &
I : AST) {
262 bool TypeCheck =
true;
265 HasMod |= AS.
isMod();
266 for (
const auto &MemLoc : AS) {
274 TypeCheck = (TypeCheck && (SomePtr->
getType() ==
Ptr->getType()));
277 TypeSafety |= TypeCheck;
305bool LoopVersioningLICM::instructionSafeForVersioning(
Instruction *
I) {
306 assert(
I !=
nullptr &&
"Null instruction found!");
308 if (
auto *Call = dyn_cast<CallBase>(
I)) {
309 if (
Call->isConvergent() ||
Call->cannotDuplicate()) {
314 if (!AA->doesNotAccessMemory(Call)) {
322 LLVM_DEBUG(
dbgs() <<
" May throw instruction found in loop body\n");
327 if (
I->mayReadFromMemory()) {
333 LoadAndStoreCounter++;
336 if (SE->isLoopInvariant(SE->getSCEV(
Ptr), CurLoop))
341 else if (
I->mayWriteToMemory()) {
347 LoadAndStoreCounter++;
350 if (SE->isLoopInvariant(SE->getSCEV(
Ptr), CurLoop))
353 IsReadOnlyLoop =
false;
360bool LoopVersioningLICM::legalLoopInstructions() {
362 LoadAndStoreCounter = 0;
363 InvariantCounter = 0;
364 IsReadOnlyLoop =
true;
368 for (
auto *
Block : CurLoop->getBlocks())
369 for (
auto &Inst : *
Block) {
371 if (!instructionSafeForVersioning(&Inst)) {
374 <<
" Unsafe Loop Instruction";
380 LAI = &LAIs.getInfo(*CurLoop);
382 if (LAI->getRuntimePointerChecking()->getChecks().empty()) {
387 if (LAI->getNumRuntimePointerChecks() >
390 dbgs() <<
" LAA: Runtime checks are more than threshold !!\n");
393 CurLoop->getStartLoc(),
394 CurLoop->getHeader())
395 <<
"Number of runtime checks "
396 <<
NV(
"RuntimeChecks", LAI->getNumRuntimePointerChecks())
397 <<
" exceeds threshold "
403 if (!InvariantCounter) {
408 if (IsReadOnlyLoop) {
414 if (InvariantCounter * 100 < InvariantThreshold * LoadAndStoreCounter) {
417 <<
" Invariant load & store are less then defined threshold\n");
419 << ((InvariantCounter * 100) / LoadAndStoreCounter)
422 << InvariantThreshold <<
"%\n");
425 CurLoop->getStartLoc(),
426 CurLoop->getHeader())
427 <<
"Invariant load & store "
428 <<
NV(
"LoadAndStoreCounter",
429 ((InvariantCounter * 100) / LoadAndStoreCounter))
430 <<
" are less then defined threshold "
431 <<
NV(
"Threshold", InvariantThreshold);
441bool LoopVersioningLICM::isLoopAlreadyVisited() {
453bool LoopVersioningLICM::isLegalForVersioning() {
457 if (isLoopAlreadyVisited()) {
459 dbgs() <<
" Revisiting loop in LoopVersioningLICM not allowed.\n\n");
463 if (!legalLoopStructure()) {
465 dbgs() <<
" Loop structure not suitable for LoopVersioningLICM\n\n");
468 CurLoop->getStartLoc(),
469 CurLoop->getHeader())
470 <<
" Unsafe Loop structure";
475 if (!legalLoopInstructions()) {
478 <<
" Loop instructions not suitable for LoopVersioningLICM\n\n");
482 if (!legalLoopMemoryAccesses()) {
485 <<
" Loop memory access not suitable for LoopVersioningLICM\n\n");
488 CurLoop->getStartLoc(),
489 CurLoop->getHeader())
490 <<
" Unsafe Loop memory access";
495 LLVM_DEBUG(
dbgs() <<
" Loop Versioning found to be beneficial\n\n");
498 CurLoop->getStartLoc(), CurLoop->getHeader())
499 <<
" Versioned loop for LICM."
500 <<
" Number of runtime checks we had to insert "
501 <<
NV(
"RuntimeChecks", LAI->getNumRuntimePointerChecks());
511void LoopVersioningLICM::setNoAliasToLoop(
Loop *VerLoop) {
516 MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain(
"LVDomain");
518 MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain,
Name);
522 for (
auto *
Block : CurLoop->getBlocks()) {
523 for (
auto &Inst : *
Block) {
525 if (!Inst.mayReadFromMemory() && !Inst.mayWriteToMemory())
529 LLVMContext::MD_noalias,
534 LLVMContext::MD_alias_scope,
546 bool Changed =
false;
551 if (isLegalForVersioning()) {
555 LoopVersioning LVer(*LAI, LAI->getRuntimePointerChecking()->getChecks(),
556 CurLoop, &LI, DT, SE);
566 "llvm.mem.parallel_loop_access");
568 setNoAliasToLoop(LVer.getVersionedLoop());
582 const Function *
F = L.getHeader()->getParent();
586 if (!LoopVersioningLICM(AA, SE, &ORE, LAIs, LAR.
LI, &L).run(DT))
static cl::opt< bool > NoAliases("csky-no-aliases", cl::desc("Disable the emission of assembler pseudo instructions"), cl::init(false), cl::Hidden)
This is the interface for a simple mod/ref and alias analysis over globals.
static const char * LICMVersioningMetaData
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.
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
bool isForwardingAliasSet() const
Return true if this alias set should be ignored as part of the AliasSetTracker object.
A container for analyses that lazily runs them and caches their results.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
An instruction for reading from memory.
Value * getPointerOperand()
Drive the analysis of memory accesses in the loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &LAR, LPMUpdater &U)
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
Represents a single loop in the control flow graph.
static MDNode * concatenate(MDNode *A, MDNode *B)
Methods for metadata merging.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Value * getPointerOperand()
StringRef - Represent a constant reference to a string, i.e.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
std::optional< const MDOperand * > findStringMetadataForLoop(const Loop *TheLoop, StringRef Name)
Find string metadata for loop.
void addStringMetadataToLoop(Loop *TheLoop, const char *MDString, unsigned V=0)
Set input string into loop metadata by keeping other values intact.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
TransformationMode hasLICMVersioningTransformation(const Loop *L)
@ TM_Disable
The transformation should not be applied.
PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
static unsigned RuntimeMemoryCheckThreshold
\When performing memory disambiguation checks at runtime do not make more than this number of compari...