xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SizeOpts.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 #include "llvm/Support/Compiler.h"
19 
20 namespace llvm {
21 LLVM_ABI extern cl::opt<bool> EnablePGSO;
22 LLVM_ABI extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
23 LLVM_ABI extern cl::opt<bool> PGSOColdCodeOnly;
24 LLVM_ABI extern cl::opt<bool> PGSOColdCodeOnlyForInstrPGO;
25 LLVM_ABI extern cl::opt<bool> PGSOColdCodeOnlyForSamplePGO;
26 LLVM_ABI extern cl::opt<bool> PGSOColdCodeOnlyForPartialSamplePGO;
27 LLVM_ABI extern cl::opt<bool> ForcePGSO;
28 LLVM_ABI extern cl::opt<int> PgsoCutoffInstrProf;
29 LLVM_ABI 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 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 PSI->isFunctionColdInCallGraph(F, *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 PSI->isFunctionColdInCallGraphNthPercentile(PgsoCutoffSampleProf, F,
67                                                        *BFI);
68   return !PSI->isFunctionHotInCallGraphNthPercentile(PgsoCutoffInstrProf, F,
69                                                      *BFI);
70 }
71 
72 template <typename BlockTOrBlockFreq, typename BFIT>
shouldOptimizeForSizeImpl(BlockTOrBlockFreq BBOrBlockFreq,ProfileSummaryInfo * PSI,BFIT * BFI,PGSOQueryType QueryType)73 bool shouldOptimizeForSizeImpl(BlockTOrBlockFreq BBOrBlockFreq,
74                                ProfileSummaryInfo *PSI, BFIT *BFI,
75                                PGSOQueryType QueryType) {
76   if (!PSI || !BFI || !PSI->hasProfileSummary())
77     return false;
78   if (ForcePGSO)
79     return true;
80   if (!EnablePGSO)
81     return false;
82   if (isPGSOColdCodeOnly(PSI))
83     return PSI->isColdBlock(BBOrBlockFreq, BFI);
84   if (PSI->hasSampleProfile())
85     // The "isCold" check seems to work better for Sample PGO as it could have
86     // many profile-unannotated functions.
87     return PSI->isColdBlockNthPercentile(PgsoCutoffSampleProf, BBOrBlockFreq,
88                                          BFI);
89   return !PSI->isHotBlockNthPercentile(PgsoCutoffInstrProf, BBOrBlockFreq, BFI);
90 }
91 
92 /// Returns true if function \p F is suggested to be size-optimized based on the
93 /// profile.
94 LLVM_ABI bool
95 shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI,
96                       BlockFrequencyInfo *BFI,
97                       PGSOQueryType QueryType = PGSOQueryType::Other);
98 
99 /// Returns true if basic block \p BB is suggested to be size-optimized based on
100 /// the profile.
101 LLVM_ABI bool
102 shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI,
103                       BlockFrequencyInfo *BFI,
104                       PGSOQueryType QueryType = PGSOQueryType::Other);
105 
106 } // end namespace llvm
107 
108 #endif // LLVM_TRANSFORMS_UTILS_SIZEOPTS_H
109