Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to LLVM 5.1 #46

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ before_install:
- travis_retry sudo apt-get update
- sudo apt-get install libedit-dev -y
- sudo apt-get install -y llvm-$LLVMVER llvm-$LLVMVER-dev
- alias llvm-config="llvm-config-4.0"
- alias llvm-config="llvm-config"
#- sudo ln -s /usr/bin/opt-$LLVMVER /usr/bin/opt
- export PATH="/usr/bin:$PATH"

Expand All @@ -51,4 +51,4 @@ install:
# Here starts the actual work to be performed for the package under test; any command which exits
# with a non-zero exit code causes the build to fail.
script:
- cabal install
- cabal install
31 changes: 16 additions & 15 deletions kaleidoscope.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ Source-Repository head
executable chapter2
default-language: Haskell2010
main-is: Main.hs
other-modules:
other-modules:
Parser
Syntax
Lexer
build-depends:
base >= 4.7 && <5
, haskeline >= 0.7.1.2
, llvm-hs >= 4.0.0.0
, llvm-hs-pure >= 4.0.0.0
, llvm-hs >= 5.1.0.0
, llvm-hs-pure >= 5.1.0.0
, parsec >= 3.1
, mtl >= 2.1.3
, transformers >= 0.3.0.0 && < 0.6
Expand All @@ -47,12 +47,13 @@ executable chapter3
build-depends:
base >= 4.7 && <5
, haskeline >= 0.7.1.2
, llvm-hs >= 4.0.0.0
, llvm-hs-pure >= 4.0.0.0
, llvm-hs >= 5.1.0.0
, llvm-hs-pure >= 5.1.0.0
, parsec >= 3.1
, mtl >= 2.1.3
, transformers >= 0.3.0.0 && < 0.6
, containers >= 0.4
, bytestring
hs-source-dirs: src/chapter3

executable chapter4
Expand All @@ -69,8 +70,8 @@ executable chapter4
build-depends:
base >= 4.7 && <5
, haskeline >= 0.7.1.2
, llvm-hs >= 4.0.0.0
, llvm-hs-pure >= 4.0.0.0
, llvm-hs >= 5.1.0.0
, llvm-hs-pure >= 5.1.0.0
, parsec >= 3.1
, containers >= 0.4
, mtl >= 2.1.3
Expand All @@ -91,8 +92,8 @@ executable chapter5
build-depends:
base >= 4.7 && <5
, haskeline >= 0.7.1.2
, llvm-hs >= 4.0.0.0
, llvm-hs-pure >= 4.0.0.0
, llvm-hs >= 5.1.0.0
, llvm-hs-pure >= 5.1.0.0
, parsec >= 3.1
, containers >= 0.4
, mtl >= 2.1.3
Expand All @@ -113,8 +114,8 @@ executable chapter6
build-depends:
base >= 4.7 && <5
, haskeline >= 0.7.1.2
, llvm-hs >= 4.0.0.0
, llvm-hs-pure >= 4.0.0.0
, llvm-hs >= 5.1.0.0
, llvm-hs-pure >= 5.1.0.0
, parsec >= 3.1
, containers >= 0.4
, mtl >= 2.1.3
Expand All @@ -135,8 +136,8 @@ executable chapter7
build-depends:
base >= 4.7 && <5
, haskeline >= 0.7.1.2
, llvm-hs >= 4.0.0.0
, llvm-hs-pure >= 4.0.0.0
, llvm-hs >= 5.1.0.0
, llvm-hs-pure >= 5.1.0.0
, parsec >= 3.1
, containers >= 0.4
, mtl >= 2.1.3
Expand All @@ -148,7 +149,7 @@ library
build-depends:
base >= 4.7 && <5
, haskeline >= 0.7.1.2
, llvm-hs >= 4.0.0.0
, llvm-hs-pure >= 4.0.0.0
, llvm-hs >= 5.1.0.0
, llvm-hs-pure >= 5.1.0.0
, mtl >= 2.1.3
, transformers >= 0.3.0.0 && < 0.6
61 changes: 43 additions & 18 deletions src/chapter3/Codegen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import Data.Word
import Data.String
import Data.List
import Data.Function
import Data.ByteString.Short (ShortByteString)
import qualified Data.Map as Map

import Control.Monad.State
import Control.Applicative

import LLVM.AST
import LLVM.AST.Global
import LLVM.AST.AddrSpace
import qualified LLVM.AST as AST

import qualified LLVM.AST.Linkage as L
Expand All @@ -33,51 +35,68 @@ runLLVM :: AST.Module -> LLVM a -> AST.Module
runLLVM mod (LLVM m) = execState m mod

emptyModule :: String -> AST.Module
emptyModule label = defaultModule { moduleName = label }
emptyModule label = defaultModule { moduleName = fromString label }

addDefn :: Definition -> LLVM ()
addDefn d = do
defs <- gets moduleDefinitions
modify $ \s -> s { moduleDefinitions = defs ++ [d] }

define :: Type -> String -> [(Type, Name)] -> [BasicBlock] -> LLVM ()
define :: Type -> Name -> [(Type, Name)] -> [BasicBlock] -> LLVM ()
define retty label argtys body = addDefn $
GlobalDefinition $ functionDefaults {
name = Name label
name = label
, parameters = ([Parameter ty nm [] | (ty, nm) <- argtys], False)
, returnType = retty
, basicBlocks = body
}

external :: Type -> String -> [(Type, Name)] -> LLVM ()
external :: Type -> Name -> [(Type, Name)] -> LLVM ()
external retty label argtys = addDefn $
GlobalDefinition $ functionDefaults {
name = Name label
name = label
, linkage = L.External
, parameters = ([Parameter ty nm [] | (ty, nm) <- argtys], False)
, returnType = retty
, basicBlocks = []
}

lookupFnTypeH :: [Definition] -> Name -> Type
lookupFnTypeH defs nm =
case lookup nm fns of
Nothing -> error $ "Function not declared: " ++ show nm
Just (rt, (params, _)) -> pointerType rt [ty | (Parameter ty _ _) <- params]
where
fns = [(nm, (rt, params)) | GlobalDefinition f@(Function { name = nm, returnType = rt, parameters = params }) <- defs]
pointerType resultType argsType =
PointerType {
pointerReferent = FunctionType {
resultType = resultType
, argumentTypes = argsType
, isVarArg = False
}
, pointerAddrSpace = AddrSpace 0 -- TODO: Really?
}

---------------------------------------------------------------------------------
-- Types
-------------------------------------------------------------------------------

-- IEEE 754 double
double :: Type
double = FloatingPointType 64 IEEE
double = FloatingPointType DoubleFP

-------------------------------------------------------------------------------
-- Names
-------------------------------------------------------------------------------

type Names = Map.Map String Int
type Names = Map.Map ShortByteString Int

uniqueName :: String -> Names -> (String, Names)
uniqueName :: ShortByteString -> Names -> (Name, Names)
uniqueName nm ns =
case Map.lookup nm ns of
Nothing -> (nm, Map.insert nm 1 ns)
Just ix -> (nm ++ show ix, Map.insert nm (ix+1) ns)
Nothing -> (Name $ nm, Map.insert nm 1 ns)
Just ix -> (Name $ nm `mappend` fromString (show ix), Map.insert nm (ix+1) ns)

-------------------------------------------------------------------------------
-- Codegen State
Expand Down Expand Up @@ -121,7 +140,7 @@ makeBlock (l, (BlockState _ s t)) = BasicBlock l (reverse s) (maketerm t)
maketerm (Just x) = x
maketerm Nothing = error $ "Block has no terminator: " ++ (show l)

entryBlockName :: String
entryBlockName :: ShortByteString
entryBlockName = "entry"

emptyBlock :: Int -> BlockState
Expand All @@ -148,6 +167,12 @@ instr ins = do
modifyBlock (blk { stack = (ref := ins) : i } )
return $ local ref

unnminstr :: Instruction -> Codegen ()
unnminstr ins = do
blk <- current
let i = stack blk
modifyBlock (blk { stack = (Do ins) : i } )

terminator :: Named Terminator -> Codegen (Named Terminator)
terminator trm = do
blk <- current
Expand All @@ -161,7 +186,7 @@ terminator trm = do
entry :: Codegen Name
entry = gets currentBlock

addBlock :: String -> Codegen Name
addBlock :: ShortByteString -> Codegen Name
addBlock bname = do
bls <- gets blocks
ix <- gets blockCount
Expand All @@ -170,11 +195,11 @@ addBlock bname = do
let new = emptyBlock ix
(qname, supply) = uniqueName bname nms

modify $ \s -> s { blocks = Map.insert (Name qname) new bls
modify $ \s -> s { blocks = Map.insert qname new bls
, blockCount = ix + 1
, names = supply
}
return (Name qname)
return qname

setBlock :: Name -> Codegen Name
setBlock bname = do
Expand Down Expand Up @@ -222,8 +247,8 @@ local = LocalReference double
global :: Name -> C.Constant
global = C.GlobalReference double

externf :: Name -> Operand
externf = ConstantOperand . C.GlobalReference double
externf :: Type -> Name -> Operand
externf ty nm = ConstantOperand $ C.GlobalReference ty nm

-- Arithmetic and Constants
fadd :: Operand -> Operand -> Codegen Operand
Expand Down Expand Up @@ -257,8 +282,8 @@ call fn args = instr $ Call Nothing CC.C [] (Right fn) (toArgs args) [] []
alloca :: Type -> Codegen Operand
alloca ty = instr $ Alloca ty Nothing 0 []

store :: Operand -> Operand -> Codegen Operand
store ptr val = instr $ Store False ptr val Nothing 0 []
store :: Operand -> Operand -> Codegen ()
store ptr val = unnminstr $ Store False ptr val Nothing 0 []

load :: Operand -> Codegen Operand
load ptr = instr $ Load False ptr Nothing 0 []
Expand Down
80 changes: 43 additions & 37 deletions src/chapter3/Emit.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,54 @@

module Emit where

import LLVM.Module
import LLVM.Context
import LLVM.Module (withModuleFromAST, moduleLLVMAssembly)
import LLVM.Context (withContext)

import qualified LLVM.AST.Global as AST (name, returnType)
import qualified LLVM.AST as AST
import qualified LLVM.AST.Constant as C
import qualified LLVM.AST.Float as F
import qualified LLVM.AST.FloatingPointPredicate as FP

import Data.Word
import Data.Int
import Control.Monad.State
import Control.Monad.Except
import Control.Applicative
import Data.ByteString.Short (ShortByteString)
import qualified Data.ByteString.Char8 as BS (putStrLn)
import qualified Data.Map as Map

import Codegen
import qualified Syntax as S

toSig :: [String] -> [(AST.Type, AST.Name)]
toSig = map (\x -> (double, AST.Name x))
toSig :: [S.Name] -> [(AST.Type, AST.Name)]
toSig = map (\x -> (double, AST.mkName x))

codegenTop :: S.Expr -> LLVM ()
codegenTop (S.Function name args body) = do
define double name fnargs bls
defs <- gets AST.moduleDefinitions
let bls = createBlocks $ execCodegen $ do
entry <- addBlock entryBlockName
setBlock entry
forM args $ \a -> do
var <- alloca double
store var (local (AST.mkName a))
assign a var
cgen (lookupFnTypeH defs) body >>= ret
define double (AST.mkName name) fnargs bls
where
fnargs = toSig args
bls = createBlocks $ execCodegen $ do
entry <- addBlock entryBlockName
setBlock entry
forM args $ \a -> do
var <- alloca double
store var (local (AST.Name a))
assign a var
cgen body >>= ret

codegenTop (S.Extern name args) = do
external double name fnargs
external double (AST.mkName name) fnargs
where fnargs = toSig args

codegenTop exp = do
defs <- gets AST.moduleDefinitions
let blks = createBlocks $ execCodegen $ do
entry <- addBlock entryBlockName
setBlock entry
cgen (lookupFnTypeH defs) exp >>= ret
define double "main" [] blks
where
blks = createBlocks $ execCodegen $ do
entry <- addBlock entryBlockName
setBlock entry
cgen exp >>= ret


-------------------------------------------------------------------------------
-- Operations
Expand All @@ -65,26 +68,29 @@ binops = Map.fromList [
, ("<", lt)
]

cgen :: S.Expr -> Codegen AST.Operand
cgen (S.UnaryOp op a) = do
cgen $ S.Call ("unary" ++ op) [a]
cgen (S.BinaryOp "=" (S.Var var) val) = do
cgen :: (AST.Name -> AST.Type) -> S.Expr -> Codegen AST.Operand
cgen lookupFnType (S.UnaryOp op a) = do
cgen lookupFnType $ S.Call ("unary" ++ op) [a]
cgen lookupFnType (S.BinaryOp "=" (S.Var var) val) = do
a <- getvar var
cval <- cgen val
cval <- cgen lookupFnType val
store a cval
return cval
cgen (S.BinaryOp op a b) = do
cgen lookupFnType (S.BinaryOp op a b) = do
case Map.lookup op binops of
Just f -> do
ca <- cgen a
cb <- cgen b
ca <- cgen lookupFnType a
cb <- cgen lookupFnType b
f ca cb
Nothing -> error "No such operator"
cgen (S.Var x) = getvar x >>= load
cgen (S.Float n) = return $ cons $ C.Float (F.Double n)
cgen (S.Call fn args) = do
largs <- mapM cgen args
call (externf (AST.Name fn)) largs
cgen _ (S.Var x) = getvar x >>= load
cgen _ (S.Float n) = return $ cons $ C.Float (F.Double n)
cgen lookupFnType (S.Call fn args) = do
largs <- mapM (cgen lookupFnType) args
call (externf fnType fnnm) largs
where
fnnm = AST.mkName fn
fnType = lookupFnType fnnm

-------------------------------------------------------------------------------
-- Compilation
Expand All @@ -95,9 +101,9 @@ liftError = runExceptT >=> either fail return

codegen :: AST.Module -> [S.Expr] -> IO AST.Module
codegen mod fns = withContext $ \context ->
liftError $ withModuleFromAST context newast $ \m -> do
withModuleFromAST context newast $ \m -> do
llstr <- moduleLLVMAssembly m
putStrLn llstr
BS.putStrLn llstr
return newast
where
modn = mapM codegenTop fns
Expand Down
Loading