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 extern llvm::cl::opt<bool> EnablePGSO; 21 extern llvm::cl::opt<bool> PGSOLargeWorkingSetSizeOnly; 22 extern llvm::cl::opt<bool> PGSOIRPassOrTestOnly; 23 extern llvm::cl::opt<bool> PGSOColdCodeOnly; 24 extern llvm::cl::opt<bool> ForcePGSO; 25 extern llvm::cl::opt<int> PgsoCutoffInstrProf; 26 extern llvm::cl::opt<int> PgsoCutoffSampleProf; 27 28 namespace llvm { 29 30 class BasicBlock; 31 class BlockFrequencyInfo; 32 class Function; 33 class ProfileSummaryInfo; 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 template<typename AdapterT, typename FuncT, typename BFIT> 42 bool shouldFuncOptimizeForSizeImpl(const FuncT *F, ProfileSummaryInfo *PSI, 43 BFIT *BFI, PGSOQueryType QueryType) { 44 assert(F); 45 if (!PSI || !BFI || !PSI->hasProfileSummary()) 46 return false; 47 if (ForcePGSO) 48 return true; 49 if (!EnablePGSO) 50 return false; 51 // Temporarily enable size optimizations only for the IR pass or test query 52 // sites for gradual commit/rollout. This is to be removed later. 53 if (PGSOIRPassOrTestOnly && !(QueryType == PGSOQueryType::IRPass || 54 QueryType == PGSOQueryType::Test)) 55 return false; 56 if (PGSOColdCodeOnly || 57 (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize())) { 58 // Even if the working set size isn't large, size-optimize cold code. 59 return AdapterT::isFunctionColdInCallGraph(F, PSI, *BFI); 60 } 61 return !AdapterT::isFunctionHotInCallGraphNthPercentile( 62 PSI->hasSampleProfile() ? PgsoCutoffSampleProf : PgsoCutoffInstrProf, 63 F, PSI, *BFI); 64 } 65 66 template<typename AdapterT, typename BlockT, typename BFIT> 67 bool shouldOptimizeForSizeImpl(const BlockT *BB, ProfileSummaryInfo *PSI, 68 BFIT *BFI, PGSOQueryType QueryType) { 69 assert(BB); 70 if (!PSI || !BFI || !PSI->hasProfileSummary()) 71 return false; 72 if (ForcePGSO) 73 return true; 74 if (!EnablePGSO) 75 return false; 76 // Temporarily enable size optimizations only for the IR pass or test query 77 // sites for gradual commit/rollout. This is to be removed later. 78 if (PGSOIRPassOrTestOnly && !(QueryType == PGSOQueryType::IRPass || 79 QueryType == PGSOQueryType::Test)) 80 return false; 81 if (PGSOColdCodeOnly || 82 (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize())) { 83 // Even if the working set size isn't large, size-optimize cold code. 84 return AdapterT::isColdBlock(BB, PSI, BFI); 85 } 86 return !AdapterT::isHotBlockNthPercentile( 87 PSI->hasSampleProfile() ? PgsoCutoffSampleProf : PgsoCutoffInstrProf, 88 BB, 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