LLVM IR代码中是否需要对齐指令?

问题描述

使用clang ++生成IR代码时,它将包含align x指令,并且变量和struct的内存对齐。如:

struct CT {
  char   c1;
  bool   b1;
  int    i1;
  double d1; // 8
  char   c2;
  int    i2;
};

int main() {
  char c1 = 'a';
  int  i1 = 2;
  char c2 = 'b';
  char c3 = 'c';
  int  i2 = 4;
  printf("address of c1 = %p ;\n",&c1);
  printf("address of i1 = %p ;\n",&i1);
  printf("address of c2 = %p ;\n",&c2);
  printf("address of c3 = %p ;\n",&c3);
  printf("address of i2 = %p ;\n",&i2);

  return 0;
}

它将生成IR代码(带有对齐指令):

source_filename = "oper.cpp"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.15.0"

@.str = private unnamed_addr constant [22 x i8] c"address of c1 = %p ;\0A\00",align 1
@.str.1 = private unnamed_addr constant [22 x i8] c"address of i1 = %p ;\0A\00",align 1
@.str.2 = private unnamed_addr constant [22 x i8] c"address of c2 = %p ;\0A\00",align 1
@.str.3 = private unnamed_addr constant [22 x i8] c"address of c3 = %p ;\0A\00",align 1
@.str.4 = private unnamed_addr constant [22 x i8] c"address of i2 = %p ;\0A\00",align 1

; Function Attrs: noinline norecurse optnone ssp uwtable
define i32 @main() #0 {
  %1 = alloca i32,align 4
  %2 = alloca i8,align 1
  %3 = alloca i32,align 4
  %4 = alloca i8,align 1
  %5 = alloca i8,align 1
  %6 = alloca i32,align 4
  store i32 0,i32* %1,align 4
  store i8 97,i8* %2,align 1
  store i32 2,i32* %3,align 4
  store i8 98,i8* %4,align 1
  store i8 99,i8* %5,align 1
  store i32 4,i32* %6,align 4

  %7 = call i32 (i8*,...) @printf(i8* getelementptr inbounds ([22 x i8],[22 x i8]* @.str,i64 0,i64 0),i8* %2)
  %8 = call i32 (i8*,[22 x i8]* @.str.1,i32* %3)
  %9 = call i32 (i8*,[22 x i8]* @.str.2,i8* %4)
  %10 = call i32 (i8*,[22 x i8]* @.str.3,i8* %5)
  %11 = call i32 (i8*,[22 x i8]* @.str.4,i32* %6)
  ret i32 0
}

declare i32 @printf(i8*,...) #1

这将输出

address of c1 = 0x7ffee900328b ;
address of i1 = 0x7ffee9003284 ;
address of c2 = 0x7ffee9003283 ;
address of c3 = 0x7ffee9003282 ;
address of i2 = 0x7ffee900327c ;

我们可以看到变量的内存是对齐的。

但是,如果删除IR代码的align指令,它也将正确运行,并且变量的内存也将对齐。如下面的IR代码

source_filename = "oper.cpp"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.15.0"

@.str = private unnamed_addr constant [22 x i8] c"address of c1 = %p ;\0A\00"
@.str.1 = private unnamed_addr constant [22 x i8] c"address of i1 = %p ;\0A\00"
@.str.2 = private unnamed_addr constant [22 x i8] c"address of c2 = %p ;\0A\00"
@.str.3 = private unnamed_addr constant [22 x i8] c"address of c3 = %p ;\0A\00"
@.str.4 = private unnamed_addr constant [22 x i8] c"address of i2 = %p ;\0A\00"

; Function Attrs: noinline norecurse optnone ssp uwtable
define i32 @main() #0 {
  %1 = alloca i32
  %2 = alloca i8
  %3 = alloca i32
  %4 = alloca i8
  %5 = alloca i8
  %6 = alloca i32
  store i32 0,i32* %1
  store i8 97,i8* %2
  store i32 2,i32* %3
  store i8 98,i8* %4
  store i8 99,i8* %5
  store i32 4,i32* %6
  %7 = call i32 (i8*,...) #1

无论您使用clang命令还是LLJIT(LLVM的工具API),这还将输出变量的对齐地址。


我的问题:

  1. 我们无法将对齐指令添加到IR代码吗? LLVM JIT会自动添加吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)