summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/LateCC.hs
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2021-12-23 15:46:18 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-02-10 04:35:35 -0500
commit48f257151f30f6b4d2f8b1a6ea4185ccd00ebd95 (patch)
treec440e41d67f5c4d2f62deaed0b9dbb6991e06338 /compiler/GHC/Core/LateCC.hs
parentac2d18a7353cd3ac1ba4b5993f2776fe0c5eedc9 (diff)
downloadhaskell-48f257151f30f6b4d2f8b1a6ea4185ccd00ebd95.tar.gz
Add late cost centre support
This allows cost centres to be inserted after the core optimization pipeline has run.
Diffstat (limited to 'compiler/GHC/Core/LateCC.hs')
-rw-r--r--compiler/GHC/Core/LateCC.hs82
1 files changed, 82 insertions, 0 deletions
diff --git a/compiler/GHC/Core/LateCC.hs b/compiler/GHC/Core/LateCC.hs
new file mode 100644
index 0000000000..d7a3b0cd8d
--- /dev/null
+++ b/compiler/GHC/Core/LateCC.hs
@@ -0,0 +1,82 @@
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE TupleSections #-}
+
+-- | Adds cost-centers after the core piple has run.
+module GHC.Core.LateCC
+ ( addLateCostCentres
+ ) where
+
+import Control.Applicative
+import GHC.Utils.Monad.State.Strict
+import Control.Monad
+
+import GHC.Prelude
+import GHC.Driver.Session
+import GHC.Types.CostCentre
+import GHC.Types.CostCentre.State
+import GHC.Types.Name hiding (varName)
+import GHC.Types.Tickish
+import GHC.Unit.Module.ModGuts
+import GHC.Types.Var
+import GHC.Unit.Types
+import GHC.Data.FastString
+import GHC.Core
+import GHC.Core.Opt.Monad
+import GHC.Types.Id
+import GHC.Core.Utils (mkTick)
+
+addLateCostCentres :: ModGuts -> CoreM ModGuts
+addLateCostCentres guts = do
+ dflags <- getDynFlags
+ let env :: Env
+ env = Env
+ { thisModule = mg_module guts
+ , ccState = newCostCentreState
+ , dflags = dflags
+ }
+ let guts' = guts { mg_binds = doCoreProgram env (mg_binds guts)
+ }
+ return guts'
+
+doCoreProgram :: Env -> CoreProgram -> CoreProgram
+doCoreProgram env binds = flip evalState newCostCentreState $ do
+ mapM (doBind env) binds
+
+doBind :: Env -> CoreBind -> M CoreBind
+doBind env (NonRec b rhs) = NonRec b <$> doBndr env b rhs
+doBind env (Rec bs) = Rec <$> mapM doPair bs
+ where
+ doPair :: ((Id, CoreExpr) -> M (Id, CoreExpr))
+ doPair (b,rhs) = (b,) <$> doBndr env b rhs
+
+doBndr :: Env -> Id -> CoreExpr -> M CoreExpr
+doBndr env bndr rhs = do
+ let name = idName bndr
+ name_loc = nameSrcSpan name
+ cc_name = getOccFS name
+ count = gopt Opt_ProfCountEntries (dflags env)
+ cc_flavour <- getCCExprFlavour cc_name
+ let cc_mod = thisModule env
+ bndrCC = NormalCC cc_flavour cc_name cc_mod name_loc
+ note = ProfNote bndrCC count True
+ return $ mkTick note rhs
+
+type M = State CostCentreState
+
+getCCExprFlavour :: FastString -> M CCFlavour
+getCCExprFlavour name = ExprCC <$> getCCIndex' name
+
+getCCIndex' :: FastString -> M CostCentreIndex
+getCCIndex' name = state (getCCIndex name)
+
+data Env = Env
+ { thisModule :: Module
+ , dflags :: DynFlags
+ , ccState :: CostCentreState
+ }
+