module LLVM.ExecutionEngine(
ExecutionEngine,
createExecutionEngine,
runStaticConstructors,
runStaticDestructors,
Translatable, Generic,
generateFunction,
Unsafe,
unsafePurify,
simpleFunction,
unsafeGenerateFunction
) where
import System.IO.Unsafe (unsafePerformIO)
import LLVM.ExecutionEngine.Engine
import LLVM.FFI.Core(ValueRef)
import LLVM.Core.CodeGen(Value(..))
import LLVM.Core
import LLVM.Core.Util(runFunctionPassManager, initializeFunctionPassManager, finalizeFunctionPassManager)
class Translatable f where
translate :: ExecutionEngine -> [GenericValue] -> ValueRef -> f
instance (Generic a, Translatable b) => Translatable (a -> b) where
translate ee args f = \ arg -> translate ee (toGeneric arg : args) f
instance (Generic a) => Translatable (IO a) where
translate ee args f = fmap fromGeneric $ runFunction ee f $ reverse args
generateFunction :: (Translatable f) =>
ExecutionEngine -> Value (Ptr f) -> f
generateFunction ee (Value f) = translate ee [] f
class Unsafe a b | a -> b where
unsafePurify :: a -> b
instance (Unsafe b b') => Unsafe (a->b) (a->b') where
unsafePurify f = unsafePurify . f
instance Unsafe (IO a) a where
unsafePurify = unsafePerformIO
simpleFunction :: (Translatable f) => CodeGenModule (Function f) -> IO f
simpleFunction bld = do
m <- newModule
func <- defineModule m bld
prov <- createModuleProviderForExistingModule m
ee <- createExecutionEngine prov
pm <- createFunctionPassManager prov
td <- getExecutionEngineTargetData ee
addTargetData td pm
addInstructionCombiningPass pm
addReassociatePass pm
addGVNPass pm
addCFGSimplificationPass pm
addPromoteMemoryToRegisterPass pm
initializeFunctionPassManager pm
runFunctionPassManager pm (unValue func)
finalizeFunctionPassManager pm
return $ generateFunction ee func
unsafeGenerateFunction :: (Unsafe t a, Translatable t) =>
CodeGenModule (Function t) -> a
unsafeGenerateFunction bld = unsafePerformIO $ do
fun <- simpleFunction bld
return $ unsafePurify fun