[llvm-dev] ORC JIT Weekly #6 -- General initializer support and JITLink optimizations

Lang Hames via llvm-dev
2020-02-24T07:46:37Z

Hi All,

The general initializer support patch has landed (see 85fb997659b plus
follow up fixes).

Some quick background:

Until now ORC, like MCJIT, has handled static initializer discovery by
searching for llvm.global_ctors and llvm.global_dtors arrays in the IR
added to the JIT. This approach suffers from several drawbacks:
1) It provides no built-in support for other program representations:
Object files and custom program representations added to the JIT require
manual intervention from the user to run their initializers.
2) It requires naming and promoting the linkage of initializer functions,
since they have to be looked up by name to be run.
3) It doesn't handle platform-specific initializers, e.g. Objective-C
registration, which are described by globals in specific sections.

The general initializer support patch has changed how initialization is
handled. Now all MaterializationUnits, regardless of what kind of program
representation they wrap (IR, object files, ASTs, etc.) can now declare an
optional "initializer symbol". Instances of the new Platform class
(see
include/llvm/ExecutionEngine/Orc/Core.h) are notified whenever
MaterializationUnits are added to a JITDylib, and can record the presence
of any declared initializers. By issuing lookups for initializers, the
Platform can force their materialization and arrange for them to be run in
a platform specific way (See https://reviews.llvm.org/D74300 for more
discussion on this).

This new system is flexible enough to permit two very different platform
implementations for LLJIT that are already available in tree:
GenericLLVMIRPlatform and MachOPlatform. The former essentially
re-implements the existing llvm.global_ctor scanning scheme: It promotes
functions that appear in the llvm.global_ctors array, then looks them up by
name and executes them when requested. On the other hand, MachOPlatform
implements a scheme that mimics the behavior of the Darwin dynamic loader,
dyld: By installing an ObjectLinkingLayer::Plugin, the MachOPlatform can
scan all objects as they are materialized to discover known special
sections (E.g. __mod_init_func, __objc_classlist, and __objc_selref), then
handle them according the usual platform rules (__mod_init_func pointers
are executed, Objective-C classes and selectors are registered with the
Objective-C runtime).

While this system is still very new, it is far enough along that the lli
command line tool, when run with the -jit-mode=orc-lazy option, can now
execute simple IR compiled from simple Objective C and Swift programs on
Darwin.

Also of interest this week: JITLink has a new "GOT and Stub bypass"
optimization for x86-64. When linking position independent code, JITLink
must conservatively build global offset table entries and stubs to
access/call external symbols that may be out of range of the JIT'd code.
With this new optimization, these indirect accesses may be bypassed if the
JIT'd code ends up being allocated within range of the target. Coupled with
a slab allocator for your JIT this optimization can eliminate a layer of
indirection and may improve performance for some use cases. See 27a79b72162.

Just a heads up: I expect next week to be a quiet one, as I'm out on
vacation from Wednesday.

-- Lang.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20200223/0e95dbdc/attachment.html>