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