[llvm-commits] [llvm] r78199 - in /llvm/trunk: include/llvm/Analysis/ProfileInfoLoader.h lib/Analysis/ProfileInfoLoader.cpp lib/Analysis/ProfileInfoLoaderPass.cpp tools/llvm-prof/llvm-prof.cpp

Daniel Dunbar daniel at zuster.org
Wed Aug 5 08:56:11 PDT 2009


Author: ddunbar
Date: Wed Aug  5 10:55:56 2009
New Revision: 78199

URL: http://llvm.org/viewvc/llvm-project?rev=78199&view=rev
Log:
Remove unnecessary ProfileInfoLoader methods.
 - Part of optimal static profiling patch sequence by Andreas Neustifter.

Modified:
    llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h
    llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp
    llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp
    llvm/trunk/tools/llvm-prof/llvm-prof.cpp

Modified: llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h?rev=78199&r1=78198&r2=78199&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h (original)
+++ llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h Wed Aug  5 10:55:56 2009
@@ -27,6 +27,7 @@
 class BasicBlock;
 
 class ProfileInfoLoader {
+  const std::string &Filename;
   Module &M;
   std::vector<std::string> CommandLines;
   std::vector<unsigned>    FunctionCounts;
@@ -43,46 +44,28 @@
   unsigned getNumExecutions() const { return CommandLines.size(); }
   const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
 
-  // getFunctionCounts - This method is used by consumers of function counting
-  // information.  If we do not directly have function count information, we
-  // compute it from other, more refined, types of profile information.
-  //
-  void getFunctionCounts(std::vector<std::pair<Function*, unsigned> > &Counts);
+  const std::string &getFileName() const { return Filename; }
 
-  // hasAccurateBlockCounts - Return true if we can synthesize accurate block
-  // frequency information from whatever we have.
+  // getRawFunctionCounts - This method is used by consumers of function
+  // counting information.
   //
-  bool hasAccurateBlockCounts() const {
-    return !BlockCounts.empty() || !EdgeCounts.empty();
+  const std::vector<unsigned> &getRawFunctionCounts() const {
+    return FunctionCounts;
   }
 
-  // hasAccurateEdgeCounts - Return true if we can synthesize accurate edge
-  // frequency information from whatever we have.
+  // getRawBlockCounts - This method is used by consumers of block counting
+  // information.
   //
-  bool hasAccurateEdgeCounts() const {
-    return !EdgeCounts.empty();
+  const std::vector<unsigned> &getRawBlockCounts() const {
+    return BlockCounts;
   }
 
-  // getBlockCounts - This method is used by consumers of block counting
-  // information.  If we do not directly have block count information, we
-  // compute it from other, more refined, types of profile information.
-  //
-  void getBlockCounts(std::vector<std::pair<BasicBlock*, unsigned> > &Counts);
-
   // getEdgeCounts - This method is used by consumers of edge counting
-  // information.  If we do not directly have edge count information, we compute
-  // it from other, more refined, types of profile information.
-  //
-  // Edges are represented as a pair, where the first element is the basic block
-  // and the second element is the successor number.
-  //
-  typedef std::pair<BasicBlock*, unsigned> Edge;
-  void getEdgeCounts(std::vector<std::pair<Edge, unsigned> > &Counts);
-
-  // getBBTrace - This method is used by consumers of basic-block trace
   // information.
   //
-  void getBBTrace(std::vector<BasicBlock *> &Trace);
+  const std::vector<unsigned> &getRawEdgeCounts() const {
+    return EdgeCounts;
+  }
 };
 
 } // End llvm namespace

Modified: llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp?rev=78199&r1=78198&r2=78199&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp (original)
+++ llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp Wed Aug  5 10:55:56 2009
@@ -73,8 +73,9 @@
 //
 ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
                                      const std::string &Filename,
-                                     Module &TheModule) : 
-                              M(TheModule), Warned(false) {
+                                     Module &TheModule) :
+                                     Filename(Filename), 
+                                     M(TheModule), Warned(false) {
   FILE *F = fopen(Filename.c_str(), "r");
   if (F == 0) {
     cerr << ToolName << ": Error opening '" << Filename << "': ";
@@ -139,139 +140,3 @@
   fclose(F);
 }
 
-
-// getFunctionCounts - This method is used by consumers of function counting
-// information.  If we do not directly have function count information, we
-// compute it from other, more refined, types of profile information.
-//
-void ProfileInfoLoader::getFunctionCounts(std::vector<std::pair<Function*,
-                                                      unsigned> > &Counts) {
-  if (FunctionCounts.empty()) {
-    if (hasAccurateBlockCounts()) {
-      // Synthesize function frequency information from the number of times
-      // their entry blocks were executed.
-      std::vector<std::pair<BasicBlock*, unsigned> > BlockCounts;
-      getBlockCounts(BlockCounts);
-
-      for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i)
-        if (&BlockCounts[i].first->getParent()->getEntryBlock() ==
-            BlockCounts[i].first)
-          Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(),
-                                          BlockCounts[i].second));
-    } else {
-      cerr << "Function counts are not available!\n";
-    }
-    return;
-  }
-
-  unsigned Counter = 0;
-  for (Module::iterator I = M.begin(), E = M.end();
-       I != E && Counter != FunctionCounts.size(); ++I)
-    if (!I->isDeclaration())
-      Counts.push_back(std::make_pair(I, FunctionCounts[Counter++]));
-}
-
-// getBlockCounts - This method is used by consumers of block counting
-// information.  If we do not directly have block count information, we
-// compute it from other, more refined, types of profile information.
-//
-void ProfileInfoLoader::getBlockCounts(std::vector<std::pair<BasicBlock*,
-                                                         unsigned> > &Counts) {
-  if (BlockCounts.empty()) {
-    if (hasAccurateEdgeCounts()) {
-      // Synthesize block count information from edge frequency information.
-      // The block execution frequency is equal to the sum of the execution
-      // frequency of all outgoing edges from a block.
-      //
-      // If a block has no successors, this will not be correct, so we have to
-      // special case it. :(
-      std::vector<std::pair<Edge, unsigned> > EdgeCounts;
-      getEdgeCounts(EdgeCounts);
-
-      std::map<BasicBlock*, unsigned> InEdgeFreqs;
-
-      BasicBlock *LastBlock = 0;
-      TerminatorInst *TI = 0;
-      for (unsigned i = 0, e = EdgeCounts.size(); i != e; ++i) {
-        if (EdgeCounts[i].first.first != LastBlock) {
-          LastBlock = EdgeCounts[i].first.first;
-          TI = LastBlock->getTerminator();
-          Counts.push_back(std::make_pair(LastBlock, 0));
-        }
-        Counts.back().second += EdgeCounts[i].second;
-        unsigned SuccNum = EdgeCounts[i].first.second;
-        if (SuccNum >= TI->getNumSuccessors()) {
-          if (!Warned) {
-            cerr << "WARNING: profile info doesn't seem to match"
-                 << " the program!\n";
-            Warned = true;
-          }
-        } else {
-          // If this successor has no successors of its own, we will never
-          // compute an execution count for that block.  Remember the incoming
-          // edge frequencies to add later.
-          BasicBlock *Succ = TI->getSuccessor(SuccNum);
-          if (Succ->getTerminator()->getNumSuccessors() == 0)
-            InEdgeFreqs[Succ] += EdgeCounts[i].second;
-        }
-      }
-
-      // Now we have to accumulate information for those blocks without
-      // successors into our table.
-      for (std::map<BasicBlock*, unsigned>::iterator I = InEdgeFreqs.begin(),
-             E = InEdgeFreqs.end(); I != E; ++I) {
-        unsigned i = 0;
-        for (; i != Counts.size() && Counts[i].first != I->first; ++i)
-          /*empty*/;
-        if (i == Counts.size()) Counts.push_back(std::make_pair(I->first, 0));
-        Counts[i].second += I->second;
-      }
-
-    } else {
-      cerr << "Block counts are not available!\n";
-    }
-    return;
-  }
-
-  unsigned Counter = 0;
-  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
-    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
-      Counts.push_back(std::make_pair(BB, BlockCounts[Counter++]));
-      if (Counter == BlockCounts.size())
-        return;
-    }
-}
-
-// getEdgeCounts - This method is used by consumers of edge counting
-// information.  If we do not directly have edge count information, we compute
-// it from other, more refined, types of profile information.
-//
-void ProfileInfoLoader::getEdgeCounts(std::vector<std::pair<Edge,
-                                                  unsigned> > &Counts) {
-  if (EdgeCounts.empty()) {
-    cerr << "Edge counts not available, and no synthesis "
-         << "is implemented yet!\n";
-    return;
-  }
-
-  unsigned Counter = 0;
-  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
-    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
-      for (unsigned i = 0, e = BB->getTerminator()->getNumSuccessors();
-           i != e; ++i) {
-        Counts.push_back(std::make_pair(Edge(BB, i), EdgeCounts[Counter++]));
-        if (Counter == EdgeCounts.size())
-          return;
-      }
-}
-
-// getBBTrace - This method is used by consumers of basic-block trace
-// information.
-//
-void ProfileInfoLoader::getBBTrace(std::vector<BasicBlock *> &Trace) {
-  if (BBTrace.empty ()) {
-    cerr << "Basic block trace is not available!\n";
-    return;
-  }
-  cerr << "Basic block trace loading is not implemented yet!\n";
-}

Modified: llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp?rev=78199&r1=78198&r2=78199&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp (original)
+++ llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp Wed Aug  5 10:55:56 2009
@@ -14,6 +14,7 @@
 
 #include "llvm/BasicBlock.h"
 #include "llvm/InstrTypes.h"
+#include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Analysis/ProfileInfo.h"
@@ -69,23 +70,25 @@
 bool LoaderPass::runOnModule(Module &M) {
   ProfileInfoLoader PIL("profile-loader", Filename, M);
   EdgeCounts.clear();
-  bool PrintedWarning = false;
 
-  std::vector<std::pair<ProfileInfoLoader::Edge, unsigned> > ECs;
-  PIL.getEdgeCounts(ECs);
-  for (unsigned i = 0, e = ECs.size(); i != e; ++i) {
-    BasicBlock *BB = ECs[i].first.first;
-    unsigned SuccNum = ECs[i].first.second;
-    TerminatorInst *TI = BB->getTerminator();
-    if (SuccNum >= TI->getNumSuccessors()) {
-      if (!PrintedWarning) {
-        cerr << "WARNING: profile information is inconsistent with "
-             << "the current program!\n";
-        PrintedWarning = true;
+  std::vector<unsigned> ECs = PIL.getRawEdgeCounts();
+  // Instrument all of the edges...
+  unsigned i = 0;
+  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
+    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
+      // Okay, we have to add a counter of each outgoing edge.  If the
+      // outgoing edge is not critical don't split it, just insert the counter
+      // in the source or destination of the edge.
+      TerminatorInst *TI = BB->getTerminator();
+      for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
+        if (i < ECs.size())
+          EdgeCounts[std::make_pair(BB, TI->getSuccessor(s))]+= ECs[i++];
       }
-    } else {
-      EdgeCounts[std::make_pair(BB, TI->getSuccessor(SuccNum))]+= ECs[i].second;
     }
+ 
+  if (i != ECs.size()) {
+    cerr << "WARNING: profile information is inconsistent with "
+         << "the current program!\n";
   }
 
   return false;

Modified: llvm/trunk/tools/llvm-prof/llvm-prof.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-prof/llvm-prof.cpp?rev=78199&r1=78198&r2=78199&view=diff

==============================================================================
--- llvm/trunk/tools/llvm-prof/llvm-prof.cpp (original)
+++ llvm/trunk/tools/llvm-prof/llvm-prof.cpp Wed Aug  5 10:55:56 2009
@@ -20,6 +20,7 @@
 #include "llvm/Assembly/AsmAnnotationWriter.h"
 #include "llvm/Analysis/ProfileInfo.h"
 #include "llvm/Analysis/ProfileInfoLoader.h"
+#include "llvm/Analysis/Passes.h"
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ManagedStatic.h"
@@ -67,48 +68,38 @@
 
 namespace {
   class ProfileAnnotator : public AssemblyAnnotationWriter {
-    std::map<const Function  *, unsigned> &FuncFreqs;
-    std::map<const BasicBlock*, unsigned> &BlockFreqs;
-    std::map<ProfileInfoLoader::Edge, unsigned> &EdgeFreqs;
+    ProfileInfo &PI;
   public:
-    ProfileAnnotator(std::map<const Function  *, unsigned> &FF,
-                     std::map<const BasicBlock*, unsigned> &BF,
-                     std::map<ProfileInfoLoader::Edge, unsigned> &EF)
-      : FuncFreqs(FF), BlockFreqs(BF), EdgeFreqs(EF) {}
+    ProfileAnnotator(ProfileInfo& pi) : PI(pi) {}
 
     virtual void emitFunctionAnnot(const Function *F, raw_ostream &OS) {
-      OS << ";;; %" << F->getName() << " called " << FuncFreqs[F]
+      OS << ";;; %" << F->getName() << " called " << PI.getExecutionCount(F)
          << " times.\n;;;\n";
     }
     virtual void emitBasicBlockStartAnnot(const BasicBlock *BB,
                                           raw_ostream &OS) {
-      if (BlockFreqs.empty()) return;
-      std::map<const BasicBlock *, unsigned>::const_iterator I =
-        BlockFreqs.find(BB);
-      if (I != BlockFreqs.end())
-        OS << "\t;;; Basic block executed " << I->second << " times.\n";
+      unsigned w = PI.getExecutionCount(BB);
+      if (w != 0)
+        OS << "\t;;; Basic block executed " << w << " times.\n";
       else
         OS << "\t;;; Never executed!\n";
     }
 
     virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, raw_ostream &OS) {
-      if (EdgeFreqs.empty()) return;
-
       // Figure out how many times each successor executed.
-      std::vector<std::pair<const BasicBlock*, unsigned> > SuccCounts;
-      const TerminatorInst *TI = BB->getTerminator();
+      std::vector<std::pair<ProfileInfo::Edge, unsigned> > SuccCounts;
 
-      std::map<ProfileInfoLoader::Edge, unsigned>::iterator I =
-        EdgeFreqs.lower_bound(std::make_pair(const_cast<BasicBlock*>(BB), 0U));
-      for (; I != EdgeFreqs.end() && I->first.first == BB; ++I)
-        if (I->second)
-          SuccCounts.push_back(std::make_pair(TI->getSuccessor(I->first.second),
-                                              I->second));
+      const TerminatorInst *TI = BB->getTerminator();
+      for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
+        BasicBlock* Succ = TI->getSuccessor(s);
+        SuccCounts.push_back(std::make_pair(std::make_pair(BB,Succ),
+                                            PI.getEdgeWeight(BB,Succ)));
+      }
       if (!SuccCounts.empty()) {
         OS << "\t;;; Out-edge counts:";
         for (unsigned i = 0, e = SuccCounts.size(); i != e; ++i)
-          OS << " [" << SuccCounts[i].second << " -> "
-             << SuccCounts[i].first->getName() << "]";
+          OS << " [" << (SuccCounts[i]).second << " -> "
+             << (SuccCounts[i]).first.second->getName() << "]";
         OS << "\n";
       }
     }
@@ -139,17 +130,26 @@
 char ProfileInfoPrinterPass::ID = 0;
 
 bool ProfileInfoPrinterPass::runOnModule(Module &M) {
+  ProfileInfo &PI = getAnalysis<ProfileInfo>();
   std::map<const Function  *, unsigned> FuncFreqs;
   std::map<const BasicBlock*, unsigned> BlockFreqs;
-  std::map<ProfileInfoLoader::Edge, unsigned> EdgeFreqs;
+  std::map<ProfileInfo::Edge, unsigned> EdgeFreqs;
 
   // Output a report. Eventually, there will be multiple reports selectable on
   // the command line, for now, just keep things simple.
 
   // Emit the most frequent function table...
   std::vector<std::pair<Function*, unsigned> > FunctionCounts;
-  PIL.getFunctionCounts(FunctionCounts);
-  FuncFreqs.insert(FunctionCounts.begin(), FunctionCounts.end());
+  std::vector<std::pair<BasicBlock*, unsigned> > Counts;
+  for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
+    unsigned w = PI.getExecutionCount(FI);
+    if (w != (unsigned) -1)
+      FunctionCounts.push_back(std::make_pair(FI,PI.getExecutionCount(FI)));
+    for (Function::iterator BB = FI->begin(), BBE = FI->end(); 
+         BB != BBE; ++BB) {
+      Counts.push_back(std::make_pair(BB,PI.getExecutionCount(BB)));
+    }
+  }
 
   // Sort by the frequency, backwards.
   sort(FunctionCounts.begin(), FunctionCounts.end(),
@@ -190,54 +190,39 @@
 
   std::set<Function*> FunctionsToPrint;
 
-  // If we have block count information, print out the LLVM module with
-  // frequency annotations.
-  if (PIL.hasAccurateBlockCounts()) {
-    std::vector<std::pair<BasicBlock*, unsigned> > Counts;
-    PIL.getBlockCounts(Counts);
-
-    TotalExecutions = 0;
-    for (unsigned i = 0, e = Counts.size(); i != e; ++i)
-      TotalExecutions += Counts[i].second;
-
-    // Sort by the frequency, backwards.
-    sort(Counts.begin(), Counts.end(),
-              PairSecondSortReverse<BasicBlock*>());
-
-    std::cout << "\n===" << std::string(73, '-') << "===\n";
-    std::cout << "Top 20 most frequently executed basic blocks:\n\n";
-
-    // Print out the function frequencies...
-    std::cout <<" ##      %% \tFrequency\n";
-    unsigned BlocksToPrint = Counts.size();
-    if (BlocksToPrint > 20) BlocksToPrint = 20;
-    for (unsigned i = 0; i != BlocksToPrint; ++i) {
-      if (Counts[i].second == 0) break;
-      Function *F = Counts[i].first->getParent();
-      std::cout << std::setw(3) << i+1 << ". " 
-        << std::setw(5) << std::setprecision(2) 
-        << Counts[i].second/(double)TotalExecutions*100 << "% "
-        << std::setw(5) << Counts[i].second << "/"
-        << TotalExecutions << "\t"
-        << F->getNameStr() << "() - "
-        << Counts[i].first->getNameStr() << "\n";
-      FunctionsToPrint.insert(F);
-    }
-
-    BlockFreqs.insert(Counts.begin(), Counts.end());
-  }
-
-  if (PIL.hasAccurateEdgeCounts()) {
-    std::vector<std::pair<ProfileInfoLoader::Edge, unsigned> > Counts;
-    PIL.getEdgeCounts(Counts);
-    EdgeFreqs.insert(Counts.begin(), Counts.end());
+  TotalExecutions = 0;
+  for (unsigned i = 0, e = Counts.size(); i != e; ++i)
+    TotalExecutions += Counts[i].second;
+  
+  // Sort by the frequency, backwards.
+  sort(Counts.begin(), Counts.end(),
+       PairSecondSortReverse<BasicBlock*>());
+  
+  std::cout << "\n===" << std::string(73, '-') << "===\n";
+  std::cout << "Top 20 most frequently executed basic blocks:\n\n";
+  
+  // Print out the function frequencies...
+  std::cout <<" ##      %% \tFrequency\n";
+  unsigned BlocksToPrint = Counts.size();
+  if (BlocksToPrint > 20) BlocksToPrint = 20;
+  for (unsigned i = 0; i != BlocksToPrint; ++i) {
+    if (Counts[i].second == 0) break;
+    Function *F = Counts[i].first->getParent();
+    std::cout << std::setw(3) << i+1 << ". " 
+              << std::setw(5) << std::setprecision(2) 
+              << Counts[i].second/(double)TotalExecutions*100 << "% "
+              << std::setw(5) << Counts[i].second << "/"
+              << TotalExecutions << "\t"
+              << F->getNameStr() << "() - "
+              << Counts[i].first->getNameStr() << "\n";
+    FunctionsToPrint.insert(F);
   }
 
   if (PrintAnnotatedLLVM || PrintAllCode) {
     std::cout << "\n===" << std::string(73, '-') << "===\n";
     std::cout << "Annotated LLVM code for the module:\n\n";
-
-    ProfileAnnotator PA(FuncFreqs, BlockFreqs, EdgeFreqs);
+  
+    ProfileAnnotator PA(PI);
 
     if (FunctionsToPrint.empty() || PrintAllCode)
       M.print(std::cout, &PA);





More information about the llvm-commits mailing list