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