xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MachineSizeOpts.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1480093f4SDimitry Andric //===- MachineSizeOpts.cpp - code size optimization related code ----------===//
2480093f4SDimitry Andric //
3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric //
7480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8480093f4SDimitry Andric //
9480093f4SDimitry Andric // This file contains some shared machine IR code size optimization related
10480093f4SDimitry Andric // code.
11480093f4SDimitry Andric //
12480093f4SDimitry Andric //===----------------------------------------------------------------------===//
13480093f4SDimitry Andric 
14480093f4SDimitry Andric #include "llvm/CodeGen/MachineSizeOpts.h"
15*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MBFIWrapper.h"
16480093f4SDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h"
17480093f4SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
18480093f4SDimitry Andric 
19480093f4SDimitry Andric using namespace llvm;
20480093f4SDimitry Andric 
21480093f4SDimitry Andric extern cl::opt<bool> EnablePGSO;
22480093f4SDimitry Andric extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
23480093f4SDimitry Andric extern cl::opt<bool> ForcePGSO;
24480093f4SDimitry Andric extern cl::opt<int> PgsoCutoffInstrProf;
25480093f4SDimitry Andric extern cl::opt<int> PgsoCutoffSampleProf;
26480093f4SDimitry Andric 
27*5ffd83dbSDimitry Andric namespace {
28480093f4SDimitry Andric namespace machine_size_opts_detail {
29480093f4SDimitry Andric 
30480093f4SDimitry Andric /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock.
31480093f4SDimitry Andric bool isColdBlock(const MachineBasicBlock *MBB,
32480093f4SDimitry Andric                  ProfileSummaryInfo *PSI,
33480093f4SDimitry Andric                  const MachineBlockFrequencyInfo *MBFI) {
34480093f4SDimitry Andric   auto Count = MBFI->getBlockProfileCount(MBB);
35480093f4SDimitry Andric   return Count && PSI->isColdCount(*Count);
36480093f4SDimitry Andric }
37480093f4SDimitry Andric 
38*5ffd83dbSDimitry Andric bool isColdBlock(BlockFrequency BlockFreq,
39*5ffd83dbSDimitry Andric                  ProfileSummaryInfo *PSI,
40*5ffd83dbSDimitry Andric                  const MachineBlockFrequencyInfo *MBFI) {
41*5ffd83dbSDimitry Andric   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
42*5ffd83dbSDimitry Andric   return Count && PSI->isColdCount(*Count);
43*5ffd83dbSDimitry Andric }
44*5ffd83dbSDimitry Andric 
45480093f4SDimitry Andric /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock.
46480093f4SDimitry Andric static bool isHotBlockNthPercentile(int PercentileCutoff,
47480093f4SDimitry Andric                                     const MachineBasicBlock *MBB,
48480093f4SDimitry Andric                                     ProfileSummaryInfo *PSI,
49480093f4SDimitry Andric                                     const MachineBlockFrequencyInfo *MBFI) {
50480093f4SDimitry Andric   auto Count = MBFI->getBlockProfileCount(MBB);
51480093f4SDimitry Andric   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
52480093f4SDimitry Andric }
53480093f4SDimitry Andric 
54*5ffd83dbSDimitry Andric static bool isHotBlockNthPercentile(int PercentileCutoff,
55*5ffd83dbSDimitry Andric                                     BlockFrequency BlockFreq,
56*5ffd83dbSDimitry Andric                                     ProfileSummaryInfo *PSI,
57*5ffd83dbSDimitry Andric                                     const MachineBlockFrequencyInfo *MBFI) {
58*5ffd83dbSDimitry Andric   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
59*5ffd83dbSDimitry Andric   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
60*5ffd83dbSDimitry Andric }
61*5ffd83dbSDimitry Andric 
62*5ffd83dbSDimitry Andric static bool isColdBlockNthPercentile(int PercentileCutoff,
63*5ffd83dbSDimitry Andric                                      const MachineBasicBlock *MBB,
64*5ffd83dbSDimitry Andric                                      ProfileSummaryInfo *PSI,
65*5ffd83dbSDimitry Andric                                      const MachineBlockFrequencyInfo *MBFI) {
66*5ffd83dbSDimitry Andric   auto Count = MBFI->getBlockProfileCount(MBB);
67*5ffd83dbSDimitry Andric   return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count);
68*5ffd83dbSDimitry Andric }
69*5ffd83dbSDimitry Andric 
70*5ffd83dbSDimitry Andric static bool isColdBlockNthPercentile(int PercentileCutoff,
71*5ffd83dbSDimitry Andric                                      BlockFrequency BlockFreq,
72*5ffd83dbSDimitry Andric                                      ProfileSummaryInfo *PSI,
73*5ffd83dbSDimitry Andric                                      const MachineBlockFrequencyInfo *MBFI) {
74*5ffd83dbSDimitry Andric   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
75*5ffd83dbSDimitry Andric   return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count);
76*5ffd83dbSDimitry Andric }
77*5ffd83dbSDimitry Andric 
78480093f4SDimitry Andric /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for
79480093f4SDimitry Andric /// MachineFunction.
80480093f4SDimitry Andric bool isFunctionColdInCallGraph(
81480093f4SDimitry Andric     const MachineFunction *MF,
82480093f4SDimitry Andric     ProfileSummaryInfo *PSI,
83480093f4SDimitry Andric     const MachineBlockFrequencyInfo &MBFI) {
84480093f4SDimitry Andric   if (auto FunctionCount = MF->getFunction().getEntryCount())
85480093f4SDimitry Andric     if (!PSI->isColdCount(FunctionCount.getCount()))
86480093f4SDimitry Andric       return false;
87480093f4SDimitry Andric   for (const auto &MBB : *MF)
88480093f4SDimitry Andric     if (!isColdBlock(&MBB, PSI, &MBFI))
89480093f4SDimitry Andric       return false;
90480093f4SDimitry Andric   return true;
91480093f4SDimitry Andric }
92480093f4SDimitry Andric 
93480093f4SDimitry Andric /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for
94480093f4SDimitry Andric /// MachineFunction.
95480093f4SDimitry Andric bool isFunctionHotInCallGraphNthPercentile(
96480093f4SDimitry Andric     int PercentileCutoff,
97480093f4SDimitry Andric     const MachineFunction *MF,
98480093f4SDimitry Andric     ProfileSummaryInfo *PSI,
99480093f4SDimitry Andric     const MachineBlockFrequencyInfo &MBFI) {
100480093f4SDimitry Andric   if (auto FunctionCount = MF->getFunction().getEntryCount())
101480093f4SDimitry Andric     if (PSI->isHotCountNthPercentile(PercentileCutoff,
102480093f4SDimitry Andric                                      FunctionCount.getCount()))
103480093f4SDimitry Andric       return true;
104480093f4SDimitry Andric   for (const auto &MBB : *MF)
105480093f4SDimitry Andric     if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
106480093f4SDimitry Andric       return true;
107480093f4SDimitry Andric   return false;
108480093f4SDimitry Andric }
109*5ffd83dbSDimitry Andric 
110*5ffd83dbSDimitry Andric bool isFunctionColdInCallGraphNthPercentile(
111*5ffd83dbSDimitry Andric     int PercentileCutoff, const MachineFunction *MF, ProfileSummaryInfo *PSI,
112*5ffd83dbSDimitry Andric     const MachineBlockFrequencyInfo &MBFI) {
113*5ffd83dbSDimitry Andric   if (auto FunctionCount = MF->getFunction().getEntryCount())
114*5ffd83dbSDimitry Andric     if (!PSI->isColdCountNthPercentile(PercentileCutoff,
115*5ffd83dbSDimitry Andric                                        FunctionCount.getCount()))
116*5ffd83dbSDimitry Andric       return false;
117*5ffd83dbSDimitry Andric   for (const auto &MBB : *MF)
118*5ffd83dbSDimitry Andric     if (!isColdBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
119*5ffd83dbSDimitry Andric       return false;
120*5ffd83dbSDimitry Andric   return true;
121*5ffd83dbSDimitry Andric }
122480093f4SDimitry Andric } // namespace machine_size_opts_detail
123480093f4SDimitry Andric 
124480093f4SDimitry Andric struct MachineBasicBlockBFIAdapter {
125480093f4SDimitry Andric   static bool isFunctionColdInCallGraph(const MachineFunction *MF,
126480093f4SDimitry Andric                                         ProfileSummaryInfo *PSI,
127480093f4SDimitry Andric                                         const MachineBlockFrequencyInfo &MBFI) {
128480093f4SDimitry Andric     return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI);
129480093f4SDimitry Andric   }
130480093f4SDimitry Andric   static bool isFunctionHotInCallGraphNthPercentile(
131480093f4SDimitry Andric       int CutOff,
132480093f4SDimitry Andric       const MachineFunction *MF,
133480093f4SDimitry Andric       ProfileSummaryInfo *PSI,
134480093f4SDimitry Andric       const MachineBlockFrequencyInfo &MBFI) {
135480093f4SDimitry Andric     return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile(
136480093f4SDimitry Andric         CutOff, MF, PSI, MBFI);
137480093f4SDimitry Andric   }
138*5ffd83dbSDimitry Andric   static bool isFunctionColdInCallGraphNthPercentile(
139*5ffd83dbSDimitry Andric       int CutOff, const MachineFunction *MF, ProfileSummaryInfo *PSI,
140*5ffd83dbSDimitry Andric       const MachineBlockFrequencyInfo &MBFI) {
141*5ffd83dbSDimitry Andric     return machine_size_opts_detail::isFunctionColdInCallGraphNthPercentile(
142*5ffd83dbSDimitry Andric         CutOff, MF, PSI, MBFI);
143*5ffd83dbSDimitry Andric   }
144480093f4SDimitry Andric   static bool isColdBlock(const MachineBasicBlock *MBB,
145480093f4SDimitry Andric                           ProfileSummaryInfo *PSI,
146480093f4SDimitry Andric                           const MachineBlockFrequencyInfo *MBFI) {
147480093f4SDimitry Andric     return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI);
148480093f4SDimitry Andric   }
149*5ffd83dbSDimitry Andric   static bool isColdBlock(BlockFrequency BlockFreq,
150*5ffd83dbSDimitry Andric                           ProfileSummaryInfo *PSI,
151*5ffd83dbSDimitry Andric                           const MachineBlockFrequencyInfo *MBFI) {
152*5ffd83dbSDimitry Andric     return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI);
153*5ffd83dbSDimitry Andric   }
154480093f4SDimitry Andric   static bool isHotBlockNthPercentile(int CutOff,
155480093f4SDimitry Andric                                       const MachineBasicBlock *MBB,
156480093f4SDimitry Andric                                       ProfileSummaryInfo *PSI,
157480093f4SDimitry Andric                                       const MachineBlockFrequencyInfo *MBFI) {
158480093f4SDimitry Andric     return machine_size_opts_detail::isHotBlockNthPercentile(
159480093f4SDimitry Andric         CutOff, MBB, PSI, MBFI);
160480093f4SDimitry Andric   }
161*5ffd83dbSDimitry Andric   static bool isHotBlockNthPercentile(int CutOff,
162*5ffd83dbSDimitry Andric                                       BlockFrequency BlockFreq,
163*5ffd83dbSDimitry Andric                                       ProfileSummaryInfo *PSI,
164*5ffd83dbSDimitry Andric                                       const MachineBlockFrequencyInfo *MBFI) {
165*5ffd83dbSDimitry Andric     return machine_size_opts_detail::isHotBlockNthPercentile(
166*5ffd83dbSDimitry Andric         CutOff, BlockFreq, PSI, MBFI);
167*5ffd83dbSDimitry Andric   }
168*5ffd83dbSDimitry Andric   static bool isColdBlockNthPercentile(int CutOff, const MachineBasicBlock *MBB,
169*5ffd83dbSDimitry Andric                                        ProfileSummaryInfo *PSI,
170*5ffd83dbSDimitry Andric                                        const MachineBlockFrequencyInfo *MBFI) {
171*5ffd83dbSDimitry Andric     return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, MBB, PSI,
172*5ffd83dbSDimitry Andric                                                               MBFI);
173*5ffd83dbSDimitry Andric   }
174*5ffd83dbSDimitry Andric   static bool isColdBlockNthPercentile(int CutOff, BlockFrequency BlockFreq,
175*5ffd83dbSDimitry Andric                                        ProfileSummaryInfo *PSI,
176*5ffd83dbSDimitry Andric                                        const MachineBlockFrequencyInfo *MBFI) {
177*5ffd83dbSDimitry Andric     return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, BlockFreq,
178*5ffd83dbSDimitry Andric                                                               PSI, MBFI);
179*5ffd83dbSDimitry Andric   }
180480093f4SDimitry Andric };
181480093f4SDimitry Andric } // end anonymous namespace
182480093f4SDimitry Andric 
183480093f4SDimitry Andric bool llvm::shouldOptimizeForSize(const MachineFunction *MF,
184480093f4SDimitry Andric                                  ProfileSummaryInfo *PSI,
185480093f4SDimitry Andric                                  const MachineBlockFrequencyInfo *MBFI,
186480093f4SDimitry Andric                                  PGSOQueryType QueryType) {
187480093f4SDimitry Andric   return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
188480093f4SDimitry Andric       MF, PSI, MBFI, QueryType);
189480093f4SDimitry Andric }
190480093f4SDimitry Andric 
191480093f4SDimitry Andric bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
192480093f4SDimitry Andric                                  ProfileSummaryInfo *PSI,
193480093f4SDimitry Andric                                  const MachineBlockFrequencyInfo *MBFI,
194480093f4SDimitry Andric                                  PGSOQueryType QueryType) {
195*5ffd83dbSDimitry Andric   assert(MBB);
196480093f4SDimitry Andric   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
197480093f4SDimitry Andric       MBB, PSI, MBFI, QueryType);
198480093f4SDimitry Andric }
199*5ffd83dbSDimitry Andric 
200*5ffd83dbSDimitry Andric bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
201*5ffd83dbSDimitry Andric                                  ProfileSummaryInfo *PSI,
202*5ffd83dbSDimitry Andric                                  MBFIWrapper *MBFIW,
203*5ffd83dbSDimitry Andric                                  PGSOQueryType QueryType) {
204*5ffd83dbSDimitry Andric   assert(MBB);
205*5ffd83dbSDimitry Andric   if (!PSI || !MBFIW)
206*5ffd83dbSDimitry Andric     return false;
207*5ffd83dbSDimitry Andric   BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB);
208*5ffd83dbSDimitry Andric   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
209*5ffd83dbSDimitry Andric       BlockFreq, PSI, &MBFIW->getMBFI(), QueryType);
210*5ffd83dbSDimitry Andric }
211