module GHC.CmmToAsm.Reg.Linear.JoinToTargets (joinToTargets) where
import GHC.Prelude
import GHC.CmmToAsm.Reg.Linear.State
import GHC.CmmToAsm.Reg.Linear.Base
import GHC.CmmToAsm.Reg.Linear.FreeRegs
import GHC.CmmToAsm.Reg.Liveness
import GHC.CmmToAsm.Instr
import GHC.CmmToAsm.Config
import GHC.CmmToAsm.Types
import GHC.Platform.Reg
import GHC.Cmm.BlockId
import GHC.Cmm.Dataflow.Label
import GHC.Data.Graph.Directed
import GHC.Data.Maybe
import GHC.Utils.Panic
import GHC.Utils.Monad (concatMapM)
import GHC.Types.Unique
import GHC.Types.Unique.FM
import GHC.Utils.Outputable
import GHC.CmmToAsm.Format
import GHC.Types.Unique.Set
import Data.Coerce (coerce)
joinToTargets
:: (FR freeRegs, Instruction instr)
=> BlockMap Regs
-> BlockId
-> instr
-> RegM freeRegs ([NatBasicBlock instr]
, instr)
joinToTargets :: forall freeRegs instr.
(FR freeRegs, Instruction instr) =>
BlockMap Regs
-> BlockId -> instr -> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets BlockMap Regs
block_live BlockId
id 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 a. a -> RegM freeRegs a
forall (m :: * -> *) a. Monad m => a -> m a
return ([], instr
instr)
| Bool
otherwise
= BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap Regs
block_live [] BlockId
id instr
instr (instr -> [BlockId]
forall instr. Instruction instr => instr -> [BlockId]
jumpDestsOfInstr instr
instr)
joinToTargets'
:: (FR freeRegs, Instruction instr)
=> BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' :: forall freeRegs instr.
(FR freeRegs, Instruction instr) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap Regs
_ [NatBasicBlock instr]
new_blocks BlockId
_ instr
instr []
= ([NatBasicBlock instr], instr)
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall a. a -> RegM freeRegs a
forall (m :: * -> *) a. Monad m => a -> m a
return ([NatBasicBlock instr]
new_blocks, instr
instr)
joinToTargets' BlockMap Regs
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr (BlockId
dest:[BlockId]
dests)
= do
block_assig <- RegM freeRegs (BlockAssignment freeRegs)
forall freeRegs. RegM freeRegs (BlockAssignment freeRegs)
getBlockAssigR
assig <- getAssigR
let live_set = Maybe Regs -> Regs
forall a. HasCallStack => Maybe a -> a
expectJust (Maybe Regs -> Regs) -> Maybe Regs -> Regs
forall a b. (a -> b) -> a -> b
$ BlockId -> BlockMap Regs -> Maybe Regs
forall a. BlockId -> LabelMap a -> Maybe a
mapLookup BlockId
dest BlockMap Regs
block_live
let still_live Unique
uniq Loc
_ = Unique
uniq Unique -> UniqSet RegWithFormat -> Bool
forall a. Unique -> UniqSet a -> Bool
`elemUniqSet_Directly` Regs -> UniqSet RegWithFormat
getRegs Regs
live_set
let adjusted_assig = (Unique -> Loc -> Bool) -> RegMap Loc -> RegMap Loc
forall {k} elt (key :: k).
(Unique -> elt -> Bool) -> UniqFM key elt -> UniqFM key elt
filterUFM_Directly Unique -> Loc -> Bool
still_live RegMap Loc
assig
let to_free =
[ RealReg
r | (Unique
reg, Loc VLoc
loc Format
_locFmt) <- RegMap Loc -> [(Unique, Loc)]
forall {k} (key :: k) elt. UniqFM key elt -> [(Unique, elt)]
nonDetUFMToList RegMap Loc
assig
, Bool -> Bool
not (Unique -> UniqSet RegWithFormat -> Bool
forall a. Unique -> UniqSet a -> Bool
elemUniqSet_Directly Unique
reg (UniqSet RegWithFormat -> Bool) -> UniqSet RegWithFormat -> Bool
forall a b. (a -> b) -> a -> b
$ Regs -> UniqSet RegWithFormat
getRegs Regs
live_set)
, RealReg
r <- VLoc -> [RealReg]
regsOfLoc VLoc
loc ]
case lookupBlockAssignment dest block_assig of
Maybe (freeRegs, RegMap Loc)
Nothing
-> BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> BlockAssignment freeRegs
-> RegMap Loc
-> [RealReg]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> BlockAssignment freeRegs
-> RegMap Loc
-> [RealReg]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_first
BlockMap Regs
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 (freeRegs
_, RegMap Loc
dest_assig)
-> BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> RegMap Loc
-> RegMap Loc
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall instr freeRegs.
(Instruction instr, FR freeRegs) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> RegMap Loc
-> RegMap Loc
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_again
BlockMap Regs
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)
=> BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> BlockAssignment freeRegs
-> RegMap Loc
-> [RealReg]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_first :: forall freeRegs instr.
(FR freeRegs, Instruction instr) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> BlockAssignment freeRegs
-> RegMap Loc
-> [RealReg]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_first BlockMap Regs
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr BlockId
dest [BlockId]
dests
BlockAssignment freeRegs
block_assig RegMap Loc
src_assig
[RealReg]
to_free
= do config <- RegM freeRegs NCGConfig
forall a. RegM a NCGConfig
getConfig
let platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
freeregs <- getFreeRegsR
let freeregs' = (freeRegs -> RealReg -> freeRegs)
-> freeRegs -> [RealReg] -> freeRegs
forall b a. (b -> a -> b) -> b -> [a] -> b
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
setBlockAssigR (updateBlockAssignment dest (freeregs', src_assig) block_assig)
joinToTargets' block_live new_blocks block_id instr dests
joinToTargets_again :: (Instruction instr, FR freeRegs)
=> BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> UniqFM Reg Loc
-> UniqFM Reg Loc
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_again :: forall instr freeRegs.
(Instruction instr, FR freeRegs) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> BlockId
-> [BlockId]
-> RegMap Loc
-> RegMap Loc
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets_again
BlockMap Regs
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr BlockId
dest [BlockId]
dests
RegMap Loc
src_assig RegMap Loc
dest_assig
| [(Unique, Loc)] -> [(Unique, Loc)] -> Bool
equalIgnoringFormats
(RegMap Loc -> [(Unique, Loc)]
forall {k} (key :: k) elt. UniqFM key elt -> [(Unique, elt)]
nonDetUFMToList RegMap Loc
dest_assig)
(RegMap Loc -> [(Unique, Loc)]
forall {k} (key :: k) elt. UniqFM key elt -> [(Unique, elt)]
nonDetUFMToList RegMap Loc
src_assig)
= BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap Regs
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)]
movementGraphSCCs [Node Loc Unique]
graph
delta <- RegM freeRegs Int
forall freeRegs. RegM freeRegs Int
getDeltaR
fixUpInstrs <- concatMapM (handleComponent delta instr) sccs
fixup_block_id <- mkBlockId <$> getUniqueR
let 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 fixUpInstrs of
[] -> BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap Regs
block_live [NatBasicBlock instr]
new_blocks BlockId
block_id instr
instr [BlockId]
dests
[instr]
_ -> let instr' :: instr
instr' = instr -> (BlockId -> BlockId) -> instr
forall instr.
Instruction instr =>
instr -> (BlockId -> BlockId) -> instr
patchJumpInstr instr
instr
(\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 Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
forall freeRegs instr.
(FR freeRegs, Instruction instr) =>
BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
-> [BlockId]
-> RegM freeRegs ([NatBasicBlock instr], instr)
joinToTargets' BlockMap Regs
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 RegMap Loc
adjusted_assig RegMap Loc
dest_assig
= [ Node Loc Unique
node | (Unique
vreg, Loc
src) <- RegMap Loc -> [(Unique, Loc)]
forall {k} (key :: k) elt. UniqFM key elt -> [(Unique, elt)]
nonDetUFMToList RegMap Loc
adjusted_assig
, Just Loc
loc <- [RegMap Loc -> Unique -> Maybe Loc
forall {k} (key :: k) elt. UniqFM key 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 :: forall a. a -> Loc -> Loc -> [Node Loc a]
expandNode a
vreg src :: Loc
src@(Loc VLoc
srcLoc Format
srcFmt) dst :: Loc
dst@(Loc VLoc
dstLoc Format
dstFmt) =
case (VLoc
srcLoc, VLoc
dstLoc) of
(InReg RealReg
srcReg, InBoth RealReg
dstReg Int
dstMem)
| RealReg
srcReg RealReg -> RealReg -> Bool
forall a. Eq a => a -> a -> Bool
== RealReg
dstReg
-> [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
src [VLoc -> Format -> Loc
Loc (Int -> VLoc
InMem Int
dstMem) Format
dstFmt]]
| Bool
otherwise
-> [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
src [VLoc -> Format -> Loc
Loc (RealReg -> VLoc
InReg RealReg
dstReg) Format
dstFmt
,VLoc -> Format -> Loc
Loc (Int -> VLoc
InMem Int
dstMem) Format
dstFmt]]
(InMem Int
srcMem, InBoth RealReg
dstReg Int
dstMem)
| Int
srcMem Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
dstMem
-> [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
src [VLoc -> Format -> Loc
Loc (RealReg -> VLoc
InReg RealReg
dstReg) Format
dstFmt]]
| Bool
otherwise
-> [a -> Loc -> [Loc] -> Node Loc a
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode a
vreg Loc
src [VLoc -> Format -> Loc
Loc (RealReg -> VLoc
InReg RealReg
dstReg) Format
dstFmt
,VLoc -> Format -> Loc
Loc (Int -> VLoc
InMem Int
dstMem) Format
dstFmt]]
(InBoth RealReg
_ Int
srcMem, InMem Int
dstMem)
| Int
srcMem Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
dstMem
-> []
(InBoth RealReg
srcReg Int
_, InReg RealReg
dstReg)
| RealReg
srcReg RealReg -> RealReg -> Bool
forall a. Eq a => a -> a -> Bool
== RealReg
dstReg
-> []
(InBoth RealReg
srcReg Int
_, VLoc
_)
-> a -> Loc -> Loc -> [Node Loc a]
forall a. a -> Loc -> Loc -> [Node Loc a]
expandNode a
vreg (VLoc -> Format -> Loc
Loc (RealReg -> VLoc
InReg RealReg
srcReg) Format
srcFmt) Loc
dst
(VLoc, VLoc)
_
| VLoc
srcLoc VLoc -> VLoc -> Bool
forall a. Eq a => a -> a -> Bool
== VLoc
dstLoc
-> []
| 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 :: forall instr freeRegs.
Instruction instr =>
Int -> instr -> SCC (Node Loc Unique) -> RegM freeRegs [instr]
handleComponent Int
delta instr
_ (AcyclicSCC (DigraphNode Unique
vreg Loc
src [Loc]
dsts))
= (Loc -> RegM freeRegs [instr]) -> [Loc] -> RegM freeRegs [instr]
forall (m :: * -> *) (f :: * -> *) a b.
(Monad m, Traversable f) =>
(a -> m [b]) -> f a -> m [b]
concatMapM (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 Int
delta instr
instr
(CyclicSCC ((DigraphNode Unique
vreg (Loc (InReg RealReg
sreg) Format
scls) ((Loc (InReg RealReg
dreg) Format
dcls: [Loc]
_))) : [Node Loc Unique]
rest))
= do
(instrSpill, slot)
<- RegWithFormat -> Unique -> RegM freeRegs ([instr], Int)
forall instr freeRegs.
Instruction instr =>
RegWithFormat -> Unique -> RegM freeRegs ([instr], Int)
spillR (Reg -> Format -> RegWithFormat
RegWithFormat (RealReg -> Reg
RegReal RealReg
sreg) Format
scls) Unique
vreg
instrLoad <- loadR (RegWithFormat (RegReal dreg) dcls) slot
remainingFixUps <- mapM (handleComponent delta instr)
(movementGraphSCCs rest)
return (instrSpill ++ concat remainingFixUps ++ instrLoad)
handleComponent Int
_ instr
_ (CyclicSCC [Node Loc Unique]
_)
= String -> RegM freeRegs [instr]
forall a. HasCallStack => String -> a
panic String
"Register Allocator: handleComponent cyclic"
equalIgnoringFormats :: [(Unique, Loc)] -> [(Unique, Loc)] -> Bool
equalIgnoringFormats :: [(Unique, Loc)] -> [(Unique, Loc)] -> Bool
equalIgnoringFormats =
([(Unique, IgnoreFormat Loc)]
-> [(Unique, IgnoreFormat Loc)] -> Bool)
-> [(Unique, Loc)] -> [(Unique, Loc)] -> Bool
forall a b. Coercible a b => a -> b
coerce (([(Unique, IgnoreFormat Loc)]
-> [(Unique, IgnoreFormat Loc)] -> Bool)
-> [(Unique, Loc)] -> [(Unique, Loc)] -> Bool)
-> ([(Unique, IgnoreFormat Loc)]
-> [(Unique, IgnoreFormat Loc)] -> Bool)
-> [(Unique, Loc)]
-> [(Unique, Loc)]
-> Bool
forall a b. (a -> b) -> a -> b
$ forall a. Eq a => a -> a -> Bool
(==) @[(Unique, IgnoreFormat Loc)]
movementGraphSCCs :: [Node Loc Unique] -> [SCC (Node Loc Unique)]
movementGraphSCCs :: [Node Loc Unique] -> [SCC (Node Loc Unique)]
movementGraphSCCs =
([Node (IgnoreFormat Loc) Unique]
-> [SCC (Node (IgnoreFormat Loc) Unique)])
-> [Node Loc Unique] -> [SCC (Node Loc Unique)]
forall a b. Coercible a b => a -> b
coerce (([Node (IgnoreFormat Loc) Unique]
-> [SCC (Node (IgnoreFormat Loc) Unique)])
-> [Node Loc Unique] -> [SCC (Node Loc Unique)])
-> ([Node (IgnoreFormat Loc) Unique]
-> [SCC (Node (IgnoreFormat Loc) Unique)])
-> [Node Loc Unique]
-> [SCC (Node Loc Unique)]
forall a b. (a -> b) -> a -> b
$ forall key payload.
Ord key =>
[Node key payload] -> [SCC (Node key payload)]
stronglyConnCompFromEdgedVerticesOrdR @(IgnoreFormat Loc) @Unique
makeMove
:: Instruction instr
=> Int
-> Unique
-> Loc
-> Loc
-> RegM freeRegs [instr]
makeMove :: forall instr freeRegs.
Instruction instr =>
Int -> Unique -> Loc -> Loc -> RegM freeRegs [instr]
makeMove Int
delta Unique
vreg (Loc VLoc
src Format
_srcFmt) (Loc VLoc
dst Format
dstFmt)
= do config <- RegM freeRegs NCGConfig
forall a. RegM a NCGConfig
getConfig
case (src, dst) of
(InReg RealReg
s, InReg RealReg
d) ->
do SpillReason -> RegM freeRegs ()
forall freeRegs. SpillReason -> RegM freeRegs ()
recordSpill (Unique -> SpillReason
SpillJoinRR Unique
vreg)
[instr] -> RegM freeRegs [instr]
forall a. a -> RegM freeRegs a
forall (m :: * -> *) a. Monad m => a -> m a
return ([instr] -> RegM freeRegs [instr])
-> [instr] -> RegM freeRegs [instr]
forall a b. (a -> b) -> a -> b
$ [NCGConfig -> Format -> Reg -> Reg -> instr
forall instr.
(Instruction instr, HasDebugCallStack) =>
NCGConfig -> Format -> Reg -> Reg -> instr
mkRegRegMoveInstr NCGConfig
config Format
dstFmt (RealReg -> Reg
RegReal RealReg
s) (RealReg -> Reg
RegReal RealReg
d)]
(InMem Int
s, InReg RealReg
d) ->
do SpillReason -> RegM freeRegs ()
forall freeRegs. SpillReason -> RegM freeRegs ()
recordSpill (Unique -> SpillReason
SpillJoinRM Unique
vreg)
[instr] -> RegM freeRegs [instr]
forall a. a -> RegM freeRegs a
forall (m :: * -> *) a. Monad m => a -> m a
return ([instr] -> RegM freeRegs [instr])
-> [instr] -> RegM freeRegs [instr]
forall a b. (a -> b) -> a -> b
$ NCGConfig -> RegWithFormat -> Int -> Int -> [instr]
forall instr.
(Instruction instr, HasDebugCallStack) =>
NCGConfig -> RegWithFormat -> Int -> Int -> [instr]
mkLoadInstr NCGConfig
config (Reg -> Format -> RegWithFormat
RegWithFormat (RealReg -> Reg
RegReal RealReg
d) Format
dstFmt) Int
delta Int
s
(InReg RealReg
s, InMem Int
d) ->
do SpillReason -> RegM freeRegs ()
forall freeRegs. SpillReason -> RegM freeRegs ()
recordSpill (Unique -> SpillReason
SpillJoinRM Unique
vreg)
[instr] -> RegM freeRegs [instr]
forall a. a -> RegM freeRegs a
forall (m :: * -> *) a. Monad m => a -> m a
return ([instr] -> RegM freeRegs [instr])
-> [instr] -> RegM freeRegs [instr]
forall a b. (a -> b) -> a -> b
$ NCGConfig -> RegWithFormat -> Int -> Int -> [instr]
forall instr.
(Instruction instr, HasDebugCallStack) =>
NCGConfig -> RegWithFormat -> Int -> Int -> [instr]
mkSpillInstr NCGConfig
config (Reg -> Format -> RegWithFormat
RegWithFormat (RealReg -> Reg
RegReal RealReg
s) Format
dstFmt) Int
delta Int
d
(VLoc, VLoc)
_ ->
String -> SDoc -> RegM freeRegs [instr]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"makeMove: we don't handle mem->mem moves"
(Unique -> SDoc
forall a. Outputable a => a -> SDoc
ppr Unique
vreg SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (VLoc -> SDoc
forall a. Outputable a => a -> SDoc
ppr VLoc
src) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (VLoc -> SDoc
forall a. Outputable a => a -> SDoc
ppr VLoc
dst))