How can I find the size of a type?

和自甴很熟 提交于 2020-12-27 08:38:19

问题


I'm holding a Type* in my hand. How do I find out its size (the size objects of this type will occupy in memory) in bits / bytes? I see all kinds of methods allowing me to get "primitive" or "scalar" size, but that won't help me with aggregate types...


回答1:


If you only need the size because you are inserting it into the IR (e.g., so you can send it to a call to malloc()), you can use the getelementptr instruction to do the dirty work (with a little casting), as described here (with updating for modern LLVM):

Though LLVM does not contain a special purpose sizeof/offsetof instruction, the getelementptr instruction can be used to evaluate these values. The basic idea is to use getelementptr from the null pointer to compute the value as desired. Because getelementptr produces the value as a pointer, the result is casted to an integer before use.

For example, to get the size of some type, %T, we would use something like this:

%Size = getelementptr %T* null, i32 1
%SizeI = ptrtoint %T* %Size to i32

This code is effectively pretending that there is an array of T elements, starting at the null pointer. This gets a pointer to the 2nd T element (element #1) in the array and treats it as an integer. This computes the size of one T element.

The good thing about doing this is that it is useful in exactly the cases where you do not care what the value is; where you just need to pass the correct value from the IR to something. That's by far the most common case for my need for sizeof()-alike operations in the IR generation.


The page also goes on to describe how to do an offsetof() equivalent:

To get the offset of some field in a structure, a similar trick is used. For example, to get the address of the 2nd element (element #1) of { i8, i32* } (which depends on the target alignment requirement for pointers), something like this should be used:

%Offset = getelementptr {i8,i32*}* null, i32 0, i32 1
%OffsetI = ptrtoint i32** %Offset to i32

This works the same way as the sizeof trick: we pretend there is an instance of the type at the null pointer and get the address of the field we are interested in. This address is the offset of the field.

Note that in both of these cases, the expression will be evaluated to a constant at code generation time, so there is no runtime overhead to using this technique.

The IR optimizer also converts the values to constants.




回答2:


The size depends on the target (for several reasons, alignment being one of them).

In LLVM versions 3.2 and above, you need to use DataLayout, in particular its getTypeAllocSize method. This returns the size in bytes, there's also a bit version named getTypeAllocSizeInBits. A DataLayout instance can be obtained by creating it from the current module: DataLayout* TD = new DataLayout(M).

With LLVM up to version 3.1 (including), use TargetData instead of DataLayout. It exposes the same getTypeAllocSize methods, though.



来源:https://stackoverflow.com/questions/14608250/how-can-i-find-the-size-of-a-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!