175f72f6bSHiroshi Yamauchi //===- MachineSizeOpts.cpp - code size optimization related code ----------===//
275f72f6bSHiroshi Yamauchi //
375f72f6bSHiroshi Yamauchi // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
475f72f6bSHiroshi Yamauchi // See https://llvm.org/LICENSE.txt for license information.
575f72f6bSHiroshi Yamauchi // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
675f72f6bSHiroshi Yamauchi //
775f72f6bSHiroshi Yamauchi //===----------------------------------------------------------------------===//
875f72f6bSHiroshi Yamauchi //
975f72f6bSHiroshi Yamauchi // This file contains some shared machine IR code size optimization related
1075f72f6bSHiroshi Yamauchi // code.
1175f72f6bSHiroshi Yamauchi //
1275f72f6bSHiroshi Yamauchi //===----------------------------------------------------------------------===//
1375f72f6bSHiroshi Yamauchi 
1475f72f6bSHiroshi Yamauchi #include "llvm/CodeGen/MachineSizeOpts.h"
1575f72f6bSHiroshi Yamauchi #include "llvm/Analysis/ProfileSummaryInfo.h"
16*5dd566b7SSimon Pilgrim #include "llvm/CodeGen/MBFIWrapper.h"
1775f72f6bSHiroshi Yamauchi #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
18*5dd566b7SSimon Pilgrim #include "llvm/IR/Function.h"
1975f72f6bSHiroshi Yamauchi 
2075f72f6bSHiroshi Yamauchi using namespace llvm;
2175f72f6bSHiroshi Yamauchi 
2275f72f6bSHiroshi Yamauchi extern cl::opt<bool> EnablePGSO;
2375f72f6bSHiroshi Yamauchi extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
2475f72f6bSHiroshi Yamauchi extern cl::opt<bool> ForcePGSO;
2575f72f6bSHiroshi Yamauchi extern cl::opt<int> PgsoCutoffInstrProf;
2675f72f6bSHiroshi Yamauchi extern cl::opt<int> PgsoCutoffSampleProf;
2775f72f6bSHiroshi Yamauchi 
28564a9de2SBenjamin Kramer namespace {
2975f72f6bSHiroshi Yamauchi namespace machine_size_opts_detail {
3075f72f6bSHiroshi Yamauchi 
3175f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock.
3275f72f6bSHiroshi Yamauchi bool isColdBlock(const MachineBasicBlock *MBB,
3375f72f6bSHiroshi Yamauchi                  ProfileSummaryInfo *PSI,
3475f72f6bSHiroshi Yamauchi                  const MachineBlockFrequencyInfo *MBFI) {
3575f72f6bSHiroshi Yamauchi   auto Count = MBFI->getBlockProfileCount(MBB);
3675f72f6bSHiroshi Yamauchi   return Count && PSI->isColdCount(*Count);
3775f72f6bSHiroshi Yamauchi }
3875f72f6bSHiroshi Yamauchi 
39ac8da31aSHiroshi Yamauchi bool isColdBlock(BlockFrequency BlockFreq,
40ac8da31aSHiroshi Yamauchi                  ProfileSummaryInfo *PSI,
41ac8da31aSHiroshi Yamauchi                  const MachineBlockFrequencyInfo *MBFI) {
42ac8da31aSHiroshi Yamauchi   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
43ac8da31aSHiroshi Yamauchi   return Count && PSI->isColdCount(*Count);
44ac8da31aSHiroshi Yamauchi }
45ac8da31aSHiroshi Yamauchi 
4675f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock.
4775f72f6bSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff,
4875f72f6bSHiroshi Yamauchi                                     const MachineBasicBlock *MBB,
4975f72f6bSHiroshi Yamauchi                                     ProfileSummaryInfo *PSI,
5075f72f6bSHiroshi Yamauchi                                     const MachineBlockFrequencyInfo *MBFI) {
5175f72f6bSHiroshi Yamauchi   auto Count = MBFI->getBlockProfileCount(MBB);
5275f72f6bSHiroshi Yamauchi   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
5375f72f6bSHiroshi Yamauchi }
5475f72f6bSHiroshi Yamauchi 
55ac8da31aSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff,
56ac8da31aSHiroshi Yamauchi                                     BlockFrequency BlockFreq,
57ac8da31aSHiroshi Yamauchi                                     ProfileSummaryInfo *PSI,
58ac8da31aSHiroshi Yamauchi                                     const MachineBlockFrequencyInfo *MBFI) {
59ac8da31aSHiroshi Yamauchi   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
60ac8da31aSHiroshi Yamauchi   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
61ac8da31aSHiroshi Yamauchi }
62ac8da31aSHiroshi Yamauchi 
6376b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int PercentileCutoff,
6476b9901fSHiroshi Yamauchi                                      const MachineBasicBlock *MBB,
6576b9901fSHiroshi Yamauchi                                      ProfileSummaryInfo *PSI,
6676b9901fSHiroshi Yamauchi                                      const MachineBlockFrequencyInfo *MBFI) {
6776b9901fSHiroshi Yamauchi   auto Count = MBFI->getBlockProfileCount(MBB);
6876b9901fSHiroshi Yamauchi   return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count);
6976b9901fSHiroshi Yamauchi }
7076b9901fSHiroshi Yamauchi 
7176b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int PercentileCutoff,
7276b9901fSHiroshi Yamauchi                                      BlockFrequency BlockFreq,
7376b9901fSHiroshi Yamauchi                                      ProfileSummaryInfo *PSI,
7476b9901fSHiroshi Yamauchi                                      const MachineBlockFrequencyInfo *MBFI) {
7576b9901fSHiroshi Yamauchi   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
7676b9901fSHiroshi Yamauchi   return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count);
7776b9901fSHiroshi Yamauchi }
7876b9901fSHiroshi Yamauchi 
7975f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for
8075f72f6bSHiroshi Yamauchi /// MachineFunction.
8175f72f6bSHiroshi Yamauchi bool isFunctionColdInCallGraph(
8275f72f6bSHiroshi Yamauchi     const MachineFunction *MF,
8375f72f6bSHiroshi Yamauchi     ProfileSummaryInfo *PSI,
8475f72f6bSHiroshi Yamauchi     const MachineBlockFrequencyInfo &MBFI) {
8575f72f6bSHiroshi Yamauchi   if (auto FunctionCount = MF->getFunction().getEntryCount())
8675f72f6bSHiroshi Yamauchi     if (!PSI->isColdCount(FunctionCount.getCount()))
8775f72f6bSHiroshi Yamauchi       return false;
8875f72f6bSHiroshi Yamauchi   for (const auto &MBB : *MF)
8975f72f6bSHiroshi Yamauchi     if (!isColdBlock(&MBB, PSI, &MBFI))
9075f72f6bSHiroshi Yamauchi       return false;
9175f72f6bSHiroshi Yamauchi   return true;
9275f72f6bSHiroshi Yamauchi }
9375f72f6bSHiroshi Yamauchi 
9475f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for
9575f72f6bSHiroshi Yamauchi /// MachineFunction.
9675f72f6bSHiroshi Yamauchi bool isFunctionHotInCallGraphNthPercentile(
9775f72f6bSHiroshi Yamauchi     int PercentileCutoff,
9875f72f6bSHiroshi Yamauchi     const MachineFunction *MF,
9975f72f6bSHiroshi Yamauchi     ProfileSummaryInfo *PSI,
10075f72f6bSHiroshi Yamauchi     const MachineBlockFrequencyInfo &MBFI) {
10175f72f6bSHiroshi Yamauchi   if (auto FunctionCount = MF->getFunction().getEntryCount())
10275f72f6bSHiroshi Yamauchi     if (PSI->isHotCountNthPercentile(PercentileCutoff,
10375f72f6bSHiroshi Yamauchi                                      FunctionCount.getCount()))
10475f72f6bSHiroshi Yamauchi       return true;
10575f72f6bSHiroshi Yamauchi   for (const auto &MBB : *MF)
10675f72f6bSHiroshi Yamauchi     if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
10775f72f6bSHiroshi Yamauchi       return true;
10875f72f6bSHiroshi Yamauchi   return false;
10975f72f6bSHiroshi Yamauchi }
11076b9901fSHiroshi Yamauchi 
11176b9901fSHiroshi Yamauchi bool isFunctionColdInCallGraphNthPercentile(
11276b9901fSHiroshi Yamauchi     int PercentileCutoff, const MachineFunction *MF, ProfileSummaryInfo *PSI,
11376b9901fSHiroshi Yamauchi     const MachineBlockFrequencyInfo &MBFI) {
11476b9901fSHiroshi Yamauchi   if (auto FunctionCount = MF->getFunction().getEntryCount())
11576b9901fSHiroshi Yamauchi     if (!PSI->isColdCountNthPercentile(PercentileCutoff,
11676b9901fSHiroshi Yamauchi                                        FunctionCount.getCount()))
11776b9901fSHiroshi Yamauchi       return false;
11876b9901fSHiroshi Yamauchi   for (const auto &MBB : *MF)
11976b9901fSHiroshi Yamauchi     if (!isColdBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
12076b9901fSHiroshi Yamauchi       return false;
12176b9901fSHiroshi Yamauchi   return true;
12276b9901fSHiroshi Yamauchi }
12375f72f6bSHiroshi Yamauchi } // namespace machine_size_opts_detail
12475f72f6bSHiroshi Yamauchi 
12575f72f6bSHiroshi Yamauchi struct MachineBasicBlockBFIAdapter {
12675f72f6bSHiroshi Yamauchi   static bool isFunctionColdInCallGraph(const MachineFunction *MF,
12775f72f6bSHiroshi Yamauchi                                         ProfileSummaryInfo *PSI,
12875f72f6bSHiroshi Yamauchi                                         const MachineBlockFrequencyInfo &MBFI) {
12975f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI);
13075f72f6bSHiroshi Yamauchi   }
13175f72f6bSHiroshi Yamauchi   static bool isFunctionHotInCallGraphNthPercentile(
13275f72f6bSHiroshi Yamauchi       int CutOff,
13375f72f6bSHiroshi Yamauchi       const MachineFunction *MF,
13475f72f6bSHiroshi Yamauchi       ProfileSummaryInfo *PSI,
13575f72f6bSHiroshi Yamauchi       const MachineBlockFrequencyInfo &MBFI) {
13675f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile(
13775f72f6bSHiroshi Yamauchi         CutOff, MF, PSI, MBFI);
13875f72f6bSHiroshi Yamauchi   }
13976b9901fSHiroshi Yamauchi   static bool isFunctionColdInCallGraphNthPercentile(
14076b9901fSHiroshi Yamauchi       int CutOff, const MachineFunction *MF, ProfileSummaryInfo *PSI,
14176b9901fSHiroshi Yamauchi       const MachineBlockFrequencyInfo &MBFI) {
14276b9901fSHiroshi Yamauchi     return machine_size_opts_detail::isFunctionColdInCallGraphNthPercentile(
14376b9901fSHiroshi Yamauchi         CutOff, MF, PSI, MBFI);
14476b9901fSHiroshi Yamauchi   }
14575f72f6bSHiroshi Yamauchi   static bool isColdBlock(const MachineBasicBlock *MBB,
14675f72f6bSHiroshi Yamauchi                           ProfileSummaryInfo *PSI,
14775f72f6bSHiroshi Yamauchi                           const MachineBlockFrequencyInfo *MBFI) {
14875f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI);
14975f72f6bSHiroshi Yamauchi   }
150ac8da31aSHiroshi Yamauchi   static bool isColdBlock(BlockFrequency BlockFreq,
151ac8da31aSHiroshi Yamauchi                           ProfileSummaryInfo *PSI,
152ac8da31aSHiroshi Yamauchi                           const MachineBlockFrequencyInfo *MBFI) {
153ac8da31aSHiroshi Yamauchi     return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI);
154ac8da31aSHiroshi Yamauchi   }
15575f72f6bSHiroshi Yamauchi   static bool isHotBlockNthPercentile(int CutOff,
15675f72f6bSHiroshi Yamauchi                                       const MachineBasicBlock *MBB,
15775f72f6bSHiroshi Yamauchi                                       ProfileSummaryInfo *PSI,
15875f72f6bSHiroshi Yamauchi                                       const MachineBlockFrequencyInfo *MBFI) {
15975f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isHotBlockNthPercentile(
16075f72f6bSHiroshi Yamauchi         CutOff, MBB, PSI, MBFI);
16175f72f6bSHiroshi Yamauchi   }
162ac8da31aSHiroshi Yamauchi   static bool isHotBlockNthPercentile(int CutOff,
163ac8da31aSHiroshi Yamauchi                                       BlockFrequency BlockFreq,
164ac8da31aSHiroshi Yamauchi                                       ProfileSummaryInfo *PSI,
165ac8da31aSHiroshi Yamauchi                                       const MachineBlockFrequencyInfo *MBFI) {
166ac8da31aSHiroshi Yamauchi     return machine_size_opts_detail::isHotBlockNthPercentile(
167ac8da31aSHiroshi Yamauchi         CutOff, BlockFreq, PSI, MBFI);
168ac8da31aSHiroshi Yamauchi   }
16976b9901fSHiroshi Yamauchi   static bool isColdBlockNthPercentile(int CutOff, const MachineBasicBlock *MBB,
17076b9901fSHiroshi Yamauchi                                        ProfileSummaryInfo *PSI,
17176b9901fSHiroshi Yamauchi                                        const MachineBlockFrequencyInfo *MBFI) {
17276b9901fSHiroshi Yamauchi     return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, MBB, PSI,
17376b9901fSHiroshi Yamauchi                                                               MBFI);
17476b9901fSHiroshi Yamauchi   }
17576b9901fSHiroshi Yamauchi   static bool isColdBlockNthPercentile(int CutOff, BlockFrequency BlockFreq,
17676b9901fSHiroshi Yamauchi                                        ProfileSummaryInfo *PSI,
17776b9901fSHiroshi Yamauchi                                        const MachineBlockFrequencyInfo *MBFI) {
17876b9901fSHiroshi Yamauchi     return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, BlockFreq,
17976b9901fSHiroshi Yamauchi                                                               PSI, MBFI);
18076b9901fSHiroshi Yamauchi   }
18175f72f6bSHiroshi Yamauchi };
18275f72f6bSHiroshi Yamauchi } // end anonymous namespace
18375f72f6bSHiroshi Yamauchi 
18475f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineFunction *MF,
18575f72f6bSHiroshi Yamauchi                                  ProfileSummaryInfo *PSI,
1868cdfdfeeSHiroshi Yamauchi                                  const MachineBlockFrequencyInfo *MBFI,
1878cdfdfeeSHiroshi Yamauchi                                  PGSOQueryType QueryType) {
18875f72f6bSHiroshi Yamauchi   return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
1898cdfdfeeSHiroshi Yamauchi       MF, PSI, MBFI, QueryType);
19075f72f6bSHiroshi Yamauchi }
19175f72f6bSHiroshi Yamauchi 
19275f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
19375f72f6bSHiroshi Yamauchi                                  ProfileSummaryInfo *PSI,
1948cdfdfeeSHiroshi Yamauchi                                  const MachineBlockFrequencyInfo *MBFI,
1958cdfdfeeSHiroshi Yamauchi                                  PGSOQueryType QueryType) {
196ac8da31aSHiroshi Yamauchi   assert(MBB);
19775f72f6bSHiroshi Yamauchi   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
1988cdfdfeeSHiroshi Yamauchi       MBB, PSI, MBFI, QueryType);
19975f72f6bSHiroshi Yamauchi }
200ac8da31aSHiroshi Yamauchi 
201ac8da31aSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
202ac8da31aSHiroshi Yamauchi                                  ProfileSummaryInfo *PSI,
203ac8da31aSHiroshi Yamauchi                                  MBFIWrapper *MBFIW,
204ac8da31aSHiroshi Yamauchi                                  PGSOQueryType QueryType) {
205ac8da31aSHiroshi Yamauchi   assert(MBB);
206ac8da31aSHiroshi Yamauchi   if (!PSI || !MBFIW)
207ac8da31aSHiroshi Yamauchi     return false;
208ac8da31aSHiroshi Yamauchi   BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB);
209ac8da31aSHiroshi Yamauchi   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
210ac8da31aSHiroshi Yamauchi       BlockFreq, PSI, &MBFIW->getMBFI(), QueryType);
211ac8da31aSHiroshi Yamauchi }
212