| //===- MachineSizeOpts.cpp - code size optimization related code ----------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains some shared machine IR code size optimization related |
| // code. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/CodeGen/MachineSizeOpts.h" |
| #include "llvm/CodeGen/MBFIWrapper.h" |
| #include "llvm/Analysis/ProfileSummaryInfo.h" |
| #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" |
| |
| using namespace llvm; |
| |
| extern cl::opt<bool> EnablePGSO; |
| extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly; |
| extern cl::opt<bool> ForcePGSO; |
| extern cl::opt<int> PgsoCutoffInstrProf; |
| extern cl::opt<int> PgsoCutoffSampleProf; |
| |
| namespace { |
| namespace machine_size_opts_detail { |
| |
| /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock. |
| bool isColdBlock(const MachineBasicBlock *MBB, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| auto Count = MBFI->getBlockProfileCount(MBB); |
| return Count && PSI->isColdCount(*Count); |
| } |
| |
| bool isColdBlock(BlockFrequency BlockFreq, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); |
| return Count && PSI->isColdCount(*Count); |
| } |
| |
| /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock. |
| static bool isHotBlockNthPercentile(int PercentileCutoff, |
| const MachineBasicBlock *MBB, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| auto Count = MBFI->getBlockProfileCount(MBB); |
| return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); |
| } |
| |
| static bool isHotBlockNthPercentile(int PercentileCutoff, |
| BlockFrequency BlockFreq, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); |
| return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); |
| } |
| |
| static bool isColdBlockNthPercentile(int PercentileCutoff, |
| const MachineBasicBlock *MBB, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| auto Count = MBFI->getBlockProfileCount(MBB); |
| return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); |
| } |
| |
| static bool isColdBlockNthPercentile(int PercentileCutoff, |
| BlockFrequency BlockFreq, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); |
| return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); |
| } |
| |
| /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for |
| /// MachineFunction. |
| bool isFunctionColdInCallGraph( |
| const MachineFunction *MF, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo &MBFI) { |
| if (auto FunctionCount = MF->getFunction().getEntryCount()) |
| if (!PSI->isColdCount(FunctionCount->getCount())) |
| return false; |
| for (const auto &MBB : *MF) |
| if (!isColdBlock(&MBB, PSI, &MBFI)) |
| return false; |
| return true; |
| } |
| |
| /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for |
| /// MachineFunction. |
| bool isFunctionHotInCallGraphNthPercentile( |
| int PercentileCutoff, |
| const MachineFunction *MF, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo &MBFI) { |
| if (auto FunctionCount = MF->getFunction().getEntryCount()) |
| if (PSI->isHotCountNthPercentile(PercentileCutoff, |
| FunctionCount->getCount())) |
| return true; |
| for (const auto &MBB : *MF) |
| if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) |
| return true; |
| return false; |
| } |
| |
| bool isFunctionColdInCallGraphNthPercentile( |
| int PercentileCutoff, const MachineFunction *MF, ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo &MBFI) { |
| if (auto FunctionCount = MF->getFunction().getEntryCount()) |
| if (!PSI->isColdCountNthPercentile(PercentileCutoff, |
| FunctionCount->getCount())) |
| return false; |
| for (const auto &MBB : *MF) |
| if (!isColdBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) |
| return false; |
| return true; |
| } |
| } // namespace machine_size_opts_detail |
| |
| struct MachineBasicBlockBFIAdapter { |
| static bool isFunctionColdInCallGraph(const MachineFunction *MF, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo &MBFI) { |
| return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI); |
| } |
| static bool isFunctionHotInCallGraphNthPercentile( |
| int CutOff, |
| const MachineFunction *MF, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo &MBFI) { |
| return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile( |
| CutOff, MF, PSI, MBFI); |
| } |
| static bool isFunctionColdInCallGraphNthPercentile( |
| int CutOff, const MachineFunction *MF, ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo &MBFI) { |
| return machine_size_opts_detail::isFunctionColdInCallGraphNthPercentile( |
| CutOff, MF, PSI, MBFI); |
| } |
| static bool isColdBlock(const MachineBasicBlock *MBB, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI); |
| } |
| static bool isColdBlock(BlockFrequency BlockFreq, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI); |
| } |
| static bool isHotBlockNthPercentile(int CutOff, |
| const MachineBasicBlock *MBB, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| return machine_size_opts_detail::isHotBlockNthPercentile( |
| CutOff, MBB, PSI, MBFI); |
| } |
| static bool isHotBlockNthPercentile(int CutOff, |
| BlockFrequency BlockFreq, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| return machine_size_opts_detail::isHotBlockNthPercentile( |
| CutOff, BlockFreq, PSI, MBFI); |
| } |
| static bool isColdBlockNthPercentile(int CutOff, const MachineBasicBlock *MBB, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, MBB, PSI, |
| MBFI); |
| } |
| static bool isColdBlockNthPercentile(int CutOff, BlockFrequency BlockFreq, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI) { |
| return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, BlockFreq, |
| PSI, MBFI); |
| } |
| }; |
| } // end anonymous namespace |
| |
| bool llvm::shouldOptimizeForSize(const MachineFunction *MF, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI, |
| PGSOQueryType QueryType) { |
| return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( |
| MF, PSI, MBFI, QueryType); |
| } |
| |
| bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, |
| ProfileSummaryInfo *PSI, |
| const MachineBlockFrequencyInfo *MBFI, |
| PGSOQueryType QueryType) { |
| assert(MBB); |
| return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( |
| MBB, PSI, MBFI, QueryType); |
| } |
| |
| bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, |
| ProfileSummaryInfo *PSI, |
| MBFIWrapper *MBFIW, |
| PGSOQueryType QueryType) { |
| assert(MBB); |
| if (!PSI || !MBFIW) |
| return false; |
| BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB); |
| return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( |
| BlockFreq, PSI, &MBFIW->getMBFI(), QueryType); |
| } |