module DDC.Build.Pipeline.Llvm
( PipeLlvm(..)
, pipeLlvm)
where
import DDC.Build.Pipeline.Error
import DDC.Build.Pipeline.Sink
import DDC.Base.Pretty
import Control.Monad
import qualified DDC.Build.Builder as Build
import qualified DDC.Llvm.Pretty as Llvm
import qualified DDC.Llvm.Syntax as Llvm
import System.Directory
data PipeLlvm
= PipeLlvmPrint Sink
| PipeLlvmCompile
{ pipeBuilder :: Build.Builder
, pipeFileLlvm :: FilePath
, pipeFileAsm :: FilePath
, pipeFileObject :: FilePath
, pipeFileExe :: Maybe FilePath
, pipeLinkOtherObjects :: [FilePath]
, pipeKeepLlvmFiles :: Bool
, pipeKeepAsmFiles :: Bool }
deriving (Show)
pipeLlvm
:: Llvm.Module
-> PipeLlvm
-> IO [Error]
pipeLlvm !mm !pp
= case pp of
PipeLlvmPrint !sink
->
pipeSink (renderIndent $ ppr mm) sink
PipeLlvmCompile
!builder !llPath !sPath !oPath !mExePath !osLinkOther
!keepLlvmFiles !keepAsmFiles
->
do
let llConfig = Llvm.configOfVersion
$ Just $ Build.buildLlvmVersion builder
let llMode = Llvm.prettyModeModuleOfConfig llConfig
let llSrc = renderIndent $ pprModePrec llMode (0 :: Int) mm
writeFile llPath llSrc
Build.buildLlc builder llPath sPath
Build.buildAs builder sPath oPath
(case mExePath of
Nothing
-> return ()
Just exePath
-> do Build.buildLdExe builder (oPath : osLinkOther) exePath
return ())
when (not keepLlvmFiles)
$ removeFile llPath
when (not keepAsmFiles)
$ removeFile sPath
return []