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/TargetTransformInfo.h"
14 #include "llvm/IR/CallSite.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/MDBuilder.h"
18 #include "llvm/IR/PassManager.h"
19 #include "llvm/ProfileData/InstrProf.h"
20 #include "llvm/Transforms/Instrumentation.h"
26 PreservedAnalyses
CGProfilePass::run(Module
&M
, ModuleAnalysisManager
&MAM
) {
27 MapVector
<std::pair
<Function
*, Function
*>, uint64_t> Counts
;
28 FunctionAnalysisManager
&FAM
=
29 MAM
.getResult
<FunctionAnalysisManagerModuleProxy
>(M
).getManager();
30 InstrProfSymtab Symtab
;
31 auto UpdateCounts
= [&](TargetTransformInfo
&TTI
, Function
*F
,
32 Function
*CalledF
, uint64_t NewCount
) {
33 if (!CalledF
|| !TTI
.isLoweredToCall(CalledF
))
35 uint64_t &Count
= Counts
[std::make_pair(F
, CalledF
)];
36 Count
= SaturatingAdd(Count
, NewCount
);
38 // Ignore error here. Indirect calls are ignored if this fails.
39 (void)(bool)Symtab
.create(M
);
41 if (F
.isDeclaration())
43 auto &BFI
= FAM
.getResult
<BlockFrequencyAnalysis
>(F
);
44 if (BFI
.getEntryFreq() == 0)
46 TargetTransformInfo
&TTI
= FAM
.getResult
<TargetIRAnalysis
>(F
);
48 Optional
<uint64_t> BBCount
= BFI
.getBlockProfileCount(&BB
);
55 if (CS
.isIndirectCall()) {
56 InstrProfValueData ValueData
[8];
57 uint32_t ActualNumValueData
;
59 if (!getValueProfDataFromInst(*CS
.getInstruction(),
60 IPVK_IndirectCallTarget
, 8, ValueData
,
61 ActualNumValueData
, TotalC
))
64 ArrayRef
<InstrProfValueData
>(ValueData
, ActualNumValueData
)) {
65 UpdateCounts(TTI
, &F
, Symtab
.getFunction(VD
.Value
), VD
.Count
);
69 UpdateCounts(TTI
, &F
, CS
.getCalledFunction(), *BBCount
);
74 addModuleFlags(M
, Counts
);
76 return PreservedAnalyses::all();
79 void CGProfilePass::addModuleFlags(
81 MapVector
<std::pair
<Function
*, Function
*>, uint64_t> &Counts
) const {
85 LLVMContext
&Context
= M
.getContext();
86 MDBuilder
MDB(Context
);
87 std::vector
<Metadata
*> Nodes
;
89 for (auto E
: Counts
) {
90 Metadata
*Vals
[] = {ValueAsMetadata::get(E
.first
.first
),
91 ValueAsMetadata::get(E
.first
.second
),
92 MDB
.createConstant(ConstantInt::get(
93 Type::getInt64Ty(Context
), E
.second
))};
94 Nodes
.push_back(MDNode::get(Context
, Vals
));
97 M
.addModuleFlag(Module::Append
, "CG Profile", MDNode::get(Context
, Nodes
));