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