Ошибка при создании выделения с помощью LLVM IR Builder CreateAlloca
У меня есть следующая строка кода, вызывающая исключение в LLVM IR C++ API:
AllocaInst *allocate = builder->CreateAlloca(objectType);
При запуске выдает следующее исключение:
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x38)
* frame #0: 0x00000001000302fa birdd`llvm::BasicBlock::getModule() const + 4
frame #1: 0x0000000100003018 birdd`llvm::IRBuilderBase::CreateAlloca(llvm::Type*, llvm::Value*, llvm::Twine const&) [inlined] llvm::BasicBlock::getModule(this=<unavailable>) at BasicBlock.h:117:68 [opt]
frame #2: 0x0000000100003013 birdd`llvm::IRBuilderBase::CreateAlloca(this=0x0000000101102230, Ty=0x0000000101801000, ArraySize=0x0000000000000000, Name=0x00007ffeefbff038) at IRBuilder.h:1598 [opt]
Это дало мне указание на то, что getModule() возвращает недопустимый указатель. Забавно то, что
builder
и доля такая же
LLVMContext
.
Так что я решил запустить его через
verifyModule
следующим образом:
verifyModule(*builder->GetInsertBlock()->getModule());
Та же ошибка. Но когда я получаю доступ к
module
объект напрямую, кажется, все в порядке.
Вот мой код инициализации:
static LLVMContext context;
std::unique_ptr<Module> module = std::make_unique<Module>("Main", context);
std::unique_ptr<IRBuilder<>> builder = std::make_unique<llvm::IRBuilder<>>(context);
Я застрял. Любая помощь будет оценена!
1 ответ
IRBuilder
не сможет выбрать из контекста (один и тот же контекст может использоваться несколькими модулями) и в любом случае
Module
одного было бы недостаточно - сборщик также должен знать точку, в которой должны быть вставлены инструкции. Таким образом, вам нужно либо предоставить ему
BasicBlock
во время строительства или установить его явно через
builder->SetInsertPoint(BB);
или даже
builder->SetInsertPoint(Inst);
если вы хотите вставить не в конец ББ.
Несколько дополнительных замечаний:
- Я бы посоветовал следовать стилю кодирования LLVM с именами переменных в верхнем регистре (это облегчит обслуживание в дальнейшем).
- Строители дешевы в создании, поэтому чаще всего они просто создаются как локальные переменные в функциях, которые в них нуждаются:
IRBuilder<> IRB;