[haskell-llvm] enforce block structure of functions

Henning Thielemann lemming at henning-thielemann.de
Sun Oct 10 14:57:29 EDT 2010

On Sun, 10 Oct 2010, Henning Thielemann wrote:

> In LLVM.Core.Instructions I read:
> -- TODO:
> -- Use Terminate to ensure bb termination (how?)
> To answer this question: I would introduce a Block monad. LLVM assembly
> instructions become actions of the Block monad and a block must be
> terminated with a terminator directive like 'br' or 'ret'. This rule is
> ensured by a function that lifts a Block to a CodeGenFunction:
>   embedBlock :: Block r Terminate -> CodeGenFunction r ()

Hm, there must also be a way to pass Values (i.e. virtual registers) from 
a Block to another Block in the same CodeGenFunction. And it would be even 
better to make sure, that the LLVM rules for using virtual registers in 
other blocks are satisfied (using 'phi'). So far, I have just programmed 
typical control structures in llvm-extra, in order to get rid of the 
annoying messages from LLVM that a register does not cover all of its 

The Terminate type could contain nested tuples of values, that are 
extended by the block identifier by 'embedBlock' and these (block,value) 
pairs can be later passed to 'phi'.

embedBlock ::
    (AddBlock value blockValues) =>
    BasicBlock ->
    Block r (Terminate values) ->
    CodeGenFunction r blockValues

condBr ::
    Value Bool ->
    BasicBlock -> valuesTrue ->
    BasicBlock -> valuesFalse ->
    CodeGenFunction r (Terminate (valuesTrue, valuesFalse))

Essentially embedBlock would replace defineBasicBlock.

>  Since we recently started to use the monadic result () for instructions
> without a result like 'store', we can no longer use the type synonym
> Terminate = (). But we could add a new type (data Terminate = Terminate)
> or just (data Terminate).
> This change would break most of the code that uses the llvm package, but
> it would document and force the overall structure of a piece of LLVM
> assembly code written in Haskell.
> As a light proposal for now, I would just like to define a new type
> Terminate, that is distinct from ().

More information about the Haskell-llvm mailing list