summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-09-16 18:49:09 +0000
committerReid Kleckner <rnk@google.com>2019-09-16 18:49:09 +0000
commit32837a0c93ecdb33faaba253c5c7e868db9c529f (patch)
tree84f12b4bff2056281f07b7998368da2f1eb3e26d /llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
parent69911b8d01c6cf31a3af787d3f7352292cb0f9e4 (diff)
downloadbcm5719-llvm-32837a0c93ecdb33faaba253c5c7e868db9c529f.tar.gz
bcm5719-llvm-32837a0c93ecdb33faaba253c5c7e868db9c529f.zip
[PGO] Use linkonce_odr linkage for __profd_ variables in comdat groups
This fixes relocations against __profd_ symbols in discarded sections, which is PR41380. In general, instrumentation happens very early, and optimization and inlining happens afterwards. The counters for a function are calculated early, and after inlining, counters for an inlined function may be widely referenced by other functions. For C++ inline functions of all kinds (linkonce_odr & available_externally mainly), instr profiling wants to deduplicate these __profc_ and __profd_ globals. Otherwise the binary would be quite large. I made __profd_ and __profc_ comdat in r355044, but I chose to make __profd_ internal. At the time, I was only dealing with coverage, and in that case, none of the instrumentation needs to reference __profd_. However, if you use PGO, then instrumentation passes add calls to __llvm_profile_instrument_range which reference __profd_ globals. The solution is to make these globals externally visible by using linkonce_odr linkage for data as was done for counters. This is safe because PGO adds a CFG hash to the names of the data and counter globals, so if different TUs have different globals, they will get different data and counter arrays. Reviewers: xur, hans Differential Revision: https://reviews.llvm.org/D67579 llvm-svn: 372020
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp')
-rw-r--r--llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp15
1 files changed, 8 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index a21604ad7df..65773bb6050 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -740,9 +740,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();
@@ -759,15 +758,16 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
// 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();
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.
+ // something externally visible, like linkonce_odr. Use hidden visibility
+ // to imply that this is dso local.
CmdtPrefix = getInstrProfCountersVarPrefix();
- CounterLinkage = GlobalValue::LinkOnceODRLinkage;
+ Linkage = GlobalValue::LinkOnceODRLinkage;
+ Visibility = GlobalValue::HiddenVisibility;
}
Cmdt = M->getOrInsertComdat(getVarName(Inc, CmdtPrefix));
}
@@ -786,7 +786,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat()));
CounterPtr->setAlignment(8);
CounterPtr->setComdat(Cmdt);
- CounterPtr->setLinkage(CounterLinkage);
+ CounterPtr->setLinkage(Linkage);
auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
// Allocate statically the array of pointers to value profile nodes for
@@ -841,6 +841,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat()));
Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT);
Data->setComdat(Cmdt);
+ Data->setLinkage(Linkage);
PD.RegionCounters = CounterPtr;
PD.DataVar = Data;
OpenPOWER on IntegriCloud