[llvm] r195780 - Refactor some code in SampleProfile.cpp

Diego Novillo dnovillo at google.com
Tue Nov 26 12:37:34 PST 2013


Author: dnovillo
Date: Tue Nov 26 14:37:33 2013
New Revision: 195780

URL: http://llvm.org/viewvc/llvm-project?rev=195780&view=rev
Log:
Refactor some code in SampleProfile.cpp

I'm adding new functionality in the sample profiler. This will
require more data to be kept around for each function, so I moved
the structure SampleProfile that we keep for each function into
a separate class.

There are no functional changes in this patch. It simply provides
a new home where to place all the new data that I need to propagate
weights through edges.

There are some other name and minor edits throughout.

Modified:
    llvm/trunk/lib/Transforms/Scalar/SampleProfile.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/SampleProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SampleProfile.cpp?rev=195780&r1=195779&r2=195780&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SampleProfile.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SampleProfile.cpp Tue Nov 26 14:37:33 2013
@@ -54,6 +54,55 @@ static cl::opt<std::string> SampleProfil
     cl::desc("Profile file loaded by -sample-profile"), cl::Hidden);
 
 namespace {
+
+typedef DenseMap<uint32_t, uint32_t> BodySampleMap;
+typedef DenseMap<BasicBlock *, uint32_t> BlockWeightMap;
+
+/// \brief Representation of the runtime profile for a function.
+///
+/// This data structure contains the runtime profile for a given
+/// function. It contains the total number of samples collected
+/// in the function and a map of samples collected in every statement.
+class SampleFunctionProfile {
+public:
+  SampleFunctionProfile() : TotalSamples(0), TotalHeadSamples(0) {}
+
+  bool emitAnnotations(Function &F);
+  uint32_t getInstWeight(Instruction &I, unsigned FirstLineno,
+                         BodySampleMap &BodySamples);
+  uint32_t computeBlockWeight(BasicBlock *B, unsigned FirstLineno,
+                              BodySampleMap &BodySamples);
+  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);
+
+protected:
+  /// \brief Total number of samples collected inside this function.
+  ///
+  /// Samples are cumulative, they include all the samples collected
+  /// inside this function and all its inlined callees.
+  unsigned TotalSamples;
+
+  // \brief Total number of samples collected at the head of the function.
+  unsigned TotalHeadSamples;
+
+  /// \brief Map line offsets to collected samples.
+  ///
+  /// Each entry in this map contains the number of samples
+  /// collected at the corresponding line offset. All line locations
+  /// are an offset from the start of the function.
+  BodySampleMap BodySamples;
+
+  /// \brief Map basic blocks to their computed weights.
+  ///
+  /// The weight of a basic block is defined to be the maximum
+  /// of all the instruction weights in that block.
+  BlockWeightMap BlockWeights;
+};
+
 /// \brief Sample-based profile reader.
 ///
 /// Each profile contains sample counts for all the functions
@@ -77,61 +126,26 @@ namespace {
 ///   2. The samples collected at each line in F. To provide some
 ///      protection against source code shuffling, line numbers should
 ///      be relative to the start of the function.
-class SampleProfile {
+class SampleModuleProfile {
 public:
-  SampleProfile(StringRef F) : Profiles(0), Filename(F) {}
+  SampleModuleProfile(StringRef F) : Profiles(0), Filename(F) {}
 
   void dump();
   void loadText();
   void loadNative() { llvm_unreachable("not implemented"); }
-  bool emitAnnotations(Function &F);
   void printFunctionProfile(raw_ostream &OS, StringRef FName);
   void dumpFunctionProfile(StringRef FName);
+  SampleFunctionProfile &getProfile(const Function &F) {
+    return Profiles[F.getName()];
+  }
 
 protected:
-  typedef DenseMap<uint32_t, uint32_t> BodySampleMap;
-  typedef DenseMap<BasicBlock *, uint32_t> BlockWeightMap;
-
-  /// \brief Representation of the runtime profile for a function.
-  ///
-  /// This data structure contains the runtime profile for a given
-  /// function. It contains the total number of samples collected
-  /// in the function and a map of samples collected in every statement.
-  struct FunctionProfile {
-    /// \brief Total number of samples collected inside this function.
-    ///
-    /// Samples are cumulative, they include all the samples collected
-    /// inside this function and all its inlined callees.
-    unsigned TotalSamples;
-
-    // \brief Total number of samples collected at the head of the function.
-    unsigned TotalHeadSamples;
-
-    /// \brief Map line offsets to collected samples.
-    ///
-    /// Each entry in this map contains the number of samples
-    /// collected at the corresponding line offset. All line locations
-    /// are an offset from the start of the function.
-    BodySampleMap BodySamples;
-
-    /// \brief Map basic blocks to their computed weights.
-    ///
-    /// The weight of a basic block is defined to be the maximum
-    /// of all the instruction weights in that block.
-    BlockWeightMap BlockWeights;
-  };
-
-  uint32_t getInstWeight(Instruction &I, unsigned FirstLineno,
-                         BodySampleMap &BodySamples);
-  uint32_t computeBlockWeight(BasicBlock *B, unsigned FirstLineno,
-                              BodySampleMap &BodySamples);
-
   /// \brief Map every function to its associated profile.
   ///
   /// The profile of every function executed at runtime is collected
-  /// in the structure FunctionProfile. This maps function objects
+  /// in the structure SampleFunctionProfile. This maps function objects
   /// to their corresponding profiles.
-  StringMap<FunctionProfile> Profiles;
+  StringMap<SampleFunctionProfile> Profiles;
 
   /// \brief Path name to the file holding the profile data.
   ///
@@ -228,41 +242,48 @@ public:
 
 protected:
   /// \brief Profile reader object.
-  OwningPtr<SampleProfile> Profiler;
+  OwningPtr<SampleModuleProfile> Profiler;
 
   /// \brief Name of the profile file to load.
   StringRef Filename;
 };
 }
 
-/// \brief Print the function profile for \p FName on stream \p OS.
+/// \brief Print this function profile on stream \p OS.
 ///
 /// \param OS Stream to emit the output to.
-/// \param FName Name of the function to print.
-void SampleProfile::printFunctionProfile(raw_ostream &OS, StringRef FName) {
-  FunctionProfile FProfile = Profiles[FName];
-  OS << "Function: " << FName << ", " << FProfile.TotalSamples << ", "
-     << FProfile.TotalHeadSamples << ", " << FProfile.BodySamples.size()
+void SampleFunctionProfile::print(raw_ostream &OS) {
+  OS << TotalSamples << ", " << TotalHeadSamples << ", " << BodySamples.size()
      << " sampled lines\n";
-  for (BodySampleMap::const_iterator SI = FProfile.BodySamples.begin(),
-                                     SE = FProfile.BodySamples.end();
+  for (BodySampleMap::const_iterator SI = BodySamples.begin(),
+                                     SE = BodySamples.end();
        SI != SE; ++SI)
     OS << "\tline offset: " << SI->first
        << ", number of samples: " << SI->second << "\n";
   OS << "\n";
 }
 
+/// \brief Print the function profile for \p FName on stream \p OS.
+///
+/// \param OS Stream to emit the output to.
+/// \param FName Name of the function to print.
+void SampleModuleProfile::printFunctionProfile(raw_ostream &OS,
+                                               StringRef FName) {
+  OS << "Function: " << FName << ":\n";
+  Profiles[FName].print(OS);
+}
+
 /// \brief Dump the function profile for \p FName.
 ///
 /// \param FName Name of the function to print.
-void SampleProfile::dumpFunctionProfile(StringRef FName) {
+void SampleModuleProfile::dumpFunctionProfile(StringRef FName) {
   printFunctionProfile(dbgs(), FName);
 }
 
 /// \brief Dump all the function profiles found.
-void SampleProfile::dump() {
-  for (StringMap<FunctionProfile>::const_iterator I = Profiles.begin(),
-                                                  E = Profiles.end();
+void SampleModuleProfile::dump() {
+  for (StringMap<SampleFunctionProfile>::const_iterator I = Profiles.begin(),
+                                                        E = Profiles.end();
        I != E; ++I)
     dumpFunctionProfile(I->getKey());
 }
@@ -297,7 +318,7 @@ void SampleProfile::dump() {
 /// for debugging purposes, but it should not be used to generate
 /// profiles for large programs, as the representation is extremely
 /// inefficient.
-void SampleProfile::loadText() {
+void SampleModuleProfile::loadText() {
   ExternalProfileTextLoader Loader(Filename);
 
   // Read the symbol table.
@@ -308,13 +329,8 @@ void SampleProfile::loadText() {
   Line = Loader.readLine();
   if (Line.getAsInteger(10, NumSymbols))
     Loader.reportParseError("Expected a number, found " + Line);
-  for (int I = 0; I < NumSymbols; I++) {
-    StringRef FName = Loader.readLine();
-    FunctionProfile &FProfile = Profiles[FName];
-    FProfile.BodySamples.clear();
-    FProfile.TotalSamples = 0;
-    FProfile.TotalHeadSamples = 0;
-  }
+  for (int I = 0; I < NumSymbols; I++)
+    Profiles[Loader.readLine()] = SampleFunctionProfile();
 
   // Read the profile of each function. Since each function may be
   // mentioned more than once, and we are collecting flat profiles,
@@ -333,10 +349,9 @@ void SampleProfile::loadText() {
     Matches[2].getAsInteger(10, NumSamples);
     Matches[3].getAsInteger(10, NumHeadSamples);
     Matches[4].getAsInteger(10, NumSampledLines);
-    FunctionProfile &FProfile = Profiles[FName];
-    FProfile.TotalSamples += NumSamples;
-    FProfile.TotalHeadSamples += NumHeadSamples;
-    BodySampleMap &SampleMap = FProfile.BodySamples;
+    SampleFunctionProfile &FProfile = Profiles[FName];
+    FProfile.addTotalSamples(NumSamples);
+    FProfile.addHeadSamples(NumHeadSamples);
     unsigned I;
     for (I = 0; I < NumSampledLines && !Loader.atEOF(); I++) {
       Line = Loader.readLine();
@@ -346,7 +361,7 @@ void SampleProfile::loadText() {
       unsigned LineOffset, NumSamples;
       Matches[1].getAsInteger(10, LineOffset);
       Matches[2].getAsInteger(10, NumSamples);
-      SampleMap[LineOffset] += NumSamples;
+      FProfile.addBodySamples(LineOffset, NumSamples);
     }
 
     if (I < NumSampledLines)
@@ -354,6 +369,24 @@ void SampleProfile::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
@@ -367,8 +400,9 @@ void SampleProfile::loadText() {
 /// \param BodySamples Map of relative source line locations to samples.
 ///
 /// \returns The profiled weight of I.
-uint32_t SampleProfile::getInstWeight(Instruction &Inst, unsigned FirstLineno,
-                                      BodySampleMap &BodySamples) {
+uint32_t SampleFunctionProfile::getInstWeight(Instruction &Inst,
+                                              unsigned FirstLineno,
+                                              BodySampleMap &BodySamples) {
   unsigned LOffset = Inst.getDebugLoc().getLine() - FirstLineno + 1;
   return BodySamples.lookup(LOffset);
 }
@@ -385,13 +419,12 @@ uint32_t SampleProfile::getInstWeight(In
 ///     function.
 ///
 /// \returns The computed weight of B.
-uint32_t SampleProfile::computeBlockWeight(BasicBlock *B, unsigned FirstLineno,
-                                           BodySampleMap &BodySamples) {
+uint32_t SampleFunctionProfile::computeBlockWeight(BasicBlock *B,
+                                                   unsigned FirstLineno,
+                                                   BodySampleMap &BodySamples) {
   // If we've computed B's weight before, return it.
-  Function *F = B->getParent();
-  FunctionProfile &FProfile = Profiles[F->getName()];
   std::pair<BlockWeightMap::iterator, bool> Entry =
-      FProfile.BlockWeights.insert(std::make_pair(B, 0));
+      BlockWeights.insert(std::make_pair(B, 0));
   if (!Entry.second)
     return Entry.first->second;
 
@@ -420,14 +453,13 @@ uint32_t SampleProfile::computeBlockWeig
 /// metadata on B using the computed values.
 ///
 /// \param F The function to query.
-bool SampleProfile::emitAnnotations(Function &F) {
+bool SampleFunctionProfile::emitAnnotations(Function &F) {
   bool Changed = false;
-  FunctionProfile &FProfile = Profiles[F.getName()];
   unsigned FirstLineno = inst_begin(F)->getDebugLoc().getLine();
   MDBuilder MDB(F.getContext());
 
   // Clear the block weights cache.
-  FProfile.BlockWeights.clear();
+  BlockWeights.clear();
 
   // 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.
@@ -443,8 +475,7 @@ bool SampleProfile::emitAnnotations(Func
     unsigned NSuccs = TI->getNumSuccessors();
     for (unsigned I = 0; I < NSuccs; ++I) {
       BasicBlock *Succ = TI->getSuccessor(I);
-      uint32_t Weight =
-          computeBlockWeight(Succ, FirstLineno, FProfile.BodySamples);
+      uint32_t Weight = computeBlockWeight(Succ, FirstLineno, BodySamples);
       Weights.push_back(Weight);
     }
 
@@ -456,24 +487,6 @@ bool SampleProfile::emitAnnotations(Func
   return Changed;
 }
 
-char SampleProfileLoader::ID = 0;
-INITIALIZE_PASS(SampleProfileLoader, "sample-profile", "Sample Profile loader",
-                false, false)
-
 bool SampleProfileLoader::runOnFunction(Function &F) {
-  return Profiler->emitAnnotations(F);
-}
-
-bool SampleProfileLoader::doInitialization(Module &M) {
-  Profiler.reset(new SampleProfile(Filename));
-  Profiler->loadText();
-  return true;
-}
-
-FunctionPass *llvm::createSampleProfileLoaderPass() {
-  return new SampleProfileLoader(SampleProfileFile);
-}
-
-FunctionPass *llvm::createSampleProfileLoaderPass(StringRef Name) {
-  return new SampleProfileLoader(Name);
+  return Profiler->getProfile(F).emitAnnotations(F);
 }





More information about the llvm-commits mailing list