1 //===- MachineSizeOpts.cpp - code size optimization related code ----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains some shared machine IR code size optimization related 10 // code. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/CodeGen/MachineSizeOpts.h" 15 #include "llvm/CodeGen/MBFIWrapper.h" 16 #include "llvm/Analysis/ProfileSummaryInfo.h" 17 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 18 19 using namespace llvm; 20 21 extern cl::opt<bool> EnablePGSO; 22 extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly; 23 extern cl::opt<bool> ForcePGSO; 24 extern cl::opt<int> PgsoCutoffInstrProf; 25 extern cl::opt<int> PgsoCutoffSampleProf; 26 27 namespace machine_size_opts_detail { 28 29 /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock. 30 bool isColdBlock(const MachineBasicBlock *MBB, 31 ProfileSummaryInfo *PSI, 32 const MachineBlockFrequencyInfo *MBFI) { 33 auto Count = MBFI->getBlockProfileCount(MBB); 34 return Count && PSI->isColdCount(*Count); 35 } 36 37 bool isColdBlock(BlockFrequency BlockFreq, 38 ProfileSummaryInfo *PSI, 39 const MachineBlockFrequencyInfo *MBFI) { 40 auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 41 return Count && PSI->isColdCount(*Count); 42 } 43 44 /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock. 45 static bool isHotBlockNthPercentile(int PercentileCutoff, 46 const MachineBasicBlock *MBB, 47 ProfileSummaryInfo *PSI, 48 const MachineBlockFrequencyInfo *MBFI) { 49 auto Count = MBFI->getBlockProfileCount(MBB); 50 return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 51 } 52 53 static bool isHotBlockNthPercentile(int PercentileCutoff, 54 BlockFrequency BlockFreq, 55 ProfileSummaryInfo *PSI, 56 const MachineBlockFrequencyInfo *MBFI) { 57 auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 58 return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 59 } 60 61 /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for 62 /// MachineFunction. 63 bool isFunctionColdInCallGraph( 64 const MachineFunction *MF, 65 ProfileSummaryInfo *PSI, 66 const MachineBlockFrequencyInfo &MBFI) { 67 if (auto FunctionCount = MF->getFunction().getEntryCount()) 68 if (!PSI->isColdCount(FunctionCount.getCount())) 69 return false; 70 for (const auto &MBB : *MF) 71 if (!isColdBlock(&MBB, PSI, &MBFI)) 72 return false; 73 return true; 74 } 75 76 /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for 77 /// MachineFunction. 78 bool isFunctionHotInCallGraphNthPercentile( 79 int PercentileCutoff, 80 const MachineFunction *MF, 81 ProfileSummaryInfo *PSI, 82 const MachineBlockFrequencyInfo &MBFI) { 83 if (auto FunctionCount = MF->getFunction().getEntryCount()) 84 if (PSI->isHotCountNthPercentile(PercentileCutoff, 85 FunctionCount.getCount())) 86 return true; 87 for (const auto &MBB : *MF) 88 if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 89 return true; 90 return false; 91 } 92 } // namespace machine_size_opts_detail 93 94 namespace { 95 struct MachineBasicBlockBFIAdapter { 96 static bool isFunctionColdInCallGraph(const MachineFunction *MF, 97 ProfileSummaryInfo *PSI, 98 const MachineBlockFrequencyInfo &MBFI) { 99 return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI); 100 } 101 static bool isFunctionHotInCallGraphNthPercentile( 102 int CutOff, 103 const MachineFunction *MF, 104 ProfileSummaryInfo *PSI, 105 const MachineBlockFrequencyInfo &MBFI) { 106 return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile( 107 CutOff, MF, PSI, MBFI); 108 } 109 static bool isColdBlock(const MachineBasicBlock *MBB, 110 ProfileSummaryInfo *PSI, 111 const MachineBlockFrequencyInfo *MBFI) { 112 return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI); 113 } 114 static bool isColdBlock(BlockFrequency BlockFreq, 115 ProfileSummaryInfo *PSI, 116 const MachineBlockFrequencyInfo *MBFI) { 117 return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI); 118 } 119 static bool isHotBlockNthPercentile(int CutOff, 120 const MachineBasicBlock *MBB, 121 ProfileSummaryInfo *PSI, 122 const MachineBlockFrequencyInfo *MBFI) { 123 return machine_size_opts_detail::isHotBlockNthPercentile( 124 CutOff, MBB, PSI, MBFI); 125 } 126 static bool isHotBlockNthPercentile(int CutOff, 127 BlockFrequency BlockFreq, 128 ProfileSummaryInfo *PSI, 129 const MachineBlockFrequencyInfo *MBFI) { 130 return machine_size_opts_detail::isHotBlockNthPercentile( 131 CutOff, BlockFreq, PSI, MBFI); 132 } 133 }; 134 } // end anonymous namespace 135 136 bool llvm::shouldOptimizeForSize(const MachineFunction *MF, 137 ProfileSummaryInfo *PSI, 138 const MachineBlockFrequencyInfo *MBFI, 139 PGSOQueryType QueryType) { 140 return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 141 MF, PSI, MBFI, QueryType); 142 } 143 144 bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 145 ProfileSummaryInfo *PSI, 146 const MachineBlockFrequencyInfo *MBFI, 147 PGSOQueryType QueryType) { 148 assert(MBB); 149 return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 150 MBB, PSI, MBFI, QueryType); 151 } 152 153 bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 154 ProfileSummaryInfo *PSI, 155 MBFIWrapper *MBFIW, 156 PGSOQueryType QueryType) { 157 assert(MBB); 158 if (!PSI || !MBFIW) 159 return false; 160 BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB); 161 return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 162 BlockFreq, PSI, &MBFIW->getMBFI(), QueryType); 163 } 164