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/BlockFrequencyInfo.h" 17 #include "llvm/Analysis/ProfileSummaryInfo.h" 18 #include "llvm/Support/CommandLine.h" 19 20 namespace llvm { 21 extern cl::opt<bool> EnablePGSO; 22 extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly; 23 extern cl::opt<bool> PGSOColdCodeOnly; 24 extern cl::opt<bool> PGSOColdCodeOnlyForInstrPGO; 25 extern cl::opt<bool> PGSOColdCodeOnlyForSamplePGO; 26 extern cl::opt<bool> PGSOColdCodeOnlyForPartialSamplePGO; 27 extern cl::opt<bool> ForcePGSO; 28 extern cl::opt<int> PgsoCutoffInstrProf; 29 extern cl::opt<int> PgsoCutoffSampleProf; 30 31 class BasicBlock; 32 class BlockFrequencyInfo; 33 class Function; 34 35 enum class PGSOQueryType { 36 IRPass, // A query call from an IR-level transform pass. 37 Test, // A query call from a unit test. 38 Other, // Others. 39 }; 40 41 static inline bool isPGSOColdCodeOnly(ProfileSummaryInfo *PSI) { 42 return PGSOColdCodeOnly || 43 (PSI->hasInstrumentationProfile() && PGSOColdCodeOnlyForInstrPGO) || 44 (PSI->hasSampleProfile() && 45 ((!PSI->hasPartialSampleProfile() && PGSOColdCodeOnlyForSamplePGO) || 46 (PSI->hasPartialSampleProfile() && 47 PGSOColdCodeOnlyForPartialSamplePGO))) || 48 (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize()); 49 } 50 51 template<typename AdapterT, typename FuncT, typename BFIT> 52 bool shouldFuncOptimizeForSizeImpl(const FuncT *F, ProfileSummaryInfo *PSI, 53 BFIT *BFI, PGSOQueryType QueryType) { 54 assert(F); 55 if (!PSI || !BFI || !PSI->hasProfileSummary()) 56 return false; 57 if (ForcePGSO) 58 return true; 59 if (!EnablePGSO) 60 return false; 61 if (isPGSOColdCodeOnly(PSI)) 62 return AdapterT::isFunctionColdInCallGraph(F, PSI, *BFI); 63 if (PSI->hasSampleProfile()) 64 // The "isCold" check seems to work better for Sample PGO as it could have 65 // many profile-unannotated functions. 66 return AdapterT::isFunctionColdInCallGraphNthPercentile( 67 PgsoCutoffSampleProf, F, PSI, *BFI); 68 return !AdapterT::isFunctionHotInCallGraphNthPercentile(PgsoCutoffInstrProf, 69 F, PSI, *BFI); 70 } 71 72 template<typename AdapterT, typename BlockTOrBlockFreq, typename BFIT> 73 bool shouldOptimizeForSizeImpl(BlockTOrBlockFreq BBOrBlockFreq, ProfileSummaryInfo *PSI, 74 BFIT *BFI, PGSOQueryType QueryType) { 75 if (!PSI || !BFI || !PSI->hasProfileSummary()) 76 return false; 77 if (ForcePGSO) 78 return true; 79 if (!EnablePGSO) 80 return false; 81 if (isPGSOColdCodeOnly(PSI)) 82 return AdapterT::isColdBlock(BBOrBlockFreq, PSI, BFI); 83 if (PSI->hasSampleProfile()) 84 // The "isCold" check seems to work better for Sample PGO as it could have 85 // many profile-unannotated functions. 86 return AdapterT::isColdBlockNthPercentile(PgsoCutoffSampleProf, 87 BBOrBlockFreq, PSI, BFI); 88 return !AdapterT::isHotBlockNthPercentile(PgsoCutoffInstrProf, BBOrBlockFreq, 89 PSI, BFI); 90 } 91 92 /// Returns true if function \p F is suggested to be size-optimized based on the 93 /// profile. 94 bool shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI, 95 BlockFrequencyInfo *BFI, 96 PGSOQueryType QueryType = PGSOQueryType::Other); 97 98 /// Returns true if basic block \p BB is suggested to be size-optimized based on 99 /// the profile. 100 bool shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI, 101 BlockFrequencyInfo *BFI, 102 PGSOQueryType QueryType = PGSOQueryType::Other); 103 104 } // end namespace llvm 105 106 #endif // LLVM_TRANSFORMS_UTILS_SIZEOPTS_H 107