问题
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/offsetofinstruction, thegetelementptrinstruction can be used to evaluate these values. The basic idea is to usegetelementptrfrom thenullpointer to compute the value as desired. Becausegetelementptrproduces 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 i32This code is effectively pretending that there is an array of
Telements, starting at thenullpointer. This gets a pointer to the 2ndTelement (element #1) in the array and treats it as an integer. This computes the size of oneTelement.
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 i32This works the same way as the
sizeoftrick: we pretend there is an instance of the type at thenullpointer 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