Ошибка при создании выделения с помощью 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);

если вы хотите вставить не в конец ББ.

Несколько дополнительных замечаний:

  1. Я бы посоветовал следовать стилю кодирования LLVM с именами переменных в верхнем регистре (это облегчит обслуживание в дальнейшем).
  2. Строители дешевы в создании, поэтому чаще всего они просто создаются как локальные переменные в функциях, которые в них нуждаются:
      IRBuilder<> IRB;
Другие вопросы по тегам