1 //===- MachineSizeOpts.cpp - code size optimization related code ----------===//
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 machine IR code size optimization related
10 // code.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/CodeGen/MachineSizeOpts.h"
15 #include "llvm/CodeGen/MBFIWrapper.h"
16 #include "llvm/Analysis/ProfileSummaryInfo.h"
17 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
18 
19 using namespace llvm;
20 
21 extern cl::opt<bool> EnablePGSO;
22 extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
23 extern cl::opt<bool> ForcePGSO;
24 extern cl::opt<int> PgsoCutoffInstrProf;
25 extern cl::opt<int> PgsoCutoffSampleProf;
26 
27 namespace {
28 namespace machine_size_opts_detail {
29 
30 /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock.
31 bool isColdBlock(const MachineBasicBlock *MBB,
32                  ProfileSummaryInfo *PSI,
33                  const MachineBlockFrequencyInfo *MBFI) {
34   auto Count = MBFI->getBlockProfileCount(MBB);
35   return Count && PSI->isColdCount(*Count);
36 }
37 
38 bool isColdBlock(BlockFrequency BlockFreq,
39                  ProfileSummaryInfo *PSI,
40                  const MachineBlockFrequencyInfo *MBFI) {
41   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
42   return Count && PSI->isColdCount(*Count);
43 }
44 
45 /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock.
46 static bool isHotBlockNthPercentile(int PercentileCutoff,
47                                     const MachineBasicBlock *MBB,
48                                     ProfileSummaryInfo *PSI,
49                                     const MachineBlockFrequencyInfo *MBFI) {
50   auto Count = MBFI->getBlockProfileCount(MBB);
51   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
52 }
53 
54 static bool isHotBlockNthPercentile(int PercentileCutoff,
55                                     BlockFrequency BlockFreq,
56                                     ProfileSummaryInfo *PSI,
57                                     const MachineBlockFrequencyInfo *MBFI) {
58   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
59   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
60 }
61 
62 static bool isColdBlockNthPercentile(int PercentileCutoff,
63                                      const MachineBasicBlock *MBB,
64                                      ProfileSummaryInfo *PSI,
65                                      const MachineBlockFrequencyInfo *MBFI) {
66   auto Count = MBFI->getBlockProfileCount(MBB);
67   return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count);
68 }
69 
70 static bool isColdBlockNthPercentile(int PercentileCutoff,
71                                      BlockFrequency BlockFreq,
72                                      ProfileSummaryInfo *PSI,
73                                      const MachineBlockFrequencyInfo *MBFI) {
74   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
75   return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count);
76 }
77 
78 /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for
79 /// MachineFunction.
80 bool isFunctionColdInCallGraph(
81     const MachineFunction *MF,
82     ProfileSummaryInfo *PSI,
83     const MachineBlockFrequencyInfo &MBFI) {
84   if (auto FunctionCount = MF->getFunction().getEntryCount())
85     if (!PSI->isColdCount(FunctionCount.getCount()))
86       return false;
87   for (const auto &MBB : *MF)
88     if (!isColdBlock(&MBB, PSI, &MBFI))
89       return false;
90   return true;
91 }
92 
93 /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for
94 /// MachineFunction.
95 bool isFunctionHotInCallGraphNthPercentile(
96     int PercentileCutoff,
97     const MachineFunction *MF,
98     ProfileSummaryInfo *PSI,
99     const MachineBlockFrequencyInfo &MBFI) {
100   if (auto FunctionCount = MF->getFunction().getEntryCount())
101     if (PSI->isHotCountNthPercentile(PercentileCutoff,
102                                      FunctionCount.getCount()))
103       return true;
104   for (const auto &MBB : *MF)
105     if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
106       return true;
107   return false;
108 }
109 
110 bool isFunctionColdInCallGraphNthPercentile(
111     int PercentileCutoff, const MachineFunction *MF, ProfileSummaryInfo *PSI,
112     const MachineBlockFrequencyInfo &MBFI) {
113   if (auto FunctionCount = MF->getFunction().getEntryCount())
114     if (!PSI->isColdCountNthPercentile(PercentileCutoff,
115                                        FunctionCount.getCount()))
116       return false;
117   for (const auto &MBB : *MF)
118     if (!isColdBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
119       return false;
120   return true;
121 }
122 } // namespace machine_size_opts_detail
123 
124 struct MachineBasicBlockBFIAdapter {
125   static bool isFunctionColdInCallGraph(const MachineFunction *MF,
126                                         ProfileSummaryInfo *PSI,
127                                         const MachineBlockFrequencyInfo &MBFI) {
128     return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI);
129   }
130   static bool isFunctionHotInCallGraphNthPercentile(
131       int CutOff,
132       const MachineFunction *MF,
133       ProfileSummaryInfo *PSI,
134       const MachineBlockFrequencyInfo &MBFI) {
135     return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile(
136         CutOff, MF, PSI, MBFI);
137   }
138   static bool isFunctionColdInCallGraphNthPercentile(
139       int CutOff, const MachineFunction *MF, ProfileSummaryInfo *PSI,
140       const MachineBlockFrequencyInfo &MBFI) {
141     return machine_size_opts_detail::isFunctionColdInCallGraphNthPercentile(
142         CutOff, MF, PSI, MBFI);
143   }
144   static bool isColdBlock(const MachineBasicBlock *MBB,
145                           ProfileSummaryInfo *PSI,
146                           const MachineBlockFrequencyInfo *MBFI) {
147     return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI);
148   }
149   static bool isColdBlock(BlockFrequency BlockFreq,
150                           ProfileSummaryInfo *PSI,
151                           const MachineBlockFrequencyInfo *MBFI) {
152     return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI);
153   }
154   static bool isHotBlockNthPercentile(int CutOff,
155                                       const MachineBasicBlock *MBB,
156                                       ProfileSummaryInfo *PSI,
157                                       const MachineBlockFrequencyInfo *MBFI) {
158     return machine_size_opts_detail::isHotBlockNthPercentile(
159         CutOff, MBB, PSI, MBFI);
160   }
161   static bool isHotBlockNthPercentile(int CutOff,
162                                       BlockFrequency BlockFreq,
163                                       ProfileSummaryInfo *PSI,
164                                       const MachineBlockFrequencyInfo *MBFI) {
165     return machine_size_opts_detail::isHotBlockNthPercentile(
166         CutOff, BlockFreq, PSI, MBFI);
167   }
168   static bool isColdBlockNthPercentile(int CutOff, const MachineBasicBlock *MBB,
169                                        ProfileSummaryInfo *PSI,
170                                        const MachineBlockFrequencyInfo *MBFI) {
171     return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, MBB, PSI,
172                                                               MBFI);
173   }
174   static bool isColdBlockNthPercentile(int CutOff, BlockFrequency BlockFreq,
175                                        ProfileSummaryInfo *PSI,
176                                        const MachineBlockFrequencyInfo *MBFI) {
177     return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, BlockFreq,
178                                                               PSI, MBFI);
179   }
180 };
181 } // end anonymous namespace
182 
183 bool llvm::shouldOptimizeForSize(const MachineFunction *MF,
184                                  ProfileSummaryInfo *PSI,
185                                  const MachineBlockFrequencyInfo *MBFI,
186                                  PGSOQueryType QueryType) {
187   return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
188       MF, PSI, MBFI, QueryType);
189 }
190 
191 bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
192                                  ProfileSummaryInfo *PSI,
193                                  const MachineBlockFrequencyInfo *MBFI,
194                                  PGSOQueryType QueryType) {
195   assert(MBB);
196   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
197       MBB, PSI, MBFI, QueryType);
198 }
199 
200 bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
201                                  ProfileSummaryInfo *PSI,
202                                  MBFIWrapper *MBFIW,
203                                  PGSOQueryType QueryType) {
204   assert(MBB);
205   if (!PSI || !MBFIW)
206     return false;
207   BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB);
208   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
209       BlockFreq, PSI, &MBFIW->getMBFI(), QueryType);
210 }
211