ghc-9.12.1: GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
module GHC.CmmToAsm.Reg.Linear.FreeRegs (
FR(..),
allFreeRegs,
maxSpillSlots
)
where
import GHC.Prelude
import GHC.Platform.Reg
import GHC.Platform.Reg.Class
import qualified GHC.Platform.Reg.Class.Unified as Unified
import qualified GHC.Platform.Reg.Class.Separate as Separate
import qualified GHC.Platform.Reg.Class.NoVectors as NoVectors
import GHC.CmmToAsm.Config
import GHC.Utils.Panic
import GHC.Platform
-- -----------------------------------------------------------------------------
-- The free register set
-- This needs to be *efficient*
-- Here's an inefficient 'executable specification' of the FreeRegs data type:
--
-- type FreeRegs = [RegNo]
-- noFreeRegs = 0
-- releaseReg n f = if n `elem` f then f else (n : f)
-- initFreeRegs = allocatableRegs
-- getFreeRegs cls f = filter ( (==cls) . regClass . RealReg ) f
-- allocateReg f r = filter (/= r) f
import qualified GHC.CmmToAsm.Reg.Linear.PPC as PPC
import qualified GHC.CmmToAsm.Reg.Linear.X86 as X86
import qualified GHC.CmmToAsm.Reg.Linear.X86_64 as X86_64
import qualified GHC.CmmToAsm.Reg.Linear.AArch64 as AArch64
import qualified GHC.CmmToAsm.Reg.Linear.RV64 as RV64
import qualified GHC.CmmToAsm.PPC.Instr as PPC.Instr
import qualified GHC.CmmToAsm.X86.Instr as X86.Instr
import qualified GHC.CmmToAsm.AArch64.Instr as AArch64.Instr
import qualified GHC.CmmToAsm.RV64.Instr as RV64.Instr
class Show freeRegs => FR freeRegs where
frAllocateReg :: Platform -> RealReg -> freeRegs -> freeRegs
frGetFreeRegs :: Platform -> RegClass -> freeRegs -> [RealReg]
frInitFreeRegs :: Platform -> freeRegs
frReleaseReg :: Platform -> RealReg -> freeRegs -> freeRegs
instance FR X86.FreeRegs where
frAllocateReg = \_ -> X86.allocateReg
frGetFreeRegs = X86.getFreeRegs
frInitFreeRegs = X86.initFreeRegs
frReleaseReg = \_ -> X86.releaseReg
instance FR X86_64.FreeRegs where
frAllocateReg = \_ -> X86_64.allocateReg
frGetFreeRegs = X86_64.getFreeRegs
frInitFreeRegs = X86_64.initFreeRegs
frReleaseReg = \_ -> X86_64.releaseReg
instance FR PPC.FreeRegs where
frAllocateReg = \_ -> PPC.allocateReg
frGetFreeRegs = \_ -> PPC.getFreeRegs
frInitFreeRegs = PPC.initFreeRegs
frReleaseReg = \_ -> PPC.releaseReg
instance FR AArch64.FreeRegs where
frAllocateReg = \_ -> AArch64.allocateReg
frGetFreeRegs = \_ -> AArch64.getFreeRegs
frInitFreeRegs = AArch64.initFreeRegs
frReleaseReg = \_ -> AArch64.releaseReg
instance FR RV64.FreeRegs where
frAllocateReg = const RV64.allocateReg
frGetFreeRegs = const RV64.getFreeRegs
frInitFreeRegs = RV64.initFreeRegs
frReleaseReg = const RV64.releaseReg
allFreeRegs :: FR freeRegs => Platform -> freeRegs -> [RealReg]
allFreeRegs plat fr = foldMap (\rcls -> frGetFreeRegs plat rcls fr) allRegClasses
where
allRegClasses =
case registerArch (platformArch plat) of
Unified -> Unified.allRegClasses
Separate -> Separate.allRegClasses
NoVectors -> NoVectors.allRegClasses
maxSpillSlots :: NCGConfig -> Int
maxSpillSlots config = case platformArch (ncgPlatform config) of
ArchX86 -> X86.Instr.maxSpillSlots config
ArchX86_64 -> X86.Instr.maxSpillSlots config
ArchPPC -> PPC.Instr.maxSpillSlots config
ArchS390X -> panic "maxSpillSlots ArchS390X"
ArchARM _ _ _ -> panic "maxSpillSlots ArchARM"
ArchAArch64 -> AArch64.Instr.maxSpillSlots config
ArchPPC_64 _ -> PPC.Instr.maxSpillSlots config
ArchAlpha -> panic "maxSpillSlots ArchAlpha"
ArchMipseb -> panic "maxSpillSlots ArchMipseb"
ArchMipsel -> panic "maxSpillSlots ArchMipsel"
ArchRISCV64 -> RV64.Instr.maxSpillSlots config
ArchLoongArch64->panic "maxSpillSlots ArchLoongArch64"
ArchJavaScript-> panic "maxSpillSlots ArchJavaScript"
ArchWasm32 -> panic "maxSpillSlots ArchWasm32"
ArchUnknown -> panic "maxSpillSlots ArchUnknown"