From 1a6a2b642bd61910424cb7244f547c02460f18db Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Sat, 15 Apr 2017 00:09:57 +0000 Subject: [PATCH] [ProfileData] Unify getInstrProf*SectionName helpers This is a version of D32090 that unifies all of the `getInstrProf*SectionName` helper functions. (Note: the build failures which D32090 would have addressed were fixed with r300352.) We should unify these helper functions because they are hard to use in their current form. E.g we recently introduced more helpers to fix section naming for COFF files. This scheme doesn't totally succeed at hiding low-level details about section naming, so we should switch to an API that is easier to maintain. This is not an NFC commit because it fixes llvm-cov's testing support for COFF files (this falls out of the API change naturally). This is an area where we lack tests -- I will see about adding one as a follow up. Testing: check-clang, check-profile, check-llvm. Differential Revision: https://reviews.llvm.org/D32097 llvm-svn: 300381 --- llvm/include/llvm/Object/Binary.h | 11 +++ llvm/include/llvm/ProfileData/InstrProf.h | 46 +++------- .../llvm/ProfileData/InstrProfData.inc | 12 +-- llvm/include/llvm/Transforms/InstrProfiling.h | 15 +--- .../CodeGen/TargetLoweringObjectFileImpl.cpp | 3 +- .../Coverage/CoverageMappingReader.cpp | 8 +- llvm/lib/ProfileData/InstrProf.cpp | 90 ++++--------------- .../Instrumentation/InstrProfiling.cpp | 40 +++------ .../Instrumentation/ThreadSanitizer.cpp | 4 +- llvm/tools/llvm-cov/TestingSupport.cpp | 12 ++- 10 files changed, 72 insertions(+), 169 deletions(-) diff --git a/llvm/include/llvm/Object/Binary.h b/llvm/include/llvm/Object/Binary.h index 00d06e3c7437a..bdbe94301dc76 100644 --- a/llvm/include/llvm/Object/Binary.h +++ b/llvm/include/llvm/Object/Binary.h @@ -14,6 +14,7 @@ #ifndef LLVM_OBJECT_BINARY_H #define LLVM_OBJECT_BINARY_H +#include "llvm/ADT/Triple.h" #include "llvm/Object/Error.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" @@ -133,6 +134,16 @@ class Binary { return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B || TypeID == ID_MachO32B || TypeID == ID_MachO64B); } + + Triple::ObjectFormatType getTripleObjectFormat() const { + if (isCOFF()) + return Triple::COFF; + if (isMachO()) + return Triple::MachO; + if (isELF()) + return Triple::ELF; + return Triple::UnknownObjectFormat; + } }; /// @brief Create a Binary from Source, autodetecting the file type. diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 106e81b3321cd..c9828858cce3a 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -20,6 +20,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/Triple.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/ProfileSummary.h" #include "llvm/ProfileData/InstrProfData.inc" @@ -53,40 +54,19 @@ class Instruction; class MDNode; class Module; -/// Return the name of data section containing profile counter variables. -/// If M is null, the target platform is assumed to be the same as -/// the host machine, and the segment prefix will not be added. -std::string getInstrProfCountersSectionName(const Module *M = nullptr); - -/// Return the name of data section containing names of instrumented -/// functions. If M is null, the target platform is assumed to be the same as -/// the host machine, nor will segment prefix be added. -std::string getInstrProfNameSectionName(const Module *M = nullptr); - -/// Similar to the above, but used by host tool (e.g, coverage) which has -/// object format information. The section name returned is not prefixed -/// with segment name. -std::string getInstrProfNameSectionNameInObject(bool isCoff); - -/// Return the name of the data section containing per-function control -/// data. If M is null, the target platform is assumed to be the same as -/// the host machine, and the segment prefix will not be added. -std::string getInstrProfDataSectionName(const Module *M = nullptr); - -/// Similar to the above, but used by host tool (e.g, coverage) which has -/// object format information. The section name returned is not prefixed -/// with segment name. -std::string getInstrProfDataSectionNameInObject(bool isCoff); - -/// Return the name of data section containing pointers to value profile -/// counters/nodes. If M is null, the target platform is assumed to be -/// the same as the host machine, and the segment prefix will not be added. -std::string getInstrProfValuesSectionName(const Module *M = nullptr); +enum InstrProfSectKind { +#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Kind, +#include "llvm/ProfileData/InstrProfData.inc" +}; -/// Return the name of data section containing nodes holdling value -/// profiling data. If M is null, the target platform is assumed to be -/// the same as the host machine, and the segment prefix will not be added. -std::string getInstrProfVNodesSectionName(const Module *M = nullptr); +/// Return the name of the profile section corresponding to \p IPSK. +/// +/// The name of the section depends on the object format type \p OF. If +/// \p AddSegmentInfo is true, a segment prefix and additional linker hints may +/// be added to the section name (this is the default). +std::string getInstrProfSectionName(InstrProfSectKind IPSK, + Triple::ObjectFormatType OF, + bool AddSegmentInfo = true); /// Return the name profile runtime entry point to do value profiling /// for a given site. diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc index 949a50c0b3f96..be0dd4ad04bf6 100644 --- a/llvm/include/llvm/ProfileData/InstrProfData.inc +++ b/llvm/include/llvm/ProfileData/InstrProfData.inc @@ -248,22 +248,22 @@ COVMAP_HEADER(uint32_t, Int32Ty, Version, \ #ifdef INSTR_PROF_SECT_ENTRY #define INSTR_PROF_DATA_DEFINED -INSTR_PROF_SECT_ENTRY(IPSK_data, INSTR_PROF_DATA_SECT_NAME_STR, \ +INSTR_PROF_SECT_ENTRY(IPSK_data, \ INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON), \ INSTR_PROF_QUOTE(INSTR_PROF_DATA_COFF), "__DATA,") -INSTR_PROF_SECT_ENTRY(IPSK_cnts, INSTR_PROF_CNTS_SECT_NAME_STR, \ +INSTR_PROF_SECT_ENTRY(IPSK_cnts, \ INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON), \ INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COFF), "__DATA,") -INSTR_PROF_SECT_ENTRY(IPSK_name, INSTR_PROF_NAME_SECT_NAME_STR, \ +INSTR_PROF_SECT_ENTRY(IPSK_name, \ INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON), \ INSTR_PROF_QUOTE(INSTR_PROF_NAME_COFF), "__DATA,") -INSTR_PROF_SECT_ENTRY(IPSK_vals, INSTR_PROF_VALS_SECT_NAME_STR, \ +INSTR_PROF_SECT_ENTRY(IPSK_vals, \ INSTR_PROF_QUOTE(INSTR_PROF_VALS_COMMON), \ INSTR_PROF_QUOTE(INSTR_PROF_VALS_COFF), "__DATA,") -INSTR_PROF_SECT_ENTRY(IPSK_vnodes, INSTR_PROF_VNODES_SECT_NAME_STR, \ +INSTR_PROF_SECT_ENTRY(IPSK_vnodes, \ INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON), \ INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COFF), "__DATA,") -INSTR_PROF_SECT_ENTRY(IPSK_covmap, INSTR_PROF_COVMAP_SECT_NAME_STR, \ +INSTR_PROF_SECT_ENTRY(IPSK_covmap, \ INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON), \ INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COFF), "__LLVM_COV,") diff --git a/llvm/include/llvm/Transforms/InstrProfiling.h b/llvm/include/llvm/Transforms/InstrProfiling.h index 6f2286f32ecfa..65e69761baddd 100644 --- a/llvm/include/llvm/Transforms/InstrProfiling.h +++ b/llvm/include/llvm/Transforms/InstrProfiling.h @@ -43,6 +43,7 @@ class InstrProfiling : public PassInfoMixin { private: InstrProfOptions Options; Module *M; + Triple TT; const TargetLibraryInfo *TLI; struct PerFunctionProfileData { uint32_t NumValueSites[IPVK_Last + 1]; @@ -64,20 +65,6 @@ class InstrProfiling : public PassInfoMixin { // The end value of precise value profile range for memory intrinsic sizes. int64_t MemOPSizeRangeLast; - bool isMachO() const; - - /// Get the section name for the counter variables. - std::string getCountersSection() const; - - /// Get the section name for the name variables. - std::string getNameSection() const; - - /// Get the section name for the profile data variables. - std::string getDataSection() const; - - /// Get the section name for the coverage mapping data. - std::string getCoverageSection() const; - /// Count the number of instrumented value sites for the function. void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins); diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 8ce4dfd4ecc38..34892680aceb3 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -133,7 +133,8 @@ getELFKindForNamedSection(StringRef Name, SectionKind K) { // // .section .eh_frame,"a",@progbits - if (Name == getInstrProfCoverageSectionNameInObject(false /*not coff*/)) + if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, + /*AddSegmentInfo=*/false)) return SectionKind::getMetadata(); if (Name.empty() || Name[0] != '.') return K; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index dab602afd25ee..a34f359cd5427 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -649,13 +649,15 @@ static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer, : support::endianness::big; // Look for the sections that we are interested in. - bool IsCoff = (dyn_cast(OF.get()) != nullptr); + auto ObjFormat = OF->getTripleObjectFormat(); auto NamesSection = - lookupSection(*OF, getInstrProfNameSectionNameInObject(IsCoff)); + lookupSection(*OF, getInstrProfSectionName(IPSK_name, ObjFormat, + /*AddSegmentInfo=*/false)); if (auto E = NamesSection.takeError()) return E; auto CoverageSection = - lookupSection(*OF, getInstrProfCoverageSectionNameInObject(IsCoff)); + lookupSection(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat, + /*AddSegmentInfo=*/false)); if (auto E = CoverageSection.takeError()) return E; diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index a8f5b7f3d0e10..64a65ccc11a19 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -138,103 +138,45 @@ const std::error_category &llvm::instrprof_category() { namespace { -enum InstrProfSectKind { -#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \ - Prefix) \ - Kind, -#include "llvm/ProfileData/InstrProfData.inc" -}; - -const char *InstrProfSectName[] = { -#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \ - Prefix) \ - SectName, -#include "llvm/ProfileData/InstrProfData.inc" -}; - const char *InstrProfSectNameCommon[] = { -#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \ - Prefix) \ +#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \ SectNameCommon, #include "llvm/ProfileData/InstrProfData.inc" }; const char *InstrProfSectNameCoff[] = { -#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \ - Prefix) \ +#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \ SectNameCoff, #include "llvm/ProfileData/InstrProfData.inc" }; const char *InstrProfSectNamePrefix[] = { -#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \ - Prefix) \ +#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \ Prefix, #include "llvm/ProfileData/InstrProfData.inc" }; -std::string getInstrProfSectionName(bool isCoff, InstrProfSectKind Kind) { - return isCoff ? InstrProfSectNameCoff[Kind] : InstrProfSectNameCommon[Kind]; -} - -std::string getInstrProfSectionName(const Module *M, InstrProfSectKind Kind) { - if (!M) - return InstrProfSectName[Kind]; - - bool AddSegment = Triple(M->getTargetTriple()).isOSBinFormatMachO(); - std::string SectName; - if (Triple(M->getTargetTriple()).isOSBinFormatCOFF()) - SectName = InstrProfSectNameCoff[Kind]; - else - SectName = InstrProfSectNameCommon[Kind]; - - if (AddSegment) { - SectName = InstrProfSectNamePrefix[Kind] + SectName; - if (Kind == IPSK_data) { - SectName += ",regular,live_support"; - } - } - return SectName; -} - } // namespace namespace llvm { -std::string getInstrProfCountersSectionName(const Module *M) { - return getInstrProfSectionName(M, IPSK_cnts); -} - -std::string getInstrProfNameSectionName(const Module *M) { - return getInstrProfSectionName(M, IPSK_name); -} - -std::string getInstrProfNameSectionNameInObject(bool isCoff) { - return getInstrProfSectionName(isCoff, IPSK_name); -} - -std::string getInstrProfDataSectionName(const Module *M) { - return getInstrProfSectionName(M, IPSK_data); -} - -std::string getInstrProfDataSectionNameInObject(bool isCoff) { - return getInstrProfSectionName(isCoff, IPSK_data); -} +std::string getInstrProfSectionName(InstrProfSectKind IPSK, + Triple::ObjectFormatType OF, + bool AddSegmentInfo) { + std::string SectName; -std::string getInstrProfValuesSectionName(const Module *M) { - return getInstrProfSectionName(M, IPSK_vals); -} + if (OF == Triple::MachO && AddSegmentInfo) + SectName = InstrProfSectNamePrefix[IPSK]; -std::string getInstrProfVNodesSectionName(const Module *M) { - return getInstrProfSectionName(M, IPSK_vnodes); -} + if (OF == Triple::COFF) + SectName += InstrProfSectNameCoff[IPSK]; + else + SectName += InstrProfSectNameCommon[IPSK]; -std::string getInstrProfCoverageSectionName(const Module *M) { - return getInstrProfSectionName(M, IPSK_covmap); -} + if (OF == Triple::MachO && IPSK == IPSK_data && AddSegmentInfo) + SectName += ",regular,live_support"; -std::string getInstrProfCoverageSectionNameInObject(bool isCoff) { - return getInstrProfSectionName(isCoff, IPSK_covmap); + return SectName; } void SoftInstrProfErrors::addError(instrprof_error IE) { diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index c47467f1a84cb..d91ac6ac78830 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -140,30 +140,6 @@ llvm::createInstrProfilingLegacyPass(const InstrProfOptions &Options) { return new InstrProfilingLegacyPass(Options); } -bool InstrProfiling::isMachO() const { - return Triple(M->getTargetTriple()).isOSBinFormatMachO(); -} - -/// Get the section name for the counter variables. -std::string InstrProfiling::getCountersSection() const { - return getInstrProfCountersSectionName(M); -} - -/// Get the section name for the name variables. -std::string InstrProfiling::getNameSection() const { - return getInstrProfNameSectionName(M); -} - -/// Get the section name for the profile data variables. -std::string InstrProfiling::getDataSection() const { - return getInstrProfDataSectionName(M); -} - -/// Get the section name for the coverage mapping data. -std::string InstrProfiling::getCoverageSection() const { - return getInstrProfCoverageSectionName(M); -} - static InstrProfIncrementInst *castToIncrementInst(Instruction *Instr) { InstrProfIncrementInst *Inc = dyn_cast(Instr); if (Inc) @@ -182,6 +158,7 @@ bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) { UsedVars.clear(); getMemOPSizeRangeFromOption(MemOPSizeRange, MemOPSizeRangeStart, MemOPSizeRangeLast); + TT = Triple(M.getTargetTriple()); // We did not know how many value sites there would be inside // the instrumented function. This is counting the number of instrumented @@ -442,7 +419,8 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { Constant::getNullValue(CounterTy), getVarName(Inc, getInstrProfCountersVarPrefix())); CounterPtr->setVisibility(NamePtr->getVisibility()); - CounterPtr->setSection(getCountersSection()); + CounterPtr->setSection( + getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat())); CounterPtr->setAlignment(8); CounterPtr->setComdat(ProfileVarsComdat); @@ -462,7 +440,8 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { Constant::getNullValue(ValuesTy), getVarName(Inc, getInstrProfValuesVarPrefix())); ValuesVar->setVisibility(NamePtr->getVisibility()); - ValuesVar->setSection(getInstrProfValuesSectionName(M)); + ValuesVar->setSection( + getInstrProfSectionName(IPSK_vals, TT.getObjectFormat())); ValuesVar->setAlignment(8); ValuesVar->setComdat(ProfileVarsComdat); ValuesPtrExpr = @@ -495,7 +474,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { ConstantStruct::get(DataTy, DataVals), getVarName(Inc, getInstrProfDataVarPrefix())); Data->setVisibility(NamePtr->getVisibility()); - Data->setSection(getDataSection()); + Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat())); Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT); Data->setComdat(ProfileVarsComdat); @@ -557,7 +536,8 @@ void InstrProfiling::emitVNodes() { auto *VNodesVar = new GlobalVariable( *M, VNodesTy, false, GlobalValue::PrivateLinkage, Constant::getNullValue(VNodesTy), getInstrProfVNodesVarName()); - VNodesVar->setSection(getInstrProfVNodesSectionName(M)); + VNodesVar->setSection( + getInstrProfSectionName(IPSK_vnodes, TT.getObjectFormat())); UsedVars.push_back(VNodesVar); } @@ -580,7 +560,8 @@ void InstrProfiling::emitNameData() { GlobalValue::PrivateLinkage, NamesVal, getInstrProfNamesVarName()); NamesSize = CompressedNameStr.size(); - NamesVar->setSection(getNameSection()); + NamesVar->setSection( + getInstrProfSectionName(IPSK_name, TT.getObjectFormat())); UsedVars.push_back(NamesVar); for (auto *NamePtr : ReferencedNames) @@ -676,7 +657,6 @@ void InstrProfiling::emitInitialization() { GlobalVariable *ProfileNameVar = new GlobalVariable( *M, ProfileNameConst->getType(), true, GlobalValue::WeakAnyLinkage, ProfileNameConst, INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR)); - Triple TT(M->getTargetTriple()); if (TT.supportsCOMDAT()) { ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage); ProfileNameVar->setComdat(M->getOrInsertComdat( diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index b6255f651fdd4..9260217bd5e62 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -280,7 +280,9 @@ static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr) { if (GV->hasSection()) { StringRef SectionName = GV->getSection(); // Check if the global is in the PGO counters section. - if (SectionName.endswith(getInstrProfCountersSectionName(M))) + auto OF = Triple(M->getTargetTriple()).getObjectFormat(); + if (SectionName.endswith( + getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false))) return false; } diff --git a/llvm/tools/llvm-cov/TestingSupport.cpp b/llvm/tools/llvm-cov/TestingSupport.cpp index a272aa5422e07..4713d75f17dd4 100644 --- a/llvm/tools/llvm-cov/TestingSupport.cpp +++ b/llvm/tools/llvm-cov/TestingSupport.cpp @@ -48,18 +48,16 @@ int convertForTestingMain(int argc, const char *argv[]) { // Look for the sections that we are interested in. int FoundSectionCount = 0; SectionRef ProfileNames, CoverageMapping; + auto ObjFormat = OF->getTripleObjectFormat(); for (const auto &Section : OF->sections()) { StringRef Name; if (Section.getName(Name)) return 1; - // TODO: with the current getInstrProfXXXSectionName interfaces, the - // the host tool is limited to read coverage section on - // binaries with compatible profile section naming scheme as the host - // platform. Currently, COFF format binaries have different section - // naming scheme from the all the rest. - if (Name == llvm::getInstrProfNameSectionName()) { + if (Name == llvm::getInstrProfSectionName(IPSK_name, ObjFormat, + /*AddSegmentInfo=*/false)) { ProfileNames = Section; - } else if (Name == llvm::getInstrProfCoverageSectionName()) { + } else if (Name == llvm::getInstrProfSectionName( + IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)) { CoverageMapping = Section; } else continue;