diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -6257,6 +6257,15 @@ !3 = distinct !{} ; access group for instructions in the inner loop (which are implicitly contained in outer loop as well) !4 = distinct !{} ; access group for instructions in the outer, but not the inner loop +'``llvm.loop.mustprogress``' Metadata +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``llvm.loop.mustprogress`` metadata indicates that this loop is required to +terminate, unwind, or interact with the environment in an observable way e.g. +via a volatile memory access, I/O, or other synchronization. If such a loop is +not found to interact with the environment in an observable way, the loop may +be removed. This corresponds to the ``mustprogress`` function attribute. + '``irr_loop``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/include/llvm/Analysis/LoopInfo.h @@ -840,6 +840,9 @@ /// unrolling pass is run more than once (which it generally is). void setLoopAlreadyUnrolled(); + /// Add llvm.loop.mustprogress to this loop's loop id metadata. + void setLoopMustProgress(); + void dump() const; void dumpVerbose() const; diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -176,9 +176,9 @@ function_ref GetAssumptionCache = nullptr, ProfileSummaryInfo *PSI = nullptr, BlockFrequencyInfo *CallerBFI = nullptr, - BlockFrequencyInfo *CalleeBFI = nullptr) + BlockFrequencyInfo *CalleeBFI = nullptr, LoopInfo *CalleeLI = nullptr) : CG(cg), GetAssumptionCache(GetAssumptionCache), PSI(PSI), - CallerBFI(CallerBFI), CalleeBFI(CalleeBFI) {} + CallerBFI(CallerBFI), CalleeBFI(CalleeBFI), CalleeLI(CalleeLI) {} /// If non-null, InlineFunction will update the callgraph to reflect the /// changes it makes. @@ -186,6 +186,7 @@ function_ref GetAssumptionCache; ProfileSummaryInfo *PSI; BlockFrequencyInfo *CallerBFI, *CalleeBFI; + LoopInfo *CalleeLI; /// InlineFunction fills this in with all static allocas that get copied into /// the caller. diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -535,6 +535,22 @@ setLoopID(NewLoopID); } +void Loop::setLoopMustProgress() { + LLVMContext &Context = getHeader()->getContext(); + + MDNode *MustProgress = findOptionMDForLoop(this, "llvm.loop.mustprogress"); + + 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); +} + bool Loop::isAnnotatedParallel() const { MDNode *DesiredLoopIdMetadata = getLoopID();