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
isPGSOColdCodeOnly(ProfileSummaryInfo * PSI)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>
shouldFuncOptimizeForSizeImpl(const FuncT * F,ProfileSummaryInfo * PSI,BFIT * BFI,PGSOQueryType QueryType)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>
shouldOptimizeForSizeImpl(BlockTOrBlockFreq BBOrBlockFreq,ProfileSummaryInfo * PSI,BFIT * BFI,PGSOQueryType QueryType)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