สู่การทำความเข้าใจ CodeGen* ในการผูก Haskell LLVM

ความเป็นมา: ฉันกำลังเขียนของเล่น Lisp interperter/compiler ใน Haskell เพื่อความบันเทิง/การสั่งสอนของฉันเอง ฉันกำลังพยายามเพิ่มความสามารถในการคอมไพล์เป็น LLVM bytecode

บริบท: ฉันได้อ่านเอกสารประกอบสำหรับ LLVM.Core และตัวอย่างโค้ด (ที่นี่) พยายามที่จะเข้าใจ วิธีการรวมกัน และ วิธีการของนามธรรม (ตามที่อธิบายไว้ใน Abelson และ Sussman โครงสร้างและการตีความโปรแกรมคอมพิวเตอร์) ที่ใช้ในการผูก Haskell LLVM มีชิ้นส่วนเล็กๆ มากมาย และฉันไม่ชัดเจนว่าพวกมันตั้งใจจะทำงานร่วมกันอย่างไร ดูเหมือนว่ามีระดับของสิ่งที่เป็นนามธรรมเหนือคำสั่งเครื่อง LLVM พื้นฐานซึ่งเห็นได้ชัดสำหรับผู้ที่มีประสบการณ์มากมายกับ LLVM แต่ไม่ได้รับการบันทึกไว้สำหรับคนเช่นฉันที่เพิ่งจะเปียก

คำถาม: CodeGenModule และ CodeGenFunction คืออะไร และใช้ในการสร้าง Functions และ Modules ได้อย่างไร


person John F. Miller    schedule 15.06.2011    source แหล่งที่มา


คำตอบ (2)


ประเภท Module และ Function เป็นเพียงการห่อบางๆ รอบพอยน์เตอร์ไปยังอ็อบเจ็กต์ 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

ประเภท CodeGenModule และ CodeGenFunction เป็นส่วนหนึ่งของ EDSL ที่สร้างขึ้นบนโมดูล LLVM.FFI.* พวกเขาใช้ Function, Module และฟังก์ชันจาก LLVM.FFI.* ภายใน และอนุญาตให้คุณเขียน LLVM IR ใน Haskell อย่างกระชับโดยใช้ do-notation (ตัวอย่างที่นำมาจาก บล็อกของ 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

คุณสามารถนึกถึง CodeGenModule ว่าเป็น AST ที่แสดงถึงไฟล์แอสเซมบลี LLVM ที่แยกวิเคราะห์ (.ll) เมื่อให้ 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 () 

ฉันขอแนะนำให้คุณทำความคุ้นเคยกับ คลาสหลักของ LLVM เนื่องจากคลาสเหล่านี้จะแสดงผ่านใน Haskell API

person Mikhail Glushenkov    schedule 15.06.2011

CodeGenFunction รักษารหัสแอสเซมบลี LLVM สำหรับฟังก์ชันเดียว CodeGenModule รักษาฟังก์ชันดังกล่าวหลายประการ ในแพ็คเกจการผูก Haskell llvm จะมีไดเร็กทอรีตัวอย่างพร้อมโค้ดที่ใช้งานได้

person Lemming    schedule 25.06.2011