diff options
Diffstat (limited to 'compiler/main/SysTools.hs')
-rw-r--r-- | compiler/main/SysTools.hs | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs index fa339bbb87..b3312b0dae 100644 --- a/compiler/main/SysTools.hs +++ b/compiler/main/SysTools.hs @@ -13,7 +13,7 @@ module SysTools ( -- * Initialisation initSysTools, - initLlvmConfig, + lazyInitLlvmConfig, -- * Interface to system tools module SysTools.Tasks, @@ -52,6 +52,7 @@ import DynFlags import Control.Monad.Trans.Except (runExceptT) import System.FilePath import System.IO +import System.IO.Unsafe (unsafeInterleaveIO) import SysTools.ExtraObj import SysTools.Info import SysTools.Tasks @@ -110,13 +111,34 @@ stuff. ************************************************************************ -} -initLlvmConfig :: String +-- Note [LLVM configuration] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- The `llvm-targets` and `llvm-passes` files are shipped with GHC and contain +-- information needed by the LLVM backend to invoke `llc` and `opt`. +-- Specifically: +-- +-- * llvm-targets maps autoconf host triples to the corresponding LLVM +-- `data-layout` declarations. This information is extracted from clang using +-- the script in utils/llvm-targets/gen-data-layout.sh and should be updated +-- whenever we target a new version of LLVM. +-- +-- * llvm-passes maps GHC optimization levels to sets of LLVM optimization +-- flags that GHC should pass to `opt`. +-- +-- This information is contained in files rather the GHC source to allow users +-- to add new targets to GHC without having to recompile the compiler. +-- +-- Since this information is only needed by the LLVM backend we load it lazily +-- with unsafeInterleaveIO. Consequently it is important that we lazily pattern +-- match on LlvmConfig until we actually need its contents. + +lazyInitLlvmConfig :: String -> IO LlvmConfig -initLlvmConfig top_dir - = do +lazyInitLlvmConfig top_dir + = unsafeInterleaveIO $ do -- see Note [LLVM configuration] targets <- readAndParse "llvm-targets" mkLlvmTarget passes <- readAndParse "llvm-passes" id - return (targets, passes) + return $ LlvmConfig { llvmTargets = targets, llvmPasses = passes } where readAndParse name builder = do let llvmConfigFile = top_dir </> name |