ki92
ki92

Reputation: 320

LLVM malloc an array of pointers

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

Answers (1)

Michael Haidl
Michael Haidl

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

Related Questions