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(Kind: Attribute::Cold)) |
26 | return true; |
27 | if (!PSI.hasProfileSummary()) |
28 | return false; |
29 | BlockFrequencyInfo &BFI = FAM.getResult<BlockFrequencyAnalysis>(IR&: F); |
30 | return PSI.isFunctionColdInCallGraph(F: &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>(IR&: M); |
38 | FunctionAnalysisManager &FAM = |
39 | AM.getResult<FunctionAnalysisManagerModuleProxy>(IR&: 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(Kind: Attribute::OptimizeForSize); |
50 | break; |
51 | case PGOOptions::ColdFuncOpt::MinSize: |
52 | F.addFnAttr(Kind: Attribute::MinSize); |
53 | break; |
54 | case PGOOptions::ColdFuncOpt::OptNone: |
55 | // alwaysinline is incompatible with optnone. |
56 | if (F.hasFnAttribute(Kind: Attribute::AlwaysInline)) |
57 | continue; |
58 | F.addFnAttr(Kind: Attribute::OptimizeNone); |
59 | F.addFnAttr(Kind: Attribute::NoInline); |
60 | break; |
61 | } |
62 | MadeChange = true; |
63 | } |
64 | return MadeChange ? PreservedAnalyses::none() : PreservedAnalyses::all(); |
65 | } |
66 |