如何在clang ++中禁用自动"通过指针传递"优化?

Nec*_*cto 8 c++ clang compiler-optimization llvm-clang clang++

我有一个功能

void X(Object o)
{
 ....
}
Run Code Online (Sandbox Code Playgroud)

当我编译它时,我看到,该clang将其签名更改为

void X(Object* o)
Run Code Online (Sandbox Code Playgroud)

这很不方便,因为我直接从一些llvm IR代码中使用这个函数.如何禁止它进行此优化?

编辑:最小的工作示例:

#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;
}
Run Code Online (Sandbox Code Playgroud)

通过以下命令行:

clang++ tst.cpp -emit-llvm -O0 tst.cpp -S -std=c++11
Run Code Online (Sandbox Code Playgroud)

Function被翻译成:

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
}
Run Code Online (Sandbox Code Playgroud)

Vin*_*ink 2

您需要添加该选项-mdisable-fp-elim

禁用帧指针消除优化。

我在这里找到这个选项:clang option

在这里我很好地解释了 clang 这样做的原因:理解选项“省略帧指针”

*编辑: *

经过一番检查后我发现了这一点:

  • 编译后,您的对象已正确通过副本传递:

例子:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

对象已创建

创建对象副本

我是一个对象副本

我是一个物体

  • 第二点:

你可以在函数原型之后看到

; 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
Run Code Online (Sandbox Code Playgroud)

该函数获取对象的副本。main您可以在对象的副本中看到

所以你的代码实际上似乎运行良好;)