diff options
author | Reid Kleckner <rnk@google.com> | 2019-09-16 18:49:09 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2019-09-16 18:49:09 +0000 |
commit | 32837a0c93ecdb33faaba253c5c7e868db9c529f (patch) | |
tree | 84f12b4bff2056281f07b7998368da2f1eb3e26d /llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp | |
parent | 69911b8d01c6cf31a3af787d3f7352292cb0f9e4 (diff) | |
download | bcm5719-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.cpp | 15 |
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; |