2011-06-15 8 views
22

Arka plan: Kendi eğlenceme/düzeltmem için Haskell'de bir oyuncak Lisp interperter/compiler yazıyorum. LLVM bayt koduna derleme yeteneği eklemeye çalışıyorum.Haskell LLVM bağlamalarında CodeGen * 'i anlamağa doğru

Bağlam: Haskell LLVM kullanılan kombinasyon arasında aracı ve soyutlama (. Abelson and Sussman Structure and Interpretation of Computer Programs tarif edildiği gibi) arasında araçlarını anlamaya çalışan LLVM.Core belgelerine ve bir kod örneği (here) okuma edilmiştir bağlamaları. Bir sürü küçük parça var ve birlikte nasıl çalışacaklarını açıklamıyorum. LLVM ile çok fazla tecrübeye sahip olan ama benim gibi ayakları ıslak olan kişiler için belgelenmemiş olan temel LLVM makine talimatlarının üzerinde bir soyutlama seviyesi var gibi görünüyor.

Soru: Ne CodeGenModule ve CodeGenFunction ve nasıl Functions ve Modules oluşturmak için kullanılır?

cevap

16

Module ve Function tip (diğer bir deyişle, Module* ve Value* olan) nesneler ++ karşılık gelen C işaretçiler çevresinde sadece ince sargı olan:

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

CodeGenModule ve CodeGenFunction türleri üzerine inşa EDSL parçalarıdır LLVM.FFI.* modülleri. Onlar Function, Module ve içten LLVM.FFI.* işlevleri kullanmak ve kısaca (Lennart Augustsson's blog alınan örnek) do-gösterimi kullanılarak Haskell LLVM IR yazmak için izin: Bir AST bir çözümlenen temsil ettiği

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 

Sen CodeGenModule düşünebilirsiniz LLVM montaj dosyası (.ll). CodeGenModule verildiğinde, ör. Bir .bc dosyaya yazma:

-- 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() 

Ayrıca onlar da Haskell API yoluyla göstermek beri, core classes of LLVM tanımaya önerilir.

0

CodeGenFunction, tek bir işlev için LLVM derleme kodunu korur. CodeGenModule, bu gibi çeşitli işlevleri korur. Haskell llvm bağlamaları paketinde, çalışma koduna sahip bir örnek dizin vardır.