1 //===-- CGProfile.cpp -----------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/MapVector.h" 11 #include "llvm/Analysis/BlockFrequencyInfo.h" 12 #include "llvm/Analysis/BranchProbabilityInfo.h" 13 #include "llvm/IR/Constants.h" 14 #include "llvm/IR/Instructions.h" 15 #include "llvm/IR/MDBuilder.h" 16 #include "llvm/IR/PassManager.h" 17 #include "llvm/Transforms/Instrumentation.h" 18 19 #include <array> 20 21 using namespace llvm; 22 23 class CGProfilePass : public ModulePass { 24 public: 25 static char ID; 26 27 CGProfilePass() : ModulePass(ID) { 28 initializeCGProfilePassPass(*PassRegistry::getPassRegistry()); 29 } 30 31 StringRef getPassName() const override { return "CGProfilePass"; } 32 33 private: 34 bool runOnModule(Module &M) override; 35 bool addModuleFlags( 36 Module &M, 37 MapVector<std::pair<Function *, Function *>, uint64_t> &Counts) const; 38 39 void getAnalysisUsage(AnalysisUsage &AU) const override { 40 AU.addRequired<BlockFrequencyInfoWrapperPass>(); 41 AU.addRequired<BranchProbabilityInfoWrapperPass>(); 42 } 43 }; 44 45 bool CGProfilePass::runOnModule(Module &M) { 46 if (skipModule(M)) 47 return false; 48 49 MapVector<std::pair<Function *, Function *>, uint64_t> Counts; 50 51 for (auto &F : M) { 52 if (F.isDeclaration()) 53 continue; 54 getAnalysis<BranchProbabilityInfoWrapperPass>(F).getBPI(); 55 auto &BFI = getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI(); 56 for (const auto &BB : F) { 57 Optional<uint64_t> BBCount = BFI.getBlockProfileCount(&BB); 58 if (!BBCount) 59 continue; 60 for (const auto &I : BB) { 61 auto *CI = dyn_cast<CallInst>(&I); 62 if (!CI) 63 continue; 64 Function *CalledF = CI->getCalledFunction(); 65 if (!CalledF || CalledF->isIntrinsic()) 66 continue; 67 68 uint64_t &Count = Counts[std::make_pair(&F, CalledF)]; 69 Count = SaturatingAdd(Count, *BBCount); 70 } 71 } 72 } 73 74 return addModuleFlags(M, Counts); 75 } 76 77 bool CGProfilePass::addModuleFlags( 78 Module &M, 79 MapVector<std::pair<Function *, Function *>, uint64_t> &Counts) const { 80 if (Counts.empty()) 81 return false; 82 83 LLVMContext &Context = M.getContext(); 84 MDBuilder MDB(Context); 85 std::vector<Metadata *> Nodes; 86 87 for (auto E : Counts) { 88 SmallVector<Metadata *, 3> Vals; 89 Vals.push_back(ValueAsMetadata::get(E.first.first)); 90 Vals.push_back(ValueAsMetadata::get(E.first.second)); 91 Vals.push_back(MDB.createConstant( 92 ConstantInt::get(Type::getInt64Ty(Context), E.second))); 93 Nodes.push_back(MDNode::get(Context, Vals)); 94 } 95 96 M.addModuleFlag(Module::Append, "CG Profile", MDNode::get(Context, Nodes)); 97 return true; 98 } 99 100 char CGProfilePass::ID = 0; 101 INITIALIZE_PASS_BEGIN(CGProfilePass, "cg-profile", 102 "Generate profile information from the call graph.", 103 false, false) 104 INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) 105 INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass) 106 INITIALIZE_PASS_END(CGProfilePass, "cg-profile", 107 "Generate profile information from the call graph.", false, 108 false) 109 110 ModulePass *llvm::createCGProfilePass() { return new CGProfilePass(); } 111