module RegAlloc.Linear.JoinToTargets (joinToTargets) where
import GhcPrelude
import RegAlloc.Linear.State
import RegAlloc.Linear.Base
import RegAlloc.Linear.FreeRegs
import RegAlloc.Liveness
import Instruction
import Reg
import BlockId
import Hoopl.Collections
import Digraph
import DynFlags
import Outputable
import Unique
import UniqFM
import UniqSet
joinToTargets
:: (FR freeRegs, Instruction instr, Outputable instr)
=> BlockMap RegSet
-> BlockId
-> instr
-> RegM freeRegs ([NatBasicBlock instr]
, instr)
joinToTargets :: BlockMap RegSet
-> BlockId -> instr -> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets block_live :: BlockMap RegSet
block_live id :: BlockId
id instr :: instr
instr
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ instr -> Bool
forall instr. Instruction instr => instr -> Bool
isJumpishInstr instr
instr
= ([NatBasicBlock instr], instr)
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall (m :: * -> *) a. Monad m => a -> m a
return ([], instr
instr)
| Bool
otherwise
= BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr, Outputable instr) =>
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap RegSet
block_live [] BlockId
id instr
instr (instr -> [BlockId]
forall instr. Instruction instr => instr -> [BlockId]
jumpDestsOfInstr instr
instr)
joinToTargets'
:: (FR freeRegs, Instruction instr, Outputable instr)
=> BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' :: BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' _ new_blocks :: [NatBasicBlock instr]
new_blocks _ instr :: instr
instr []
= ([NatBasicBlock instr], instr)
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall (m :: * -> *) a. Monad m => a -> m a
return ([NatBasicBlock instr]
new_blocks, instr
instr)
joinToTargets' block_live :: BlockMap RegSet
block_live new_blocks :: [NatBasicBlock instr]
new_blocks block_id :: BlockId
block_id instr :: instr
instr (dest :: BlockId
dest:dests :: [BlockId]
dests)
= do
BlockAssignment freeRegs
block_assig <- RegM freeRegs (BlockAssignment freeRegs)
forall freeRegs. RegM freeRegs (BlockAssignment freeRegs)
getBlockAssigR
RegMap Loc
assig <- RegM freeRegs (RegMap Loc)
forall freeRegs. RegM freeRegs (RegMap Loc)
getAssigR
let Just live_set :: RegSet
live_set = KeyOf LabelMap -> BlockMap RegSet -> Maybe RegSet
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
dest BlockMap RegSet
block_live
let still_live :: Unique -> p -> Bool
still_live uniq :: Unique
uniq _ = Unique
uniq Unique -> RegSet -> Bool
forall a. Unique -> UniqSet a -> Bool
`elemUniqSet_Directly` RegSet
live_set
let adjusted_assig :: RegMap Loc
adjusted_assig = (Unique -> Loc -> Bool) -> RegMap Loc -> RegMap Loc
forall elt. (Unique -> elt -> Bool) -> UniqFM elt -> UniqFM elt
filterUFM_Directly Unique -> Loc -> Bool
forall p. Unique -> p -> Bool
still_live RegMap Loc
assig
let to_free :: [RealReg]
to_free =
[ RealReg
r | (reg :: Unique
reg, loc :: Loc
loc) <- RegMap Loc -> [(Unique, Loc)]
forall elt. UniqFM elt -> [(Unique, elt)]
nonDetUFMToList RegMap Loc
assig
, Bool -> Bool
not (Unique -> RegSet -> Bool
forall a. Unique -> UniqSet a -> Bool
elemUniqSet_Directly Unique
reg RegSet
live_set)
, RealReg
r <- Loc -> [RealReg]
regsOfLoc Loc
loc ]
case KeyOf LabelMap
-> BlockAssignment freeRegs -> Maybe (freeRegs, RegMap Loc)
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
dest BlockAssignment freeRegs
block_assig of
Nothing
-> BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> BlockAssignment freeRegs
-> RegMap Loc
-> [RealReg]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr, Outputable instr) =>
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> BlockAssignment freeRegs
-> RegMap Loc
-> [RealReg]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_first
BlockMap RegSet
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr BlockId
dest [BlockId]
dests
BlockAssignment freeRegs
block_assig RegMap Loc
adjusted_assig [RealReg]
to_free
Just (_, dest_assig :: RegMap Loc
dest_assig)
-> BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> RegMap Loc
-> RegMap Loc
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall instr freeRegs.
(Instruction instr, FR freeRegs, Outputable instr) =>
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> RegMap Loc
-> RegMap Loc
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_again
BlockMap RegSet
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr BlockId
dest [BlockId]
dests
RegMap Loc
adjusted_assig RegMap Loc
dest_assig
joinToTargets_first :: (FR freeRegs, Instruction instr, Outputable instr)
=> BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> BlockAssignment freeRegs
-> RegMap Loc
-> [RealReg]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_first :: BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> BlockAssignment freeRegs
-> RegMap Loc
-> [RealReg]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_first block_live :: BlockMap RegSet
block_live new_blocks :: [NatBasicBlock instr]
new_blocks block_id :: BlockId
block_id instr :: instr
instr dest :: BlockId
dest dests :: [BlockId]
dests
block_assig :: BlockAssignment freeRegs
block_assig src_assig :: RegMap Loc
src_assig
to_free :: [RealReg]
to_free
= do DynFlags
dflags <- RegM freeRegs DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
let platform :: Platform
platform = DynFlags -> Platform
targetPlatform DynFlags
dflags
freeRegs
freeregs <- RegM freeRegs freeRegs
forall freeRegs. RegM freeRegs freeRegs
getFreeRegsR
let freeregs' :: freeRegs
freeregs' = (freeRegs -> RealReg -> freeRegs)
-> freeRegs -> [RealReg] -> freeRegs
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((RealReg -> freeRegs -> freeRegs)
-> freeRegs -> RealReg -> freeRegs
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((RealReg -> freeRegs -> freeRegs)
-> freeRegs -> RealReg -> freeRegs)
-> (RealReg -> freeRegs -> freeRegs)
-> freeRegs
-> RealReg
-> freeRegs
forall a b. (a -> b) -> a -> b
$ Platform -> RealReg -> freeRegs -> freeRegs
forall freeRegs.
FR freeRegs =>
Platform -> RealReg -> freeRegs -> freeRegs
frReleaseReg Platform
platform) freeRegs
freeregs [RealReg]
to_free
BlockAssignment freeRegs -> RegM freeRegs ()
forall freeRegs. BlockAssignment freeRegs -> RegM freeRegs ()
setBlockAssigR (KeyOf LabelMap
-> (freeRegs, RegMap Loc)
-> BlockAssignment freeRegs
-> BlockAssignment freeRegs
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> a -> map a -> map a
mapInsert KeyOf LabelMap
BlockId
dest (freeRegs
freeregs', RegMap Loc
src_assig) BlockAssignment freeRegs
block_assig)
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr, Outputable instr) =>
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap RegSet
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr [BlockId]
dests
joinToTargets_again :: (Instruction instr, FR freeRegs, Outputable instr)
=> BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> UniqFM Loc
-> UniqFM Loc
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_again :: BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> RegMap Loc
-> RegMap Loc
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_again
block_live :: BlockMap RegSet
block_live new_blocks :: [NatBasicBlock instr]
new_blocks block_id :: BlockId
block_id instr :: instr
instr dest :: BlockId
dest dests :: [BlockId]
dests
src_assig :: RegMap Loc
src_assig dest_assig :: RegMap Loc
dest_assig
| RegMap Loc -> [(Unique, Loc)]
forall elt. UniqFM elt -> [(Unique, elt)]
nonDetUFMToList RegMap Loc
dest_assig [(Unique, Loc)] -> [(Unique, Loc)] -> Bool
forall a. Eq a => a -> a -> Bool
== RegMap Loc -> [(Unique, Loc)]
forall elt. UniqFM elt -> [(Unique, elt)]
nonDetUFMToList RegMap Loc
src_assig
= BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr, Outputable instr) =>
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap RegSet
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr [BlockId]
dests
| Bool
otherwise
= do
let graph :: [Node Loc Unique]
graph = RegMap Loc -> RegMap Loc -> [Node Loc Unique]
makeRegMovementGraph RegMap Loc
src_assig RegMap Loc
dest_assig
let sccs :: [SCC (Node Loc Unique)]
sccs = [Node Loc Unique] -> [SCC (Node Loc Unique)]
forall key payload.
Ord key =>
[Node key payload] -> [SCC (Node key payload)]
stronglyConnCompFromEdgedVerticesOrdR [Node Loc Unique]
graph
Int
delta <- RegM freeRegs Int
forall freeRegs. RegM freeRegs Int
getDeltaR
[[instr]]
fixUpInstrs_ <- (SCC (Node Loc Unique) -> RegM freeRegs [instr])
-> [SCC (Node Loc Unique)] -> RegM freeRegs [[instr]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Int -> instr -> SCC (Node Loc Unique) -> RegM freeRegs [instr]
forall instr freeRegs.
Instruction instr =>
Int -> instr -> SCC (Node Loc Unique) -> RegM freeRegs [instr]
handleComponent Int
delta instr
instr) [SCC (Node Loc Unique)]
sccs
let fixUpInstrs :: [instr]
fixUpInstrs = [[instr]] -> [instr]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[instr]]
fixUpInstrs_
BlockId
fixup_block_id <- Unique -> BlockId
mkBlockId (Unique -> BlockId)
-> RegM freeRegs Unique -> RegM freeRegs BlockId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RegM freeRegs Unique
forall freeRegs. RegM freeRegs Unique
getUniqueR
let block :: NatBasicBlock instr
block = BlockId -> [instr] -> NatBasicBlock instr
forall i. BlockId -> [i] -> GenBasicBlock i
BasicBlock BlockId
fixup_block_id
([instr] -> NatBasicBlock instr) -> [instr] -> NatBasicBlock instr
forall a b. (a -> b) -> a -> b
$ [instr]
fixUpInstrs [instr] -> [instr] -> [instr]
forall a. [a] -> [a] -> [a]
++ BlockId -> [instr]
forall instr. Instruction instr => BlockId -> [instr]
mkJumpInstr BlockId
dest
case [instr]
fixUpInstrs of
[] -> BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr, Outputable instr) =>
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap RegSet
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr [BlockId]
dests
_ -> let instr' :: instr
instr' = instr -> (BlockId -> BlockId) -> instr
forall instr.
Instruction instr =>
instr -> (BlockId -> BlockId) -> instr
patchJumpInstr instr
instr
(\bid :: BlockId
bid -> if BlockId
bid BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
dest
then BlockId
fixup_block_id
else BlockId
bid)
in do
BlockId -> BlockId -> BlockId -> RegM freeRegs ()
forall freeRegs. BlockId -> BlockId -> BlockId -> RegM freeRegs ()
recordFixupBlock BlockId
block_id BlockId
fixup_block_id BlockId
dest
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr, Outputable instr) =>
BlockMap RegSet
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap RegSet
block_live (NatBasicBlock instr
block NatBasicBlock instr
-> [NatBasicBlock instr] -> [NatBasicBlock instr]
forall a. a -> [a] -> [a]
: [NatBasicBlock instr]
new_blocks)
BlockId
block_id instr
instr' [BlockId]
dests
makeRegMovementGraph :: RegMap Loc -> RegMap Loc -> [Node Loc Unique]
makeRegMovementGraph :: RegMap Loc -> RegMap Loc -> [Node Loc Unique]
makeRegMovementGraph adjusted_assig :: RegMap Loc
adjusted_assig dest_assig :: RegMap Loc
dest_assig
= [ Node Loc Unique
node | (vreg :: Unique
vreg, src :: Loc
src) <- RegMap Loc -> [(Unique, Loc)]
forall elt. UniqFM elt -> [(Unique, elt)]
nonDetUFMToList RegMap Loc
adjusted_assig
, Just loc :: Loc
loc <- [RegMap Loc -> Unique -> Maybe Loc
forall elt. UniqFM elt -> Unique -> Maybe elt
lookupUFM_Directly RegMap Loc
dest_assig Unique
vreg]
, Node Loc Unique
node <- Unique -> Loc -> Loc -> [Node Loc Unique]
forall a. a -> Loc -> Loc -> [Node Loc a]
expandNode Unique
vreg Loc
src Loc
loc ]
expandNode
:: a
-> Loc
-> Loc
-> [Node Loc a ]
expandNode :: a -> Loc -> Loc -> [Node Loc a]
expandNode vreg :: a
vreg loc :: Loc
loc@(InReg src :: RealReg
src) (InBoth dst :: RealReg
dst mem :: Int
mem)
| RealReg
src RealReg -> RealReg -> Bool
forall a. Eq a => a -> a -> Bool
== RealReg
dst = [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
loc [Int -> Loc
InMem Int
mem]]
| Bool
otherwise = [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
loc [RealReg -> Loc
InReg RealReg
dst, Int -> Loc
InMem Int
mem]]
expandNode vreg :: a
vreg loc :: Loc
loc@(InMem src :: Int
src) (InBoth dst :: RealReg
dst mem :: Int
mem)
| Int
src Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
mem = [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
loc [RealReg -> Loc
InReg RealReg
dst]]
| Bool
otherwise = [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
loc [RealReg -> Loc
InReg RealReg
dst, Int -> Loc
InMem Int
mem]]
expandNode _ (InBoth _ src :: Int
src) (InMem dst :: Int
dst)
| Int
src Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
dst = []
expandNode _ (InBoth src :: RealReg
src _) (InReg dst :: RealReg
dst)
| RealReg
src RealReg -> RealReg -> Bool
forall a. Eq a => a -> a -> Bool
== RealReg
dst = []
expandNode vreg :: a
vreg (InBoth src :: RealReg
src _) dst :: Loc
dst
= a -> Loc -> Loc -> [Node Loc a]
forall a. a -> Loc -> Loc -> [Node Loc a]
expandNode a
vreg (RealReg -> Loc
InReg RealReg
src) Loc
dst
expandNode vreg :: a
vreg src :: Loc
src dst :: Loc
dst
| Loc
src Loc -> Loc -> Bool
forall a. Eq a => a -> a -> Bool
== Loc
dst = []
| Bool
otherwise = [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
src [Loc
dst]]
handleComponent
:: Instruction instr
=> Int -> instr -> SCC (Node Loc Unique)
-> RegM freeRegs [instr]
handleComponent :: Int -> instr -> SCC (Node Loc Unique) -> RegM freeRegs [instr]
handleComponent delta :: Int
delta _ (AcyclicSCC (DigraphNode vreg :: Unique
vreg src :: Loc
src dsts :: [Loc]
dsts))
= (Loc -> RegM freeRegs instr) -> [Loc] -> RegM freeRegs [instr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Int -> Unique -> Loc -> Loc -> RegM freeRegs instr
forall instr freeRegs.
Instruction instr =>
Int -> Unique -> Loc -> Loc -> RegM freeRegs instr
makeMove Int
delta Unique
vreg Loc
src) [Loc]
dsts
handleComponent delta :: Int
delta instr :: instr
instr
(CyclicSCC ((DigraphNode vreg :: Unique
vreg (InReg sreg :: RealReg
sreg) ((InReg dreg :: RealReg
dreg: _))) : rest :: [Node Loc Unique]
rest))
= do
(instrSpill :: instr
instrSpill, slot :: Int
slot)
<- Reg -> Unique -> RegM freeRegs (instr, Int)
forall instr freeRegs.
Instruction instr =>
Reg -> Unique -> RegM freeRegs (instr, Int)
spillR (RealReg -> Reg
RegReal RealReg
sreg) Unique
vreg
instr
instrLoad <- Reg -> Int -> RegM freeRegs instr
forall instr freeRegs.
Instruction instr =>
Reg -> Int -> RegM freeRegs instr
loadR (RealReg -> Reg
RegReal RealReg
dreg) Int
slot
[[instr]]
remainingFixUps <- (SCC (Node Loc Unique) -> RegM freeRegs [instr])
-> [SCC (Node Loc Unique)] -> RegM freeRegs [[instr]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Int -> instr -> SCC (Node Loc Unique) -> RegM freeRegs [instr]
forall instr freeRegs.
Instruction instr =>
Int -> instr -> SCC (Node Loc Unique) -> RegM freeRegs [instr]
handleComponent Int
delta instr
instr)
([Node Loc Unique] -> [SCC (Node Loc Unique)]
forall key payload.
Ord key =>
[Node key payload] -> [SCC (Node key payload)]
stronglyConnCompFromEdgedVerticesOrdR [Node Loc Unique]
rest)
[instr] -> RegM freeRegs [instr]
forall (m :: * -> *) a. Monad m => a -> m a
return ([instr
instrSpill] [instr] -> [instr] -> [instr]
forall a. [a] -> [a] -> [a]
++ [[instr]] -> [instr]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[instr]]
remainingFixUps [instr] -> [instr] -> [instr]
forall a. [a] -> [a] -> [a]
++ [instr
instrLoad])
handleComponent _ _ (CyclicSCC _)
= String -> RegM freeRegs [instr]
forall a. String -> a
panic "Register Allocator: handleComponent cyclic"
makeMove
:: Instruction instr
=> Int
-> Unique
-> Loc
-> Loc
-> RegM freeRegs instr
makeMove :: Int -> Unique -> Loc -> Loc -> RegM freeRegs instr
makeMove delta :: Int
delta vreg :: Unique
vreg src :: Loc
src dst :: Loc
dst
= do DynFlags
dflags <- RegM freeRegs DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
let platform :: Platform
platform = DynFlags -> Platform
targetPlatform DynFlags
dflags
case (Loc
src, Loc
dst) of
(InReg s :: RealReg
s, InReg d :: RealReg
d) ->
do SpillReason -> RegM freeRegs ()
forall freeRegs. SpillReason -> RegM freeRegs ()
recordSpill (Unique -> SpillReason
SpillJoinRR Unique
vreg)
instr -> RegM freeRegs instr
forall (m :: * -> *) a. Monad m => a -> m a
return (instr -> RegM freeRegs instr) -> instr -> RegM freeRegs instr
forall a b. (a -> b) -> a -> b
$ Platform -> Reg -> Reg -> instr
forall instr. Instruction instr => Platform -> Reg -> Reg -> instr
mkRegRegMoveInstr Platform
platform (RealReg -> Reg
RegReal RealReg
s) (RealReg -> Reg
RegReal RealReg
d)
(InMem s :: Int
s, InReg d :: RealReg
d) ->
do SpillReason -> RegM freeRegs ()
forall freeRegs. SpillReason -> RegM freeRegs ()
recordSpill (Unique -> SpillReason
SpillJoinRM Unique
vreg)
instr -> RegM freeRegs instr
forall (m :: * -> *) a. Monad m => a -> m a
return (instr -> RegM freeRegs instr) -> instr -> RegM freeRegs instr
forall a b. (a -> b) -> a -> b
$ DynFlags -> Reg -> Int -> Int -> instr
forall instr.
Instruction instr =>
DynFlags -> Reg -> Int -> Int -> instr
mkLoadInstr DynFlags
dflags (RealReg -> Reg
RegReal RealReg
d) Int
delta Int
s
(InReg s :: RealReg
s, InMem d :: Int
d) ->
do SpillReason -> RegM freeRegs ()
forall freeRegs. SpillReason -> RegM freeRegs ()
recordSpill (Unique -> SpillReason
SpillJoinRM Unique
vreg)
instr -> RegM freeRegs instr
forall (m :: * -> *) a. Monad m => a -> m a
return (instr -> RegM freeRegs instr) -> instr -> RegM freeRegs instr
forall a b. (a -> b) -> a -> b
$ DynFlags -> Reg -> Int -> Int -> instr
forall instr.
Instruction instr =>
DynFlags -> Reg -> Int -> Int -> instr
mkSpillInstr DynFlags
dflags (RealReg -> Reg
RegReal RealReg
s) Int
delta Int
d
_ ->
String -> RegM freeRegs instr
forall a. String -> a
panic ("makeMove " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Unique -> String
forall a. Show a => a -> String
show Unique
vreg String -> String -> String
forall a. [a] -> [a] -> [a]
++ " (" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Loc -> String
forall a. Show a => a -> String
show Loc
src String -> String -> String
forall a. [a] -> [a] -> [a]
++ ") ("
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Loc -> String
forall a. Show a => a -> String
show Loc
dst String -> String -> String
forall a. [a] -> [a] -> [a]
++ ")"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ " we don't handle mem->mem moves.")