{-# LANGUAGE DeriveDataTypeable #-}
module GHC.Types.CostCentre (
        -- All abstract except to friend: ParseIface.y
        CostCentre(..), CcName, CCFlavour,
        mkCafFlavour, mkExprCCFlavour, mkDeclCCFlavour, mkHpcCCFlavour,
        mkLateCCFlavour, mkCallerCCFlavour,

        pprCostCentre,
        CostCentreStack,
        pprCostCentreStack,
        CollectedCCs, emptyCollectedCCs, collectCC,
        currentCCS, dontCareCCS,
        isCurrentCCS,
        maybeSingletonCCS,

        mkUserCC, mkAutoCC, mkAllCafsCC,
        mkSingletonCCS,
        isCafCCS, isCafCC, isSccCountCC, sccAbleCC, ccFromThisModule,

        pprCostCentreCore,
        costCentreUserName, costCentreUserNameFS,
        costCentreSrcSpan,

        cmpCostCentre   -- used for removing dups in a list
    ) where

import GHC.Prelude

import GHC.Utils.Binary
import GHC.Types.Var
import GHC.Types.Name
import GHC.Unit.Module
import GHC.Types.Unique
import GHC.Utils.Outputable
import GHC.Types.SrcLoc
import GHC.Data.FastString
import GHC.Types.CostCentre.State

import Data.Data

-----------------------------------------------------------------------------
-- Cost Centres

-- | A Cost Centre is a single @{-# SCC #-}@ annotation.

data CostCentre
  = NormalCC {
                CostCentre -> CCFlavour
cc_flavour  :: CCFlavour,
                 -- ^ Two cost centres may have the same name and
                 -- module but different SrcSpans, so we need a way to
                 -- distinguish them easily and give them different
                 -- object-code labels.  So every CostCentre has an
                 -- associated flavour that indicates how it was
                 -- generated, and flavours that allow multiple instances
                 -- of the same name and module have a deterministic 0-based
                 -- index.
                CostCentre -> CcName
cc_name :: CcName,      -- ^ Name of the cost centre itself
                CostCentre -> Module
cc_mod  :: Module,      -- ^ Name of module defining this CC.
                CostCentre -> SrcSpan
cc_loc  :: SrcSpan
    }

  | AllCafsCC {
                cc_mod  :: Module,      -- Name of module defining this CC.
                cc_loc  :: SrcSpan
    }
  deriving Typeable CostCentre
Typeable CostCentre =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> CostCentre -> c CostCentre)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c CostCentre)
-> (CostCentre -> Constr)
-> (CostCentre -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c CostCentre))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c CostCentre))
-> ((forall b. Data b => b -> b) -> CostCentre -> CostCentre)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> CostCentre -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> CostCentre -> r)
-> (forall u. (forall d. Data d => d -> u) -> CostCentre -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> CostCentre -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> CostCentre -> m CostCentre)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CostCentre -> m CostCentre)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CostCentre -> m CostCentre)
-> Data CostCentre
CostCentre -> Constr
CostCentre -> DataType
(forall b. Data b => b -> b) -> CostCentre -> CostCentre
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> CostCentre -> u
forall u. (forall d. Data d => d -> u) -> CostCentre -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CostCentre -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CostCentre -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CostCentre -> m CostCentre
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CostCentre -> m CostCentre
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CostCentre
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CostCentre -> c CostCentre
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CostCentre)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CostCentre)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CostCentre -> c CostCentre
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CostCentre -> c CostCentre
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CostCentre
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CostCentre
$ctoConstr :: CostCentre -> Constr
toConstr :: CostCentre -> Constr
$cdataTypeOf :: CostCentre -> DataType
dataTypeOf :: CostCentre -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CostCentre)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CostCentre)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CostCentre)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CostCentre)
$cgmapT :: (forall b. Data b => b -> b) -> CostCentre -> CostCentre
gmapT :: (forall b. Data b => b -> b) -> CostCentre -> CostCentre
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CostCentre -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CostCentre -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CostCentre -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CostCentre -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> CostCentre -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> CostCentre -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CostCentre -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CostCentre -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CostCentre -> m CostCentre
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CostCentre -> m CostCentre
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CostCentre -> m CostCentre
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CostCentre -> m CostCentre
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CostCentre -> m CostCentre
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CostCentre -> m CostCentre
Data

type CcName = FastString

data IndexedCCFlavour
    = ExprCC -- ^ Explicitly annotated expression
    | DeclCC -- ^ Explicitly annotated declaration
    | HpcCC -- ^ Generated by HPC for coverage
    | LateCC -- ^ Annotated by the one of the prof-last* passes.
    | CallerCC -- ^ Annotated by the one of the prof-last* passes.
    deriving (IndexedCCFlavour -> IndexedCCFlavour -> Bool
(IndexedCCFlavour -> IndexedCCFlavour -> Bool)
-> (IndexedCCFlavour -> IndexedCCFlavour -> Bool)
-> Eq IndexedCCFlavour
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
== :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
$c/= :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
/= :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
Eq,Eq IndexedCCFlavour
Eq IndexedCCFlavour =>
(IndexedCCFlavour -> IndexedCCFlavour -> Ordering)
-> (IndexedCCFlavour -> IndexedCCFlavour -> Bool)
-> (IndexedCCFlavour -> IndexedCCFlavour -> Bool)
-> (IndexedCCFlavour -> IndexedCCFlavour -> Bool)
-> (IndexedCCFlavour -> IndexedCCFlavour -> Bool)
-> (IndexedCCFlavour -> IndexedCCFlavour -> IndexedCCFlavour)
-> (IndexedCCFlavour -> IndexedCCFlavour -> IndexedCCFlavour)
-> Ord IndexedCCFlavour
IndexedCCFlavour -> IndexedCCFlavour -> Bool
IndexedCCFlavour -> IndexedCCFlavour -> Ordering
IndexedCCFlavour -> IndexedCCFlavour -> IndexedCCFlavour
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IndexedCCFlavour -> IndexedCCFlavour -> Ordering
compare :: IndexedCCFlavour -> IndexedCCFlavour -> Ordering
$c< :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
< :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
$c<= :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
<= :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
$c> :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
> :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
$c>= :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
>= :: IndexedCCFlavour -> IndexedCCFlavour -> Bool
$cmax :: IndexedCCFlavour -> IndexedCCFlavour -> IndexedCCFlavour
max :: IndexedCCFlavour -> IndexedCCFlavour -> IndexedCCFlavour
$cmin :: IndexedCCFlavour -> IndexedCCFlavour -> IndexedCCFlavour
min :: IndexedCCFlavour -> IndexedCCFlavour -> IndexedCCFlavour
Ord,Typeable IndexedCCFlavour
Typeable IndexedCCFlavour =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> IndexedCCFlavour -> c IndexedCCFlavour)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c IndexedCCFlavour)
-> (IndexedCCFlavour -> Constr)
-> (IndexedCCFlavour -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c IndexedCCFlavour))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c IndexedCCFlavour))
-> ((forall b. Data b => b -> b)
    -> IndexedCCFlavour -> IndexedCCFlavour)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> IndexedCCFlavour -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> IndexedCCFlavour -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> IndexedCCFlavour -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> IndexedCCFlavour -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> IndexedCCFlavour -> m IndexedCCFlavour)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> IndexedCCFlavour -> m IndexedCCFlavour)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> IndexedCCFlavour -> m IndexedCCFlavour)
-> Data IndexedCCFlavour
IndexedCCFlavour -> Constr
IndexedCCFlavour -> DataType
(forall b. Data b => b -> b)
-> IndexedCCFlavour -> IndexedCCFlavour
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> IndexedCCFlavour -> u
forall u. (forall d. Data d => d -> u) -> IndexedCCFlavour -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> IndexedCCFlavour -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> IndexedCCFlavour -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> IndexedCCFlavour -> m IndexedCCFlavour
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> IndexedCCFlavour -> m IndexedCCFlavour
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c IndexedCCFlavour
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> IndexedCCFlavour -> c IndexedCCFlavour
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c IndexedCCFlavour)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c IndexedCCFlavour)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> IndexedCCFlavour -> c IndexedCCFlavour
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> IndexedCCFlavour -> c IndexedCCFlavour
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c IndexedCCFlavour
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c IndexedCCFlavour
$ctoConstr :: IndexedCCFlavour -> Constr
toConstr :: IndexedCCFlavour -> Constr
$cdataTypeOf :: IndexedCCFlavour -> DataType
dataTypeOf :: IndexedCCFlavour -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c IndexedCCFlavour)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c IndexedCCFlavour)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c IndexedCCFlavour)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c IndexedCCFlavour)
$cgmapT :: (forall b. Data b => b -> b)
-> IndexedCCFlavour -> IndexedCCFlavour
gmapT :: (forall b. Data b => b -> b)
-> IndexedCCFlavour -> IndexedCCFlavour
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> IndexedCCFlavour -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> IndexedCCFlavour -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> IndexedCCFlavour -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> IndexedCCFlavour -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> IndexedCCFlavour -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> IndexedCCFlavour -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> IndexedCCFlavour -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> IndexedCCFlavour -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> IndexedCCFlavour -> m IndexedCCFlavour
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> IndexedCCFlavour -> m IndexedCCFlavour
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> IndexedCCFlavour -> m IndexedCCFlavour
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> IndexedCCFlavour -> m IndexedCCFlavour
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> IndexedCCFlavour -> m IndexedCCFlavour
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> IndexedCCFlavour -> m IndexedCCFlavour
Data,Int -> IndexedCCFlavour
IndexedCCFlavour -> Int
IndexedCCFlavour -> [IndexedCCFlavour]
IndexedCCFlavour -> IndexedCCFlavour
IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour]
IndexedCCFlavour
-> IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour]
(IndexedCCFlavour -> IndexedCCFlavour)
-> (IndexedCCFlavour -> IndexedCCFlavour)
-> (Int -> IndexedCCFlavour)
-> (IndexedCCFlavour -> Int)
-> (IndexedCCFlavour -> [IndexedCCFlavour])
-> (IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour])
-> (IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour])
-> (IndexedCCFlavour
    -> IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour])
-> Enum IndexedCCFlavour
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: IndexedCCFlavour -> IndexedCCFlavour
succ :: IndexedCCFlavour -> IndexedCCFlavour
$cpred :: IndexedCCFlavour -> IndexedCCFlavour
pred :: IndexedCCFlavour -> IndexedCCFlavour
$ctoEnum :: Int -> IndexedCCFlavour
toEnum :: Int -> IndexedCCFlavour
$cfromEnum :: IndexedCCFlavour -> Int
fromEnum :: IndexedCCFlavour -> Int
$cenumFrom :: IndexedCCFlavour -> [IndexedCCFlavour]
enumFrom :: IndexedCCFlavour -> [IndexedCCFlavour]
$cenumFromThen :: IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour]
enumFromThen :: IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour]
$cenumFromTo :: IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour]
enumFromTo :: IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour]
$cenumFromThenTo :: IndexedCCFlavour
-> IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour]
enumFromThenTo :: IndexedCCFlavour
-> IndexedCCFlavour -> IndexedCCFlavour -> [IndexedCCFlavour]
Enum)
-- | The flavour of a cost centre.
--
-- Index fields represent 0-based indices giving source-code ordering of
-- centres with the same module, name, and flavour.
data CCFlavour = CafCC -- ^ Auto-generated top-level thunk, they all go into the same bucket
               | IndexedCC !IndexedCCFlavour !CostCentreIndex -- ^ Explicitly annotated expression
               deriving (CCFlavour -> CCFlavour -> Bool
(CCFlavour -> CCFlavour -> Bool)
-> (CCFlavour -> CCFlavour -> Bool) -> Eq CCFlavour
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CCFlavour -> CCFlavour -> Bool
== :: CCFlavour -> CCFlavour -> Bool
$c/= :: CCFlavour -> CCFlavour -> Bool
/= :: CCFlavour -> CCFlavour -> Bool
Eq, Eq CCFlavour
Eq CCFlavour =>
(CCFlavour -> CCFlavour -> Ordering)
-> (CCFlavour -> CCFlavour -> Bool)
-> (CCFlavour -> CCFlavour -> Bool)
-> (CCFlavour -> CCFlavour -> Bool)
-> (CCFlavour -> CCFlavour -> Bool)
-> (CCFlavour -> CCFlavour -> CCFlavour)
-> (CCFlavour -> CCFlavour -> CCFlavour)
-> Ord CCFlavour
CCFlavour -> CCFlavour -> Bool
CCFlavour -> CCFlavour -> Ordering
CCFlavour -> CCFlavour -> CCFlavour
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: CCFlavour -> CCFlavour -> Ordering
compare :: CCFlavour -> CCFlavour -> Ordering
$c< :: CCFlavour -> CCFlavour -> Bool
< :: CCFlavour -> CCFlavour -> Bool
$c<= :: CCFlavour -> CCFlavour -> Bool
<= :: CCFlavour -> CCFlavour -> Bool
$c> :: CCFlavour -> CCFlavour -> Bool
> :: CCFlavour -> CCFlavour -> Bool
$c>= :: CCFlavour -> CCFlavour -> Bool
>= :: CCFlavour -> CCFlavour -> Bool
$cmax :: CCFlavour -> CCFlavour -> CCFlavour
max :: CCFlavour -> CCFlavour -> CCFlavour
$cmin :: CCFlavour -> CCFlavour -> CCFlavour
min :: CCFlavour -> CCFlavour -> CCFlavour
Ord, Typeable CCFlavour
Typeable CCFlavour =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> CCFlavour -> c CCFlavour)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c CCFlavour)
-> (CCFlavour -> Constr)
-> (CCFlavour -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c CCFlavour))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CCFlavour))
-> ((forall b. Data b => b -> b) -> CCFlavour -> CCFlavour)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> CCFlavour -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> CCFlavour -> r)
-> (forall u. (forall d. Data d => d -> u) -> CCFlavour -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> CCFlavour -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour)
-> Data CCFlavour
CCFlavour -> Constr
CCFlavour -> DataType
(forall b. Data b => b -> b) -> CCFlavour -> CCFlavour
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> CCFlavour -> u
forall u. (forall d. Data d => d -> u) -> CCFlavour -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CCFlavour -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CCFlavour -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CCFlavour
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CCFlavour -> c CCFlavour
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CCFlavour)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CCFlavour)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CCFlavour -> c CCFlavour
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CCFlavour -> c CCFlavour
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CCFlavour
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CCFlavour
$ctoConstr :: CCFlavour -> Constr
toConstr :: CCFlavour -> Constr
$cdataTypeOf :: CCFlavour -> DataType
dataTypeOf :: CCFlavour -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CCFlavour)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CCFlavour)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CCFlavour)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CCFlavour)
$cgmapT :: (forall b. Data b => b -> b) -> CCFlavour -> CCFlavour
gmapT :: (forall b. Data b => b -> b) -> CCFlavour -> CCFlavour
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CCFlavour -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CCFlavour -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CCFlavour -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CCFlavour -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> CCFlavour -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> CCFlavour -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CCFlavour -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CCFlavour -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CCFlavour -> m CCFlavour
Data)

-- Construct a CC flavour
mkCafFlavour :: CCFlavour
mkCafFlavour :: CCFlavour
mkCafFlavour = CCFlavour
CafCC
mkExprCCFlavour :: CostCentreIndex -> CCFlavour
mkExprCCFlavour :: CostCentreIndex -> CCFlavour
mkExprCCFlavour CostCentreIndex
idx = IndexedCCFlavour -> CostCentreIndex -> CCFlavour
IndexedCC IndexedCCFlavour
ExprCC CostCentreIndex
idx
mkDeclCCFlavour :: CostCentreIndex -> CCFlavour
mkDeclCCFlavour :: CostCentreIndex -> CCFlavour
mkDeclCCFlavour CostCentreIndex
idx = IndexedCCFlavour -> CostCentreIndex -> CCFlavour
IndexedCC IndexedCCFlavour
DeclCC CostCentreIndex
idx
mkHpcCCFlavour :: CostCentreIndex -> CCFlavour
mkHpcCCFlavour :: CostCentreIndex -> CCFlavour
mkHpcCCFlavour CostCentreIndex
idx = IndexedCCFlavour -> CostCentreIndex -> CCFlavour
IndexedCC IndexedCCFlavour
HpcCC CostCentreIndex
idx
mkLateCCFlavour :: CostCentreIndex -> CCFlavour
mkLateCCFlavour :: CostCentreIndex -> CCFlavour
mkLateCCFlavour CostCentreIndex
idx = IndexedCCFlavour -> CostCentreIndex -> CCFlavour
IndexedCC IndexedCCFlavour
LateCC CostCentreIndex
idx
mkCallerCCFlavour :: CostCentreIndex -> CCFlavour
mkCallerCCFlavour :: CostCentreIndex -> CCFlavour
mkCallerCCFlavour CostCentreIndex
idx = IndexedCCFlavour -> CostCentreIndex -> CCFlavour
IndexedCC IndexedCCFlavour
CallerCC CostCentreIndex
idx

-- | Extract the index from a flavour
flavourIndex :: CCFlavour -> Int
flavourIndex :: CCFlavour -> Int
flavourIndex CCFlavour
CafCC = Int
0
flavourIndex (IndexedCC IndexedCCFlavour
_flav CostCentreIndex
x) = CostCentreIndex -> Int
unCostCentreIndex CostCentreIndex
x

instance Eq CostCentre where
        CostCentre
c1 == :: CostCentre -> CostCentre -> Bool
== CostCentre
c2 = case CostCentre
c1 CostCentre -> CostCentre -> Ordering
`cmpCostCentre` CostCentre
c2 of { Ordering
EQ -> Bool
True; Ordering
_ -> Bool
False }

instance Ord CostCentre where
        compare :: CostCentre -> CostCentre -> Ordering
compare = CostCentre -> CostCentre -> Ordering
cmpCostCentre

cmpCostCentre :: CostCentre -> CostCentre -> Ordering

cmpCostCentre :: CostCentre -> CostCentre -> Ordering
cmpCostCentre (AllCafsCC  {cc_mod :: CostCentre -> Module
cc_mod = Module
m1}) (AllCafsCC  {cc_mod :: CostCentre -> Module
cc_mod = Module
m2})
  = Module
m1 Module -> Module -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Module
m2

cmpCostCentre NormalCC {cc_flavour :: CostCentre -> CCFlavour
cc_flavour = CCFlavour
f1, cc_mod :: CostCentre -> Module
cc_mod =  Module
m1, cc_name :: CostCentre -> CcName
cc_name = CcName
n1}
              NormalCC {cc_flavour :: CostCentre -> CCFlavour
cc_flavour = CCFlavour
f2, cc_mod :: CostCentre -> Module
cc_mod =  Module
m2, cc_name :: CostCentre -> CcName
cc_name = CcName
n2}
    -- first key is module name, then centre name, then flavour
  = [Ordering] -> Ordering
forall a. Monoid a => [a] -> a
mconcat
      [ Module
m1 Module -> Module -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Module
m2
      , CcName
n1 CcName -> CcName -> Ordering
`lexicalCompareFS` CcName
n2 -- compare lexically to avoid non-determinism
      , CCFlavour
f1 CCFlavour -> CCFlavour -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` CCFlavour
f2
      ]

cmpCostCentre CostCentre
other_1 CostCentre
other_2
  = let
        tag1 :: Int
tag1 = CostCentre -> Int
tag_CC CostCentre
other_1
        tag2 :: Int
tag2 = CostCentre -> Int
tag_CC CostCentre
other_2
    in
    if Int
tag1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
tag2 then Ordering
LT else Ordering
GT
  where
    tag_CC :: CostCentre -> Int
    tag_CC :: CostCentre -> Int
tag_CC (NormalCC   {}) = Int
0
    tag_CC (AllCafsCC  {}) = Int
1


-----------------------------------------------------------------------------
-- Predicates on CostCentre

isCafCC :: CostCentre -> Bool
isCafCC :: CostCentre -> Bool
isCafCC (AllCafsCC {})                  = Bool
True
isCafCC (NormalCC {cc_flavour :: CostCentre -> CCFlavour
cc_flavour = CCFlavour
CafCC}) = Bool
True
isCafCC CostCentre
_                               = Bool
False

-- | Is this a cost-centre which records scc counts
isSccCountCC :: CostCentre -> Bool
isSccCountCC :: CostCentre -> Bool
isSccCountCC CostCentre
cc | CostCentre -> Bool
isCafCC CostCentre
cc  = Bool
False
                | Bool
otherwise   = Bool
True

-- | Is this a cost-centre which can be sccd ?
sccAbleCC :: CostCentre -> Bool
sccAbleCC :: CostCentre -> Bool
sccAbleCC CostCentre
cc | CostCentre -> Bool
isCafCC CostCentre
cc = Bool
False
             | Bool
otherwise  = Bool
True

ccFromThisModule :: CostCentre -> Module -> Bool
ccFromThisModule :: CostCentre -> Module -> Bool
ccFromThisModule CostCentre
cc Module
m = CostCentre -> Module
cc_mod CostCentre
cc Module -> Module -> Bool
forall a. Eq a => a -> a -> Bool
== Module
m


-----------------------------------------------------------------------------
-- Building cost centres

mkUserCC :: FastString -> Module -> SrcSpan -> CCFlavour -> CostCentre
mkUserCC :: CcName -> Module -> SrcSpan -> CCFlavour -> CostCentre
mkUserCC CcName
cc_name Module
mod SrcSpan
loc CCFlavour
flavour
  = NormalCC { cc_name :: CcName
cc_name = CcName
cc_name, cc_mod :: Module
cc_mod =  Module
mod, cc_loc :: SrcSpan
cc_loc = SrcSpan
loc,
               cc_flavour :: CCFlavour
cc_flavour = CCFlavour
flavour
    }

mkAutoCC :: Id -> Module -> CostCentre
mkAutoCC :: Id -> Module -> CostCentre
mkAutoCC Id
id Module
mod
  = NormalCC { cc_name :: CcName
cc_name = CcName
str, cc_mod :: Module
cc_mod =  Module
mod,
               cc_loc :: SrcSpan
cc_loc = Name -> SrcSpan
nameSrcSpan (Id -> Name
forall a. NamedThing a => a -> Name
getName Id
id),
               cc_flavour :: CCFlavour
cc_flavour = CCFlavour
CafCC
    }
  where
        name :: Name
name = Id -> Name
forall a. NamedThing a => a -> Name
getName Id
id
        -- beware: only external names are guaranteed to have unique
        -- Occnames.  If the name is not external, we must append its
        -- Unique.
        -- See bug #249, tests prof001, prof002,  also #2411
        str :: CcName
str | Name -> Bool
isExternalName Name
name = OccName -> CcName
occNameFS (Id -> OccName
forall a. NamedThing a => a -> OccName
getOccName Id
id)
            | Bool
otherwise           = [CcName] -> CcName
concatFS [OccName -> CcName
occNameFS (Id -> OccName
forall a. NamedThing a => a -> OccName
getOccName Id
id),
                                              String -> CcName
fsLit String
"_",
                                              String -> CcName
mkFastString (Unique -> String
forall a. Show a => a -> String
show (Name -> Unique
forall a. Uniquable a => a -> Unique
getUnique Name
name))]
mkAllCafsCC :: Module -> SrcSpan -> CostCentre
mkAllCafsCC :: Module -> SrcSpan -> CostCentre
mkAllCafsCC Module
m SrcSpan
loc = AllCafsCC { cc_mod :: Module
cc_mod = Module
m, cc_loc :: SrcSpan
cc_loc = SrcSpan
loc }

-----------------------------------------------------------------------------
-- Cost Centre Stacks

-- | A Cost Centre Stack is something that can be attached to a closure.
-- This is either:
--
--      * the current cost centre stack (CCCS)
--      * a pre-defined cost centre stack (there are several
--        pre-defined CCSs, see below).

data CostCentreStack
  = CurrentCCS          -- Pinned on a let(rec)-bound
                        -- thunk/function/constructor, this says that the
                        -- cost centre to be attached to the object, when it
                        -- is allocated, is whatever is in the
                        -- current-cost-centre-stack register.

  | DontCareCCS         -- We need a CCS to stick in static closures
                        -- (for data), but we *don't* expect them to
                        -- accumulate any costs.  But we still need
                        -- the placeholder.  This CCS is it.

  | SingletonCCS CostCentre

  deriving (CostCentreStack -> CostCentreStack -> Bool
(CostCentreStack -> CostCentreStack -> Bool)
-> (CostCentreStack -> CostCentreStack -> Bool)
-> Eq CostCentreStack
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CostCentreStack -> CostCentreStack -> Bool
== :: CostCentreStack -> CostCentreStack -> Bool
$c/= :: CostCentreStack -> CostCentreStack -> Bool
/= :: CostCentreStack -> CostCentreStack -> Bool
Eq, Eq CostCentreStack
Eq CostCentreStack =>
(CostCentreStack -> CostCentreStack -> Ordering)
-> (CostCentreStack -> CostCentreStack -> Bool)
-> (CostCentreStack -> CostCentreStack -> Bool)
-> (CostCentreStack -> CostCentreStack -> Bool)
-> (CostCentreStack -> CostCentreStack -> Bool)
-> (CostCentreStack -> CostCentreStack -> CostCentreStack)
-> (CostCentreStack -> CostCentreStack -> CostCentreStack)
-> Ord CostCentreStack
CostCentreStack -> CostCentreStack -> Bool
CostCentreStack -> CostCentreStack -> Ordering
CostCentreStack -> CostCentreStack -> CostCentreStack
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: CostCentreStack -> CostCentreStack -> Ordering
compare :: CostCentreStack -> CostCentreStack -> Ordering
$c< :: CostCentreStack -> CostCentreStack -> Bool
< :: CostCentreStack -> CostCentreStack -> Bool
$c<= :: CostCentreStack -> CostCentreStack -> Bool
<= :: CostCentreStack -> CostCentreStack -> Bool
$c> :: CostCentreStack -> CostCentreStack -> Bool
> :: CostCentreStack -> CostCentreStack -> Bool
$c>= :: CostCentreStack -> CostCentreStack -> Bool
>= :: CostCentreStack -> CostCentreStack -> Bool
$cmax :: CostCentreStack -> CostCentreStack -> CostCentreStack
max :: CostCentreStack -> CostCentreStack -> CostCentreStack
$cmin :: CostCentreStack -> CostCentreStack -> CostCentreStack
min :: CostCentreStack -> CostCentreStack -> CostCentreStack
Ord)    -- needed for Ord on CLabel


-- synonym for triple which describes the cost centre info in the generated
-- code for a module.
type CollectedCCs
  = ( [CostCentre]       -- local cost-centres that need to be decl'd
    , [CostCentreStack]  -- pre-defined "singleton" cost centre stacks
    )

emptyCollectedCCs :: CollectedCCs
emptyCollectedCCs :: CollectedCCs
emptyCollectedCCs = ([], [])

collectCC :: CostCentre -> CostCentreStack -> CollectedCCs -> CollectedCCs
collectCC :: CostCentre -> CostCentreStack -> CollectedCCs -> CollectedCCs
collectCC CostCentre
cc CostCentreStack
ccs ([CostCentre]
c, [CostCentreStack]
cs) = (CostCentre
cc CostCentre -> [CostCentre] -> [CostCentre]
forall a. a -> [a] -> [a]
: [CostCentre]
c, CostCentreStack
ccs CostCentreStack -> [CostCentreStack] -> [CostCentreStack]
forall a. a -> [a] -> [a]
: [CostCentreStack]
cs)

currentCCS, dontCareCCS :: CostCentreStack

currentCCS :: CostCentreStack
currentCCS              = CostCentreStack
CurrentCCS
dontCareCCS :: CostCentreStack
dontCareCCS             = CostCentreStack
DontCareCCS

-----------------------------------------------------------------------------
-- Predicates on Cost-Centre Stacks

isCurrentCCS :: CostCentreStack -> Bool
isCurrentCCS :: CostCentreStack -> Bool
isCurrentCCS CostCentreStack
CurrentCCS                 = Bool
True
isCurrentCCS CostCentreStack
_                          = Bool
False

isCafCCS :: CostCentreStack -> Bool
isCafCCS :: CostCentreStack -> Bool
isCafCCS (SingletonCCS CostCentre
cc)              = CostCentre -> Bool
isCafCC CostCentre
cc
isCafCCS CostCentreStack
_                              = Bool
False

maybeSingletonCCS :: CostCentreStack -> Maybe CostCentre
maybeSingletonCCS :: CostCentreStack -> Maybe CostCentre
maybeSingletonCCS (SingletonCCS CostCentre
cc)     = CostCentre -> Maybe CostCentre
forall a. a -> Maybe a
Just CostCentre
cc
maybeSingletonCCS CostCentreStack
_                     = Maybe CostCentre
forall a. Maybe a
Nothing

mkSingletonCCS :: CostCentre -> CostCentreStack
mkSingletonCCS :: CostCentre -> CostCentreStack
mkSingletonCCS CostCentre
cc = CostCentre -> CostCentreStack
SingletonCCS CostCentre
cc


-----------------------------------------------------------------------------
-- Printing Cost Centre Stacks.

-- The outputable instance for CostCentreStack prints the CCS as a C
-- expression.

instance Outputable CostCentreStack where
  ppr :: CostCentreStack -> SDoc
ppr = CostCentreStack -> SDoc
forall doc. IsLine doc => CostCentreStack -> doc
pprCostCentreStack

pprCostCentreStack :: IsLine doc => CostCentreStack -> doc
pprCostCentreStack :: forall doc. IsLine doc => CostCentreStack -> doc
pprCostCentreStack CostCentreStack
CurrentCCS        = String -> doc
forall doc. IsLine doc => String -> doc
text String
"CCCS"
pprCostCentreStack CostCentreStack
DontCareCCS       = String -> doc
forall doc. IsLine doc => String -> doc
text String
"CCS_DONT_CARE"
pprCostCentreStack (SingletonCCS CostCentre
cc) = CostCentre -> doc
forall doc. IsLine doc => CostCentre -> doc
pprCostCentre CostCentre
cc doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
"_ccs"
{-# SPECIALISE pprCostCentreStack :: CostCentreStack -> SDoc #-}
{-# SPECIALISE pprCostCentreStack :: CostCentreStack -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable

-----------------------------------------------------------------------------
-- Printing Cost Centres
--
-- There are several different ways in which we might want to print a
-- cost centre:
--
--      - the name of the cost centre, for profiling output (a C string)
--      - the label, i.e. C label for cost centre in .hc file.
--      - the debugging name, for output in -ddump things
--      - the interface name, for printing in _scc_ exprs in iface files.
--
-- The last 3 are derived from costCentreStr below.  The first is given
-- by costCentreName.

instance Outputable CostCentre where
  ppr :: CostCentre -> SDoc
ppr = CostCentre -> SDoc
forall doc. IsLine doc => CostCentre -> doc
pprCostCentre

pprCostCentre :: IsLine doc => CostCentre -> doc
pprCostCentre :: forall doc. IsLine doc => CostCentre -> doc
pprCostCentre CostCentre
cc = (SDocContext -> doc) -> doc
forall doc. IsOutput doc => (SDocContext -> doc) -> doc
docWithContext ((SDocContext -> doc) -> doc) -> (SDocContext -> doc) -> doc
forall a b. (a -> b) -> a -> b
$ \ SDocContext
sty ->
  if PprStyle -> Bool
codeStyle (SDocContext -> PprStyle
sdocStyle SDocContext
sty)
  then CostCentre -> doc
forall doc. IsLine doc => CostCentre -> doc
ppCostCentreLbl CostCentre
cc
  else CcName -> doc
forall doc. IsLine doc => CcName -> doc
ftext (CostCentre -> CcName
costCentreUserNameFS CostCentre
cc)
{-# SPECIALISE pprCostCentre :: CostCentre -> SDoc #-}
{-# SPECIALISE pprCostCentre :: CostCentre -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable

-- Printing in Core
pprCostCentreCore :: CostCentre -> SDoc
pprCostCentreCore :: CostCentre -> SDoc
pprCostCentreCore (AllCafsCC {cc_mod :: CostCentre -> Module
cc_mod = Module
m})
  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"__sccC" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
m)
pprCostCentreCore (NormalCC {cc_flavour :: CostCentre -> CCFlavour
cc_flavour = CCFlavour
flavour, cc_name :: CostCentre -> CcName
cc_name = CcName
n,
                             cc_mod :: CostCentre -> Module
cc_mod = Module
m, cc_loc :: CostCentre -> SrcSpan
cc_loc = SrcSpan
loc})
  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"__scc" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [
        Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
m SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'.' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> CcName -> SDoc
forall doc. IsLine doc => CcName -> doc
ftext CcName
n,
        CCFlavour -> SDoc
pprFlavourCore CCFlavour
flavour,
        SDoc -> SDoc
forall doc. IsOutput doc => doc -> doc
whenPprDebug (SrcSpan -> SDoc
forall a. Outputable a => a -> SDoc
ppr SrcSpan
loc)
    ])

-- ^ Print a flavour in Core
pprFlavourCore :: CCFlavour -> SDoc
pprFlavourCore :: CCFlavour -> SDoc
pprFlavourCore CCFlavour
CafCC = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"__C"
pprFlavourCore CCFlavour
f     = Int -> SDoc
pprIdxCore (Int -> SDoc) -> Int -> SDoc
forall a b. (a -> b) -> a -> b
$ CCFlavour -> Int
flavourIndex CCFlavour
f

-- ^ Print a flavour's index in Core
pprIdxCore :: Int -> SDoc
pprIdxCore :: Int -> SDoc
pprIdxCore Int
0 = SDoc
forall doc. IsOutput doc => doc
empty
pprIdxCore Int
idx = SDoc -> SDoc
forall doc. IsOutput doc => doc -> doc
whenPprDebug (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
idx

-- Printing as a C label
ppCostCentreLbl :: IsLine doc => CostCentre -> doc
ppCostCentreLbl :: forall doc. IsLine doc => CostCentre -> doc
ppCostCentreLbl (AllCafsCC  {cc_mod :: CostCentre -> Module
cc_mod = Module
m}) = Module -> doc
forall doc. IsLine doc => Module -> doc
pprModule Module
m doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
"_CAFs_cc"
ppCostCentreLbl (NormalCC {cc_flavour :: CostCentre -> CCFlavour
cc_flavour = CCFlavour
f, cc_name :: CostCentre -> CcName
cc_name = CcName
n, cc_mod :: CostCentre -> Module
cc_mod = Module
m})
  = Module -> doc
forall doc. IsLine doc => Module -> doc
pprModule Module
m doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'_' doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> FastZString -> doc
forall doc. IsLine doc => FastZString -> doc
ztext (CcName -> FastZString
zEncodeFS CcName
n) doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'_' doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<>
        CCFlavour -> doc
forall doc. IsLine doc => CCFlavour -> doc
ppFlavourLblComponent CCFlavour
f doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
"_cc"
{-# SPECIALISE ppCostCentreLbl :: CostCentre -> SDoc #-}
{-# SPECIALISE ppCostCentreLbl :: CostCentre -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable

-- ^ Print the flavour component of a C label
ppFlavourLblComponent :: IsLine doc => CCFlavour -> doc
ppFlavourLblComponent :: forall doc. IsLine doc => CCFlavour -> doc
ppFlavourLblComponent CCFlavour
CafCC = String -> doc
forall doc. IsLine doc => String -> doc
text String
"CAF"
ppFlavourLblComponent (IndexedCC IndexedCCFlavour
flav CostCentreIndex
i) =
  case IndexedCCFlavour
flav of
    IndexedCCFlavour
ExprCC -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"EXPR" doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> CostCentreIndex -> doc
forall doc. IsLine doc => CostCentreIndex -> doc
ppIdxLblComponent CostCentreIndex
i
    IndexedCCFlavour
DeclCC -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"DECL" doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> CostCentreIndex -> doc
forall doc. IsLine doc => CostCentreIndex -> doc
ppIdxLblComponent CostCentreIndex
i
    IndexedCCFlavour
HpcCC -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"HPC" doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> CostCentreIndex -> doc
forall doc. IsLine doc => CostCentreIndex -> doc
ppIdxLblComponent CostCentreIndex
i
    IndexedCCFlavour
LateCC -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"LATECC" doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> CostCentreIndex -> doc
forall doc. IsLine doc => CostCentreIndex -> doc
ppIdxLblComponent CostCentreIndex
i
    IndexedCCFlavour
CallerCC -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"CALLERCC" doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> CostCentreIndex -> doc
forall doc. IsLine doc => CostCentreIndex -> doc
ppIdxLblComponent CostCentreIndex
i
{-# SPECIALISE ppFlavourLblComponent :: CCFlavour -> SDoc #-}
{-# SPECIALISE ppFlavourLblComponent :: CCFlavour -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable

-- ^ Print the flavour index component of a C label
ppIdxLblComponent :: IsLine doc => CostCentreIndex -> doc
ppIdxLblComponent :: forall doc. IsLine doc => CostCentreIndex -> doc
ppIdxLblComponent CostCentreIndex
n =
  case CostCentreIndex -> Int
unCostCentreIndex CostCentreIndex
n of
    Int
0 -> doc
forall doc. IsOutput doc => doc
empty
    Int
n -> Int -> doc
forall doc. IsLine doc => Int -> doc
int Int
n
{-# SPECIALISE ppIdxLblComponent :: CostCentreIndex -> SDoc #-}
{-# SPECIALISE ppIdxLblComponent :: CostCentreIndex -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable

-- This is the name to go in the user-displayed string,
-- recorded in the cost centre declaration
costCentreUserName :: CostCentre -> String
costCentreUserName :: CostCentre -> String
costCentreUserName = CcName -> String
unpackFS (CcName -> String)
-> (CostCentre -> CcName) -> CostCentre -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CostCentre -> CcName
costCentreUserNameFS

costCentreUserNameFS :: CostCentre -> FastString
costCentreUserNameFS :: CostCentre -> CcName
costCentreUserNameFS (AllCafsCC {})  = String -> CcName
mkFastString String
"CAF"
costCentreUserNameFS (NormalCC {cc_name :: CostCentre -> CcName
cc_name = CcName
name, cc_flavour :: CostCentre -> CCFlavour
cc_flavour = CCFlavour
is_caf})
  =  case CCFlavour
is_caf of
      CCFlavour
CafCC -> String -> CcName
mkFastString String
"CAF:" CcName -> CcName -> CcName
`appendFS` CcName
name
      CCFlavour
_     -> CcName
name

costCentreSrcSpan :: CostCentre -> SrcSpan
costCentreSrcSpan :: CostCentre -> SrcSpan
costCentreSrcSpan = CostCentre -> SrcSpan
cc_loc

instance Binary CCFlavour where
    put_ :: BinHandle -> CCFlavour -> IO ()
put_ BinHandle
bh CCFlavour
CafCC =
        BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
    put_ BinHandle
bh (IndexedCC IndexedCCFlavour
flav CostCentreIndex
i) = do
        BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
        let !flav_index :: Int
flav_index = IndexedCCFlavour -> Int
forall a. Enum a => a -> Int
fromEnum IndexedCCFlavour
flav
        BinHandle -> Int -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh Int
flav_index
        BinHandle -> CostCentreIndex -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh CostCentreIndex
i
    get :: BinHandle -> IO CCFlavour
get BinHandle
bh = do
            Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
            case Word8
h of
              Word8
0 -> CCFlavour -> IO CCFlavour
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return CCFlavour
CafCC
              Word8
_ -> do
                IndexedCCFlavour -> CostCentreIndex -> CCFlavour
IndexedCC (IndexedCCFlavour -> CostCentreIndex -> CCFlavour)
-> IO IndexedCCFlavour -> IO (CostCentreIndex -> CCFlavour)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> IndexedCCFlavour
forall a. Enum a => Int -> a
toEnum (Int -> IndexedCCFlavour) -> IO Int -> IO IndexedCCFlavour
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BinHandle -> IO Int
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh) IO (CostCentreIndex -> CCFlavour)
-> IO CostCentreIndex -> IO CCFlavour
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> BinHandle -> IO CostCentreIndex
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh

instance Binary CostCentre where
    put_ :: BinHandle -> CostCentre -> IO ()
put_ BinHandle
bh (NormalCC CCFlavour
aa CcName
ab Module
ac SrcSpan
_ad) = do
            BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
            BinHandle -> CCFlavour -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh CCFlavour
aa
            BinHandle -> CcName -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh CcName
ab
            BinHandle -> Module -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh Module
ac
    put_ BinHandle
bh (AllCafsCC Module
ae SrcSpan
_af) = do
            BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
            BinHandle -> Module -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh Module
ae
    get :: BinHandle -> IO CostCentre
get BinHandle
bh = do
            Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
            case Word8
h of
              Word8
0 -> do CCFlavour
aa <- BinHandle -> IO CCFlavour
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
                      CcName
ab <- BinHandle -> IO CcName
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
                      Module
ac <- BinHandle -> IO Module
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
                      CostCentre -> IO CostCentre
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CCFlavour -> CcName -> Module -> SrcSpan -> CostCentre
NormalCC CCFlavour
aa CcName
ab Module
ac SrcSpan
noSrcSpan)
              Word8
_ -> do Module
ae <- BinHandle -> IO Module
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
                      CostCentre -> IO CostCentre
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Module -> SrcSpan -> CostCentre
AllCafsCC Module
ae SrcSpan
noSrcSpan)

    -- We ignore the SrcSpans in CostCentres when we serialise them,
    -- and set the SrcSpans to noSrcSpan when deserialising.  This is
    -- ok, because we only need the SrcSpan when declaring the
    -- CostCentre in the original module, it is not used by importing
    -- modules.