[llvm-dev] Implementing a VTable in LLVM
Mukul Rathi via llvm-dev
llvm-dev at lists.llvm.org
Wed Jun 10 12:12:09 PDT 2020
Thanks David, that makes sense, I’d hadn’t realised the function had to be known at compile-time.
It now works as expected, thank you!
Mukul
> On 10 Jun 2020, at 18:35, David Blaikie <dblaikie at gmail.com> wrote:
>
> I'd bet that CreateLoad is returning non-null but the dyn_cast is returning null.
>
> llvm::Function represents a specific function known at compile-time. You have loaded a function pointer (void (%Foo*, i32)*) not a function itself. You shuold pass that (function pointer) to IRBuilder createCall - no need for the dyn_cast.
>
> On Wed, Jun 10, 2020 at 10:01 AM Mukul Rathi via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
> Hi all,
>
> I’ve been working on a Java-esque object-oriented language Bolt that targets LLVM IR. I’m agonisingly close to getting a virtual table working, and was hoping one of you could point out the gap in my understanding. I’ve linked the C++ code snippets relevant to the vtable below.
>
>
> Example IR generated (partially displayed below): https://github.com/mukul-rathi/bolt/blob/vtable/examples/vtable/foo.ll <https://github.com/mukul-rathi/bolt/blob/vtable/examples/vtable/foo.ll>
> And the Bolt source code that compiles to it- https://github.com/mukul-rathi/bolt/blob/vtable/examples/vtable/foo.bolt <https://github.com/mukul-rathi/bolt/blob/vtable/examples/vtable/foo.bolt>
>
>
> I currently have code (https://github.com/mukul-rathi/bolt/blob/vtable/src/llvm-backend/llvm_ir_codegen/class_codegen.cc#L57:L77 <https://github.com/mukul-rathi/bolt/blob/vtable/src/llvm-backend/llvm_ir_codegen/class_codegen.cc#L57:L77>)
> that generates the following global Vtable for a class Foo:
>
> %_VtableFoo = type { void (%Foo*, i32)* }
> %Foo = type { %_VtableFoo*, %pthread_t*, i32, i32, i32, i32 }
>
> @_VtableFoo = common global %_VtableFoo { void (%Foo*, i32)* @_Foo__setgi }
>
> The code for instantiating the table seems to generate the correct IR (create an object, store a pointer to its vtable) - https://github.com/mukul-rathi/bolt/blob/vtable/src/llvm-backend/llvm_ir_codegen/expr_codegen.cc#L66:L89 <https://github.com/mukul-rathi/bolt/blob/vtable/src/llvm-backend/llvm_ir_codegen/expr_codegen.cc#L66:L89>
>
> entry:
> %_var_y0 = alloca %Foo*
> %0 = call i8* @malloc(i64 ptrtoint (%Foo* getelementptr (%Foo, %Foo* null, i64 1) to i64))
> %1 = bitcast i8* %0 to %Foo*
> %2 = getelementptr inbounds %Foo, %Foo* %1, i32 0, i32 0
> store %_VtableFoo* @_VtableFoo, %_VtableFoo** %2
>
>
>
> The issue is when it comes to actually calling the method. Up to this point, the code generates the expected IR (https://github.com/mukul-rathi/bolt/blob/vtable/src/llvm-backend/llvm_ir_codegen/expr_codegen.cc#L188:L202 <https://github.com/mukul-rathi/bolt/blob/vtable/src/llvm-backend/llvm_ir_codegen/expr_codegen.cc#L188:L202>)
>
>
> %5 = load %Foo*, %Foo** %_var_y0
> %6 = getelementptr inbounds %Foo, %Foo* %5, i32 0, i32 0
> %7 = load %_VtableFoo*, %_VtableFoo** %6
> %8 = getelementptr inbounds %_VtableFoo, %_VtableFoo* %7, i32 0, i32 0
> %9 = load void (%Foo*, i32)*, void (%Foo*, i32)** %8
>
>
> However, the builder->CreateLoad instruction corresponding to the line with %9 returns null:
> llvm::Function *calleeMethod = llvm::dyn_cast<llvm::Function>(builder->CreateLoad(calleeMethodPtr));
> So if I then try to execute the following builder->CreateCall function I end up with a segmentation fault since calleeMethod is null:
>
> builder->CreateCall(calleeMethod, argVals);
>
>
> Under what circumstances would builder->CreateLoad return null? Is the global vTable's memory not allocated correctly? Or have I been approaching this incorrectly - is there another method in the C++ API that I should be using for indirect function calls?
>
> I’d really appreciate any assistance.
>
> Thanks,
>
> Mukul
>
>
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev <https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200610/7b4654ed/attachment.html>
More information about the llvm-dev
mailing list