1 //===- llvm/Transforms/Utils/SizeOpts.h - size optimization -----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains some shared code size optimization related code. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_TRANSFORMS_UTILS_SIZEOPTS_H 14 #define LLVM_TRANSFORMS_UTILS_SIZEOPTS_H 15 16 #include "llvm/Analysis/ProfileSummaryInfo.h" 17 #include "llvm/Support/CommandLine.h" 18 19 namespace llvm { 20 extern cl::opt<bool> EnablePGSO; 21 extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly; 22 extern cl::opt<bool> PGSOColdCodeOnly; 23 extern cl::opt<bool> PGSOColdCodeOnlyForInstrPGO; 24 extern cl::opt<bool> PGSOColdCodeOnlyForSamplePGO; 25 extern cl::opt<bool> PGSOColdCodeOnlyForPartialSamplePGO; 26 extern cl::opt<bool> ForcePGSO; 27 extern cl::opt<int> PgsoCutoffInstrProf; 28 extern cl::opt<int> PgsoCutoffSampleProf; 29 30 class BasicBlock; 31 class BlockFrequencyInfo; 32 class Function; 33 34 enum class PGSOQueryType { 35 IRPass, // A query call from an IR-level transform pass. 36 Test, // A query call from a unit test. 37 Other, // Others. 38 }; 39 40 static inline bool isPGSOColdCodeOnly(ProfileSummaryInfo *PSI) { 41 return PGSOColdCodeOnly || 42 (PSI->hasInstrumentationProfile() && PGSOColdCodeOnlyForInstrPGO) || 43 (PSI->hasSampleProfile() && 44 ((!PSI->hasPartialSampleProfile() && PGSOColdCodeOnlyForSamplePGO) || 45 (PSI->hasPartialSampleProfile() && 46 PGSOColdCodeOnlyForPartialSamplePGO))) || 47 (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize()); 48 } 49 50 template<typename AdapterT, typename FuncT, typename BFIT> 51 bool shouldFuncOptimizeForSizeImpl(const FuncT *F, ProfileSummaryInfo *PSI, 52 BFIT *BFI, PGSOQueryType QueryType) { 53 assert(F); 54 if (!PSI || !BFI || !PSI->hasProfileSummary()) 55 return false; 56 if (ForcePGSO) 57 return true; 58 if (!EnablePGSO) 59 return false; 60 if (isPGSOColdCodeOnly(PSI)) 61 return AdapterT::isFunctionColdInCallGraph(F, PSI, *BFI); 62 if (PSI->hasSampleProfile()) 63 // The "isCold" check seems to work better for Sample PGO as it could have 64 // many profile-unannotated functions. 65 return AdapterT::isFunctionColdInCallGraphNthPercentile( 66 PgsoCutoffSampleProf, F, PSI, *BFI); 67 return !AdapterT::isFunctionHotInCallGraphNthPercentile(PgsoCutoffInstrProf, 68 F, PSI, *BFI); 69 } 70 71 template<typename AdapterT, typename BlockTOrBlockFreq, typename BFIT> 72 bool shouldOptimizeForSizeImpl(BlockTOrBlockFreq BBOrBlockFreq, ProfileSummaryInfo *PSI, 73 BFIT *BFI, PGSOQueryType QueryType) { 74 if (!PSI || !BFI || !PSI->hasProfileSummary()) 75 return false; 76 if (ForcePGSO) 77 return true; 78 if (!EnablePGSO) 79 return false; 80 if (isPGSOColdCodeOnly(PSI)) 81 return AdapterT::isColdBlock(BBOrBlockFreq, PSI, BFI); 82 if (PSI->hasSampleProfile()) 83 // The "isCold" check seems to work better for Sample PGO as it could have 84 // many profile-unannotated functions. 85 return AdapterT::isColdBlockNthPercentile(PgsoCutoffSampleProf, 86 BBOrBlockFreq, PSI, BFI); 87 return !AdapterT::isHotBlockNthPercentile(PgsoCutoffInstrProf, BBOrBlockFreq, 88 PSI, BFI); 89 } 90 91 /// Returns true if function \p F is suggested to be size-optimized based on the 92 /// profile. 93 bool shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI, 94 BlockFrequencyInfo *BFI, 95 PGSOQueryType QueryType = PGSOQueryType::Other); 96 97 /// Returns true if basic block \p BB is suggested to be size-optimized based on 98 /// the profile. 99 bool shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI, 100 BlockFrequencyInfo *BFI, 101 PGSOQueryType QueryType = PGSOQueryType::Other); 102 103 } // end namespace llvm 104 105 #endif // LLVM_TRANSFORMS_UTILS_SIZEOPTS_H 106