Skip to content

Commit 33a7b4d

Browse files
committed
[InstrProfiling] Use external weak reference for bias variable
We need the compiler generated variable to override the weak symbol of the same name inside the profile runtime, but using LinkOnceODRLinkage results in weak symbol being emitted which leads to an issue where the linker might choose either of the weak symbols potentially disabling the runtime counter relocation. This change replaces the use of weak definition inside the runtime with an external weak reference to address the issue. We also place the compiler generated symbol inside a COMDAT group so dead definition can be garbage collected by the linker. Differential Revision: https://reviews.llvm.org/D105176
1 parent 14d64be commit 33a7b4d

File tree

7 files changed

+21
-26
lines changed

7 files changed

+21
-26
lines changed

compiler-rt/lib/profile/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ set(PROFILE_SOURCES
5353
InstrProfiling.c
5454
InstrProfilingInternal.c
5555
InstrProfilingValue.c
56-
InstrProfilingBiasVar.c
5756
InstrProfilingBuffer.c
5857
InstrProfilingFile.c
5958
InstrProfilingMerge.c

compiler-rt/lib/profile/InstrProfiling.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,10 @@ extern uint64_t INSTR_PROF_RAW_VERSION_VAR; /* __llvm_profile_raw_version */
320320
extern char INSTR_PROF_PROFILE_NAME_VAR[1]; /* __llvm_profile_filename. */
321321

322322
/*!
323-
* This variable is a weak symbol defined in InstrProfilingBiasVar.c. It
324-
* allows compiler instrumentation to provide overriding definition with
325-
* value from compiler command line. This variable has hidden visibility.
323+
* This variable is a weak external reference which could be used to detect
324+
* whether or not the compiler defined this symbol.
326325
*/
327-
COMPILER_RT_VISIBILITY extern intptr_t __llvm_profile_counter_bias;
326+
COMPILER_RT_VISIBILITY COMPILER_RT_WEAK extern intptr_t
327+
__llvm_profile_counter_bias;
328328

329329
#endif /* PROFILE_INSTRPROFILING_H_ */

compiler-rt/lib/profile/InstrProfilingBiasVar.c

Lines changed: 0 additions & 15 deletions
This file was deleted.

compiler-rt/lib/profile/InstrProfilingFile.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,9 @@ void __llvm_profile_initialize_file(void) {
999999
ProfileNameSpecifier PNS = PNS_unknown;
10001000
int hasCommandLineOverrider = (INSTR_PROF_PROFILE_NAME_VAR[0] != 0);
10011001

1002-
if (__llvm_profile_counter_bias != -1)
1002+
/* This symbol is defined by the compiler when runtime counter relocation is
1003+
* used and runtime provides a weak external reference so we can check it. */
1004+
if (&__llvm_profile_counter_bias)
10031005
lprofSetRuntimeCounterRelocation(1);
10041006

10051007
EnvFilenamePat = getFilenamePatFromEnv();

compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,9 @@ void __llvm_profile_initialize(void) {
116116
return;
117117
}
118118

119-
/* This symbol is defined as weak and initialized to -1 by the runtimer, but
120-
* compiler will generate a strong definition initialized to 0 when runtime
121-
* counter relocation is used. */
122-
if (__llvm_profile_counter_bias == -1) {
119+
/* This symbol is defined by the compiler when runtime counter relocation is
120+
* used and runtime provides a weak external reference so we can check it. */
121+
if (!&__llvm_profile_counter_bias) {
123122
lprofWrite("LLVM Profile: counter relocation at runtime is required\n");
124123
return;
125124
}

llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,10 +690,19 @@ void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
690690
Type *Int64Ty = Type::getInt64Ty(M->getContext());
691691
GlobalVariable *Bias = M->getGlobalVariable(getInstrProfCounterBiasVarName());
692692
if (!Bias) {
693+
// Compiler must define this variable when runtime counter relocation
694+
// is being used. Runtime has a weak external reference that is used
695+
// to check whether that's the case or not.
693696
Bias = new GlobalVariable(*M, Int64Ty, false, GlobalValue::LinkOnceODRLinkage,
694697
Constant::getNullValue(Int64Ty),
695698
getInstrProfCounterBiasVarName());
696699
Bias->setVisibility(GlobalVariable::HiddenVisibility);
700+
// A definition that's weak (linkonce_odr) without being in a COMDAT
701+
// section wouldn't lead to link errors, but it would lead to a dead
702+
// data word from every TU but one. Putting it in COMDAT ensures there
703+
// will be exactly one data slot in the link.
704+
if (TT.supportsCOMDAT())
705+
Bias->setComdat(M->getOrInsertComdat(Bias->getName()));
697706
}
698707
LI = Builder.CreateLoad(Int64Ty, Bias);
699708
}

llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
target triple = "x86_64-unknown-linux-gnu"
55

66
@__profn_foo = private constant [3 x i8] c"foo"
7-
; RELOC: @__llvm_profile_counter_bias = linkonce_odr hidden global i64 0
7+
; RELOC: $__llvm_profile_counter_bias = comdat any
8+
; RELOC: @__llvm_profile_counter_bias = linkonce_odr hidden global i64 0, comdat
89

910
; CHECK-LABEL: define void @foo
1011
; CHECK-NEXT: %pgocount = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)

0 commit comments

Comments
 (0)