[PATCH] D105959: Use ManagedStatic and lazy initialization of cl::opt in libSupport to make it free of global initializer

Duncan P. N. Exon Smith via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 16 12:06:17 PDT 2021


dexonsmith added a comment.

In D105959#2883954 <https://reviews.llvm.org/D105959#2883954>, @mehdi_amini wrote:

> That's interesting!
>
> I'm not sure how to get there though: a complete solution should be able to "degrade" to global constructor when the platform-specific logic isn't available (unless we're confident that no such environment can exist?).

Right, it needs to downgrade (and I think there should be a CMake flag to turn it off in case there are reasons some LLVM user doesn't want it).

I think this would work:

  #ifdef USE_DARWIN_CLOPT
  // Add F to the list of initializers for LLVMSupport to iterate through.
  #define LLVM_ADD_CLOPT_CONSTRUCTOR(F, V) \
    __attribute__((section("__DATA,__llvmopts"),visibility("hidden"))) \
    void (*V)() = F;
  #elif defined(...) // Handle magic for other platforms.
  #else
  // Create a local symbol with a static initializer that calls F.
  #define LLVM_ADD_CLOPT_CONSTRUCTOR(F, V) \
    namespace { struct V##Type { V##Type() { F(); } } V; }
  #endif
  
  void initOptions();
  // Add an options constructor the array of cl::opt initializers.
  LLVM_ADD_CLOPT_CONSTRUCTOR(initOptions, OptionsConstructorVariable);

but maybe there's a cleaner downgrade that doesn't add an extra type.

In D105959#2883956 <https://reviews.llvm.org/D105959#2883956>, @mehdi_amini wrote:

> Something else I'm not sure about is how it works across DSOs: when each LLVM library is linked into its own shared library, is the dynamic linker creating this array when loading the libraries? (I'm starting to doubt about how this would even work on windows)

Yeah, this technique only works within a single final linked image. It'd need to be off when the library isn't statically linked to LLVMSupport.

I imagine we'd want CMake to just "get this right" for us, but we can also enforce this at link time to catch configuration errors -- add a (dead-strippable) symbol to LLVMSupport that's `visibility("hidden")`, and manufacture a (dead-strippable) reference to it in any TU that uses the macro. If the TU ends up in a different linked image than LLVMSupport you'll get a link error.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105959/new/

https://reviews.llvm.org/D105959



More information about the cfe-commits mailing list