module LLVM.DSL.Execution where
import qualified LLVM.DSL.Dump as Dump
import qualified LLVM.ExecutionEngine as EE
import qualified LLVM.Util.Optimize as Opt
import qualified LLVM.Core as LLVM
import Foreign.Ptr (FunPtr)
import Control.Monad (void, liftM2, when)
import Control.Applicative (liftA2, pure, (<$>))
import Data.Functor.Compose (Compose(Compose))
import Prelude2010
import Prelude ()
dumper :: String -> IO (String -> LLVM.Module -> IO ())
dumper = Dump.writer
compile :: String -> Exec funcs -> IO funcs
compile name (Compose bld) = do
LLVM.initializeNativeTarget
td <- EE.getTargetData
m <- LLVM.newNamedModule name
(funcs, mappings) <-
LLVM.defineModule m $ do
LLVM.setTarget LLVM.hostTriple
LLVM.setDataLayout $ EE.dataLayoutStr td
liftM2 (,) bld LLVM.getGlobalMappings
writeBitcodeToFile <- dumper name
writeBitcodeToFile "" m
when True $ do
void $ Opt.optimizeModule 3 m
writeBitcodeToFile "-opt" m
EE.runEngineAccessWithModule m $
EE.addGlobalMappings mappings >> funcs
type Exec = Compose LLVM.CodeGenModule EE.EngineAccess
type Importer f = FunPtr f -> f
createLLVMFunction ::
(LLVM.FunctionArgs f) =>
String -> LLVM.FunctionCodeGen f -> LLVM.CodeGenModule (LLVM.Function f)
createLLVMFunction = LLVM.createNamedFunction LLVM.ExternalLinkage
createFunction ::
(EE.ExecutionFunction f, LLVM.FunctionArgs f) =>
Importer f -> String -> LLVM.FunctionCodeGen f -> Exec f
createFunction importer name f =
Compose $ EE.getExecutionFunction importer <$> createLLVMFunction name f
type Finalizer a = (EE.ExecutionEngine, LLVM.Ptr a -> IO ())
createFinalizer ::
(EE.ExecutionFunction f, LLVM.FunctionArgs f) =>
Importer f -> String -> LLVM.FunctionCodeGen f ->
Exec (EE.ExecutionEngine, f)
createFinalizer importer name f =
liftA2 (,)
(Compose $ pure EE.getEngine)
(createFunction importer name f)