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...
The size of a variable depends on its type, and C++ has a very convenient operator called sizeof that tells you the size in bytes of a variable or a type. The usage of sizeof is simple. To determine the size of an integer, you invoke sizeof with parameter int (the type) as demonstrated by Listing 3.5.
In the C programming language, and several of the languages based on C, the sizeof operator can be used to calculate how many bytes a data type occupies in memory.
A size variable is a visual variable that defines the size of a symbol based on a numeric data value returned from a field or expression.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With