6

私は llvm を初めて使用し、ここでオンライン チュートリアルのみを行いまし た。これを解析したい:

(def i 1)

次の 2 つのことを行う必要があります。

  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、double で正しく埋められBuilder.CreateRet( RetVal )、ret ステートメントを返しますが、エントリに挿入されません。

4

1 に答える 1

12

質問を作成して少し休憩すると、問題をうまく解決できる場合があります。Parent ブロックを記憶するように変更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 ) );
}
于 2013-04-08T10:38:51.257 に答える