2015-01-29 3 views
3

Я пишу компилятор моего языка для LLVM-IR. Я определил некоторый тип структуры, представляющий собой массив:LLVM malloc массив указателей

{ i32, [ 0 x i32] } 

Теперь мне нужно Alloc память для реального массива указателей на эти структур, т.е.

[{ i32, [ 0 x i32] }* x 10] 

Но сказать таНос выделить память , Мне нужен размер указателя. Как я могу это узнать?

P.S. Я вижу, что 8 байт на указатель должны быть в порядке, так как там не существует архитектуры с большими указателями, но я ищу более общее решение.

ответ

3

DataLayout LLVM Module указывает размер указателей. DataLayout привязан к архитектуре и целевой тройке, что должно иметь каждый LLVM Module.

DataLayout из x86_64 архитектуры выглядит следующим образом:

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 
target triple = "x86_64-unknown-linux-gnu" 

Edit: явно установить размер указателя вы можете добавить p[n]:<size>:<abi>:<pref> где р обозначает указатели адресного пространства [п] (это не является обязательным, и по умолчанию 0). Второй параметр - размер указателя (например, 64 бит). В представленной DataLayout выше правил замены используются (цит here):

Когда LLVM является определяющим выравнивание для данного типа, он использует следующие правила:

  • Если тип искал является точным соответствием для одной из спецификаций, эта спецификация используется. Если совпадение не найдено, а искомый тип является целым типом, то используется наименьший целочисленный тип, который является более крупным
    , чем битовая ширина искомого типа.
  • Если ни одна из спецификаций не превышает ширину бита, то используется самый большой целочисленный тип. Например, учитывая приведенные выше значения по умолчанию , тип i7 будет использовать выравнивание i8 (следующий по величине), в то время как i65 и i256 будут использовать выравнивание i64 (наибольшее заданное значение).
  • Если совпадение не найдено, и тип seek является векторным типом, тогда самый большой векторный тип, который меньше, чем искомый векторный тип , будет использоваться в качестве возврата. Это происходит потому, что < 128 x double> может быть реализовано в терминах 64 < 2 x double>, например.

Бэкэндс распознает размер указателя и примет его (если он действителен).

С этим сказал, что вы можете сделать следующее, чтобы получить размер распределения каждого Type используя Module «ы DataLayout с API LLVM C++:

Module* M = /*your current module*/; 
Type* myType = /*some type*/; 
unsigend size = M->getDataLayout()->getTypeAllocSize(myType); 
//size is 8 with the DataLayout defined above 
+0

Это не работает для меня, так как я генерируя текстовое представление от LLVM-IR. Есть ли способ сделать это в таком случае? – ki92

+0

Что вы имеете в виду с текстовым представлением? Представление DataLayout в текстовой форме для модуля. Если вы укажете свои указатели на 8 байт в вашем DL, то размер вашего malloc всегда будет 8 для типа указателя. –

+0

Я имею в виду, что я создаю текстовый файл, который затем скомпилирован в биткод с использованием 'llvm-as' и не использует API. – ki92