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