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 27*564a9de2SBenjamin 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 6275f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for 6375f72f6bSHiroshi Yamauchi /// MachineFunction. 6475f72f6bSHiroshi Yamauchi bool isFunctionColdInCallGraph( 6575f72f6bSHiroshi Yamauchi const MachineFunction *MF, 6675f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 6775f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 6875f72f6bSHiroshi Yamauchi if (auto FunctionCount = MF->getFunction().getEntryCount()) 6975f72f6bSHiroshi Yamauchi if (!PSI->isColdCount(FunctionCount.getCount())) 7075f72f6bSHiroshi Yamauchi return false; 7175f72f6bSHiroshi Yamauchi for (const auto &MBB : *MF) 7275f72f6bSHiroshi Yamauchi if (!isColdBlock(&MBB, PSI, &MBFI)) 7375f72f6bSHiroshi Yamauchi return false; 7475f72f6bSHiroshi Yamauchi return true; 7575f72f6bSHiroshi Yamauchi } 7675f72f6bSHiroshi Yamauchi 7775f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for 7875f72f6bSHiroshi Yamauchi /// MachineFunction. 7975f72f6bSHiroshi Yamauchi bool isFunctionHotInCallGraphNthPercentile( 8075f72f6bSHiroshi Yamauchi int PercentileCutoff, 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->isHotCountNthPercentile(PercentileCutoff, 8675f72f6bSHiroshi Yamauchi FunctionCount.getCount())) 8775f72f6bSHiroshi Yamauchi return true; 8875f72f6bSHiroshi Yamauchi for (const auto &MBB : *MF) 8975f72f6bSHiroshi Yamauchi if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 9075f72f6bSHiroshi Yamauchi return true; 9175f72f6bSHiroshi Yamauchi return false; 9275f72f6bSHiroshi Yamauchi } 9375f72f6bSHiroshi Yamauchi } // namespace machine_size_opts_detail 9475f72f6bSHiroshi Yamauchi 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 } 114ac8da31aSHiroshi Yamauchi static bool isColdBlock(BlockFrequency BlockFreq, 115ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 116ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 117ac8da31aSHiroshi Yamauchi return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI); 118ac8da31aSHiroshi 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 } 126ac8da31aSHiroshi Yamauchi static bool isHotBlockNthPercentile(int CutOff, 127ac8da31aSHiroshi Yamauchi BlockFrequency BlockFreq, 128ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 129ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 130ac8da31aSHiroshi Yamauchi return machine_size_opts_detail::isHotBlockNthPercentile( 131ac8da31aSHiroshi Yamauchi CutOff, BlockFreq, PSI, MBFI); 132ac8da31aSHiroshi 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) { 148ac8da31aSHiroshi Yamauchi assert(MBB); 14975f72f6bSHiroshi Yamauchi return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 1508cdfdfeeSHiroshi Yamauchi MBB, PSI, MBFI, QueryType); 15175f72f6bSHiroshi Yamauchi } 152ac8da31aSHiroshi Yamauchi 153ac8da31aSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 154ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 155ac8da31aSHiroshi Yamauchi MBFIWrapper *MBFIW, 156ac8da31aSHiroshi Yamauchi PGSOQueryType QueryType) { 157ac8da31aSHiroshi Yamauchi assert(MBB); 158ac8da31aSHiroshi Yamauchi if (!PSI || !MBFIW) 159ac8da31aSHiroshi Yamauchi return false; 160ac8da31aSHiroshi Yamauchi BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB); 161ac8da31aSHiroshi Yamauchi return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 162ac8da31aSHiroshi Yamauchi BlockFreq, PSI, &MBFIW->getMBFI(), QueryType); 163ac8da31aSHiroshi Yamauchi } 164