    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    module GHC.Cmm.LRegSet (
        LRegSet,
        LRegKey,

        emptyLRegSet,
        nullLRegSet,
        insertLRegSet,
        elemLRegSet,

        deleteFromLRegSet,
        sizeLRegSet,

        plusLRegSet,
        elemsLRegSet
      ) where

    import GHC.Prelude
    import GHC.Types.Unique
    import GHC.Cmm.Expr

    import Data.IntSet as IntSet

    -- Compact sets for membership tests of local variables.

    type LRegSet = IntSet.IntSet
    type LRegKey = Int

    emptyLRegSet :: LRegSet
    emptyLRegSet :: LRegSet
    emptyLRegSet = LRegSet
    IntSet.empty

    nullLRegSet :: LRegSet -> Bool
    nullLRegSet :: LRegSet -> Bool
    nullLRegSet = LRegSet -> Bool
    IntSet.null

    insertLRegSet :: LocalReg -> LRegSet -> LRegSet
    insertLRegSet :: LocalReg -> LRegSet -> LRegSet
    insertLRegSet LocalReg
    l = Key -> LRegSet -> LRegSet
    IntSet.insert (Unique -> Key
    getKey (LocalReg -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique LocalReg
    l))

    elemLRegSet :: LocalReg -> LRegSet -> Bool
    elemLRegSet :: LocalReg -> LRegSet -> Bool
    elemLRegSet LocalReg
    l = Key -> LRegSet -> Bool
    IntSet.member (Unique -> Key
    getKey (LocalReg -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique LocalReg
    l))

    deleteFromLRegSet :: LRegSet -> LocalReg -> LRegSet
    deleteFromLRegSet :: LRegSet -> LocalReg -> LRegSet
    deleteFromLRegSet LRegSet
    set LocalReg
    reg = Key -> LRegSet -> LRegSet
    IntSet.delete (Unique -> Key
    getKey (Unique -> Key) -> (LocalReg -> Unique) -> LocalReg -> Key
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LocalReg -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique (LocalReg -> Key) -> LocalReg -> Key
    forall a b. (a -> b) -> a -> b
    $ LocalReg
    reg) LRegSet
    set

    sizeLRegSet :: IntSet -> Int
    sizeLRegSet :: LRegSet -> Key
    sizeLRegSet = LRegSet -> Key
    IntSet.size

    plusLRegSet :: IntSet -> IntSet -> IntSet
    plusLRegSet :: LRegSet -> LRegSet -> LRegSet
    plusLRegSet = LRegSet -> LRegSet -> LRegSet
    IntSet.union

    elemsLRegSet :: IntSet -> [Int]
    elemsLRegSet :: LRegSet -> [Key]
    elemsLRegSet = LRegSet -> [Key]
    IntSet.toList