【问题标题】:LLVM - setting insert point of BasicBlock after adding instructions causes segfaultLLVM - 添加指令后设置 BasicBlock 的插入点会导致段错误
【发布时间】:2020-08-04 21:59:20
【问题描述】:

我正在使用 LLVM 编写编译器前端。如果我创建一个BasicBlock,向它添加一些说明,最后设置插入点,一切正常。但是当我打电话给SetInsertPoint 然后添加一些这样的指令:

    Function * MainFunction = Function::Create( FT, Function::ExternalLinkage, "main", m_Module );
    BasicBlock * BB = BasicBlock::Create( m_Parser->m_Context, "entry", MainFunction );
    m_Builder.SetInsertPoint( BB );
    CallInst * call = m_Builder.CreateCall( m_Module.getFunction( "writeln" ), {ConstantInt::get( m_Context, APInt( INT_SIZE, 1 ) )}, "calltmp" );
    BB->getInstList().push_back( call );
    m_Builder.CreateRet( ConstantInt::get( Type::getInt32Ty( m_Context ), 0 ) );

程序正确生成 LLVM IR,但在最后(当调用 LLVM 模块、上下文和构建器的析构函数时?)它给出了段错误。我真的很想这样做,因为生成指令的函数可以将BB 称为m_Builder.GetInsertBlock()。而且我想不出任何其他方式来实现 ifs、嵌套块等。

为什么它会正确生成代码并在最后崩溃?是有什么小问题,还是我遗漏了一些东西而无法像这样完成?

【问题讨论】:

  • 我不使用builder,我自己构建,所以无法回答。但我可以评论:在 valgrind 下运行你的代码,它通常会直接指出这些问题的根源。

标签: c++ llvm


【解决方案1】:
m_Builder.SetInsertPoint( BB );
m_Builder.CreateCall( m_Module.getFunction( "writeln" ), {ConstantInt::get( m_Context, APInt( INT_SIZE, 1 ) )}, "calltmp" );
m_Builder.CreateRet( ConstantInt::get( Type::getInt32Ty( m_Context ), 0 ) );

试试这个。

【讨论】:

  • 哦,我想我知道构建器现在是如何工作的了。就是这么简单。谢谢你。您认为崩溃是 LLVM 的错误吗?还是只是使用不当。
  • 使用IRBuilder创建指令时,会通过setInsertionPoint()将创建的指令添加到指定指令之后。因此手动将其再次添加到指令列表会导致此问题。
  • 有道理,但我希望该指令在块中出现两次。但它只存在一次,并且生成的 IR 是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 1970-01-01
  • 2014-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多