/compiler/nativeGen/Reg.hs
https://github.com/pepeiborra/ghc · Haskell · 220 lines · 138 code · 40 blank · 42 comment · 16 complexity · 4a692eebdac607be8e55e8662dec4aa7 MD5 · raw file
- -- | An architecture independent description of a register.
- -- This needs to stay architecture independent because it is used
- -- by NCGMonad and the register allocators, which are shared
- -- by all architectures.
- --
- module Reg (
- RegNo,
- Reg(..),
- regPair,
- regSingle,
- isRealReg, takeRealReg,
- isVirtualReg, takeVirtualReg,
-
- VirtualReg(..),
- renameVirtualReg,
- classOfVirtualReg,
- getHiVirtualRegFromLo,
- getHiVRegFromLo,
- RealReg(..),
- regNosOfRealReg,
- realRegsAlias,
-
- liftPatchFnToRegReg
- )
- where
- import Outputable
- import Unique
- import RegClass
- import Data.List
- -- | An identifier for a primitive real machine register.
- type RegNo
- = Int
- -- VirtualRegs are virtual registers. The register allocator will
- -- eventually have to map them into RealRegs, or into spill slots.
- --
- -- VirtualRegs are allocated on the fly, usually to represent a single
- -- value in the abstract assembly code (i.e. dynamic registers are
- -- usually single assignment).
- --
- -- The single assignment restriction isn't necessary to get correct code,
- -- although a better register allocation will result if single
- -- assignment is used -- because the allocator maps a VirtualReg into
- -- a single RealReg, even if the VirtualReg has multiple live ranges.
- --
- -- Virtual regs can be of either class, so that info is attached.
- --
- data VirtualReg
- = VirtualRegI {-# UNPACK #-} !Unique
- | VirtualRegHi {-# UNPACK #-} !Unique -- High part of 2-word register
- | VirtualRegF {-# UNPACK #-} !Unique
- | VirtualRegD {-# UNPACK #-} !Unique
- | VirtualRegSSE {-# UNPACK #-} !Unique
- deriving (Eq, Show, Ord)
- instance Uniquable VirtualReg where
- getUnique reg
- = case reg of
- VirtualRegI u -> u
- VirtualRegHi u -> u
- VirtualRegF u -> u
- VirtualRegD u -> u
- VirtualRegSSE u -> u
- instance Outputable VirtualReg where
- ppr reg
- = case reg of
- VirtualRegI u -> text "%vI_" <> pprUnique u
- VirtualRegHi u -> text "%vHi_" <> pprUnique u
- VirtualRegF u -> text "%vF_" <> pprUnique u
- VirtualRegD u -> text "%vD_" <> pprUnique u
- VirtualRegSSE u -> text "%vSSE_" <> pprUnique u
- renameVirtualReg :: Unique -> VirtualReg -> VirtualReg
- renameVirtualReg u r
- = case r of
- VirtualRegI _ -> VirtualRegI u
- VirtualRegHi _ -> VirtualRegHi u
- VirtualRegF _ -> VirtualRegF u
- VirtualRegD _ -> VirtualRegD u
- VirtualRegSSE _ -> VirtualRegSSE u
- classOfVirtualReg :: VirtualReg -> RegClass
- classOfVirtualReg vr
- = case vr of
- VirtualRegI{} -> RcInteger
- VirtualRegHi{} -> RcInteger
- VirtualRegF{} -> RcFloat
- VirtualRegD{} -> RcDouble
- VirtualRegSSE{} -> RcDoubleSSE
- -- Determine the upper-half vreg for a 64-bit quantity on a 32-bit platform
- -- when supplied with the vreg for the lower-half of the quantity.
- -- (NB. Not reversible).
- getHiVirtualRegFromLo :: VirtualReg -> VirtualReg
- getHiVirtualRegFromLo reg
- = case reg of
- -- makes a pseudo-unique with tag 'H'
- VirtualRegI u -> VirtualRegHi (newTagUnique u 'H')
- _ -> panic "Reg.getHiVirtualRegFromLo"
- getHiVRegFromLo :: Reg -> Reg
- getHiVRegFromLo reg
- = case reg of
- RegVirtual vr -> RegVirtual (getHiVirtualRegFromLo vr)
- RegReal _ -> panic "Reg.getHiVRegFromLo"
-
- ------------------------------------------------------------------------------------
- -- | RealRegs are machine regs which are available for allocation, in
- -- the usual way. We know what class they are, because that's part of
- -- the processor's architecture.
- --
- -- RealRegPairs are pairs of real registers that are allocated together
- -- to hold a larger value, such as with Double regs on SPARC.
- --
- data RealReg
- = RealRegSingle {-# UNPACK #-} !RegNo
- | RealRegPair {-# UNPACK #-} !RegNo {-# UNPACK #-} !RegNo
- deriving (Eq, Show, Ord)
- instance Uniquable RealReg where
- getUnique reg
- = case reg of
- RealRegSingle i -> mkRegSingleUnique i
- RealRegPair r1 r2 -> mkRegPairUnique (r1 * 65536 + r2)
- instance Outputable RealReg where
- ppr reg
- = case reg of
- RealRegSingle i -> text "%r" <> int i
- RealRegPair r1 r2 -> text "%r(" <> int r1 <> text "|" <> int r2 <> text ")"
- regNosOfRealReg :: RealReg -> [RegNo]
- regNosOfRealReg rr
- = case rr of
- RealRegSingle r1 -> [r1]
- RealRegPair r1 r2 -> [r1, r2]
-
- realRegsAlias :: RealReg -> RealReg -> Bool
- realRegsAlias rr1 rr2
- = not $ null $ intersect (regNosOfRealReg rr1) (regNosOfRealReg rr2)
- --------------------------------------------------------------------------------
- -- | A register, either virtual or real
- data Reg
- = RegVirtual !VirtualReg
- | RegReal !RealReg
- deriving (Eq, Ord)
- regSingle :: RegNo -> Reg
- regSingle regNo = RegReal $ RealRegSingle regNo
- regPair :: RegNo -> RegNo -> Reg
- regPair regNo1 regNo2 = RegReal $ RealRegPair regNo1 regNo2
- -- We like to have Uniques for Reg so that we can make UniqFM and UniqSets
- -- in the register allocator.
- instance Uniquable Reg where
- getUnique reg
- = case reg of
- RegVirtual vr -> getUnique vr
- RegReal rr -> getUnique rr
-
- -- | Print a reg in a generic manner
- -- If you want the architecture specific names, then use the pprReg
- -- function from the appropriate Ppr module.
- instance Outputable Reg where
- ppr reg
- = case reg of
- RegVirtual vr -> ppr vr
- RegReal rr -> ppr rr
- isRealReg :: Reg -> Bool
- isRealReg reg
- = case reg of
- RegReal _ -> True
- RegVirtual _ -> False
- takeRealReg :: Reg -> Maybe RealReg
- takeRealReg reg
- = case reg of
- RegReal rr -> Just rr
- _ -> Nothing
- isVirtualReg :: Reg -> Bool
- isVirtualReg reg
- = case reg of
- RegReal _ -> False
- RegVirtual _ -> True
- takeVirtualReg :: Reg -> Maybe VirtualReg
- takeVirtualReg reg
- = case reg of
- RegReal _ -> Nothing
- RegVirtual vr -> Just vr
- -- | The patch function supplied by the allocator maps VirtualReg to RealReg
- -- regs, but sometimes we want to apply it to plain old Reg.
- --
- liftPatchFnToRegReg :: (VirtualReg -> RealReg) -> (Reg -> Reg)
- liftPatchFnToRegReg patchF reg
- = case reg of
- RegVirtual vr -> RegReal (patchF vr)
- RegReal _ -> reg