[LLVMdev] JIT pass runtime struct on to subroutines

Kevin Streit kevin.streit at googlemail.com
Wed Apr 24 08:06:52 PDT 2013


Hi Adriaan,

if I understand correctly what you want to do, then you might use 
llvm::Argument in a wrong way.
In order to build a CallInst you should not refer in any way to the 
arguments (in terms of llvm::Argument) of the Callee (in your case the 
machine_instr).
The arguments of a function that you get via arg_begin() and arg_end() 
are used from WITHIN the function.

So in your case that would mean that you would replace parts of your 
code as follows:

On 24.04.13 13:23, Adriaan Callaerts wrote:
> // create the function for the predicate. This should take one parameter: the machine-struct that will be provided at runtime when the function is called
> llvm::Function *llvm_function = llvm::cast<llvm::Function>(
> 			llvm_module->getOrInsertFunction(*name, llvm::Type::getVoidTy(&llvm_context), llvm::PointerType::getUnqual(llvm::StructType::create(&llvm_context)), (llvm::Type *)0));
> // prepare for the construction of this function
> llvm::BasicBlock *llvm_basic_block = BasicBlock::Create(&llvm_context, "EntryBlock", llvm_function);
> llvm::IRBuilder<> llvm_builder(llvm_basic_block);
>
> // pseudo: I'll loop over all the instructions in a predicate. This sets instruction_function_name to the appropriate value in each iteration and makes sure I can iterate over the instruction's parameters
> foreach (instruction in predicate) {
>      // Fetch the instruction from the already initialised execution engine. I can do this because I compiled all instruction-functions to an LLVM Module and loaded it.
>      llvm::Function *machine_instr = llvm_execution_engine->FindFunctionNamed(instruction_function_name);
>      // Prepare for setting the parameters of a call instruction
>      llvm::Argument *llvm_arg = machine_instr->arg_begin();
llvm::SmallVector<llvm::Value*, 4> llvm_arg;
>      // Add a pointer to the machine-struct as a first parameter to every instruction-function call.
>      // This should be the same pointer that is passed at runtime to the predicate-function (llvm_function)
>      llvm_arg++ = ??;
llvm_arg.push_back(llvm_function->arg_begin());
>
>      // pseudo: for any additional parameters of the machine instruction
>      foreach (param in instruction_parameters) {
>          // add any additional parameters of the machine instruction to the function call
>          llvm_arg++ = param;
llvm_arg.push_back(param); // Whatever param here is...
>      }
>
>      // add the call to the function we're creating
>      llvm_builder.CreateCall(machine_instr, llvm_arg);
> }
>
> // finish the function by adding return
> llvm_builder.CreateRetVoid();
> // and finish with generating the function and saving it for later use
> llvm_function_pass_manager->run(*llvm_function);
> jit_functions[predicate_id] = (void*)(llvm_execution_engine->getPointerToFunction(llvm_function));



More information about the llvm-dev mailing list