1480093f4SDimitry Andric //===- MachineSizeOpts.cpp - code size optimization related code ----------===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric // 9480093f4SDimitry Andric // This file contains some shared machine IR code size optimization related 10480093f4SDimitry Andric // code. 11480093f4SDimitry Andric // 12480093f4SDimitry Andric //===----------------------------------------------------------------------===// 13480093f4SDimitry Andric 14480093f4SDimitry Andric #include "llvm/CodeGen/MachineSizeOpts.h" 15*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MBFIWrapper.h" 16480093f4SDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h" 17480093f4SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 18480093f4SDimitry Andric 19480093f4SDimitry Andric using namespace llvm; 20480093f4SDimitry Andric 21480093f4SDimitry Andric extern cl::opt<bool> EnablePGSO; 22480093f4SDimitry Andric extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly; 23480093f4SDimitry Andric extern cl::opt<bool> ForcePGSO; 24480093f4SDimitry Andric extern cl::opt<int> PgsoCutoffInstrProf; 25480093f4SDimitry Andric extern cl::opt<int> PgsoCutoffSampleProf; 26480093f4SDimitry Andric 27*5ffd83dbSDimitry Andric namespace { 28480093f4SDimitry Andric namespace machine_size_opts_detail { 29480093f4SDimitry Andric 30480093f4SDimitry Andric /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock. 31480093f4SDimitry Andric bool isColdBlock(const MachineBasicBlock *MBB, 32480093f4SDimitry Andric ProfileSummaryInfo *PSI, 33480093f4SDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 34480093f4SDimitry Andric auto Count = MBFI->getBlockProfileCount(MBB); 35480093f4SDimitry Andric return Count && PSI->isColdCount(*Count); 36480093f4SDimitry Andric } 37480093f4SDimitry Andric 38*5ffd83dbSDimitry Andric bool isColdBlock(BlockFrequency BlockFreq, 39*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 40*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 41*5ffd83dbSDimitry Andric auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 42*5ffd83dbSDimitry Andric return Count && PSI->isColdCount(*Count); 43*5ffd83dbSDimitry Andric } 44*5ffd83dbSDimitry Andric 45480093f4SDimitry Andric /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock. 46480093f4SDimitry Andric static bool isHotBlockNthPercentile(int PercentileCutoff, 47480093f4SDimitry Andric const MachineBasicBlock *MBB, 48480093f4SDimitry Andric ProfileSummaryInfo *PSI, 49480093f4SDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 50480093f4SDimitry Andric auto Count = MBFI->getBlockProfileCount(MBB); 51480093f4SDimitry Andric return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 52480093f4SDimitry Andric } 53480093f4SDimitry Andric 54*5ffd83dbSDimitry Andric static bool isHotBlockNthPercentile(int PercentileCutoff, 55*5ffd83dbSDimitry Andric BlockFrequency BlockFreq, 56*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 57*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 58*5ffd83dbSDimitry Andric auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 59*5ffd83dbSDimitry Andric return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 60*5ffd83dbSDimitry Andric } 61*5ffd83dbSDimitry Andric 62*5ffd83dbSDimitry Andric static bool isColdBlockNthPercentile(int PercentileCutoff, 63*5ffd83dbSDimitry Andric const MachineBasicBlock *MBB, 64*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 65*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 66*5ffd83dbSDimitry Andric auto Count = MBFI->getBlockProfileCount(MBB); 67*5ffd83dbSDimitry Andric return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); 68*5ffd83dbSDimitry Andric } 69*5ffd83dbSDimitry Andric 70*5ffd83dbSDimitry Andric static bool isColdBlockNthPercentile(int PercentileCutoff, 71*5ffd83dbSDimitry Andric BlockFrequency BlockFreq, 72*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 73*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 74*5ffd83dbSDimitry Andric auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 75*5ffd83dbSDimitry Andric return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); 76*5ffd83dbSDimitry Andric } 77*5ffd83dbSDimitry Andric 78480093f4SDimitry Andric /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for 79480093f4SDimitry Andric /// MachineFunction. 80480093f4SDimitry Andric bool isFunctionColdInCallGraph( 81480093f4SDimitry Andric const MachineFunction *MF, 82480093f4SDimitry Andric ProfileSummaryInfo *PSI, 83480093f4SDimitry Andric const MachineBlockFrequencyInfo &MBFI) { 84480093f4SDimitry Andric if (auto FunctionCount = MF->getFunction().getEntryCount()) 85480093f4SDimitry Andric if (!PSI->isColdCount(FunctionCount.getCount())) 86480093f4SDimitry Andric return false; 87480093f4SDimitry Andric for (const auto &MBB : *MF) 88480093f4SDimitry Andric if (!isColdBlock(&MBB, PSI, &MBFI)) 89480093f4SDimitry Andric return false; 90480093f4SDimitry Andric return true; 91480093f4SDimitry Andric } 92480093f4SDimitry Andric 93480093f4SDimitry Andric /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for 94480093f4SDimitry Andric /// MachineFunction. 95480093f4SDimitry Andric bool isFunctionHotInCallGraphNthPercentile( 96480093f4SDimitry Andric int PercentileCutoff, 97480093f4SDimitry Andric const MachineFunction *MF, 98480093f4SDimitry Andric ProfileSummaryInfo *PSI, 99480093f4SDimitry Andric const MachineBlockFrequencyInfo &MBFI) { 100480093f4SDimitry Andric if (auto FunctionCount = MF->getFunction().getEntryCount()) 101480093f4SDimitry Andric if (PSI->isHotCountNthPercentile(PercentileCutoff, 102480093f4SDimitry Andric FunctionCount.getCount())) 103480093f4SDimitry Andric return true; 104480093f4SDimitry Andric for (const auto &MBB : *MF) 105480093f4SDimitry Andric if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 106480093f4SDimitry Andric return true; 107480093f4SDimitry Andric return false; 108480093f4SDimitry Andric } 109*5ffd83dbSDimitry Andric 110*5ffd83dbSDimitry Andric bool isFunctionColdInCallGraphNthPercentile( 111*5ffd83dbSDimitry Andric int PercentileCutoff, const MachineFunction *MF, ProfileSummaryInfo *PSI, 112*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo &MBFI) { 113*5ffd83dbSDimitry Andric if (auto FunctionCount = MF->getFunction().getEntryCount()) 114*5ffd83dbSDimitry Andric if (!PSI->isColdCountNthPercentile(PercentileCutoff, 115*5ffd83dbSDimitry Andric FunctionCount.getCount())) 116*5ffd83dbSDimitry Andric return false; 117*5ffd83dbSDimitry Andric for (const auto &MBB : *MF) 118*5ffd83dbSDimitry Andric if (!isColdBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 119*5ffd83dbSDimitry Andric return false; 120*5ffd83dbSDimitry Andric return true; 121*5ffd83dbSDimitry Andric } 122480093f4SDimitry Andric } // namespace machine_size_opts_detail 123480093f4SDimitry Andric 124480093f4SDimitry Andric struct MachineBasicBlockBFIAdapter { 125480093f4SDimitry Andric static bool isFunctionColdInCallGraph(const MachineFunction *MF, 126480093f4SDimitry Andric ProfileSummaryInfo *PSI, 127480093f4SDimitry Andric const MachineBlockFrequencyInfo &MBFI) { 128480093f4SDimitry Andric return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI); 129480093f4SDimitry Andric } 130480093f4SDimitry Andric static bool isFunctionHotInCallGraphNthPercentile( 131480093f4SDimitry Andric int CutOff, 132480093f4SDimitry Andric const MachineFunction *MF, 133480093f4SDimitry Andric ProfileSummaryInfo *PSI, 134480093f4SDimitry Andric const MachineBlockFrequencyInfo &MBFI) { 135480093f4SDimitry Andric return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile( 136480093f4SDimitry Andric CutOff, MF, PSI, MBFI); 137480093f4SDimitry Andric } 138*5ffd83dbSDimitry Andric static bool isFunctionColdInCallGraphNthPercentile( 139*5ffd83dbSDimitry Andric int CutOff, const MachineFunction *MF, ProfileSummaryInfo *PSI, 140*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo &MBFI) { 141*5ffd83dbSDimitry Andric return machine_size_opts_detail::isFunctionColdInCallGraphNthPercentile( 142*5ffd83dbSDimitry Andric CutOff, MF, PSI, MBFI); 143*5ffd83dbSDimitry Andric } 144480093f4SDimitry Andric static bool isColdBlock(const MachineBasicBlock *MBB, 145480093f4SDimitry Andric ProfileSummaryInfo *PSI, 146480093f4SDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 147480093f4SDimitry Andric return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI); 148480093f4SDimitry Andric } 149*5ffd83dbSDimitry Andric static bool isColdBlock(BlockFrequency BlockFreq, 150*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 151*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 152*5ffd83dbSDimitry Andric return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI); 153*5ffd83dbSDimitry Andric } 154480093f4SDimitry Andric static bool isHotBlockNthPercentile(int CutOff, 155480093f4SDimitry Andric const MachineBasicBlock *MBB, 156480093f4SDimitry Andric ProfileSummaryInfo *PSI, 157480093f4SDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 158480093f4SDimitry Andric return machine_size_opts_detail::isHotBlockNthPercentile( 159480093f4SDimitry Andric CutOff, MBB, PSI, MBFI); 160480093f4SDimitry Andric } 161*5ffd83dbSDimitry Andric static bool isHotBlockNthPercentile(int CutOff, 162*5ffd83dbSDimitry Andric BlockFrequency BlockFreq, 163*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 164*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 165*5ffd83dbSDimitry Andric return machine_size_opts_detail::isHotBlockNthPercentile( 166*5ffd83dbSDimitry Andric CutOff, BlockFreq, PSI, MBFI); 167*5ffd83dbSDimitry Andric } 168*5ffd83dbSDimitry Andric static bool isColdBlockNthPercentile(int CutOff, const MachineBasicBlock *MBB, 169*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 170*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 171*5ffd83dbSDimitry Andric return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, MBB, PSI, 172*5ffd83dbSDimitry Andric MBFI); 173*5ffd83dbSDimitry Andric } 174*5ffd83dbSDimitry Andric static bool isColdBlockNthPercentile(int CutOff, BlockFrequency BlockFreq, 175*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 176*5ffd83dbSDimitry Andric const MachineBlockFrequencyInfo *MBFI) { 177*5ffd83dbSDimitry Andric return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, BlockFreq, 178*5ffd83dbSDimitry Andric PSI, MBFI); 179*5ffd83dbSDimitry Andric } 180480093f4SDimitry Andric }; 181480093f4SDimitry Andric } // end anonymous namespace 182480093f4SDimitry Andric 183480093f4SDimitry Andric bool llvm::shouldOptimizeForSize(const MachineFunction *MF, 184480093f4SDimitry Andric ProfileSummaryInfo *PSI, 185480093f4SDimitry Andric const MachineBlockFrequencyInfo *MBFI, 186480093f4SDimitry Andric PGSOQueryType QueryType) { 187480093f4SDimitry Andric return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 188480093f4SDimitry Andric MF, PSI, MBFI, QueryType); 189480093f4SDimitry Andric } 190480093f4SDimitry Andric 191480093f4SDimitry Andric bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 192480093f4SDimitry Andric ProfileSummaryInfo *PSI, 193480093f4SDimitry Andric const MachineBlockFrequencyInfo *MBFI, 194480093f4SDimitry Andric PGSOQueryType QueryType) { 195*5ffd83dbSDimitry Andric assert(MBB); 196480093f4SDimitry Andric return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 197480093f4SDimitry Andric MBB, PSI, MBFI, QueryType); 198480093f4SDimitry Andric } 199*5ffd83dbSDimitry Andric 200*5ffd83dbSDimitry Andric bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 201*5ffd83dbSDimitry Andric ProfileSummaryInfo *PSI, 202*5ffd83dbSDimitry Andric MBFIWrapper *MBFIW, 203*5ffd83dbSDimitry Andric PGSOQueryType QueryType) { 204*5ffd83dbSDimitry Andric assert(MBB); 205*5ffd83dbSDimitry Andric if (!PSI || !MBFIW) 206*5ffd83dbSDimitry Andric return false; 207*5ffd83dbSDimitry Andric BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB); 208*5ffd83dbSDimitry Andric return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 209*5ffd83dbSDimitry Andric BlockFreq, PSI, &MBFIW->getMBFI(), QueryType); 210*5ffd83dbSDimitry Andric } 211