diff options
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SampleProfile.cpp | 672 | 
1 files changed, 605 insertions, 67 deletions
| diff --git a/llvm/lib/Transforms/Scalar/SampleProfile.cpp b/llvm/lib/Transforms/Scalar/SampleProfile.cpp index 170a070aa5a..e3d290194cf 100644 --- a/llvm/lib/Transforms/Scalar/SampleProfile.cpp +++ b/llvm/lib/Transforms/Scalar/SampleProfile.cpp @@ -26,9 +26,14 @@  #include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallPtrSet.h"  #include "llvm/ADT/StringMap.h"  #include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/DIContext.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/PostDominators.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/DebugInfo.h"  #include "llvm/IR/Constants.h"  #include "llvm/IR/Function.h"  #include "llvm/IR/Instructions.h" @@ -52,11 +57,19 @@ using namespace llvm;  static cl::opt<std::string> SampleProfileFile(      "sample-profile-file", cl::init(""), cl::value_desc("filename"),      cl::desc("Profile file loaded by -sample-profile"), cl::Hidden); +static cl::opt<unsigned> SampleProfileMaxPropagateIterations( +    "sample-profile-max-propagate-iterations", cl::init(100), +    cl::desc("Maximum number of iterations to go through when propagating " +             "sample block/edge weights through the CFG."));  namespace {  typedef DenseMap<uint32_t, uint32_t> BodySampleMap;  typedef DenseMap<BasicBlock *, uint32_t> BlockWeightMap; +typedef DenseMap<BasicBlock *, BasicBlock *> EquivalenceClassMap; +typedef std::pair<BasicBlock *, BasicBlock *> Edge; +typedef DenseMap<Edge, uint32_t> EdgeWeightMap; +typedef DenseMap<BasicBlock *, SmallVector<BasicBlock *, 8> > BlockEdgeMap;  /// \brief Representation of the runtime profile for a function.  /// @@ -65,19 +78,34 @@ typedef DenseMap<BasicBlock *, uint32_t> BlockWeightMap;  /// in the function and a map of samples collected in every statement.  class SampleFunctionProfile {  public: -  SampleFunctionProfile() : TotalSamples(0), TotalHeadSamples(0) {} +  SampleFunctionProfile() +      : TotalSamples(0), TotalHeadSamples(0), HeaderLineno(0), DT(0), PDT(0), +        LI(0) {} -  bool emitAnnotations(Function &F); -  uint32_t getInstWeight(Instruction &I, unsigned FirstLineno, -                         BodySampleMap &BodySamples); -  uint32_t computeBlockWeight(BasicBlock *B, unsigned FirstLineno, -                              BodySampleMap &BodySamples); +  unsigned getFunctionLoc(Function &F); +  bool emitAnnotations(Function &F, DominatorTree *DomTree, +                       PostDominatorTree *PostDomTree, LoopInfo *Loops); +  uint32_t getInstWeight(Instruction &I); +  uint32_t getBlockWeight(BasicBlock *B);    void addTotalSamples(unsigned Num) { TotalSamples += Num; }    void addHeadSamples(unsigned Num) { TotalHeadSamples += Num; }    void addBodySamples(unsigned LineOffset, unsigned Num) {      BodySamples[LineOffset] += Num;    }    void print(raw_ostream &OS); +  void printEdgeWeight(raw_ostream &OS, Edge E); +  void printBlockWeight(raw_ostream &OS, BasicBlock *BB); +  void printBlockEquivalence(raw_ostream &OS, BasicBlock *BB); +  bool computeBlockWeights(Function &F); +  void findEquivalenceClasses(Function &F); +  void findEquivalencesFor(BasicBlock *BB1, +                           SmallVector<BasicBlock *, 8> Descendants, +                           DominatorTreeBase<BasicBlock> *DomTree); +  void propagateWeights(Function &F); +  uint32_t visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge); +  void buildEdges(Function &F); +  bool propagateThroughEdges(Function &F); +  bool empty() { return BodySamples.empty(); }  protected:    /// \brief Total number of samples collected inside this function. @@ -86,9 +114,15 @@ protected:    /// inside this function and all its inlined callees.    unsigned TotalSamples; -  // \brief Total number of samples collected at the head of the function. +  /// \brief Total number of samples collected at the head of the function.    unsigned TotalHeadSamples; +  /// \brief Line number for the function header. Used to compute relative +  /// line numbers from the absolute line LOCs found in instruction locations. +  /// The relative line numbers are needed to address the samples from the +  /// profile file. +  unsigned HeaderLineno; +    /// \brief Map line offsets to collected samples.    ///    /// Each entry in this map contains the number of samples @@ -101,6 +135,37 @@ protected:    /// The weight of a basic block is defined to be the maximum    /// of all the instruction weights in that block.    BlockWeightMap BlockWeights; + +  /// \brief Map edges to their computed weights. +  /// +  /// Edge weights are computed by propagating basic block weights in +  /// SampleProfile::propagateWeights. +  EdgeWeightMap EdgeWeights; + +  /// \brief Set of visited blocks during propagation. +  SmallPtrSet<BasicBlock *, 128> VisitedBlocks; + +  /// \brief Set of visited edges during propagation. +  SmallSet<Edge, 128> VisitedEdges; + +  /// \brief Equivalence classes for block weights. +  /// +  /// Two blocks BB1 and BB2 are in the same equivalence class if they +  /// dominate and post-dominate each other, and they are in the same loop +  /// nest. When this happens, the two blocks are guaranteed to execute +  /// the same number of times. +  EquivalenceClassMap EquivalenceClass; + +  /// \brief Dominance, post-dominance and loop information. +  DominatorTree *DT; +  PostDominatorTree *PDT; +  LoopInfo *LI; + +  /// \brief Predecessors for each basic block in the CFG. +  BlockEdgeMap Predecessors; + +  /// \brief Successors for each basic block in the CFG. +  BlockEdgeMap Successors;  };  /// \brief Sample-based profile reader. @@ -238,6 +303,9 @@ public:    virtual void getAnalysisUsage(AnalysisUsage &AU) const {      AU.setPreservesCFG(); +    AU.addRequired<LoopInfo>(); +    AU.addRequired<DominatorTree>(); +    AU.addRequired<PostDominatorTree>();    }  protected: @@ -263,6 +331,34 @@ void SampleFunctionProfile::print(raw_ostream &OS) {    OS << "\n";  } +/// \brief Print the weight of edge \p E on stream \p OS. +/// +/// \param OS  Stream to emit the output to. +/// \param E  Edge to print. +void SampleFunctionProfile::printEdgeWeight(raw_ostream &OS, Edge E) { +  OS << "weight[" << E.first->getName() << "->" << E.second->getName() +     << "]: " << EdgeWeights[E] << "\n"; +} + +/// \brief Print the equivalence class of block \p BB on stream \p OS. +/// +/// \param OS  Stream to emit the output to. +/// \param BB  Block to print. +void SampleFunctionProfile::printBlockEquivalence(raw_ostream &OS, +                                                  BasicBlock *BB) { +  BasicBlock *Equiv = EquivalenceClass[BB]; +  OS << "equivalence[" << BB->getName() +     << "]: " << ((Equiv) ? EquivalenceClass[BB]->getName() : "NONE") << "\n"; +} + +/// \brief Print the weight of block \p BB on stream \p OS. +/// +/// \param OS  Stream to emit the output to. +/// \param BB  Block to print. +void SampleFunctionProfile::printBlockWeight(raw_ostream &OS, BasicBlock *BB) { +  OS << "weight[" << BB->getName() << "]: " << BlockWeights[BB] << "\n"; +} +  /// \brief Print the function profile for \p FName on stream \p OS.  ///  /// \param OS Stream to emit the output to. @@ -361,6 +457,12 @@ void SampleModuleProfile::loadText() {        unsigned LineOffset, NumSamples;        Matches[1].getAsInteger(10, LineOffset);        Matches[2].getAsInteger(10, NumSamples); +      // When dealing with instruction weights, we use the value +      // zero to indicate the absence of a sample. If we read an +      // actual zero from the profile file, return it as 1 to +      // avoid the confusion later on. +      if (NumSamples == 0) +        NumSamples = 1;        FProfile.addBodySamples(LineOffset, NumSamples);      } @@ -369,59 +471,39 @@ void SampleModuleProfile::loadText() {    }  } -char SampleProfileLoader::ID = 0; -INITIALIZE_PASS(SampleProfileLoader, "sample-profile", "Sample Profile loader", -                false, false) - -bool SampleProfileLoader::doInitialization(Module &M) { -  Profiler.reset(new SampleModuleProfile(Filename)); -  Profiler->loadText(); -  return true; -} - -FunctionPass *llvm::createSampleProfileLoaderPass() { -  return new SampleProfileLoader(SampleProfileFile); -} - -FunctionPass *llvm::createSampleProfileLoaderPass(StringRef Name) { -  return new SampleProfileLoader(Name); -} -  /// \brief Get the weight for an instruction.  ///  /// The "weight" of an instruction \p Inst is the number of samples  /// collected on that instruction at runtime. To retrieve it, we  /// need to compute the line number of \p Inst relative to the start of its -/// function. We use \p FirstLineno to compute the offset. We then -/// look up the samples collected for \p Inst using \p BodySamples. +/// function. We use HeaderLineno to compute the offset. We then +/// look up the samples collected for \p Inst using BodySamples.  ///  /// \param Inst Instruction to query. -/// \param FirstLineno Line number of the first instruction in the function. -/// \param BodySamples Map of relative source line locations to samples.  ///  /// \returns The profiled weight of I. -uint32_t SampleFunctionProfile::getInstWeight(Instruction &Inst, -                                              unsigned FirstLineno, -                                              BodySampleMap &BodySamples) { -  unsigned LOffset = Inst.getDebugLoc().getLine() - FirstLineno + 1; -  return BodySamples.lookup(LOffset); +uint32_t SampleFunctionProfile::getInstWeight(Instruction &Inst) { +  unsigned Lineno = Inst.getDebugLoc().getLine(); +  if (Lineno < HeaderLineno) +    return 0; +  unsigned LOffset = Lineno - HeaderLineno; +  uint32_t Weight = BodySamples.lookup(LOffset); +  DEBUG(dbgs() << "    " << Lineno << ":" << Inst.getDebugLoc().getCol() << ":" +               << Inst << " (line offset: " << LOffset +               << " - weight: " << Weight << ")\n"); +  return Weight;  }  /// \brief Compute the weight of a basic block.  ///  /// The weight of basic block \p B is the maximum weight of all the -/// instructions in B. +/// instructions in B. The weight of \p B is computed and cached in +/// the BlockWeights map.  ///  /// \param B The basic block to query. -/// \param FirstLineno The line number for the first line in the -///     function holding B. -/// \param BodySamples The map containing all the samples collected in that -///     function.  ///  /// \returns The computed weight of B. -uint32_t SampleFunctionProfile::computeBlockWeight(BasicBlock *B, -                                                   unsigned FirstLineno, -                                                   BodySampleMap &BodySamples) { +uint32_t SampleFunctionProfile::getBlockWeight(BasicBlock *B) {    // If we've computed B's weight before, return it.    std::pair<BlockWeightMap::iterator, bool> Entry =        BlockWeights.insert(std::make_pair(B, 0)); @@ -431,7 +513,7 @@ uint32_t SampleFunctionProfile::computeBlockWeight(BasicBlock *B,    // Otherwise, compute and cache B's weight.    uint32_t Weight = 0;    for (BasicBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) { -    uint32_t InstWeight = getInstWeight(*I, FirstLineno, BodySamples); +    uint32_t InstWeight = getInstWeight(*I);      if (InstWeight > Weight)        Weight = InstWeight;    } @@ -439,30 +521,344 @@ uint32_t SampleFunctionProfile::computeBlockWeight(BasicBlock *B,    return Weight;  } -/// \brief Generate branch weight metadata for all branches in \p F. +/// \brief Compute and store the weights of every basic block. +/// +/// This populates the BlockWeights map by computing +/// the weights of every basic block in the CFG.  /// -/// For every branch instruction B in \p F, we compute the weight of the -/// target block for each of the edges out of B. This is the weight -/// that we associate with that branch. +/// \param F The function to query. +bool SampleFunctionProfile::computeBlockWeights(Function &F) { +  bool Changed = false; +  DEBUG(dbgs() << "Block weights\n"); +  for (Function::iterator B = F.begin(), E = F.end(); B != E; ++B) { +    uint32_t Weight = getBlockWeight(B); +    Changed |= (Weight > 0); +    DEBUG(printBlockWeight(dbgs(), B)); +  } + +  return Changed; +} + +/// \brief Find equivalence classes for the given block.  /// -/// TODO - This weight assignment will most likely be wrong if the -/// target branch has more than two predecessors. This needs to be done -/// using some form of flow propagation. +/// This finds all the blocks that are guaranteed to execute the same +/// number of times as \p BB1. To do this, it traverses all the the +/// descendants of \p BB1 in the dominator or post-dominator tree.  /// -/// Once all the branch weights are computed, we emit the MD_prof -/// metadata on B using the computed values. +/// A block BB2 will be in the same equivalence class as \p BB1 if +/// the following holds: +/// +/// 1- \p BB1 is a descendant of BB2 in the opposite tree. So, if BB2 +///    is a descendant of \p BB1 in the dominator tree, then BB2 should +///    dominate BB1 in the post-dominator tree. +/// +/// 2- Both BB2 and \p BB1 must be in the same loop. +/// +/// For every block BB2 that meets those two requirements, we set BB2's +/// equivalence class to \p BB1. +/// +/// \param BB1  Block to check. +/// \param Descendants  Descendants of \p BB1 in either the dom or pdom tree. +/// \param DomTree  Opposite dominator tree. If \p Descendants is filled +///                 with blocks from \p BB1's dominator tree, then +///                 this is the post-dominator tree, and vice versa. +void SampleFunctionProfile::findEquivalencesFor( +    BasicBlock *BB1, SmallVector<BasicBlock *, 8> Descendants, +    DominatorTreeBase<BasicBlock> *DomTree) { +  for (SmallVectorImpl<BasicBlock *>::iterator I = Descendants.begin(), +                                               E = Descendants.end(); +       I != E; ++I) { +    BasicBlock *BB2 = *I; +    bool IsDomParent = DomTree->dominates(BB2, BB1); +    bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2); +    if (BB1 != BB2 && VisitedBlocks.insert(BB2) && IsDomParent && +        IsInSameLoop) { +      EquivalenceClass[BB2] = BB1; + +      // If BB2 is heavier than BB1, make BB2 have the same weight +      // as BB1. +      // +      // Note that we don't worry about the opposite situation here +      // (when BB2 is lighter than BB1). We will deal with this +      // during the propagation phase. Right now, we just want to +      // make sure that BB1 has the largest weight of all the +      // members of its equivalence set. +      uint32_t &BB1Weight = BlockWeights[BB1]; +      uint32_t &BB2Weight = BlockWeights[BB2]; +      BB1Weight = std::max(BB1Weight, BB2Weight); +    } +  } +} + +/// \brief Find equivalence classes. +/// +/// Since samples may be missing from blocks, we can fill in the gaps by setting +/// the weights of all the blocks in the same equivalence class to the same +/// weight. To compute the concept of equivalence, we use dominance and loop +/// information. Two blocks B1 and B2 are in the same equivalence class if B1 +/// dominates B2, B2 post-dominates B1 and both are in the same loop.  ///  /// \param F The function to query. -bool SampleFunctionProfile::emitAnnotations(Function &F) { +void SampleFunctionProfile::findEquivalenceClasses(Function &F) { +  SmallVector<BasicBlock *, 8> DominatedBBs; +  DEBUG(dbgs() << "\nBlock equivalence classes\n"); +  // Find equivalence sets based on dominance and post-dominance information. +  for (Function::iterator B = F.begin(), E = F.end(); B != E; ++B) { +    BasicBlock *BB1 = B; + +    // Compute BB1's equivalence class once. +    if (EquivalenceClass.count(BB1)) { +      DEBUG(printBlockEquivalence(dbgs(), BB1)); +      continue; +    } + +    // By default, blocks are in their own equivalence class. +    EquivalenceClass[BB1] = BB1; + +    // Traverse all the blocks dominated by BB1. We are looking for +    // every basic block BB2 such that: +    // +    // 1- BB1 dominates BB2. +    // 2- BB2 post-dominates BB1. +    // 3- BB1 and BB2 are in the same loop nest. +    // +    // If all those conditions hold, it means that BB2 is executed +    // as many times as BB1, so they are placed in the same equivalence +    // class by making BB2's equivalence class be BB1. +    DominatedBBs.clear(); +    DT->getDescendants(BB1, DominatedBBs); +    findEquivalencesFor(BB1, DominatedBBs, PDT->DT); + +    // Repeat the same logic for all the blocks post-dominated by BB1. +    // We are looking for every basic block BB2 such that: +    // +    // 1- BB1 post-dominates BB2. +    // 2- BB2 dominates BB1. +    // 3- BB1 and BB2 are in the same loop nest. +    // +    // If all those conditions hold, BB2's equivalence class is BB1. +    DominatedBBs.clear(); +    PDT->getDescendants(BB1, DominatedBBs); +    findEquivalencesFor(BB1, DominatedBBs, DT->DT); + +    DEBUG(printBlockEquivalence(dbgs(), BB1)); +  } + +  // Assign weights to equivalence classes. +  // +  // All the basic blocks in the same equivalence class will execute +  // the same number of times. Since we know that the head block in +  // each equivalence class has the largest weight, assign that weight +  // to all the blocks in that equivalence class. +  DEBUG(dbgs() << "\nAssign the same weight to all blocks in the same class\n"); +  for (Function::iterator B = F.begin(), E = F.end(); B != E; ++B) { +    BasicBlock *BB = B; +    BasicBlock *EquivBB = EquivalenceClass[BB]; +    if (BB != EquivBB) +      BlockWeights[BB] = BlockWeights[EquivBB]; +    DEBUG(printBlockWeight(dbgs(), BB)); +  } +} + +/// \brief Visit the given edge to decide if it has a valid weight. +/// +/// If \p E has not been visited before, we copy to \p UnknownEdge +/// and increment the count of unknown edges. +/// +/// \param E  Edge to visit. +/// \param NumUnknownEdges  Current number of unknown edges. +/// \param UnknownEdge  Set if E has not been visited before. +/// +/// \returns E's weight, if known. Otherwise, return 0. +uint32_t SampleFunctionProfile::visitEdge(Edge E, unsigned *NumUnknownEdges, +                                          Edge *UnknownEdge) { +  if (!VisitedEdges.count(E)) { +    (*NumUnknownEdges)++; +    *UnknownEdge = E; +    return 0; +  } + +  return EdgeWeights[E]; +} + +/// \brief Propagate weights through incoming/outgoing edges. +/// +/// If the weight of a basic block is known, and there is only one edge +/// with an unknown weight, we can calculate the weight of that edge. +/// +/// Similarly, if all the edges have a known count, we can calculate the +/// count of the basic block, if needed. +/// +/// \param F  Function to process. +/// +/// \returns  True if new weights were assigned to edges or blocks. +bool SampleFunctionProfile::propagateThroughEdges(Function &F) {    bool Changed = false; -  unsigned FirstLineno = inst_begin(F)->getDebugLoc().getLine(); -  MDBuilder MDB(F.getContext()); +  DEBUG(dbgs() << "\nPropagation through edges\n"); +  for (Function::iterator BI = F.begin(), EI = F.end(); BI != EI; ++BI) { +    BasicBlock *BB = BI; + +    // Visit all the predecessor and successor edges to determine +    // which ones have a weight assigned already. Note that it doesn't +    // matter that we only keep track of a single unknown edge. The +    // only case we are interested in handling is when only a single +    // edge is unknown (see setEdgeOrBlockWeight). +    for (unsigned i = 0; i < 2; i++) { +      uint32_t TotalWeight = 0; +      unsigned NumUnknownEdges = 0; +      Edge UnknownEdge, SelfReferentialEdge; + +      if (i == 0) { +        // First, visit all predecessor edges. +        for (size_t I = 0; I < Predecessors[BB].size(); I++) { +          Edge E = std::make_pair(Predecessors[BB][I], BB); +          TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge); +          if (E.first == E.second) +            SelfReferentialEdge = E; +        } +      } else { +        // On the second round, visit all successor edges. +        for (size_t I = 0; I < Successors[BB].size(); I++) { +          Edge E = std::make_pair(BB, Successors[BB][I]); +          TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge); +        } +      } + +      // After visiting all the edges, there are three cases that we +      // can handle immediately: +      // +      // - All the edge weights are known (i.e., NumUnknownEdges == 0). +      //   In this case, we simply check that the sum of all the edges +      //   is the same as BB's weight. If not, we change BB's weight +      //   to match. Additionally, if BB had not been visited before, +      //   we mark it visited. +      // +      // - Only one edge is unknown and BB has already been visited. +      //   In this case, we can compute the weight of the edge by +      //   subtracting the total block weight from all the known +      //   edge weights. If the edges weight more than BB, then the +      //   edge of the last remaining edge is set to zero. +      // +      // - There exists a self-referential edge and the weight of BB is +      //   known. In this case, this edge can be based on BB's weight. +      //   We add up all the other known edges and set the weight on +      //   the self-referential edge as we did in the previous case. +      // +      // In any other case, we must continue iterating. Eventually, +      // all edges will get a weight, or iteration will stop when +      // it reaches SampleProfileMaxPropagateIterations. +      if (NumUnknownEdges <= 1) { +        uint32_t &BBWeight = BlockWeights[BB]; +        if (NumUnknownEdges == 0) { +          // If we already know the weight of all edges, the weight of the +          // basic block can be computed. It should be no larger than the sum +          // of all edge weights. +          if (TotalWeight > BBWeight) { +            BBWeight = TotalWeight; +            Changed = true; +            DEBUG(dbgs() << "All edge weights for " << BB->getName() +                         << " known. Set weight for block: "; +                  printBlockWeight(dbgs(), BB);); +          } +          if (VisitedBlocks.insert(BB)) +            Changed = true; +        } else if (NumUnknownEdges == 1 && VisitedBlocks.count(BB)) { +          // If there is a single unknown edge and the block has been +          // visited, then we can compute E's weight. +          if (BBWeight >= TotalWeight) +            EdgeWeights[UnknownEdge] = BBWeight - TotalWeight; +          else +            EdgeWeights[UnknownEdge] = 0; +          VisitedEdges.insert(UnknownEdge); +          Changed = true; +          DEBUG(dbgs() << "Set weight for edge: "; +                printEdgeWeight(dbgs(), UnknownEdge)); +        } +      } else if (SelfReferentialEdge.first && VisitedBlocks.count(BB)) { +        uint32_t &BBWeight = BlockWeights[BB]; +        // We have a self-referential edge and the weight of BB is known. +        if (BBWeight >= TotalWeight) +          EdgeWeights[SelfReferentialEdge] = BBWeight - TotalWeight; +        else +          EdgeWeights[SelfReferentialEdge] = 0; +        VisitedEdges.insert(SelfReferentialEdge); +        Changed = true; +        DEBUG(dbgs() << "Set self-referential edge weight to: "; +              printEdgeWeight(dbgs(), SelfReferentialEdge)); +      } +    } +  } + +  return Changed; +} + +/// \brief Build in/out edge lists for each basic block in the CFG. +/// +/// We are interested in unique edges. If a block B1 has multiple +/// edges to another block B2, we only add a single B1->B2 edge. +void SampleFunctionProfile::buildEdges(Function &F) { +  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { +    BasicBlock *B1 = I; + +    // Add predecessors for B1. +    SmallPtrSet<BasicBlock *, 16> Visited; +    if (!Predecessors[B1].empty()) +      llvm_unreachable("Found a stale predecessors list in a basic block."); +    for (pred_iterator PI = pred_begin(B1), PE = pred_end(B1); PI != PE; ++PI) { +      BasicBlock *B2 = *PI; +      if (Visited.insert(B2)) +        Predecessors[B1].push_back(B2); +    } + +    // Add successors for B1. +    Visited.clear(); +    if (!Successors[B1].empty()) +      llvm_unreachable("Found a stale successors list in a basic block."); +    for (succ_iterator SI = succ_begin(B1), SE = succ_end(B1); SI != SE; ++SI) { +      BasicBlock *B2 = *SI; +      if (Visited.insert(B2)) +        Successors[B1].push_back(B2); +    } +  } +} + +/// \brief Propagate weights into edges +/// +/// The following rules are applied to every block B in the CFG: +/// +/// - If B has a single predecessor/successor, then the weight +///   of that edge is the weight of the block. +/// +/// - If all incoming or outgoing edges are known except one, and the +///   weight of the block is already known, the weight of the unknown +///   edge will be the weight of the block minus the sum of all the known +///   edges. If the sum of all the known edges is larger than B's weight, +///   we set the unknown edge weight to zero. +/// +/// - If there is a self-referential edge, and the weight of the block is +///   known, the weight for that edge is set to the weight of the block +///   minus the weight of the other incoming edges to that block (if +///   known). +void SampleFunctionProfile::propagateWeights(Function &F) { +  bool Changed = true; +  unsigned i = 0; -  // Clear the block weights cache. -  BlockWeights.clear(); +  // Before propagation starts, build, for each block, a list of +  // unique predecessors and successors. This is necessary to handle +  // identical edges in multiway branches. Since we visit all blocks and all +  // edges of the CFG, it is cleaner to build these lists once at the start +  // of the pass. +  buildEdges(F); -  // When we find a branch instruction: For each edge E out of the branch, -  // the weight of E is the weight of the target block. +  // Propagate until we converge or we go past the iteration limit. +  while (Changed && i++ < SampleProfileMaxPropagateIterations) { +    Changed = propagateThroughEdges(F); +  } + +  // Generate MD_prof metadata for every branch instruction using the +  // edge weights computed during propagation. +  DEBUG(dbgs() << "\nPropagation complete. Setting branch weights\n"); +  MDBuilder MDB(F.getContext());    for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {      BasicBlock *B = I;      TerminatorInst *TI = B->getTerminator(); @@ -471,22 +867,164 @@ bool SampleFunctionProfile::emitAnnotations(Function &F) {      if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI))        continue; +    DEBUG(dbgs() << "\nGetting weights for branch at line " +                 << TI->getDebugLoc().getLine() << ":" +                 << TI->getDebugLoc().getCol() << ".\n");      SmallVector<uint32_t, 4> Weights; -    unsigned NSuccs = TI->getNumSuccessors(); -    for (unsigned I = 0; I < NSuccs; ++I) { +    bool AllWeightsZero = true; +    for (unsigned I = 0; I < TI->getNumSuccessors(); ++I) {        BasicBlock *Succ = TI->getSuccessor(I); -      uint32_t Weight = computeBlockWeight(Succ, FirstLineno, BodySamples); +      Edge E = std::make_pair(B, Succ); +      uint32_t Weight = EdgeWeights[E]; +      DEBUG(dbgs() << "\t"; printEdgeWeight(dbgs(), E));        Weights.push_back(Weight); +      if (Weight != 0) +        AllWeightsZero = false; +    } + +    // Only set weights if there is at least one non-zero weight. +    // In any other case, let the analyzer set weights. +    if (!AllWeightsZero) { +      DEBUG(dbgs() << "SUCCESS. Found non-zero weights.\n"); +      TI->setMetadata(llvm::LLVMContext::MD_prof, +                      MDB.createBranchWeights(Weights)); +    } else { +      DEBUG(dbgs() << "SKIPPED. All branch weights are zero.\n"); +    } +  } +} + +/// \brief Get the line number for the function header. +/// +/// This looks up function \p F in the current compilation unit and +/// retrieves the line number where the function is defined. This is +/// line 0 for all the samples read from the profile file. Every line +/// number is relative to this line. +/// +/// \param F  Function object to query. +/// +/// \returns the line number where \p F is defined. +unsigned SampleFunctionProfile::getFunctionLoc(Function &F) { +  NamedMDNode *CUNodes = F.getParent()->getNamedMetadata("llvm.dbg.cu"); +  if (CUNodes) { +    for (unsigned I = 0, E1 = CUNodes->getNumOperands(); I != E1; ++I) { +      DICompileUnit CU(CUNodes->getOperand(I)); +      DIArray Subprograms = CU.getSubprograms(); +      for (unsigned J = 0, E2 = Subprograms.getNumElements(); J != E2; ++J) { +        DISubprogram Subprogram(Subprograms.getElement(J)); +        if (Subprogram.describes(&F)) +          return Subprogram.getLineNumber(); +      }      } +  } + +  report_fatal_error("No debug information found in function " + F.getName() + +                     "\n"); +} + +/// \brief Generate branch weight metadata for all branches in \p F. +/// +/// Branch weights are computed out of instruction samples using a +/// propagation heuristic. Propagation proceeds in 3 phases: +/// +/// 1- Assignment of block weights. All the basic blocks in the function +///    are initial assigned the same weight as their most frequently +///    executed instruction. +/// +/// 2- Creation of equivalence classes. Since samples may be missing from +///    blocks, we can fill in the gaps by setting the weights of all the +///    blocks in the same equivalence class to the same weight. To compute +///    the concept of equivalence, we use dominance and loop information. +///    Two blocks B1 and B2 are in the same equivalence class if B1 +///    dominates B2, B2 post-dominates B1 and both are in the same loop. +/// +/// 3- Propagation of block weights into edges. This uses a simple +///    propagation heuristic. The following rules are applied to every +///    block B in the CFG: +/// +///    - If B has a single predecessor/successor, then the weight +///      of that edge is the weight of the block. +/// +///    - If all the edges are known except one, and the weight of the +///      block is already known, the weight of the unknown edge will +///      be the weight of the block minus the sum of all the known +///      edges. If the sum of all the known edges is larger than B's weight, +///      we set the unknown edge weight to zero. +/// +///    - If there is a self-referential edge, and the weight of the block is +///      known, the weight for that edge is set to the weight of the block +///      minus the weight of the other incoming edges to that block (if +///      known). +/// +/// Since this propagation is not guaranteed to finalize for every CFG, we +/// only allow it to proceed for a limited number of iterations (controlled +/// by -sample-profile-max-propagate-iterations). +/// +/// FIXME: Try to replace this propagation heuristic with a scheme +/// that is guaranteed to finalize. A work-list approach similar to +/// the standard value propagation algorithm used by SSA-CCP might +/// work here. +/// +/// Once all the branch weights are computed, we emit the MD_prof +/// metadata on B using the computed values for each of its branches. +/// +/// \param F The function to query. +bool SampleFunctionProfile::emitAnnotations(Function &F, DominatorTree *DomTree, +                                            PostDominatorTree *PostDomTree, +                                            LoopInfo *Loops) { +  bool Changed = false; -    TI->setMetadata(llvm::LLVMContext::MD_prof, -                    MDB.createBranchWeights(Weights)); -    Changed = true; +  // Initialize invariants used during computation and propagation. +  HeaderLineno = getFunctionLoc(F); +  DEBUG(dbgs() << "Line number for the first instruction in " << F.getName() +               << ": " << HeaderLineno << "\n"); +  DT = DomTree; +  PDT = PostDomTree; +  LI = Loops; + +  // Compute basic block weights. +  Changed |= computeBlockWeights(F); + +  if (Changed) { +    // Find equivalence classes. +    findEquivalenceClasses(F); + +    // Propagate weights to all edges. +    propagateWeights(F);    }    return Changed;  } +char SampleProfileLoader::ID = 0; +INITIALIZE_PASS_BEGIN(SampleProfileLoader, "sample-profile", +                      "Sample Profile loader", false, false) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_END(SampleProfileLoader, "sample-profile", +                    "Sample Profile loader", false, false) + +bool SampleProfileLoader::doInitialization(Module &M) { +  Profiler.reset(new SampleModuleProfile(Filename)); +  Profiler->loadText(); +  return true; +} + +FunctionPass *llvm::createSampleProfileLoaderPass() { +  return new SampleProfileLoader(SampleProfileFile); +} + +FunctionPass *llvm::createSampleProfileLoaderPass(StringRef Name) { +  return new SampleProfileLoader(Name); +} +  bool SampleProfileLoader::runOnFunction(Function &F) { -  return Profiler->getProfile(F).emitAnnotations(F); +  DominatorTree *DT = &getAnalysis<DominatorTree>(); +  PostDominatorTree *PDT = &getAnalysis<PostDominatorTree>(); +  LoopInfo *LI = &getAnalysis<LoopInfo>(); +  SampleFunctionProfile &FunctionProfile = Profiler->getProfile(F); +  if (!FunctionProfile.empty()) +    return FunctionProfile.emitAnnotations(F, DT, PDT, LI); +  return false;  } | 

