diff options
Diffstat (limited to 'compiler/main')
-rw-r--r-- | compiler/main/CodeOutput.lhs | 57 | ||||
-rw-r--r-- | compiler/main/DynFlags.hs | 4 | ||||
-rw-r--r-- | compiler/main/HscMain.hs | 75 | ||||
-rw-r--r-- | compiler/main/HscTypes.lhs | 6 |
4 files changed, 93 insertions, 49 deletions
diff --git a/compiler/main/CodeOutput.lhs b/compiler/main/CodeOutput.lhs index 24906671cd..e92eb4f34c 100644 --- a/compiler/main/CodeOutput.lhs +++ b/compiler/main/CodeOutput.lhs @@ -15,22 +15,22 @@ import UniqSupply ( mkSplitUniqSupply ) import Finder ( mkStubPaths ) import PprC ( writeCs ) -import CmmLint ( cmmLint ) +import OldCmmLint ( cmmLint ) import Packages import OldCmm ( RawCmmGroup ) import HscTypes import DynFlags import Config import SysTools +import Stream (Stream) +import qualified Stream import ErrUtils import Outputable import Module -import Maybes ( firstJusts ) import SrcLoc import Control.Exception -import Control.Monad import System.Directory import System.FilePath import System.IO @@ -48,19 +48,26 @@ codeOutput :: DynFlags -> ModLocation -> ForeignStubs -> [PackageId] - -> [RawCmmGroup] -- Compiled C-- + -> Stream IO RawCmmGroup () -- Compiled C-- -> IO (Bool{-stub_h_exists-}, Maybe FilePath{-stub_c_exists-}) -codeOutput dflags this_mod location foreign_stubs pkg_deps flat_abstractC +codeOutput dflags this_mod location foreign_stubs pkg_deps cmm_stream = - do { when (dopt Opt_DoCmmLinting dflags) $ do + do { + -- Lint each CmmGroup as it goes past + ; let linted_cmm_stream = + if dopt Opt_DoCmmLinting dflags + then Stream.mapM do_lint cmm_stream + else cmm_stream + + do_lint cmm = do { showPass dflags "CmmLint" - ; let lints = map (cmmLint (targetPlatform dflags)) flat_abstractC - ; case firstJusts lints of + ; case cmmLint (targetPlatform dflags) cmm of Just err -> do { log_action dflags dflags SevDump noSrcSpan defaultDumpStyle err ; ghcExit dflags 1 } Nothing -> return () + ; return cmm } ; showPass dflags "CodeOutput" @@ -68,9 +75,9 @@ codeOutput dflags this_mod location foreign_stubs pkg_deps flat_abstractC ; stubs_exist <- outputForeignStubs dflags this_mod location foreign_stubs ; case hscTarget dflags of { HscInterpreted -> return (); - HscAsm -> outputAsm dflags filenm flat_abstractC; - HscC -> outputC dflags filenm flat_abstractC pkg_deps; - HscLlvm -> outputLlvm dflags filenm flat_abstractC; + HscAsm -> outputAsm dflags filenm linted_cmm_stream; + HscC -> outputC dflags filenm linted_cmm_stream pkg_deps; + HscLlvm -> outputLlvm dflags filenm linted_cmm_stream; HscNothing -> panic "codeOutput: HscNothing" } ; return stubs_exist @@ -90,12 +97,16 @@ doOutput filenm io_action = bracket (openFile filenm WriteMode) hClose io_action \begin{code} outputC :: DynFlags -> FilePath - -> [RawCmmGroup] + -> Stream IO RawCmmGroup () -> [PackageId] -> IO () -outputC dflags filenm flat_absC packages +outputC dflags filenm cmm_stream packages = do + -- ToDo: make the C backend consume the C-- incrementally, by + -- pushing the cmm_stream inside (c.f. nativeCodeGen) + rawcmms <- Stream.collect cmm_stream + -- figure out which header files to #include in the generated .hc file: -- -- * extra_includes from packages @@ -117,7 +128,7 @@ outputC dflags filenm flat_absC packages doOutput filenm $ \ h -> do hPutStr h ("/* GHC_PACKAGES " ++ unwords pkg_names ++ "\n*/\n") hPutStr h cc_injects - writeCs dflags h flat_absC + writeCs dflags h rawcmms \end{code} @@ -128,14 +139,14 @@ outputC dflags filenm flat_absC packages %************************************************************************ \begin{code} -outputAsm :: DynFlags -> FilePath -> [RawCmmGroup] -> IO () -outputAsm dflags filenm flat_absC +outputAsm :: DynFlags -> FilePath -> Stream IO RawCmmGroup () -> IO () +outputAsm dflags filenm cmm_stream | cGhcWithNativeCodeGen == "YES" = do ncg_uniqs <- mkSplitUniqSupply 'n' {-# SCC "OutputAsm" #-} doOutput filenm $ \f -> {-# SCC "NativeCodeGen" #-} - nativeCodeGen dflags f ncg_uniqs flat_absC + nativeCodeGen dflags f ncg_uniqs cmm_stream | otherwise = panic "This compiler was built without a native code generator" @@ -149,12 +160,17 @@ outputAsm dflags filenm flat_absC %************************************************************************ \begin{code} -outputLlvm :: DynFlags -> FilePath -> [RawCmmGroup] -> IO () -outputLlvm dflags filenm flat_absC +outputLlvm :: DynFlags -> FilePath -> Stream IO RawCmmGroup () -> IO () +outputLlvm dflags filenm cmm_stream = do ncg_uniqs <- mkSplitUniqSupply 'n' + + -- ToDo: make the LLVM backend consume the C-- incrementally, + -- by pushing the cmm_stream inside (c.f. nativeCodeGen) + rawcmms <- Stream.collect cmm_stream + {-# SCC "llvm_output" #-} doOutput filenm $ \f -> {-# SCC "llvm_CodeGen" #-} - llvmCodeGen dflags f ncg_uniqs flat_absC + llvmCodeGen dflags f ncg_uniqs rawcmms \end{code} @@ -240,4 +256,3 @@ outputForeignStubs_help fname doc_str header footer = do writeFile fname (header ++ doc_str ++ '\n':footer ++ "\n") return True \end{code} - diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index 53aa39f04e..60b6e82bb7 100644 --- a/compiler/main/DynFlags.hs +++ b/compiler/main/DynFlags.hs @@ -164,9 +164,9 @@ data DynFlag = Opt_D_dump_cmm | Opt_D_dump_raw_cmm | Opt_D_dump_cmmz - | Opt_D_dump_cmmz_pretty -- All of the cmmz subflags (there are a lot!) Automatically -- enabled if you run -ddump-cmmz + | Opt_D_dump_cmmz_cfg | Opt_D_dump_cmmz_cbe | Opt_D_dump_cmmz_proc | Opt_D_dump_cmmz_spills @@ -1675,7 +1675,7 @@ dynamic_flags = [ , Flag "ddump-cmm" (setDumpFlag Opt_D_dump_cmm) , Flag "ddump-raw-cmm" (setDumpFlag Opt_D_dump_raw_cmm) , Flag "ddump-cmmz" (setDumpFlag Opt_D_dump_cmmz) - , Flag "ddump-cmmz-pretty" (setDumpFlag Opt_D_dump_cmmz_pretty) + , Flag "ddump-cmmz-cfg" (setDumpFlag Opt_D_dump_cmmz_cbe) , Flag "ddump-cmmz-cbe" (setDumpFlag Opt_D_dump_cmmz_cbe) , Flag "ddump-cmmz-spills" (setDumpFlag Opt_D_dump_cmmz_spills) , Flag "ddump-cmmz-proc" (setDumpFlag Opt_D_dump_cmmz_proc) diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs index 562332d52a..0b03e83029 100644 --- a/compiler/main/HscMain.hs +++ b/compiler/main/HscMain.hs @@ -119,13 +119,12 @@ import TyCon import Name import SimplStg ( stg2stg ) import CodeGen ( codeGen ) -import OldCmm as Old ( CmmGroup ) -import PprCmm ( pprCmms ) +import qualified OldCmm as Old +import qualified Cmm as New import CmmParse ( parseCmmFile ) import CmmBuildInfoTables import CmmPipeline import CmmInfo -import OptimizationFuel ( initOptFuelState ) import CmmCvt import CodeOutput import NameEnv ( emptyNameEnv ) @@ -147,6 +146,9 @@ import UniqFM ( emptyUFM ) import UniqSupply ( initUs_ ) import Bag import Exception +import qualified Stream +import Stream (Stream) + import Util import Data.List @@ -172,7 +174,6 @@ newHscEnv dflags = do nc_var <- newIORef (initNameCache us knownKeyNames) fc_var <- newIORef emptyUFM mlc_var <- newIORef emptyModuleEnv - optFuel <- initOptFuelState return HscEnv { hsc_dflags = dflags, hsc_targets = [], hsc_mod_graph = [], @@ -182,7 +183,6 @@ newHscEnv dflags = do hsc_NC = nc_var, hsc_FC = fc_var, hsc_MLC = mlc_var, - hsc_OptFuel = optFuel, hsc_type_env_var = Nothing } @@ -1276,20 +1276,27 @@ hscGenHardCode cgguts mod_summary = do cost_centre_info stg_binds hpc_info else {-# SCC "CodeGen" #-} - codeGen dflags this_mod data_tycons - cost_centre_info - stg_binds hpc_info + return (codeGen dflags this_mod data_tycons + cost_centre_info + stg_binds hpc_info) + ------------------ Code output ----------------------- - rawcmms <- {-# SCC "cmmToRawCmm" #-} + rawcmms0 <- {-# SCC "cmmToRawCmm" #-} cmmToRawCmm platform cmms - dumpIfSet_dyn dflags Opt_D_dump_raw_cmm "Raw Cmm" (ppr rawcmms) + + let dump a = do dumpIfSet_dyn dflags Opt_D_dump_raw_cmm "Raw Cmm" + (ppr a) + return a + rawcmms1 = Stream.mapM dump rawcmms0 + (_stub_h_exists, stub_c_exists) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod location foreign_stubs - dependencies rawcmms + dependencies rawcmms1 return stub_c_exists + hscInteractive :: (ModIface, ModDetails, CgGuts) -> ModSummary -> Hsc (InteractiveStatus, ModIface, ModDetails) @@ -1335,7 +1342,7 @@ hscCompileCmmFile hsc_env filename = runHsc hsc_env $ do let dflags = hsc_dflags hsc_env cmm <- ioMsgMaybe $ parseCmmFile dflags filename liftIO $ do - rawCmms <- cmmToRawCmm (targetPlatform dflags) [cmm] + rawCmms <- cmmToRawCmm (targetPlatform dflags) (Stream.yield cmm) _ <- codeOutput dflags no_mod no_loc NoStubs [] rawCmms return () where @@ -1350,24 +1357,52 @@ tryNewCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [(StgBinding,[(Id,[Id])])] -> HpcInfo - -> IO [Old.CmmGroup] + -> IO (Stream IO Old.CmmGroup ()) + -- Note we produce a 'Stream' of CmmGroups, so that the + -- backend can be run incrementally. Otherwise it generates all + -- the C-- up front, which has a significant space cost. tryNewCodeGen hsc_env this_mod data_tycons cost_centre_info stg_binds hpc_info = do let dflags = hsc_dflags hsc_env - prog <- StgCmm.codeGen dflags this_mod data_tycons + + let cmm_stream :: Stream IO New.CmmGroup () + cmm_stream = {-# SCC "StgCmm" #-} + StgCmm.codeGen dflags this_mod data_tycons cost_centre_info stg_binds hpc_info - dumpIfSet_dyn dflags Opt_D_dump_cmmz "Cmm produced by new codegen" - (pprCmms prog) + + -- codegen consumes a stream of CmmGroup, and produces a new + -- stream of CmmGroup (not necessarily synchronised: one + -- CmmGroup on input may produce many CmmGroups on output due + -- to proc-point splitting). + + let dump1 a = do dumpIfSet_dyn dflags Opt_D_dump_cmmz + "Cmm produced by new codegen" (ppr a) + return a + + ppr_stream1 = Stream.mapM dump1 cmm_stream -- We are building a single SRT for the entire module, so -- we must thread it through all the procedures as we cps-convert them. us <- mkSplitUniqSupply 'S' let initTopSRT = initUs_ us emptySRT - (topSRT, prog) <- foldM (cmmPipeline hsc_env) (initTopSRT, []) prog - let prog' = map cmmOfZgraph (srtToData topSRT : prog) - dumpIfSet_dyn dflags Opt_D_dump_cmmz "Output Cmm" (ppr prog') - return prog' + let run_pipeline topSRT cmmgroup = do + (topSRT, cmmgroup) <- cmmPipeline hsc_env topSRT cmmgroup + return (topSRT,cmmOfZgraph cmmgroup) + + let pipeline_stream = {-# SCC "cmmPipeline" #-} do + topSRT <- Stream.mapAccumL run_pipeline initTopSRT ppr_stream1 + Stream.yield (cmmOfZgraph (srtToData topSRT)) + + let + dump2 a = do dumpIfSet_dyn dflags Opt_D_dump_cmmz "Output Cmm" $ ppr a + return a + + ppr_stream2 = Stream.mapM dump2 pipeline_stream + + return ppr_stream2 + + myCoreToStg :: DynFlags -> Module -> CoreProgram -> IO ( [(StgBinding,[(Id,[Id])])] -- output program diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs index 156f081d3e..adaa9a3171 100644 --- a/compiler/main/HscTypes.lhs +++ b/compiler/main/HscTypes.lhs @@ -142,7 +142,6 @@ import Packages hiding ( Version(..) ) import DynFlags import DriverPhases import BasicTypes -import OptimizationFuel ( OptFuelState ) import IfaceSyn import CoreSyn ( CoreRule, CoreVect ) import Maybes @@ -318,11 +317,6 @@ data HscEnv -- ^ This caches the location of modules, so we don't have to -- search the filesystem multiple times. See also 'hsc_FC'. - hsc_OptFuel :: OptFuelState, - -- ^ Settings to control the use of \"optimization fuel\": - -- by limiting the number of transformations, - -- we can use binary search to help find compiler bugs. - hsc_type_env_var :: Maybe (Module, IORef TypeEnv) -- ^ Used for one-shot compilation only, to initialise -- the 'IfGblEnv'. See 'TcRnTypes.tcg_type_env_var' for |