From d26200423ee818e54d4088bd0c499caf840d866d Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Tue, 28 Aug 2012 22:21:25 +0000 Subject: Profile: set branch weight metadata with data generated from profiling. This patch implements ProfileDataLoader which loads profile data generated by -insert-edge-profiling and updates branch weight metadata accordingly. Patch by Alastair Murray. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162799 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ProfileDataLoaderPass.cpp | 188 +++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 lib/Analysis/ProfileDataLoaderPass.cpp (limited to 'lib/Analysis/ProfileDataLoaderPass.cpp') diff --git a/lib/Analysis/ProfileDataLoaderPass.cpp b/lib/Analysis/ProfileDataLoaderPass.cpp new file mode 100644 index 0000000..2a61a0b --- /dev/null +++ b/lib/Analysis/ProfileDataLoaderPass.cpp @@ -0,0 +1,188 @@ +//===- ProfileDataLoaderPass.cpp - Set branch weight metadata from prof ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass loads profiling data from a dump file and sets branch weight +// metadata. +// +// TODO: Replace all "profile-metadata-loader" strings with "profile-loader" +// once ProfileInfo etc. has been removed. +// +//===----------------------------------------------------------------------===// +#define DEBUG_TYPE "profile-metadata-loader" +#include "llvm/BasicBlock.h" +#include "llvm/InstrTypes.h" +#include "llvm/Module.h" +#include "llvm/LLVMContext.h" +#include "llvm/MDBuilder.h" +#include "llvm/Metadata.h" +#include "llvm/Pass.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/ProfileDataLoader.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/CFG.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Format.h" +#include "llvm/ADT/Statistic.h" +#include +using namespace llvm; + +STATISTIC(NumEdgesRead, "The # of edges read."); +STATISTIC(NumTermsAnnotated, "The # of terminator instructions annotated."); + +static cl::opt +ProfileMetadataFilename("profile-file", cl::init("llvmprof.out"), + cl::value_desc("filename"), + cl::desc("Profile file loaded by -profile-metadata-loader")); + +namespace { + /// This pass loads profiling data from a dump file and sets branch weight + /// metadata. + class ProfileMetadataLoaderPass : public ModulePass { + std::string Filename; + public: + static char ID; // Class identification, replacement for typeinfo + explicit ProfileMetadataLoaderPass(const std::string &filename = "") + : ModulePass(ID), Filename(filename) { + initializeProfileMetadataLoaderPassPass(*PassRegistry::getPassRegistry()); + if (filename.empty()) Filename = ProfileMetadataFilename; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + + virtual const char *getPassName() const { + return "Profile loader"; + } + + virtual void readEdge(unsigned, ProfileData&, ProfileData::Edge, + std::vector&); + virtual unsigned matchEdges(Module&, ProfileData&, std::vector&); + virtual void setBranchWeightMetadata(Module&, ProfileData&); + + virtual bool runOnModule(Module &M); + }; +} // End of anonymous namespace + +char ProfileMetadataLoaderPass::ID = 0; +INITIALIZE_PASS_BEGIN(ProfileMetadataLoaderPass, "profile-metadata-loader", + "Load profile information from llvmprof.out", false, true) +INITIALIZE_PASS_END(ProfileMetadataLoaderPass, "profile-metadata-loader", + "Load profile information from llvmprof.out", false, true) + +char &llvm::ProfileMetadataLoaderPassID = ProfileMetadataLoaderPass::ID; + +/// createProfileMetadataLoaderPass - This function returns a Pass that loads +/// the profiling information for the module from the specified filename, +/// making it available to the optimizers. +ModulePass *llvm::createProfileMetadataLoaderPass() { + return new ProfileMetadataLoaderPass(); +} +ModulePass *llvm::createProfileMetadataLoaderPass(const std::string &Filename) { + return new ProfileMetadataLoaderPass(Filename); +} + +/// readEdge - Take the value from a profile counter and assign it to an edge. +void ProfileMetadataLoaderPass::readEdge(unsigned ReadCount, + ProfileData &PB, ProfileData::Edge e, + std::vector &Counters) { + if (ReadCount < Counters.size()) { + unsigned weight = Counters[ReadCount]; + assert(weight != ProfileDataLoader::Uncounted); + PB.addEdgeWeight(e, weight); + + DEBUG(dbgs() << "-- Read Edge Counter for " << e + << " (# "<< (ReadCount) << "): " + << PB.getEdgeWeight(e) << "\n"); + } +} + +/// matchEdges - Link every profile counter with an edge. +unsigned ProfileMetadataLoaderPass::matchEdges(Module &M, ProfileData &PB, + std::vector &Counters) { + if (Counters.size() == 0) return 0; + + unsigned ReadCount = 0; + + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { + if (F->isDeclaration()) continue; + DEBUG(dbgs() << "Loading edges in '" << F->getName() << "'\n"); + readEdge(ReadCount++, PB, PB.getEdge(0, &F->getEntryBlock()), Counters); + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + TerminatorInst *TI = BB->getTerminator(); + for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { + readEdge(ReadCount++, PB, PB.getEdge(BB,TI->getSuccessor(s)), + Counters); + } + } + } + + return ReadCount; +} + +/// setBranchWeightMetadata - Translate the counter values associated with each +/// edge into branch weights for each conditional branch (a branch with 2 or +/// more desinations). +void ProfileMetadataLoaderPass::setBranchWeightMetadata(Module &M, + ProfileData &PB) { + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { + if (F->isDeclaration()) continue; + DEBUG(dbgs() << "Setting branch metadata in '" << F->getName() << "'\n"); + + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + TerminatorInst *TI = BB->getTerminator(); + unsigned NumSuccessors = TI->getNumSuccessors(); + + // If there is only one successor then we can not set a branch + // probability as the target is certain. + if (NumSuccessors < 2) continue; + + // Load the weights of all edges leading from this terminator. + DEBUG(dbgs() << "-- Terminator with " << NumSuccessors + << " successors:\n"); + std::vector Weights(NumSuccessors); + for (unsigned s = 0 ; s < NumSuccessors ; ++s) { + ProfileData::Edge edge = PB.getEdge(BB, TI->getSuccessor(s)); + Weights[s] = (uint32_t)PB.getEdgeWeight(edge); + DEBUG(dbgs() << "---- Edge '" << edge << "' has weight " + << Weights[s] << "\n"); + } + + // Set branch weight metadata. This will set branch probabilities of + // 100%/0% if that is true of the dynamic execution. + // BranchProbabilityInfo can account for this when it loads this metadata + // (it gives the unexectuted branch a weight of 1 for the purposes of + // probability calculations). + MDBuilder MDB(TI->getContext()); + MDNode *Node = MDB.createBranchWeights(Weights); + TI->setMetadata(LLVMContext::MD_prof, Node); + NumTermsAnnotated++; + } + } +} + +bool ProfileMetadataLoaderPass::runOnModule(Module &M) { + ProfileDataLoader PDL("profile-data-loader", Filename); + ProfileData PB; + + std::vector Counters = PDL.getRawEdgeCounts(); + + unsigned ReadCount = matchEdges(M, PB, Counters); + + if (ReadCount != Counters.size()) { + errs() << "WARNING: profile information is inconsistent with " + << "the current program!\n"; + } + NumEdgesRead = ReadCount; + + setBranchWeightMetadata(M, PB); + + return ReadCount > 0; +} -- cgit v1.1 From f91e400b2125067e75e0f2159bca7ffd0cf109a0 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 31 Aug 2012 05:18:31 +0000 Subject: Cleanups due to feedback. No functionality change. Patch by Alistair. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162979 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ProfileDataLoaderPass.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'lib/Analysis/ProfileDataLoaderPass.cpp') diff --git a/lib/Analysis/ProfileDataLoaderPass.cpp b/lib/Analysis/ProfileDataLoaderPass.cpp index 2a61a0b..c43cff0 100644 --- a/lib/Analysis/ProfileDataLoaderPass.cpp +++ b/lib/Analysis/ProfileDataLoaderPass.cpp @@ -15,6 +15,7 @@ // //===----------------------------------------------------------------------===// #define DEBUG_TYPE "profile-metadata-loader" +#include "llvm/ADT/ArrayRef.h" #include "llvm/BasicBlock.h" #include "llvm/InstrTypes.h" #include "llvm/Module.h" @@ -30,7 +31,6 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Format.h" #include "llvm/ADT/Statistic.h" -#include using namespace llvm; STATISTIC(NumEdgesRead, "The # of edges read."); @@ -63,8 +63,8 @@ namespace { } virtual void readEdge(unsigned, ProfileData&, ProfileData::Edge, - std::vector&); - virtual unsigned matchEdges(Module&, ProfileData&, std::vector&); + ArrayRef); + virtual unsigned matchEdges(Module&, ProfileData&, ArrayRef); virtual void setBranchWeightMetadata(Module&, ProfileData&); virtual bool runOnModule(Module &M); @@ -92,21 +92,21 @@ ModulePass *llvm::createProfileMetadataLoaderPass(const std::string &Filename) { /// readEdge - Take the value from a profile counter and assign it to an edge. void ProfileMetadataLoaderPass::readEdge(unsigned ReadCount, ProfileData &PB, ProfileData::Edge e, - std::vector &Counters) { - if (ReadCount < Counters.size()) { - unsigned weight = Counters[ReadCount]; - assert(weight != ProfileDataLoader::Uncounted); - PB.addEdgeWeight(e, weight); - - DEBUG(dbgs() << "-- Read Edge Counter for " << e - << " (# "<< (ReadCount) << "): " - << PB.getEdgeWeight(e) << "\n"); - } + ArrayRef Counters) { + if (ReadCount >= Counters.size()) return; + + unsigned weight = Counters[ReadCount]; + assert(weight != ProfileDataLoader::Uncounted); + PB.addEdgeWeight(e, weight); + + DEBUG(dbgs() << "-- Read Edge Counter for " << e + << " (# "<< (ReadCount) << "): " + << PB.getEdgeWeight(e) << "\n"); } /// matchEdges - Link every profile counter with an edge. unsigned ProfileMetadataLoaderPass::matchEdges(Module &M, ProfileData &PB, - std::vector &Counters) { + ArrayRef Counters) { if (Counters.size() == 0) return 0; unsigned ReadCount = 0; @@ -147,7 +147,7 @@ void ProfileMetadataLoaderPass::setBranchWeightMetadata(Module &M, // Load the weights of all edges leading from this terminator. DEBUG(dbgs() << "-- Terminator with " << NumSuccessors << " successors:\n"); - std::vector Weights(NumSuccessors); + SmallVector Weights(NumSuccessors); for (unsigned s = 0 ; s < NumSuccessors ; ++s) { ProfileData::Edge edge = PB.getEdge(BB, TI->getSuccessor(s)); Weights[s] = (uint32_t)PB.getEdgeWeight(edge); @@ -172,7 +172,7 @@ bool ProfileMetadataLoaderPass::runOnModule(Module &M) { ProfileDataLoader PDL("profile-data-loader", Filename); ProfileData PB; - std::vector Counters = PDL.getRawEdgeCounts(); + ArrayRef Counters = PDL.getRawEdgeCounts(); unsigned ReadCount = matchEdges(M, PB, Counters); -- cgit v1.1