1 //===-- CGProfile.cpp -----------------------------------------------------===//
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/CGProfile.h"
11 #include "llvm/ADT/MapVector.h"
12 #include "llvm/Analysis/BlockFrequencyInfo.h"
13 #include "llvm/Analysis/LazyBlockFrequencyInfo.h"
14 #include "llvm/Analysis/TargetTransformInfo.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/MDBuilder.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/PassManager.h"
19 #include "llvm/ProfileData/InstrProf.h"
20 #include "llvm/Transforms/Utils/Instrumentation.h"
26 addModuleFlags(Module
&M
,
27 MapVector
<std::pair
<Function
*, Function
*>, uint64_t> &Counts
) {
31 LLVMContext
&Context
= M
.getContext();
32 MDBuilder
MDB(Context
);
33 std::vector
<Metadata
*> Nodes
;
35 for (auto E
: Counts
) {
36 Metadata
*Vals
[] = {ValueAsMetadata::get(E
.first
.first
),
37 ValueAsMetadata::get(E
.first
.second
),
38 MDB
.createConstant(ConstantInt::get(
39 Type::getInt64Ty(Context
), E
.second
))};
40 Nodes
.push_back(MDNode::get(Context
, Vals
));
43 M
.addModuleFlag(Module::Append
, "CG Profile",
44 MDTuple::getDistinct(Context
, Nodes
));
48 static bool runCGProfilePass(Module
&M
, FunctionAnalysisManager
&FAM
,
50 MapVector
<std::pair
<Function
*, Function
*>, uint64_t> Counts
;
51 InstrProfSymtab Symtab
;
52 auto UpdateCounts
= [&](TargetTransformInfo
&TTI
, Function
*F
,
53 Function
*CalledF
, uint64_t NewCount
) {
56 if (!CalledF
|| !TTI
.isLoweredToCall(CalledF
) ||
57 CalledF
->hasDLLImportStorageClass())
59 uint64_t &Count
= Counts
[std::make_pair(F
, CalledF
)];
60 Count
= SaturatingAdd(Count
, NewCount
);
62 // Ignore error here. Indirect calls are ignored if this fails.
63 (void)(bool)Symtab
.create(M
, InLTO
);
65 // Avoid extra cost of running passes for BFI when the function doesn't have
67 if (F
.isDeclaration() || !F
.getEntryCount())
69 auto &BFI
= FAM
.getResult
<BlockFrequencyAnalysis
>(F
);
70 if (BFI
.getEntryFreq() == BlockFrequency(0))
72 TargetTransformInfo
&TTI
= FAM
.getResult
<TargetIRAnalysis
>(F
);
74 std::optional
<uint64_t> BBCount
= BFI
.getBlockProfileCount(&BB
);
78 CallBase
*CB
= dyn_cast
<CallBase
>(&I
);
81 if (CB
->isIndirectCall()) {
84 getValueProfDataFromInst(*CB
, IPVK_IndirectCallTarget
, 8, TotalC
);
85 for (const auto &VD
: ValueData
)
86 UpdateCounts(TTI
, &F
, Symtab
.getFunction(VD
.Value
), VD
.Count
);
89 UpdateCounts(TTI
, &F
, CB
->getCalledFunction(), *BBCount
);
94 return addModuleFlags(M
, Counts
);
97 PreservedAnalyses
CGProfilePass::run(Module
&M
, ModuleAnalysisManager
&MAM
) {
98 FunctionAnalysisManager
&FAM
=
99 MAM
.getResult
<FunctionAnalysisManagerModuleProxy
>(M
).getManager();
100 runCGProfilePass(M
, FAM
, InLTO
);
102 return PreservedAnalyses::all();