Index: llvm/trunk/docs/CoverageMappingFormat.rst =================================================================== --- llvm/trunk/docs/CoverageMappingFormat.rst +++ llvm/trunk/docs/CoverageMappingFormat.rst @@ -260,20 +260,31 @@ i32 20, ; The length of the string that contains the encoded coverage mapping data i32 0, ; Coverage mapping format version }, - [2 x { i8*, i32, i32, i64 }] [ ; Function records - { i8*, i32, i32, i64 } { i8* getelementptr inbounds ([3 x i8]* @__profn_foo, i32 0, i32 0), ; Function's name - i32 3, ; Function's name length + [2 x { i64, i32, i64 }] [ ; Function records + { i64, i32, i64 } { + i64 0x5cf8c24cdb18bdac, ; Function's name MD5 i32 9, ; Function's encoded coverage mapping data string length i64 0 ; Function's structural hash }, - { i8*, i32, i32, i64 } { i8* getelementptr inbounds ([3 x i8]* @__profn_bar, i32 0, i32 0), ; Function's name - i32 3, ; Function's name length + { i64, i32, i64 } { + i64 0xe413754a191db537, ; Function's name MD5 i32 9, ; Function's encoded coverage mapping data string length i64 0 ; Function's structural hash }], [40 x i8] c"..." ; Encoded data (dissected later) }, section "__llvm_covmap", align 8 +The function record layout has evolved since version 1. In version 1, the function record for *foo* is defined as follows: + +.. code-block:: llvm + + { i8*, i32, i32, i64 } { i8* getelementptr inbounds ([3 x i8]* @__profn_foo, i32 0, i32 0), ; Function's name + i32 3, ; Function's name length + i32 9, ; Function's encoded coverage mapping data string length + i64 0 ; Function's structural hash + } + + Coverage Mapping Header: ------------------------ @@ -296,11 +307,10 @@ .. code-block:: llvm - { i8*, i32, i32, i64 } + { i64, i32, i64 } -It contains the pointer to the function's name, function's name length, -the length of the encoded mapping data for that function, and function's -hash value. +It contains function name's MD5, the length of the encoded mapping data for that function, and function's +structural hash value. Encoded data: ------------- Index: llvm/trunk/include/llvm/ProfileData/CoverageMapping.h =================================================================== --- llvm/trunk/include/llvm/ProfileData/CoverageMapping.h +++ llvm/trunk/include/llvm/ProfileData/CoverageMapping.h @@ -488,9 +488,11 @@ // [ArrayEnd] // [Encoded Region Mapping Data] LLVM_PACKED_START -template struct CovMapFunctionRecord { +template struct CovMapFunctionRecordV1 { +#define COVMAP_V1 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name; #include "llvm/ProfileData/InstrProfData.inc" +#undef COVMAP_V1 // Return the structural hash associated with the function. template uint64_t getFuncHash() const { @@ -516,6 +518,33 @@ return std::error_code(); } }; + +template struct CovMapFunctionRecord { +#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name; +#include "llvm/ProfileData/InstrProfData.inc" + + // Return the structural hash associated with the function. + template uint64_t getFuncHash() const { + return support::endian::byte_swap(FuncHash); + } + // Return the coverage map data size for the funciton. + template uint32_t getDataSize() const { + return support::endian::byte_swap(DataSize); + } + // Return function lookup key. The value is consider opaque. + template uint64_t getFuncNameRef() const { + return support::endian::byte_swap(NameRef); + } + // Return the PGO name of the function */ + template + std::error_code getFuncName(InstrProfSymtab &ProfileNames, + StringRef &FuncName) const { + IntPtrT NameRef = getFuncNameRef(); + FuncName = ProfileNames.getFuncName(NameRef); + return std::error_code(); + } +}; + // Per module coverage mapping data header, i.e. CoverageMapFileHeader // documented above. struct CovMapHeader { @@ -539,12 +568,21 @@ enum CovMapVersion { Version1 = 0, - // The current version is Version1 + // Function's name reference from CovMapFuncRecord is changed from raw + // name string pointer to MD5 to support name section compression. Name + // section is also compressed. + Version2 = 1, + // The current version is Version2 CurrentVersion = INSTR_PROF_COVMAP_VERSION }; template struct CovMapTraits { typedef CovMapFunctionRecord CovMapFuncRecordType; + typedef uint64_t NameRefType; +}; + +template struct CovMapTraits { + typedef CovMapFunctionRecordV1 CovMapFuncRecordType; typedef IntPtrT NameRefType; }; Index: llvm/trunk/include/llvm/ProfileData/InstrProf.h =================================================================== --- llvm/trunk/include/llvm/ProfileData/InstrProf.h +++ llvm/trunk/include/llvm/ProfileData/InstrProf.h @@ -85,6 +85,12 @@ /// associated with a COMDAT function. inline StringRef getInstrProfComdatPrefix() { return "__profv_"; } +/// Return the name of the variable holding the strings (possibly compressed) +/// of all function's PGO names. +inline StringRef getInstrProfNamesVarName() { + return "__llvm_prf_nm"; +} + /// Return the name of a covarage mapping variable (internal linkage) /// for each instrumented source module. Such variables are allocated /// in the __llvm_covmap section. @@ -115,6 +121,11 @@ return "__llvm_profile_register_function"; } +/// Return the name of the runtime interface that registers the PGO name strings. +inline StringRef getInstrProfNamesRegFuncName() { + return "__llvm_profile_register_names_function"; +} + /// Return the name of the runtime initialization method that is generated by /// the compiler. The function calls __llvm_profile_register_functions and /// __llvm_profile_override_default_filename functions if needed. This function @@ -766,6 +777,11 @@ namespace RawInstrProf { +// Version 1: First version +// Version 2: Added value profile data section. Per-function control data +// struct has more fields to describe value profile information. +// Version 3: Compressed name section support. Function PGO name reference +// from control data struct is changed from raw pointer to Name's MD5 value. const uint64_t Version = INSTR_PROF_RAW_VERSION; template inline uint64_t getMagic(); Index: llvm/trunk/include/llvm/ProfileData/InstrProfData.inc =================================================================== --- llvm/trunk/include/llvm/ProfileData/InstrProfData.inc +++ llvm/trunk/include/llvm/ProfileData/InstrProfData.inc @@ -64,17 +64,12 @@ #else #define INSTR_PROF_DATA_DEFINED #endif - -INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \ - ConstantInt::get(llvm::Type::getInt32Ty(Ctx), \ - NamePtr->getType()->getPointerElementType()->getArrayNumElements())) -INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumCounters, \ - ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumCounters)) +INSTR_PROF_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), NameRef, \ + ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \ + IndexedInstrProf::ComputeHash(getPGOFuncNameVarInitializer(Inc->getName())))) INSTR_PROF_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \ ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \ Inc->getHash()->getZExtValue())) -INSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), NamePtr, \ - ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx))) INSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt64PtrTy(Ctx), CounterPtr, \ ConstantExpr::getBitCast(CounterPtr, \ llvm::Type::getInt64PtrTy(Ctx))) @@ -82,6 +77,8 @@ FunctionAddr) INSTR_PROF_DATA(IntPtrT, llvm::Type::getInt8PtrTy(Ctx), Values, \ ConstantPointerNull::get(Int8PtrTy)) +INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumCounters, \ + ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumCounters)) INSTR_PROF_DATA(const uint16_t, Int16ArrayTy, NumValueSites[IPVK_Last+1], \ ConstantArray::get(Int16ArrayTy, Int16ArrayVals)) #undef INSTR_PROF_DATA @@ -153,12 +150,18 @@ #else #define INSTR_PROF_DATA_DEFINED #endif +#ifdef COVMAP_V1 COVMAP_FUNC_RECORD(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), \ NamePtr, llvm::ConstantExpr::getBitCast(NamePtr, \ llvm::Type::getInt8PtrTy(Ctx))) COVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \ - llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx),\ + llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), \ NameValue.size())) +#else +COVMAP_FUNC_RECORD(const int64_t, llvm::Type::getInt64Ty(Ctx), NameRef, \ + llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \ + llvm::IndexedInstrProf::ComputeHash(NameValue))) +#endif COVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), DataSize, \ llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx),\ CoverageMapping.size())) @@ -691,10 +694,12 @@ (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 | \ (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129 -/* Raw profile format version. */ -#define INSTR_PROF_RAW_VERSION 2 +/* Raw profile format version (start from 1). */ +#define INSTR_PROF_RAW_VERSION 3 +/* Indexed profile format version (start from 1). */ #define INSTR_PROF_INDEX_VERSION 4 -#define INSTR_PROF_COVMAP_VERSION 0 +/* Coverage mapping format vresion (start from 0). */ +#define INSTR_PROF_COVMAP_VERSION 1 /* Profile version is always of type uint64_t. Reserve the upper 8 bits in the * version for other variants of profile. We set the lowest bit of the upper 8 Index: llvm/trunk/include/llvm/ProfileData/InstrProfReader.h =================================================================== --- llvm/trunk/include/llvm/ProfileData/InstrProfReader.h +++ llvm/trunk/include/llvm/ProfileData/InstrProfReader.h @@ -160,6 +160,7 @@ const RawInstrProf::ProfileData *DataEnd; const uint64_t *CountersStart; const char *NamesStart; + uint64_t NamesSize; const uint8_t *ValueDataStart; const char *ProfileEnd; uint32_t ValueKindLast; @@ -216,9 +217,8 @@ ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t); return CountersStart + Offset; } - const char *getName(IntPtrT NamePtr) const { - ptrdiff_t Offset = (swap(NamePtr) - NamesDelta) / sizeof(char); - return NamesStart + Offset; + StringRef getName(uint64_t NameRef) const { + return Symtab->getFuncName(swap(NameRef)); } }; Index: llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp =================================================================== --- llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp +++ llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp @@ -426,6 +426,11 @@ case CovMapVersion::Version1: return llvm::make_unique>(P, R, F); + case CovMapVersion::Version2: + // Decompress the name data. + P.create(P.getNameData()); + return llvm::make_unique>(P, R, F); } llvm_unreachable("Unsupported version"); } Index: llvm/trunk/lib/ProfileData/InstrProfReader.cpp =================================================================== --- llvm/trunk/lib/ProfileData/InstrProfReader.cpp +++ llvm/trunk/lib/ProfileData/InstrProfReader.cpp @@ -280,13 +280,12 @@ template void RawInstrProfReader::createSymtab(InstrProfSymtab &Symtab) { + Symtab.create(StringRef(NamesStart, NamesSize)); for (const RawInstrProf::ProfileData *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 @@ 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 @@ template std::error_code RawInstrProfReader::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(ValueDataStart)) - return error(instrprof_error::malformed); + Record.Name = getName(Data->NameRef); return success(); } Index: llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -27,6 +27,10 @@ namespace { +cl::opt 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 @@ } PerFunctionProfileData; DenseMap ProfileDataMap; std::vector UsedVars; + std::vector ReferencedNames; + GlobalVariable *NamesVar; + size_t NamesSize; bool isMachO() const { return Triple(M->getTargetTriple()).isOSBinFormatMachO(); @@ -102,6 +109,9 @@ /// 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 MadeChange = false; this->M = &M; + NamesVar = nullptr; + NamesSize = 0; ProfileDataMap.clear(); UsedVars.clear(); @@ -174,6 +186,7 @@ if (!MadeChange) return false; + emitNameData(); emitRegistration(); emitRuntimeHook(); emitUses(); @@ -252,9 +265,8 @@ assert(isa(V) && "Missing reference to function name"); GlobalVariable *Name = cast(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 @@ // 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 @@ 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 @@ // 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 @@ // 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 @@ 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(); } Index: llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll =================================================================== --- llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll +++ llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll @@ -10,13 +10,15 @@ @__profn__Z3barIvEvv = linkonce_odr hidden constant [11 x i8] c"_Z3barIvEvv", align 1 -; CHECK: @__profn__Z3barIvEvv = linkonce_odr hidden constant [11 x i8] c"_Z3barIvEvv", section "{{.*}}__llvm_prf_names", comdat($__profv__Z3barIvEvv), align 1 +; CHECK: @__profn__Z3barIvEvv = private constant [11 x i8] c"_Z3barIvEvv", align 1 ; CHECK: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat($__profv__Z3barIvEvv), align 8 -; CHECK: @__profd__Z3barIvEvv = linkonce_odr hidden global { i32, i32, i64, i8*, i64*, i8*, i8*, [1 x i16] } { i32 11, i32 1, i64 0, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @__profn__Z3barIvEvv, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8* null, i8* null, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__profv__Z3barIvEvv), align 8 +; CHECK: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8* null, i8* null, i32 1, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__profv__Z3barIvEvv), align 8 +; CHECK: @__llvm_prf_nm = private constant [{{.*}} x i8] c"{{.*}}", section "{{.*}}__llvm_prf_names" -; COFF: @__profn__Z3barIvEvv = linkonce_odr hidden constant [11 x i8] c"_Z3barIvEvv", section "{{.*}}__llvm_prf_names", comdat, align 1 -; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat($__profn__Z3barIvEvv), align 8 -; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i32, i32, i64, i8*, i64*, i8*, i8*, [1 x i16] } { i32 11, i32 1, i64 0, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @__profn__Z3barIvEvv, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8* null, i8* null, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__profn__Z3barIvEvv), align 8 + +; COFF: @__profn__Z3barIvEvv = private constant [11 x i8] c"_Z3barIvEvv", align 1 +; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat, align 8 +; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8* null, i8* null, i32 1, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__profc__Z3barIvEvv), align 8 declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1 Index: llvm/trunk/test/Instrumentation/InstrProfiling/platform.ll =================================================================== --- llvm/trunk/test/Instrumentation/InstrProfiling/platform.ll +++ llvm/trunk/test/Instrumentation/InstrProfiling/platform.ll @@ -6,8 +6,8 @@ ; RUN: opt < %s -mtriple=x86_64-pc-solaris -instrprof -S | FileCheck %s -check-prefix=SOLARIS @__profn_foo = hidden constant [3 x i8] c"foo" -; MACHO: @__profn_foo = hidden constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1 -; ELF: @__profn_foo = hidden constant [3 x i8] c"foo", section "__llvm_prf_names", align 1 +; MACHO: @__profn_foo = private constant [3 x i8] c"foo" +; ELF: @__profn_foo = private constant [3 x i8] c"foo" ; MACHO: @__profc_foo = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 ; ELF: @__profc_foo = hidden global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", align 8 @@ -17,6 +17,8 @@ ; FREEBSD: @__profd_foo = hidden {{.*}}, section "__llvm_prf_data", align 8 ; SOLARIS: @__profd_foo = hidden {{.*}}, section "__llvm_prf_data", align 8 +; ELF: @__llvm_prf_nm = private constant [{{.*}} x i8] c"{{.*}}", section "{{.*}}__llvm_prf_names" + define void @foo() { call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @__profn_foo, i32 0, i32 0), i64 0, i32 1, i32 0) ret void Index: llvm/trunk/test/Instrumentation/InstrProfiling/profiling.ll =================================================================== --- llvm/trunk/test/Instrumentation/InstrProfiling/profiling.ll +++ llvm/trunk/test/Instrumentation/InstrProfiling/profiling.ll @@ -3,11 +3,11 @@ target triple = "x86_64-apple-macosx10.10.0" @__profn_foo = hidden constant [3 x i8] c"foo" -; CHECK: @__profn_foo = hidden constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1 +; CHECK: @__profn_foo = private constant [3 x i8] c"foo" @__profn_bar = hidden constant [4 x i8] c"bar\00" -; CHECK: @__profn_bar = hidden constant [4 x i8] c"bar\00", section "__DATA,__llvm_prf_names", align 1 +; CHECK: @__profn_bar = private constant [4 x i8] c"bar\00" @__profn_baz = hidden constant [3 x i8] c"baz" -; CHECK: @__profn_baz = hidden constant [3 x i8] c"baz", section "__DATA,__llvm_prf_names", align 1 +; CHECK: @__profn_baz = private constant [3 x i8] c"baz" ; CHECK: @__profc_foo = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 ; CHECK: @__profd_foo = hidden {{.*}}, section "__DATA,__llvm_prf_data", align 8 Index: llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test =================================================================== --- llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test +++ llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test @@ -1,36 +1,34 @@ RUN: printf '\377lprofR\201' > %t -RUN: printf '\0\0\0\0\0\0\0\2' >> %t +RUN: printf '\0\0\0\0\0\0\0\3' >> %t RUN: printf '\0\0\0\0\0\0\0\2' >> %t RUN: printf '\0\0\0\0\0\0\0\3' >> %t -RUN: printf '\0\0\0\0\0\0\0\6' >> %t +RUN: printf '\0\0\0\0\0\0\0\20' >> %t RUN: printf '\0\0\0\0\1\0\0\0' >> %t RUN: printf '\0\0\0\0\2\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\0\3' >> %t -RUN: printf '\0\0\0\1' >> %t +RUN: printf '\134\370\302\114\333\030\275\254' >> %t RUN: printf '\0\0\0\0\0\0\0\1' >> %t -RUN: printf '\2\0\0\0' >> %t RUN: printf '\1\0\0\0' >> %t RUN: printf '\0\0\0\0' >> %t RUN: printf '\0\0\0\0' >> %t +RUN: printf '\0\0\0\1' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\0\3' >> %t -RUN: printf '\0\0\0\2' >> %t +RUN: printf '\344\023\165\112\031\035\265\067' >> %t RUN: printf '\0\0\0\0\0\0\0\2' >> %t -RUN: printf '\2\0\0\03' >> %t RUN: printf '\1\0\0\10' >> %t RUN: printf '\0\0\0\0' >> %t RUN: printf '\0\0\0\0' >> %t +RUN: printf '\0\0\0\2' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\023' >> %t RUN: printf '\0\0\0\0\0\0\0\067' >> %t RUN: printf '\0\0\0\0\0\0\0\101' >> %t -RUN: printf 'foobar\0\0' >> %t +RUN: printf '\7\0foo bar\0\0\0\0\0\0\0' >> %t RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s Index: llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test =================================================================== --- llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test +++ llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test @@ -1,36 +1,34 @@ RUN: printf '\201Rforpl\377' > %t -RUN: printf '\2\0\0\0\0\0\0\0' >> %t +RUN: printf '\3\0\0\0\0\0\0\0' >> %t RUN: printf '\2\0\0\0\0\0\0\0' >> %t RUN: printf '\3\0\0\0\0\0\0\0' >> %t -RUN: printf '\6\0\0\0\0\0\0\0' >> %t +RUN: printf '\20\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\1\0\0\0\0' >> %t RUN: printf '\0\0\0\2\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\3\0\0\0' >> %t -RUN: printf '\1\0\0\0' >> %t +RUN: printf '\254\275\030\333\114\302\370\134' >> %t RUN: printf '\1\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\0\2' >> %t RUN: printf '\0\0\0\1' >> %t RUN: printf '\0\0\0\0' >> %t RUN: printf '\0\0\0\0' >> %t +RUN: printf '\1\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\3\0\0\0' >> %t -RUN: printf '\2\0\0\0' >> %t +RUN: printf '\067\265\035\031\112\165\023\344' >> %t RUN: printf '\02\0\0\0\0\0\0\0' >> %t -RUN: printf '\03\0\0\2' >> %t RUN: printf '\10\0\0\1' >> %t RUN: printf '\0\0\0\0' >> %t RUN: printf '\0\0\0\0' >> %t +RUN: printf '\2\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\023\0\0\0\0\0\0\0' >> %t RUN: printf '\067\0\0\0\0\0\0\0' >> %t RUN: printf '\101\0\0\0\0\0\0\0' >> %t -RUN: printf 'foobar\0\0' >> %t +RUN: printf '\7\0foo bar\0\0\0\0\0\0\0' >> %t RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s Index: llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test =================================================================== --- llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test +++ llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test @@ -1,36 +1,32 @@ RUN: printf '\377lprofr\201' > %t -RUN: printf '\0\0\0\0\0\0\0\2' >> %t +RUN: printf '\0\0\0\0\0\0\0\3' >> %t RUN: printf '\0\0\0\0\0\0\0\2' >> %t RUN: printf '\0\0\0\0\0\0\0\3' >> %t -RUN: printf '\0\0\0\0\0\0\0\6' >> %t +RUN: printf '\0\0\0\0\0\0\0\20' >> %t RUN: printf '\0\0\0\1\0\4\0\0' >> %t RUN: printf '\0\0\0\2\0\4\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\0\3' >> %t -RUN: printf '\0\0\0\1' >> %t +RUN: printf '\134\370\302\114\333\030\275\254' >> %t RUN: printf '\0\0\0\0\0\0\0\1' >> %t -RUN: printf '\0\0\0\2\0\4\0\0' >> %t RUN: printf '\0\0\0\1\0\4\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\0\0\0\0\0\0' >> %t +RUN: printf '\0\0\0\1\0\0\0\0' >> %t -RUN: printf '\0\0\0\3' >> %t -RUN: printf '\0\0\0\2' >> %t +RUN: printf '\344\023\165\112\031\035\265\067' >> %t RUN: printf '\0\0\0\0\0\0\0\02' >> %t -RUN: printf '\0\0\0\2\0\4\0\03' >> %t RUN: printf '\0\0\0\1\0\4\0\10' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\0\0\0\0\0\0' >> %t +RUN: printf '\0\0\0\02\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\023' >> %t RUN: printf '\0\0\0\0\0\0\0\067' >> %t RUN: printf '\0\0\0\0\0\0\0\101' >> %t -RUN: printf 'foobar\0\0' >> %t +RUN: printf '\7\0foo bar\0\0\0\0\0\0\0' >> %t RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s Index: llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test =================================================================== --- llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test +++ llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test @@ -1,36 +1,32 @@ RUN: printf '\201rforpl\377' > %t -RUN: printf '\2\0\0\0\0\0\0\0' >> %t +RUN: printf '\3\0\0\0\0\0\0\0' >> %t RUN: printf '\2\0\0\0\0\0\0\0' >> %t RUN: printf '\3\0\0\0\0\0\0\0' >> %t -RUN: printf '\6\0\0\0\0\0\0\0' >> %t +RUN: printf '\20\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\4\0\1\0\0\0' >> %t RUN: printf '\0\0\4\0\2\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\3\0\0\0' >> %t -RUN: printf '\1\0\0\0' >> %t +RUN: printf '\254\275\030\333\114\302\370\134' >> %t RUN: printf '\1\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\4\0\2\0\0\0' >> %t RUN: printf '\0\0\4\0\1\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\0\0\0\0\0\0' >> %t +RUN: printf '\1\0\0\0\0\0\0\0' >> %t -RUN: printf '\03\0\0\0' >> %t -RUN: printf '\02\0\0\0' >> %t +RUN: printf '\067\265\035\031\112\165\023\344' >> %t RUN: printf '\02\0\0\0\0\0\0\0' >> %t -RUN: printf '\03\0\4\0\2\0\0\0' >> %t RUN: printf '\10\0\4\0\1\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t -RUN: printf '\0\0\0\0\0\0\0\0' >> %t +RUN: printf '\02\0\0\0\0\0\0\0' >> %t RUN: printf '\023\0\0\0\0\0\0\0' >> %t RUN: printf '\067\0\0\0\0\0\0\0' >> %t RUN: printf '\101\0\0\0\0\0\0\0' >> %t -RUN: printf 'foobar\0\0' >> %t +RUN: printf '\7\0foo bar\0\0\0\0\0\0\0' >> %t RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s Index: llvm/trunk/test/tools/llvm-profdata/raw-two-profiles.test =================================================================== --- llvm/trunk/test/tools/llvm-profdata/raw-two-profiles.test +++ llvm/trunk/test/tools/llvm-profdata/raw-two-profiles.test @@ -1,49 +1,45 @@ RUN: printf '\201rforpl\377' > %t-foo.profraw -RUN: printf '\2\0\0\0\0\0\0\0' >> %t-foo.profraw +RUN: printf '\3\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw -RUN: printf '\3\0\0\0\0\0\0\0' >> %t-foo.profraw +RUN: printf '\10\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\4\0\1\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\4\0\2\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw -RUN: printf '\3\0\0\0' >> %t-foo.profraw -RUN: printf '\1\0\0\0' >> %t-foo.profraw +RUN: printf '\254\275\030\333\114\302\370\134' >> %t-foo.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw -RUN: printf '\0\0\4\0\2\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\4\0\1\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw -RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw +RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\023\0\0\0\0\0\0\0' >> %t-foo.profraw -RUN: printf 'foo\0\0\0\0\0' >> %t-foo.profraw +RUN: printf '\3\0foo\0\0\0' >> %t-foo.profraw RUN: printf '\201rforpl\377' > %t-bar.profraw -RUN: printf '\2\0\0\0\0\0\0\0' >> %t-bar.profraw +RUN: printf '\3\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\2\0\0\0\0\0\0\0' >> %t-bar.profraw -RUN: printf '\3\0\0\0\0\0\0\0' >> %t-bar.profraw +RUN: printf '\10\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\6\0\1\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\6\0\2\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw -RUN: printf '\3\0\0\0' >> %t-bar.profraw -RUN: printf '\2\0\0\0' >> %t-bar.profraw -RUN: printf '\2\0\0\0\0\0\0\0' >> %t-bar.profraw -RUN: printf '\0\0\6\0\2\0\0\0' >> %t-bar.profraw +RUN: printf '\067\265\035\031\112\165\023\344' >> %t-bar.profraw +RUN: printf '\02\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\6\0\1\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw -RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw +RUN: printf '\02\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\067\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\101\0\0\0\0\0\0\0' >> %t-bar.profraw -RUN: printf 'bar\0\0\0\0\0' >> %t-bar.profraw +RUN: printf '\3\0bar\0\0\0' >> %t-bar.profraw RUN: cat %t-foo.profraw %t-bar.profraw > %t-pad.profraw RUN: llvm-profdata show %t-pad.profraw -all-functions -counts | FileCheck %s