繁体   English   中英

阻止clang扩展聚合类型的参数?

[英]Prevent clang from expanding arguments that are aggregate types?

我正在使用clang为一些C代码吐出优化的LLVM IR,我遇到了麻烦。 我假设,如果我只传递函数一次铿锵一声(声明必要的依赖项),结果LLVM例程的函数签名将与我传入的函数一致(即相同的数量)具有相同类型的参数)。 这在大多数情况下都有效,除了聚合类型的情况。 例如:

以下C代码

struct A {
    double x;
    int y;
};

int f(struct A a) {
    return a.y;
}

结果在以下LLVM中

; Function Attrs: nounwind readnone uwtable
define i32 @f(double %a.coerce0, i32 %a.coerce1) #0 {
entry:
  ret i32 %a.coerce1
}

结构已经扩展为连续的参数,因此函数现在看起来接受两个参数而不是一个。 有没有办法防止这种扩张? 即使它是某种向前声明结构的方式,以便clang不会知道它的组成字段以扩展它?

谢谢您的帮助!

此行为由AMD64 ABI (x86 64位体系结构的应用程序二进制接口)指定。 它在ABI中指定,以便不同编译器编译的函数可以互操作。 出于同样的原因,它不能在不违反ABI的情况下进行更改,这意味着该函数的所有客户端都需要知道如何调用它。

ABI要求在以下情况下以这种方式拆分聚合对象:

  • 聚合对象的大小不超过16个字节

  • 在C ++的情况下,聚合对象是“POD”(普通旧数据)。

否则,参数将通过地址传递(尽管仍需要复制)。

因此,您可以通过使类型更大来抵消聚合类型的分解,但对于使用该类型的每个翻译单元必须是可见的。

您也可以通过void *传递内容并将内存转换为您想要的结构,但更好的问题是为什么您要避免让前端执行一些基于类型的降低它需要执行的操作(ABI答案)以上)。 FWIW我们也可以在后端执行此操作,但它需要前端类型信息才能正确执行降低,并且对于llvm和clang来说是一个很大的变化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM