<div dir="ltr"><div>Hi All,<br><br>There have been recent discussions about how to generate unique module identifiers which can be embedded in AIX static init function names.<br> <br>On AIX, static init functions are sinit/sterm pairs looking like this:<br><br><span style="font-family:times new roman,serif"><font size="2"><i>__sinit<priority #>_<unique module identifier><br>__sterm<priority #>_<unique module identifier></i></font></span><br><br>There is one sinit/sterm pair per priority number for each module.<br><br>The AIX linker collects static init functions simply based on their name. So we need to guarantee that each module has its own unique sinit/sterm pairs. To achieve that, we need a unique module identifier which will be used as a part of static init function name as suffix.<br><br></div>Our several thoughts about this so far are as follows:<br><div><br><b>1. `getUniqueModuleId` function to generate unique module identifier</b><br><a href="https://llvm.org/doxygen/ModuleUtils_8cpp_source.html#l00255"><u>https://llvm.org/doxygen/ModuleUtils_8cpp_source.html#l00255 </u></a><br><br><span style="font-family:times new roman,serif"><i>“Produce unique identifier for a module by taking the MD5 sum of the names of the module's strong external symbols. However, if the module has no strong external symbols (such a module may still have a semantic effect if it performs global initialization), we cannot produce a unique identifier for this module, so we return the empty string.”</i></span><br><br>Issues with this `getUniqueModuleId` function are:<br>(1)Since this function does not take either `Internal linkage` or `WeakOnceODR linkage` global variables, so it is not able to return a string for the following cases:<br>1)<br><i><span style="font-family:times new roman,serif">class test {<br>public:<br>    test();<br>    ~test();<br>};<br><br>static test t;  //Internal linkage</span></i><br><br>2)<br><span style="font-family:times new roman,serif"><i>extern "C" int puts(const char *);<br><br>template <typename = void><br>struct A {<br>   A() { puts("hello\n"); }<br>  ~A() { puts("bye\n"); }<br>  static A instance;<br>};<br><br>template <typename T> A<T> A<T>::instance;<br>template A<> A<>::instance;   //WeakOnceODR linkage</i></span><br><br>(2) Even if we add our own version `getUniqueModuleId` to care about above linkage types, the biggest issue here is content-based hashing won't work for the identical-content internal linkage case.<br><br><br><b>2. Source filename string as the module</b> <b>identifier</b><br>The `source filename` string is set to the original module identifier, which will be the name of the compiled source file when compiling from source through the clang front end. [<u><i> <a href="https://releases.llvm.org/10.0.0/docs/LangRef.html#source-filename">https://releases.llvm.org/10.0.0/docs/LangRef.html#source-filename</a></i></u> ]</div><div><br></div><div>That means if we have multiple objects compiled with the same command-line source file path, we have same module identifiers. The static init functions are not guaranteed to be unique.<br><br>Also, there's <a href="https://reviews.llvm.org/D73307?vs=on&id=262801&whitespace=ignore-most#change-Qs7eGduOQs42"><u>Unique Names for Functions with Internal Linkage</u></a> patch, whose solution does not guarantee uniqueness either. <br><br><b>3. Using the information around the compilation process itself</b><br>Though using the information around the compilation process itself (PID, timestamp) can give us unique module identifiers, but it could be problematic for reproducibility.<br><br><b>4. source file full path + OutputFile name following -o  option</b><br>Another thing hopeful is to use<b> the <i>source file full path plus the OutputFile name following -o option</i></b> as something to hash on or as a suffix for static init functions on AIX.<br><br>We didn’t find any precedent in LLVM to do so so far. And it requires us to pass -o ’s OutputFile name from `FrontendOpts` to `llvm::Module` like we pass each `Input` from `FrontendOpts.Inputs` to `llvm::Module` as SourceFileName.<br><a href="https://llvm.org/doxygen/Module_8cpp_source.html#l00073"><u>https://llvm.org/doxygen/Module_8cpp_source.html#l00073 </u></a><br><br></div><div><br></div><div><br>Any thoughts about what to hash on or encode into the unique ID we need?<br><br>Please let me know if there are any questions as well. Your feedback is appreciated.<br> <br>Regards,<br> <br>Xiangling Liao<br></div></div>