Carter Cheng
2009-Jul-02 08:05 UTC
[LLVMdev] Having JIT resolve extern "C" functions declared in executible
Hi, I am having some difficulties getting the LLVM JIT to resolve extern "C" functions which I have defined in source file and invoking them via EE::runFunction() after generating a Function prototype for it. Is this possible or do I need to generate a .so for my functions are link against it? Thanks in advanced, Carter. Sorry for the double post but apparently I mistakenly tagged this message onto the bottom of another thread.
John McCall
2009-Jul-02 09:06 UTC
[LLVMdev] Having JIT resolve extern "C" functions declared in executible
On Jul 2, 2009, at 1:05 AM, Carter Cheng wrote:> I am having some difficulties getting the LLVM JIT to resolve extern > "C" functions which I have defined in source file and invoking them > via EE::runFunction() after generating a Function prototype for it. > Is this possible or do I need to generate a .so for my functions are > link against it?If the JIT needs a pointer to a function, and that function has no body, it'll ask the ModuleProvider to materialize the function. If the MP returns false, it'll just ask the dynamic linker for the function with that name. If no such function is linked into your program, then the JIT will just give up. So you have three options: (1) You can circumvent this entire process by giving the JIT an explicit pointer to the function using JIT::addGlobalMapping(). Obviously this requires the function to be compiled and linked into your program. (2) You can compile and link the function into your program in such a way that the dynamic linker will find it. (3) You can give the JIT a custom module provider which somehow materializes IR for the given function. The highest-performance option is probably #1, but #2 can be more convenient. If the code is totally static, I see no reason to do #3 unless you really need the IR (e.g. if you want to inline the function). Is that what you were asking? John.
Carter Cheng
2009-Jul-02 12:30 UTC
[LLVMdev] Having JIT resolve extern "C" functions declared in executible
Hi John, Thanks. I was considering pursuing option 2) initially but also started thinking about option 1) and I suspect with that hint I will be able to figure it out. Thanks. Regards, Carter. --- On Thu, 7/2/09, John McCall <rjmccall at apple.com> wrote:> From: John McCall <rjmccall at apple.com> > Subject: Re: [LLVMdev] Having JIT resolve extern "C" functions declared in executible > To: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu> > Date: Thursday, July 2, 2009, 2:06 AM > On Jul 2, 2009, at 1:05 AM, Carter > Cheng wrote: > > I am having some difficulties getting the LLVM JIT to > resolve extern > > "C" functions which I have defined in source file and > invoking them > > via EE::runFunction() after generating a Function > prototype for it. > > Is this possible or do I need to generate a .so for my > functions are > > link against it? > > If the JIT needs a pointer to a function, and that function > has no > body, it'll ask the ModuleProvider to materialize the > function. If > the MP returns false, it'll just ask the dynamic linker for > the > function with that name. If no such function is > linked into your > program, then the JIT will just give up. So you have > three options: > > (1) You can circumvent this entire process by giving > the JIT an > explicit pointer to the function using > JIT::addGlobalMapping(). > Obviously this requires the function to be compiled and > linked into > your program. > (2) You can compile and link the function into your > program in such a > way that the dynamic linker will find it. > (3) You can give the JIT a custom module provider > which somehow > materializes IR for the given function. > > The highest-performance option is probably #1, but #2 can > be more > convenient. If the code is totally static, I see no > reason to do #3 > unless you really need the IR (e.g. if you want to inline > the function). > > Is that what you were asking? > > John. > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu > http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Albert Graef
2009-Jul-04 16:19 UTC
[LLVMdev] Having JIT resolve extern "C" functions declared in executible
John McCall wrote:> On Jul 2, 2009, at 1:05 AM, Carter Cheng wrote: >> I am having some difficulties getting the LLVM JIT to resolve extern >> "C" functions which I have defined in source file and invoking them >> via EE::runFunction() after generating a Function prototype for it. >> Is this possible or do I need to generate a .so for my functions are >> link against it? > > If the JIT needs a pointer to a function, and that function has no > body, it'll ask the ModuleProvider to materialize the function. If > the MP returns false, it'll just ask the dynamic linker for the > function with that name. If no such function is linked into your > program, then the JIT will just give up. So you have three options: > > (1) You can circumvent this entire process by giving the JIT an > explicit pointer to the function using JIT::addGlobalMapping(). > Obviously this requires the function to be compiled and linked into > your program. > (2) You can compile and link the function into your program in such a > way that the dynamic linker will find it. > (3) You can give the JIT a custom module provider which somehow > materializes IR for the given function.Maybe I'm missing something, but this seems to be overkill. As John mentioned, if the C function to be called is linked into your program then the JIT should normally resolve it just fine. The Kaleidoscope tutorial [1] illustrates how to do this. [1] http://llvm.org/docs/tutorial/ There is one gotcha here, though: If the symbol is linked directly into your main executable, as is in the Kaleidoscope example, then you *must* use -rdynamic (or whatever flag your compiler provides to enable backlinking) when linking the executable, in order to make this work. This isn't necessary if the symbol is in a shared library linked into your program. Otherwise you just put the function into a shared library and load that library through llvm::sys::DynamicLibrary::LoadLibraryPermanently() [2]. Then the JIT resolves it without the shared library being linked at compile/link time. [2] http://llvm.org/doxygen/classllvm_1_1sys_1_1DynamicLibrary.html Only in unusual circumstances (i.e., you can't/don't want want to put the stuff into a separate shared library *and* your C compiler doesn't support backlinking a la -rdynamic), it's necessary to explicitly tell the dynamic loader about your C function, by calling sys::DynamicLibrary::AddSymbol() with a pointer to the function. This is all I ever needed to interface to C functions using LLVM. It's really easy. Of course you still need a prototype of the external function (function definition without body) in your IR, but that's it. HTH, Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr.Graef at t-online.de, ag at muwiinfa.geschichte.uni-mainz.de WWW: http://www.musikinformatik.uni-mainz.de/ag
Possibly Parallel Threads
- [LLVMdev] Having JIT resolve extern "C" functions declared in executible
- [LLVMdev] Having JIT resolve extern "C" functions declared in executible
- Function attributes for LibFunc and its impact on GlobalsAA
- [LLVMdev] Calling a function with bad signature, possible bug.
- [LLVMdev] Queries regarding function's arguments data type