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

Why does clang output alignment specific things

本文关键字:clang 输出 对齐 为什么      更新时间:2023-10-16

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

#include "stdio.h"
int x = 0x7FFFFFFF;
int main(void)
{
    printf("%dn",x);
}

clang -emit-llvm temp.c -fno-rtti -O3 -S编译会产生以下位码:

; 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"%dA0", 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 s应该对齐?我的主张是clang没有任何关于变量对齐的线索,因为这取决于您使用的后端。例如,我可以为8位机器使用后端,那么它根本不需要对齐。

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

查看LLVM MAN

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

target datalayout = "layout specification"

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

[…]

n & lt;size1祝辞: & lt;size2祝辞: & lt;size3祝辞…

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

<>共舞,强调我的

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

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

  1. 如果没有找到匹配项,并且所查找的类型是整数类型,则大于位宽的最小整数类型
  2. 如果没有一个规格大于位宽,则使用最大整数类型。例如,给定默认值以上规格说明,i7型将采用i8(下)的对齐方式最大),而i65和i256将使用i64的对齐方式(指定最大)。
  3. 如果没有找到匹配项,并且所查找的类型是vector类型,则小于所寻向量类型的最大向量类型被用作退路。这是因为<128 x double>可以例如,以64 <2 x double>实现。

+ +全局变量* *

[…]

可以为全局变量指定显式对齐,全局变量必须是2的幂。如果不存在,或者如果对齐设置为零,则全局变量的对齐由目标设置为它认为方便的任何值。如果显式指定了对齐方式,则全局变量强制采用该对齐方式。

<>共舞,强调我的