r206658 - CodeGen: Use LLVM's InstrProfReader in -fprofile-instr-use=

Justin Bogner mail at justinbogner.com
Fri Apr 18 14:52:01 PDT 2014


Author: bogner
Date: Fri Apr 18 16:52:00 2014
New Revision: 206658

URL: http://llvm.org/viewvc/llvm-project?rev=206658&view=rev
Log:
CodeGen: Use LLVM's InstrProfReader in -fprofile-instr-use=

Update clang to use the InstrProfReader from LLVM to read
instrumentation based profile data. This also switches us from the
naive text format to the binary format, since that's what's
implemented in the reader.

Modified:
    cfe/trunk/lib/CodeGen/CMakeLists.txt
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
    cfe/trunk/lib/CodeGen/CodeGenPGO.h
    cfe/trunk/tools/driver/CMakeLists.txt
    cfe/trunk/tools/driver/Makefile

Modified: cfe/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CMakeLists.txt?rev=206658&r1=206657&r2=206658&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ cfe/trunk/lib/CodeGen/CMakeLists.txt Fri Apr 18 16:52:00 2014
@@ -9,6 +9,7 @@ set(LLVM_LINK_COMPONENTS
   Linker
   MC
   ObjCARCOpts
+  ProfileData
   ScalarOpts
   Support
   Target

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=206658&r1=206657&r2=206658&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Apr 18 16:52:00 2014
@@ -47,6 +47,7 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
+#include "llvm/ProfileData/InstrProfReader.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -78,7 +79,7 @@ CodeGenModule::CodeGenModule(ASTContext
       ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(0),
       TheTargetCodeGenInfo(0), Types(*this), VTables(*this), ObjCRuntime(0),
       OpenCLRuntime(0), CUDARuntime(0), DebugInfo(0), ARCData(0),
-      NoObjCARCExceptionsMetadata(0), RRData(0), PGOData(0),
+      NoObjCARCExceptionsMetadata(0), RRData(0), PGOReader(nullptr),
       CFConstantStringClassRef(0),
       ConstantStringClassRef(0), NSConstantStringType(0),
       NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssign(0),
@@ -134,8 +135,14 @@ CodeGenModule::CodeGenModule(ASTContext
     ARCData = new ARCEntrypoints();
   RRData = new RREntrypoints();
 
-  if (!CodeGenOpts.InstrProfileInput.empty())
-    PGOData = new PGOProfileData(*this, CodeGenOpts.InstrProfileInput);
+  if (!CodeGenOpts.InstrProfileInput.empty()) {
+    if (llvm::error_code EC = llvm::IndexedInstrProfReader::create(
+            CodeGenOpts.InstrProfileInput, PGOReader)) {
+      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+                                              "Could not read profile: %0");
+      getDiags().Report(DiagID) << EC.message();
+    }
+  }
 }
 
 CodeGenModule::~CodeGenModule() {
@@ -286,7 +293,7 @@ void CodeGenModule::Release() {
   if (getCodeGenOpts().ProfileInstrGenerate)
     if (llvm::Function *PGOInit = CodeGenPGO::emitInitialization(*this))
       AddGlobalCtor(PGOInit, 0);
-  if (PGOData && PGOStats.isOutOfDate())
+  if (PGOReader && PGOStats.isOutOfDate())
     getDiags().Report(diag::warn_profile_data_out_of_date)
         << PGOStats.Visited << PGOStats.Missing << PGOStats.Mismatched;
   EmitCtorList(GlobalCtors, "llvm.global_ctors");

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=206658&r1=206657&r2=206658&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Apr 18 16:52:00 2014
@@ -42,6 +42,7 @@ namespace llvm {
   class DataLayout;
   class FunctionType;
   class LLVMContext;
+  class IndexedInstrProfReader;
 }
 
 namespace clang {
@@ -85,7 +86,6 @@ namespace CodeGen {
   class CGCUDARuntime;
   class BlockFieldFlags;
   class FunctionArgList;
-  class PGOProfileData;
 
   struct OrderGlobalInits {
     unsigned int priority;
@@ -266,7 +266,7 @@ class CodeGenModule : public CodeGenType
   ARCEntrypoints *ARCData;
   llvm::MDNode *NoObjCARCExceptionsMetadata;
   RREntrypoints *RRData;
-  PGOProfileData *PGOData;
+  std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader;
   InstrProfStats PGOStats;
 
   // WeakRefReferences - A set of references that have only been seen via
@@ -493,13 +493,8 @@ public:
     return *RRData;
   }
 
-  InstrProfStats &getPGOStats() {
-    return PGOStats;
-  }
-
-  PGOProfileData *getPGOData() const {
-    return PGOData;
-  }
+  InstrProfStats &getPGOStats() { return PGOStats; }
+  llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
 
   llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {
     return StaticLocalDeclMap[D];

Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=206658&r1=206657&r2=206658&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Fri Apr 18 16:52:00 2014
@@ -17,6 +17,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "llvm/Config/config.h" // for strtoull()/strtoul() define
 #include "llvm/IR/MDBuilder.h"
+#include "llvm/ProfileData/InstrProfReader.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MD5.h"
@@ -24,136 +25,6 @@
 using namespace clang;
 using namespace CodeGen;
 
-static void ReportBadPGOData(CodeGenModule &CGM, const char *Message) {
-  DiagnosticsEngine &Diags = CGM.getDiags();
-  unsigned diagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0");
-  Diags.Report(diagID) << Message;
-}
-
-PGOProfileData::PGOProfileData(CodeGenModule &CGM, std::string Path)
-  : CGM(CGM) {
-  if (llvm::MemoryBuffer::getFile(Path, DataBuffer)) {
-    ReportBadPGOData(CGM, "failed to open pgo data file");
-    return;
-  }
-
-  if (DataBuffer->getBufferSize() > std::numeric_limits<unsigned>::max()) {
-    ReportBadPGOData(CGM, "pgo data file too big");
-    return;
-  }
-
-  // Scan through the data file and map each function to the corresponding
-  // file offset where its counts are stored.
-  const char *BufferStart = DataBuffer->getBufferStart();
-  const char *BufferEnd = DataBuffer->getBufferEnd();
-  const char *CurPtr = BufferStart;
-  uint64_t MaxCount = 0;
-  while (CurPtr < BufferEnd) {
-    // Read the function name.
-    const char *FuncStart = CurPtr;
-    // For Objective-C methods, the name may include whitespace, so search
-    // backward from the end of the line to find the space that separates the
-    // name from the number of counters. (This is a temporary hack since we are
-    // going to completely replace this file format in the near future.)
-    CurPtr = strchr(CurPtr, '\n');
-    if (!CurPtr) {
-      ReportBadPGOData(CGM, "pgo data file has malformed function entry");
-      return;
-    }
-    StringRef FuncName(FuncStart, CurPtr - FuncStart);
-
-    // Skip over the function hash.
-    CurPtr = strchr(++CurPtr, '\n');
-    if (!CurPtr) {
-      ReportBadPGOData(CGM, "pgo data file is missing the function hash");
-      return;
-    }
-
-    // Read the number of counters.
-    char *EndPtr;
-    unsigned NumCounters = strtoul(++CurPtr, &EndPtr, 10);
-    if (EndPtr == CurPtr || *EndPtr != '\n' || NumCounters <= 0) {
-      ReportBadPGOData(CGM, "pgo data file has unexpected number of counters");
-      return;
-    }
-    CurPtr = EndPtr;
-
-    // Read function count.
-    uint64_t Count = strtoull(CurPtr, &EndPtr, 10);
-    if (EndPtr == CurPtr || *EndPtr != '\n') {
-      ReportBadPGOData(CGM, "pgo-data file has bad count value");
-      return;
-    }
-    CurPtr = EndPtr; // Point to '\n'.
-    FunctionCounts[FuncName] = Count;
-    MaxCount = Count > MaxCount ? Count : MaxCount;
-
-    // There is one line for each counter; skip over those lines.
-    // Since function count is already read, we start the loop from 1.
-    for (unsigned N = 1; N < NumCounters; ++N) {
-      CurPtr = strchr(++CurPtr, '\n');
-      if (!CurPtr) {
-        ReportBadPGOData(CGM, "pgo data file is missing some counter info");
-        return;
-      }
-    }
-
-    // Skip over the blank line separating functions.
-    CurPtr += 2;
-
-    DataOffsets[FuncName] = FuncStart - BufferStart;
-  }
-  MaxFunctionCount = MaxCount;
-}
-
-bool PGOProfileData::getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
-                                       std::vector<uint64_t> &Counts) {
-  // Find the relevant section of the pgo-data file.
-  llvm::StringMap<unsigned>::const_iterator OffsetIter =
-    DataOffsets.find(FuncName);
-  if (OffsetIter == DataOffsets.end())
-    return true;
-  const char *CurPtr = DataBuffer->getBufferStart() + OffsetIter->getValue();
-
-  // Skip over the function name.
-  CurPtr = strchr(CurPtr, '\n');
-  assert(CurPtr && "pgo-data has corrupted function entry");
-
-  char *EndPtr;
-  // Read the function hash.
-  FuncHash = strtoull(++CurPtr, &EndPtr, 10);
-  assert(EndPtr != CurPtr && *EndPtr == '\n' &&
-         "pgo-data file has corrupted function hash");
-  CurPtr = EndPtr;
-
-  // Read the number of counters.
-  unsigned NumCounters = strtoul(++CurPtr, &EndPtr, 10);
-  assert(EndPtr != CurPtr && *EndPtr == '\n' && NumCounters > 0 &&
-         "pgo-data file has corrupted number of counters");
-  CurPtr = EndPtr;
-
-  Counts.reserve(NumCounters);
-
-  for (unsigned N = 0; N < NumCounters; ++N) {
-    // Read the count value.
-    uint64_t Count = strtoull(CurPtr, &EndPtr, 10);
-    if (EndPtr == CurPtr || *EndPtr != '\n') {
-      ReportBadPGOData(CGM, "pgo-data file has bad count value");
-      return true;
-    }
-    Counts.push_back(Count);
-    CurPtr = EndPtr + 1;
-  }
-
-  // Make sure the number of counters matches up.
-  if (Counts.size() != NumCounters) {
-    ReportBadPGOData(CGM, "pgo-data file has inconsistent counters");
-    return true;
-  }
-
-  return false;
-}
-
 void CodeGenPGO::setFuncName(llvm::Function *Fn) {
   RawFuncName = Fn->getName();
 
@@ -930,8 +801,8 @@ static void emitRuntimeHook(CodeGenModul
 
 void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
   bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
-  PGOProfileData *PGOData = CGM.getPGOData();
-  if (!InstrumentRegions && !PGOData)
+  llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
+  if (!InstrumentRegions && !PGOReader)
     return;
   if (!D)
     return;
@@ -957,10 +828,10 @@ void CodeGenPGO::assignRegionCounters(co
     emitRuntimeHook(CGM);
     emitCounterVariables();
   }
-  if (PGOData) {
-    loadRegionCounts(PGOData);
+  if (PGOReader) {
+    loadRegionCounts(PGOReader);
     computeRegionCounts(D);
-    applyFunctionAttributes(PGOData, Fn);
+    applyFunctionAttributes(PGOReader, Fn);
   }
 }
 
@@ -992,12 +863,13 @@ void CodeGenPGO::computeRegionCounts(con
     Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
 }
 
-void CodeGenPGO::applyFunctionAttributes(PGOProfileData *PGOData,
-                                         llvm::Function *Fn) {
+void
+CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
+                                    llvm::Function *Fn) {
   if (!haveRegionCounts())
     return;
 
-  uint64_t MaxFunctionCount = PGOData->getMaximumFunctionCount();
+  uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
   uint64_t FunctionCount = getRegionCount(0);
   if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
     // Turn on InlineHint attribute for hot functions.
@@ -1031,11 +903,11 @@ void CodeGenPGO::emitCounterIncrement(CG
   Builder.CreateStore(Count, Addr);
 }
 
-void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) {
+void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader) {
   CGM.getPGOStats().Visited++;
   RegionCounts.reset(new std::vector<uint64_t>);
   uint64_t Hash;
-  if (PGOData->getFunctionCounts(getFuncName(), Hash, *RegionCounts)) {
+  if (PGOReader->getFunctionCounts(getFuncName(), Hash, *RegionCounts)) {
     CGM.getPGOStats().Missing++;
     RegionCounts.reset();
   } else if (Hash != FunctionHash ||

Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=206658&r1=206657&r2=206658&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.h Fri Apr 18 16:52:00 2014
@@ -26,28 +26,6 @@ namespace clang {
 namespace CodeGen {
 class RegionCounter;
 
-/// The raw counter data from an instrumented PGO binary
-class PGOProfileData {
-private:
-  /// The PGO data
-  std::unique_ptr<llvm::MemoryBuffer> DataBuffer;
-  /// Offsets into DataBuffer for each function's counters
-  llvm::StringMap<unsigned> DataOffsets;
-  /// Execution counts for each function.
-  llvm::StringMap<uint64_t> FunctionCounts;
-  /// The maximal execution count among all functions.
-  uint64_t MaxFunctionCount;
-  CodeGenModule &CGM;
-public:
-  PGOProfileData(CodeGenModule &CGM, std::string Path);
-  /// Fill Counts with the profile data for the given function name. Returns
-  /// false on success.
-  bool getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
-                         std::vector<uint64_t> &Counts);
-  /// Return the maximum of all known function counts.
-  uint64_t getMaximumFunctionCount() { return MaxFunctionCount; }
-};
-
 /// Per-function PGO state. This class should generally not be used directly,
 /// but instead through the CodeGenFunction and RegionCounter types.
 class CodeGenPGO {
@@ -138,8 +116,9 @@ private:
   void setFuncName(llvm::Function *Fn);
   void mapRegionCounters(const Decl *D);
   void computeRegionCounts(const Decl *D);
-  void applyFunctionAttributes(PGOProfileData *PGOData, llvm::Function *Fn);
-  void loadRegionCounts(PGOProfileData *PGOData);
+  void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
+                               llvm::Function *Fn);
+  void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader);
   void emitCounterVariables();
   llvm::GlobalVariable *buildDataVar();
 

Modified: cfe/trunk/tools/driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/CMakeLists.txt?rev=206658&r1=206657&r2=206658&view=diff
==============================================================================
--- cfe/trunk/tools/driver/CMakeLists.txt (original)
+++ cfe/trunk/tools/driver/CMakeLists.txt Fri Apr 18 16:52:00 2014
@@ -10,6 +10,7 @@ set( LLVM_LINK_COMPONENTS
   MCParser
   ObjCARCOpts
   Option
+  ProfileData
   ScalarOpts
   Support
   TransformUtils

Modified: cfe/trunk/tools/driver/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/Makefile?rev=206658&r1=206657&r2=206658&view=diff
==============================================================================
--- cfe/trunk/tools/driver/Makefile (original)
+++ cfe/trunk/tools/driver/Makefile Fri Apr 18 16:52:00 2014
@@ -33,7 +33,7 @@ endif
 
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
                    instrumentation ipo irreader linker objcarcopts option \
-                   selectiondag
+                   profiledata selectiondag
 USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
            clangSerialization.a clangCodeGen.a clangParse.a clangSema.a
 





More information about the cfe-commits mailing list