[LLVMdev] [Proposal] Adding callback mechanism to Execution Engines

Sean Silva chisophugis at gmail.com
Thu Oct 31 23:20:45 PDT 2013


On Thu, Oct 31, 2013 at 11:39 PM, sumeeth kc <sumeethkc at gmail.com> wrote:

> Hello,
>
> I would like to have your opinions on this.
>
> *Problem:*
>
> Currently, there are no ways to perform hypercalls into LLVM (they
> transfer execution from the program being executed to the LLVM
> infrastructure to perform compilation).  The goal of this project is to
> cleanly integrate an API into the LLVM code/execution engine to create
> custom callbacks.  The “lli” executable should allow having a function be
> registered as callback with the execution engines and the program being
> compiled by LLVM should be able to make a callback into that function
> inside lli during its execution.
>

What are you using lli for that you are running into this problem?

-- Sean Silva


>
>
> *Design:*
>
> 1.       The user programs link with a dummy library function called
> PerformCustomCallback(const char* CallbackName, void *Args).
>
> 2.       LLVM ExecutionEngines (JIT and MCJIT) will implement this
> function to perform the multiplexing of the various callbacks registered
> with them.
>
> 3.       Whenever the user program calls PerformCustomCallback with
> appropriate arguments, lli should experience a call to one of the
> registered callbacks.
>
>
>
> *Methodology:*
>
> In JIT, the external symbols are resolved during the call to void
> *JIT::getPointerToNamedFunction(const std::string &Name, bool
> AbortOnFailure). So, the hypercall resolution can be done here.
>
> In MCJIT, during finalizeObject(), all the symbol relocations are
> finalized. In the Memory Managers, the external symbols are resolved. So,
> the hypercall resolution can be done in
> LinkingMemoryManager::getSymbolAddress().
>
>
>
> In JIT::getPointerToNamedFunction(), check whether the function name is
> PerformCustomCallback and store the address of the function
> PerformCustomCallback in the global table. So the next time a call happens,
> JIT will get the address directly from the table.
>
>
>
> In MCJIT, in LinkingMemoryManager::getSymbolAddress() do the same.
>
>
>
> The execution engines (JIT and MCJIT) will provide the concrete
> implementation of PerformCustomCallback function. The PerformCustomCallback
> function has to call the appropriate function with the callback name
> provided by the user program and pass the arguments supplied by the user
> program to the callback functions. It also passes an extra argument to the
> callback functions which may contain the LLVM context as specified during
> the registering of the callback.
>
>
>
> I propose to add a new API to the LLVM ExecutionEngine *int
> registerCustomCallback(const char *CallbackName, void* (*)(), void
> *LLVM_args)* to be used by llvm tools such as lli. This takes a
> function’s name to be registered as a callback, the pointer to the function
> and a placeholder for any extra arguments which the lli needs to pass to
> the callback functions.  The ExecutionEngine will register the function
> names as callbacks and calls them when it encounters a callback in the user
> program.
>
>
>
> *Interface*:
>
> Whenever a new callback has to be registered, the following things are to
> be done:
>
> 1.       The new callback has to be defined in lli (a function
> definition).
>
> 2.       The callback has to be registered with the ExecutionEngine (JIT
> or MCJIT) using the API registerCustomCallback(). Depending upon the flags
> set during lli invocation, the call goes to JIT or MCJIT.
>
> 3.       In the user program, a call to PerformCustomCallback() with the
> name and arguments will execute the registered callback.
>
>
>
> Example:
>
> Suppose, I want to register a function named Callback1 which takes two
> integers as its parameters.
>
> In lli.cpp in main(), define the function Callback1 and register it as
> follows:
>
> EE->registerCustomCallback("Callback1",
> (reinterpret_cast<void*(*)()>(&Callback1)));
>
>
>
> The user programs have to include the header file of the dummy library to
> get the PerformCustomCallback symbol. To make a hypercall to "Callback1",
> do the following:
>
> struct arg {
>
>       int arg1;
>
>       int arg2;
>
>   }Arg;
>
>   Arg.arg1 = 10;
>
>   Arg.arg2 = 20;
>
>
>
> PerformCustomCallback("Callback1", &Arg);
>
>
>
> Compile the user program (test.cc) using clang as follows:
>
> # clang -c -emit-llvm `llvm-config --cppflags` -o test test.cc
> `llvm-config --libs` `llvm-config --ldflags` -lLLVMCustomCallback
>
>
>
> *Usecases:*
>
> A typical usecase for this is to induce LLVM into Recompiling and
> relinking a function on demand from the client. Also, if we want to find
> the address of a function in a large module, we can get it using a
> mechanism like this.
>
>
>
> Please let me know if there is a better design to achieve this. I am
> attaching the diff of the implementation for your reference.
>
>
>
> Thanks,
>
> Sumeeth
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131101/51670cbe/attachment.html>


More information about the llvm-dev mailing list