Author: Wael Yehia Date: 2022-05-05T04:10:39Z New Revision: 2407c13aa4a42f3a3438ae2d03fa38df0a5fd30b
URL: https://github.com/llvm/llvm-project/commit/2407c13aa4a42f3a3438ae2d03fa38df0a5fd30b DIFF: https://github.com/llvm/llvm-project/commit/2407c13aa4a42f3a3438ae2d03fa38df0a5fd30b.diff LOG: [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 Added: Modified: clang/lib/Driver/ToolChains/AIX.cpp clang/test/Driver/aix-ld.c compiler-rt/lib/profile/InstrProfilingPlatformLinux.c compiler-rt/lib/profile/InstrProfilingPlatformOther.c llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp llvm/test/Instrumentation/InstrProfiling/platform.ll llvm/test/Instrumentation/InstrProfiling/profiling.ll Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index 37316a792f6d12..878b84a777027c 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -117,7 +117,7 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_profile_generate, false) || Args.hasArg(options::OPT_fcreate_profile) || Args.hasArg(options::OPT_coverage)) - CmdArgs.push_back("-bdbg:namedsects"); + CmdArgs.push_back("-bdbg:namedsects:ss"); // Specify linker output file. assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); diff --git a/clang/test/Driver/aix-ld.c b/clang/test/Driver/aix-ld.c index eccae132763d5e..3f4784daa1e3eb 100644 --- a/clang/test/Driver/aix-ld.c +++ b/clang/test/Driver/aix-ld.c @@ -664,7 +664,7 @@ // CHECK-PGO-NON-LTO: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-PGO-NON-LTO: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-PGO-NON-LTO: "{{.*}}ld{{(.exe)?}}" -// CHECK-PGO-NON-LTO: "-bdbg:namedsects" +// CHECK-PGO-NON-LTO: "-bdbg:namedsects:ss" // CHECK-PGO-NON-LTO: "-b32" // CHECK-PGO-NON-LTO: "-bpT:0x10000000" "-bpD:0x20000000" // CHECK-PGO-NON-LTO: "[[SYSROOT]]/usr/lib{{/|\\\\}}crt0.o" @@ -692,7 +692,7 @@ // CHECK-PGO-LTO: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-PGO-LTO: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-PGO-LTO: "{{.*}}ld{{(.exe)?}}" -// CHECK-PGO-LTO: "-bdbg:namedsects" +// CHECK-PGO-LTO: "-bdbg:namedsects:ss" // CHECK-PGO-LTO: "-b32" // CHECK-PGO-LTO: "-bpT:0x10000000" "-bpD:0x20000000" // CHECK-PGO-LTO: "[[SYSROOT]]/usr/lib{{/|\\\\}}crt0.o" diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c index 592c09b49d4b15..3af61d24948e7c 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c @@ -7,10 +7,13 @@ \*===----------------------------------------------------------------------===*/ #if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ - (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) + (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \ + defined(_AIX) +#if !defined(_AIX) #include <elf.h> #include <link.h> +#endif #include <stdlib.h> #include <string.h> @@ -227,4 +230,43 @@ COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) { } #endif +#if defined(_AIX) +// Empty stubs to allow linking object files using the registration-based scheme +COMPILER_RT_VISIBILITY +void __llvm_profile_register_function(void *Data_) {} + +COMPILER_RT_VISIBILITY +void __llvm_profile_register_names_function(void *NamesStart, + uint64_t NamesSize) {} + +// The __start_SECNAME and __stop_SECNAME symbols (for SECNAME \in +// {"__llvm_prf_cnts", "__llvm_prf_data", "__llvm_prf_name", "__llvm_prf_vnds"}) +// are always live when linking on AIX, regardless if the .o's being linked +// reference symbols from the profile library (for example when no files were +// compiled with -fprofile-generate). That's because these symbols are kept +// alive through references in constructor functions that are always live in the +// default linking model on AIX (-bcdtors:all). The __start_SECNAME and +// __stop_SECNAME symbols are only resolved by the linker when the SECNAME +// section exists. So for the scenario where the user objects have no such +// section (i.e. when they are compiled with -fno-profile-generate), we always +// define these zero length variables in each of the above 4 sections. +COMPILER_RT_VISIBILITY int dummy_cnts[0] COMPILER_RT_SECTION( + COMPILER_RT_SEG INSTR_PROF_CNTS_SECT_NAME); +COMPILER_RT_VISIBILITY int dummy_data[0] COMPILER_RT_SECTION( + COMPILER_RT_SEG INSTR_PROF_DATA_SECT_NAME); +COMPILER_RT_VISIBILITY const int dummy_name[0] COMPILER_RT_SECTION( + COMPILER_RT_SEG INSTR_PROF_NAME_SECT_NAME); +COMPILER_RT_VISIBILITY int dummy_vnds[0] COMPILER_RT_SECTION( + COMPILER_RT_SEG INSTR_PROF_VNODES_SECT_NAME); + +// Create a fake reference to avoid GC'ing of the dummy variables by the linker. +// Ideally, we create a ".ref" of each variable inside the function +// __llvm_profile_begin_counters(), but there's no source level construct +// that allows us to generate that. +__attribute__((destructor)) void keep() { + int volatile use = &dummy_cnts < &dummy_data && &dummy_name < &dummy_vnds; + (void)use; +} +#endif + #endif diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c index 7f535e6a32d6a8..c7b6e842c9fac2 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c @@ -8,7 +8,7 @@ #if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \ !defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) && \ - !defined(__NetBSD__) && !defined(_WIN32) + !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) #include <stdlib.h> #include <stdio.h> diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index 379c41ce669362..06c1b8990dbe61 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -855,7 +855,7 @@ static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) { if (TT.isOSDarwin()) return false; // Use linker script magic to get data/cnts/name start/end. - if (TT.isOSLinux() || TT.isOSFreeBSD() || TT.isOSNetBSD() || + if (TT.isOSAIX() || TT.isOSLinux() || TT.isOSFreeBSD() || TT.isOSNetBSD() || TT.isOSSolaris() || TT.isOSFuchsia() || TT.isPS4() || TT.isOSWindows()) return false; diff --git a/llvm/test/Instrumentation/InstrProfiling/platform.ll b/llvm/test/Instrumentation/InstrProfiling/platform.ll index e07264c478baa5..02b2c037316177 100644 --- a/llvm/test/Instrumentation/InstrProfiling/platform.ll +++ b/llvm/test/Instrumentation/InstrProfiling/platform.ll @@ -50,7 +50,7 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32) ; SOLARIS-NOT: define internal void @__llvm_profile_register_functions ; PS4-NOT: define internal void @__llvm_profile_register_functions ; WINDOWS-NOT: define internal void @__llvm_profile_register_functions -; AIX: define internal void @__llvm_profile_register_functions +; AIX-NOT: define internal void @__llvm_profile_register_functions ;; PR38340: When dynamic registration is used, we had a bug where we'd register ;; something that's not a __profd_* variable. @@ -61,4 +61,4 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32) ; SOLARIS-NOT: define internal void @__llvm_profile_init ; PS4-NOT: define internal void @__llvm_profile_init ; WINDOWS-NOT: define internal void @__llvm_profile_init -; AIX: define internal void @__llvm_profile_init +; AIX-NOT: define internal void @__llvm_profile_init diff --git a/llvm/test/Instrumentation/InstrProfiling/profiling.ll b/llvm/test/Instrumentation/InstrProfiling/profiling.ll index 8138552b42d591..b72a8bece714fa 100644 --- a/llvm/test/Instrumentation/InstrProfiling/profiling.ll +++ b/llvm/test/Instrumentation/InstrProfiling/profiling.ll @@ -119,9 +119,4 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32) ; ELF_GENERIC-NEXT: ret void ; ELF_GENERIC-NEXT: } -; XCOFF: define internal void @__llvm_profile_register_functions() unnamed_addr { -; XCOFF-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64, i8*, i8*, i32, [{{.*}} x i16] }* @__profd_foo to i8*)) -; XCOFF-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64, i8*, i8*, i32, [{{.*}} x i16] }* @__profd_foo_weak to i8*)) -; XCOFF: call void @__llvm_profile_register_names_function(i8* getelementptr inbounds {{.*}} @__llvm_prf_nm -; XCOFF-NEXT: ret void -; XCOFF-NEXT: } +; XCOFF-NOT: internal void @__llvm_profile_register_functions() _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits