Глобальные переменные без указателей в LLVM

Я пишу проход функции и хотел бы добавить глобальную переменную типа int на этапе инициализации для использования в фактической работе прохода.

До сих пор у меня есть

bool doInitialization(Module &M) {
    LLVMContext &c = M.getContext();
    Type *intTy = TypeBuilder<int,false>::get(c);
    Value *p = M.getOrInsertGlobal("var1",intTy);
    return true
}

По какой-то причине var1 имеет тип int*. Например, добавив это после объявления

Type *pt = p->getType();
if (isa<PointerType>(pt)) {
    errs().write_escaped("Is a pointer ty") << '\n';
}

Закончится печатью при запуске скомпилированного кода, и

if ((intTy->getPointerTo()) == (p->getType())) {
  errs().write_escaped("This is confusing") << '\n';
}

Снова напечатает строку.

Можно ли с помощью этого метода добавить глобальную переменную типа int, и если да, то где я ошибаюсь?


person Community    schedule 15.11.2015    source источник


Ответы (2)


Ты делаешь это правильно. Глобальные переменные всегда хранятся в памяти — вы вставили глобальную переменную типа i32 и получили указатель на эту ячейку памяти. В терминах C вы получили &var1 вместо var1. Чтобы манипулировать значением, хранящимся в указателе, вам нужно создать инструкции load и store.

person Ismail Badawi    schedule 15.11.2015
comment
Спасибо за вашу помощь! Это немного не по теме, но я чувствую, что это достаточно связано, чтобы остаться на этой странице: В моем проходе функции я вызываю Value* vpointer = M->getGlobalVariable(var1); LoadInst load (vpointer, var1, & i); &i из итератора. Этот код segfaults. Проблема заключается в LoadInst, его удаление устраняет segfault. Я думаю, что проблема связана со строковым аргументом для LoadInst(), потому что я в основном просто догадываюсь, что туда поместить (документации мало). Как мне исправить этот segfault? - person ; 15.11.2015
comment
@LLVMHacker30 Я бы посоветовал изучить использование IRBuilder, а не создавать инструкции вручную. - person Ismail Badawi; 16.11.2015
comment
Не уверен, что этот ответ добавляет, что мой предыдущий ответ не добавлял :( - person dune.rocks; 16.11.2015
comment
@dune.rocks Голосование не мое (у меня нет «репутации», чтобы голосовать), и я попросил Исмаила продолжить, потому что он оказался выше на странице, когда я вернулся. Оба ответа действительно полезны. - person ; 16.11.2015

При использовании getOrInsertGlobal вы передаете основной тип объекта, который хотите создать, в глобальном пространстве имен. Затем реализация использует getPointerType для фактического создания отображения в таблице символов модуля, поэтому вы видите указатель на тип, который вы передаете.

Таким образом, вам нужно загрузить и сохранить в файл global.

person dune.rocks    schedule 15.11.2015