<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/