[LLVMdev] [Help] How can we call an object's virtual function inside IR?

27 views
Skip to first unread message

Gyounghwa Kim

unread,
Jan 5, 2010, 5:35:50 AM1/5/10
to llv...@cs.uiuc.edu
Dear experts,

I am learning llvm by reading documents and have a question to ask.

The following is the example of code generation that I created.

[[a [10.00]] > [3.00]]
; ModuleID = 'ExprF'

define i1 @expr(double* %record) {
entry:
%0 = getelementptr double* %record, i32 0 ;
<double*> [#uses=1]
%1 = load double* %0 ; <double> [#uses=1]
%2 = frem double %1, 1.000000e+01 ; <double> [#uses=1]
%3 = fcmp ogt double %2, 3.000000e+00 ; <i1> [#uses=1]
ret i1 %3
}

Now, I would like to change the type of the argument from double * to
a pointer to an object ( C++ class ) like ClassA * %record, and inside
the function body, I would like to call the virtual functions of the
ClassA %record object to get the value
for the evaluation. As far as I understand, we can get the members of
a struct from getElementPtr function, but is it possible
to call a virtual function of an object to get the value?

Could you explain on how to do this?

Thank you very much for your help in advance. :)

Best regards,

Gyounghwa Kim
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Duncan Sands

unread,
Jan 5, 2010, 5:59:36 AM1/5/10
to Gyounghwa Kim, llv...@cs.uiuc.edu
Hi Gyounghwa Kim, try pasting C++ code into http://llvm.org/demo/
in order to see the LLVM IR that llvm-g++ turns it into. That way
you will see how this can be done.

Best wishes,

Duncan.

David Greene

unread,
Jan 5, 2010, 12:33:43 PM1/5/10
to llv...@cs.uiuc.edu
On Tuesday 05 January 2010 04:59, Duncan Sands wrote:
> Hi Gyounghwa Kim, try pasting C++ code into http://llvm.org/demo/
> in order to see the LLVM IR that llvm-g++ turns it into. That way
> you will see how this can be done.

LLVM has no direct support for class hierarchies, virtual functions,
templates or anything of that support. It is very low-level. The
frontend is responsible for implementing the C++ object model in
terms of LLVM constructs. This the frontend will have to generate
vtables, indirect calls, etc. to implement virtual function calls.

This is all highly compiler-dependent. Everyone does it a little
bit differently. Using the llvm-g++ online demo as Duncan suggests
will show you how g++ implements this stuff.

-Dave

Duncan Sands

unread,
Jan 6, 2010, 5:39:49 AM1/6/10
to Gyounghwa Kim, LLVM Developers Mailing List
Hi Gyounghwa Kim,

> First of all, thank you very much for your answer.
> I tried your sugestion and found out that it is not what I wanted.
> What I have to do is call a native C function from inside this
> generated function.
> Is there any way that we can find and call native C functions not
> created by LLVM IR?

You can insert a declaration of the function into the IR, then call
it. Of course, for this to work you need to link in the native function
when running. If you are building a standalone application then this
is no problem. If you are running the IR using the JIT then it is also
possible, hopefully someone else will explain how.

> I am asking this question because I want to fix this example to get a
> class member variable (ClassA * %record) and call the member function
> of it from inside LLVM IR.

You are allowed to call a pointer, i.e. a function declaration is not
required. So you can just load the pointer out of %record, bitcast it
to the right function type, and call it.

Ciao,

Duncan.

PS: Please reply to the list and not to me personally. That way, others
may answer, and the discussion is archived which may help in the future
if someone else has the same question.

If LLVM IR cannot access the member
> function of a class. If it is not supported, we can change class
> member functions like a c function. For example, ClassA->funca () can
> be created as funcb(&ClassA ) -a C style function. Then we need to
> call funcb from inside LLVM IR.
>
> Will that be possible?
> I tried to search web and documents, but really couldn't find it.


>
> [[a [10.00]] > [3.00]]
> ; ModuleID = 'ExprF'
>
> define i1 @expr(double* %record) {
> entry:
> %0 = getelementptr double* %record, i32 0 ;
> <double*> [#uses=1]
> %1 = load double* %0 ; <double> [#uses=1]
> %2 = frem double %1, 1.000000e+01 ; <double> [#uses=1]
> %3 = fcmp ogt double %2, 3.000000e+00 ; <i1> [#uses=1]
> ret i1 %3
> }
>

Kenneth Uildriks

unread,
Jan 6, 2010, 7:38:55 AM1/6/10
to Duncan Sands, Gyounghwa Kim, LLVM Developers Mailing List
On Wed, Jan 6, 2010 at 4:39 AM, Duncan Sands <bald...@free.fr> wrote:
> Hi Gyounghwa Kim,
>
>> First of all, thank you very much for your answer.
>> I tried your sugestion and found out that it is not what I wanted.
>> What I have to do is call a native C function from inside this
>> generated function.
>> Is there any way that we can find and call native C functions not
>> created by LLVM IR?
>
> You can insert a declaration of the function into the IR, then call
> it.  Of course, for this to work you need to link in the native function
> when running.  If you are building a standalone application then this
> is no problem.  If you are running the IR using the JIT then it is also
> possible, hopefully someone else will explain how.

If you are running the IR using the JIT:

1. If the function is exported from the executable itself, or if it is
in a static library linked with the executable using the -rdynamic
flag, then you can insert a declaration of the function into the IR
and then call it.

2. Otherwise, you can insert a declaration of the function into the
IR, call ExecutionEngine::addGlobalMapping with the llvm::Function
object and a native function pointer to link the declaration to the
actual function, and then call it.

Gyounghwa Kim

unread,
Jan 11, 2010, 3:21:30 AM1/11/10
to Duncan Sands, LLVM Developers Mailing List
Dear Duncan,

Thank you very much for your answer.
Actually, I was able to call a C function from LLVM IR, now I try to
call a class member function from inside IR and tried to follow your
instructions.

1. I am trying to create a ConstantInt pointer to the class member function.
2. Covert it to a Function Pointer and call it from IRBuilder.

However, I can't figure out what to pass as the value of the pointer
to the member function.
Could you help me with this?

My code parts are shown below.

using namespace llvm;

class Record
{
public:
Record(){value=0;}
Record(int a){value=a;}
int getValue(){return value;}
void setValue(int a){value=a;}
int addOneToValue(){return value+1;}
private:
int value;
};

typedef int (Record::*RecMemFunc)();

int main(int argc, char*args[])
{
Record *rec= new Record(5);
int y = rec->addOneToValue();
printf("Hi y = %d\n", y);

RecMemFunc rp = &Record::addOneToValue;
y = (rec->*rp)();
printf("Hi y = %d\n", y);

Constant* constInt = ConstantInt::get(Type::Int64Ty, (int64)thePointer);
Value* constPtr = ConstantExpr::getIntToPtr(constInt,
PointerType::getUnqual(Type::Int32Ty));
//builder.CreateCall(myFunction, constPtr);
:
:
}

What will be the value to pass in instead of thePointer??????

Thank you very much for your help in advance. :)

- Gyounghwa

Reply all
Reply to author
Forward
0 new messages