gpt4 book ai didi

compiler-construction - 为什么 Clang 将结构参数强制转换为整数

转载 作者:行者123 更新时间:2023-12-04 04:05:20 26 4
gpt4 key购买 nike

在函数中使用结构参数时,clang 将更改函数签名。签名不是使用结构类型,而是大小相等的强制 int。在我的编译器项目中,我使用 llvm 结构类型作为方法签名(这似乎更合乎逻辑)。

这不会是一个问题,除了 LLVM 在使用结构或强制类型时生成的程序集不同并且调用不兼容这一事实。这导致我的编译器与带有结构的 C 函数不兼容 ABI。

为什么clang会这样做?这是 C ABI 中指定的内容吗?

这是一个简单的示例 C 源文件:

struct TwoInt { int a, b; };

struct EightChar { char a, b, c, d, e, f, g, h; };

void doTwoInt(struct TwoInt a) {}

void doEightChar(struct EightChar a) {}

int main()
{
struct TwoInt ti;
struct EightChar fc;

doTwoInt(ti);
doEightChar(fc);

return 0;
}

从 Clang 生成的 LLVM-IR
%struct.TwoInt = type { i32, i32 }
%struct.EightChar = type { i8, i8, i8, i8, i8, i8, i8, i8 }

define void @doTwoInt(i64 %a.coerce) nounwind uwtable {
%a = alloca %struct.TwoInt, align 8
%1 = bitcast %struct.TwoInt* %a to i64*
store i64 %a.coerce, i64* %1, align 1
ret void
}

define void @doEightChar(i64 %a.coerce) nounwind uwtable {
%a = alloca %struct.EightChar, align 8
%1 = bitcast %struct.EightChar* %a to i64*
store i64 %a.coerce, i64* %1, align 1
ret void
}

define i32 @main() nounwind uwtable {
%1 = alloca i32, align 4
%ti = alloca %struct.TwoInt, align 4
%fc = alloca %struct.EightChar, align 1
store i32 0, i32* %1
%2 = bitcast %struct.TwoInt* %ti to i64*
%3 = load i64* %2, align 1
call void @doTwoInt(i64 %3)
%4 = bitcast %struct.EightChar* %fc to i64*
%5 = load i64* %4, align 1
call void @doEightChar(i64 %5)
ret i32 0
}

我所期望的(以及我的编译器输出的):
%TwoInt = type { i32, i32 }
%EightChar = type { i8, i8, i8, i8, i8, i8, i8, i8 }

define void @doTwoInt(%TwoInt %a) {
%1 = alloca i32
%2 = alloca %TwoInt
store %TwoInt %a, %TwoInt* %2
ret void
}

define void @doEightChar(%EightChar %a) {
%1 = alloca i32
%2 = alloca %EightChar
store %EightChar %a, %EightChar* %2
ret void
}

define i32 @main() {
%1 = alloca i32
%ti = alloca %TwoInt
%fc = alloca %EightChar
%2 = load %TwoInt* %ti
call void @doTwoInt(%TwoInt %2)
%3 = load %EightChar* %fc
call void @doEightChar(%EightChar %3)
ret i32 0
}

最佳答案

两个月前 llvmdev 中有一个线程:[LLVMdev] "Struct parameters being converted to other types"作者:Jaymie Strecker,2013 年 1 月 14 日 19:50:04 CST。她遇到了类似的问题:“当使用 clang -O0 -emit-llvm 编译具有结构参数或返回类型的函数时,生成的位码会因结构类型的不同而有很大差异。” , 并且 clang 将 struct 变成了指针、向量,将它作为几个 double 值传递,或者合并为单个 i64 类型。 Anton Korobeynikov replied at Jan 15 00:41:43 CST 2013 :

The struct is lowered to something which corresponds to C/C++ ABI on your platform for passing the struct in proper way.



因此,clang 会根据您的操作系统、库和 native 编译器使用的方式进行结构传递。这样做是为了允许您构建模块,这些模块将与本地库一起使用。我认为您的编译器项目使用了错误的 ABI。

您可以修复您的编译器项目以使用平台 ABI(转换结构,就像它由 clang 完成的那样),或者您可以定义自己的 ABI 并调整 clang 以使用它。

关于compiler-construction - 为什么 Clang 将结构参数强制转换为整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22776391/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com