Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 2fc706b

Browse files
committed
[Profile] PE binary coverage bug fix
PR/32584 Differential Revision: https://reviews.llvm.org/D32023 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300277 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 0100c80 commit 2fc706b

File tree

10 files changed

+195
-59
lines changed

10 files changed

+195
-59
lines changed

Diff for: include/llvm/ProfileData/InstrProf.h

+16-29
Original file line numberDiff line numberDiff line change
@@ -54,39 +54,29 @@ class MDNode;
5454
class Module;
5555

5656
/// Return the name of data section containing profile counter variables.
57-
inline StringRef getInstrProfCountersSectionName(bool AddSegment) {
58-
return AddSegment ? "__DATA," INSTR_PROF_CNTS_SECT_NAME_STR
59-
: INSTR_PROF_CNTS_SECT_NAME_STR;
60-
}
57+
/// If M is null, the target platform is assumed to be the same as
58+
/// the host machine, and the segment prefix will not be added.
59+
std::string getInstrProfCountersSectionName(const Module *M = nullptr);
6160

6261
/// Return the name of data section containing names of instrumented
63-
/// functions.
64-
inline StringRef getInstrProfNameSectionName(bool AddSegment) {
65-
return AddSegment ? "__DATA," INSTR_PROF_NAME_SECT_NAME_STR
66-
: INSTR_PROF_NAME_SECT_NAME_STR;
67-
}
62+
/// functions. If M is null, the target platform is assumed to be the same as
63+
/// the host machine, nor will segment prefix be added.
64+
std::string getInstrProfNameSectionName(const Module *M = nullptr);
6865

6966
/// Return the name of the data section containing per-function control
70-
/// data.
71-
inline StringRef getInstrProfDataSectionName(bool AddSegment) {
72-
return AddSegment ? "__DATA," INSTR_PROF_DATA_SECT_NAME_STR
73-
",regular,live_support"
74-
: INSTR_PROF_DATA_SECT_NAME_STR;
75-
}
67+
/// data. If M is null, the target platform is assumed to be the same as
68+
/// the host machine, and the segment prefix will not be added.
69+
std::string getInstrProfDataSectionName(const Module *M = nullptr);
7670

7771
/// Return the name of data section containing pointers to value profile
78-
/// counters/nodes.
79-
inline StringRef getInstrProfValuesSectionName(bool AddSegment) {
80-
return AddSegment ? "__DATA," INSTR_PROF_VALS_SECT_NAME_STR
81-
: INSTR_PROF_VALS_SECT_NAME_STR;
82-
}
72+
/// counters/nodes. If M is null, the target platform is assumed to be
73+
/// the same as the host machine, and the segment prefix will not be added.
74+
std::string getInstrProfValuesSectionName(const Module *M = nullptr);
8375

8476
/// Return the name of data section containing nodes holdling value
85-
/// profiling data.
86-
inline StringRef getInstrProfVNodesSectionName(bool AddSegment) {
87-
return AddSegment ? "__DATA," INSTR_PROF_VNODES_SECT_NAME_STR
88-
: INSTR_PROF_VNODES_SECT_NAME_STR;
89-
}
77+
/// profiling data. If M is null, the target platform is assumed to be
78+
/// the same as the host machine, and the segment prefix will not be added.
79+
std::string getInstrProfVNodesSectionName(const Module *M = nullptr);
9080

9181
/// Return the name profile runtime entry point to do value profiling
9282
/// for a given site.
@@ -101,10 +91,7 @@ inline StringRef getInstrProfValueRangeProfFuncName() {
10191

10292
/// Return the name of the section containing function coverage mapping
10393
/// data.
104-
inline StringRef getInstrProfCoverageSectionName(bool AddSegment) {
105-
return AddSegment ? "__LLVM_COV," INSTR_PROF_COVMAP_SECT_NAME_STR
106-
: INSTR_PROF_COVMAP_SECT_NAME_STR;
107-
}
94+
std::string getInstrProfCoverageSectionName(const Module *M = nullptr);
10895

10996
/// Return the name prefix of variables containing instrumented function names.
11097
inline StringRef getInstrProfNameVarPrefix() { return "__profn_"; }

Diff for: include/llvm/ProfileData/InstrProfData.inc

+61-6
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,31 @@ COVMAP_HEADER(uint32_t, Int32Ty, Version, \
246246
/* COVMAP_HEADER end. */
247247

248248

249+
#ifdef INSTR_PROF_SECT_ENTRY
250+
#define INSTR_PROF_DATA_DEFINED
251+
INSTR_PROF_SECT_ENTRY(IPSK_data, INSTR_PROF_DATA_SECT_NAME_STR, \
252+
INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON), \
253+
INSTR_PROF_QUOTE(INSTR_PROF_DATA_COFF), "__DATA,")
254+
INSTR_PROF_SECT_ENTRY(IPSK_cnts, INSTR_PROF_CNTS_SECT_NAME_STR, \
255+
INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON), \
256+
INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COFF), "__DATA,")
257+
INSTR_PROF_SECT_ENTRY(IPSK_name, INSTR_PROF_NAME_SECT_NAME_STR, \
258+
INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON), \
259+
INSTR_PROF_QUOTE(INSTR_PROF_NAME_COFF), "__DATA,")
260+
INSTR_PROF_SECT_ENTRY(IPSK_vals, INSTR_PROF_VALS_SECT_NAME_STR, \
261+
INSTR_PROF_QUOTE(INSTR_PROF_VALS_COMMON), \
262+
INSTR_PROF_QUOTE(INSTR_PROF_VALS_COFF), "__DATA,")
263+
INSTR_PROF_SECT_ENTRY(IPSK_vnodes, INSTR_PROF_VNODES_SECT_NAME_STR, \
264+
INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON), \
265+
INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COFF), "__DATA,")
266+
INSTR_PROF_SECT_ENTRY(IPSK_covmap, INSTR_PROF_COVMAP_SECT_NAME_STR, \
267+
INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON), \
268+
INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COFF), "__LLVM_COV,")
269+
270+
#undef INSTR_PROF_SECT_ENTRY
271+
#endif
272+
273+
249274
#ifdef INSTR_PROF_VALUE_PROF_DATA
250275
#define INSTR_PROF_DATA_DEFINED
251276

@@ -622,17 +647,47 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
622647
* specified via command line. */
623648
#define INSTR_PROF_PROFILE_NAME_VAR __llvm_profile_filename
624649

650+
/* section name strings common to all targets other
651+
than WIN32 */
652+
#define INSTR_PROF_DATA_COMMON __llvm_prf_data
653+
#define INSTR_PROF_NAME_COMMON __llvm_prf_names
654+
#define INSTR_PROF_CNTS_COMMON __llvm_prf_cnts
655+
#define INSTR_PROF_VALS_COMMON __llvm_prf_vals
656+
#define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds
657+
#define INSTR_PROF_COVMAP_COMMON __llvm_covmap
658+
/* Win32 */
659+
#define INSTR_PROF_DATA_COFF .lprfd
660+
#define INSTR_PROF_NAME_COFF .lprfn
661+
#define INSTR_PROF_CNTS_COFF .lprfc
662+
#define INSTR_PROF_VALS_COFF .lprfv
663+
#define INSTR_PROF_VNODES_COFF .lprfnd
664+
#define INSTR_PROF_COVMAP_COFF .lcovmap
665+
666+
#ifdef _WIN32
625667
/* Runtime section names and name strings. */
626-
#define INSTR_PROF_DATA_SECT_NAME __llvm_prf_data
627-
#define INSTR_PROF_NAME_SECT_NAME __llvm_prf_names
628-
#define INSTR_PROF_CNTS_SECT_NAME __llvm_prf_cnts
668+
#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COFF
669+
#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COFF
670+
#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COFF
629671
/* Array of pointers. Each pointer points to a list
630672
* of value nodes associated with one value site.
631673
*/
632-
#define INSTR_PROF_VALS_SECT_NAME __llvm_prf_vals
674+
#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COFF
633675
/* Value profile nodes section. */
634-
#define INSTR_PROF_VNODES_SECT_NAME __llvm_prf_vnds
635-
#define INSTR_PROF_COVMAP_SECT_NAME __llvm_covmap
676+
#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COFF
677+
#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COFF
678+
#else
679+
/* Runtime section names and name strings. */
680+
#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COMMON
681+
#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COMMON
682+
#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COMMON
683+
/* Array of pointers. Each pointer points to a list
684+
* of value nodes associated with one value site.
685+
*/
686+
#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COMMON
687+
/* Value profile nodes section. */
688+
#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COMMON
689+
#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COMMON
690+
#endif
636691

637692
#define INSTR_PROF_DATA_SECT_NAME_STR \
638693
INSTR_PROF_QUOTE(INSTR_PROF_DATA_SECT_NAME)

Diff for: include/llvm/Transforms/InstrProfiling.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,16 @@ class InstrProfiling : public PassInfoMixin<InstrProfiling> {
6767
bool isMachO() const;
6868

6969
/// Get the section name for the counter variables.
70-
StringRef getCountersSection() const;
70+
std::string getCountersSection() const;
7171

7272
/// Get the section name for the name variables.
73-
StringRef getNameSection() const;
73+
std::string getNameSection() const;
7474

7575
/// Get the section name for the profile data variables.
76-
StringRef getDataSection() const;
76+
std::string getDataSection() const;
7777

7878
/// Get the section name for the coverage mapping data.
79-
StringRef getCoverageSection() const;
79+
std::string getCoverageSection() const;
8080

8181
/// Count the number of instrumented value sites for the function.
8282
void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);

Diff for: lib/CodeGen/TargetLoweringObjectFileImpl.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ getELFKindForNamedSection(StringRef Name, SectionKind K) {
133133
//
134134
// .section .eh_frame,"a",@progbits
135135

136-
if (Name == getInstrProfCoverageSectionName(false))
136+
// TODO: to support Win->ELF cross compilation with coverage properly,
137+
// need to pass the module pointer to the following call.
138+
if (Name == getInstrProfCoverageSectionName())
137139
return SectionKind::getMetadata();
138140

139141
if (Name.empty() || Name[0] != '.') return K;

Diff for: lib/ProfileData/Coverage/CoverageMappingReader.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -648,11 +648,15 @@ static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
648648
: support::endianness::big;
649649

650650
// Look for the sections that we are interested in.
651-
auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName(false));
651+
// TODO: with the current getInstrProfXXXSectionName interfaces, the
652+
// the coverage reader host tool is limited to read coverage section on
653+
// binaries with compatible profile section naming scheme as the host
654+
// platform. Currently, COFF format binaries have different section
655+
// naming scheme from the all the rest.
656+
auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName());
652657
if (auto E = NamesSection.takeError())
653658
return E;
654-
auto CoverageSection =
655-
lookupSection(*OF, getInstrProfCoverageSectionName(false));
659+
auto CoverageSection = lookupSection(*OF, getInstrProfCoverageSectionName());
656660
if (auto E = CoverageSection.takeError())
657661
return E;
658662

Diff for: lib/ProfileData/InstrProf.cpp

+84
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,92 @@ const std::error_category &llvm::instrprof_category() {
136136
return *ErrorCategory;
137137
}
138138

139+
namespace {
140+
141+
enum InstrProfSectKind {
142+
#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \
143+
Prefix) \
144+
Kind,
145+
#include "llvm/ProfileData/InstrProfData.inc"
146+
};
147+
148+
const char *InstrProfSectName[] = {
149+
#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \
150+
Prefix) \
151+
SectName,
152+
#include "llvm/ProfileData/InstrProfData.inc"
153+
};
154+
155+
const char *InstrProfSectNameCommon[] = {
156+
#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \
157+
Prefix) \
158+
SectNameCommon,
159+
#include "llvm/ProfileData/InstrProfData.inc"
160+
};
161+
162+
const char *InstrProfSectNameCoff[] = {
163+
#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \
164+
Prefix) \
165+
SectNameCoff,
166+
#include "llvm/ProfileData/InstrProfData.inc"
167+
};
168+
169+
const char *InstrProfSectNamePrefix[] = {
170+
#define INSTR_PROF_SECT_ENTRY(Kind, SectName, SectNameCommon, SectNameCoff, \
171+
Prefix) \
172+
Prefix,
173+
#include "llvm/ProfileData/InstrProfData.inc"
174+
};
175+
176+
std::string getInstrProfSectionName(const Module *M, InstrProfSectKind Kind) {
177+
178+
if (!M)
179+
return InstrProfSectName[Kind];
180+
181+
bool AddSegment = Triple(M->getTargetTriple()).isOSBinFormatMachO();
182+
std::string SectName;
183+
if (Triple(M->getTargetTriple()).isOSBinFormatCOFF())
184+
SectName = InstrProfSectNameCoff[Kind];
185+
else
186+
SectName = InstrProfSectNameCommon[Kind];
187+
188+
if (AddSegment) {
189+
SectName = InstrProfSectNamePrefix[Kind] + SectName;
190+
if (Kind == IPSK_data) {
191+
SectName += ",regular,live_support";
192+
}
193+
}
194+
return SectName;
195+
}
196+
197+
} // namespace
198+
139199
namespace llvm {
140200

201+
std::string getInstrProfCountersSectionName(const Module *M) {
202+
return getInstrProfSectionName(M, IPSK_cnts);
203+
}
204+
205+
std::string getInstrProfNameSectionName(const Module *M) {
206+
return getInstrProfSectionName(M, IPSK_name);
207+
}
208+
209+
std::string getInstrProfDataSectionName(const Module *M) {
210+
return getInstrProfSectionName(M, IPSK_data);
211+
}
212+
213+
std::string getInstrProfValuesSectionName(const Module *M) {
214+
return getInstrProfSectionName(M, IPSK_vals);
215+
}
216+
217+
std::string getInstrProfVNodesSectionName(const Module *M) {
218+
return getInstrProfSectionName(M, IPSK_vnodes);
219+
}
220+
221+
std::string getInstrProfCoverageSectionName(const Module *M) {
222+
return getInstrProfSectionName(M, IPSK_covmap);
223+
}
224+
141225
void SoftInstrProfErrors::addError(instrprof_error IE) {
142226
if (IE == instrprof_error::success)
143227
return;

Diff for: lib/Transforms/Instrumentation/InstrProfiling.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -145,23 +145,23 @@ bool InstrProfiling::isMachO() const {
145145
}
146146

147147
/// Get the section name for the counter variables.
148-
StringRef InstrProfiling::getCountersSection() const {
149-
return getInstrProfCountersSectionName(isMachO());
148+
std::string InstrProfiling::getCountersSection() const {
149+
return getInstrProfCountersSectionName(M);
150150
}
151151

152152
/// Get the section name for the name variables.
153-
StringRef InstrProfiling::getNameSection() const {
154-
return getInstrProfNameSectionName(isMachO());
153+
std::string InstrProfiling::getNameSection() const {
154+
return getInstrProfNameSectionName(M);
155155
}
156156

157157
/// Get the section name for the profile data variables.
158-
StringRef InstrProfiling::getDataSection() const {
159-
return getInstrProfDataSectionName(isMachO());
158+
std::string InstrProfiling::getDataSection() const {
159+
return getInstrProfDataSectionName(M);
160160
}
161161

162162
/// Get the section name for the coverage mapping data.
163-
StringRef InstrProfiling::getCoverageSection() const {
164-
return getInstrProfCoverageSectionName(isMachO());
163+
std::string InstrProfiling::getCoverageSection() const {
164+
return getInstrProfCoverageSectionName(M);
165165
}
166166

167167
static InstrProfIncrementInst *castToIncrementInst(Instruction *Instr) {
@@ -462,7 +462,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
462462
Constant::getNullValue(ValuesTy),
463463
getVarName(Inc, getInstrProfValuesVarPrefix()));
464464
ValuesVar->setVisibility(NamePtr->getVisibility());
465-
ValuesVar->setSection(getInstrProfValuesSectionName(isMachO()));
465+
ValuesVar->setSection(getInstrProfValuesSectionName(M));
466466
ValuesVar->setAlignment(8);
467467
ValuesVar->setComdat(ProfileVarsComdat);
468468
ValuesPtrExpr =
@@ -557,7 +557,7 @@ void InstrProfiling::emitVNodes() {
557557
auto *VNodesVar = new GlobalVariable(
558558
*M, VNodesTy, false, GlobalValue::PrivateLinkage,
559559
Constant::getNullValue(VNodesTy), getInstrProfVNodesVarName());
560-
VNodesVar->setSection(getInstrProfVNodesSectionName(isMachO()));
560+
VNodesVar->setSection(getInstrProfVNodesSectionName(M));
561561
UsedVars.push_back(VNodesVar);
562562
}
563563

Diff for: lib/Transforms/Instrumentation/ThreadSanitizer.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,7 @@ static bool shouldInstrumentReadWriteFromAddress(Value *Addr) {
280280
if (GV->hasSection()) {
281281
StringRef SectionName = GV->getSection();
282282
// Check if the global is in the PGO counters section.
283-
if (SectionName.endswith(getInstrProfCountersSectionName(
284-
/*AddSegment=*/false)))
283+
if (SectionName.endswith(getInstrProfCountersSectionName()))
285284
return false;
286285
}
287286

Diff for: test/Instrumentation/InstrProfiling/PR23499.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ $_Z3barIvEvv = comdat any
2020

2121

2222
; COFF-NOT: __profn__Z3barIvEvv
23-
; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat, align 8
24-
; 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
23+
; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}prfc", comdat, align 8
24+
; 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
2525

2626

2727
declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1

Diff for: tools/llvm-cov/TestingSupport.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,14 @@ int convertForTestingMain(int argc, const char *argv[]) {
5252
StringRef Name;
5353
if (Section.getName(Name))
5454
return 1;
55-
if (Name == llvm::getInstrProfNameSectionName(false)) {
55+
// TODO: with the current getInstrProfXXXSectionName interfaces, the
56+
// the host tool is limited to read coverage section on
57+
// binaries with compatible profile section naming scheme as the host
58+
// platform. Currently, COFF format binaries have different section
59+
// naming scheme from the all the rest.
60+
if (Name == llvm::getInstrProfNameSectionName()) {
5661
ProfileNames = Section;
57-
} else if (Name == llvm::getInstrProfCoverageSectionName(false)) {
62+
} else if (Name == llvm::getInstrProfCoverageSectionName()) {
5863
CoverageMapping = Section;
5964
} else
6065
continue;

0 commit comments

Comments
 (0)