1616#include " llvm/ADT/Statistic.h"
1717#include " llvm/ADT/Twine.h"
1818#include " llvm/Analysis/AssumptionCache.h"
19+ #include " llvm/Analysis/BlockFrequencyInfo.h"
1920#include " llvm/Analysis/CFG.h"
2021#include " llvm/Analysis/CodeMetrics.h"
2122#include " llvm/Analysis/GuardUtils.h"
2627#include " llvm/Analysis/MemorySSA.h"
2728#include " llvm/Analysis/MemorySSAUpdater.h"
2829#include " llvm/Analysis/MustExecute.h"
30+ #include " llvm/Analysis/ProfileSummaryInfo.h"
2931#include " llvm/Analysis/ScalarEvolution.h"
3032#include " llvm/Analysis/TargetTransformInfo.h"
3133#include " llvm/Analysis/ValueTracking.h"
@@ -3044,6 +3046,7 @@ unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
30443046 bool NonTrivial,
30453047 function_ref<void (bool , bool , ArrayRef<Loop *>)> UnswitchCB,
30463048 ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
3049+ ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
30473050 function_ref<void(Loop &, StringRef)> DestroyLoopCB) {
30483051 assert (L.isRecursivelyLCSSAForm (DT, LI) &&
30493052 " Loops must be in LCSSA form before unswitching." );
@@ -3080,6 +3083,14 @@ unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
30803083 if (L.getHeader ()->getParent ()->hasOptSize ())
30813084 return false ;
30823085
3086+ // Skip cold loops, as unswitching them brings little benefit
3087+ // but increases the code size
3088+ if (PSI && PSI->hasProfileSummary () && BFI &&
3089+ PSI->isColdBlock (L.getHeader (), BFI)) {
3090+ LLVM_DEBUG (dbgs () << " Skip cold loop: " << L << " \n " );
3091+ return false ;
3092+ }
3093+
30833094 // Skip non-trivial unswitching for loops that cannot be cloned.
30843095 if (!L.isSafeToClone ())
30853096 return false ;
@@ -3105,7 +3116,11 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,
31053116 LPMUpdater &U) {
31063117 Function &F = *L.getHeader ()->getParent ();
31073118 (void )F;
3108-
3119+ ProfileSummaryInfo *PSI = nullptr ;
3120+ if (auto OuterProxy =
3121+ AM.getResult <FunctionAnalysisManagerLoopProxy>(L, AR)
3122+ .getCachedResult <ModuleAnalysisManagerFunctionProxy>(F))
3123+ PSI = OuterProxy->getCachedResult <ProfileSummaryAnalysis>(*F.getParent ());
31093124 LLVM_DEBUG (dbgs () << " Unswitching loop in " << F.getName () << " : " << L
31103125 << " \n " );
31113126
@@ -3152,7 +3167,7 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,
31523167 }
31533168 if (!unswitchLoop (L, AR.DT , AR.LI , AR.AC , AR.AA , AR.TTI , Trivial, NonTrivial,
31543169 UnswitchCB, &AR.SE , MSSAU ? MSSAU.getPointer () : nullptr ,
3155- DestroyLoopCB))
3170+ PSI, AR. BFI , DestroyLoopCB))
31563171 return PreservedAnalyses::all ();
31573172
31583173 if (AR.MSSA && VerifyMemorySSA)
@@ -3214,7 +3229,6 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
32143229
32153230 LLVM_DEBUG (dbgs () << " Unswitching loop in " << F.getName () << " : " << *L
32163231 << " \n " );
3217-
32183232 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
32193233 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo ();
32203234 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache (F);
@@ -3251,9 +3265,9 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
32513265
32523266 if (VerifyMemorySSA)
32533267 MSSA->verifyMemorySSA ();
3254-
3255- bool Changed = unswitchLoop (*L, DT, LI, AC, AA, TTI, true , NonTrivial,
3256- UnswitchCB, SE, &MSSAU , DestroyLoopCB);
3268+ bool Changed =
3269+ unswitchLoop (*L, DT, LI, AC, AA, TTI, true , NonTrivial, UnswitchCB, SE ,
3270+ &MSSAU, nullptr , nullptr , DestroyLoopCB);
32573271
32583272 if (VerifyMemorySSA)
32593273 MSSA->verifyMemorySSA ();
0 commit comments