Skip to content

Commit cc13dbe

Browse files
committed
JIT, extern , evaluation completed
1 parent e5a7f86 commit cc13dbe

File tree

6 files changed

+121
-38
lines changed

6 files changed

+121
-38
lines changed

package.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: Haskull
22
version: 0.1.0.0
33
github: "https://github.com/IITH-SBJoshi/haskell-11"
44
license: BSD3
5-
author: "Anjani Kumar"
6-
maintainer: "cs17btech11002@iith.ac.in"
7-
copyright: "2019 Anjani Kumar"
5+
author: "Vijay"
6+
maintainer: "cs17btech11040@iith.ac.in"
7+
copyright: "2019 Vijay"
88

99
extra-source-files:
1010
- README.md

src/AST.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ data Op
8080
| Minus
8181
| Mul
8282
| Divide
83+
| Null
8384
deriving (Show, Ord, Eq)
8485

8586
data Type

src/CodeGen.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module CodeGen (
2020
getvar,
2121
assign,
2222
createBlocks,
23+
external,
2324
Codegen(..),
2425
CodegenState(..),
2526
BlockState(..),
@@ -84,6 +85,11 @@ define retty label argtys body = addDef $
8485
, basicBlocks = body
8586
}
8687

88+
89+
-- | Defines a function here the return type is Type
90+
external :: ASTL.Type -> String -> [(ASTL.Type, ASTL.Name)] -> LLVM ()
91+
external retty label argtys = define retty label argtys []
92+
8793
addDef :: ASTL.Definition -> LLVM ()
8894
addDef def = do
8995
prev <- gets ASTL.moduleDefinitions

src/Emit.hs

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@ module Emit (
1616
varDeclGen,
1717
literalGen,
1818
moduleGen,
19+
codegenTop',
1920
call,
2021
toArgs,
2122

22-
x',
23-
y',
2423
funcCallGen,
2524

2625
)where
@@ -46,7 +45,7 @@ import qualified LLVM.AST.Attribute as A
4645

4746
import Control.Monad.State
4847
import Control.Applicative
49-
48+
import JIT
5049
-- | Parser ASTL to LLVM code
5150

5251

@@ -77,16 +76,16 @@ binops = Map.fromList [
7776

7877
-- Arithmetic and Constants
7978
fadd :: ASTL.Operand -> ASTL.Operand -> Codegen ASTL.Operand
80-
fadd a b = instr $ FAdd NoFastMathFlags a b []
79+
fadd a b = instr $ ASTL.Add False False a b []
8180

8281
fsub :: ASTL.Operand -> ASTL.Operand -> Codegen ASTL.Operand
83-
fsub a b = instr $ FSub NoFastMathFlags a b []
82+
fsub a b = instr $ ASTL.Sub False False a b []
8483

8584
fmul :: ASTL.Operand -> ASTL.Operand -> Codegen ASTL.Operand
86-
fmul a b = instr $ FMul NoFastMathFlags a b []
85+
fmul a b = instr $ ASTL.Mul False False a b []
8786

8887
fdiv :: ASTL.Operand -> ASTL.Operand -> Codegen ASTL.Operand
89-
fdiv a b = instr $ FDiv NoFastMathFlags a b []
88+
fdiv a b = instr $ ASTL.UDiv False a b []
9089

9190
externf :: ASTL.Name -> ASTL.Operand
9291
externf = ConstantOperand . C.GlobalReference intL
@@ -101,42 +100,50 @@ toArgs :: [ASTL.Operand] -> [(ASTL.Operand, [A.ParameterAttribute])]
101100
toArgs = map (\x -> (x, []))
102101

103102

103+
liftError :: ExceptT String IO a -> IO a
104+
liftError = runExceptT >=> either fail return
104105

105106

106-
y' :: Traversable t => t Func -> LLVM (t ())
107-
y' fns = mapM codegenTop fns
108-
109-
x' :: ASTL.Module -> LLVM a -> ASTL.Module
110-
x' mod modn = runLLVM mod modn
111-
107+
-- | Actions associated with each branch of ASTL
108+
-- | Used to refer to a variable
112109

113110

114111
-- withContext == Create a Context, run an action (to which it is provided), then destroy the Context.
112+
-- codegen :: ASTL.Module -> [ASTp.Func] -> IO ASTL.Module
113+
-- codegen mod fns = withContext $ \context -> -- fns = [(Function "foo " ["a", "b"] (Float 1.0)) ]
114+
-- liftError $ withModuleFromAST context newast $ \m -> do
115+
-- llstr <- moduleLLVMAssembly m
116+
-- putStrLn llstr
117+
-- return newast
118+
-- where
119+
-- modn = mapM codegenTop fns -- list of LLVM ()
120+
-- newast = runLLVM mod modn
121+
115122
codegen :: ASTL.Module -> [ASTp.Func] -> IO ASTL.Module
116-
codegen mod fns = withContext $ \context -> -- fns = [(Function "foo " ["a", "b"] (Float 1.0)) ]
123+
codegen mod fns = do
124+
res <- runJIT oldast
125+
case res of
126+
Right newast -> return newast
127+
Left err -> putStrLn err >> return oldast
128+
where
129+
modn = mapM codegenTop fns
130+
oldast = runLLVM mod modn
131+
132+
codegen' :: ASTL.Module -> [ASTp.Declaration] -> IO ASTL.Module
133+
codegen' mod decl = withContext $ \context ->
117134
liftError $ withModuleFromAST context newast $ \m -> do
118135
llstr <- moduleLLVMAssembly m
119136
putStrLn llstr
120137
return newast
121138
where
122-
modn = mapM codegenTop fns -- list of LLVM ()
139+
modn = mapM codegenTop' decl -- list of LLVM ()
123140
newast = runLLVM mod modn
124141

125142

126-
127-
128-
129-
130-
liftError :: ExceptT String IO a -> IO a
131-
liftError = runExceptT >=> either fail return
132-
133-
134-
135-
-- funcGen :: ASTp.Func -> LLVM ()
136-
-- funcGen x = addDef $ getDef x
137-
138-
-- declarationGen :: ASTp.Declaration -> LLVM ()
139-
-- declarationGen c@(ASTp.ExternDecl _ _ _) = addDef $ getExtern c
143+
codegenTop' :: ASTp.Declaration -> LLVM ()
144+
codegenTop' (ASTp.ExternDecl name fnargs retT) = do
145+
external intL name args
146+
where args = getArgList fnargs
140147

141148

142149

@@ -146,6 +153,9 @@ liftError = runExceptT >=> either fail return
146153

147154
-- | Parser Module to LLVM Module
148155
moduleGen :: ASTL.Module -> ASTp.Module -> IO ASTL.Module
156+
moduleGen modL (ASTp.Command (DeclarationStmt c@(ExternDecl _ _ _))) =
157+
codegen' modL [c]
158+
149159
moduleGen modL (ASTp.Method func) = codegen modL [func]
150160
moduleGen modL (ASTp.Command expr) = codegen modL [rest]
151161
where rest = ASTp.Func {

src/JIT.hs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module JIT where
2+
3+
import Data.Int
4+
import Data.Word
5+
import Foreign.Ptr ( FunPtr, castFunPtr )
6+
7+
import Control.Monad.Except
8+
9+
import LLVM.Target
10+
import LLVM.Context
11+
import LLVM.CodeModel
12+
import LLVM.Module as Mod
13+
import qualified LLVM.AST as AST
14+
15+
import LLVM.PassManager
16+
import LLVM.Transforms
17+
import LLVM.Analysis
18+
19+
import qualified LLVM.ExecutionEngine as EE
20+
21+
foreign import ccall "dynamic" haskFun :: FunPtr (IO Int) -> (IO Int)
22+
23+
run :: FunPtr a -> IO Int
24+
run fn = haskFun (castFunPtr fn :: FunPtr (IO Int))
25+
26+
jit :: Context -> (EE.MCJIT -> IO a) -> IO a
27+
jit c = EE.withMCJIT c optlevel model ptrelim fastins
28+
where
29+
optlevel = Just 0 -- optimization level
30+
model = Nothing -- code model ( Default )
31+
ptrelim = Nothing -- frame pointer elimination
32+
fastins = Nothing -- fast instruction selection
33+
34+
passes :: PassSetSpec
35+
passes = defaultCuratedPassSetSpec { optLevel = Just 3 }
36+
37+
runJIT :: AST.Module -> IO (Either String AST.Module)
38+
runJIT mod = do
39+
withContext $ \context ->
40+
jit context $ \executionEngine ->
41+
runExceptT $ withModuleFromAST context mod $ \m ->
42+
withPassManager passes $ \pm -> do
43+
-- Optimization Pass
44+
runPassManager pm m
45+
optmod <- moduleAST m
46+
s <- moduleLLVMAssembly m
47+
putStrLn s
48+
49+
EE.withModuleInEngine executionEngine m $ \ee -> do
50+
mainfn <- EE.getFunction ee (AST.Name "main")
51+
case mainfn of
52+
Just fn -> do
53+
res <- run fn
54+
putStrLn $ "Evaluated to: " ++ show res
55+
Nothing -> return ()
56+
57+
-- Return the optimized module
58+
return optmod

src/Parser.hs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
module Parser (
22
moduleParser,
3-
z',
43
funcParser
54
)where
65

@@ -13,9 +12,6 @@ import qualified Text.Parsec.Token as Tok
1312
import qualified Data.Map as Map
1413
import AST
1514

16-
z' = [Func {fname = "x", argList = [(IntC,"p")], retType = IntC, body = [ DeclarationStmt (VarDecl {vType = IntC, vName = ["y"]}) ]}]
17-
18-
1915
moduleParser :: Parser Module
2016
moduleParser = spaces >> ( try methodParser
2117
<|> commandParser )
@@ -49,8 +45,7 @@ funcParser = do
4945

5046

5147
exprParser :: Parser Expr
52-
exprParser = try binOpCallStmtParser
53-
<|> try factor
48+
exprParser = try primary
5449
<|> declarationStmtParser
5550

5651
variableParser :: Parser Expr
@@ -168,11 +163,24 @@ funcCallParser = do
168163
(spaces >> (char ')') >> spaces)
169164
return $ FuncCall callee args
170165

166+
171167
binOpCallStmtParser :: Parser Expr
172168
binOpCallStmtParser = do
173169
res <- binOpCallParser
174170
return $ BinOpCallStmt res
175171

172+
primary :: Parser Expr
173+
primary = do
174+
res <- factor
175+
spaces
176+
lop <- try (lookAhead opParser) <|> return Null
177+
if lop == Null
178+
then return res
179+
else do
180+
lhs <- try (func res) <|> (return res)
181+
return lhs
182+
183+
176184
binOpCallParser :: Parser BinOpCall
177185
binOpCallParser = do
178186
temp <- factor

0 commit comments

Comments
 (0)