Home | History | Annotate | Download | only in Analysis
      1 //===- ProfileDataLoaderPass.cpp - Set branch weight metadata from prof ---===//
      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 // This pass loads profiling data from a dump file and sets branch weight
     11 // metadata.
     12 //
     13 // TODO: Replace all "profile-metadata-loader" strings with "profile-loader"
     14 // once ProfileInfo etc. has been removed.
     15 //
     16 //===----------------------------------------------------------------------===//
     17 #define DEBUG_TYPE "profile-metadata-loader"
     18 #include "llvm/Analysis/Passes.h"
     19 #include "llvm/ADT/ArrayRef.h"
     20 #include "llvm/ADT/Statistic.h"
     21 #include "llvm/Analysis/ProfileDataLoader.h"
     22 #include "llvm/IR/BasicBlock.h"
     23 #include "llvm/IR/InstrTypes.h"
     24 #include "llvm/IR/LLVMContext.h"
     25 #include "llvm/IR/MDBuilder.h"
     26 #include "llvm/IR/Metadata.h"
     27 #include "llvm/IR/Module.h"
     28 #include "llvm/Pass.h"
     29 #include "llvm/Support/CFG.h"
     30 #include "llvm/Support/CommandLine.h"
     31 #include "llvm/Support/Debug.h"
     32 #include "llvm/Support/Format.h"
     33 #include "llvm/Support/raw_ostream.h"
     34 using namespace llvm;
     35 
     36 STATISTIC(NumEdgesRead, "The # of edges read.");
     37 STATISTIC(NumTermsAnnotated, "The # of terminator instructions annotated.");
     38 
     39 static cl::opt<std::string>
     40 ProfileMetadataFilename("profile-file", cl::init("llvmprof.out"),
     41                   cl::value_desc("filename"),
     42                   cl::desc("Profile file loaded by -profile-metadata-loader"));
     43 
     44 namespace {
     45   /// This pass loads profiling data from a dump file and sets branch weight
     46   /// metadata.
     47   class ProfileMetadataLoaderPass : public ModulePass {
     48     std::string Filename;
     49   public:
     50     static char ID; // Class identification, replacement for typeinfo
     51     explicit ProfileMetadataLoaderPass(const std::string &filename = "")
     52         : ModulePass(ID), Filename(filename) {
     53       initializeProfileMetadataLoaderPassPass(*PassRegistry::getPassRegistry());
     54       if (filename.empty()) Filename = ProfileMetadataFilename;
     55     }
     56 
     57     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     58       AU.setPreservesAll();
     59     }
     60 
     61     virtual const char *getPassName() const {
     62       return "Profile loader";
     63     }
     64 
     65     virtual void readEdge(unsigned, ProfileData&, ProfileData::Edge,
     66                           ArrayRef<unsigned>);
     67     virtual unsigned matchEdges(Module&, ProfileData&, ArrayRef<unsigned>);
     68     virtual void setBranchWeightMetadata(Module&, ProfileData&);
     69 
     70     virtual bool runOnModule(Module &M);
     71   };
     72 }  // End of anonymous namespace
     73 
     74 char ProfileMetadataLoaderPass::ID = 0;
     75 INITIALIZE_PASS_BEGIN(ProfileMetadataLoaderPass, "profile-metadata-loader",
     76               "Load profile information from llvmprof.out", false, true)
     77 INITIALIZE_PASS_END(ProfileMetadataLoaderPass, "profile-metadata-loader",
     78               "Load profile information from llvmprof.out", false, true)
     79 
     80 char &llvm::ProfileMetadataLoaderPassID = ProfileMetadataLoaderPass::ID;
     81 
     82 /// createProfileMetadataLoaderPass - This function returns a Pass that loads
     83 /// the profiling information for the module from the specified filename,
     84 /// making it available to the optimizers.
     85 ModulePass *llvm::createProfileMetadataLoaderPass() {
     86     return new ProfileMetadataLoaderPass();
     87 }
     88 ModulePass *llvm::createProfileMetadataLoaderPass(const std::string &Filename) {
     89   return new ProfileMetadataLoaderPass(Filename);
     90 }
     91 
     92 /// readEdge - Take the value from a profile counter and assign it to an edge.
     93 void ProfileMetadataLoaderPass::readEdge(unsigned ReadCount,
     94                                          ProfileData &PB, ProfileData::Edge e,
     95                                          ArrayRef<unsigned> Counters) {
     96   if (ReadCount >= Counters.size()) return;
     97 
     98   unsigned weight = Counters[ReadCount];
     99   assert(weight != ProfileDataLoader::Uncounted);
    100   PB.addEdgeWeight(e, weight);
    101 
    102   DEBUG(dbgs() << "-- Read Edge Counter for " << e
    103                << " (# "<< (ReadCount) << "): "
    104                << PB.getEdgeWeight(e) << "\n");
    105 }
    106 
    107 /// matchEdges - Link every profile counter with an edge.
    108 unsigned ProfileMetadataLoaderPass::matchEdges(Module &M, ProfileData &PB,
    109                                                ArrayRef<unsigned> Counters) {
    110   if (Counters.size() == 0) return 0;
    111 
    112   unsigned ReadCount = 0;
    113 
    114   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    115     if (F->isDeclaration()) continue;
    116     DEBUG(dbgs() << "Loading edges in '" << F->getName() << "'\n");
    117     readEdge(ReadCount++, PB, PB.getEdge(0, &F->getEntryBlock()), Counters);
    118     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    119       TerminatorInst *TI = BB->getTerminator();
    120       for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
    121         readEdge(ReadCount++, PB, PB.getEdge(BB,TI->getSuccessor(s)),
    122                  Counters);
    123       }
    124     }
    125   }
    126 
    127   return ReadCount;
    128 }
    129 
    130 /// setBranchWeightMetadata - Translate the counter values associated with each
    131 /// edge into branch weights for each conditional branch (a branch with 2 or
    132 /// more desinations).
    133 void ProfileMetadataLoaderPass::setBranchWeightMetadata(Module &M,
    134                                                         ProfileData &PB) {
    135   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    136     if (F->isDeclaration()) continue;
    137     DEBUG(dbgs() << "Setting branch metadata in '" << F->getName() << "'\n");
    138 
    139     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    140       TerminatorInst *TI = BB->getTerminator();
    141       unsigned NumSuccessors = TI->getNumSuccessors();
    142 
    143       // If there is only one successor then we can not set a branch
    144       // probability as the target is certain.
    145       if (NumSuccessors < 2) continue;
    146 
    147       // Load the weights of all edges leading from this terminator.
    148       DEBUG(dbgs() << "-- Terminator with " << NumSuccessors
    149                    << " successors:\n");
    150       SmallVector<uint32_t, 4> Weights(NumSuccessors);
    151       for (unsigned s = 0 ; s < NumSuccessors ; ++s) {
    152           ProfileData::Edge edge = PB.getEdge(BB, TI->getSuccessor(s));
    153           Weights[s] = (uint32_t)PB.getEdgeWeight(edge);
    154           DEBUG(dbgs() << "---- Edge '" << edge << "' has weight "
    155                        << Weights[s] << "\n");
    156       }
    157 
    158       // Set branch weight metadata.  This will set branch probabilities of
    159       // 100%/0% if that is true of the dynamic execution.
    160       // BranchProbabilityInfo can account for this when it loads this metadata
    161       // (it gives the unexectuted branch a weight of 1 for the purposes of
    162       // probability calculations).
    163       MDBuilder MDB(TI->getContext());
    164       MDNode *Node = MDB.createBranchWeights(Weights);
    165       TI->setMetadata(LLVMContext::MD_prof, Node);
    166       NumTermsAnnotated++;
    167     }
    168   }
    169 }
    170 
    171 bool ProfileMetadataLoaderPass::runOnModule(Module &M) {
    172   ProfileDataLoader PDL("profile-data-loader", Filename);
    173   ProfileData PB;
    174 
    175   ArrayRef<unsigned> Counters = PDL.getRawEdgeCounts();
    176 
    177   unsigned ReadCount = matchEdges(M, PB, Counters);
    178 
    179   if (ReadCount != Counters.size()) {
    180     errs() << "WARNING: profile information is inconsistent with "
    181            << "the current program!\n";
    182   }
    183   NumEdgesRead = ReadCount;
    184 
    185   setBranchWeightMetadata(M, PB);
    186 
    187   return ReadCount > 0;
    188 }
    189