1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
18 static bool shouldRunOnFunction(Function
&F
, ProfileSummaryInfo
&PSI
,
19 FunctionAnalysisManager
&FAM
) {
20 if (F
.isDeclaration())
22 // Respect existing attributes.
23 if (F
.hasOptNone() || F
.hasOptSize() || F
.hasMinSize())
25 if (F
.hasFnAttribute(Attribute::Cold
))
27 if (!PSI
.hasProfileSummary())
29 BlockFrequencyInfo
&BFI
= FAM
.getResult
<BlockFrequencyAnalysis
>(F
);
30 return PSI
.isFunctionColdInCallGraph(&F
, BFI
);
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
))
45 case PGOOptions::ColdFuncOpt::Default
:
46 llvm_unreachable("bailed out for default above");
48 case PGOOptions::ColdFuncOpt::OptSize
:
49 F
.addFnAttr(Attribute::OptimizeForSize
);
51 case PGOOptions::ColdFuncOpt::MinSize
:
52 F
.addFnAttr(Attribute::MinSize
);
54 case PGOOptions::ColdFuncOpt::OptNone
:
55 // alwaysinline is incompatible with optnone.
56 if (F
.hasFnAttribute(Attribute::AlwaysInline
))
58 F
.addFnAttr(Attribute::OptimizeNone
);
59 F
.addFnAttr(Attribute::NoInline
);
64 return MadeChange
? PreservedAnalyses::none() : PreservedAnalyses::all();