1*75f72f6bSHiroshi Yamauchi //===- MachineSizeOpts.cpp - code size optimization related code ----------===//
2*75f72f6bSHiroshi Yamauchi //
3*75f72f6bSHiroshi Yamauchi // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*75f72f6bSHiroshi Yamauchi // See https://llvm.org/LICENSE.txt for license information.
5*75f72f6bSHiroshi Yamauchi // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*75f72f6bSHiroshi Yamauchi //
7*75f72f6bSHiroshi Yamauchi //===----------------------------------------------------------------------===//
8*75f72f6bSHiroshi Yamauchi //
9*75f72f6bSHiroshi Yamauchi // This file contains some shared machine IR code size optimization related
10*75f72f6bSHiroshi Yamauchi // code.
11*75f72f6bSHiroshi Yamauchi //
12*75f72f6bSHiroshi Yamauchi //===----------------------------------------------------------------------===//
13*75f72f6bSHiroshi Yamauchi 
14*75f72f6bSHiroshi Yamauchi #include "llvm/CodeGen/MachineSizeOpts.h"
15*75f72f6bSHiroshi Yamauchi #include "llvm/Analysis/ProfileSummaryInfo.h"
16*75f72f6bSHiroshi Yamauchi #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
17*75f72f6bSHiroshi Yamauchi 
18*75f72f6bSHiroshi Yamauchi using namespace llvm;
19*75f72f6bSHiroshi Yamauchi 
20*75f72f6bSHiroshi Yamauchi extern cl::opt<bool> EnablePGSO;
21*75f72f6bSHiroshi Yamauchi extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
22*75f72f6bSHiroshi Yamauchi extern cl::opt<bool> ForcePGSO;
23*75f72f6bSHiroshi Yamauchi extern cl::opt<int> PgsoCutoffInstrProf;
24*75f72f6bSHiroshi Yamauchi extern cl::opt<int> PgsoCutoffSampleProf;
25*75f72f6bSHiroshi Yamauchi 
26*75f72f6bSHiroshi Yamauchi namespace machine_size_opts_detail {
27*75f72f6bSHiroshi Yamauchi 
28*75f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock.
29*75f72f6bSHiroshi Yamauchi bool isColdBlock(const MachineBasicBlock *MBB,
30*75f72f6bSHiroshi Yamauchi                  ProfileSummaryInfo *PSI,
31*75f72f6bSHiroshi Yamauchi                  const MachineBlockFrequencyInfo *MBFI) {
32*75f72f6bSHiroshi Yamauchi   auto Count = MBFI->getBlockProfileCount(MBB);
33*75f72f6bSHiroshi Yamauchi   return Count && PSI->isColdCount(*Count);
34*75f72f6bSHiroshi Yamauchi }
35*75f72f6bSHiroshi Yamauchi 
36*75f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock.
37*75f72f6bSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff,
38*75f72f6bSHiroshi Yamauchi                                     const MachineBasicBlock *MBB,
39*75f72f6bSHiroshi Yamauchi                                     ProfileSummaryInfo *PSI,
40*75f72f6bSHiroshi Yamauchi                                     const MachineBlockFrequencyInfo *MBFI) {
41*75f72f6bSHiroshi Yamauchi   auto Count = MBFI->getBlockProfileCount(MBB);
42*75f72f6bSHiroshi Yamauchi   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
43*75f72f6bSHiroshi Yamauchi }
44*75f72f6bSHiroshi Yamauchi 
45*75f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for
46*75f72f6bSHiroshi Yamauchi /// MachineFunction.
47*75f72f6bSHiroshi Yamauchi bool isFunctionColdInCallGraph(
48*75f72f6bSHiroshi Yamauchi     const MachineFunction *MF,
49*75f72f6bSHiroshi Yamauchi     ProfileSummaryInfo *PSI,
50*75f72f6bSHiroshi Yamauchi     const MachineBlockFrequencyInfo &MBFI) {
51*75f72f6bSHiroshi Yamauchi   if (auto FunctionCount = MF->getFunction().getEntryCount())
52*75f72f6bSHiroshi Yamauchi     if (!PSI->isColdCount(FunctionCount.getCount()))
53*75f72f6bSHiroshi Yamauchi       return false;
54*75f72f6bSHiroshi Yamauchi   for (const auto &MBB : *MF)
55*75f72f6bSHiroshi Yamauchi     if (!isColdBlock(&MBB, PSI, &MBFI))
56*75f72f6bSHiroshi Yamauchi       return false;
57*75f72f6bSHiroshi Yamauchi   return true;
58*75f72f6bSHiroshi Yamauchi }
59*75f72f6bSHiroshi Yamauchi 
60*75f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for
61*75f72f6bSHiroshi Yamauchi /// MachineFunction.
62*75f72f6bSHiroshi Yamauchi bool isFunctionHotInCallGraphNthPercentile(
63*75f72f6bSHiroshi Yamauchi     int PercentileCutoff,
64*75f72f6bSHiroshi Yamauchi     const MachineFunction *MF,
65*75f72f6bSHiroshi Yamauchi     ProfileSummaryInfo *PSI,
66*75f72f6bSHiroshi Yamauchi     const MachineBlockFrequencyInfo &MBFI) {
67*75f72f6bSHiroshi Yamauchi   if (auto FunctionCount = MF->getFunction().getEntryCount())
68*75f72f6bSHiroshi Yamauchi     if (PSI->isHotCountNthPercentile(PercentileCutoff,
69*75f72f6bSHiroshi Yamauchi                                      FunctionCount.getCount()))
70*75f72f6bSHiroshi Yamauchi       return true;
71*75f72f6bSHiroshi Yamauchi   for (const auto &MBB : *MF)
72*75f72f6bSHiroshi Yamauchi     if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
73*75f72f6bSHiroshi Yamauchi       return true;
74*75f72f6bSHiroshi Yamauchi   return false;
75*75f72f6bSHiroshi Yamauchi }
76*75f72f6bSHiroshi Yamauchi } // namespace machine_size_opts_detail
77*75f72f6bSHiroshi Yamauchi 
78*75f72f6bSHiroshi Yamauchi namespace {
79*75f72f6bSHiroshi Yamauchi struct MachineBasicBlockBFIAdapter {
80*75f72f6bSHiroshi Yamauchi   static bool isFunctionColdInCallGraph(const MachineFunction *MF,
81*75f72f6bSHiroshi Yamauchi                                         ProfileSummaryInfo *PSI,
82*75f72f6bSHiroshi Yamauchi                                         const MachineBlockFrequencyInfo &MBFI) {
83*75f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI);
84*75f72f6bSHiroshi Yamauchi   }
85*75f72f6bSHiroshi Yamauchi   static bool isFunctionHotInCallGraphNthPercentile(
86*75f72f6bSHiroshi Yamauchi       int CutOff,
87*75f72f6bSHiroshi Yamauchi       const MachineFunction *MF,
88*75f72f6bSHiroshi Yamauchi       ProfileSummaryInfo *PSI,
89*75f72f6bSHiroshi Yamauchi       const MachineBlockFrequencyInfo &MBFI) {
90*75f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile(
91*75f72f6bSHiroshi Yamauchi         CutOff, MF, PSI, MBFI);
92*75f72f6bSHiroshi Yamauchi   }
93*75f72f6bSHiroshi Yamauchi   static bool isColdBlock(const MachineBasicBlock *MBB,
94*75f72f6bSHiroshi Yamauchi                           ProfileSummaryInfo *PSI,
95*75f72f6bSHiroshi Yamauchi                           const MachineBlockFrequencyInfo *MBFI) {
96*75f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI);
97*75f72f6bSHiroshi Yamauchi   }
98*75f72f6bSHiroshi Yamauchi   static bool isHotBlockNthPercentile(int CutOff,
99*75f72f6bSHiroshi Yamauchi                                       const MachineBasicBlock *MBB,
100*75f72f6bSHiroshi Yamauchi                                       ProfileSummaryInfo *PSI,
101*75f72f6bSHiroshi Yamauchi                                       const MachineBlockFrequencyInfo *MBFI) {
102*75f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isHotBlockNthPercentile(
103*75f72f6bSHiroshi Yamauchi         CutOff, MBB, PSI, MBFI);
104*75f72f6bSHiroshi Yamauchi   }
105*75f72f6bSHiroshi Yamauchi };
106*75f72f6bSHiroshi Yamauchi } // end anonymous namespace
107*75f72f6bSHiroshi Yamauchi 
108*75f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineFunction *MF,
109*75f72f6bSHiroshi Yamauchi                                  ProfileSummaryInfo *PSI,
110*75f72f6bSHiroshi Yamauchi                                  const MachineBlockFrequencyInfo *MBFI) {
111*75f72f6bSHiroshi Yamauchi   return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
112*75f72f6bSHiroshi Yamauchi       MF, PSI, MBFI);
113*75f72f6bSHiroshi Yamauchi }
114*75f72f6bSHiroshi Yamauchi 
115*75f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
116*75f72f6bSHiroshi Yamauchi                                  ProfileSummaryInfo *PSI,
117*75f72f6bSHiroshi Yamauchi                                  const MachineBlockFrequencyInfo *MBFI) {
118*75f72f6bSHiroshi Yamauchi   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
119*75f72f6bSHiroshi Yamauchi       MBB, PSI, MBFI);
120*75f72f6bSHiroshi Yamauchi }
121