Подтвердить что ты не робот

К пониманию CodeGen * в привязках LLVM Haskell

Фон: Я пишу игрушку Lisp interperter/compiler в Haskell для собственного развлечения/назидания. Я пытаюсь добавить возможность компиляции в байт-код LLVM.

Контекст: Я читал документацию для LLVM.Core и пример кода (здесь), пытаясь понять средства сочетания и средства абстракции (как описано в Структура и интерпретация Абельсона и Суссмана компьютерных программ.), используемых в привязках LLVM Haskell. Есть много мелких предметов, и я не совсем понимаю, как они предназначены для совместной работы. Похоже, что есть уровень абстракции выше основных инструкций машины LLVM, которые очевидны для кого-то, у кого большой опыт работы с LLVM, но не документированы для тех, кто я, как я, просто мокрые ноги.

Вопрос: Что такое CodeGenModule и CodeGenFunction и как они используются для создания Functions и Modules?

4b9b3361

Ответ 1

Типы Module и Function представляют собой только тонкие обертки вокруг указателей на соответствующие объекты С++ (то есть 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 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

Вы можете думать о 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, так как они также отображаются в API Haskell.

Ответ 2

CodeGenFunction поддерживает код сборки LLVM для одной функции. CodeGenModule поддерживает несколько таких функций. В пакете привязок llvm Haskell есть пример каталога с рабочим кодом.