module Reg (
RegNo,
Reg(..),
regPair,
regSingle,
isRealReg, takeRealReg,
isVirtualReg, takeVirtualReg,
VirtualReg(..),
renameVirtualReg,
classOfVirtualReg,
getHiVirtualRegFromLo,
getHiVRegFromLo,
RealReg(..),
regNosOfRealReg,
realRegsAlias,
liftPatchFnToRegReg
)
where
import GhcPrelude
import Outputable
import Unique
import RegClass
import Data.List (intersect)
type RegNo
= Int
data VirtualReg
= VirtualRegI {-# UNPACK #-} !Unique
| VirtualRegHi {-# UNPACK #-} !Unique
| VirtualRegF {-# UNPACK #-} !Unique
| VirtualRegD {-# UNPACK #-} !Unique
deriving (VirtualReg -> VirtualReg -> Bool
(VirtualReg -> VirtualReg -> Bool)
-> (VirtualReg -> VirtualReg -> Bool) -> Eq VirtualReg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VirtualReg -> VirtualReg -> Bool
$c/= :: VirtualReg -> VirtualReg -> Bool
== :: VirtualReg -> VirtualReg -> Bool
$c== :: VirtualReg -> VirtualReg -> Bool
Eq, Int -> VirtualReg -> ShowS
[VirtualReg] -> ShowS
VirtualReg -> String
(Int -> VirtualReg -> ShowS)
-> (VirtualReg -> String)
-> ([VirtualReg] -> ShowS)
-> Show VirtualReg
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VirtualReg] -> ShowS
$cshowList :: [VirtualReg] -> ShowS
show :: VirtualReg -> String
$cshow :: VirtualReg -> String
showsPrec :: Int -> VirtualReg -> ShowS
$cshowsPrec :: Int -> VirtualReg -> ShowS
Show)
instance Ord VirtualReg where
compare :: VirtualReg -> VirtualReg -> Ordering
compare (VirtualRegI Unique
a) (VirtualRegI Unique
b) = Unique -> Unique -> Ordering
nonDetCmpUnique Unique
a Unique
b
compare (VirtualRegHi Unique
a) (VirtualRegHi Unique
b) = Unique -> Unique -> Ordering
nonDetCmpUnique Unique
a Unique
b
compare (VirtualRegF Unique
a) (VirtualRegF Unique
b) = Unique -> Unique -> Ordering
nonDetCmpUnique Unique
a Unique
b
compare (VirtualRegD Unique
a) (VirtualRegD Unique
b) = Unique -> Unique -> Ordering
nonDetCmpUnique Unique
a Unique
b
compare VirtualRegI{} VirtualReg
_ = Ordering
LT
compare VirtualReg
_ VirtualRegI{} = Ordering
GT
compare VirtualRegHi{} VirtualReg
_ = Ordering
LT
compare VirtualReg
_ VirtualRegHi{} = Ordering
GT
compare VirtualRegF{} VirtualReg
_ = Ordering
LT
compare VirtualReg
_ VirtualRegF{} = Ordering
GT
instance Uniquable VirtualReg where
getUnique :: VirtualReg -> Unique
getUnique VirtualReg
reg
= case VirtualReg
reg of
VirtualRegI Unique
u -> Unique
u
VirtualRegHi Unique
u -> Unique
u
VirtualRegF Unique
u -> Unique
u
VirtualRegD Unique
u -> Unique
u
instance Outputable VirtualReg where
ppr :: VirtualReg -> SDoc
ppr VirtualReg
reg
= case VirtualReg
reg of
VirtualRegI Unique
u -> String -> SDoc
text String
"%vI_" SDoc -> SDoc -> SDoc
<> Unique -> SDoc
pprUniqueAlways Unique
u
VirtualRegHi Unique
u -> String -> SDoc
text String
"%vHi_" SDoc -> SDoc -> SDoc
<> Unique -> SDoc
pprUniqueAlways Unique
u
VirtualRegF Unique
u -> String -> SDoc
text String
"%vFloat_" SDoc -> SDoc -> SDoc
<> Unique -> SDoc
pprUniqueAlways Unique
u
VirtualRegD Unique
u -> String -> SDoc
text String
"%vDouble_" SDoc -> SDoc -> SDoc
<> Unique -> SDoc
pprUniqueAlways Unique
u
renameVirtualReg :: Unique -> VirtualReg -> VirtualReg
renameVirtualReg :: Unique -> VirtualReg -> VirtualReg
renameVirtualReg Unique
u VirtualReg
r
= case VirtualReg
r of
VirtualRegI Unique
_ -> Unique -> VirtualReg
VirtualRegI Unique
u
VirtualRegHi Unique
_ -> Unique -> VirtualReg
VirtualRegHi Unique
u
VirtualRegF Unique
_ -> Unique -> VirtualReg
VirtualRegF Unique
u
VirtualRegD Unique
_ -> Unique -> VirtualReg
VirtualRegD Unique
u
classOfVirtualReg :: VirtualReg -> RegClass
classOfVirtualReg :: VirtualReg -> RegClass
classOfVirtualReg VirtualReg
vr
= case VirtualReg
vr of
VirtualRegI{} -> RegClass
RcInteger
VirtualRegHi{} -> RegClass
RcInteger
VirtualRegF{} -> RegClass
RcFloat
VirtualRegD{} -> RegClass
RcDouble
getHiVirtualRegFromLo :: VirtualReg -> VirtualReg
getHiVirtualRegFromLo :: VirtualReg -> VirtualReg
getHiVirtualRegFromLo VirtualReg
reg
= case VirtualReg
reg of
VirtualRegI Unique
u -> Unique -> VirtualReg
VirtualRegHi (Unique -> Char -> Unique
newTagUnique Unique
u Char
'H')
VirtualReg
_ -> String -> VirtualReg
forall a. String -> a
panic String
"Reg.getHiVirtualRegFromLo"
getHiVRegFromLo :: Reg -> Reg
getHiVRegFromLo :: Reg -> Reg
getHiVRegFromLo Reg
reg
= case Reg
reg of
RegVirtual VirtualReg
vr -> VirtualReg -> Reg
RegVirtual (VirtualReg -> VirtualReg
getHiVirtualRegFromLo VirtualReg
vr)
RegReal RealReg
_ -> String -> Reg
forall a. String -> a
panic String
"Reg.getHiVRegFromLo"
data RealReg
= RealRegSingle {-# UNPACK #-} !RegNo
| RealRegPair {-# UNPACK #-} !RegNo {-# UNPACK #-} !RegNo
deriving (RealReg -> RealReg -> Bool
(RealReg -> RealReg -> Bool)
-> (RealReg -> RealReg -> Bool) -> Eq RealReg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RealReg -> RealReg -> Bool
$c/= :: RealReg -> RealReg -> Bool
== :: RealReg -> RealReg -> Bool
$c== :: RealReg -> RealReg -> Bool
Eq, Int -> RealReg -> ShowS
[RealReg] -> ShowS
RealReg -> String
(Int -> RealReg -> ShowS)
-> (RealReg -> String) -> ([RealReg] -> ShowS) -> Show RealReg
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RealReg] -> ShowS
$cshowList :: [RealReg] -> ShowS
show :: RealReg -> String
$cshow :: RealReg -> String
showsPrec :: Int -> RealReg -> ShowS
$cshowsPrec :: Int -> RealReg -> ShowS
Show, Eq RealReg
Eq RealReg
-> (RealReg -> RealReg -> Ordering)
-> (RealReg -> RealReg -> Bool)
-> (RealReg -> RealReg -> Bool)
-> (RealReg -> RealReg -> Bool)
-> (RealReg -> RealReg -> Bool)
-> (RealReg -> RealReg -> RealReg)
-> (RealReg -> RealReg -> RealReg)
-> Ord RealReg
RealReg -> RealReg -> Bool
RealReg -> RealReg -> Ordering
RealReg -> RealReg -> RealReg
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RealReg -> RealReg -> RealReg
$cmin :: RealReg -> RealReg -> RealReg
max :: RealReg -> RealReg -> RealReg
$cmax :: RealReg -> RealReg -> RealReg
>= :: RealReg -> RealReg -> Bool
$c>= :: RealReg -> RealReg -> Bool
> :: RealReg -> RealReg -> Bool
$c> :: RealReg -> RealReg -> Bool
<= :: RealReg -> RealReg -> Bool
$c<= :: RealReg -> RealReg -> Bool
< :: RealReg -> RealReg -> Bool
$c< :: RealReg -> RealReg -> Bool
compare :: RealReg -> RealReg -> Ordering
$ccompare :: RealReg -> RealReg -> Ordering
$cp1Ord :: Eq RealReg
Ord)
instance Uniquable RealReg where
getUnique :: RealReg -> Unique
getUnique RealReg
reg
= case RealReg
reg of
RealRegSingle Int
i -> Int -> Unique
mkRegSingleUnique Int
i
RealRegPair Int
r1 Int
r2 -> Int -> Unique
mkRegPairUnique (Int
r1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
65536 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
r2)
instance Outputable RealReg where
ppr :: RealReg -> SDoc
ppr RealReg
reg
= case RealReg
reg of
RealRegSingle Int
i -> String -> SDoc
text String
"%r" SDoc -> SDoc -> SDoc
<> Int -> SDoc
int Int
i
RealRegPair Int
r1 Int
r2 -> String -> SDoc
text String
"%r(" SDoc -> SDoc -> SDoc
<> Int -> SDoc
int Int
r1
SDoc -> SDoc -> SDoc
<> SDoc
vbar SDoc -> SDoc -> SDoc
<> Int -> SDoc
int Int
r2 SDoc -> SDoc -> SDoc
<> String -> SDoc
text String
")"
regNosOfRealReg :: RealReg -> [RegNo]
regNosOfRealReg :: RealReg -> [Int]
regNosOfRealReg RealReg
rr
= case RealReg
rr of
RealRegSingle Int
r1 -> [Int
r1]
RealRegPair Int
r1 Int
r2 -> [Int
r1, Int
r2]
realRegsAlias :: RealReg -> RealReg -> Bool
realRegsAlias :: RealReg -> RealReg -> Bool
realRegsAlias RealReg
rr1 RealReg
rr2
= Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Int] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Int] -> Bool) -> [Int] -> Bool
forall a b. (a -> b) -> a -> b
$ [Int] -> [Int] -> [Int]
forall a. Eq a => [a] -> [a] -> [a]
intersect (RealReg -> [Int]
regNosOfRealReg RealReg
rr1) (RealReg -> [Int]
regNosOfRealReg RealReg
rr2)
data Reg
= RegVirtual !VirtualReg
| RegReal !RealReg
deriving (Reg -> Reg -> Bool
(Reg -> Reg -> Bool) -> (Reg -> Reg -> Bool) -> Eq Reg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Reg -> Reg -> Bool
$c/= :: Reg -> Reg -> Bool
== :: Reg -> Reg -> Bool
$c== :: Reg -> Reg -> Bool
Eq, Eq Reg
Eq Reg
-> (Reg -> Reg -> Ordering)
-> (Reg -> Reg -> Bool)
-> (Reg -> Reg -> Bool)
-> (Reg -> Reg -> Bool)
-> (Reg -> Reg -> Bool)
-> (Reg -> Reg -> Reg)
-> (Reg -> Reg -> Reg)
-> Ord Reg
Reg -> Reg -> Bool
Reg -> Reg -> Ordering
Reg -> Reg -> Reg
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Reg -> Reg -> Reg
$cmin :: Reg -> Reg -> Reg
max :: Reg -> Reg -> Reg
$cmax :: Reg -> Reg -> Reg
>= :: Reg -> Reg -> Bool
$c>= :: Reg -> Reg -> Bool
> :: Reg -> Reg -> Bool
$c> :: Reg -> Reg -> Bool
<= :: Reg -> Reg -> Bool
$c<= :: Reg -> Reg -> Bool
< :: Reg -> Reg -> Bool
$c< :: Reg -> Reg -> Bool
compare :: Reg -> Reg -> Ordering
$ccompare :: Reg -> Reg -> Ordering
$cp1Ord :: Eq Reg
Ord)
regSingle :: RegNo -> Reg
regSingle :: Int -> Reg
regSingle Int
regNo = RealReg -> Reg
RegReal (RealReg -> Reg) -> RealReg -> Reg
forall a b. (a -> b) -> a -> b
$ Int -> RealReg
RealRegSingle Int
regNo
regPair :: RegNo -> RegNo -> Reg
regPair :: Int -> Int -> Reg
regPair Int
regNo1 Int
regNo2 = RealReg -> Reg
RegReal (RealReg -> Reg) -> RealReg -> Reg
forall a b. (a -> b) -> a -> b
$ Int -> Int -> RealReg
RealRegPair Int
regNo1 Int
regNo2
instance Uniquable Reg where
getUnique :: Reg -> Unique
getUnique Reg
reg
= case Reg
reg of
RegVirtual VirtualReg
vr -> VirtualReg -> Unique
forall a. Uniquable a => a -> Unique
getUnique VirtualReg
vr
RegReal RealReg
rr -> RealReg -> Unique
forall a. Uniquable a => a -> Unique
getUnique RealReg
rr
instance Outputable Reg where
ppr :: Reg -> SDoc
ppr Reg
reg
= case Reg
reg of
RegVirtual VirtualReg
vr -> VirtualReg -> SDoc
forall a. Outputable a => a -> SDoc
ppr VirtualReg
vr
RegReal RealReg
rr -> RealReg -> SDoc
forall a. Outputable a => a -> SDoc
ppr RealReg
rr
isRealReg :: Reg -> Bool
isRealReg :: Reg -> Bool
isRealReg Reg
reg
= case Reg
reg of
RegReal RealReg
_ -> Bool
True
RegVirtual VirtualReg
_ -> Bool
False
takeRealReg :: Reg -> Maybe RealReg
takeRealReg :: Reg -> Maybe RealReg
takeRealReg Reg
reg
= case Reg
reg of
RegReal RealReg
rr -> RealReg -> Maybe RealReg
forall a. a -> Maybe a
Just RealReg
rr
Reg
_ -> Maybe RealReg
forall a. Maybe a
Nothing
isVirtualReg :: Reg -> Bool
isVirtualReg :: Reg -> Bool
isVirtualReg Reg
reg
= case Reg
reg of
RegReal RealReg
_ -> Bool
False
RegVirtual VirtualReg
_ -> Bool
True
takeVirtualReg :: Reg -> Maybe VirtualReg
takeVirtualReg :: Reg -> Maybe VirtualReg
takeVirtualReg Reg
reg
= case Reg
reg of
RegReal RealReg
_ -> Maybe VirtualReg
forall a. Maybe a
Nothing
RegVirtual VirtualReg
vr -> VirtualReg -> Maybe VirtualReg
forall a. a -> Maybe a
Just VirtualReg
vr
liftPatchFnToRegReg :: (VirtualReg -> RealReg) -> (Reg -> Reg)
liftPatchFnToRegReg :: (VirtualReg -> RealReg) -> Reg -> Reg
liftPatchFnToRegReg VirtualReg -> RealReg
patchF Reg
reg
= case Reg
reg of
RegVirtual VirtualReg
vr -> RealReg -> Reg
RegReal (VirtualReg -> RealReg
patchF VirtualReg
vr)
RegReal RealReg
_ -> Reg
reg