LLVM的整数类型

27

LLVM语言将整数类型指定为iN,其中N是整数的位宽,范围从1到2^23-1(参见:http://llvm.org/docs/LangRef.html#integer-type

我有两个问题:

  1. 将C程序编译为LLVM IR级别时,可能降低哪些类型为 i1、i2、i3等?看起来像是 i8、i16、i32、i64 这些类型就足够了,那其他将近800万种整数类型是用来干什么的呢?

  2. 是否真的将带符号和无符号整数类型都降低为 i32?这是什么原因,为什么不适用于32位浮点数(在LLVM中表示为f32)?

1个回答

29
首先,需要注意的是LLVM 2.0版本添加了任意大小的整数和无符号整数之间没有区别的修改。早期版本只有一些整数类型,并且有一个带符号/无符号的区别。
现在,回答你的问题:
  1. 虽然LLVM的设计初衷是为了C/C++,但它并不特定于这些语言。拥有更多可能的整数类型能够提高灵活性。当然你并不一定需要使用这些类型 - 我猜测,任何一个C/C++前端到LLVM(比如Clang)都只会生成i1,i8,i16,i32和i64。

    编辑:显然我错了,Clang也使用其他一些整数类型,请参见Jens下面的评论。

  2. 是的,LLVM不区分有符号整数类型和无符号整数类型,所以两种类型都将转化为i32。然而,针对无符号整数的运算将根据原始类型进行翻译;例如,在无符号整数之间的除法将是udiv,而在有符号整数之间将是sdiv。但因为整数是用二进制补码表示的,所以许多操作(如add)不关心符号/无符号,因此只有一个版本。

    至于为什么LLVM中没有对有符号和无符号进行区分,请阅读关于这个增强请求的详细信息 - 简而言之,同时具备有符号和无符号版本会导致IR膨胀,对某些优化是不利的,因此被取消了。

    最后,你问的为什么没有f32 - 我也不知道,也许相对于任意大小的整数来说,它被认为不太有用。但请注意,f32并不真正描述性 - 如果你想要任意浮点类型,你至少需要指定基数和指数的大小,类似于f23e8而不是float,以及f52e11而不是double。我觉得这有点繁琐,但我想floatdouble可能已经被赋予了这些含义。


实际上,对于浮点数来说,f32是存在的。我之所以问这个问题,是因为我认为如果有符号和无符号整数都可以用i32表示,那么32位浮点数也可以用同样的方式表示。我猜想这可能是一个详细的设计决策,正如你所提到的一样。 - Ali J
@AliJ 我没有在浮点类型的语言参考部分中看到 f32... 除非你是指该名称关联着一种常见的实现方式? - Oak
4
谢谢这个!恰好我刚刚发现了Clang生成的两个指令:store i576 %bla, i576* bitcast (%class.Foo* @_Global to i576*), align 8%11 = load i384* %10, align 8。我会假设它们被降级为使用SIMD类型的memcpy调用或者一系列智能的存储/加载指令序列。 - Jens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接