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"
15*ac8da31aSHiroshi Yamauchi #include "llvm/CodeGen/MBFIWrapper.h"
1675f72f6bSHiroshi Yamauchi #include "llvm/Analysis/ProfileSummaryInfo.h"
1775f72f6bSHiroshi Yamauchi #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
1875f72f6bSHiroshi Yamauchi 
1975f72f6bSHiroshi Yamauchi using namespace llvm;
2075f72f6bSHiroshi Yamauchi 
2175f72f6bSHiroshi Yamauchi extern cl::opt<bool> EnablePGSO;
2275f72f6bSHiroshi Yamauchi extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
2375f72f6bSHiroshi Yamauchi extern cl::opt<bool> ForcePGSO;
2475f72f6bSHiroshi Yamauchi extern cl::opt<int> PgsoCutoffInstrProf;
2575f72f6bSHiroshi Yamauchi extern cl::opt<int> PgsoCutoffSampleProf;
2675f72f6bSHiroshi Yamauchi 
2775f72f6bSHiroshi Yamauchi namespace machine_size_opts_detail {
2875f72f6bSHiroshi Yamauchi 
2975f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock.
3075f72f6bSHiroshi Yamauchi bool isColdBlock(const MachineBasicBlock *MBB,
3175f72f6bSHiroshi Yamauchi                  ProfileSummaryInfo *PSI,
3275f72f6bSHiroshi Yamauchi                  const MachineBlockFrequencyInfo *MBFI) {
3375f72f6bSHiroshi Yamauchi   auto Count = MBFI->getBlockProfileCount(MBB);
3475f72f6bSHiroshi Yamauchi   return Count && PSI->isColdCount(*Count);
3575f72f6bSHiroshi Yamauchi }
3675f72f6bSHiroshi Yamauchi 
37*ac8da31aSHiroshi Yamauchi bool isColdBlock(BlockFrequency BlockFreq,
38*ac8da31aSHiroshi Yamauchi                  ProfileSummaryInfo *PSI,
39*ac8da31aSHiroshi Yamauchi                  const MachineBlockFrequencyInfo *MBFI) {
40*ac8da31aSHiroshi Yamauchi   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
41*ac8da31aSHiroshi Yamauchi   return Count && PSI->isColdCount(*Count);
42*ac8da31aSHiroshi Yamauchi }
43*ac8da31aSHiroshi Yamauchi 
4475f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock.
4575f72f6bSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff,
4675f72f6bSHiroshi Yamauchi                                     const MachineBasicBlock *MBB,
4775f72f6bSHiroshi Yamauchi                                     ProfileSummaryInfo *PSI,
4875f72f6bSHiroshi Yamauchi                                     const MachineBlockFrequencyInfo *MBFI) {
4975f72f6bSHiroshi Yamauchi   auto Count = MBFI->getBlockProfileCount(MBB);
5075f72f6bSHiroshi Yamauchi   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
5175f72f6bSHiroshi Yamauchi }
5275f72f6bSHiroshi Yamauchi 
53*ac8da31aSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff,
54*ac8da31aSHiroshi Yamauchi                                     BlockFrequency BlockFreq,
55*ac8da31aSHiroshi Yamauchi                                     ProfileSummaryInfo *PSI,
56*ac8da31aSHiroshi Yamauchi                                     const MachineBlockFrequencyInfo *MBFI) {
57*ac8da31aSHiroshi Yamauchi   auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency());
58*ac8da31aSHiroshi Yamauchi   return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
59*ac8da31aSHiroshi Yamauchi }
60*ac8da31aSHiroshi Yamauchi 
6175f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for
6275f72f6bSHiroshi Yamauchi /// MachineFunction.
6375f72f6bSHiroshi Yamauchi bool isFunctionColdInCallGraph(
6475f72f6bSHiroshi Yamauchi     const MachineFunction *MF,
6575f72f6bSHiroshi Yamauchi     ProfileSummaryInfo *PSI,
6675f72f6bSHiroshi Yamauchi     const MachineBlockFrequencyInfo &MBFI) {
6775f72f6bSHiroshi Yamauchi   if (auto FunctionCount = MF->getFunction().getEntryCount())
6875f72f6bSHiroshi Yamauchi     if (!PSI->isColdCount(FunctionCount.getCount()))
6975f72f6bSHiroshi Yamauchi       return false;
7075f72f6bSHiroshi Yamauchi   for (const auto &MBB : *MF)
7175f72f6bSHiroshi Yamauchi     if (!isColdBlock(&MBB, PSI, &MBFI))
7275f72f6bSHiroshi Yamauchi       return false;
7375f72f6bSHiroshi Yamauchi   return true;
7475f72f6bSHiroshi Yamauchi }
7575f72f6bSHiroshi Yamauchi 
7675f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for
7775f72f6bSHiroshi Yamauchi /// MachineFunction.
7875f72f6bSHiroshi Yamauchi bool isFunctionHotInCallGraphNthPercentile(
7975f72f6bSHiroshi Yamauchi     int PercentileCutoff,
8075f72f6bSHiroshi Yamauchi     const MachineFunction *MF,
8175f72f6bSHiroshi Yamauchi     ProfileSummaryInfo *PSI,
8275f72f6bSHiroshi Yamauchi     const MachineBlockFrequencyInfo &MBFI) {
8375f72f6bSHiroshi Yamauchi   if (auto FunctionCount = MF->getFunction().getEntryCount())
8475f72f6bSHiroshi Yamauchi     if (PSI->isHotCountNthPercentile(PercentileCutoff,
8575f72f6bSHiroshi Yamauchi                                      FunctionCount.getCount()))
8675f72f6bSHiroshi Yamauchi       return true;
8775f72f6bSHiroshi Yamauchi   for (const auto &MBB : *MF)
8875f72f6bSHiroshi Yamauchi     if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
8975f72f6bSHiroshi Yamauchi       return true;
9075f72f6bSHiroshi Yamauchi   return false;
9175f72f6bSHiroshi Yamauchi }
9275f72f6bSHiroshi Yamauchi } // namespace machine_size_opts_detail
9375f72f6bSHiroshi Yamauchi 
9475f72f6bSHiroshi Yamauchi namespace {
9575f72f6bSHiroshi Yamauchi struct MachineBasicBlockBFIAdapter {
9675f72f6bSHiroshi Yamauchi   static bool isFunctionColdInCallGraph(const MachineFunction *MF,
9775f72f6bSHiroshi Yamauchi                                         ProfileSummaryInfo *PSI,
9875f72f6bSHiroshi Yamauchi                                         const MachineBlockFrequencyInfo &MBFI) {
9975f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI);
10075f72f6bSHiroshi Yamauchi   }
10175f72f6bSHiroshi Yamauchi   static bool isFunctionHotInCallGraphNthPercentile(
10275f72f6bSHiroshi Yamauchi       int CutOff,
10375f72f6bSHiroshi Yamauchi       const MachineFunction *MF,
10475f72f6bSHiroshi Yamauchi       ProfileSummaryInfo *PSI,
10575f72f6bSHiroshi Yamauchi       const MachineBlockFrequencyInfo &MBFI) {
10675f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile(
10775f72f6bSHiroshi Yamauchi         CutOff, MF, PSI, MBFI);
10875f72f6bSHiroshi Yamauchi   }
10975f72f6bSHiroshi Yamauchi   static bool isColdBlock(const MachineBasicBlock *MBB,
11075f72f6bSHiroshi Yamauchi                           ProfileSummaryInfo *PSI,
11175f72f6bSHiroshi Yamauchi                           const MachineBlockFrequencyInfo *MBFI) {
11275f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI);
11375f72f6bSHiroshi Yamauchi   }
114*ac8da31aSHiroshi Yamauchi   static bool isColdBlock(BlockFrequency BlockFreq,
115*ac8da31aSHiroshi Yamauchi                           ProfileSummaryInfo *PSI,
116*ac8da31aSHiroshi Yamauchi                           const MachineBlockFrequencyInfo *MBFI) {
117*ac8da31aSHiroshi Yamauchi     return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI);
118*ac8da31aSHiroshi Yamauchi   }
11975f72f6bSHiroshi Yamauchi   static bool isHotBlockNthPercentile(int CutOff,
12075f72f6bSHiroshi Yamauchi                                       const MachineBasicBlock *MBB,
12175f72f6bSHiroshi Yamauchi                                       ProfileSummaryInfo *PSI,
12275f72f6bSHiroshi Yamauchi                                       const MachineBlockFrequencyInfo *MBFI) {
12375f72f6bSHiroshi Yamauchi     return machine_size_opts_detail::isHotBlockNthPercentile(
12475f72f6bSHiroshi Yamauchi         CutOff, MBB, PSI, MBFI);
12575f72f6bSHiroshi Yamauchi   }
126*ac8da31aSHiroshi Yamauchi   static bool isHotBlockNthPercentile(int CutOff,
127*ac8da31aSHiroshi Yamauchi                                       BlockFrequency BlockFreq,
128*ac8da31aSHiroshi Yamauchi                                       ProfileSummaryInfo *PSI,
129*ac8da31aSHiroshi Yamauchi                                       const MachineBlockFrequencyInfo *MBFI) {
130*ac8da31aSHiroshi Yamauchi     return machine_size_opts_detail::isHotBlockNthPercentile(
131*ac8da31aSHiroshi Yamauchi         CutOff, BlockFreq, PSI, MBFI);
132*ac8da31aSHiroshi Yamauchi   }
13375f72f6bSHiroshi Yamauchi };
13475f72f6bSHiroshi Yamauchi } // end anonymous namespace
13575f72f6bSHiroshi Yamauchi 
13675f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineFunction *MF,
13775f72f6bSHiroshi Yamauchi                                  ProfileSummaryInfo *PSI,
1388cdfdfeeSHiroshi Yamauchi                                  const MachineBlockFrequencyInfo *MBFI,
1398cdfdfeeSHiroshi Yamauchi                                  PGSOQueryType QueryType) {
14075f72f6bSHiroshi Yamauchi   return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
1418cdfdfeeSHiroshi Yamauchi       MF, PSI, MBFI, QueryType);
14275f72f6bSHiroshi Yamauchi }
14375f72f6bSHiroshi Yamauchi 
14475f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
14575f72f6bSHiroshi Yamauchi                                  ProfileSummaryInfo *PSI,
1468cdfdfeeSHiroshi Yamauchi                                  const MachineBlockFrequencyInfo *MBFI,
1478cdfdfeeSHiroshi Yamauchi                                  PGSOQueryType QueryType) {
148*ac8da31aSHiroshi Yamauchi   assert(MBB);
14975f72f6bSHiroshi Yamauchi   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
1508cdfdfeeSHiroshi Yamauchi       MBB, PSI, MBFI, QueryType);
15175f72f6bSHiroshi Yamauchi }
152*ac8da31aSHiroshi Yamauchi 
153*ac8da31aSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
154*ac8da31aSHiroshi Yamauchi                                  ProfileSummaryInfo *PSI,
155*ac8da31aSHiroshi Yamauchi                                  MBFIWrapper *MBFIW,
156*ac8da31aSHiroshi Yamauchi                                  PGSOQueryType QueryType) {
157*ac8da31aSHiroshi Yamauchi   assert(MBB);
158*ac8da31aSHiroshi Yamauchi   if (!PSI || !MBFIW)
159*ac8da31aSHiroshi Yamauchi     return false;
160*ac8da31aSHiroshi Yamauchi   BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB);
161*ac8da31aSHiroshi Yamauchi   return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
162*ac8da31aSHiroshi Yamauchi       BlockFreq, PSI, &MBFIW->getMBFI(), QueryType);
163*ac8da31aSHiroshi Yamauchi }
164