    {-# LANGUAGE TypeSynonymInstances #-}
    {-# OPTIONS_GHC -fno-warn-orphans #-}

    {- BlockId module should probably go away completely, being superseded by Label -}
    module GHC.Cmm.BlockId
      ( BlockId, mkBlockId -- ToDo: BlockId should be abstract, but it isn't yet
      , newBlockId
      , blockLbl, infoTblLbl
      ) where

    import GHC.Prelude

    import GHC.Cmm.CLabel
    import GHC.Data.FastString
    import GHC.Types.Id.Info
    import GHC.Types.Name
    import GHC.Types.Unique
    import qualified GHC.Types.Unique.DSM as DSM

    import GHC.Cmm.Dataflow.Label (Label, mkHooplLabel)

    ----------------------------------------------------------------
    --- Block Ids, their environments, and their sets

    {- Note [Unique BlockId]
    ~~~~~~~~~~~~~~~~~~~~~~~~
    Although a 'BlockId' is a local label, for reasons of implementation,
    'BlockId's must be unique within an entire compilation unit.  The reason
    is that each local label is mapped to an assembly-language label, and in
    most assembly languages allow, a label is visible throughout the entire
    compilation unit in which it appears.
    -}

    type BlockId = Label

    mkBlockId :: Unique -> BlockId
    mkBlockId :: Unique -> BlockId
    mkBlockId Unique
    unique = Word64 -> BlockId
    mkHooplLabel (Word64 -> BlockId) -> Word64 -> BlockId
    forall a b. (a -> b) -> a -> b
    $ Unique -> Word64
    getKey Unique
    unique

    -- If the monad unique instance uses a deterministic unique supply, this will
    -- give you a deterministic unique. Otherwise, it will not. Note that from Cmm
    -- onwards (after deterministic renaming in 'codeGen'), there should only exist
    -- deterministic block labels.
    newBlockId :: DSM.MonadGetUnique m => m BlockId
    newBlockId :: forall (m :: * -> *). MonadGetUnique m => m BlockId
    newBlockId = Unique -> BlockId
    mkBlockId (Unique -> BlockId) -> m Unique -> m BlockId
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m Unique
    forall (m :: * -> *). MonadGetUnique m => m Unique
    DSM.getUniqueM

    blockLbl :: BlockId -> CLabel
    blockLbl :: BlockId -> CLabel
    blockLbl BlockId
    label = Unique -> CLabel
    mkLocalBlockLabel (BlockId -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique BlockId
    label)

    infoTblLbl :: BlockId -> CLabel
    infoTblLbl :: BlockId -> CLabel
    infoTblLbl BlockId
    label
      = Name -> CafInfo -> CLabel
    mkBlockInfoTableLabel (Unique -> FastString -> Name
    mkFCallName (BlockId -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique BlockId
    label) (String -> FastString
    fsLit String
    "block")) CafInfo
    NoCafRefs