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 { 28 namespace machine_size_opts_detail { 29 30 /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock. 31 bool isColdBlock(const MachineBasicBlock *MBB, 32 ProfileSummaryInfo *PSI, 33 const MachineBlockFrequencyInfo *MBFI) { 34 auto Count = MBFI->getBlockProfileCount(MBB); 35 return Count && PSI->isColdCount(*Count); 36 } 37 38 bool isColdBlock(BlockFrequency BlockFreq, 39 ProfileSummaryInfo *PSI, 40 const MachineBlockFrequencyInfo *MBFI) { 41 auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 42 return Count && PSI->isColdCount(*Count); 43 } 44 45 /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock. 46 static bool isHotBlockNthPercentile(int PercentileCutoff, 47 const MachineBasicBlock *MBB, 48 ProfileSummaryInfo *PSI, 49 const MachineBlockFrequencyInfo *MBFI) { 50 auto Count = MBFI->getBlockProfileCount(MBB); 51 return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 52 } 53 54 static bool isHotBlockNthPercentile(int PercentileCutoff, 55 BlockFrequency BlockFreq, 56 ProfileSummaryInfo *PSI, 57 const MachineBlockFrequencyInfo *MBFI) { 58 auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 59 return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count); 60 } 61 62 static bool isColdBlockNthPercentile(int PercentileCutoff, 63 const MachineBasicBlock *MBB, 64 ProfileSummaryInfo *PSI, 65 const MachineBlockFrequencyInfo *MBFI) { 66 auto Count = MBFI->getBlockProfileCount(MBB); 67 return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); 68 } 69 70 static bool isColdBlockNthPercentile(int PercentileCutoff, 71 BlockFrequency BlockFreq, 72 ProfileSummaryInfo *PSI, 73 const MachineBlockFrequencyInfo *MBFI) { 74 auto Count = MBFI->getProfileCountFromFreq(BlockFreq.getFrequency()); 75 return Count && PSI->isColdCountNthPercentile(PercentileCutoff, *Count); 76 } 77 78 /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for 79 /// MachineFunction. 80 bool isFunctionColdInCallGraph( 81 const MachineFunction *MF, 82 ProfileSummaryInfo *PSI, 83 const MachineBlockFrequencyInfo &MBFI) { 84 if (auto FunctionCount = MF->getFunction().getEntryCount()) 85 if (!PSI->isColdCount(FunctionCount.getCount())) 86 return false; 87 for (const auto &MBB : *MF) 88 if (!isColdBlock(&MBB, PSI, &MBFI)) 89 return false; 90 return true; 91 } 92 93 /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for 94 /// MachineFunction. 95 bool isFunctionHotInCallGraphNthPercentile( 96 int PercentileCutoff, 97 const MachineFunction *MF, 98 ProfileSummaryInfo *PSI, 99 const MachineBlockFrequencyInfo &MBFI) { 100 if (auto FunctionCount = MF->getFunction().getEntryCount()) 101 if (PSI->isHotCountNthPercentile(PercentileCutoff, 102 FunctionCount.getCount())) 103 return true; 104 for (const auto &MBB : *MF) 105 if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 106 return true; 107 return false; 108 } 109 110 bool isFunctionColdInCallGraphNthPercentile( 111 int PercentileCutoff, const MachineFunction *MF, ProfileSummaryInfo *PSI, 112 const MachineBlockFrequencyInfo &MBFI) { 113 if (auto FunctionCount = MF->getFunction().getEntryCount()) 114 if (!PSI->isColdCountNthPercentile(PercentileCutoff, 115 FunctionCount.getCount())) 116 return false; 117 for (const auto &MBB : *MF) 118 if (!isColdBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 119 return false; 120 return true; 121 } 122 } // namespace machine_size_opts_detail 123 124 struct MachineBasicBlockBFIAdapter { 125 static bool isFunctionColdInCallGraph(const MachineFunction *MF, 126 ProfileSummaryInfo *PSI, 127 const MachineBlockFrequencyInfo &MBFI) { 128 return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI); 129 } 130 static bool isFunctionHotInCallGraphNthPercentile( 131 int CutOff, 132 const MachineFunction *MF, 133 ProfileSummaryInfo *PSI, 134 const MachineBlockFrequencyInfo &MBFI) { 135 return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile( 136 CutOff, MF, PSI, MBFI); 137 } 138 static bool isFunctionColdInCallGraphNthPercentile( 139 int CutOff, const MachineFunction *MF, ProfileSummaryInfo *PSI, 140 const MachineBlockFrequencyInfo &MBFI) { 141 return machine_size_opts_detail::isFunctionColdInCallGraphNthPercentile( 142 CutOff, MF, PSI, MBFI); 143 } 144 static bool isColdBlock(const MachineBasicBlock *MBB, 145 ProfileSummaryInfo *PSI, 146 const MachineBlockFrequencyInfo *MBFI) { 147 return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI); 148 } 149 static bool isColdBlock(BlockFrequency BlockFreq, 150 ProfileSummaryInfo *PSI, 151 const MachineBlockFrequencyInfo *MBFI) { 152 return machine_size_opts_detail::isColdBlock(BlockFreq, PSI, MBFI); 153 } 154 static bool isHotBlockNthPercentile(int CutOff, 155 const MachineBasicBlock *MBB, 156 ProfileSummaryInfo *PSI, 157 const MachineBlockFrequencyInfo *MBFI) { 158 return machine_size_opts_detail::isHotBlockNthPercentile( 159 CutOff, MBB, PSI, MBFI); 160 } 161 static bool isHotBlockNthPercentile(int CutOff, 162 BlockFrequency BlockFreq, 163 ProfileSummaryInfo *PSI, 164 const MachineBlockFrequencyInfo *MBFI) { 165 return machine_size_opts_detail::isHotBlockNthPercentile( 166 CutOff, BlockFreq, PSI, MBFI); 167 } 168 static bool isColdBlockNthPercentile(int CutOff, const MachineBasicBlock *MBB, 169 ProfileSummaryInfo *PSI, 170 const MachineBlockFrequencyInfo *MBFI) { 171 return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, MBB, PSI, 172 MBFI); 173 } 174 static bool isColdBlockNthPercentile(int CutOff, BlockFrequency BlockFreq, 175 ProfileSummaryInfo *PSI, 176 const MachineBlockFrequencyInfo *MBFI) { 177 return machine_size_opts_detail::isColdBlockNthPercentile(CutOff, BlockFreq, 178 PSI, MBFI); 179 } 180 }; 181 } // end anonymous namespace 182 183 bool llvm::shouldOptimizeForSize(const MachineFunction *MF, 184 ProfileSummaryInfo *PSI, 185 const MachineBlockFrequencyInfo *MBFI, 186 PGSOQueryType QueryType) { 187 return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 188 MF, PSI, MBFI, QueryType); 189 } 190 191 bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 192 ProfileSummaryInfo *PSI, 193 const MachineBlockFrequencyInfo *MBFI, 194 PGSOQueryType QueryType) { 195 assert(MBB); 196 return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 197 MBB, PSI, MBFI, QueryType); 198 } 199 200 bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB, 201 ProfileSummaryInfo *PSI, 202 MBFIWrapper *MBFIW, 203 PGSOQueryType QueryType) { 204 assert(MBB); 205 if (!PSI || !MBFIW) 206 return false; 207 BlockFrequency BlockFreq = MBFIW->getBlockFreq(MBB); 208 return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>( 209 BlockFreq, PSI, &MBFIW->getMBFI(), QueryType); 210 } 211