Как использовать LLVMBuildStore API - PullRequest
0 голосов
/ 21 ноября 2018
long i=3;
long *j;
j=&i;

Я хочу использовать LLVM C API для преобразования приведенного выше кода, особенно последней строки, в код llvm. Теперь я ищу правильную функцию в LLVM C API, я думаю, что следует использовать "LLVMBuildStore", но есть оператор "&"Как я могу перевести это?Второй параметр LLVMBuildStore - это значение типа LLVMValueRef, которое в данном случае ссылается на «i», как получить адрес из этого значения?

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Учитывая следующую функцию C

int main() {
      long i=3;
      long *j;
      j=&i;
      return 0;
}

Clang 3.8 сгенерирует:

define i32 @main() {
  %1 = alloca i32, align 4
  %2 = alloca i64, align 8
  %3 = alloca i64*, align 8
  store i32 0, i32* %1, align 4
  store i64 3, i64* %2, align 8
  store i64* %2, i64** %3, align 8
  ret i32 0
}

Что мы можем видеть из сгенерированного кода, так это то, что clang генерирует один базовый блок.В этом базовом блоке мы генерируем три инструкции alloca и три инструкции store и одну инструкцию ret, которая завершает базовый блок.

Для инструкций store вы можете использовать LLVMBuildStore ().LLVMBuildStore принимает три аргумента, первый из которых ваш строитель.Второй параметр - это то, что вы хотели бы сохранить, третий - где его хранить.Для первых двух инструкций хранилища вы можете просто использовать значение LLVM, которое представляет ваши целые числа.

Для третьего параметра используйте инструкцию LLVMBuildStore напрямую, не загружая переменную.Где вторым параметром является LLVMValueRef, который вы получили от вашего предыдущего LLVMBuildAlloca (), который вы получили при создании:

%2 = alloca i64*, align 8
0 голосов
/ 22 ноября 2018

Учитывая, что вы предоставили выражение назначения адреса для j, я полагаю, что переменные не глобальные, а скорее расположены внутри функции.

Итак, чтобы перевести этот фрагмент кода C в LLVM IR, вы сначаланеобходимо выделить место в стеке для переменной i и указателя j, а затем сохранить константу 3 по адресу i и по адресу i по адресу указателя j.

В LLVM IR:

%i = alloca i64, align 8  ;allocation for i. %i is a pointer i64* to variable i
%j = alloca i64*, align 8  ;respectively, the type of %j is i64** (pointer to i64*)
store i64 3, i64* %i, align 8  ; i=3
store i64* %i, i64** %j, align 8  ; store %i (the address of var i) to the address of pointer j

Я не знаю, как сгенерировать эти инструкции, используя LLVM C API, потому что я никогда не использовал их.Тем не менее, мы надеемся, что между API C и C ++ может существовать связь, и, возможно, предоставление кода, который я напишу с использованием API C ++, может помочь вам понять тип аргументов, которые вы должны использовать.Надеюсь, это поможет.

AllocaInst *alloc_i = new AllocaInst(Type::getInt64Ty(M.getContext()), //Type i64
                                          0,        //AddressSpace
                                          nullptr,  //Arraysize
                                          8,        //Alignment
                                          "i",      //name of result in IR. Leave "" for default
                                          I);       //Add alloca instruction before Instruction I

AllocaInst *alloc_j = new AllocaInst(Type::getInt64PtrTy(M.getContext()), //Type i64*
                                          0,        //AddressSpace
                                          nullptr,  //Arraysize
                                          8,        //Alignment
                                          "i",      //name of result in IR. Leave "" for default
                                          I);       //Add alloca instruction before Instruction I

StoreInst *store_i = new StoreInst(ConstantInt::get(Type::getInt64Ty(M.getContext()), 3), //get constant 3 of type i64
                                          alloc_i,   //store to the result Value* of alloc_i
                                          false, 
                                          8,         //Alignment
                                          I);        //Insert before instr I

StoreInst *store_j = new StoreInst(alloc_i,   //i64* pointer to i
                                          alloc_j,   //store to the address of pointer j
                                          false, 
                                          8,         //Alignment
                                          I);        //Insert before instr I

Наконец, рассмотрите возможность использования C ++ API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...