r203712 - Revert "CodeGen: Use a binary format for instrumentation based profiling"
Justin Bogner
mail at justinbogner.com
Wed Mar 12 14:06:32 PDT 2014
Author: bogner
Date: Wed Mar 12 16:06:31 2014
New Revision: 203712
URL: http://llvm.org/viewvc/llvm-project?rev=203712&view=rev
Log:
Revert "CodeGen: Use a binary format for instrumentation based profiling"
I've clearly done something wrong with how to get this to link
correctly. Reverting for now.
This reverts commit r203711.
Modified:
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/test/Profile/Inputs/c-attributes.profdata
cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata
cfe/trunk/test/Profile/Inputs/c-general.profdata
cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata
cfe/trunk/test/Profile/Inputs/cxx-class.profdata
cfe/trunk/test/Profile/Inputs/cxx-throws.profdata
cfe/trunk/test/Profile/Inputs/objc-general.profdata
cfe/trunk/tools/driver/CMakeLists.txt
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Mar 12 16:06:31 2014
@@ -47,7 +47,6 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/Profile/ProfileDataReader.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
@@ -78,7 +77,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), PGOReader(nullptr),
+ NoObjCARCExceptionsMetadata(0), RRData(0), PGOData(0),
CFConstantStringClassRef(0),
ConstantStringClassRef(0), NSConstantStringType(0),
NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssign(0),
@@ -134,14 +133,8 @@ CodeGenModule::CodeGenModule(ASTContext
ARCData = new ARCEntrypoints();
RRData = new RREntrypoints();
- if (!CodeGenOpts.InstrProfileInput.empty()) {
- if (llvm::error_code EC = llvm::ProfileDataReader::create(
- CodeGenOpts.InstrProfileInput, PGOReader)) {
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "Could not read profile: %0");
- getDiags().Report(DiagID) << EC.message();
- }
- }
+ if (!CodeGenOpts.InstrProfileInput.empty())
+ PGOData = new PGOProfileData(*this, CodeGenOpts.InstrProfileInput);
}
CodeGenModule::~CodeGenModule() {
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Mar 12 16:06:31 2014
@@ -42,7 +42,6 @@ namespace llvm {
class DataLayout;
class FunctionType;
class LLVMContext;
- class ProfileDataReader;
}
namespace clang {
@@ -86,6 +85,7 @@ namespace CodeGen {
class CGCUDARuntime;
class BlockFieldFlags;
class FunctionArgList;
+ class PGOProfileData;
struct OrderGlobalInits {
unsigned int priority;
@@ -257,7 +257,7 @@ class CodeGenModule : public CodeGenType
ARCEntrypoints *ARCData;
llvm::MDNode *NoObjCARCExceptionsMetadata;
RREntrypoints *RRData;
- std::unique_ptr<llvm::ProfileDataReader> PGOReader;
+ PGOProfileData *PGOData;
// WeakRefReferences - A set of references that have only been seen via
// a weakref so far. This is used to remove the weak of the reference if we
@@ -480,8 +480,8 @@ public:
return *RRData;
}
- llvm::ProfileDataReader *getPGOReader() const {
- return PGOReader.get();
+ PGOProfileData *getPGOData() const {
+ return PGOData;
}
llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {
Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Wed Mar 12 16:06:31 2014
@@ -17,12 +17,132 @@
#include "clang/AST/StmtVisitor.h"
#include "llvm/Config/config.h" // for strtoull()/strtoll() define
#include "llvm/IR/MDBuilder.h"
-#include "llvm/Profile/ProfileDataReader.h"
#include "llvm/Support/FileSystem.h"
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;
+ }
+ while (*--CurPtr != ' ')
+ ;
+ StringRef FuncName(FuncStart, CurPtr - FuncStart);
+
+ // Read the number of counters.
+ char *EndPtr;
+ unsigned NumCounters = strtol(++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 = strtoll(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,
+ 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");
+ while (*--CurPtr != ' ')
+ ;
+
+ // Read the number of counters.
+ char *EndPtr;
+ unsigned NumCounters = strtol(++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 = strtoll(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) {
StringRef Func = Fn->getName();
@@ -57,23 +177,22 @@ void CodeGenPGO::emitWriteoutFunction()
llvm::Type *Int32Ty = llvm::Type::getInt32Ty(Ctx);
llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
- llvm::Function *AddFuncsF =
- CGM.getModule().getFunction("__llvm_pgo_add_functions");
- if (!AddFuncsF) {
- llvm::FunctionType *AddFuncsFTy =
+ llvm::Function *WriteoutF =
+ CGM.getModule().getFunction("__llvm_pgo_writeout");
+ if (!WriteoutF) {
+ llvm::FunctionType *WriteoutFTy =
llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), false);
- AddFuncsF = llvm::Function::Create(AddFuncsFTy,
+ WriteoutF = llvm::Function::Create(WriteoutFTy,
llvm::GlobalValue::InternalLinkage,
- "__llvm_pgo_add_functions",
- &CGM.getModule());
+ "__llvm_pgo_writeout", &CGM.getModule());
}
- AddFuncsF->setUnnamedAddr(true);
- AddFuncsF->addFnAttr(llvm::Attribute::NoInline);
+ WriteoutF->setUnnamedAddr(true);
+ WriteoutF->addFnAttr(llvm::Attribute::NoInline);
if (CGM.getCodeGenOpts().DisableRedZone)
- AddFuncsF->addFnAttr(llvm::Attribute::NoRedZone);
+ WriteoutF->addFnAttr(llvm::Attribute::NoRedZone);
- llvm::BasicBlock *BB = AddFuncsF->empty() ?
- llvm::BasicBlock::Create(Ctx, "", AddFuncsF) : &AddFuncsF->getEntryBlock();
+ llvm::BasicBlock *BB = WriteoutF->empty() ?
+ llvm::BasicBlock::Create(Ctx, "", WriteoutF) : &WriteoutF->getEntryBlock();
CGBuilderTy PGOBuilder(BB);
@@ -83,35 +202,32 @@ void CodeGenPGO::emitWriteoutFunction()
PGOBuilder.SetInsertPoint(I);
llvm::Type *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
- llvm::Type *Int64Ty = llvm::Type::getInt64Ty(Ctx);
llvm::Type *Args[] = {
Int8PtrTy, // const char *FuncName
- Int64Ty, // uint64_t FunctionHash
Int32Ty, // uint32_t NumCounters
Int64PtrTy // uint64_t *Counters
};
llvm::FunctionType *FTy =
llvm::FunctionType::get(PGOBuilder.getVoidTy(), Args, false);
llvm::Constant *EmitFunc =
- CGM.getModule().getOrInsertFunction("llvm_pgo_add_function", FTy);
+ CGM.getModule().getOrInsertFunction("llvm_pgo_emit", FTy);
llvm::Constant *NameString =
CGM.GetAddrOfConstantCString(getFuncName(), "__llvm_pgo_name");
NameString = llvm::ConstantExpr::getBitCast(NameString, Int8PtrTy);
- PGOBuilder.CreateCall4(EmitFunc, NameString,
- // TODO: This should be a hash, not just the count!
- PGOBuilder.getInt64(NumRegionCounters),
+ PGOBuilder.CreateCall3(EmitFunc, NameString,
PGOBuilder.getInt32(NumRegionCounters),
PGOBuilder.CreateBitCast(RegionCounters, Int64PtrTy));
}
llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
- llvm::Function *AddFuncsF =
- CGM.getModule().getFunction("__llvm_pgo_add_functions");
- if (!AddFuncsF)
+ llvm::Function *WriteoutF =
+ CGM.getModule().getFunction("__llvm_pgo_writeout");
+ if (!WriteoutF)
return NULL;
- // Create a small bit of code that initializes PGO at startup
+ // Create a small bit of code that registers the "__llvm_pgo_writeout" to
+ // be executed at exit.
llvm::Function *F = CGM.getModule().getFunction("__llvm_pgo_init");
if (F)
return NULL;
@@ -139,7 +255,7 @@ llvm::Function *CodeGenPGO::emitInitiali
// Inialize the environment and register the local writeout function.
llvm::Constant *PGOInit =
CGM.getModule().getOrInsertFunction("llvm_pgo_init", FTy);
- PGOBuilder.CreateCall(PGOInit, AddFuncsF);
+ PGOBuilder.CreateCall(PGOInit, WriteoutF);
PGOBuilder.CreateRetVoid();
return F;
@@ -642,8 +758,8 @@ namespace {
void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
- llvm::ProfileDataReader *PGOReader = CGM.getPGOReader();
- if (!InstrumentRegions && !PGOReader)
+ PGOProfileData *PGOData = CGM.getPGOData();
+ if (!InstrumentRegions && !PGOData)
return;
if (!D)
return;
@@ -651,10 +767,10 @@ void CodeGenPGO::assignRegionCounters(co
mapRegionCounters(D);
if (InstrumentRegions)
emitCounterVariables();
- if (PGOReader) {
- loadRegionCounts(PGOReader);
+ if (PGOData) {
+ loadRegionCounts(PGOData);
computeRegionCounts(D);
- applyFunctionAttributes(PGOReader, Fn);
+ applyFunctionAttributes(PGOData, Fn);
}
}
@@ -681,12 +797,12 @@ void CodeGenPGO::computeRegionCounts(con
Walker.VisitBlockDecl(BD);
}
-void CodeGenPGO::applyFunctionAttributes(llvm::ProfileDataReader *PGOReader,
+void CodeGenPGO::applyFunctionAttributes(PGOProfileData *PGOData,
llvm::Function *Fn) {
if (!haveRegionCounts())
return;
- uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
+ uint64_t MaxFunctionCount = PGOData->getMaximumFunctionCount();
uint64_t FunctionCount = getRegionCount(0);
if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
// Turn on InlineHint attribute for hot functions.
@@ -719,15 +835,13 @@ void CodeGenPGO::emitCounterIncrement(CG
Builder.CreateStore(Count, Addr);
}
-void CodeGenPGO::loadRegionCounts(llvm::ProfileDataReader *PGOReader) {
+void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) {
// For now, ignore the counts from the PGO data file only if the number of
// counters does not match. This could be tightened down in the future to
// ignore counts when the input changes in various ways, e.g., by comparing a
// hash value based on some characteristics of the input.
RegionCounts = new std::vector<uint64_t>();
- uint64_t Hash;
- // TODO: Check for hash mismatch
- if (PGOReader->getFunctionCounts(getFuncName(), Hash, *RegionCounts) ||
+ if (PGOData->getFunctionCounts(getFuncName(), *RegionCounts) ||
RegionCounts->size() != NumRegionCounters) {
delete RegionCounts;
RegionCounts = 0;
Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.h Wed Mar 12 16:06:31 2014
@@ -26,6 +26,27 @@ 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, 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 {
@@ -115,9 +136,8 @@ private:
void setFuncName(llvm::Function *Fn);
void mapRegionCounters(const Decl *D);
void computeRegionCounts(const Decl *D);
- void applyFunctionAttributes(llvm::ProfileDataReader *PGOReader,
- llvm::Function *Fn);
- void loadRegionCounts(llvm::ProfileDataReader *PGOReader);
+ void applyFunctionAttributes(PGOProfileData *PGOData, llvm::Function *Fn);
+ void loadRegionCounts(PGOProfileData *PGOData);
void emitCounterVariables();
/// Emit code to increment the counter at the given index
Modified: cfe/trunk/test/Profile/Inputs/c-attributes.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/c-attributes.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/c-attributes.profdata (original) and cfe/trunk/test/Profile/Inputs/c-attributes.profdata Wed Mar 12 16:06:31 2014 differ
Modified: cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata (original) and cfe/trunk/test/Profile/Inputs/c-counter-overflows.profdata Wed Mar 12 16:06:31 2014 differ
Modified: cfe/trunk/test/Profile/Inputs/c-general.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/c-general.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/c-general.profdata (original) and cfe/trunk/test/Profile/Inputs/c-general.profdata Wed Mar 12 16:06:31 2014 differ
Modified: cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata (original) and cfe/trunk/test/Profile/Inputs/c-outdated-data.profdata Wed Mar 12 16:06:31 2014 differ
Modified: cfe/trunk/test/Profile/Inputs/cxx-class.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/cxx-class.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/cxx-class.profdata (original) and cfe/trunk/test/Profile/Inputs/cxx-class.profdata Wed Mar 12 16:06:31 2014 differ
Modified: cfe/trunk/test/Profile/Inputs/cxx-throws.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/cxx-throws.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/cxx-throws.profdata (original) and cfe/trunk/test/Profile/Inputs/cxx-throws.profdata Wed Mar 12 16:06:31 2014 differ
Modified: cfe/trunk/test/Profile/Inputs/objc-general.profdata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/Inputs/objc-general.profdata?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
Binary files cfe/trunk/test/Profile/Inputs/objc-general.profdata (original) and cfe/trunk/test/Profile/Inputs/objc-general.profdata Wed Mar 12 16:06:31 2014 differ
Modified: cfe/trunk/tools/driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/CMakeLists.txt?rev=203712&r1=203711&r2=203712&view=diff
==============================================================================
--- cfe/trunk/tools/driver/CMakeLists.txt (original)
+++ cfe/trunk/tools/driver/CMakeLists.txt Wed Mar 12 16:06:31 2014
@@ -10,7 +10,6 @@ set( LLVM_LINK_COMPONENTS
MCParser
ObjCARCOpts
Option
- Profile
ScalarOpts
Support
TransformUtils
More information about the cfe-commits
mailing list