【问题标题】:no Basic Block terminator generated in llvmllvm 中没有生成基本块终止符
【发布时间】:2013-03-30 08:06:19
【问题描述】:

我对 llvm 还很陌生,只在这里做了在线教程:http://llvm.org/docs/tutorial/LangImpl1.html 现在我想做我自己的小语言并遇到了一个小问题。 我想解析这个:

(def i 1)

它应该做两件事:

  1. 定义一个返回 1 的新函数
  2. 返回一个值,以便将其用作表达式

该函数已正确创建,但我在将其用作表达式时遇到了问题。 AST 看起来像这样:

FunctionAST // the whole statement
  - Prototype // is an nameless statement
  - Body // contains the definition expression
    - DefExprAST
      - Body // contains the Function definition
        - FunctionAST
          - Prototype // named i
          - Body // the value 1

该函数的代码创建代码如下所示:

Function *FunctionAST::Codegen() {
  NamedValues.clear();

  Function *TheFunction = Proto->Codegen();
  if ( TheFunction == 0 ) return 0;

  BasicBlock *BB = BasicBlock::Create( getGlobalContext(), "entry", TheFunction );
  Builder.SetInsertPoint( BB );

  if ( Value *RetVal = Body->Codegen() ) {
    Builder.CreateRet( RetVal );

    verifyFunction( *TheFunction );

    return TheFunction;
  }
  return 0;
}

DefExprAST 是这样的:

Value *DefExprAST::Codegen() {
  if ( Body->Codegen() == 0 ) return 0;

  return ConstantFP::get( getGlobalContext(), APFloat( 0.0 ) );
}

verifyFunction 给出以下错误:

Basic Block in function '' does not have terminator!
label %entry
LLVM ERROR: Broken module, no Basic Block terminator!

确实,生成的函数没有 ret 条目。它是空的:

define double @0() {
entry:
}

RetVal 正确填充了双精度,Builder.CreateRet( RetVal ) 返回 ret 语句,但它没有插入到条目中。

【问题讨论】:

    标签: llvm llvm-ir


    【解决方案1】:

    有时提出问题并稍作休息有助于很好地解决问题。我更改了DefExprAST::Codegen 以记住父块并将其设置为返回值的插入点。

    Value *DefExprAST::Codegen() {
      BasicBlock *Parent = Builder.GetInsertBlock();
      if ( Body->Codegen() == 0 ) return 0;
    
      Builder.SetInsertPoint( Parent );
    
      return ConstantFP::get( getGlobalContext(), APFloat( 0.0 ) );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-07
      相关资源
      最近更新 更多