在Haskell LLVM绑定中理解CodeGen*

Joh*_*ler 22 haskell language-design llvm

背景:我正在Haskell写一个玩具Lisp interperter /编译器,用于我自己的娱乐/启发.我试图添加编译为LLVM字节码的能力.

语境:我一直在阅读的文档LLVM.Core和代码示例(在这里),试图了解该组合的手段抽象的手段(如描述阿伯尔森和萨斯曼计算机程序的结构与解释的哈斯克尔LLVM使用.)绑定.有很多小件,我不清楚他们打算如何合作.看起来基本的LLVM机器指令之上有一定程度的抽象,对于那些对LLVM有很多经验的人来说是显而易见的,但对于那些像我这样只是沾沾自喜的人来说,没有记录.

问:什么是CodeGenModuleCodeGenFunction它们是怎样被用来建立FunctionsModules

Mik*_*kov 16

ModuleFunction类型是围绕指针只是薄包装成相应的C++的对象(即,Module*Value*):

-- LLVM.Core.Util
newtype Module = Module {
      fromModule :: FFI.ModuleRef
    }
    deriving (Show, Typeable)

type Function a = Value (Ptr a)    

newtype Value a = Value { unValue :: FFI.ValueRef }
    deriving (Show, Typeable)

-- LLVM.FFI.Core
data Module
    deriving (Typeable)
type ModuleRef = Ptr Module

data Value
    deriving (Typeable)
type ValueRef = Ptr Value
Run Code Online (Sandbox Code Playgroud)

CodeGenModuleCodeGenFunction类型是建立在顶部的EDSL的部分LLVM.FFI.*模块.他们使用Function,Module并从功能,LLVM.FFI.*在内部,并允许你写LLVM IR在Haskell简明使用DO-符号(例如取自伦纳特·奥古斯塔茨森的博客):

mFib :: CodeGenModule (Function (Word32 -> IO Word32))
mFib = do
    fib <- newFunction ExternalLinkage
    defineFunction fib $ \ arg -> do
        -- Create the two basic blocks.
        recurse <- newBasicBlock
        exit <- newBasicBlock

        [...]
        ret r
    return fib
Run Code Online (Sandbox Code Playgroud)

您可以将其CodeGenModule视为表示已解析的LLVM程序集文件(.ll)的AST .给定a CodeGenModule,您可以将其写入.bc文件:

-- newModule :: IO Module
mod <- newModule
-- defineModule :: Module -> CodeGenModule a -> IO a
defineModule mod $ do [...]

-- writeBitcodeToFile :: FilePath -> Module -> IO ()
writeBitcodeToFile "mymodule.bc" mod

--- Alternatively, just use this function from LLVM.Util.File:
writeCodeGenModule :: FilePath -> CodeGenModule a -> IO () 
Run Code Online (Sandbox Code Playgroud)

我还建议您熟悉LLVM的核心类,因为它们也在Haskell API中显示出来.