Necto
Necto

Reputation: 2654

How to disable automatic "pass by pointer" optimization in clang++?

I have a function

void X(Object o)
{
 ....
}

When I compile it, I see, that clang changes its signature to

void X(Object* o)

It is inconvenient, because I use this function from some llvm IR code directly. How to forbid it from doing this optimization?

Edit: Minimal working example:

#include <stdio.h>

class Object
{
public:
    Object();
    ~Object();
    int* pointer;
};

void Function(Object o)
{
    o.pointer = 0;
}

int main()
{
    Object a;
    Function(a);
    return 0;
}

By the following command line:

clang++ tst.cpp -emit-llvm -O0 tst.cpp -S -std=c++11

The Function is translated into:

define void @_Z8Function6Object(%class.Object* %o) nounwind uwtable {
  %1 = getelementptr inbounds %class.Object* %o, i32 0, i32 0
  store i32* null, i32** %1, align 8
  ret void
}

Upvotes: 8

Views: 1478

Answers (1)

Vink
Vink

Reputation: 1277

You need to add the option -mdisable-fp-elim

Disable frame pointer elimination optimization.

Here where i find this option : clang option

And here i well explanation of why clang do this : understand option 'omit frame pointer'

*Edit: *

After some inspection i have found this :

  • Your object is correctly pass by copy after compilling :

example:

#include <stdio.h>
#include <iostream>

class Object
{
public:
    std::string test;
    Object() {
    this->test = "I'm an object";
    std::cout << "Object created" << std::endl;
    }
    Object(Object &o) {
    this->test = "I'm a object copy";
    std::cout << "Object copy created" << std::endl;    
}
    ~Object() {
}
    int* pointer;
};

void Function(Object o)
{
    o.pointer = 0;
    std::cout << o.test << std::endl;
}

int main()
{
    Object a;
    Function(a);
    std::cout << a.test << std::endl;
    return 0;
}

output:

Object created

Object copy created

I'm a object copy

I'm an object

  • Second point:

you can see just after the function prototype

; Function Attrs: uwtable
define void @_Z8Function6Object(%class.Object* %o) #3 {
  %1 = getelementptr inbounds %class.Object* %o, i32 0, i32 1 // Get 
  store i32* null, i32** %1, align 8

That the function get the copy of the object. You can see in the main the copy of the object

So your code seems to work well in fact ;)

Upvotes: 2

Related Questions