为什么clang输出对齐特定的东西
Why does clang output alignment specific things
假设我有一个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"%d A 0", 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决定给定类型的对齐时,它使用以下规则:
如果查找的类型与其中一个规范完全匹配,则使用该规范。
- 如果没有找到匹配项,并且所查找的类型是整数类型,则大于位宽的最小整数类型
- 如果没有一个规格大于位宽,则使用最大整数类型。例如,给定默认值以上规格说明,i7型将采用i8(下)的对齐方式最大),而i65和i256将使用i64的对齐方式(指定最大)。
- 如果没有找到匹配项,并且所查找的类型是vector类型,则小于所寻向量类型的最大向量类型被用作退路。这是因为<128 x double>可以例如,以64 <2 x double>实现。
和
+ +全局变量* *
[…]
可以为全局变量指定显式对齐,全局变量必须是2的幂。如果不存在,或者如果对齐设置为零,则全局变量的对齐由目标设置为它认为方便的任何值。如果显式指定了对齐方式,则全局变量强制采用该对齐方式。
<>共舞,强调我的
- 递归函数计算序列中的平方和(并输出过程)
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 请解释"函数1(p1,p2,p3);"的输出
- C++:将控制台输出存储在宏中更好吗
- Clang 给了我符号更改的警告,但代码仍然产生正确的输出
- -fsanitize=Address with clang++ 与 g++ 的不同输出
- 为什么 gcc 和 clang 各自为这个程序产生不同的输出?(转换运算符与构造函数)
- clang和clang++与ASAN产生不同的输出
- 使用Clang的UB消毒剂构建的程序的附加输出
- 不同的输出调用clang上的malloc应用编译器选项-00和-03
- Clang 输出错误"no matching construct for initialization"
- 为什么 clang 在 Scons 下不显示颜色输出?
- 如何使用类似于gcc-xml的clang生成元数据输出
- 为什么clang和g++对a1输出0 ?V和a2.v在c++ 1z中的这个例子中
- LLVM Clang在OS X上产生非常慢的输入/输出
- 操作符重载clang++和g++不同的输出
- 为什么clang输出对齐特定的东西
- 有没有一种方法可以在输出二进制文件中存储clang编译时标志
- Clang是否可以输出将double转换为float的警告
- clang:从输出中剥离类名