From eb8e692cab7970c495681e14721d05ecadd21581 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Mon, 26 Sep 2016 12:07:05 +0100 Subject: An overhaul of the SRT representation Summary: - Previously we would hvae a single big table of pointers per module, with a set of bitmaps to reference entries within it. The new representation is identical to a static constructor, which is much simpler for the GC to traverse, and we get to remove the complicated bitmap-traversal code from the GC. - Rewrite all the code to generate SRTs in CmmBuildInfoTables, and document it much better (see Note [SRTs]). This has been something I've wanted to do since we moved to the new code generator, I finally had the opportunity to finish it while on a transatlantic flight recently :) There are a series of 4 diffs: 1. D4632 (this one), which does the bulk of the changes 2. D4633 which adds support for smaller `CmmLabelDiffOff` constants 3. D4634 which takes advantage of D4632 and D4633 to save a word in info tables that have an SRT on x86_64. This is where most of the binary size improvement comes from. 4. D4637 which makes a further optimisation to merge some SRTs with static FUN closures. This adds some complexity and the benefits are fairly modest, so it's not clear yet whether we should do this. Results (after (3), on x86_64) - GHC itself (staticaly linked) is 5.2% smaller - -1.7% binary sizes in nofib, -2.9% module sizes. Full nofib results: P176 - I measured the overhead of traversing all the static objects in a major GC in GHC itself by doing `replicateM_ 1000 performGC` as the first thing in `Main.main`. The new version was 5-10% faster, but the results did vary quite a bit. - I'm not sure if there's a compile-time difference, the results are too unreliable. Test Plan: validate Reviewers: bgamari, michalt, niteria, simonpj, erikd, osa1 Subscribers: thomie, carter Differential Revision: https://phabricator.haskell.org/D4632 --- compiler/main/HscMain.hs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'compiler/main/HscMain.hs') diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs index 223886a1fc..9012025ece 100644 --- a/compiler/main/HscMain.hs +++ b/compiler/main/HscMain.hs @@ -1397,15 +1397,13 @@ hscCompileCmmFile hsc_env filename output_filename = runHsc hsc_env $ do let dflags = hsc_dflags hsc_env cmm <- ioMsgMaybe $ parseCmmFile dflags filename liftIO $ do - us <- mkSplitUniqSupply 'S' - let initTopSRT = initUs_ us emptySRT dumpIfSet_dyn dflags Opt_D_dump_cmm_verbose "Parsed Cmm" (ppr cmm) - (_, cmmgroup) <- cmmPipeline hsc_env initTopSRT cmm - rawCmms <- cmmToRawCmm dflags (Stream.yield cmmgroup) let -- Make up a module name to give the NCG. We can't pass bottom here -- lest we reproduce #11784. mod_name = mkModuleName $ "Cmm$" ++ FilePath.takeFileName filename cmm_mod = mkModule (thisPackage dflags) mod_name + (_, cmmgroup) <- cmmPipeline hsc_env (emptySRT cmm_mod) cmm + rawCmms <- cmmToRawCmm dflags (Stream.yield cmmgroup) _ <- codeOutput dflags cmm_mod output_filename no_loc NoStubs [] [] rawCmms return () @@ -1456,21 +1454,17 @@ doCodeGen hsc_env this_mod data_tycons osSubsectionsViaSymbols (platformOS (targetPlatform dflags)) = {-# SCC "cmmPipeline" #-} let run_pipeline us cmmgroup = do - let (topSRT', us') = initUs us emptySRT - (topSRT, cmmgroup) <- cmmPipeline hsc_env topSRT' cmmgroup - let srt | isEmptySRT topSRT = [] - | otherwise = srtToData topSRT - return (us', srt ++ cmmgroup) + (_topSRT, cmmgroup) <- + cmmPipeline hsc_env (emptySRT this_mod) cmmgroup + return (us, cmmgroup) in do _ <- Stream.mapAccumL run_pipeline us ppr_stream1 return () | otherwise = {-# SCC "cmmPipeline" #-} - let initTopSRT = initUs_ us emptySRT - run_pipeline = cmmPipeline hsc_env - in do topSRT <- Stream.mapAccumL run_pipeline initTopSRT ppr_stream1 - Stream.yield (srtToData topSRT) + let run_pipeline = cmmPipeline hsc_env + in void $ Stream.mapAccumL run_pipeline (emptySRT this_mod) ppr_stream1 let dump2 a = do dumpIfSet_dyn dflags Opt_D_dump_cmm -- cgit v1.2.1