module DDC.Core.Llvm.Convert
( convertModule
, convertType
, convertSuperType)
where
import DDC.Core.Llvm.Convert.Super
import DDC.Core.Llvm.Convert.Type
import DDC.Core.Llvm.LlvmM
import DDC.Llvm.Syntax
import DDC.Core.Salt.Platform
import DDC.Core.Compounds
import Control.Monad.State.Strict (evalState)
import Control.Monad.State.Strict (gets)
import Control.Monad
import Data.Map (Map)
import qualified DDC.Llvm.Transform.Clean as Llvm
import qualified DDC.Llvm.Transform.LinkPhi as Llvm
import qualified DDC.Core.Salt as A
import qualified DDC.Core.Module as C
import qualified DDC.Core.Exp as C
import qualified DDC.Type.Env as Env
import qualified DDC.Core.Simplifier as Simp
import qualified Data.Map as Map
convertModule :: Platform -> C.Module () A.Name -> Module
convertModule platform mm@(C.ModuleCore{})
=
let
prims = primDeclsMap platform
state = llvmStateInit platform mm prims
mmElab = Simp.result
$ evalState (Simp.applySimplifier
A.profile Env.empty Env.empty
(Simp.Trans Simp.Elaborate) mm)
state
stateElab = state { llvmStateModule = mmElab }
mmRaw = evalState (convModuleM mmElab) stateElab
mmClean = Llvm.clean mmRaw
mmPhi = Llvm.linkPhi mmClean
in mmPhi
convModuleM :: C.Module () A.Name -> LlvmM Module
convModuleM mm@(C.ModuleCore{})
| ([C.LRec bxs], _) <- splitXLets $ C.moduleBody mm
= do platform <- gets llvmStatePlatform
let vHeapTop = Var (NameGlobal "_DDC__heapTop") (tAddr platform)
let vHeapMax = Var (NameGlobal "_DDC__heapMax") (tAddr platform)
let globalsRts
| C.moduleName mm == C.ModuleName ["Main"]
= [ GlobalStatic vHeapTop (StaticLit (LitInt (tAddr platform) 0))
, GlobalStatic vHeapMax (StaticLit (LitInt (tAddr platform) 0)) ]
| otherwise
= [ GlobalExternal vHeapTop
, GlobalExternal vHeapMax ]
let kenv = C.moduleKindEnv mm
let tenv = C.moduleTypeEnv mm `Env.union` (Env.fromList $ map fst bxs)
let Just importDecls
= sequence
$ [ importedFunctionDeclOfType platform kenv
isrc
(lookup n (C.moduleExportValues mm))
n
(C.typeOfImportSource isrc)
| (n, isrc) <- C.moduleImportValues mm ]
(functions, mdecls)
<- liftM unzip
$ mapM (uncurry (convSuperM kenv tenv)) bxs
return $ Module
{ modComments = []
, modAliases = [aObj platform]
, modGlobals = globalsRts
, modFwdDecls = primDecls platform ++ importDecls
, modFuncs = functions
, modMDecls = concat mdecls }
| otherwise = die "Invalid module"
primDeclsMap :: Platform -> Map String FunctionDecl
primDeclsMap pp
= Map.fromList
$ [ (declName decl, decl) | decl <- primDecls pp ]
primDecls :: Platform -> [FunctionDecl]
primDecls pp
= [ FunctionDecl
{ declName = "malloc"
, declLinkage = External
, declCallConv = CC_Ccc
, declReturnType = tAddr pp
, declParamListType = FixedArgs
, declParams = [Param (tNat pp) []]
, declAlign = AlignBytes (platformAlignBytes pp) }
, FunctionDecl
{ declName = "abort"
, declLinkage = External
, declCallConv = CC_Ccc
, declReturnType = TVoid
, declParamListType = FixedArgs
, declParams = []
, declAlign = AlignBytes (platformAlignBytes pp) } ]