我手里拿着Type*
。如何以位/字节找出其大小(此类型的大小对象将占用内存)?我看到各种方法允许我获得“原始”或“标量”大小,但这对我的聚合类型没有帮助......
答案 0 :(得分:24)
如果仅需要大小,因为您将其插入IR(例如,因此您可以将其发送到malloc()
的调用),您可以使用{{1执行脏工作(使用一点点转换)的指令,如described here(更新现代LLVM):
虽然LLVM不包含特殊目的
getelementptr
/sizeof
指令,但是offsetof
指令可用于评估这些值。基本的想法 是使用getelementptr
指针中的getelementptr
来根据需要计算值。 因为null
将值作为指针生成,所以结果将转换为 使用前的整数。例如,要获得某种类型
getelementptr
的大小,我们会使用类似的东西 这样:%T
此代码实际上假装有一个
%Size = getelementptr %T* null, i32 1 %SizeI = ptrtoint %T* %Size to i32
元素数组, 从T
指针开始。这将获得指向第二个null
元素的指针 (数组#1)在数组中将其视为整数。这计算了 一个T
元素的大小。
这样做的好处在于它完全适用于您不关心价值的情况;你只需要将IR中的正确值传递给某些东西。到目前为止,这是我在IR代中需要T
类似操作的最常见情况。
该页面还介绍了如何进行sizeof()
等效:
为了获得结构中某些字段的偏移量,使用了类似的技巧。对于 例如,获取
offsetof()
的第2个元素(元素#1)的地址 (这取决于指针的目标对齐要求) 像这样应该使用:{ i8, i32* }
这与
%Offset = getelementptr {i8,i32*}* null, i32 0, i32 1 %OffsetI = ptrtoint i32** %Offset to i32
技巧的工作方式相同:我们假装有一个实例sizeof
指针处的类型,并获取我们感兴趣的字段的地址 in。该地址是该字段的偏移量。请注意,在这两种情况下,表达式都将计算为a 在代码生成时保持不变,因此使用它不会有运行时开销 技术
IR优化器还将值转换为常量。
答案 1 :(得分:23)
大小取决于目标(由于多种原因,对齐是其中之一)。
在LLVM版本3.2及更高版本中,您需要使用DataLayout,特别是其getTypeAllocSize
方法。这将返回以字节为单位的大小,还有一个名为getTypeAllocSizeInBits
的位版本。可以通过从当前模块DataLayout
创建DataLayout* TD = new DataLayout(M)
实例来获取TargetData
实例。
对于LLVM最高版本3.1(包括),请使用DataLayout
而不是getTypeAllocSize
。但它暴露了相同的{{1}}方法。