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/Analysis/ProfileSummaryInfo.h"
16 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
17 
18 using namespace llvm;
19 
20 extern cl::opt<bool> EnablePGSO;
21 extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
22 extern cl::opt<bool> ForcePGSO;
23 extern cl::opt<int> PgsoCutoffInstrProf;
24 extern cl::opt<int> PgsoCutoffSampleProf;
25 
26 namespace machine_size_opts_detail {
27 
28 /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock.
29 bool isColdBlock(const MachineBasicBlock *MBB,
30                  ProfileSummaryInfo *PSI,
31                  const MachineBlockFrequencyInfo *MBFI) {
32   auto Count = MBFI->getBlockProfileCount(MBB);
33   return Count && PSI->isColdCount(*Count);
34 }
35 
36 /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock.
37 static bool isHotBlockNthPercentile(int PercentileCutoff,
38                                     const MachineBasicBlock *MBB,
39                                     ProfileSummaryInfo *PSI,
40                                     const MachineBlockFrequencyInfo *MBFI) {
41   auto Count = MBFI->getBlockProfileCount(MBB);
42   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
43 }
44 
45 /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for
46 /// MachineFunction.
47 bool isFunctionColdInCallGraph(
48     const MachineFunction *MF,
49     ProfileSummaryInfo *PSI,
50     const MachineBlockFrequencyInfo &MBFI) {
51   if (auto FunctionCount = MF->getFunction().getEntryCount())
52     if (!PSI->isColdCount(FunctionCount.getCount()))
53       return false;
54   for (const auto &MBB : *MF)
55     if (!isColdBlock(&MBB, PSI, &MBFI))
56       return false;
57   return true;
58 }
59 
60 /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for
61 /// MachineFunction.
62 bool isFunctionHotInCallGraphNthPercentile(
63     int PercentileCutoff,
64     const MachineFunction *MF,
65     ProfileSummaryInfo *PSI,
66     const MachineBlockFrequencyInfo &MBFI) {
67   if (auto FunctionCount = MF->getFunction().getEntryCount())
68     if (PSI->isHotCountNthPercentile(PercentileCutoff,
69                                      FunctionCount.getCount()))
70       return true;
71   for (const auto &MBB : *MF)
72     if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
73       return true;
74   return false;
75 }
76 } // namespace machine_size_opts_detail
77 
78 namespace {
79 struct MachineBasicBlockBFIAdapter {
80   static bool isFunctionColdInCallGraph(const MachineFunction *MF,
81                                         ProfileSummaryInfo *PSI,
82                                         const MachineBlockFrequencyInfo &MBFI) {
83     return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI);
84   }
85   static bool isFunctionHotInCallGraphNthPercentile(
86       int CutOff,
87       const MachineFunction *MF,
88       ProfileSummaryInfo *PSI,
89       const MachineBlockFrequencyInfo &MBFI) {
90     return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile(
91         CutOff, MF, PSI, MBFI);
92   }
93   static bool isColdBlock(const MachineBasicBlock *MBB,
94                           ProfileSummaryInfo *PSI,
95                           const MachineBlockFrequencyInfo *MBFI) {
96     return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI);
97   }
98   static bool isHotBlockNthPercentile(int CutOff,
99                                       const MachineBasicBlock *MBB,
100                                       ProfileSummaryInfo *PSI,
101                                       const MachineBlockFrequencyInfo *MBFI) {
102     return machine_size_opts_detail::isHotBlockNthPercentile(
103         CutOff, MBB, PSI, MBFI);
104   }
105 };
106 } // end anonymous namespace
107 
108 bool llvm::shouldOptimizeForSize(const MachineFunction *MF,
109                                  ProfileSummaryInfo *PSI,
110                                  const MachineBlockFrequencyInfo *MBFI,
111                                  PGSOQueryType QueryType) {
112   return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
113       MF, PSI, MBFI, QueryType);
114 }
115 
116 bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
117                                  ProfileSummaryInfo *PSI,
118                                  const MachineBlockFrequencyInfo *MBFI,
119                                  PGSOQueryType QueryType) {
120   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
121       MBB, PSI, MBFI, QueryType);
122 }
123