[llvm-dev] JIT, LTO and @llvm.global_ctors: Looking for advise
Benoit Belley via llvm-dev
llvm-dev at lists.llvm.org
Mon Jun 19 09:15:36 PDT 2017
Hi Everyone,
We are looking for advise regarding the proper use of LTO in
conjunction with just-in time generated code. Our usage scenario goes
as follows.
1. Our front-end generates an LLVM module.
2. A small runtime support library is linked-in. The runtime
library is distributed as bitcode. It is generated using "clang++
-emit-llvm' and 'llvm-link'. This allows LTO to kick-in and
functions from the runtime support library become candidates for
inlining. This is the desired effect that we are looking for.
3. The resulting LLVM module is compiled and dynamically loaded. We
are currently using the MCJIT API, but are planning to move to ORC
very soon.
Our LLVM module linking code goes roughly as follows:
Linker linker(jittedModule);
std::unique_ptr<llvm::Module> moduleToLink(
getLazyIRFileModule(bcFileName, error, context));
linker.linkInModule(std::move(module),
Linker::LinkOnlyNeeded |
Linker::InternalizeLinkedSymbol);
Our issue is with the Linker::LinkOnlyNeeded flag. Using it has a huge
positive impact on link and compilation time :-). But, it causes the
@llvm.global_ctors and @llvm.global_dtors references from the
linked-in modules to be discarded :-(. AFAICT, the Linker code assumes
ThinLTO when the LinkOnlyNeeded flags is specified, and full-LTO
otherwise.
To resolve this, we have locally patched
llvm/lib/Linker/LinkModules.cpp with:
bool ModuleLinker::run() {
// ....
if (shouldImportIntrinsicGlobalVariables()) {
auto addIntrinsicGlobalVariable = [ValuesToLink,
srcM](llvm::StringRef name) {
if (GlobalValue *GV = SrcM->getGlobalVariable(name)) {
ValuesToLink.insert(GV);
}
};
// These are added here, because they must not be internalized.
addIntrinsicGlobalVariable("llvm.used");
addIntrinsicGlobalVariable("llvm.compiler.used");
addIntrinsicGlobalVariable("llvm.global_ctors");
addIntrinsicGlobalVariable("llvm.global_dtors");
}
// ...
}
Questions:
1. Is attempting to use llvm::Linker appropriate for our usage
pattern ? Should we directly use llvm::IRMover instead ?
2. Or, is our patch to ModuleLinker::run() the way to go ? Should
we submit back a patch along these lines ?
3. Other suggestions ?
[Note] We are currently using LLVM 4.0.1-rc2.
Cheers,
Benoit
Benoit Belley
Sr Principal Developer
M&E-Product Development Group
MAIN +1 514 393 1616
DIRECT +1 438 448 6304
FAX +1 514 393 0110
Twitter <http://twitter.com/autodesk>
Facebook <https://www.facebook.com/Autodesk>
Autodesk, Inc.
10 Duke Street
Montreal, Quebec, Canada H3C 2L7
www.autodesk.com <http://www.autodesk.com/>
More information about the llvm-dev
mailing list