{-# 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