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
shouldRunOnFunction(Function & F,ProfileSummaryInfo & PSI,FunctionAnalysisManager & FAM)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
run(Module & M,ModuleAnalysisManager & AM)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