nativeGen/RegAlloc/Linear/StackMap.hs

    -- | The assignment of virtual registers to stack slots

    --      We have lots of stack slots. Memory-to-memory moves are a pain on most
    --      architectures. Therefore, we avoid having to generate memory-to-memory moves
    --      by simply giving every virtual register its own stack slot.

    --      The StackMap stack map keeps track of virtual register - stack slot
    --      associations and of which stack slots are still free. Once it has been
    --      associated, a stack slot is never "freed" or removed from the StackMap again,
    --      it remains associated until we are done with the current CmmProc.
    --
    module RegAlloc.Linear.StackMap (
            StackSlot,
            StackMap(..),
            emptyStackMap,
            getStackSlotFor,
            getStackUse
    )

    where

    import GhcPrelude

    import DynFlags
    import UniqFM
    import Unique

    -- | Identifier for a stack slot.
    type StackSlot = Int

    data StackMap
            = StackMap
            { -- | The slots that are still available to be allocated.
              stackMapNextFreeSlot  :: !Int

              -- | Assignment of vregs to stack slots.
            , stackMapAssignment    :: UniqFM StackSlot }

    -- | An empty stack map, with all slots available.
    emptyStackMap :: DynFlags -> StackMap
    emptyStackMap _ = StackMap 0 emptyUFM

    -- | If this vreg unique already has a stack assignment then return the slot number,
    --      otherwise allocate a new slot, and update the map.
    --
    getStackSlotFor :: StackMap -> Unique -> (StackMap, Int)

    getStackSlotFor fs@(StackMap _ reserved) reg
      | Just slot <- lookupUFM reserved reg  =  (fs, slot)

    getStackSlotFor (StackMap freeSlot reserved) reg =
        (StackMap (freeSlot+1) (addToUFM reserved reg freeSlot), freeSlot)

    -- | Return the number of stack slots that were allocated
    getStackUse :: StackMap -> Int
    getStackUse (StackMap freeSlot _) = freeSlot