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