dexonsmith added a comment.

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

> In D105959#2882099 <https://reviews.llvm.org/D105959#2882099>, @bondhugula 
> wrote:
>
>> This is a really welcome change! Multiple registration issues were really an 
>> inconvenience - I had no clue this was the pattern to use to fix it. Thanks!
>
> To be fair: we can do it transparently only for libSupport, as it contains 
> the entry point for command line parsing it can explicitly trigger the 
> registration of the options for itself. Other libraries in LLVM don't have 
> this luxury...

We could probably combine this with the technique used to avoid static 
constructors in compiler-rt/lib/profile to pick up other libraries in the same 
final linked image. The idea would be to ask the linker to build an array of 
initializer functions that LLVMSupport could iterate through to initialize 
options it doesn't know about.

For example, on Darwin, this code adds an initializer to a global array in 
section `__DATA,__llvmopts`:

  using OptionConstructorT = void (*)(); // Declared in LLVMSupport headers to 
get safety.
  
  void initOptions();
  
  // Add an options constructor the array of cl::opt initializers.
  __attribute__((section("__DATA,__llvmopts"),visibility("hidden")))
  OptionConstructorT OptionsConstructor = initOptions;

Also on Darwin, this could go in LLVMSupport to access it:

  using OptionConstructorT = void (*)(); // Declared in LLVMSupport headers to 
get safety.
  
  // Declare symbols to access the global array.
  extern OptionConstructorT *ExternalOptionsInitBegin
    __asm("section$start$__DATA$__llvmopts");
  extern OptionConstructorT *ExternalOptionsInitEnd
    __asm("section$end$__DATA$__llvmopts");
  
  void initCommonOptions();
  void initOptions() {
    initCommonOptions();
    // Iterate through external initializers for options.
    for (auto I = ExternalOptionsInitBegin, E = ExternalOptionsInitEnd; I != E; 
++I)
      (*I)();
  }

The relevant code for other platforms is in 
`compiler-rt/lib/profile/InstrProfilingPlatform*.c`.

If we did this, we'd maybe want to control it with a CMake configuration? When 
off (always for platforms where we don't have/know the magic incantations), the 
various `initOptions()` would be added to static initializers as before. When 
on, we could add `-Werror=global-constructors` to other libraries (once they're 
clean).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105959

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to