module LLVM.Internal.OrcJIT.IRTransformLayer where
import LLVM.Prelude
import Control.Exception
import Control.Monad.AnyCont
import Control.Monad.IO.Class
import Data.IORef
import Foreign.Ptr
import qualified LLVM.Internal.FFI.DataLayout as FFI
import qualified LLVM.Internal.FFI.Module as FFI
import qualified LLVM.Internal.FFI.OrcJIT.IRTransformLayer as FFI
import qualified LLVM.Internal.FFI.PtrHierarchy as FFI
import LLVM.Internal.OrcJIT
import LLVM.Internal.OrcJIT.CompileLayer
import LLVM.Internal.Target
data IRTransformLayer baseLayer =
IRTransformLayer {
compileLayer :: !(Ptr FFI.IRTransformLayer),
dataLayout :: !(Ptr FFI.DataLayout),
cleanupActions :: !(IORef [IO ()])
}
deriving Eq
instance CompileLayer (IRTransformLayer l) where
getCompileLayer = FFI.upCast . compileLayer
getDataLayout = dataLayout
getCleanups = cleanupActions
newIRTransformLayer
:: CompileLayer l
=> l
-> TargetMachine
-> (Ptr FFI.Module -> IO (Ptr FFI.Module))
-> IO (IRTransformLayer l)
newIRTransformLayer compileLayer tm moduleTransform =
flip runAnyContT return $ do
cleanups <- liftIO (newIORef [])
dl <- createRegisteredDataLayout tm cleanups
let encodedModuleTransform =
allocFunPtr cleanups (FFI.wrapModuleTransform moduleTransform)
moduleTransform' <-
anyContToM $ bracketOnError encodedModuleTransform freeHaskellFunPtr
cl <-
liftIO
(FFI.createIRTransformLayer
(getCompileLayer compileLayer)
moduleTransform')
return (IRTransformLayer cl dl cleanups)
withIRTransformLayer ::
CompileLayer l
=> l
-> TargetMachine
-> (Ptr FFI.Module -> IO (Ptr FFI.Module))
-> (IRTransformLayer l -> IO a)
-> IO a
withIRTransformLayer compileLayer tm moduleTransform =
bracket
(newIRTransformLayer compileLayer tm moduleTransform)
disposeCompileLayer