<div dir="ltr"><div>Hello,<br><br></div>I would like to have your opinions on this.<br><div><br>

<p class="MsoNormal"><b><span style="font-size:14pt">Problem:</span></b></p>

<p class="MsoNormal">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.</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal"><b><span style="font-size:14pt">Design:</span></b></p>

<p class="" style><span style><span style>1.<span style="font:7pt "Times New Roman"">      
</span></span></span>The user programs link with a dummy library
function called PerformCustomCallback(const char* CallbackName, void *Args).</p>

<p class="" style><span style><span style>2.<span style="font:7pt "Times New Roman"">      
</span></span></span>LLVM ExecutionEngines (JIT and MCJIT) will
implement this function to perform the multiplexing of the various callbacks
registered with them.</p>

<p class="" style><span style><span style>3.<span style="font:7pt "Times New Roman"">      
</span></span></span>Whenever the user program calls
PerformCustomCallback with appropriate arguments, lli should experience a call
to one of the registered callbacks.</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal"><b><span style="font-size:14pt">Methodology:</span></b></p>

<p class="MsoNormal">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.</p>

<p class="MsoNormal">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().</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">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.</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">In MCJIT, in LinkingMemoryManager::getSymbolAddress() do the
same.</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">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.</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">I propose to add a new API to the LLVM ExecutionEngine <b>int
registerCustomCallback(const char *CallbackName, void* (*)(), void *LLVM_args)</b>
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.</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal"><b><span style="font-size:14pt">Interface</span></b><span style="font-size:14pt">:</span></p>

<p class="MsoNormal">Whenever a new callback has to be registered, the following
things are to be done:</p>

<p class="" style><span style><span style>1.<span style="font:7pt "Times New Roman"">      
</span></span></span>The new callback has to be defined in lli (a
function definition).</p>

<p class="" style><span style><span style>2.<span style="font:7pt "Times New Roman"">      
</span></span></span>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.</p>

<p class="" style><span style><span style>3.<span style="font:7pt "Times New Roman"">      
</span></span></span>In the user program, a call to
PerformCustomCallback() with the name and arguments will execute the registered
callback.</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">Example:</p>

<p class="MsoNormal">Suppose, I want to register a function named Callback1 which
takes two integers as its parameters.</p>

<p class="MsoNormal">In lli.cpp in main(), define the function Callback1 and
register it as follows:</p>

<p class="MsoNormal">EE->registerCustomCallback("Callback1",
(reinterpret_cast<void*(*)()>(&Callback1)));</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">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:</p>

<p class="MsoNormal">struct arg {</p>

<p class="MsoNormal">      int arg1;</p>

<p class="MsoNormal">      int arg2;</p>

<p class="MsoNormal">  }Arg;</p>

<p class="MsoNormal">  Arg.arg1 = 10;</p>

<p class="MsoNormal">  Arg.arg2 = 20;</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">PerformCustomCallback("Callback1", &Arg);</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">Compile the user program (test.cc) using clang as follows:</p>

<p class="MsoNormal"># clang -c -emit-llvm `llvm-config --cppflags` -o test
test.cc `llvm-config --libs` `llvm-config --ldflags` -lLLVMCustomCallback</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal"><b><span style="font-size:14pt">Usecases:</span></b></p>

<p class="MsoNormal">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.</p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">Please let me know if there is a better design to achieve
this. I am attaching the diff of the implementation for your reference. <br></p>

<p class="MsoNormal"> </p>

<p class="MsoNormal">Thanks,</p>

<p class="MsoNormal">Sumeeth</p>

<br></div></div>