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.
isColdBlock(const MachineBasicBlock * MBB,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo * MBFI)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
isColdBlock(BlockFrequency BlockFreq,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo * MBFI)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.
isHotBlockNthPercentile(int PercentileCutoff,const MachineBasicBlock * MBB,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo * MBFI)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
isHotBlockNthPercentile(int PercentileCutoff,BlockFrequency BlockFreq,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo * MBFI)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
isColdBlockNthPercentile(int PercentileCutoff,const MachineBasicBlock * MBB,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo * MBFI)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
isColdBlockNthPercentile(int PercentileCutoff,BlockFrequency BlockFreq,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo * MBFI)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.
isFunctionColdInCallGraph(const MachineFunction * MF,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo & MBFI)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.
isFunctionHotInCallGraphNthPercentile(int PercentileCutoff,const MachineFunction * MF,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo & MBFI)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
isFunctionColdInCallGraphNthPercentile(int PercentileCutoff,const MachineFunction * MF,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo & MBFI)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 {
isFunctionColdInCallGraph__anon5b0f101e0111::MachineBasicBlockBFIAdapter125480093f4SDimitry 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 }
isFunctionHotInCallGraphNthPercentile__anon5b0f101e0111::MachineBasicBlockBFIAdapter130480093f4SDimitry 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 }
isFunctionColdInCallGraphNthPercentile__anon5b0f101e0111::MachineBasicBlockBFIAdapter138*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 }
isColdBlock__anon5b0f101e0111::MachineBasicBlockBFIAdapter144480093f4SDimitry 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 }
isColdBlock__anon5b0f101e0111::MachineBasicBlockBFIAdapter149*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 }
isHotBlockNthPercentile__anon5b0f101e0111::MachineBasicBlockBFIAdapter154480093f4SDimitry 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 }
isHotBlockNthPercentile__anon5b0f101e0111::MachineBasicBlockBFIAdapter161*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 }
isColdBlockNthPercentile__anon5b0f101e0111::MachineBasicBlockBFIAdapter168*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 }
isColdBlockNthPercentile__anon5b0f101e0111::MachineBasicBlockBFIAdapter174*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
shouldOptimizeForSize(const MachineFunction * MF,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo * MBFI,PGSOQueryType QueryType)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
shouldOptimizeForSize(const MachineBasicBlock * MBB,ProfileSummaryInfo * PSI,const MachineBlockFrequencyInfo * MBFI,PGSOQueryType QueryType)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
shouldOptimizeForSize(const MachineBasicBlock * MBB,ProfileSummaryInfo * PSI,MBFIWrapper * MBFIW,PGSOQueryType QueryType)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