[Git][ghc/ghc][master] 2 commits: Refactor estimation of stack info table provenance

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Thu Aug 24 20:19:28 UTC 2023



Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC


Commits:
d99c816f by Finley McIlwaine at 2023-08-24T16:18:55-04:00
Refactor estimation of stack info table provenance

This commit greatly refactors the way we compute estimated provenance for stack
info tables. Previously, this process was done using an entirely separate traversal
of the whole Cmm code stream to build the map from info tables to source locations.
The separate traversal is now fused with the Cmm code generation pipeline in
GHC.Driver.Main.

This results in very significant code generation speed ups when -finfo-table-map is
enabled. In testing, this patch reduces code generation times by almost 30% with
-finfo-table-map and -O0, and 60% with -finfo-table-map and -O1 or -O2 .

Fixes #23103

- - - - -
d3e0124c by Finley McIlwaine at 2023-08-24T16:18:55-04:00
Add a test checking overhead of -finfo-table-map

We want to make sure we don't end up with poor codegen performance resulting from
-finfo-table-map again as in #23103. This test adds a performance test tracking
total allocations while compiling ExactPrint with -finfo-table-map.

- - - - -


5 changed files:

- compiler/GHC/Driver/GenerateCgIPEStub.hs
- compiler/GHC/Driver/Main.hs
- + testsuite/tests/profiling/perf/Makefile
- + testsuite/tests/profiling/perf/T23103/all.T
- + testsuite/tests/profiling/perf/T23103/info_table_map_perf.stderr


Changes:

=====================================
compiler/GHC/Driver/GenerateCgIPEStub.hs
=====================================
@@ -1,21 +1,19 @@
 {-# LANGUAGE GADTs         #-}
 {-# LANGUAGE TupleSections #-}
 
-module GHC.Driver.GenerateCgIPEStub (generateCgIPEStub) where
+module GHC.Driver.GenerateCgIPEStub (generateCgIPEStub, lookupEstimatedTicks) where
 
 import Data.Map.Strict (Map)
 import qualified Data.Map.Strict as Map
-import Data.Maybe (mapMaybe, listToMaybe)
 import Data.Semigroup ((<>))
 import GHC.Cmm
-import GHC.Cmm.CLabel (CLabel)
-import GHC.Cmm.Dataflow (Block, C, O)
+import GHC.Cmm.CLabel (CLabel, mkAsmTempLabel)
+import GHC.Cmm.Dataflow (O)
 import GHC.Cmm.Dataflow.Block (blockSplit, blockToList)
 import GHC.Cmm.Dataflow.Collections
-import GHC.Cmm.Dataflow.Label (Label, LabelMap)
+import GHC.Cmm.Dataflow.Label (Label)
 import GHC.Cmm.Info.Build (emptySRT)
 import GHC.Cmm.Pipeline (cmmPipeline)
-import GHC.Data.Maybe (firstJusts)
 import GHC.Data.Stream (Stream, liftIO)
 import qualified GHC.Data.Stream as Stream
 import GHC.Driver.Env (hsc_dflags, hsc_logger)
@@ -26,7 +24,7 @@ import GHC.Driver.Config.StgToCmm
 import GHC.Driver.Config.Cmm
 import GHC.Prelude
 import GHC.Runtime.Heap.Layout (isStackRep)
-import GHC.Settings (Platform, platformTablesNextToCode)
+import GHC.Settings (platformTablesNextToCode)
 import GHC.StgToCmm.Monad (getCmm, initC, runC, initFCodeState)
 import GHC.StgToCmm.Prof (initInfoTableProv)
 import GHC.StgToCmm.Types (CmmCgInfos (..), ModuleLFInfos)
@@ -58,10 +56,16 @@ by `generateCgIPEStub`.
 
 This leads to the question: How to figure out the source location of a return frame?
 
-While the lookup algorithms when tables-next-to-code is on/off differ in details, they have in
-common that we want to lookup the `CmmNode.CmmTick` (containing a `SourceNote`) that is nearest
-(before) the usage of the return frame's label. (Which label and label type is used differs between
-these two use cases.)
+The algorithm for determining source locations for stack info tables is implemented in
+`lookupEstimatedTicks` as two passes over every 'CmmGroupSRTs'. The first pass generates estimated
+source locations for any labels potentially corresponding to stack info tables in the Cmm code. The
+second pass walks over the Cmm decls and creates an entry in the IPE map for every info table,
+looking up source locations for stack info tables in the map generated during the first pass.
+
+The rest of this note will document exactly how the first pass generates the map from labels to
+estimated source positions. The algorithms are different depending on whether tables-next-to-code
+is on or off. Both algorithms have in common that we are looking for a `CmmNode.CmmTick`
+(containing a `SourceNote`) that is near what we estimate to be the label of a return stack frame.
 
 With tables-next-to-code
 ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -113,15 +117,15 @@ for a detailed explanation.
 Here we use the fact, that calls (represented by `CmmNode.CmmCall`) are always closed on exit
 (`CmmNode O C`, `O` means open, `C` closed). In other words, they are always at the end of a block.
 
-So, given a stack represented info table (likely representing a return frame, but this isn't completely
-sure as there are e.g. update frames, too) with it's label (`c18g` in the example above) and a `CmmGraph`:
-  - Look at the end of every block, if it's a `CmmNode.CmmCall` returning to the continuation with the
-    label of the return frame.
-  - If there's such a call, lookup the nearest `CmmNode.CmmTick` by traversing the middle part of the block
-    backwards (from end to beginning).
-  - Take the first `CmmNode.CmmTick` that contains a `Tickish.SourceNote` and return it's payload as
-    `IpeSourceLocation`. (There are other `Tickish` constructors like `ProfNote` or `HpcTick`, these are
-    ignored.)
+So, given a `CmmGraph`:
+  - Look at the end of every block: If it is a `CmmNode.CmmCall` returning to some label, lookup
+    the nearest `CmmNode.CmmTick` by traversing the middle part of the block backwards (from end to
+    beginning).
+  - Take the first `CmmNode.CmmTick` that contains a `Tickish.SourceNote` and map the label we
+    found to it's payload as an `IpeSourceLocation`. (There are other `Tickish` constructors like
+    `ProfNote` or `HpcTick`, these are ignored.)
+
+See `labelsToSourcesWithTNTC` for the implementation of this algorithm.
 
 Without tables-next-to-code
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -176,16 +180,27 @@ In this example we have to lookup `//tick src<Main.hs:20:9-13>` for the return f
 Notice, that this cannot be done with the `Label` `c18M`, but with the `CLabel` `block_c18M_info`
 (`label: block_c18M_info` is actually a `CLabel`).
 
-The find the tick:
-  - Every `Block` is checked from top (first) to bottom (last) node for an assignment like
-   `I64[Sp - 24] = block_c18M_info;`. The lefthand side is actually ignored.
-  - If such an assignment is found the search is over, because the payload (content of
-    `Tickish.SourceNote`, represented as `IpeSourceLocation`) of last visited tick is always
-    remembered in a `Maybe`.
+Given a `CmmGraph`:
+  - Check every `CmmBlock` from top (first) to bottom (last).
+  - If a `CmmTick` holding a `SourceNote` is found, remember the source location in the tick.
+  - If an assignment of the form `... = block_c18M_info;` (a `CmmStore` whose RHS is a
+    `CmmLit (CmmLabel l)`) is found, map that label to the most recently visited source note's
+    location.
+
+See `labelsToSourcesSansTNTC` for the implementation of this algorithm.
 -}
 
-generateCgIPEStub :: HscEnv -> Module -> InfoTableProvMap -> Stream IO CmmGroupSRTs (NonCaffySet, ModuleLFInfos) -> Stream IO CmmGroupSRTs CmmCgInfos
-generateCgIPEStub hsc_env this_mod denv s = do
+generateCgIPEStub
+  :: HscEnv
+  -> Module
+  -> InfoTableProvMap
+  -> ( NonCaffySet
+     , ModuleLFInfos
+     , Map CmmInfoTable (Maybe IpeSourceLocation)
+     , IPEStats
+     )
+  -> Stream IO CmmGroupSRTs CmmCgInfos
+generateCgIPEStub hsc_env this_mod denv (nonCaffySet, moduleLFInfos, infoTablesWithTickishes, initStats) = do
   let dflags   = hsc_dflags hsc_env
       platform = targetPlatform dflags
       logger   = hsc_logger hsc_env
@@ -193,24 +208,6 @@ generateCgIPEStub hsc_env this_mod denv s = do
       cmm_cfg  = initCmmConfig dflags
   cgState <- liftIO initC
 
-  -- Collect info tables from the Cmm if -finfo-table-map is enabled. If
-  -- -finfo-table-map is not enabled, infoTablesWithTickishes will be empty. If
-  -- -finfo-table-map-with-stack is enabled, any STACK info tables will be
-  -- mapped to their source locations (See Note [Stacktraces from Info Table
-  -- Provenance Entries (IPE based stack unwinding)]). If
-  -- -finfo-table-map-with-stack is not enabled, we need to track how many STACK
-  -- info tables we have skipped (in case -dipe-stats is enabled). Note that
-  -- this is the only stats tracking we do at this stage, so initStats here
-  -- should only ever contain stats about skipped STACK info tables.
-  let
-    collectFun =
-      if gopt Opt_InfoTableMap dflags then
-        collect platform
-      else
-        collectNothing platform
-
-  ((infoTablesWithTickishes, initStats), (nonCaffySet, moduleLFInfos)) <- Stream.mapAccumL_ collectFun (mempty, mempty) s
-
   -- Yield Cmm for Info Table Provenance Entries (IPEs)
   let denv' = denv {provInfoTables = Map.mapKeys cit_lbl infoTablesWithTickishes}
       ((mIpeStub, ipeCmmGroup), _) = runC (initStgToCmmConfig dflags this_mod) fstate cgState $ getCmm (initInfoTableProv initStats (Map.keys infoTablesWithTickishes) denv')
@@ -232,102 +229,148 @@ generateCgIPEStub hsc_env this_mod denv s = do
       Nothing -> return mempty
 
   return CmmCgInfos {cgNonCafs = nonCaffySet, cgLFInfos = moduleLFInfos, cgIPEStub = ipeStub}
-  where
-    -- These functions are applied to the elements of the stream of
-    -- CmmGroupSRTs. 'collect' populates a map from info table to potential
-    -- source location, and is used when -finfo-table-map is supplied.
-    -- 'collectNothing' does nothing and just throws out the stream elements.
-    collect, collectNothing
-      :: Platform
-      -> (Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
-      -> CmmGroupSRTs
-      -> IO ((Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats), CmmGroupSRTs)
-    collect platform (!acc, !stats) cmmGroupSRTs = do
-      let
-        blocks = concatMap toBlockList (graphs cmmGroupSRTs)
-        labelsToInfoTables = collectInfoTables cmmGroupSRTs
-        (tablesToTickishes, stats') = mapFoldlWithKey (lookupEstimatedTick platform blocks) (acc, stats) labelsToInfoTables
-      return ((tablesToTickishes, stats'), cmmGroupSRTs)
-    collectNothing _ _ cmmGroupSRTs = pure ((Map.empty, mempty), cmmGroupSRTs)
-
-    collectInfoTables :: CmmGroupSRTs -> LabelMap CmmInfoTable
-    collectInfoTables cmmGroup = foldl' extractInfoTables mapEmpty cmmGroup
-
-    extractInfoTables :: LabelMap CmmInfoTable -> GenCmmDecl RawCmmStatics CmmTopInfo CmmGraph -> LabelMap CmmInfoTable
-    extractInfoTables acc (CmmProc h _ _ _) = acc `mapUnion` info_tbls h
-    extractInfoTables acc _ = acc
-
-    lookupEstimatedTick
-      :: Platform
-      -> [CmmBlock]
-      -> (Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
-      -> Label
-      -> CmmInfoTable
-      -> (Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
-    lookupEstimatedTick platform blocks (!acc, !stats) infoTableLabel infoTable = do
-      -- All return frame info tables are stack represented, though not all stack represented info
-      -- tables have to be return frames.
-      if (isStackRep . cit_rep) infoTable then
-        if gopt Opt_InfoTableMapWithStack (hsc_dflags hsc_env) then
-          -- This is a STACK info table and we DO want to put it in the info
-          -- table map
-          let
-            findFun =
-              if platformTablesNextToCode platform
-                then findCmmTickishWithTNTC infoTableLabel
-                else findCmmTickishSansTNTC (cit_lbl infoTable)
-            -- Avoid retaining the blocks
-            !srcloc =
-              case firstJusts $ map findFun blocks of
-                Just !srcloc -> Just srcloc
-                Nothing -> Nothing
-          in
-            (Map.insert infoTable srcloc acc, stats)
-        else
-          -- This is a STACK info table but we DO NOT want to put it in the info
-          -- table map (-fno-info-table-map-with-stack was given), track it as
-          -- skipped
-            (acc, stats <> skippedIpeStats)
 
+-- | Given:
+--   * an initial mapping from info tables to possible source locations,
+--   * initial 'IPEStats',
+--   * a 'CmmGroupSRTs',
+--
+-- map every info table listed in the 'CmmProc's of the group to their possible
+-- source locations and update 'IPEStats' for skipped stack info tables (in case
+-- both -finfo-table-map and -fno-info-table-map-with-stack were given). See:
+-- Note [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)]
+--
+-- Note: While it would be cleaner if we could keep the recursion and
+-- accumulation internal to this function, this cannot be done without
+-- separately traversing stream of 'CmmGroupSRTs' in 'GHC.Driver.Main'. The
+-- initial implementation of this logic did such a thing, and code generation
+-- performance suffered considerably as a result (see #23103).
+lookupEstimatedTicks
+  :: HscEnv
+  -> Map CmmInfoTable (Maybe IpeSourceLocation)
+  -> IPEStats
+  -> CmmGroupSRTs
+  -> IO (Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
+lookupEstimatedTicks hsc_env ipes stats cmm_group_srts =
+    -- Pass 2: Create an entry in the IPE map for every info table listed in
+    -- this CmmGroupSRTs. If the info table is a stack info table and
+    -- -finfo-table-map-with-stack is enabled, look up its estimated source
+    -- location in the map generate during Pass 1. If the info table is a stack
+    -- info table and -finfo-table-map-with-stack is not enabled, skip the table
+    -- and note it as skipped in the IPE stats. If the info table is not a stack
+    -- info table, insert into the IPE map with no source location information
+    -- (for now; see `convertInfoProvMap` in GHC.StgToCmm.Utils to see how source
+    -- locations for these tables get filled in)
+    pure $ foldl' collectInfoTables (ipes, stats) cmm_group_srts
+  where
+    dflags = hsc_dflags hsc_env
+    platform = targetPlatform dflags
+
+    -- Pass 1: Map every label meeting the conditions described in Note
+    -- [Stacktraces from Info Table Provenance Entries (IPE based stack
+    -- unwinding)] to the estimated source location (also as described in the
+    -- aformentioned note)
+    --
+    -- Note: It's important that this remains a thunk so we do not compute this
+    -- map if -fno-info-table-with-stack is given
+    labelsToSources :: Map CLabel IpeSourceLocation
+    labelsToSources =
+      if platformTablesNextToCode platform then
+        foldl' labelsToSourcesWithTNTC Map.empty cmm_group_srts
       else
-        -- This is not a STACK info table, so put it in the map with no source
-        -- location (for now)
-        (Map.insert infoTable Nothing acc, stats)
+        foldl' labelsToSourcesSansTNTC Map.empty cmm_group_srts
 
-    graphs :: CmmGroupSRTs -> [CmmGraph]
-    graphs = foldl' go []
+    collectInfoTables
+      :: (Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
+      -> GenCmmDecl RawCmmStatics CmmTopInfo CmmGraph
+      -> (Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
+    collectInfoTables (!acc, !stats) (CmmProc h _ _ _) =
+        mapFoldlWithKey go (acc, stats) (info_tbls h)
       where
-        go :: [CmmGraph] -> GenCmmDecl d h CmmGraph -> [CmmGraph]
-        go acc (CmmProc _ _ _ g) = g : acc
-        go acc _ = acc
-
-    findCmmTickishWithTNTC :: Label -> Block CmmNode C C -> Maybe IpeSourceLocation
-    findCmmTickishWithTNTC label block = do
-      let (_, middleBlock, endBlock) = blockSplit block
-
-      isCallWithReturnFrameLabel endBlock label
-      lastTickInBlock middleBlock
+        go :: (Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
+           -> Label
+           -> CmmInfoTable
+           -> (Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
+        go (!acc, !stats) lbl' tbl =
+          let
+            lbl =
+              if platformTablesNextToCode platform then
+                -- TNTC case, the mapped CLabel will be the result of
+                -- mkAsmTempLabel on the info table label
+                mkAsmTempLabel lbl'
+              else
+                -- Non-TNTC case, the mapped CLabel will be the CLabel of the
+                -- info table itself
+                cit_lbl tbl
+          in
+            if (isStackRep . cit_rep) tbl then
+              if gopt Opt_InfoTableMapWithStack dflags then
+                -- This is a stack info table and we DO want to put it in the
+                -- info table map
+                (Map.insert tbl (Map.lookup lbl labelsToSources) acc, stats)
+              else
+                -- This is a stack info table but we DO NOT want to put it in
+                -- the info table map (-fno-info-table-map-with-stack was
+                -- given), track it as skipped
+                (acc, stats <> skippedIpeStats)
+            else
+              -- This is not a stack info table, so put it in the map with no
+              -- source location (for now)
+              (Map.insert tbl Nothing acc, stats)
+    collectInfoTables (!acc, !stats) _ = (acc, stats)
+
+-- | See Note [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)]
+labelsToSourcesWithTNTC
+  :: Map CLabel IpeSourceLocation
+  -> GenCmmDecl RawCmmStatics CmmTopInfo CmmGraph
+  -> Map CLabel IpeSourceLocation
+labelsToSourcesWithTNTC acc (CmmProc _ _ _ cmm_graph) =
+    foldl' go acc (toBlockList cmm_graph)
+  where
+    go :: Map CLabel IpeSourceLocation -> CmmBlock -> Map CLabel IpeSourceLocation
+    go acc block =
+        case (,) <$> returnFrameLabel <*> lastTickInBlock of
+          Just (clabel, src_loc) -> Map.insert clabel src_loc acc
+          Nothing -> acc
       where
-        isCallWithReturnFrameLabel :: CmmNode O C -> Label -> Maybe ()
-        isCallWithReturnFrameLabel (CmmCall _ (Just l) _ _ _ _) clabel | l == clabel = Just ()
-        isCallWithReturnFrameLabel _ _ = Nothing
-
-        lastTickInBlock block =
-          listToMaybe $
-              mapMaybe maybeTick $ (reverse . blockToList) block
-
-        maybeTick :: CmmNode O O -> Maybe IpeSourceLocation
-        maybeTick (CmmTick (SourceNote span name)) = Just (span, name)
-        maybeTick _ = Nothing
-
-    findCmmTickishSansTNTC :: CLabel -> Block CmmNode C C -> Maybe IpeSourceLocation
-    findCmmTickishSansTNTC cLabel block = do
-      let (_, middleBlock, _) = blockSplit block
-      find cLabel (blockToList middleBlock) Nothing
+        (_, middleBlock, endBlock) = blockSplit block
+
+        returnFrameLabel :: Maybe CLabel
+        returnFrameLabel =
+          case endBlock of
+            (CmmCall _ (Just l) _ _ _ _) -> Just $ mkAsmTempLabel l
+            _ -> Nothing
+
+        lastTickInBlock = foldr maybeTick Nothing (blockToList middleBlock)
+
+        maybeTick :: CmmNode O O -> Maybe IpeSourceLocation -> Maybe IpeSourceLocation
+        maybeTick _ s@(Just _) = s
+        maybeTick (CmmTick (SourceNote span name)) Nothing = Just (span, name)
+        maybeTick _ _ = Nothing
+labelsToSourcesWithTNTC acc _ = acc
+
+-- | See Note [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)]
+labelsToSourcesSansTNTC
+  :: Map CLabel IpeSourceLocation
+  -> GenCmmDecl RawCmmStatics CmmTopInfo CmmGraph
+  -> Map CLabel IpeSourceLocation
+labelsToSourcesSansTNTC acc (CmmProc _ _ _ cmm_graph) =
+    foldl' go acc (toBlockList cmm_graph)
+  where
+    go :: Map CLabel IpeSourceLocation -> CmmBlock -> Map CLabel IpeSourceLocation
+    go acc block = fst $ foldl' collectLabels (acc, Nothing) (blockToList middleBlock)
       where
-        find :: CLabel -> [CmmNode O O] -> Maybe IpeSourceLocation -> Maybe IpeSourceLocation
-        find label (b : blocks) lastTick = case b of
-          (CmmStore _ (CmmLit (CmmLabel l)) _) -> if label == l then lastTick else find label blocks lastTick
-          (CmmTick (SourceNote span name)) -> find label blocks $ Just (span, name)
-          _ -> find label blocks lastTick
-        find _ [] _ = Nothing
+        (_, middleBlock, _) = blockSplit block
+
+        collectLabels
+          :: (Map CLabel IpeSourceLocation, Maybe IpeSourceLocation)
+          -> CmmNode O O
+          -> (Map CLabel IpeSourceLocation, Maybe IpeSourceLocation)
+        collectLabels (!acc, lastTick) b =
+          case (b, lastTick) of
+            (CmmStore _ (CmmLit (CmmLabel l)) _, Just src_loc) ->
+              (Map.insert l src_loc acc, Nothing)
+            (CmmTick (SourceNote span name), _) ->
+              (acc, Just (span, name))
+            _ -> (acc, lastTick)
+labelsToSourcesSansTNTC acc _ = acc
\ No newline at end of file


=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -136,7 +136,7 @@ import GHC.Driver.Config.StgToJS  (initStgToJSConfig)
 import GHC.Driver.Config.Diagnostic
 import GHC.Driver.Config.Tidy
 import GHC.Driver.Hooks
-import GHC.Driver.GenerateCgIPEStub (generateCgIPEStub)
+import GHC.Driver.GenerateCgIPEStub (generateCgIPEStub, lookupEstimatedTicks)
 
 import GHC.Runtime.Context
 import GHC.Runtime.Interpreter
@@ -245,7 +245,6 @@ import GHC.Types.Name
 import GHC.Types.Name.Cache ( initNameCache )
 import GHC.Types.Name.Reader
 import GHC.Types.Name.Ppr
-import GHC.Types.Name.Set (NonCaffySet)
 import GHC.Types.TyThing
 import GHC.Types.HpcInfo
 import GHC.Types.Unique.Supply (uniqFromTag)
@@ -280,11 +279,11 @@ import Control.Monad
 import Data.IORef
 import System.FilePath as FilePath
 import System.Directory
+import qualified Data.Map as M
+import Data.Map (Map)
 import qualified Data.Set as S
 import Data.Set (Set)
-import Data.Functor ((<&>))
 import Control.DeepSeq (force)
-import Data.Bifunctor (first)
 import Data.List.NonEmpty (NonEmpty ((:|)))
 import GHC.Unit.Module.WholeCoreBindings
 import GHC.Types.TypeEnv
@@ -295,8 +294,10 @@ import Data.Time
 import System.IO.Unsafe ( unsafeInterleaveIO )
 import GHC.Iface.Env ( trace_if )
 import GHC.Stg.InferTags.TagSig (seqTagSig)
+import GHC.StgToCmm.Utils (IPEStats)
 import GHC.Types.Unique.FM
 import GHC.Types.Unique.DFM
+import GHC.Cmm.Config (CmmConfig)
 
 
 {- **********************************************************************
@@ -2126,21 +2127,41 @@ doCodeGen hsc_env this_mod denv data_tycons
 
         cmm_config = initCmmConfig dflags
 
-        pipeline_stream :: Stream IO CmmGroupSRTs (NonCaffySet, ModuleLFInfos)
+        pipeline_stream :: Stream IO CmmGroupSRTs CmmCgInfos
         pipeline_stream = do
-          (non_cafs,  lf_infos) <-
+          ((mod_srt_info, ipes, ipe_stats), lf_infos) <-
             {-# SCC "cmmPipeline" #-}
-            Stream.mapAccumL_ (cmmPipeline logger cmm_config) (emptySRT this_mod) ppr_stream1
-              <&> first (srtMapNonCAFs . moduleSRTMap)
-
-          return (non_cafs, lf_infos)
+            Stream.mapAccumL_ (pipeline_action logger cmm_config) (emptySRT this_mod, M.empty, mempty) ppr_stream1
+          let nonCaffySet = srtMapNonCAFs (moduleSRTMap mod_srt_info)
+          cmmCgInfos <- generateCgIPEStub hsc_env this_mod denv (nonCaffySet, lf_infos, ipes, ipe_stats)
+          return cmmCgInfos
+
+        pipeline_action
+          :: Logger
+          -> CmmConfig
+          -> (ModuleSRTInfo, Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats)
+          -> CmmGroup
+          -> IO ((ModuleSRTInfo, Map CmmInfoTable (Maybe IpeSourceLocation), IPEStats), CmmGroupSRTs)
+        pipeline_action logger cmm_config (mod_srt_info, ipes, stats) cmm_group = do
+          (mod_srt_info', cmm_srts) <- cmmPipeline logger cmm_config mod_srt_info cmm_group
+
+          -- If -finfo-table-map is enabled, we precompute a map from info
+          -- tables to source locations. See Note [Mapping Info Tables to Source
+          -- Positions] in GHC.Stg.Debug.
+          (ipes', stats') <-
+            if (gopt Opt_InfoTableMap dflags) then
+              lookupEstimatedTicks hsc_env ipes stats cmm_srts
+            else
+              return (ipes, stats)
+
+          return ((mod_srt_info', ipes', stats'), cmm_srts)
 
         dump2 a = do
           unless (null a) $
             putDumpFileMaybe logger Opt_D_dump_cmm "Output Cmm" FormatCMM (pdoc platform a)
           return a
 
-    return $ Stream.mapM dump2 $ generateCgIPEStub hsc_env this_mod denv pipeline_stream
+    return $ Stream.mapM dump2 pipeline_stream
 
 myCoreToStg :: Logger -> DynFlags -> [Var]
             -> Bool


=====================================
testsuite/tests/profiling/perf/Makefile
=====================================
@@ -0,0 +1,3 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
\ No newline at end of file


=====================================
testsuite/tests/profiling/perf/T23103/all.T
=====================================
@@ -0,0 +1,18 @@
+test(
+    'info_table_map_perf',
+    [
+        collect_compiler_stats('bytes allocated',10),
+        extra_files(
+            [
+                '../../../../../utils/check-exact/ExactPrint.hs',
+                '../../../../../utils/check-exact/Lookup.hs',
+                '../../../../../utils/check-exact/Orphans.hs',
+                '../../../../../utils/check-exact/Types.hs',
+                '../../../../../utils/check-exact/Utils.hs',
+            ]
+        ),
+        js_skip
+    ],
+    multimod_compile,
+    ['ExactPrint.hs', '-package ghc -O -finfo-table-map']
+)


=====================================
testsuite/tests/profiling/perf/T23103/info_table_map_perf.stderr
=====================================
@@ -0,0 +1,5 @@
+[1 of 5] Compiling Orphans          ( Orphans.hs, Orphans.o )
+[2 of 5] Compiling Types            ( Types.hs, Types.o )
+[3 of 5] Compiling Lookup           ( Lookup.hs, Lookup.o )
+[4 of 5] Compiling Utils            ( Utils.hs, Utils.o )
+[5 of 5] Compiling ExactPrint       ( ExactPrint.hs, ExactPrint.o )



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1420b8cb8a7d6196eec80dc5293864c780379560...d3e0124c1157a4a423d86a1dc1d7e82c6d32ef06

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1420b8cb8a7d6196eec80dc5293864c780379560...d3e0124c1157a4a423d86a1dc1d7e82c6d32ef06
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230824/81dabc38/attachment-0001.html>


More information about the ghc-commits mailing list