diff options
author | Xinliang David Li <davidxl@google.com> | 2016-02-08 18:13:49 +0000 |
---|---|---|
committer | Xinliang David Li <davidxl@google.com> | 2016-02-08 18:13:49 +0000 |
commit | a82d6c0a4b95177289d0d79d28382ad874b073c2 (patch) | |
tree | 05dad5b9812d035c123c2b2db3a25ab13c2f3eb5 /llvm/lib | |
parent | cbeb8b24305044e727d1a2c5cb30c9a7148aa495 (diff) | |
download | bcm5719-llvm-a82d6c0a4b95177289d0d79d28382ad874b073c2.tar.gz bcm5719-llvm-a82d6c0a4b95177289d0d79d28382ad874b073c2.zip |
[PGO] Enable compression in pgo instrumentation
This reduces sizes of instrumented object files, final binaries,
process images, and raw profile data.
The format of the indexed profile data remain the same.
Differential Revision: http://reviews.llvm.org/D16388
llvm-svn: 260117
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/ProfileData/CoverageMappingReader.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/ProfileData/InstrProfReader.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp | 68 |
3 files changed, 68 insertions, 18 deletions
diff --git a/llvm/lib/ProfileData/CoverageMappingReader.cpp b/llvm/lib/ProfileData/CoverageMappingReader.cpp index 633de3202c2..617ec9e0ee1 100644 --- a/llvm/lib/ProfileData/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/CoverageMappingReader.cpp @@ -426,6 +426,11 @@ std::unique_ptr<CovMapFuncRecordReader> CovMapFuncRecordReader::get( case CovMapVersion::Version1: return llvm::make_unique<VersionedCovMapFuncRecordReader< CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F); + case CovMapVersion::Version2: + // Decompress the name data. + P.create(P.getNameData()); + return llvm::make_unique<VersionedCovMapFuncRecordReader< + CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F); } llvm_unreachable("Unsupported version"); } diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index db6dd72870f..f189713c77a 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -280,13 +280,12 @@ RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) { template <class IntPtrT> void RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) { + Symtab.create(StringRef(NamesStart, NamesSize)); for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I != DataEnd; ++I) { - StringRef FunctionName(getName(I->NamePtr), swap(I->NameSize)); - Symtab.addFuncName(FunctionName); const IntPtrT FPtr = swap(I->FunctionPointer); if (!FPtr) continue; - Symtab.mapAddress(FPtr, IndexedInstrProf::ComputeHash(FunctionName)); + Symtab.mapAddress(FPtr, I->NameRef); } Symtab.finalizeSymtab(); } @@ -301,7 +300,7 @@ RawInstrProfReader<IntPtrT>::readHeader(const RawInstrProf::Header &Header) { NamesDelta = swap(Header.NamesDelta); auto DataSize = swap(Header.DataSize); auto CountersSize = swap(Header.CountersSize); - auto NamesSize = swap(Header.NamesSize); + NamesSize = swap(Header.NamesSize); auto ValueDataSize = swap(Header.ValueDataSize); ValueKindLast = swap(Header.ValueKindLast); @@ -334,11 +333,7 @@ RawInstrProfReader<IntPtrT>::readHeader(const RawInstrProf::Header &Header) { template <class IntPtrT> std::error_code RawInstrProfReader<IntPtrT>::readName(InstrProfRecord &Record) { - Record.Name = StringRef(getName(Data->NamePtr), swap(Data->NameSize)); - if (Record.Name.data() < NamesStart || - Record.Name.data() + Record.Name.size() > - reinterpret_cast<const char *>(ValueDataStart)) - return error(instrprof_error::malformed); + Record.Name = getName(Data->NameRef); return success(); } diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index 3124262c899..ab888189987 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -27,6 +27,10 @@ using namespace llvm; namespace { +cl::opt<bool> DoNameCompression("enable-name-compression", + cl::desc("Enable name string compression"), + cl::init(true)); + class InstrProfiling : public ModulePass { public: static char ID; @@ -59,6 +63,9 @@ private: } PerFunctionProfileData; DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap; std::vector<Value *> UsedVars; + std::vector<GlobalVariable *> ReferencedNames; + GlobalVariable *NamesVar; + size_t NamesSize; bool isMachO() const { return Triple(M->getTargetTriple()).isOSBinFormatMachO(); @@ -102,6 +109,9 @@ private: /// referring to them will also be created. GlobalVariable *getOrCreateRegionCounters(InstrProfIncrementInst *Inc); + /// Emit the section with compressed function names. + void emitNameData(); + /// Emit runtime registration functions for each profile data variable. void emitRegistration(); @@ -131,6 +141,8 @@ bool InstrProfiling::runOnModule(Module &M) { bool MadeChange = false; this->M = &M; + NamesVar = nullptr; + NamesSize = 0; ProfileDataMap.clear(); UsedVars.clear(); @@ -174,6 +186,7 @@ bool InstrProfiling::runOnModule(Module &M) { if (!MadeChange) return false; + emitNameData(); emitRegistration(); emitRuntimeHook(); emitUses(); @@ -252,9 +265,8 @@ void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageNamesVar) { assert(isa<GlobalVariable>(V) && "Missing reference to function name"); GlobalVariable *Name = cast<GlobalVariable>(V); - // Move the name variable to the right section. - Name->setSection(getNameSection()); - Name->setAlignment(1); + Name->setLinkage(GlobalValue::PrivateLinkage); + ReferencedNames.push_back(Name); } } @@ -279,9 +291,9 @@ static inline Comdat *getOrCreateProfileComdat(Module &M, // COFF format requires a COMDAT section to have a key symbol with the same // name. The linker targeting COFF also requires that the COMDAT // a section is associated to must precede the associating section. For this - // reason, we must choose the name var's name as the name of the comdat. + // reason, we must choose the counter var's name as the name of the comdat. StringRef ComdatPrefix = (Triple(M.getTargetTriple()).isOSBinFormatCOFF() - ? getInstrProfNameVarPrefix() + ? getInstrProfCountersVarPrefix() : getInstrProfComdatPrefix()); return M.getOrInsertComdat(StringRef(getVarName(Inc, ComdatPrefix))); } @@ -305,9 +317,6 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { Comdat *ProfileVarsComdat = nullptr; if (Fn->hasComdat()) ProfileVarsComdat = getOrCreateProfileComdat(*M, Inc); - NamePtr->setSection(getNameSection()); - NamePtr->setAlignment(1); - NamePtr->setComdat(ProfileVarsComdat); uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); LLVMContext &Ctx = M->getContext(); @@ -359,10 +368,37 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { // Mark the data variable as used so that it isn't stripped out. UsedVars.push_back(Data); + // Now that the linkage set by the FE has been passed to the data and counter + // variables, reset Name variable's linkage and visibility to private so that + // it can be removed later by the compiler. + NamePtr->setLinkage(GlobalValue::PrivateLinkage); + // Collect the referenced names to be used by emitNameData. + ReferencedNames.push_back(NamePtr); return CounterPtr; } +void InstrProfiling::emitNameData() { + std::string UncompressedData; + + if (ReferencedNames.empty()) + return; + + std::string CompressedNameStr; + collectPGOFuncNameStrings(ReferencedNames, CompressedNameStr, + DoNameCompression); + + auto &Ctx = M->getContext(); + auto *NamesVal = llvm::ConstantDataArray::getString( + Ctx, StringRef(CompressedNameStr), false); + NamesVar = new llvm::GlobalVariable(*M, NamesVal->getType(), true, + llvm::GlobalValue::PrivateLinkage, + NamesVal, getInstrProfNamesVarName()); + NamesSize = CompressedNameStr.size(); + NamesVar->setSection(getNameSection()); + UsedVars.push_back(NamesVar); +} + void InstrProfiling::emitRegistration() { // Don't do this for Darwin. compiler-rt uses linker magic. if (Triple(M->getTargetTriple()).isOSDarwin()) @@ -376,6 +412,7 @@ void InstrProfiling::emitRegistration() { // Construct the function. auto *VoidTy = Type::getVoidTy(M->getContext()); auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext()); + auto *Int64Ty = Type::getInt64Ty(M->getContext()); auto *RegisterFTy = FunctionType::get(VoidTy, false); auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage, getInstrProfRegFuncsName(), M); @@ -389,7 +426,20 @@ void InstrProfiling::emitRegistration() { IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", RegisterF)); for (Value *Data : UsedVars) - IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy)); + if (Data != NamesVar) + IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy)); + + if (NamesVar) { + Type *ParamTypes[] = {VoidPtrTy, Int64Ty}; + auto *NamesRegisterTy = + FunctionType::get(VoidTy, makeArrayRef(ParamTypes), false); + auto *NamesRegisterF = + Function::Create(NamesRegisterTy, GlobalVariable::ExternalLinkage, + getInstrProfNamesRegFuncName(), M); + IRB.CreateCall(NamesRegisterF, {IRB.CreateBitCast(NamesVar, VoidPtrTy), + IRB.getInt64(NamesSize)}); + } + IRB.CreateRetVoid(); } |