aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp')
-rw-r--r--llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp40
1 files changed, 23 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 63c2b8078967..5d3a793dda19 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -731,9 +731,8 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
PD = It->second;
}
- // Match the linkage and visibility of the name global, except on COFF, where
- // the linkage must be local and consequentially the visibility must be
- // default.
+ // Match the linkage and visibility of the name global. COFF supports using
+ // comdats with internal symbols, so do that if we can.
Function *Fn = Inc->getParent()->getParent();
GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage();
GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility();
@@ -749,19 +748,25 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
// new comdat group for the counters and profiling data. If we use the comdat
// of the parent function, that will result in relocations against discarded
// sections.
- Comdat *Cmdt = nullptr;
- GlobalValue::LinkageTypes CounterLinkage = Linkage;
- if (needsComdatForCounter(*Fn, *M)) {
- StringRef CmdtPrefix = getInstrProfComdatPrefix();
+ bool NeedComdat = needsComdatForCounter(*Fn, *M);
+ Comdat *Cmdt = nullptr; // Comdat group.
+ if (NeedComdat) {
if (TT.isOSBinFormatCOFF()) {
- // For COFF, the comdat group name must be the name of a symbol in the
- // group. Use the counter variable name, and upgrade its linkage to
- // something externally visible, like linkonce_odr.
- CmdtPrefix = getInstrProfCountersVarPrefix();
- CounterLinkage = GlobalValue::LinkOnceODRLinkage;
+ // For COFF, put the counters, data, and values each into their own
+ // comdats. We can't use a group because the Visual C++ linker will
+ // report duplicate symbol errors if there are multiple external symbols
+ // with the same name marked IMAGE_COMDAT_SELECT_ASSOCIATIVE.
+ Linkage = GlobalValue::LinkOnceODRLinkage;
+ Visibility = GlobalValue::HiddenVisibility;
+ } else {
+ // Otherwise, create one comdat group for everything.
+ Cmdt = M->getOrInsertComdat(getVarName(Inc, getInstrProfComdatPrefix()));
}
- Cmdt = M->getOrInsertComdat(getVarName(Inc, CmdtPrefix));
}
+ auto MaybeSetComdat = [=](GlobalVariable *GV) {
+ if (NeedComdat)
+ GV->setComdat(Cmdt ? Cmdt : M->getOrInsertComdat(GV->getName()));
+ };
uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
LLVMContext &Ctx = M->getContext();
@@ -776,8 +781,8 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
CounterPtr->setSection(
getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat()));
CounterPtr->setAlignment(8);
- CounterPtr->setComdat(Cmdt);
- CounterPtr->setLinkage(CounterLinkage);
+ MaybeSetComdat(CounterPtr);
+ CounterPtr->setLinkage(Linkage);
auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
// Allocate statically the array of pointers to value profile nodes for
@@ -798,7 +803,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
ValuesVar->setSection(
getInstrProfSectionName(IPSK_vals, TT.getObjectFormat()));
ValuesVar->setAlignment(8);
- ValuesVar->setComdat(Cmdt);
+ MaybeSetComdat(ValuesVar);
ValuesPtrExpr =
ConstantExpr::getBitCast(ValuesVar, Type::getInt8PtrTy(Ctx));
}
@@ -831,7 +836,8 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
Data->setVisibility(Visibility);
Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat()));
Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT);
- Data->setComdat(Cmdt);
+ MaybeSetComdat(Data);
+ Data->setLinkage(Linkage);
PD.RegionCounters = CounterPtr;
PD.DataVar = Data;