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" 1575f72f6bSHiroshi Yamauchi #include "llvm/Analysis/ProfileSummaryInfo.h" 16*5dd566b7SSimon Pilgrim #include "llvm/CodeGen/MBFIWrapper.h" 1775f72f6bSHiroshi Yamauchi #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 18*5dd566b7SSimon Pilgrim #include "llvm/IR/Function.h" 1975f72f6bSHiroshi Yamauchi 2075f72f6bSHiroshi Yamauchi using namespace llvm; 2175f72f6bSHiroshi Yamauchi 2275f72f6bSHiroshi Yamauchi extern cl::opt<bool> EnablePGSO; 2375f72f6bSHiroshi Yamauchi extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly; 2475f72f6bSHiroshi Yamauchi extern cl::opt<bool> ForcePGSO; 2575f72f6bSHiroshi Yamauchi extern cl::opt<int> PgsoCutoffInstrProf; 2675f72f6bSHiroshi Yamauchi extern cl::opt<int> PgsoCutoffSampleProf; 2775f72f6bSHiroshi Yamauchi 28564a9de2SBenjamin Kramer namespace { 2975f72f6bSHiroshi Yamauchi namespace machine_size_opts_detail { 3075f72f6bSHiroshi Yamauchi 3175f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock. 3275f72f6bSHiroshi Yamauchi bool isColdBlock(const MachineBasicBlock *MBB, 3375f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 3475f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 3575f72f6bSHiroshi Yamauchi auto Count = MBFI->getBlockProfileCount(MBB); 3675f72f6bSHiroshi Yamauchi return Count && PSI->isColdCount(*Count); 3775f72f6bSHiroshi Yamauchi } 3875f72f6bSHiroshi Yamauchi 39ac8da31aSHiroshi Yamauchi bool isColdBlock(BlockFrequency BlockFreq, 40ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 41ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 42ac8da31aSHiroshi Yamauchi auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 43ac8da31aSHiroshi Yamauchi return Count && PSI->isColdCount(*Count); 44ac8da31aSHiroshi Yamauchi } 45ac8da31aSHiroshi Yamauchi 4675f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock. 4775f72f6bSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff, 4875f72f6bSHiroshi Yamauchi const MachineBasicBlock *MBB, 4975f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 5075f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 5175f72f6bSHiroshi Yamauchi auto Count = MBFI->getBlockProfileCount(MBB); 5275f72f6bSHiroshi Yamauchi return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 5375f72f6bSHiroshi Yamauchi } 5475f72f6bSHiroshi Yamauchi 55ac8da31aSHiroshi Yamauchi static bool isHotBlockNthPercentile(int PercentileCutoff, 56ac8da31aSHiroshi Yamauchi BlockFrequency BlockFreq, 57ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 58ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 59ac8da31aSHiroshi Yamauchi auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 60ac8da31aSHiroshi Yamauchi return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 61ac8da31aSHiroshi Yamauchi } 62ac8da31aSHiroshi Yamauchi 6376b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int PercentileCutoff, 6476b9901fSHiroshi Yamauchi const MachineBasicBlock *MBB, 6576b9901fSHiroshi Yamauchi ProfileSummaryInfo *PSI, 6676b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 6776b9901fSHiroshi Yamauchi auto Count = MBFI->getBlockProfileCount(MBB); 6876b9901fSHiroshi Yamauchi return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); 6976b9901fSHiroshi Yamauchi } 7076b9901fSHiroshi Yamauchi 7176b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int PercentileCutoff, 7276b9901fSHiroshi Yamauchi BlockFrequency BlockFreq, 7376b9901fSHiroshi Yamauchi ProfileSummaryInfo *PSI, 7476b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 7576b9901fSHiroshi Yamauchi auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 7676b9901fSHiroshi Yamauchi return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); 7776b9901fSHiroshi Yamauchi } 7876b9901fSHiroshi Yamauchi 7975f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for 8075f72f6bSHiroshi Yamauchi /// MachineFunction. 8175f72f6bSHiroshi Yamauchi bool isFunctionColdInCallGraph( 8275f72f6bSHiroshi Yamauchi const MachineFunction *MF, 8375f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 8475f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 8575f72f6bSHiroshi Yamauchi if (auto FunctionCount = MF->getFunction().getEntryCount()) 8675f72f6bSHiroshi Yamauchi if (!PSI->isColdCount(FunctionCount.getCount())) 8775f72f6bSHiroshi Yamauchi return false; 8875f72f6bSHiroshi Yamauchi for (const auto &MBB : *MF) 8975f72f6bSHiroshi Yamauchi if (!isColdBlock(&MBB, PSI, &MBFI)) 9075f72f6bSHiroshi Yamauchi return false; 9175f72f6bSHiroshi Yamauchi return true; 9275f72f6bSHiroshi Yamauchi } 9375f72f6bSHiroshi Yamauchi 9475f72f6bSHiroshi Yamauchi /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for 9575f72f6bSHiroshi Yamauchi /// MachineFunction. 9675f72f6bSHiroshi Yamauchi bool isFunctionHotInCallGraphNthPercentile( 9775f72f6bSHiroshi Yamauchi int PercentileCutoff, 9875f72f6bSHiroshi Yamauchi const MachineFunction *MF, 9975f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 10075f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 10175f72f6bSHiroshi Yamauchi if (auto FunctionCount = MF->getFunction().getEntryCount()) 10275f72f6bSHiroshi Yamauchi if (PSI->isHotCountNthPercentile(PercentileCutoff, 10375f72f6bSHiroshi Yamauchi FunctionCount.getCount())) 10475f72f6bSHiroshi Yamauchi return true; 10575f72f6bSHiroshi Yamauchi for (const auto &MBB : *MF) 10675f72f6bSHiroshi Yamauchi if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 10775f72f6bSHiroshi Yamauchi return true; 10875f72f6bSHiroshi Yamauchi return false; 10975f72f6bSHiroshi Yamauchi } 11076b9901fSHiroshi Yamauchi 11176b9901fSHiroshi Yamauchi bool isFunctionColdInCallGraphNthPercentile( 11276b9901fSHiroshi Yamauchi int PercentileCutoff, const MachineFunction *MF, ProfileSummaryInfo *PSI, 11376b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 11476b9901fSHiroshi Yamauchi if (auto FunctionCount = MF->getFunction().getEntryCount()) 11576b9901fSHiroshi Yamauchi if (!PSI->isColdCountNthPercentile(PercentileCutoff, 11676b9901fSHiroshi Yamauchi FunctionCount.getCount())) 11776b9901fSHiroshi Yamauchi return false; 11876b9901fSHiroshi Yamauchi for (const auto &MBB : *MF) 11976b9901fSHiroshi Yamauchi if (!isColdBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 12076b9901fSHiroshi Yamauchi return false; 12176b9901fSHiroshi Yamauchi return true; 12276b9901fSHiroshi Yamauchi } 12375f72f6bSHiroshi Yamauchi } // namespace machine_size_opts_detail 12475f72f6bSHiroshi Yamauchi 12575f72f6bSHiroshi Yamauchi struct MachineBasicBlockBFIAdapter { 12675f72f6bSHiroshi Yamauchi static bool isFunctionColdInCallGraph(const MachineFunction *MF, 12775f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 12875f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 12975f72f6bSHiroshi Yamauchi return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI); 13075f72f6bSHiroshi Yamauchi } 13175f72f6bSHiroshi Yamauchi static bool isFunctionHotInCallGraphNthPercentile( 13275f72f6bSHiroshi Yamauchi int CutOff, 13375f72f6bSHiroshi Yamauchi const MachineFunction *MF, 13475f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 13575f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 13675f72f6bSHiroshi Yamauchi return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile( 13775f72f6bSHiroshi Yamauchi CutOff, MF, PSI, MBFI); 13875f72f6bSHiroshi Yamauchi } 13976b9901fSHiroshi Yamauchi static bool isFunctionColdInCallGraphNthPercentile( 14076b9901fSHiroshi Yamauchi int CutOff, const MachineFunction *MF, ProfileSummaryInfo *PSI, 14176b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo &MBFI) { 14276b9901fSHiroshi Yamauchi return machine_size_opts_detail::isFunctionColdInCallGraphNthPercentile( 14376b9901fSHiroshi Yamauchi CutOff, MF, PSI, MBFI); 14476b9901fSHiroshi Yamauchi } 14575f72f6bSHiroshi Yamauchi static bool isColdBlock(const MachineBasicBlock *MBB, 14675f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 14775f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 14875f72f6bSHiroshi Yamauchi return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI); 14975f72f6bSHiroshi Yamauchi } 150ac8da31aSHiroshi Yamauchi static bool isColdBlock(BlockFrequency BlockFreq, 151ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 152ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 153ac8da31aSHiroshi Yamauchi return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI); 154ac8da31aSHiroshi Yamauchi } 15575f72f6bSHiroshi Yamauchi static bool isHotBlockNthPercentile(int CutOff, 15675f72f6bSHiroshi Yamauchi const MachineBasicBlock *MBB, 15775f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 15875f72f6bSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 15975f72f6bSHiroshi Yamauchi return machine_size_opts_detail::isHotBlockNthPercentile( 16075f72f6bSHiroshi Yamauchi CutOff, MBB, PSI, MBFI); 16175f72f6bSHiroshi Yamauchi } 162ac8da31aSHiroshi Yamauchi static bool isHotBlockNthPercentile(int CutOff, 163ac8da31aSHiroshi Yamauchi BlockFrequency BlockFreq, 164ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 165ac8da31aSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 166ac8da31aSHiroshi Yamauchi return machine_size_opts_detail::isHotBlockNthPercentile( 167ac8da31aSHiroshi Yamauchi CutOff, BlockFreq, PSI, MBFI); 168ac8da31aSHiroshi Yamauchi } 16976b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int CutOff, const MachineBasicBlock *MBB, 17076b9901fSHiroshi Yamauchi ProfileSummaryInfo *PSI, 17176b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 17276b9901fSHiroshi Yamauchi return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, MBB, PSI, 17376b9901fSHiroshi Yamauchi MBFI); 17476b9901fSHiroshi Yamauchi } 17576b9901fSHiroshi Yamauchi static bool isColdBlockNthPercentile(int CutOff, BlockFrequency BlockFreq, 17676b9901fSHiroshi Yamauchi ProfileSummaryInfo *PSI, 17776b9901fSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI) { 17876b9901fSHiroshi Yamauchi return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, BlockFreq, 17976b9901fSHiroshi Yamauchi PSI, MBFI); 18076b9901fSHiroshi Yamauchi } 18175f72f6bSHiroshi Yamauchi }; 18275f72f6bSHiroshi Yamauchi } // end anonymous namespace 18375f72f6bSHiroshi Yamauchi 18475f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineFunction *MF, 18575f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 1868cdfdfeeSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI, 1878cdfdfeeSHiroshi Yamauchi PGSOQueryType QueryType) { 18875f72f6bSHiroshi Yamauchi return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 1898cdfdfeeSHiroshi Yamauchi MF, PSI, MBFI, QueryType); 19075f72f6bSHiroshi Yamauchi } 19175f72f6bSHiroshi Yamauchi 19275f72f6bSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 19375f72f6bSHiroshi Yamauchi ProfileSummaryInfo *PSI, 1948cdfdfeeSHiroshi Yamauchi const MachineBlockFrequencyInfo *MBFI, 1958cdfdfeeSHiroshi Yamauchi PGSOQueryType QueryType) { 196ac8da31aSHiroshi Yamauchi assert(MBB); 19775f72f6bSHiroshi Yamauchi return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 1988cdfdfeeSHiroshi Yamauchi MBB, PSI, MBFI, QueryType); 19975f72f6bSHiroshi Yamauchi } 200ac8da31aSHiroshi Yamauchi 201ac8da31aSHiroshi Yamauchi bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 202ac8da31aSHiroshi Yamauchi ProfileSummaryInfo *PSI, 203ac8da31aSHiroshi Yamauchi MBFIWrapper *MBFIW, 204ac8da31aSHiroshi Yamauchi PGSOQueryType QueryType) { 205ac8da31aSHiroshi Yamauchi assert(MBB); 206ac8da31aSHiroshi Yamauchi if (!PSI || !MBFIW) 207ac8da31aSHiroshi Yamauchi return false; 208ac8da31aSHiroshi Yamauchi BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB); 209ac8da31aSHiroshi Yamauchi return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 210ac8da31aSHiroshi Yamauchi BlockFreq, PSI, &MBFIW->getMBFI(), QueryType); 211ac8da31aSHiroshi Yamauchi } 212