-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathMain.hs
More file actions
91 lines (80 loc) · 2.63 KB
/
Main.hs
File metadata and controls
91 lines (80 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wall #-}
module Main where
import Control.Monad.Except
import qualified Data.ByteString.Char8 as BS
import Data.IORef
import Data.Int
import qualified Data.Map.Strict as Map
import Foreign.Ptr
import LLVM.AST
import qualified LLVM.AST as AST
import LLVM.AST.Constant
import LLVM.AST.Global
import LLVM.CodeGenOpt
import LLVM.CodeModel
import LLVM.Context
import LLVM.Internal.OrcJIT.CompileLayer
import LLVM.Module
import LLVM.OrcJIT
import LLVM.Relocation
import LLVM.Target
import Prelude hiding (mod)
foreign import ccall "dynamic"
mkMain :: FunPtr (IO Int32) -> IO Int32
int :: Type
int = IntegerType 32
defAdd :: Definition
defAdd =
GlobalDefinition
functionDefaults
{ name = Name "add",
parameters = ([], False),
returnType = int,
basicBlocks = [body]
}
where
body =
BasicBlock
(Name "entry")
[]
(Do $ Ret (Just (ConstantOperand (Int 32 42))) [])
module_ :: AST.Module
module_ =
defaultModule
{ moduleName = "basic",
moduleDefinitions = [defAdd]
}
withTestModule :: AST.Module -> (LLVM.Module.Module -> IO a) -> IO a
withTestModule mod f = withContext $ \context -> withModuleFromAST context mod f
resolver :: CompileLayer l => l -> MangledSymbol -> IO (Either JITSymbolError JITSymbol)
resolver compileLayer symbol = findSymbol compileLayer symbol True
failInIO :: ExceptT String IO a -> IO a
failInIO = either fail return <=< runExceptT
eagerJit :: AST.Module -> IO ()
eagerJit amod = do
resolvers <- newIORef Map.empty
withTestModule amod $ \mod ->
withHostTargetMachine PIC LLVM.CodeModel.Default LLVM.CodeGenOpt.Default $ \tm ->
withExecutionSession $ \es ->
withObjectLinkingLayer es (\k -> fmap (\rs -> rs Map.! k) (readIORef resolvers)) $ \linkingLayer ->
withIRCompileLayer linkingLayer tm $ \compileLayer -> do
mainSymbol <- mangleSymbol compileLayer "add"
asm <- moduleLLVMAssembly mod
BS.putStrLn asm
withModuleKey es $ \k ->
withSymbolResolver es (SymbolResolver (resolver compileLayer)) $ \sresolver -> do
modifyIORef' resolvers (Map.insert k sresolver)
rsym <- findSymbol compileLayer mainSymbol True
case rsym of
Left err -> do
print err
Right (JITSymbol mainFn _) -> do
result <- mkMain (castPtrToFunPtr (wordPtrToPtr mainFn))
print result
main :: IO ()
main = do
res <- eagerJit module_
putStrLn "Eager JIT Result:"
print res