为什么clang输出对齐特定的东西

时间:2016-08-30 12:36:10

标签: c++ c alignment clang llvm

假设我在c中有一个基本程序,我用clang编译它,如下所示:

#include "stdio.h"
int x = 0x7FFFFFFF;
int main(void)
{

    printf("%d\n",x);
}

使用clang -emit-llvm temp.c -fno-rtti -O3 -S进行编译会生成以下bitcode:

; ModuleID = 'temp.c'
target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
target triple = "i686-pc-linux-gnu"

@x = global i32 2147483647, align 4
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1

; Function Attrs: nounwind
define i32 @main() #0 {
entry:
  %0 = load i32, i32* @x, align 4, !tbaa !1
  %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %0) #1
  ret i32 0
}

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #0

attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }

!llvm.ident = !{!0}

!0 = !{!"clang version 3.7.1 "}
!1 = !{!2, !2, i64 0}
!2 = !{!"int", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}

现在我真正的问题是关于引用变量x的行。如果您注意到,x似乎被声明为对齐变量(它与4对齐)。

clang如何知道int应该对齐?我的主张是clang对任何变量的对齐没有任何线索,因为这取决于你使用的后端。例如,我可以将后端用于8位机器,然后根本不需要对齐。

所以我的问题是:为什么铿锵猜测对齐,看到它真的不可能?

1 个答案:

答案 0 :(得分:0)

查看LLVM MAN

  

模块可以指定目标特定数据布局字符串,该字符串指定如何在内存中布置数据。数据布局的语法很简单:

target datalayout = "layout specification"
     

布局规范包含由减号字符(' - ')分隔的规范列表。每个规范都以字母开头,并且可以在字母后面包含其他信息以定义数据布局的某些方面。接受的规范如下:

[...]

  

n< size1> :< size2> :< size3> ...

     

这为目标CPU指定一组本机整数宽度(以位为单位)。例如,它可能包含32位PowerPC的n32,PowerPC 64的n32:64或X86-64的n8:16:32:64。该集合的元素被认为可以有效地支持大多数通用算术运算。

强调我的

  

当LLVM确定给定类型的对齐时,它使用以下规则:

     

如果所寻求的类型与其中一个规范完全匹配,则使用该规范。

     
      
  1. 如果找不到匹配项,并且所搜索的类型是整数类型,那么   最小的整数类型,大于的位宽   使用了寻求的类型。
  2.   
  3. 如果没有规格大于位宽那么   使用最大整数类型。例如,给定默认值   上面的规格,i7类型将使用i8的对齐(下一个   虽然i65和i256都将使用i64的对齐方式   (规定最大)。
  4.   
  5. 如果找不到匹配项,并且所搜索的类型是矢量类型,那么   最小矢量类型小于所寻求的矢量类型   被用作后退。这是因为< 128 x double>可   例如,以64< 2 x double>实现。
  6.   

  

++全局变量**

     

[...]

     

可以为全局指定显式对齐,其必须是2的幂。如果不存在,或者如果对齐设置为零,则全局的对齐由目标设置为任何它感觉方便。如果指定了显式对齐,则强制全局具有完全对齐。

强调我的