[InstCombine] Signed saturation patterns
[llvm-complete.git] / lib / Transforms / Instrumentation / CGProfile.cpp
blob358abab3cceb76fa7f75742e6ecafb07058d1a36
1 //===-- CGProfile.cpp -----------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
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"
22 #include <array>
24 using namespace llvm;
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))
34 return;
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);
40 for (auto &F : M) {
41 if (F.isDeclaration())
42 continue;
43 auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
44 if (BFI.getEntryFreq() == 0)
45 continue;
46 TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
47 for (auto &BB : F) {
48 Optional<uint64_t> BBCount = BFI.getBlockProfileCount(&BB);
49 if (!BBCount)
50 continue;
51 for (auto &I : BB) {
52 CallSite CS(&I);
53 if (!CS)
54 continue;
55 if (CS.isIndirectCall()) {
56 InstrProfValueData ValueData[8];
57 uint32_t ActualNumValueData;
58 uint64_t TotalC;
59 if (!getValueProfDataFromInst(*CS.getInstruction(),
60 IPVK_IndirectCallTarget, 8, ValueData,
61 ActualNumValueData, TotalC))
62 continue;
63 for (const auto &VD :
64 ArrayRef<InstrProfValueData>(ValueData, ActualNumValueData)) {
65 UpdateCounts(TTI, &F, Symtab.getFunction(VD.Value), VD.Count);
67 continue;
69 UpdateCounts(TTI, &F, CS.getCalledFunction(), *BBCount);
74 addModuleFlags(M, Counts);
76 return PreservedAnalyses::all();
79 void CGProfilePass::addModuleFlags(
80 Module &M,
81 MapVector<std::pair<Function *, Function *>, uint64_t> &Counts) const {
82 if (Counts.empty())
83 return;
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));