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" 15ac8da31aSHiroshi 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 27564a9de2SBenjamin Kramer namespace { 2875f72f6bSHiroshi Yamauchi namespace machine_size_opts_detail { 2975f72f6bSHiroshi Yamauchi 3075f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock. 3175f72f6bSHiroshi Yamauchi bool isColdBlock(const MachineBasicBlock *MBB, 3275f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 3375f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 3475f72f6bSHiroshi Yamauchi auto Count = MBFI->getBlockProfileCount(MBB); 3575f72f6bSHiroshi Yamauchi return Count && PSI->isColdCount(*Count); 3675f72f6bSHiroshi Yamauchi } 3775f72f6bSHiroshi Yamauchi 38ac8da31aSHiroshi Yamauchi bool isColdBlock(BlockFrequency BlockFreq, 39ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 40ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 41ac8da31aSHiroshi Yamauchi auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 42ac8da31aSHiroshi Yamauchi return Count && PSI->isColdCount(*Count); 43ac8da31aSHiroshi Yamauchi } 44ac8da31aSHiroshi Yamauchi 4575f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock. 4675f72f6bSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff, 4775f72f6bSHiroshi Yamauchi const MachineBasicBlock *MBB, 4875f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 4975f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 5075f72f6bSHiroshi Yamauchi auto Count = MBFI->getBlockProfileCount(MBB); 5175f72f6bSHiroshi Yamauchi return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 5275f72f6bSHiroshi Yamauchi } 5375f72f6bSHiroshi Yamauchi 54ac8da31aSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff, 55ac8da31aSHiroshi Yamauchi BlockFrequency BlockFreq, 56ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 57ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 58ac8da31aSHiroshi Yamauchi auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 59ac8da31aSHiroshi Yamauchi return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 60ac8da31aSHiroshi Yamauchi } 61ac8da31aSHiroshi Yamauchi 62*76b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int PercentileCutoff, 63*76b9901fSHiroshi Yamauchi const MachineBasicBlock *MBB, 64*76b9901fSHiroshi Yamauchi ProfileSummaryInfo *PSI, 65*76b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 66*76b9901fSHiroshi Yamauchi auto Count = MBFI->getBlockProfileCount(MBB); 67*76b9901fSHiroshi Yamauchi return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); 68*76b9901fSHiroshi Yamauchi } 69*76b9901fSHiroshi Yamauchi 70*76b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int PercentileCutoff, 71*76b9901fSHiroshi Yamauchi BlockFrequency BlockFreq, 72*76b9901fSHiroshi Yamauchi ProfileSummaryInfo *PSI, 73*76b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 74*76b9901fSHiroshi Yamauchi auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 75*76b9901fSHiroshi Yamauchi return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); 76*76b9901fSHiroshi Yamauchi } 77*76b9901fSHiroshi Yamauchi 7875f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for 7975f72f6bSHiroshi Yamauchi /// MachineFunction. 8075f72f6bSHiroshi Yamauchi bool isFunctionColdInCallGraph( 8175f72f6bSHiroshi Yamauchi const MachineFunction *MF, 8275f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 8375f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 8475f72f6bSHiroshi Yamauchi if (auto FunctionCount = MF->getFunction().getEntryCount()) 8575f72f6bSHiroshi Yamauchi if (!PSI->isColdCount(FunctionCount.getCount())) 8675f72f6bSHiroshi Yamauchi return false; 8775f72f6bSHiroshi Yamauchi for (const auto &MBB : *MF) 8875f72f6bSHiroshi Yamauchi if (!isColdBlock(&MBB, PSI, &MBFI)) 8975f72f6bSHiroshi Yamauchi return false; 9075f72f6bSHiroshi Yamauchi return true; 9175f72f6bSHiroshi Yamauchi } 9275f72f6bSHiroshi Yamauchi 9375f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for 9475f72f6bSHiroshi Yamauchi /// MachineFunction. 9575f72f6bSHiroshi Yamauchi bool isFunctionHotInCallGraphNthPercentile( 9675f72f6bSHiroshi Yamauchi int PercentileCutoff, 9775f72f6bSHiroshi Yamauchi const MachineFunction *MF, 9875f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 9975f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 10075f72f6bSHiroshi Yamauchi if (auto FunctionCount = MF->getFunction().getEntryCount()) 10175f72f6bSHiroshi Yamauchi if (PSI->isHotCountNthPercentile(PercentileCutoff, 10275f72f6bSHiroshi Yamauchi FunctionCount.getCount())) 10375f72f6bSHiroshi Yamauchi return true; 10475f72f6bSHiroshi Yamauchi for (const auto &MBB : *MF) 10575f72f6bSHiroshi Yamauchi if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 10675f72f6bSHiroshi Yamauchi return true; 10775f72f6bSHiroshi Yamauchi return false; 10875f72f6bSHiroshi Yamauchi } 109*76b9901fSHiroshi Yamauchi 110*76b9901fSHiroshi Yamauchi bool isFunctionColdInCallGraphNthPercentile( 111*76b9901fSHiroshi Yamauchi int PercentileCutoff, const MachineFunction *MF, ProfileSummaryInfo *PSI, 112*76b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 113*76b9901fSHiroshi Yamauchi if (auto FunctionCount = MF->getFunction().getEntryCount()) 114*76b9901fSHiroshi Yamauchi if (!PSI->isColdCountNthPercentile(PercentileCutoff, 115*76b9901fSHiroshi Yamauchi FunctionCount.getCount())) 116*76b9901fSHiroshi Yamauchi return false; 117*76b9901fSHiroshi Yamauchi for (const auto &MBB : *MF) 118*76b9901fSHiroshi Yamauchi if (!isColdBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 119*76b9901fSHiroshi Yamauchi return false; 120*76b9901fSHiroshi Yamauchi return true; 121*76b9901fSHiroshi Yamauchi } 12275f72f6bSHiroshi Yamauchi } // namespace machine_size_opts_detail 12375f72f6bSHiroshi Yamauchi 12475f72f6bSHiroshi Yamauchi struct MachineBasicBlockBFIAdapter { 12575f72f6bSHiroshi Yamauchi static bool isFunctionColdInCallGraph(const MachineFunction *MF, 12675f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 12775f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 12875f72f6bSHiroshi Yamauchi return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI); 12975f72f6bSHiroshi Yamauchi } 13075f72f6bSHiroshi Yamauchi static bool isFunctionHotInCallGraphNthPercentile( 13175f72f6bSHiroshi Yamauchi int CutOff, 13275f72f6bSHiroshi Yamauchi const MachineFunction *MF, 13375f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 13475f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 13575f72f6bSHiroshi Yamauchi return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile( 13675f72f6bSHiroshi Yamauchi CutOff, MF, PSI, MBFI); 13775f72f6bSHiroshi Yamauchi } 138*76b9901fSHiroshi Yamauchi static bool isFunctionColdInCallGraphNthPercentile( 139*76b9901fSHiroshi Yamauchi int CutOff, const MachineFunction *MF, ProfileSummaryInfo *PSI, 140*76b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 141*76b9901fSHiroshi Yamauchi return machine_size_opts_detail::isFunctionColdInCallGraphNthPercentile( 142*76b9901fSHiroshi Yamauchi CutOff, MF, PSI, MBFI); 143*76b9901fSHiroshi Yamauchi } 14475f72f6bSHiroshi Yamauchi static bool isColdBlock(const MachineBasicBlock *MBB, 14575f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 14675f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 14775f72f6bSHiroshi Yamauchi return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI); 14875f72f6bSHiroshi Yamauchi } 149ac8da31aSHiroshi Yamauchi static bool isColdBlock(BlockFrequency BlockFreq, 150ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 151ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 152ac8da31aSHiroshi Yamauchi return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI); 153ac8da31aSHiroshi Yamauchi } 15475f72f6bSHiroshi Yamauchi static bool isHotBlockNthPercentile(int CutOff, 15575f72f6bSHiroshi Yamauchi const MachineBasicBlock *MBB, 15675f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 15775f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 15875f72f6bSHiroshi Yamauchi return machine_size_opts_detail::isHotBlockNthPercentile( 15975f72f6bSHiroshi Yamauchi CutOff, MBB, PSI, MBFI); 16075f72f6bSHiroshi Yamauchi } 161ac8da31aSHiroshi Yamauchi static bool isHotBlockNthPercentile(int CutOff, 162ac8da31aSHiroshi Yamauchi BlockFrequency BlockFreq, 163ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 164ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 165ac8da31aSHiroshi Yamauchi return machine_size_opts_detail::isHotBlockNthPercentile( 166ac8da31aSHiroshi Yamauchi CutOff, BlockFreq, PSI, MBFI); 167ac8da31aSHiroshi Yamauchi } 168*76b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int CutOff, const MachineBasicBlock *MBB, 169*76b9901fSHiroshi Yamauchi ProfileSummaryInfo *PSI, 170*76b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 171*76b9901fSHiroshi Yamauchi return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, MBB, PSI, 172*76b9901fSHiroshi Yamauchi MBFI); 173*76b9901fSHiroshi Yamauchi } 174*76b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int CutOff, BlockFrequency BlockFreq, 175*76b9901fSHiroshi Yamauchi ProfileSummaryInfo *PSI, 176*76b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 177*76b9901fSHiroshi Yamauchi return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, BlockFreq, 178*76b9901fSHiroshi Yamauchi PSI, MBFI); 179*76b9901fSHiroshi Yamauchi } 18075f72f6bSHiroshi Yamauchi }; 18175f72f6bSHiroshi Yamauchi } // end anonymous namespace 18275f72f6bSHiroshi Yamauchi 18375f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineFunction *MF, 18475f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 1858cdfdfeeSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI, 1868cdfdfeeSHiroshi Yamauchi PGSOQueryType QueryType) { 18775f72f6bSHiroshi Yamauchi return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 1888cdfdfeeSHiroshi Yamauchi MF, PSI, MBFI, QueryType); 18975f72f6bSHiroshi Yamauchi } 19075f72f6bSHiroshi Yamauchi 19175f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 19275f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 1938cdfdfeeSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI, 1948cdfdfeeSHiroshi Yamauchi PGSOQueryType QueryType) { 195ac8da31aSHiroshi Yamauchi assert(MBB); 19675f72f6bSHiroshi Yamauchi return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 1978cdfdfeeSHiroshi Yamauchi MBB, PSI, MBFI, QueryType); 19875f72f6bSHiroshi Yamauchi } 199ac8da31aSHiroshi Yamauchi 200ac8da31aSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 201ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 202ac8da31aSHiroshi Yamauchi MBFIWrapper *MBFIW, 203ac8da31aSHiroshi Yamauchi PGSOQueryType QueryType) { 204ac8da31aSHiroshi Yamauchi assert(MBB); 205ac8da31aSHiroshi Yamauchi if (!PSI || !MBFIW) 206ac8da31aSHiroshi Yamauchi return false; 207ac8da31aSHiroshi Yamauchi BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB); 208ac8da31aSHiroshi Yamauchi return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 209ac8da31aSHiroshi Yamauchi BlockFreq, PSI, &MBFIW->getMBFI(), QueryType); 210ac8da31aSHiroshi Yamauchi } 211