如何找到类型的大小?

时间:2013-01-30 15:59:17

标签: llvm

我手里拿着Type*。如何以位/字节找出其大小(此类型的大小对象将占用内存)?我看到各种方法允许我获得“原始”或“标量”大小,但这对我的聚合类型没有帮助......

2 个答案:

答案 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}}方法。