Trivial call for non JIT enabled target

Hi,

I am working on a target that will not support JIT, however I want to support function calling from expressions.

I have managed to get this working by adding a CALL instruction interpreter to IRInterpreter.cpp where a CALL instruction
executes a ThreadPlanCallFunction. I have function arguments handled correctly, however getting back the
return value has been tricky.

ThreadPlanCallFunction expects a ClangASTType (describing the return type) which is passed to the ABI which actually extracts it.
Since the functions I want to call have not been JIT compiled I have no clang context to reference.

It seems this could be useful for other targets that don't support JIT too so I would like to find a clean way to implement
this that I can submit it upstream. Can anyone point me towards a clean approach?

Thanks,
Aidan

Hi,

I am working on a target that will not support JIT, however I want to support function calling from expressions.

I have managed to get this working by adding a CALL instruction interpreter to IRInterpreter.cpp where a CALL instruction
executes a ThreadPlanCallFunction. I have function arguments handled correctly,

Getting function arguments is easy for easy function calls. How are you sure you have function arguments handled correctly for all cases? Are you just assuming all arguments are simple and will fit in registers? I know there is work going on in the compiler to be able to supply us with correct locations for function calls. Did you hook into this? Static functions in optimized code can violate the ABI and change where arguments are passed/returned, so that is another tricky case that is very hard to handle.

We have a function in each ABI::PrepareTrivialCall(...) which already handles the easy cases, but it makes no attempt to handle structure arguments, complex/float arguments, or struct return types.

however getting back the return value has been tricky.

ThreadPlanCallFunction expects a ClangASTType (describing the return type) which is passed to the ABI which actually extracts it.
Since the functions I want to call have not been JIT compiled I have no clang context to reference.

It seems this could be useful for other targets that don't support JIT too so I would like to find a clean way to implement
this that I can submit it upstream. Can anyone point me towards a clean approach?

Enable debug info in the expression and it will create a JIT module that will be added to the target for as long as the expression is being run. Then you will have the type information that you need as there will be DWARF for it.

You can enable debug info by setting the option via:

EvaluateExpressionOptions::SetDebug();

Hi,

I am working on a target that will not support JIT, however I want to support function calling from expressions.

I have managed to get this working by adding a CALL instruction interpreter to IRInterpreter.cpp where a CALL instruction
executes a ThreadPlanCallFunction. I have function arguments handled correctly,

Getting function arguments is easy for easy function calls. How are you sure you have function arguments handled correctly for all cases? Are you just assuming all arguments are simple and will fit in registers? I know there is work going on in the compiler to be able to supply us with correct locations for function calls. Did you hook into this? Static functions in optimized code can violate the ABI and change where arguments are passed/returned, so that is another tricky case that is very hard to handle.

We have a function in each ABI::PrepareTrivialCall(...) which already handles the easy cases, but it makes no attempt to handle structure arguments, complex/float arguments, or struct return types.

Current arguments are evaluated and pushed into an llvm::ArrayRef<uint64_t> which is then passed to the constructor of ThreadPlanCallFunction.
ThreadPlanCallFunction then provides this to ABI::PrepareTrivialCall(), which handles setting up registers and spilling onto the stack just prior to execution.
I don't believe this will work for complex cases, like you mention, partially because these aren't supported by the ABI's; however It seems to work just fine
for simple cases at the moment.

however getting back the return value has been tricky.

ThreadPlanCallFunction expects a ClangASTType (describing the return type) which is passed to the ABI which actually extracts it.
Since the functions I want to call have not been JIT compiled I have no clang context to reference.

It seems this could be useful for other targets that don't support JIT too so I would like to find a clean way to implement
this that I can submit it upstream. Can anyone point me towards a clean approach?

Enable debug info in the expression and it will create a JIT module that will be added to the target for as long as the expression is being run. Then you will have the type information that you need as there will be DWARF for it.

You can enable debug info by setting the option via:

EvaluateExpressionOptions::SetDebug();

Thanks for suggesting this Greg, I'm looking into this now.