[PATCH] D147544: [BOLT] Move from RuntimeDyld to JITLink

Lang Hames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 5 11:12:53 PDT 2023


lhames added a comment.

@jobnoorman I've had a chance to read over this a bit more carefully. I still don't grok how BOLT works, but this is a pretty amazing application of JITLink to an area that it was never designed for. ;)

> There's one thing in particular I'm curious about: is there a better way
> to load multiple objects?

//Maybe//. ORC certainly supports linking multiple objects together into a single JIT process, but whether it's approach is applicable to BOLT I'm less sure.

> I currently have to manually keep track of the symbols of loaded objects
> so that when other objects are loaded later, they can refer to them. It feels
> like this is something JITLink should be able to do? Also, this strategy
> cannot support earlier objects referring to symbols of later ones (not an
> issue for BOLT currently but still feels like a downside). I was expecting there
>  to be a way to merge multiple LinkGraphs but couldn't find one.

JITLink usually publishes and looks up symbols in the ORC symbol tables via `notifyResolved` and `lookup` respectively. ORC's symbol tables support async lookups (and you can see this reflected in the signature of `JITLinkContext::lookup`, which is designed to dovetail with ORC): when a link for an earlier object looks up a symbol in a defined in a later object the `JITLinkAsyncLookupContinuation` for the earlier link will just sit in the ORC symbol table until the symbol addresses from the later object become available, then ORC runs the continuation and the earlier link proceeds. Supporting async lookup in a custom `JITLinkContext` is possible, but there may be a way to just use ORC for this too, if you ever find that you need to do it.

In D147544#4246122 <https://reviews.llvm.org/D147544#4246122>, @rafauler wrote:

> The reason BOLT used RuntimeDyld is because final linking already took place in the binary...

Is BOLT taking a relocatable file as input, or an executable / dylib?

And is BOLT using RuntimeDyld to apply relocations so that the final executable is bound to a specific address? Or is it creating new relocations in the output based on the ones RuntimeDyld produces, and skipping fixups?

Depending on what it's doing the best option might be to implement a merge operation on `LinkGraph`s, and then process the merged graph in BOLT rather than using JITLink. The `applyFixup` functions are already public for each architecture, so I think you might be able to do this:
(1) Parse and merge graphs for all inputs.
(2) Assign virtual addresses to all blocks in the merged graph.
(3) Walk the graph and apply fixups to internal edges (edges between blocks in the merged graph), using the architecture-specific `applyFixups` function.
(4) Write out the merged graph, with including fixup info for external edges.

It might also be worth involving some lld folks in this discussion -- maybe their APIs are more amenable to this these days, or maybe this is something they could support with minimal effort. It definitely feels like a close fit to what LLD would be doing day-to-day.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147544



More information about the llvm-commits mailing list