ddc-build-0.4.2.1: DDC/Build/Pipeline/Llvm.hs
module DDC.Build.Pipeline.Llvm
( PipeLlvm(..)
, pipeLlvm)
where
import DDC.Build.Pipeline.Error
import DDC.Build.Pipeline.Sink
import DDC.Build.Builder
import DDC.Llvm.Pretty ()
import DDC.Base.Pretty
import Control.Monad
import qualified DDC.Llvm.Syntax as Llvm
import System.Directory
-- | Process an LLVM module.
data PipeLlvm
= PipeLlvmPrint Sink
| PipeLlvmCompile
{ pipeBuilder :: Builder
, pipeFileLlvm :: FilePath
, pipeFileAsm :: FilePath
, pipeFileObject :: FilePath
, pipeFileExe :: Maybe FilePath
, pipeLinkOtherObjects :: [FilePath]
, pipeKeepLlvmFiles :: Bool
, pipeKeepAsmFiles :: Bool }
deriving (Show)
-- | Process an LLVM module.
--
-- Returns empty list on success.
pipeLlvm
:: Llvm.Module
-> PipeLlvm
-> IO [Error]
pipeLlvm !mm !pp
= case pp of
PipeLlvmPrint !sink
-> {-# SCC "PipeLlvmPrint" #-}
pipeSink (renderIndent $ ppr mm) sink
PipeLlvmCompile
!builder !llPath !sPath !oPath !mExePath !osLinkOther
!keepLlvmFiles !keepAsmFiles
-> {-# SCC "PipeLlvmCompile" #-}
do -- Write out the LLVM source file.
let llSrc = renderIndent $ ppr mm
writeFile llPath llSrc
-- Compile LLVM source file into .s file.
buildLlc builder llPath sPath
-- Assemble .s file into .o file
buildAs builder sPath oPath
-- Link .o file into an executable if we were asked for one.
(case mExePath of
Nothing
-> return ()
Just exePath
-> do buildLdExe builder (oPath : osLinkOther) exePath
return ())
-- Remove LLVM IR files if we weren't asked for them.
when (not keepLlvmFiles)
$ removeFile llPath
-- Remove Asm IR files if we weren't asked for them.
when (not keepAsmFiles)
$ removeFile sPath
return []