This is an archive of the discontinued LLVM Phabricator instance.

[PGO][AIX] Improve dummy var retention and allow -bcdtors:csect linking.
ClosedPublic

Authored by w2yehia on Oct 18 2022, 11:59 AM.

Details

Summary

This patch subsumes https://reviews.llvm.org/D134253.
It addresses a couple of problems:

  1. The problem addressed by D134253; namely, incorrect behavior when linking a shared library that has PGO into an executable with PGO (see LIT test below). The symbol keep was seen as duplicate, and one copy was thrown away; we want both to stay as keep was creating a reference to other internal symbols that we want the linker to keep.
  2. The keep symbol was visible to the user and would conflict with a user symbol with the same name.
  3. When compiling and linking with -ffunction-sections -Wl,-bcdtors:mbr, the PGO runtime was not initialized.
  4. When compiling and linking with -ffunction-sections -Wl,-bcdtors:csect, the PGO runtime was not initialized. The constructor function that does the runtime registration must be associated to a live variable, otherwise under the semantics of -Wl,-bcdtors:csect it would get GC'ed by the linker.

The following changes are made:

  1. Convert the library-internal function keep into an array (__llvm_profile_keep) that references the dummy variables that we want to retain.
  2. associate the liveness of __llvm_profile_keep with the runtime registration variable since we want that array to be live when the profile write out code is.
  3. Preserve the runtime hook variable (__llvm_profile_runtime) explicitly on AIX, same as on Linux.
  4. On AIX only, perform the runtime registration from a constructor of a variable that is guaranteed to be live; so we chose the runtime hook as that variable. This is needed to allow linking PGO rt with -Wl,-bcdtors:csect.
  5. Refactor the runtime registration logic to accomodate for AIX.

Diff Detail

Event Timeline

w2yehia created this revision.Oct 18 2022, 11:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 18 2022, 11:59 AM
w2yehia requested review of this revision.Oct 18 2022, 11:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 18 2022, 11:59 AM
hubert.reinterpretcast added inline comments.
compiler-rt/lib/profile/InstrProfilingRuntime.cpp
37

Should follow the example of __llvm_profile_runtime, etc. in terms of using __llvm_profile_ as the prefix.

clang/lib/Driver/ToolChains/AIX.cpp
356
359

Don't need to use MakeArgString to persist a string literal.

compiler-rt/lib/profile/InstrProfilingRuntime.cpp
17–18

The class still needs to be in an unnamed namespace for the constructor to not clash with a user-defined class with the same name.

w2yehia added inline comments.Oct 19 2022, 8:53 AM
compiler-rt/lib/profile/InstrProfilingRuntime.cpp
17–18

yes, i had a follow up patch that I was testing on both linux and AIX that gets rid of the class all together:

-namespace {
-
-class RegisterRuntime {
-public:
-  RegisterRuntime() {
-    __llvm_profile_initialize();
-  }
-};
-
-RegisterRuntime Registration;
-
+static int RegisterRuntime() {
+  __llvm_profile_initialize();
+  return 0;
 }
+
+#ifdef _AIX
+COMPILER_RT_VISIBILITY
+#else
+static
+#endif
+int __llvm_register_runtime = RegisterRuntime();
w2yehia updated this revision to Diff 469261.Oct 20 2022, 9:38 AM
w2yehia retitled this revision from [AIX][PGO] WIP to [PGO][AIX] Improve dummy var retention and allow -bcdtors:csect linking..
w2yehia edited the summary of this revision. (Show Details)

Improve the current patch and integrate D134253 into it.

w2yehia updated this revision to Diff 469290.Oct 20 2022, 10:48 AM

Don't move around code in InstrProfilingPlatformLinux.c

w2yehia marked 4 inline comments as done.Oct 20 2022, 10:49 AM
w2yehia edited the summary of this revision. (Show Details)Oct 20 2022, 11:19 AM

@phosek @MaskRay If you can kindly review this patch as it affects non-AIX platforms with the changes in compiler-rt/lib/profile/InstrProfilingRuntime.cpp. I'm hoping the change are like for like but I cannot be sure for all platforms.

w2yehia edited reviewers, added: phosek; removed: phodju.Oct 20 2022, 12:26 PM

This LGTM. Size of Registration changes from 1 byte to (likely) 4 bytes on non-AIX platforms and now incurs an extra memory write, but that should be insignificant.

This revision is now accepted and ready to land.Oct 20 2022, 4:15 PM
This revision was landed with ongoing or failed builds.Oct 21 2022, 9:33 AM
This revision was automatically updated to reflect the committed changes.
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptOct 21 2022, 9:33 AM
Herald added subscribers: Restricted Project, cfe-commits. · View Herald Transcript
phosek added inline comments.
compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
265–267

Does AIX linker support the retain attribute? That would be a cleaner solution.

compiler-rt/lib/profile/InstrProfilingRuntime.cpp
13–18

Is it possible to reuse the runtime hook variable on other platforms as well? I'd really like to avoid introducing another variable.

I wasn't included as a reviewer on D124857 and I missed that change so couldn't comment there, but I'm not a fan of including the AIX support in InstrProfilingPlatformLinux.c. AIX is neither Linux nor ELF-based and big chunks of that file are now #ifdefed out making it harder to comprehend which part is used where. I'd prefer introducing InstrProfilingPlatformAIX.c, moving the AIX-specific logic there, and then figuring out how to possibly share common parts between InstrProfilingPlatformLinux.c and InstrProfilingPlatformAIX.c, for example by moving them to an .inc file.

I wasn't included as a reviewer on D124857 and I missed that change so couldn't comment there, but I'm not a fan of including the AIX support in InstrProfilingPlatformLinux.c. AIX is neither Linux nor ELF-based and big chunks of that file are now #ifdefed out making it harder to comprehend which part is used where. I'd prefer introducing InstrProfilingPlatformAIX.c, moving the AIX-specific logic there, and then figuring out how to possibly share common parts between InstrProfilingPlatformLinux.c and InstrProfilingPlatformAIX.c, for example by moving them to an .inc file.

Splitting was considered but because AIX reuses the entirety of that file (except two #include's) and adds some AIX-only stuff it seemed better not to duplicate the common code. Doing a .inc file was not considered. The .inc file will have to contain the entire InstrProfilingPlatformLinux.c content.
Let me know if you want me to post a patch for the .inc. Thanks

compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
265–267

thanks for pointing out. Unfortunately the retain attribute is not supported by the AIX linker. It could be implemented on the compiler side, but as of now it's not supported by the build compiler on AIX.

compiler-rt/lib/profile/InstrProfilingRuntime.cpp
13–18

I also wanted to do that but didn't in fear of breaking others. I can do the change and see what breaks?