Work with CallSites

Hi.

I have a test program:

class A {

int A;

public:

virtual void test ( int x ) = 0;

};

class B : public A {

int B;

public:

void test ( int x ) {};

};

int main() {

A *a = new B();
a->test(1);

}

We have call site CS: “a->test(1);”. CS.getCalledFunction() - return NULL, so we can say that this call site is virtual. My optimization determines, that in this call site B::test() should be called.
I’ve tried to use CSn.setCalledFunction(F) (where F is B::test()), but I’ve got this:

Check function __cxa_pure_virtual

Call parameter type does not match function signature!

%6 = load %class.A** %a, align 4

%class.B* call void @_ZN1B4testEi(%class.A* %6, i32 1)

Ok! I’ve tried to change the first %class.A %6 to %class.B %6 by “FirstArgumentOfCS->get()->mutateType(FunctionFirstArgement->getType());”, but in this case I’ve got this:

Check function __cxa_pure_virtual

Load result type does not match pointer operand type!

%6 = load %class.A** %a, align 4

%class.A*Instruction does not dominate all uses!

%6 = load %class.A** %a, align 4

%7 = bitcast %class.B* %6 to void (%class.A*, i32)***

Instruction does not dominate all uses!

%7 = bitcast %class.B* %6 to void (%class.A*, i32)***

%8 = load void (%class.A*, i32)*** %7

Instruction does not dominate all uses!

%8 = load void (%class.A*, i32)*** %7

%9 = getelementptr inbounds void (%class.A*, i32)** %8, i64 0

Instruction does not dominate all uses!

%9 = getelementptr inbounds void (%class.A*, i32)** %8, i64 0

%10 = load void (%class.A*, i32)** %9

Instruction does not dominate all uses!

%6 = load %class.A** %a, align 4

call void @_ZN1B4testEi(%class.B* %6, i32 1)

Can you tell me how correctly I can use CSn.setCalledFunction(F) in my case. Thanks!

Yours sincerely,
Kadysev Mikhail

Hi Mikhail,

You probably want to send this to cfe-dev – this mailing list is just for the LLVM mid/backend and some of the frontend guys don’t subscribe here.

Cheers,

James

Hi Михаил,

I have a test program:

    class A {
    int A;
    public:
    virtual void test ( int x ) = 0;
    };

    class B : public A {
    int B;
    public:
    void test ( int x ) {};
    };

    int main() {
    A *a = new B();
    a->test(1);
    }

We have call site CS: "a->test(1);". CS.getCalledFunction() - return NULL,

LLVM is already capable of devirtualizing this. For example, I added
   extern void foo(int);
to your testcase, and changed
   void test ( int x ) {};
to
   void test ( int x ) { foo(x); };

Compiling with "clang -S -O4 -o -" gives:
   define i32 @main() uwtable {
   entry:
     tail call void @_Z3fooi(i32 1)
     ret i32 0
   }

If you want to enhance LLVM's devirtualization, I suggest you start by studying
how the optimizers manage to work things like this out, and build on that.

Ciao, Duncan.