IR blocks for calling function pointers

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

IR blocks for calling function pointers

Avinash Chiganmi
Hello,

I am trying to create IR block for making a call to function pointer.
For creating the IR for a function call to "foo", with "foo" being defined as "void foo(int)", I can use the "getOrInsertFunction" call from Module class as follows:

  std::vector<Type*> FooArgs;
  FooArgs.push_back(IRB.getInt64Ty());
  Value *FooFunction = M.getOrInsertFunction(std::string("foo"),
                                         FunctionType::get(IRB.getVoidTy(), ArrayRef<Type*>(FooArgs), false));
  IRB.CreateCall(FooFunction, IRB.CreateLoad(LenAlloca));

I want to create a similar call, but to the pointer of foo ("foo_ptr" is defined as "(void) *foo_ptr (int)"). In C code, I would just call "foo_ptr(var)", and it would just work. But, replacing the function name with the name of the function pointer, in the IRBlock does not work:

  std::vector<Type*> FooArgs;
  FooArgs.push_back(IRB.getInt64Ty());
  Value *FooFunctionPtr = M.getOrInsertFunction(std::string("foo_ptr"),
                                         FunctionType::get(IRB.getVoidTy(), ArrayRef<Type*>(FooArgs), false));
  IRB.CreateCall(FooFunctionPtr, IRB.CreateLoad(LenAlloca));

IRBlocks generated from the above crashes.
I see the LLVM blocks generated for a sample call to function pointer. It looks as follows:

  %4 = load void (i64)** @foo_ptr, align 8, !dbg !26
  %call = call i32 %4(i32 %3), !dbg !26

What LLVM function calls should be used to generate the above IR blocks?

Thanks,
Avi.

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: IR blocks for calling function pointers

Tim Northover-2
Hi,

On 23 March 2015 at 19:04, Avinash Chiganmi <[hidden email]> wrote:
>   %4 = load void (i64)** @foo_ptr, align 8, !dbg !26
>   %call = call i32 %4(i32 %3), !dbg !26
>
> What LLVM function calls should be used to generate the above IR blocks?

I think the key thing you should notice in the "correct" code is that
@foo_ptr isn't actually a function. It's a generic global with type
void(i64)* (which means, as with all other LLVM globals that the
symbol @foo_ptr has type void(i64)** and you must load it to get the
actual value of the function pointer). If you look at the module where
it's defined you'll see something like

    @foo_ptr = global void(i64)* null

instead of a function definition. So you'd get a handle to it via a call like

    auto FooFunctionPtr = M.getOrInsertGlobal("foo_ptr",
PointerType::get(FunctionType::get(IRB.getVoidTy(), FooArgs, false)));

after that (and given that FooFunctionPtr is a Value with type
"void(i64)**") there's really only one sane set of operations you can
perform on it:

    auto FooFunction = IRB.getLoad(FooFunctionPtr)
    IRB.CreateCall(FooFunction, IRB.CreateLoad(LenAlloca));

Does that help?

Cheers.

Tim.
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: IR blocks for calling function pointers

Avinash Chiganmi
Yes. That is exactly what I was looking for. I tried it, and it works.
Thanks, Tim!

On Mon, Mar 23, 2015 at 8:49 PM, Tim Northover <[hidden email]> wrote:
Hi,

On 23 March 2015 at 19:04, Avinash Chiganmi <[hidden email]> wrote:
>   %4 = load void (i64)** @foo_ptr, align 8, !dbg !26
>   %call = call i32 %4(i32 %3), !dbg !26
>
> What LLVM function calls should be used to generate the above IR blocks?

I think the key thing you should notice in the "correct" code is that
@foo_ptr isn't actually a function. It's a generic global with type
void(i64)* (which means, as with all other LLVM globals that the
symbol @foo_ptr has type void(i64)** and you must load it to get the
actual value of the function pointer). If you look at the module where
it's defined you'll see something like

    @foo_ptr = global void(i64)* null

instead of a function definition. So you'd get a handle to it via a call like

    auto FooFunctionPtr = M.getOrInsertGlobal("foo_ptr",
PointerType::get(FunctionType::get(IRB.getVoidTy(), FooArgs, false)));

after that (and given that FooFunctionPtr is a Value with type
"void(i64)**") there's really only one sane set of operations you can
perform on it:

    auto FooFunction = IRB.getLoad(FooFunctionPtr)
    IRB.CreateCall(FooFunction, IRB.CreateLoad(LenAlloca));

Does that help?

Cheers.

Tim.


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev