Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
}
like image 975
Necto Avatar asked Jul 01 '14 12:07

Necto


People also ask

How do I disable clang optimization?

The -fno-unroll-loops option will disable this optimization.

What is Fomit frame pointer?

-fomit-frame-pointer omits the storing of stack frame pointers during function calls. The -fomit-frame-pointer option instructs the compiler to not store stack frame pointers if the function does not need it. You can use this option to reduce the code image size.


1 Answers

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 ;)

like image 79
Vink Avatar answered Sep 23 '22 09:09

Vink