forked from OSchip/llvm-project
[Profile] PE binary coverage bug fix
PR/32584 Differential Revision: https://reviews.llvm.org/D32023 llvm-svn: 300277
This commit is contained in:
parent
c5779460f4
commit
57dea2d359
|
@ -54,39 +54,29 @@ class MDNode;
|
|||
class Module;
|
||||
|
||||
/// Return the name of data section containing profile counter variables.
|
||||
inline StringRef getInstrProfCountersSectionName(bool AddSegment) {
|
||||
return AddSegment ? "__DATA," INSTR_PROF_CNTS_SECT_NAME_STR
|
||||
: INSTR_PROF_CNTS_SECT_NAME_STR;
|
||||
}
|
||||
/// 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.
|
||||
inline StringRef getInstrProfNameSectionName(bool AddSegment) {
|
||||
return AddSegment ? "__DATA," INSTR_PROF_NAME_SECT_NAME_STR
|
||||
: INSTR_PROF_NAME_SECT_NAME_STR;
|
||||
}
|
||||
/// 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);
|
||||
|
||||
/// Return the name of the data section containing per-function control
|
||||
/// data.
|
||||
inline StringRef getInstrProfDataSectionName(bool AddSegment) {
|
||||
return AddSegment ? "__DATA," INSTR_PROF_DATA_SECT_NAME_STR
|
||||
",regular,live_support"
|
||||
: INSTR_PROF_DATA_SECT_NAME_STR;
|
||||
}
|
||||
/// 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);
|
||||
|
||||
/// Return the name of data section containing pointers to value profile
|
||||
/// counters/nodes.
|
||||
inline StringRef getInstrProfValuesSectionName(bool AddSegment) {
|
||||
return AddSegment ? "__DATA," INSTR_PROF_VALS_SECT_NAME_STR
|
||||
: INSTR_PROF_VALS_SECT_NAME_STR;
|
||||
}
|
||||
/// 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.
|
||||
inline StringRef getInstrProfVNodesSectionName(bool AddSegment) {
|
||||
return AddSegment ? "__DATA," INSTR_PROF_VNODES_SECT_NAME_STR
|
||||
: INSTR_PROF_VNODES_SECT_NAME_STR;
|
||||
}
|
||||
/// 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 profile runtime entry point to do value profiling
|
||||
/// for a given site.
|
||||
|
@ -101,10 +91,7 @@ inline StringRef getInstrProfValueRangeProfFuncName() {
|
|||
|
||||
/// Return the name of the section containing function coverage mapping
|
||||
/// data.
|
||||
inline StringRef getInstrProfCoverageSectionName(bool AddSegment) {
|
||||
return AddSegment ? "__LLVM_COV," INSTR_PROF_COVMAP_SECT_NAME_STR
|
||||
: INSTR_PROF_COVMAP_SECT_NAME_STR;
|
||||
}
|
||||
std::string getInstrProfCoverageSectionName(const Module *M = nullptr);
|
||||
|
||||
/// Return the name prefix of variables containing instrumented function names.
|
||||
inline StringRef getInstrProfNameVarPrefix() { return "__profn_"; }
|
||||
|
|
|
@ -246,6 +246,31 @@ COVMAP_HEADER(uint32_t, Int32Ty, Version, \
|
|||
/* COVMAP_HEADER end. */
|
||||
|
||||
|
||||
#ifdef INSTR_PROF_SECT_ENTRY
|
||||
#define INSTR_PROF_DATA_DEFINED
|
||||
INSTR_PROF_SECT_ENTRY(IPSK_data, INSTR_PROF_DATA_SECT_NAME_STR, \
|
||||
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_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_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_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_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_QUOTE(INSTR_PROF_COVMAP_COMMON), \
|
||||
INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COFF), "__LLVM_COV,")
|
||||
|
||||
#undef INSTR_PROF_SECT_ENTRY
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef INSTR_PROF_VALUE_PROF_DATA
|
||||
#define INSTR_PROF_DATA_DEFINED
|
||||
|
||||
|
@ -622,17 +647,47 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
|
|||
* specified via command line. */
|
||||
#define INSTR_PROF_PROFILE_NAME_VAR __llvm_profile_filename
|
||||
|
||||
/* section name strings common to all targets other
|
||||
than WIN32 */
|
||||
#define INSTR_PROF_DATA_COMMON __llvm_prf_data
|
||||
#define INSTR_PROF_NAME_COMMON __llvm_prf_names
|
||||
#define INSTR_PROF_CNTS_COMMON __llvm_prf_cnts
|
||||
#define INSTR_PROF_VALS_COMMON __llvm_prf_vals
|
||||
#define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds
|
||||
#define INSTR_PROF_COVMAP_COMMON __llvm_covmap
|
||||
/* Win32 */
|
||||
#define INSTR_PROF_DATA_COFF .lprfd
|
||||
#define INSTR_PROF_NAME_COFF .lprfn
|
||||
#define INSTR_PROF_CNTS_COFF .lprfc
|
||||
#define INSTR_PROF_VALS_COFF .lprfv
|
||||
#define INSTR_PROF_VNODES_COFF .lprfnd
|
||||
#define INSTR_PROF_COVMAP_COFF .lcovmap
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Runtime section names and name strings. */
|
||||
#define INSTR_PROF_DATA_SECT_NAME __llvm_prf_data
|
||||
#define INSTR_PROF_NAME_SECT_NAME __llvm_prf_names
|
||||
#define INSTR_PROF_CNTS_SECT_NAME __llvm_prf_cnts
|
||||
#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COFF
|
||||
#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COFF
|
||||
#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COFF
|
||||
/* Array of pointers. Each pointer points to a list
|
||||
* of value nodes associated with one value site.
|
||||
*/
|
||||
#define INSTR_PROF_VALS_SECT_NAME __llvm_prf_vals
|
||||
#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COFF
|
||||
/* Value profile nodes section. */
|
||||
#define INSTR_PROF_VNODES_SECT_NAME __llvm_prf_vnds
|
||||
#define INSTR_PROF_COVMAP_SECT_NAME __llvm_covmap
|
||||
#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COFF
|
||||
#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COFF
|
||||
#else
|
||||
/* Runtime section names and name strings. */
|
||||
#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COMMON
|
||||
#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COMMON
|
||||
#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COMMON
|
||||
/* Array of pointers. Each pointer points to a list
|
||||
* of value nodes associated with one value site.
|
||||
*/
|
||||
#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COMMON
|
||||
/* Value profile nodes section. */
|
||||
#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COMMON
|
||||
#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COMMON
|
||||
#endif
|
||||
|
||||
#define INSTR_PROF_DATA_SECT_NAME_STR \
|
||||
INSTR_PROF_QUOTE(INSTR_PROF_DATA_SECT_NAME)
|
||||
|
|
|
@ -67,16 +67,16 @@ private:
|
|||
bool isMachO() const;
|
||||
|
||||
/// Get the section name for the counter variables.
|
||||
StringRef getCountersSection() const;
|
||||
std::string getCountersSection() const;
|
||||
|
||||
/// Get the section name for the name variables.
|
||||
StringRef getNameSection() const;
|
||||
std::string getNameSection() const;
|
||||
|
||||
/// Get the section name for the profile data variables.
|
||||
StringRef getDataSection() const;
|
||||
std::string getDataSection() const;
|
||||
|
||||
/// Get the section name for the coverage mapping data.
|
||||
StringRef getCoverageSection() const;
|
||||
std::string getCoverageSection() const;
|
||||
|
||||
/// Count the number of instrumented value sites for the function.
|
||||
void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);
|
||||
|
|
|
@ -133,7 +133,9 @@ getELFKindForNamedSection(StringRef Name, SectionKind K) {
|
|||
//
|
||||
// .section .eh_frame,"a",@progbits
|
||||
|
||||
if (Name == getInstrProfCoverageSectionName(false))
|
||||
// TODO: to support Win->ELF cross compilation with coverage properly,
|
||||
// need to pass the module pointer to the following call.
|
||||
if (Name == getInstrProfCoverageSectionName())
|
||||
return SectionKind::getMetadata();
|
||||
|
||||
if (Name.empty() || Name[0] != '.') return K;
|
||||
|
|
|
@ -648,11 +648,15 @@ static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
|
|||
: support::endianness::big;
|
||||
|
||||
// Look for the sections that we are interested in.
|
||||
auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName(false));
|
||||
// TODO: with the current getInstrProfXXXSectionName interfaces, the
|
||||
// the coverage reader 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.
|
||||
auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName());
|
||||
if (auto E = NamesSection.takeError())
|
||||
return E;
|
||||
auto CoverageSection =
|
||||
lookupSection(*OF, getInstrProfCoverageSectionName(false));
|
||||
auto CoverageSection = lookupSection(*OF, getInstrProfCoverageSectionName());
|
||||
if (auto E = CoverageSection.takeError())
|
||||
return E;
|
||||
|
||||
|
|
|
@ -136,8 +136,92 @@ const std::error_category &llvm::instrprof_category() {
|
|||
return *ErrorCategory;
|
||||
}
|
||||
|
||||
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) \
|
||||
SectNameCommon,
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
};
|
||||
|
||||
const char *InstrProfSectNameCoff[] = {
|
||||
#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \
|
||||
Prefix) \
|
||||
SectNameCoff,
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
};
|
||||
|
||||
const char *InstrProfSectNamePrefix[] = {
|
||||
#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \
|
||||
Prefix) \
|
||||
Prefix,
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
};
|
||||
|
||||
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 getInstrProfDataSectionName(const Module *M) {
|
||||
return getInstrProfSectionName(M, 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);
|
||||
}
|
||||
|
||||
void SoftInstrProfErrors::addError(instrprof_error IE) {
|
||||
if (IE == instrprof_error::success)
|
||||
return;
|
||||
|
|
|
@ -145,23 +145,23 @@ bool InstrProfiling::isMachO() const {
|
|||
}
|
||||
|
||||
/// Get the section name for the counter variables.
|
||||
StringRef InstrProfiling::getCountersSection() const {
|
||||
return getInstrProfCountersSectionName(isMachO());
|
||||
std::string InstrProfiling::getCountersSection() const {
|
||||
return getInstrProfCountersSectionName(M);
|
||||
}
|
||||
|
||||
/// Get the section name for the name variables.
|
||||
StringRef InstrProfiling::getNameSection() const {
|
||||
return getInstrProfNameSectionName(isMachO());
|
||||
std::string InstrProfiling::getNameSection() const {
|
||||
return getInstrProfNameSectionName(M);
|
||||
}
|
||||
|
||||
/// Get the section name for the profile data variables.
|
||||
StringRef InstrProfiling::getDataSection() const {
|
||||
return getInstrProfDataSectionName(isMachO());
|
||||
std::string InstrProfiling::getDataSection() const {
|
||||
return getInstrProfDataSectionName(M);
|
||||
}
|
||||
|
||||
/// Get the section name for the coverage mapping data.
|
||||
StringRef InstrProfiling::getCoverageSection() const {
|
||||
return getInstrProfCoverageSectionName(isMachO());
|
||||
std::string InstrProfiling::getCoverageSection() const {
|
||||
return getInstrProfCoverageSectionName(M);
|
||||
}
|
||||
|
||||
static InstrProfIncrementInst *castToIncrementInst(Instruction *Instr) {
|
||||
|
@ -462,7 +462,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
|
|||
Constant::getNullValue(ValuesTy),
|
||||
getVarName(Inc, getInstrProfValuesVarPrefix()));
|
||||
ValuesVar->setVisibility(NamePtr->getVisibility());
|
||||
ValuesVar->setSection(getInstrProfValuesSectionName(isMachO()));
|
||||
ValuesVar->setSection(getInstrProfValuesSectionName(M));
|
||||
ValuesVar->setAlignment(8);
|
||||
ValuesVar->setComdat(ProfileVarsComdat);
|
||||
ValuesPtrExpr =
|
||||
|
@ -557,7 +557,7 @@ void InstrProfiling::emitVNodes() {
|
|||
auto *VNodesVar = new GlobalVariable(
|
||||
*M, VNodesTy, false, GlobalValue::PrivateLinkage,
|
||||
Constant::getNullValue(VNodesTy), getInstrProfVNodesVarName());
|
||||
VNodesVar->setSection(getInstrProfVNodesSectionName(isMachO()));
|
||||
VNodesVar->setSection(getInstrProfVNodesSectionName(M));
|
||||
UsedVars.push_back(VNodesVar);
|
||||
}
|
||||
|
||||
|
|
|
@ -280,8 +280,7 @@ static bool shouldInstrumentReadWriteFromAddress(Value *Addr) {
|
|||
if (GV->hasSection()) {
|
||||
StringRef SectionName = GV->getSection();
|
||||
// Check if the global is in the PGO counters section.
|
||||
if (SectionName.endswith(getInstrProfCountersSectionName(
|
||||
/*AddSegment=*/false)))
|
||||
if (SectionName.endswith(getInstrProfCountersSectionName()))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ $_Z3barIvEvv = comdat any
|
|||
|
||||
|
||||
; COFF-NOT: __profn__Z3barIvEvv
|
||||
; 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, [2 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [2 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data{{.*}}", comdat($__profc__Z3barIvEvv), align 8
|
||||
; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}prfc", comdat, align 8
|
||||
; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [2 x i16] zeroinitializer }, section "{{.*}}prfd{{.*}}", comdat($__profc__Z3barIvEvv), align 8
|
||||
|
||||
|
||||
declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1
|
||||
|
|
|
@ -52,9 +52,14 @@ int convertForTestingMain(int argc, const char *argv[]) {
|
|||
StringRef Name;
|
||||
if (Section.getName(Name))
|
||||
return 1;
|
||||
if (Name == llvm::getInstrProfNameSectionName(false)) {
|
||||
// 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()) {
|
||||
ProfileNames = Section;
|
||||
} else if (Name == llvm::getInstrProfCoverageSectionName(false)) {
|
||||
} else if (Name == llvm::getInstrProfCoverageSectionName()) {
|
||||
CoverageMapping = Section;
|
||||
} else
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue