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 /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for 63 /// MachineFunction. 64 bool isFunctionColdInCallGraph( 65 const MachineFunction *MF, 66 ProfileSummaryInfo *PSI, 67 const MachineBlockFrequencyInfo &MBFI) { 68 if (auto FunctionCount = MF->getFunction().getEntryCount()) 69 if (!PSI->isColdCount(FunctionCount.getCount())) 70 return false; 71 for (const auto &MBB : *MF) 72 if (!isColdBlock(&MBB, PSI, &MBFI)) 73 return false; 74 return true; 75 } 76 77 /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for 78 /// MachineFunction. 79 bool isFunctionHotInCallGraphNthPercentile( 80 int PercentileCutoff, 81 const MachineFunction *MF, 82 ProfileSummaryInfo *PSI, 83 const MachineBlockFrequencyInfo &MBFI) { 84 if (auto FunctionCount = MF->getFunction().getEntryCount()) 85 if (PSI->isHotCountNthPercentile(PercentileCutoff, 86 FunctionCount.getCount())) 87 return true; 88 for (const auto &MBB : *MF) 89 if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI)) 90 return true; 91 return false; 92 } 93 } // namespace machine_size_opts_detail 94 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