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

Reply via email to