[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
This commit is contained in:
Vedant Kumar 2017-04-15 00:09:57 +00:00
parent 0bffb56cbe
commit f7f1e6f3b0
10 changed files with 72 additions and 169 deletions

View File

@ -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 @@ public:
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.

View File

@ -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);
enum InstrProfSectKind {
#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Kind,
#include "llvm/ProfileData/InstrProfData.inc"
};
/// 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);
/// 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.

View File

@ -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,")

View File

@ -43,6 +43,7 @@ public:
private:
InstrProfOptions Options;
Module *M;
Triple TT;
const TargetLibraryInfo *TLI;
struct PerFunctionProfileData {
uint32_t NumValueSites[IPVK_Last + 1];
@ -64,20 +65,6 @@ private:
// 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);

View File

@ -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;

View File

@ -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<COFFObjectFile>(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;

View File

@ -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 getInstrProfSectionName(InstrProfSectKind IPSK,
Triple::ObjectFormatType OF,
bool AddSegmentInfo) {
std::string SectName;
std::string getInstrProfNameSectionName(const Module *M) {
return getInstrProfSectionName(M, IPSK_name);
}
if (OF == Triple::MachO && AddSegmentInfo)
SectName = InstrProfSectNamePrefix[IPSK];
std::string getInstrProfNameSectionNameInObject(bool isCoff) {
return getInstrProfSectionName(isCoff, IPSK_name);
}
if (OF == Triple::COFF)
SectName += InstrProfSectNameCoff[IPSK];
else
SectName += InstrProfSectNameCommon[IPSK];
std::string getInstrProfDataSectionName(const Module *M) {
return getInstrProfSectionName(M, IPSK_data);
}
if (OF == Triple::MachO && IPSK == IPSK_data && AddSegmentInfo)
SectName += ",regular,live_support";
std::string getInstrProfDataSectionNameInObject(bool isCoff) {
return getInstrProfSectionName(isCoff, IPSK_data);
}
std::string getInstrProfValuesSectionName(const Module *M) {
return getInstrProfSectionName(M, IPSK_vals);
}
std::string getInstrProfVNodesSectionName(const Module *M) {
return getInstrProfSectionName(M, IPSK_vnodes);
}
std::string getInstrProfCoverageSectionName(const Module *M) {
return getInstrProfSectionName(M, IPSK_covmap);
}
std::string getInstrProfCoverageSectionNameInObject(bool isCoff) {
return getInstrProfSectionName(isCoff, IPSK_covmap);
return SectName;
}
void SoftInstrProfErrors::addError(instrprof_error IE) {

View File

@ -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<InstrProfIncrementInstStep>(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(

View File

@ -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;
}

View File

@ -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;