LLVM IR 对结构内存对齐的有线行为?
Posted
技术标签:
【中文标题】LLVM IR 对结构内存对齐的有线行为?【英文标题】:LLVM IR wired behavior on memory alignment of struct? 【发布时间】:2020-07-30 04:35:16 【问题描述】:我在 struct(LLVM 10) 的内存对齐方面得到了有线行为,它与我对内存对齐的学习不匹配。
对于以下c++代码:
struct CC
char c1 = 'a';
double d1 = 2.0;
int i1 = 12;
bool b1 = true;
int i2 = 13;
bool b2 = true;
cc1;
int main()
CC cc2;
它会生成像这样的 IR:
%struct.CC = type < i8, [7 x i8], double, i32, i8, [3 x i8], i32, i8, [3 x i8] >
@cc1 = global i8, double, i32, i8, i32, i8 i8 97, double 2.000000e+00, i32 12, i8 1, i32 13, i8 1 , align 8
define linkonce_odr void @_ZN2CCC2Ev(%struct.CC*) unnamed_addr #1 align 2
%2 = alloca %struct.CC*, align 8
store %struct.CC* %0, %struct.CC** %2, align 8
%3 = load %struct.CC*, %struct.CC** %2, align 8
%4 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 0
store i8 97, i8* %4, align 8
%5 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 2
store double 2.000000e+00, double* %5, align 8
%6 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 3
store i32 12, i32* %6, align 8
%7 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 4
store i8 1, i8* %7, align 4
%8 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 6
store i32 13, i32* %8, align 8
%9 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 7
store i8 1, i8* %9, align 4
ret void
我的问题:
-
必须
%struct.CC
必须添加额外的数据类型([7xi8]
,[3xi8]
)才能对齐?还有其他对齐结构类型的方法吗?
为什么@cc1
不使用%struct.CC
?
为什么@cc1
不为对齐添加额外的数据类型?
为什么在使用store
时i1
对齐8 而不是4?如果对齐 4 怎么办?
为什么在使用store
时i2
对齐8 而不是4?
问题太多了,如果有人能回答其中的一些,非常感谢。
【问题讨论】:
如果您需要字节对齐的成员,请使用适当的#pragma
或编译器指令。
【参考方案1】:
几乎所有问题的答案都是相同的:Platform C/C++ ABI。 LLVM(或者更确切地说是clang前端)按照ABI的规定做必要的事情来做结构布局。为此,它可以添加必要的填充,因为结构成员应该具有正确的对齐方式。
【讨论】:
感谢您的回复。我知道原因,我不知道LLVM IR中的确切规则,以便我可以编写正确的IR代码,例如问题1和2。 LLVM IR 中没有“规则”。规则是平台 ABI(在本例中为 C)。因此,您需要为您的目标平台生成每个 C ABI 具有正确布局的 LLVM IR。包括必要的填充和对齐。由于@cc1
是一个初始化器,它基本上复制了它应该遵循 C ABI 的字段,它只是“一袋字段”
我认为我没有清楚地描述我的问题,所以我提出了一个新问题:***.com/questions/63369905/…。以上是关于LLVM IR 对结构内存对齐的有线行为?的主要内容,如果未能解决你的问题,请参考以下文章