Menuju pemahaman CodeGen* dalam binding Haskell LLVM

Latar belakang: Saya sedang menulis mainan Lisp interperter/compiler di Haskell untuk hiburan/pembangunan saya sendiri. Saya mencoba menambahkan kemampuan kompilasi ke bytecode LLVM.

Konteks: Saya telah membaca dokumentasi untuk LLVM.Core dan contoh kode (di sini) mencoba memahami sarana kombinasi dan sarana abstraksi (seperti dijelaskan dalam Abelson dan Sussman Struktur dan Interpretasi Program Komputer.) digunakan dalam binding Haskell LLVM. Ada banyak bagian kecil dan saya tidak jelas bagaimana mereka dimaksudkan untuk bekerja sama. Sepertinya ada tingkat abstraksi di atas instruksi dasar mesin LLVM yang jelas bagi seseorang yang memiliki banyak pengalaman dengan LLVM, tetapi tidak didokumentasikan bagi mereka, seperti saya, yang baru saja mulai basah kuyup.

Pertanyaan: Apa itu CodeGenModule dan CodeGenFunction dan bagaimana cara menggunakannya untuk membangun Functions dan Modules?


person John F. Miller    schedule 15.06.2011    source sumber


Jawaban (2)


Tipe Module dan Function hanyalah pembungkus tipis di sekitar pointer ke objek C++ yang sesuai (yaitu, Module* dan 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

Tipe CodeGenModule dan CodeGenFunction adalah bagian dari EDSL yang dibangun di atas modul LLVM.FFI.*. Mereka menggunakan Function, Module dan fungsi dari LLVM.FFI.* secara internal dan memungkinkan Anda menulis LLVM IR di Haskell secara ringkas menggunakan notasi do (contoh diambil dari blog Lennart Augustsson):

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

Anda dapat menganggap CodeGenModule sebagai AST yang mewakili file rakitan LLVM yang diurai (.ll). Diberikan CodeGenModule, Anda dapat mis. tulis ke file .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 () 

Saya juga menyarankan Anda untuk mengenal kelas inti LLVM, karena kelas tersebut juga ditampilkan di API Haskell.

person Mikhail Glushenkov    schedule 15.06.2011

CodeGenFunction mempertahankan kode perakitan LLVM untuk satu fungsi. CodeGenModule memelihara beberapa fungsi seperti itu. Dalam paket binding Haskell llvm terdapat direktori contoh dengan kode yang berfungsi.

person Lemming    schedule 25.06.2011