Skip to content

Commit 54902e0

Browse files
committed
[InstrProfiling] Use weak alias 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 in which case the symbol selected by the linker is going to depend on the order of inputs which can be fragile. This change replaces the use of weak definition inside the runtime with a weak alias. We place the compiler generated symbol inside a COMDAT group so dead definition can be garbage collected by the linker. We also disable the use of runtime counter relocation on Darwin since Mach-O doesn't support weak external references, but Darwin already uses a different continous mode that relies on overmapping so runtime counter relocation isn't needed there. Differential Revision: https://reviews.llvm.org/D105176
1 parent b988d69 commit 54902e0

File tree

14 files changed

+166
-162
lines changed

14 files changed

+166
-162
lines changed

compiler-rt/include/profile/InstrProfData.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
664664
#define VARIANT_MASK_INSTR_ENTRY (0x1ULL << 58)
665665
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
666666
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime
667+
#define INSTR_PROF_PROFILE_COUNTER_BIAS_VAR __llvm_profile_counter_bias
667668

668669
/* The variable that holds the name of the profile data
669670
* specified via command line. */

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: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,4 @@ extern uint64_t INSTR_PROF_RAW_VERSION_VAR; /* __llvm_profile_raw_version */
319319
*/
320320
extern char INSTR_PROF_PROFILE_NAME_VAR[1]; /* __llvm_profile_filename. */
321321

322-
/*!
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.
326-
*/
327-
COMPILER_RT_VISIBILITY extern intptr_t __llvm_profile_counter_bias;
328-
329322
#endif /* PROFILE_INSTRPROFILING_H_ */

compiler-rt/lib/profile/InstrProfilingBiasVar.c

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

compiler-rt/lib/profile/InstrProfilingBuffer.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,20 @@ static uint64_t calculateBytesNeededToPageAlign(uint64_t Offset) {
6767
return 0;
6868
}
6969

70+
static int needsCounterPadding(void) {
71+
#if defined(__APPLE__)
72+
return __llvm_profile_is_continuous_mode_enabled();
73+
#else
74+
return 0;
75+
#endif
76+
}
77+
7078
COMPILER_RT_VISIBILITY
7179
void __llvm_profile_get_padding_sizes_for_counters(
7280
uint64_t DataSize, uint64_t CountersSize, uint64_t NamesSize,
7381
uint64_t *PaddingBytesBeforeCounters, uint64_t *PaddingBytesAfterCounters,
7482
uint64_t *PaddingBytesAfterNames) {
75-
if (!__llvm_profile_is_continuous_mode_enabled() ||
76-
lprofRuntimeCounterRelocation()) {
83+
if (!needsCounterPadding()) {
7784
*PaddingBytesBeforeCounters = 0;
7885
*PaddingBytesAfterCounters = 0;
7986
*PaddingBytesAfterNames = __llvm_profile_get_num_padding_bytes(NamesSize);

compiler-rt/lib/profile/InstrProfilingFile.c

Lines changed: 132 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -426,33 +426,6 @@ static void truncateCurrentFile(void) {
426426
fclose(File);
427427
}
428428

429-
#if !defined(__Fuchsia__) && !defined(_WIN32)
430-
static void assertIsZero(int *i) {
431-
if (*i)
432-
PROF_WARN("Expected flag to be 0, but got: %d\n", *i);
433-
}
434-
435-
/* Write a partial profile to \p Filename, which is required to be backed by
436-
* the open file object \p File. */
437-
static int writeProfileWithFileObject(const char *Filename, FILE *File) {
438-
setProfileFile(File);
439-
int rc = writeFile(Filename);
440-
if (rc)
441-
PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno));
442-
setProfileFile(NULL);
443-
return rc;
444-
}
445-
446-
/* Unlock the profile \p File and clear the unlock flag. */
447-
static void unlockProfile(int *ProfileRequiresUnlock, FILE *File) {
448-
if (!*ProfileRequiresUnlock) {
449-
PROF_WARN("%s", "Expected to require profile unlock\n");
450-
}
451-
lprofUnlockFileHandle(File);
452-
*ProfileRequiresUnlock = 0;
453-
}
454-
#endif // !defined(__Fuchsia__) && !defined(_WIN32)
455-
456429
static int writeMMappedFile(FILE *OutputFile, char **Profile) {
457430
if (!OutputFile)
458431
return -1;
@@ -481,83 +454,38 @@ static int writeMMappedFile(FILE *OutputFile, char **Profile) {
481454
return 0;
482455
}
483456

484-
static void relocateCounters(void) {
485-
if (!__llvm_profile_is_continuous_mode_enabled() ||
486-
!lprofRuntimeCounterRelocation())
487-
return;
488-
489-
/* Get the sizes of various profile data sections. Taken from
490-
* __llvm_profile_get_size_for_buffer(). */
491-
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
492-
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
493-
const uint64_t *CountersBegin = __llvm_profile_begin_counters();
494-
const uint64_t *CountersEnd = __llvm_profile_end_counters();
495-
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
496-
const uint64_t CountersOffset = sizeof(__llvm_profile_header) +
497-
(DataSize * sizeof(__llvm_profile_data));
498-
499-
int Length = getCurFilenameLength();
500-
char *FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1);
501-
const char *Filename = getCurFilename(FilenameBuf, 0);
502-
if (!Filename)
503-
return;
504-
505-
FILE *File = NULL;
506-
char *Profile = NULL;
507-
508-
if (!doMerging()) {
509-
File = fopen(Filename, "w+b");
510-
if (!File)
511-
return;
512-
513-
if (writeMMappedFile(File, &Profile) == -1) {
514-
fclose(File);
515-
return;
516-
}
517-
} else {
518-
File = lprofOpenFileEx(Filename);
519-
if (!File)
520-
return;
521-
522-
uint64_t ProfileFileSize = 0;
523-
if (getProfileFileSizeForMerging(File, &ProfileFileSize) == -1) {
524-
lprofUnlockFileHandle(File);
525-
fclose(File);
526-
return;
527-
}
457+
// TODO: Move these functions into InstrProfilingPlatform* files.
458+
#if defined(__APPLE__)
459+
static void assertIsZero(int *i) {
460+
if (*i)
461+
PROF_WARN("Expected flag to be 0, but got: %d\n", *i);
462+
}
528463

529-
if (!ProfileFileSize) {
530-
if (writeMMappedFile(File, &Profile) == -1) {
531-
fclose(File);
532-
return;
533-
}
534-
} else {
535-
/* The merged profile has a non-zero length. Check that it is compatible
536-
* with the data in this process. */
537-
if (mmapProfileForMerging(File, ProfileFileSize, &Profile) == -1) {
538-
fclose(File);
539-
return;
540-
}
541-
}
464+
/* Write a partial profile to \p Filename, which is required to be backed by
465+
* the open file object \p File. */
466+
static int writeProfileWithFileObject(const char *Filename, FILE *File) {
467+
setProfileFile(File);
468+
int rc = writeFile(Filename);
469+
if (rc)
470+
PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno));
471+
setProfileFile(NULL);
472+
return rc;
473+
}
542474

543-
lprofUnlockFileHandle(File);
475+
/* Unlock the profile \p File and clear the unlock flag. */
476+
static void unlockProfile(int *ProfileRequiresUnlock, FILE *File) {
477+
if (!*ProfileRequiresUnlock) {
478+
PROF_WARN("%s", "Expected to require profile unlock\n");
544479
}
545480

546-
/* Update the profile fields based on the current mapping. */
547-
__llvm_profile_counter_bias =
548-
(intptr_t)Profile - (uintptr_t)CountersBegin + CountersOffset;
549-
550-
/* Return the memory allocated for counters to OS. */
551-
lprofReleaseMemoryPagesToOS((uintptr_t)CountersBegin, (uintptr_t)CountersEnd);
481+
lprofUnlockFileHandle(File);
482+
*ProfileRequiresUnlock = 0;
552483
}
553484

554485
static void initializeProfileForContinuousMode(void) {
555486
if (!__llvm_profile_is_continuous_mode_enabled())
556487
return;
557488

558-
#if defined(__Fuchsia__) || defined(_WIN32)
559-
PROF_ERR("%s\n", "Continuous mode not yet supported on Fuchsia or Windows.");
560-
#else // defined(__Fuchsia__) || defined(_WIN32)
561489
/* Get the sizes of various profile data sections. Taken from
562490
* __llvm_profile_get_size_for_buffer(). */
563491
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
@@ -683,8 +611,109 @@ static void initializeProfileForContinuousMode(void) {
683611

684612
if (ProfileRequiresUnlock)
685613
unlockProfile(&ProfileRequiresUnlock, File);
686-
#endif // defined(__Fuchsia__) || defined(_WIN32)
687614
}
615+
#elif defined(__ELF__) || defined(_WIN32)
616+
617+
#define INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR \
618+
INSTR_PROF_CONCAT(INSTR_PROF_PROFILE_COUNTER_BIAS_VAR, _default)
619+
intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR = 0;
620+
621+
/* This variable is a weak external reference which could be used to detect
622+
* whether or not the compiler defined this symbol. */
623+
#if defined(_WIN32)
624+
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_VAR;
625+
#pragma comment(linker, "/alternatename:" \
626+
INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_COUNTER_BIAS_VAR) "=" \
627+
INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR))
628+
#else
629+
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_VAR
630+
__attribute__((weak, alias(INSTR_PROF_QUOTE(
631+
INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR))));
632+
#endif
633+
634+
static void initializeProfileForContinuousMode(void) {
635+
if (!__llvm_profile_is_continuous_mode_enabled())
636+
return;
637+
638+
/* This symbol is defined by the compiler when runtime counter relocation is
639+
* used and runtime provides a weak alias so we can check if it's defined. */
640+
void *BiasAddr = &INSTR_PROF_PROFILE_COUNTER_BIAS_VAR;
641+
void *BiasDefaultAddr = &INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR;
642+
if (BiasAddr == BiasDefaultAddr) {
643+
PROF_ERR("%s\n", "__llvm_profile_counter_bias is undefined");
644+
return;
645+
}
646+
647+
/* Get the sizes of various profile data sections. Taken from
648+
* __llvm_profile_get_size_for_buffer(). */
649+
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
650+
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
651+
const uint64_t *CountersBegin = __llvm_profile_begin_counters();
652+
const uint64_t *CountersEnd = __llvm_profile_end_counters();
653+
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
654+
const uint64_t CountersOffset =
655+
sizeof(__llvm_profile_header) + (DataSize * sizeof(__llvm_profile_data));
656+
657+
int Length = getCurFilenameLength();
658+
char *FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1);
659+
const char *Filename = getCurFilename(FilenameBuf, 0);
660+
if (!Filename)
661+
return;
662+
663+
FILE *File = NULL;
664+
char *Profile = NULL;
665+
666+
if (!doMerging()) {
667+
File = fopen(Filename, "w+b");
668+
if (!File)
669+
return;
670+
671+
if (writeMMappedFile(File, &Profile) == -1) {
672+
fclose(File);
673+
return;
674+
}
675+
} else {
676+
File = lprofOpenFileEx(Filename);
677+
if (!File)
678+
return;
679+
680+
uint64_t ProfileFileSize = 0;
681+
if (getProfileFileSizeForMerging(File, &ProfileFileSize) == -1) {
682+
lprofUnlockFileHandle(File);
683+
fclose(File);
684+
return;
685+
}
686+
687+
if (!ProfileFileSize) {
688+
if (writeMMappedFile(File, &Profile) == -1) {
689+
fclose(File);
690+
return;
691+
}
692+
} else {
693+
/* The merged profile has a non-zero length. Check that it is compatible
694+
* with the data in this process. */
695+
if (mmapProfileForMerging(File, ProfileFileSize, &Profile) == -1) {
696+
fclose(File);
697+
return;
698+
}
699+
}
700+
701+
lprofUnlockFileHandle(File);
702+
}
703+
704+
/* Update the profile fields based on the current mapping. */
705+
INSTR_PROF_PROFILE_COUNTER_BIAS_VAR =
706+
(intptr_t)Profile - (uintptr_t)CountersBegin +
707+
CountersOffset;
708+
709+
/* Return the memory allocated for counters to OS. */
710+
lprofReleaseMemoryPagesToOS((uintptr_t)CountersBegin, (uintptr_t)CountersEnd);
711+
}
712+
#else
713+
static void initializeProfileForContinuousMode(void) {
714+
PROF_ERR("%s\n", "continuous mode is unsupported on this platform");
715+
}
716+
#endif
688717

689718
static const char *DefaultProfileName = "default.profraw";
690719
static void resetFilenameToDefault(void) {
@@ -784,9 +813,14 @@ static int parseFilenamePattern(const char *FilenamePat,
784813
FilenamePat);
785814
return -1;
786815
}
787-
816+
#if defined(__APPLE__) || defined(__ELF__) || defined(_WIN32)
788817
__llvm_profile_set_page_size(getpagesize());
789818
__llvm_profile_enable_continuous_mode();
819+
#else
820+
PROF_WARN("%s", "Continous mode is currently only supported for Mach-O,"
821+
" ELF and COFF formats.");
822+
return -1;
823+
#endif
790824
} else {
791825
unsigned MergePoolSize = getMergePoolSize(FilenamePat, &I);
792826
if (!MergePoolSize)
@@ -843,12 +877,8 @@ static void parseAndSetFilename(const char *FilenamePat,
843877
}
844878

845879
truncateCurrentFile();
846-
if (__llvm_profile_is_continuous_mode_enabled()) {
847-
if (lprofRuntimeCounterRelocation())
848-
relocateCounters();
849-
else
850-
initializeProfileForContinuousMode();
851-
}
880+
if (__llvm_profile_is_continuous_mode_enabled())
881+
initializeProfileForContinuousMode();
852882
}
853883

854884
/* Return buffer length that is required to store the current profile
@@ -1004,9 +1034,6 @@ void __llvm_profile_initialize_file(void) {
10041034
ProfileNameSpecifier PNS = PNS_unknown;
10051035
int hasCommandLineOverrider = (INSTR_PROF_PROFILE_NAME_VAR[0] != 0);
10061036

1007-
if (__llvm_profile_counter_bias != -1)
1008-
lprofSetRuntimeCounterRelocation(1);
1009-
10101037
EnvFilenamePat = getFilenamePatFromEnv();
10111038
if (EnvFilenamePat) {
10121039
/* Pass CopyFilenamePat = 1, to ensure that the filename would be valid

compiler-rt/lib/profile/InstrProfilingInternal.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,4 @@ COMPILER_RT_VISIBILITY void lprofSetProfileDumped(unsigned Value) {
2323
ProfileDumped = Value;
2424
}
2525

26-
static unsigned RuntimeCounterRelocation = 0;
27-
28-
COMPILER_RT_VISIBILITY unsigned lprofRuntimeCounterRelocation(void) {
29-
return RuntimeCounterRelocation;
30-
}
31-
32-
COMPILER_RT_VISIBILITY void lprofSetRuntimeCounterRelocation(unsigned Value) {
33-
RuntimeCounterRelocation = Value;
34-
}
35-
3626
#endif

compiler-rt/lib/profile/InstrProfilingInternal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,6 @@ uint64_t lprofGetLoadModuleSignature();
184184
unsigned lprofProfileDumped(void);
185185
void lprofSetProfileDumped(unsigned);
186186

187-
/* Return non zero value if counters are being relocated at runtime. */
188-
unsigned lprofRuntimeCounterRelocation(void);
189-
void lprofSetRuntimeCounterRelocation(unsigned);
190-
191187
COMPILER_RT_VISIBILITY extern void (*FreeHook)(void *);
192188
COMPILER_RT_VISIBILITY extern uint8_t *DynamicBufferIOBuffer;
193189
COMPILER_RT_VISIBILITY extern uint32_t VPBufferSize;

0 commit comments

Comments
 (0)