90#define DEBUG_TYPE "loop-versioning-licm"
98 cl::desc(
"LoopVersioningLICM's minimum allowed percentage"
99 "of possible invariant instructions per loop"),
104 "licm-versioning-max-depth-threshold",
106 "LoopVersioningLICM's threshold for maximum allowed loop nest/depth"),
111struct LoopVersioningLICM {
120 : AA(AA), SE(SE), LAIs(LAIs), LI(LI), CurLoop(CurLoop),
145 unsigned LoopDepthThreshold;
148 float InvariantThreshold;
151 unsigned LoadAndStoreCounter = 0;
154 unsigned InvariantCounter = 0;
157 bool IsReadOnlyLoop =
true;
162 bool isLegalForVersioning();
163 bool legalLoopStructure();
164 bool legalLoopInstructions();
165 bool legalLoopMemoryAccesses();
166 bool isLoopAlreadyVisited();
167 void setNoAliasToLoop(
Loop *VerLoop);
174bool LoopVersioningLICM::legalLoopStructure() {
176 if (!CurLoop->isLoopSimplifyForm()) {
181 if (!CurLoop->getSubLoops().empty()) {
186 if (CurLoop->getNumBackEdges() != 1) {
191 if (!CurLoop->getExitingBlock()) {
198 if (CurLoop->getExitingBlock() != CurLoop->getLoopLatch()) {
204 if (CurLoop->isAnnotatedParallel()) {
209 if (CurLoop->getLoopDepth() > LoopDepthThreshold) {
215 const SCEV *ExitCount = SE->getBackedgeTakenCount(CurLoop);
216 if (isa<SCEVCouldNotCompute>(ExitCount)) {
225bool LoopVersioningLICM::legalLoopMemoryAccesses() {
229 for (
auto *
Block : CurLoop->getBlocks()) {
231 if (LI.getLoopFor(
Block) == CurLoop)
247 bool HasMayAlias =
false;
248 bool TypeSafety =
false;
250 for (
const auto &
I : AST) {
260 bool TypeCheck =
true;
263 HasMod |= AS.
isMod();
264 for (
const auto &MemLoc : AS) {
272 TypeCheck = (TypeCheck && (SomePtr->
getType() ==
Ptr->getType()));
275 TypeSafety |= TypeCheck;
303bool LoopVersioningLICM::instructionSafeForVersioning(
Instruction *
I) {
304 assert(
I !=
nullptr &&
"Null instruction found!");
306 if (
auto *Call = dyn_cast<CallBase>(
I)) {
307 if (
Call->isConvergent() ||
Call->cannotDuplicate()) {
312 if (!AA->doesNotAccessMemory(Call)) {
320 LLVM_DEBUG(
dbgs() <<
" May throw instruction found in loop body\n");
325 if (
I->mayReadFromMemory()) {
331 LoadAndStoreCounter++;
334 if (SE->isLoopInvariant(SE->getSCEV(
Ptr), CurLoop))
339 else if (
I->mayWriteToMemory()) {
345 LoadAndStoreCounter++;
348 if (SE->isLoopInvariant(SE->getSCEV(
Ptr), CurLoop))
351 IsReadOnlyLoop =
false;
358bool LoopVersioningLICM::legalLoopInstructions() {
360 LoadAndStoreCounter = 0;
361 InvariantCounter = 0;
362 IsReadOnlyLoop =
true;
366 for (
auto *
Block : CurLoop->getBlocks())
367 for (
auto &Inst : *
Block) {
369 if (!instructionSafeForVersioning(&Inst)) {
372 <<
" Unsafe Loop Instruction";
378 LAI = &LAIs.getInfo(*CurLoop);
380 if (LAI->getRuntimePointerChecking()->getChecks().empty()) {
385 if (LAI->getNumRuntimePointerChecks() >
388 dbgs() <<
" LAA: Runtime checks are more than threshold !!\n");
391 CurLoop->getStartLoc(),
392 CurLoop->getHeader())
393 <<
"Number of runtime checks "
394 <<
NV(
"RuntimeChecks", LAI->getNumRuntimePointerChecks())
395 <<
" exceeds threshold "
401 if (!InvariantCounter) {
406 if (IsReadOnlyLoop) {
412 if (InvariantCounter * 100 < InvariantThreshold * LoadAndStoreCounter) {
415 <<
" Invariant load & store are less then defined threshold\n");
417 << ((InvariantCounter * 100) / LoadAndStoreCounter)
420 << InvariantThreshold <<
"%\n");
423 CurLoop->getStartLoc(),
424 CurLoop->getHeader())
425 <<
"Invariant load & store "
426 <<
NV(
"LoadAndStoreCounter",
427 ((InvariantCounter * 100) / LoadAndStoreCounter))
428 <<
" are less then defined threshold "
429 <<
NV(
"Threshold", InvariantThreshold);
439bool LoopVersioningLICM::isLoopAlreadyVisited() {
451bool LoopVersioningLICM::isLegalForVersioning() {
455 if (isLoopAlreadyVisited()) {
457 dbgs() <<
" Revisiting loop in LoopVersioningLICM not allowed.\n\n");
461 if (!legalLoopStructure()) {
463 dbgs() <<
" Loop structure not suitable for LoopVersioningLICM\n\n");
466 CurLoop->getStartLoc(),
467 CurLoop->getHeader())
468 <<
" Unsafe Loop structure";
473 if (!legalLoopInstructions()) {
476 <<
" Loop instructions not suitable for LoopVersioningLICM\n\n");
480 if (!legalLoopMemoryAccesses()) {
483 <<
" Loop memory access not suitable for LoopVersioningLICM\n\n");
486 CurLoop->getStartLoc(),
487 CurLoop->getHeader())
488 <<
" Unsafe Loop memory access";
493 LLVM_DEBUG(
dbgs() <<
" Loop Versioning found to be beneficial\n\n");
496 CurLoop->getStartLoc(), CurLoop->getHeader())
497 <<
" Versioned loop for LICM."
498 <<
" Number of runtime checks we had to insert "
499 <<
NV(
"RuntimeChecks", LAI->getNumRuntimePointerChecks());
509void LoopVersioningLICM::setNoAliasToLoop(
Loop *VerLoop) {
514 MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain(
"LVDomain");
516 MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain,
Name);
520 for (
auto *
Block : CurLoop->getBlocks()) {
521 for (
auto &Inst : *
Block) {
523 if (!Inst.mayReadFromMemory() && !Inst.mayWriteToMemory())
527 LLVMContext::MD_noalias,
532 LLVMContext::MD_alias_scope,
544 bool Changed =
false;
549 if (isLegalForVersioning()) {
553 LoopVersioning LVer(*LAI, LAI->getRuntimePointerChecking()->getChecks(),
554 CurLoop, &LI, DT, SE);
564 "llvm.mem.parallel_loop_access");
566 setNoAliasToLoop(LVer.getVersionedLoop());
580 const Function *
F = L.getHeader()->getParent();
584 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...