1 //===----------------------------------------------------------------------===// 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 #include "llvm/Transforms/Instrumentation/PGOForceFunctionAttrs.h" 10 #include "llvm/Analysis/BlockFrequencyInfo.h" 11 #include "llvm/Analysis/ProfileSummaryInfo.h" 12 #include "llvm/IR/Module.h" 13 #include "llvm/IR/PassManager.h" 14 #include "llvm/Support/ErrorHandling.h" 15 16 using namespace llvm; 17 18 static bool shouldRunOnFunction(Function &F, ProfileSummaryInfo &PSI, 19 FunctionAnalysisManager &FAM) { 20 if (F.isDeclaration()) 21 return false; 22 // Respect existing attributes. 23 if (F.hasOptNone() || F.hasOptSize() || F.hasMinSize()) 24 return false; 25 if (F.hasFnAttribute(Attribute::Cold)) 26 return true; 27 if (!PSI.hasProfileSummary()) 28 return false; 29 BlockFrequencyInfo &BFI = FAM.getResult<BlockFrequencyAnalysis>(F); 30 return PSI.isFunctionColdInCallGraph(&F, BFI); 31 } 32 33 PreservedAnalyses PGOForceFunctionAttrsPass::run(Module &M, 34 ModuleAnalysisManager &AM) { 35 if (ColdType == PGOOptions::ColdFuncOpt::Default) 36 return PreservedAnalyses::all(); 37 ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M); 38 FunctionAnalysisManager &FAM = 39 AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 40 bool MadeChange = false; 41 for (Function &F : M) { 42 if (!shouldRunOnFunction(F, PSI, FAM)) 43 continue; 44 switch (ColdType) { 45 case PGOOptions::ColdFuncOpt::Default: 46 llvm_unreachable("bailed out for default above"); 47 break; 48 case PGOOptions::ColdFuncOpt::OptSize: 49 F.addFnAttr(Attribute::OptimizeForSize); 50 break; 51 case PGOOptions::ColdFuncOpt::MinSize: 52 F.addFnAttr(Attribute::MinSize); 53 break; 54 case PGOOptions::ColdFuncOpt::OptNone: 55 // alwaysinline is incompatible with optnone. 56 if (F.hasFnAttribute(Attribute::AlwaysInline)) 57 continue; 58 F.addFnAttr(Attribute::OptimizeNone); 59 F.addFnAttr(Attribute::NoInline); 60 break; 61 } 62 MadeChange = true; 63 } 64 return MadeChange ? PreservedAnalyses::none() : PreservedAnalyses::all(); 65 } 66