Skip to content

Commit

Permalink
[ProfileData] Unify getInstrProf*SectionName helpers
Browse files Browse the repository at this point in the history
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
  • Loading branch information
vedantk committed Apr 15, 2017
1 parent 03df14c commit 1a6a2b6
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 169 deletions.
11 changes: 11 additions & 0 deletions llvm/include/llvm/Object/Binary.h
Expand Up @@ -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"
Expand Down Expand Up @@ -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.
Expand Down
46 changes: 13 additions & 33 deletions llvm/include/llvm/ProfileData/InstrProf.h
Expand Up @@ -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"
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 6 additions & 6 deletions llvm/include/llvm/ProfileData/InstrProfData.inc
Expand Up @@ -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,")

Expand Down
15 changes: 1 addition & 14 deletions llvm/include/llvm/Transforms/InstrProfiling.h
Expand Up @@ -43,6 +43,7 @@ class InstrProfiling : public PassInfoMixin<InstrProfiling> {
private:
InstrProfOptions Options;
Module *M;
Triple TT;
const TargetLibraryInfo *TLI;
struct PerFunctionProfileData {
uint32_t NumValueSites[IPVK_Last + 1];
Expand All @@ -64,20 +65,6 @@ class InstrProfiling : public PassInfoMixin<InstrProfiling> {
// 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);

Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Expand Up @@ -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;
Expand Down
8 changes: 5 additions & 3 deletions llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
Expand Up @@ -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;

Expand Down
90 changes: 16 additions & 74 deletions llvm/lib/ProfileData/InstrProf.cpp
Expand Up @@ -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) {
Expand Down
40 changes: 10 additions & 30 deletions llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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);

Expand All @@ -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 =
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}

Expand All @@ -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)
Expand Down Expand Up @@ -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(
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
Expand Up @@ -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;
}

Expand Down

0 comments on commit 1a6a2b6

Please sign in to comment.