aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ProfileDataLoaderPass.cpp
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2012-09-13 19:09:19 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2012-09-13 19:09:19 -0700
commit78c041bd883d86c81c42b98f326660277e6d0d9a (patch)
tree52800183ec2d22164b8f396842142c3a8aab912a /lib/Analysis/ProfileDataLoaderPass.cpp
parent828ded66831c0caaeecd2291a6bfb084f373d0e4 (diff)
parent1c4ad5ef4fab105f0c8af7edd026e00502fb6279 (diff)
downloadexternal_llvm-78c041bd883d86c81c42b98f326660277e6d0d9a.zip
external_llvm-78c041bd883d86c81c42b98f326660277e6d0d9a.tar.gz
external_llvm-78c041bd883d86c81c42b98f326660277e6d0d9a.tar.bz2
am 1c4ad5ef: Merge branch \'upstream\' into merge-2012_09_10
* commit '1c4ad5ef4fab105f0c8af7edd026e00502fb6279': (446 commits) Revert r163556. Missed updates to tablegen files. Update function names to conform to guidelines. No functional change intended. test/CodeGen/X86/ms-inline-asm.ll: Relax for non-darwin x86 targets. '##InlineAsm' could not be seen in other hosts. [ms-inline asm] Properly emit the asm directives when the AsmPrinterVariant and InlineAsmVariant don't match. Update test case for Release builds. Remove redundant semicolons which are null statements. Disable stack coloring because it makes dragonegg fail bootstrapping. [ms-inline asm] Pass the correct AsmVariant to the PrintAsmOperand() function and update the printOperand() function accordingly. [ms-inline asm] Add support for .att_syntax directive. Enable stack coloring. Don't attempt to use flags from predicated instructions. [Object] Extract Elf_Ehdr. Patch by Hemant Kulkarni! Stack Coloring: Handle the case where END markers come before BEGIN markers properly. Enhance PR11334 fix to support extload from v2f32/v4f32 Add "blocked" heuristic to the Hexagon MI scheduler. Fold multiply by 0 or 1 when in UnsafeFPMath mode in SelectionDAG::getNode(). whitespace Add boolean simplification support from CMOV Fix an assertion failure when optimising a shufflevector incorrectly into concat_vectors, and a followup bug with SelectionDAG::getNode() creating nodes with invalid types. Minor cleanup. No functional change. ...
Diffstat (limited to 'lib/Analysis/ProfileDataLoaderPass.cpp')
-rw-r--r--lib/Analysis/ProfileDataLoaderPass.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/lib/Analysis/ProfileDataLoaderPass.cpp b/lib/Analysis/ProfileDataLoaderPass.cpp
new file mode 100644
index 0000000..c43cff0
--- /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/ADT/ArrayRef.h"
+#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"
+using namespace llvm;
+
+STATISTIC(NumEdgesRead, "The # of edges read.");
+STATISTIC(NumTermsAnnotated, "The # of terminator instructions annotated.");
+
+static cl::opt<std::string>
+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,
+ ArrayRef<unsigned>);
+ virtual unsigned matchEdges(Module&, ProfileData&, ArrayRef<unsigned>);
+ 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,
+ ArrayRef<unsigned> 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,
+ ArrayRef<unsigned> 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");
+ SmallVector<uint32_t, 4> 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;
+
+ ArrayRef<unsigned> 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;
+}