Reputation: 320
I am writing a compiler of my own language to LLVM-IR. I have defined some structure type representing an array:
{ i32, [ 0 x i32] }
Now I need to alloc a memory for a real array of pointers to these structs, i.e.
[{ i32, [ 0 x i32] }* x 10]
But to tell malloc to allocate the memory, I need a size of the pointer. How can I find it out?
P.S. I see that 8 bytes per a pointer should be OK since there doesn't exist any architecture with bigger pointers, but am looking for a more general solution.
Upvotes: 3
Views: 1407
Reputation: 5482
The DataLayout
of an LLVM Module
specifies the size of pointers. The DataLayout
is bound to the architecture and the target triple what every LLVM Module
should have.
The DataLayout
from the x86_64
architecture looks like this:
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
Edit: to explicitly set your pointer size you can add p[n]:<size>:<abi>:<pref>
where p denotes pointers to address space [n] (this is optional and defaults to 0). Second parameter is the size of the pointer (e.g., 64 bit). In the provided DataLayout
above the replacement rules are used (cited from here):
When LLVM is determining the alignment for a given type, it uses the following rules:
- If the type sought is an exact match for one of the specifications, that specification is used. If no match is found, and the type sought is an integer type, then the smallest integer type that is larger
than the bitwidth of the sought type is used.- If none of the specifications are larger than the bitwidth then the largest integer type is used. For example, given the default specifications above, the i7 type will use the alignment of i8 (next largest) while both i65 and i256 will use the alignment of i64 (largest specified).
- If no match is found, and the type sought is a vector type, then the largest vector type that is smaller than the sought vector type will be used as a fall back. This happens because <128 x double> can be implemented in terms of 64 <2 x double>, for example.
Backends will recognize the pointer size and accept it (if valid).
With this said you can do the following to get the allocation size of each Type
using the Module
's DataLayout
with the LLVM C++ API:
Module* M = /*your current module*/;
Type* myType = /*some type*/;
unsigend size = M->getDataLayout()->getTypeAllocSize(myType);
//size is 8 with the DataLayout defined above
Upvotes: 3