Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

no Basic Block terminator generated in llvm

Tags:

llvm

llvm-ir

i'm pretty new to llvm and only did the online tutorial here: http://llvm.org/docs/tutorial/LangImpl1.html Now I wanted to do my own little language and got a little problem. I want to parse this:

(def i 1)

It should do two things:

  1. Define a new function which returns 1
  2. Return a value so it can be used as an expression

The function gets created correctly, but I have a problem with using it as an expression. the AST looks like this:

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

The Code for the Code Creation for the function looks like this:

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;
}

And the DefExprAST like this:

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

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

The verifyFunction gives the following error:

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

And indeed, the generated function does not have a ret entry. Its empty:

define double @0() {
entry:
}

But RetVal is correctly filled with an double and Builder.CreateRet( RetVal ) gives back the ret statement but it doesn't get inserted into the entry.

like image 369
Philip Avatar asked Apr 08 '13 09:04

Philip


1 Answers

Sometimes formulating an question and taking a little break helps to solve problems very well. I changed the DefExprAST::Codegen to remember the Parent block and set it as the insertion point for the return value.

Value *DefExprAST::Codegen() {
  BasicBlock *Parent = Builder.GetInsertBlock();
  if ( Body->Codegen() == 0 ) return 0;

  Builder.SetInsertPoint( Parent );

  return ConstantFP::get( getGlobalContext(), APFloat( 0.0 ) );
}
like image 140
Philip Avatar answered Sep 28 '22 08:09

Philip