<div dir="ltr"><div dir="ltr">Hi All,<br><div><br></div><div>Apologies for the lack of updates recently -- things have been busy over the holidays.</div><div><br></div><div>Work on the Orc runtime has continued, however I decided to tackle the hard part first so working demo code is a little way off. In the meantime anyone who's particularly curious can check out the rough work taking shape in [1].</div><div><br></div><div>The "hard part" being tackled is the initializer problem: How should static initializers be run in the executor process? Historically we've run initializers imperatively, with the JIT ordering the executor to run a particular sequence of functions, There are two substantial problems with current initializer support though:</div><div><br></div><div>(1) We've never offered in-tree support for running initializers out-of-process. This *could* be fixed now using the TargetProcessControl API, but...</div><div><br></div><div>(2) This isn't how initializers are run in ahead-of-time compiled code: They're run by the dynamic loader during process launch and dlopen calls, and on the thread that made the call. This becomes significant if the initializers spawn threads, take locks, or trigger new rounds of initialization (e.g. by calling dlopen).</div><div><br></div><div>Now that we have a runtime we can tackle the initializer problem by introducing a jit version dlopen: Executors call the jit_dlopen function in the Orc runtime, passing the name of a JITDylib as the argument. The jit_dlopen implementation calls over to the JIT (via __orc_rt_jit_dispatch, which insulates the runtime from any RPC / IPC specifics) to obtain the list of initializers to be run, then executes them. Initializers can then be run on the same thread that they would have run on in a statically compiled program.</div><div><br></div><div>That's the theory anyway. The implementation is still a work in progress. In [1] I have started adding the plumbing for __orc_rt_jit_dispatch, and taught llvm-jitlink to load the runtime into executors and use the following sequence to run the JIT'd program:</div><div><br></div><div><font face="monospace">  auto *H = jit_dlopen("Main");</font></div><div><font face="monospace">  auto *Main = ((int)(*)(int, char*[]))jit_dlsym(H, "_main");</font></div><div><font face="monospace">  int Result = Main(argc, argv);</font></div><div><font face="monospace">  jit_dlclose(H);</font></div><div><font face="monospace">  return Result;</font></div><div><br></div><div>This doesn't actually work yet as the runtime functions are empty, but I hope to fill them in over the next few days. Hopefully by next week I'll have a working demo for you.</div><div><br></div><div>Once that's done the next thing on the list will be (re)implementing eh-frame registration and atexit handling as runtime functions, and then implementing macOS TLS support.</div><div><br></div><div>-- Lang.</div><div><br></div><div>[1] <a href="https://github.com/lhames/llvm-project/commit/8c683c549fbf53455b3a4cf26957d4ce489fb90a">https://github.com/lhames/llvm-project/commit/8c683c549fbf53455b3a4cf26957d4ce489fb90a</a></div></div></div>