[LLVMdev] question about the LLVM JIT

Chris Lattner sabre at nondot.org
Tue Nov 28 11:05:35 PST 2006


<cc'ing llvmdev>

On Tue, 28 Nov 2006, Eric van Riet Paap wrote:
> I'm working on using the LLVM JIT in PyPy and I hop you can give me a few 
> hint.

ok

> I have some things working at and try to write C++ code for what I need 
> from Python. The unittest I am working on at the moment is looks like 
> this
>
> --- Python code...
> llglobalmul4 = '''%my_global_int = external global int
>
> implementation
>
> int %globalmul4(int %a) {
>     % v0 = load int* %my_global_data
>     % v1 = mul int %v0, 4
>     % v2 = add int %v1, %a
>      store int %v2, int* %my_global_int
>      ret int %v2
> }'''
>
> def test_modify_global_data():
>      llvmjit.restart()
>      llvmjit.set_global_data(10)
>      assert llvmjit.get_global_data() == 10
>      gp_data = llvmjit.get_pointer_to_global_data()
>      llvmjit.add_global_mapping('my_global_data', gp_data) #note: 
> should be prior to compile()
>      llvmjit.compile(llglobalmul4)
>      globalmul4 = llvmjit.find_function('globalmul4')
>      assert llvmjit.execute(globalmul4, 5) == 10 * 4 + 5
>      assert llvmjit.get_global_data() == 10 * 4 + 5
> ---
>
> This gives a segfault in llvm::Type::getForwardedTypeInternal as far as I can 
> tell. Probably I don't understand how global data mapping works in llvm.
> The C++ code for add_global_mapping(...) looks like this
>
> --- C++ code...
> void    add_global_mapping(const char* name, void* address) {
>    GlobalVariable  var(Type::IntTy, false, GlobalVariable::ExternalLinkage, 
> 0, name, gp_module);
>    gp_execution_engine->addGlobalMapping(&var, address);
> }

This is creating a new global variable on the stack, instead of finding 
the existing global variable in the module.  Try something like this:

   gp_execution_engine->addGlobalMapping(YourModule->getNamedGlobal(name),
              address);


> The 2nd question I have has to do with recompiling code.
>
> The 'library' I'm creating, that sits between llvm's (c++) libs and Python, 
> will remain minimal so I decided to use ParseAssemblyString to get .ll 
> sourcecode into the JIT.

Ok.

> I do not see how I can tell the jit when this .ll code contains a function 
> that should overwrite a previous version of it.
> For instance, when there is a function "int %func() { ret int 5 }" and later 
> I want this replaced by "int %func() { ret int 10 }".
> If I remember correctly this gives a 'function already defined' error 
> message. I tried to use a seperate module for each call to 
> ParseAssemblyString + addModuleProvider.
> In that way there was a problem with functions calling into other modules. 
> (which perhaps I could try to solve if would understand addGlobalMapping 
> better)

This is somewhat tricky.  To replace a function in-place like this, you 
should actually modify the function in the original module, then call 
EE->recompileAndRelinkFunction(fn).  This will require some C++ code to 
delete the original function body, then splice the body of the new 
function into the old function.

-Chris

-- 
http://nondot.org/sabre/
http://llvm.org/



More information about the llvm-dev mailing list