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