2011-06-15 10 views
22

Antecedentes: Estoy escribiendo un compilador/compilador Lisp de juguete en Haskell para mi propio entretenimiento/edificación. Estoy tratando de agregar la capacidad de compilar a bytecode LLVM.Hacia la comprensión de CodeGen * en los enlaces de Haskell LLVM

Contexto: He estado leyendo la documentación de LLVM.Core y un ejemplo de código (here) intentar entender las medio de combinación y medio de la abstracción (como se describe en Abelson and Sussman Structure and Interpretation of Computer Programs.) Utilizados en el Haskell LLVM enlaces Hay muchas piezas pequeñas y no tengo claro cómo se pretende que funcionen juntas. Parece que hay un nivel de abstracción por encima de las instrucciones básicas de máquina LLVM que es obvio para alguien con mucha experiencia con LLVM, pero no está documentado para aquellos, como yo, que solo se están mojando los pies.

Pregunta: ¿Cuáles sonCodeGenModule y CodeGenFunction y cómo se utilizan para construir Functions y Modules?

Respuesta

16

El Module y Function tipos son envolturas simplemente delgada alrededor de punteros a la C correspondiente ++ objetos (es decir, Module* y 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 

El CodeGenModule y CodeGenFunction tipos son partes de la EDSL construido encima de los módulos LLVM.FFI.*. Utilizan Function, Module y las funciones de LLVM.FFI.* internamente y le permiten escribir LLVM IR en Haskell concisa utilizando hacer notación (ejemplo tomado de Lennart Augustsson's blog):

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 

que se pueda imaginar CodeGenModule como un AST representa un analizada Archivo de ensamblaje LLVM (.ll). Dado un CodeGenModule, puede, por ejemplo, escribirlo en un archivo .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() 

También recomiendo que para familiarizarse con core classes of LLVM, ya que también se ven a través de la API de Haskell.

0

CodeGenFunction mantiene el código de ensamblaje LLVM para una función. CodeGenModule mantiene varias de estas funciones. En el paquete de enlaces de Haskell llvm hay un directorio de ejemplo con código de trabajo.

Cuestiones relacionadas