Skip to content

Commit 2407c13

Browse files
author
Wael Yehia
committed
[AIX][PGO] Enable linux style PGO on AIX
This patch switches the PGO implementation on AIX from using the runtime registration-based section tracking to the __start_SECNAME/__stop_SECNAME based. In order to enable the recognition of __start_SECNAME/__stop_SECNAME symbols in the AIX linker, the -bdbg:namedsects:ss needs to be used. Reviewed By: jsji, MaskRay, davidxl Differential Revision: https://reviews.llvm.org/D124857
1 parent 58abe36 commit 2407c13

File tree

7 files changed

+51
-14
lines changed

7 files changed

+51
-14
lines changed

clang/lib/Driver/ToolChains/AIX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
117117
options::OPT_fno_profile_generate, false) ||
118118
Args.hasArg(options::OPT_fcreate_profile) ||
119119
Args.hasArg(options::OPT_coverage))
120-
CmdArgs.push_back("-bdbg:namedsects");
120+
CmdArgs.push_back("-bdbg:namedsects:ss");
121121

122122
// Specify linker output file.
123123
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");

clang/test/Driver/aix-ld.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@
664664
// CHECK-PGO-NON-LTO: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
665665
// CHECK-PGO-NON-LTO: "-isysroot" "[[SYSROOT:[^"]+]]"
666666
// CHECK-PGO-NON-LTO: "{{.*}}ld{{(.exe)?}}"
667-
// CHECK-PGO-NON-LTO: "-bdbg:namedsects"
667+
// CHECK-PGO-NON-LTO: "-bdbg:namedsects:ss"
668668
// CHECK-PGO-NON-LTO: "-b32"
669669
// CHECK-PGO-NON-LTO: "-bpT:0x10000000" "-bpD:0x20000000"
670670
// CHECK-PGO-NON-LTO: "[[SYSROOT]]/usr/lib{{/|\\\\}}crt0.o"
@@ -692,7 +692,7 @@
692692
// CHECK-PGO-LTO: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
693693
// CHECK-PGO-LTO: "-isysroot" "[[SYSROOT:[^"]+]]"
694694
// CHECK-PGO-LTO: "{{.*}}ld{{(.exe)?}}"
695-
// CHECK-PGO-LTO: "-bdbg:namedsects"
695+
// CHECK-PGO-LTO: "-bdbg:namedsects:ss"
696696
// CHECK-PGO-LTO: "-b32"
697697
// CHECK-PGO-LTO: "-bpT:0x10000000" "-bpD:0x20000000"
698698
// CHECK-PGO-LTO: "[[SYSROOT]]/usr/lib{{/|\\\\}}crt0.o"

compiler-rt/lib/profile/InstrProfilingPlatformLinux.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
\*===----------------------------------------------------------------------===*/
88

99
#if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
10-
(defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__)
10+
(defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
11+
defined(_AIX)
1112

13+
#if !defined(_AIX)
1214
#include <elf.h>
1315
#include <link.h>
16+
#endif
1417
#include <stdlib.h>
1518
#include <string.h>
1619

@@ -227,4 +230,43 @@ COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) {
227230
}
228231
#endif
229232

233+
#if defined(_AIX)
234+
// Empty stubs to allow linking object files using the registration-based scheme
235+
COMPILER_RT_VISIBILITY
236+
void __llvm_profile_register_function(void *Data_) {}
237+
238+
COMPILER_RT_VISIBILITY
239+
void __llvm_profile_register_names_function(void *NamesStart,
240+
uint64_t NamesSize) {}
241+
242+
// The __start_SECNAME and __stop_SECNAME symbols (for SECNAME \in
243+
// {"__llvm_prf_cnts", "__llvm_prf_data", "__llvm_prf_name", "__llvm_prf_vnds"})
244+
// are always live when linking on AIX, regardless if the .o's being linked
245+
// reference symbols from the profile library (for example when no files were
246+
// compiled with -fprofile-generate). That's because these symbols are kept
247+
// alive through references in constructor functions that are always live in the
248+
// default linking model on AIX (-bcdtors:all). The __start_SECNAME and
249+
// __stop_SECNAME symbols are only resolved by the linker when the SECNAME
250+
// section exists. So for the scenario where the user objects have no such
251+
// section (i.e. when they are compiled with -fno-profile-generate), we always
252+
// define these zero length variables in each of the above 4 sections.
253+
COMPILER_RT_VISIBILITY int dummy_cnts[0] COMPILER_RT_SECTION(
254+
COMPILER_RT_SEG INSTR_PROF_CNTS_SECT_NAME);
255+
COMPILER_RT_VISIBILITY int dummy_data[0] COMPILER_RT_SECTION(
256+
COMPILER_RT_SEG INSTR_PROF_DATA_SECT_NAME);
257+
COMPILER_RT_VISIBILITY const int dummy_name[0] COMPILER_RT_SECTION(
258+
COMPILER_RT_SEG INSTR_PROF_NAME_SECT_NAME);
259+
COMPILER_RT_VISIBILITY int dummy_vnds[0] COMPILER_RT_SECTION(
260+
COMPILER_RT_SEG INSTR_PROF_VNODES_SECT_NAME);
261+
262+
// Create a fake reference to avoid GC'ing of the dummy variables by the linker.
263+
// Ideally, we create a ".ref" of each variable inside the function
264+
// __llvm_profile_begin_counters(), but there's no source level construct
265+
// that allows us to generate that.
266+
__attribute__((destructor)) void keep() {
267+
int volatile use = &dummy_cnts < &dummy_data && &dummy_name < &dummy_vnds;
268+
(void)use;
269+
}
270+
#endif
271+
230272
#endif

compiler-rt/lib/profile/InstrProfilingPlatformOther.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \
1010
!defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) && \
11-
!defined(__NetBSD__) && !defined(_WIN32)
11+
!defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX)
1212

1313
#include <stdlib.h>
1414
#include <stdio.h>

llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) {
855855
if (TT.isOSDarwin())
856856
return false;
857857
// Use linker script magic to get data/cnts/name start/end.
858-
if (TT.isOSLinux() || TT.isOSFreeBSD() || TT.isOSNetBSD() ||
858+
if (TT.isOSAIX() || TT.isOSLinux() || TT.isOSFreeBSD() || TT.isOSNetBSD() ||
859859
TT.isOSSolaris() || TT.isOSFuchsia() || TT.isPS4() || TT.isOSWindows())
860860
return false;
861861

llvm/test/Instrumentation/InstrProfiling/platform.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
5050
; SOLARIS-NOT: define internal void @__llvm_profile_register_functions
5151
; PS4-NOT: define internal void @__llvm_profile_register_functions
5252
; WINDOWS-NOT: define internal void @__llvm_profile_register_functions
53-
; AIX: define internal void @__llvm_profile_register_functions
53+
; AIX-NOT: define internal void @__llvm_profile_register_functions
5454

5555
;; PR38340: When dynamic registration is used, we had a bug where we'd register
5656
;; something that's not a __profd_* variable.
@@ -61,4 +61,4 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
6161
; SOLARIS-NOT: define internal void @__llvm_profile_init
6262
; PS4-NOT: define internal void @__llvm_profile_init
6363
; WINDOWS-NOT: define internal void @__llvm_profile_init
64-
; AIX: define internal void @__llvm_profile_init
64+
; AIX-NOT: define internal void @__llvm_profile_init

llvm/test/Instrumentation/InstrProfiling/profiling.ll

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,4 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
119119
; ELF_GENERIC-NEXT: ret void
120120
; ELF_GENERIC-NEXT: }
121121

122-
; XCOFF: define internal void @__llvm_profile_register_functions() unnamed_addr {
123-
; XCOFF-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64, i8*, i8*, i32, [{{.*}} x i16] }* @__profd_foo to i8*))
124-
; XCOFF-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64, i8*, i8*, i32, [{{.*}} x i16] }* @__profd_foo_weak to i8*))
125-
; XCOFF: call void @__llvm_profile_register_names_function(i8* getelementptr inbounds {{.*}} @__llvm_prf_nm
126-
; XCOFF-NEXT: ret void
127-
; XCOFF-NEXT: }
122+
; XCOFF-NOT: internal void @__llvm_profile_register_functions()

0 commit comments

Comments
 (0)