Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find the size of a type?

Tags:

llvm

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...

like image 982
Oak Avatar asked Jan 30 '13 15:01

Oak


People also ask

How do I get the size of a type in C++?

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.

What can you use to determine the size of a given C data type?

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.

What is the size of variable?

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.


1 Answers

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.

like image 63
Donal Fellows Avatar answered Sep 28 '22 02:09

Donal Fellows



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!