{-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-}
{-# LANGUAGE ScopedTypeVariables #-}

#if !defined(GHC_LOADED_INTO_GHCI)
{-# LANGUAGE UnboxedTuples #-}
#endif

-- | State monad for the linear register allocator.

--      Here we keep all the state that the register allocator keeps track
--      of as it walks the instructions in a basic block.

module GHC.CmmToAsm.Reg.Linear.State (
        RA_State(..),
        RegM,
        runR,

        spillR,
        loadR,

        getFreeRegsR,
        setFreeRegsR,

        getAssigR,
        setAssigR,

        getBlockAssigR,
        setBlockAssigR,

        setDeltaR,
        getDeltaR,

        getUniqueR,
        getConfig,
        getPlatform,

        recordSpill,
        recordFixupBlock
)
where

import GHC.Prelude

import GHC.CmmToAsm.Reg.Linear.Stats
import GHC.CmmToAsm.Reg.Linear.StackMap
import GHC.CmmToAsm.Reg.Linear.Base
import GHC.CmmToAsm.Reg.Liveness
import GHC.CmmToAsm.Instr
import GHC.CmmToAsm.Config
import GHC.Platform.Reg
import GHC.Cmm.BlockId

import GHC.Platform
import GHC.Types.Unique
import GHC.Types.Unique.Supply

import Control.Monad (ap)

-- Avoids using unboxed tuples when loading into GHCi
#if !defined(GHC_LOADED_INTO_GHCI)

type RA_Result freeRegs a = (# RA_State freeRegs, a #)

pattern RA_Result :: a -> b -> (# a, b #)
pattern $mRA_Result :: forall {r} {a} {b}.
(# a, b #) -> (a -> b -> r) -> (Void# -> r) -> r
$bRA_Result :: forall a b. a -> b -> (# a, b #)
RA_Result a b = (# a, b #)
{-# COMPLETE RA_Result #-}
#else

data RA_Result freeRegs a = RA_Result {-# UNPACK #-} !(RA_State freeRegs) !a
  deriving (Functor)

#endif

-- | The register allocator monad type.
newtype RegM freeRegs a
        = RegM { forall freeRegs a.
RegM freeRegs a -> RA_State freeRegs -> RA_Result freeRegs a
unReg :: RA_State freeRegs -> RA_Result freeRegs a }
        deriving ((forall a b. (a -> b) -> RegM freeRegs a -> RegM freeRegs b)
-> (forall a b. a -> RegM freeRegs b -> RegM freeRegs a)
-> Functor (RegM freeRegs)
forall a b. a -> RegM freeRegs b -> RegM freeRegs a
forall a b. (a -> b) -> RegM freeRegs a -> RegM freeRegs b
forall freeRegs a b. a -> RegM freeRegs b -> RegM freeRegs a
forall freeRegs a b. (a -> b) -> RegM freeRegs a -> RegM freeRegs b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> RegM freeRegs b -> RegM freeRegs a
$c<$ :: forall freeRegs a b. a -> RegM freeRegs b -> RegM freeRegs a
fmap :: forall a b. (a -> b) -> RegM freeRegs a -> RegM freeRegs b
$cfmap :: forall freeRegs a b. (a -> b) -> RegM freeRegs a -> RegM freeRegs b
Functor)

instance Applicative (RegM freeRegs) where
      pure :: forall a. a -> RegM freeRegs a
pure a
a  =  (RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a)
-> (RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
forall a b. (a -> b) -> a -> b
$ \RA_State freeRegs
s -> RA_State freeRegs -> a -> RA_Result freeRegs a
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s a
a
      <*> :: forall a b.
RegM freeRegs (a -> b) -> RegM freeRegs a -> RegM freeRegs b
(<*>) = RegM freeRegs (a -> b) -> RegM freeRegs a -> RegM freeRegs b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap

instance Monad (RegM freeRegs) where
  RegM freeRegs a
m >>= :: forall a b.
RegM freeRegs a -> (a -> RegM freeRegs b) -> RegM freeRegs b
>>= a -> RegM freeRegs b
k   =  (RA_State freeRegs -> RA_Result freeRegs b) -> RegM freeRegs b
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs b) -> RegM freeRegs b)
-> (RA_State freeRegs -> RA_Result freeRegs b) -> RegM freeRegs b
forall a b. (a -> b) -> a -> b
$ \RA_State freeRegs
s -> case RegM freeRegs a -> RA_State freeRegs -> RA_Result freeRegs a
forall freeRegs a.
RegM freeRegs a -> RA_State freeRegs -> RA_Result freeRegs a
unReg RegM freeRegs a
m RA_State freeRegs
s of { RA_Result RA_State freeRegs
s a
a -> RegM freeRegs b -> RA_State freeRegs -> RA_Result freeRegs b
forall freeRegs a.
RegM freeRegs a -> RA_State freeRegs -> RA_Result freeRegs a
unReg (a -> RegM freeRegs b
k a
a) RA_State freeRegs
s }

-- | Get native code generator configuration
getConfig :: RegM a NCGConfig
getConfig :: forall a. RegM a NCGConfig
getConfig = (RA_State a -> RA_Result a NCGConfig) -> RegM a NCGConfig
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State a -> RA_Result a NCGConfig) -> RegM a NCGConfig)
-> (RA_State a -> RA_Result a NCGConfig) -> RegM a NCGConfig
forall a b. (a -> b) -> a -> b
$ \RA_State a
s -> RA_State a -> NCGConfig -> RA_Result a NCGConfig
forall a b. a -> b -> (# a, b #)
RA_Result RA_State a
s (RA_State a -> NCGConfig
forall freeRegs. RA_State freeRegs -> NCGConfig
ra_config RA_State a
s)

-- | Get target platform from native code generator configuration
getPlatform :: RegM a Platform
getPlatform :: forall a. RegM a Platform
getPlatform = NCGConfig -> Platform
ncgPlatform (NCGConfig -> Platform) -> RegM a NCGConfig -> RegM a Platform
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RegM a NCGConfig
forall a. RegM a NCGConfig
getConfig

-- | Run a computation in the RegM register allocator monad.
runR    :: NCGConfig
        -> BlockAssignment freeRegs
        -> freeRegs
        -> RegMap Loc
        -> StackMap
        -> UniqSupply
        -> RegM freeRegs a
        -> (BlockAssignment freeRegs, StackMap, RegAllocStats, a)

runR :: forall freeRegs a.
NCGConfig
-> BlockAssignment freeRegs
-> freeRegs
-> RegMap Loc
-> StackMap
-> UniqSupply
-> RegM freeRegs a
-> (BlockAssignment freeRegs, StackMap, RegAllocStats, a)
runR NCGConfig
config BlockAssignment freeRegs
block_assig freeRegs
freeregs RegMap Loc
assig StackMap
stack UniqSupply
us RegM freeRegs a
thing =
  case RegM freeRegs a -> RA_State freeRegs -> RA_Result freeRegs a
forall freeRegs a.
RegM freeRegs a -> RA_State freeRegs -> RA_Result freeRegs a
unReg RegM freeRegs a
thing
        (RA_State :: forall freeRegs.
BlockAssignment freeRegs
-> freeRegs
-> RegMap Loc
-> Int
-> StackMap
-> UniqSupply
-> [SpillReason]
-> NCGConfig
-> [(BlockId, BlockId, BlockId)]
-> RA_State freeRegs
RA_State
                { ra_blockassig :: BlockAssignment freeRegs
ra_blockassig = BlockAssignment freeRegs
block_assig
                , ra_freeregs :: freeRegs
ra_freeregs   = freeRegs
freeregs
                , ra_assig :: RegMap Loc
ra_assig      = RegMap Loc
assig
                , ra_delta :: Int
ra_delta      = Int
0{-???-}
                , ra_stack :: StackMap
ra_stack      = StackMap
stack
                , ra_us :: UniqSupply
ra_us         = UniqSupply
us
                , ra_spills :: [SpillReason]
ra_spills     = []
                , ra_config :: NCGConfig
ra_config     = NCGConfig
config
                , ra_fixups :: [(BlockId, BlockId, BlockId)]
ra_fixups     = [] })
   of
        RA_Result RA_State freeRegs
state a
returned_thing
         ->     (RA_State freeRegs -> BlockAssignment freeRegs
forall freeRegs. RA_State freeRegs -> BlockAssignment freeRegs
ra_blockassig RA_State freeRegs
state, RA_State freeRegs -> StackMap
forall freeRegs. RA_State freeRegs -> StackMap
ra_stack RA_State freeRegs
state, RA_State freeRegs -> RegAllocStats
forall freeRegs. RA_State freeRegs -> RegAllocStats
makeRAStats RA_State freeRegs
state, a
returned_thing)


-- | Make register allocator stats from its final state.
makeRAStats :: RA_State freeRegs -> RegAllocStats
makeRAStats :: forall freeRegs. RA_State freeRegs -> RegAllocStats
makeRAStats RA_State freeRegs
state
        = RegAllocStats :: UniqFM Unique [Int]
-> [(BlockId, BlockId, BlockId)] -> RegAllocStats
RegAllocStats
        { ra_spillInstrs :: UniqFM Unique [Int]
ra_spillInstrs        = [SpillReason] -> UniqFM Unique [Int]
binSpillReasons (RA_State freeRegs -> [SpillReason]
forall freeRegs. RA_State freeRegs -> [SpillReason]
ra_spills RA_State freeRegs
state)
        , ra_fixupList :: [(BlockId, BlockId, BlockId)]
ra_fixupList          = RA_State freeRegs -> [(BlockId, BlockId, BlockId)]
forall freeRegs. RA_State freeRegs -> [(BlockId, BlockId, BlockId)]
ra_fixups RA_State freeRegs
state }


spillR :: Instruction instr
       => Reg -> Unique -> RegM freeRegs (instr, Int)

spillR :: forall instr freeRegs.
Instruction instr =>
Reg -> Unique -> RegM freeRegs (instr, Int)
spillR Reg
reg Unique
temp = (RA_State freeRegs -> RA_Result freeRegs (instr, Int))
-> RegM freeRegs (instr, Int)
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs (instr, Int))
 -> RegM freeRegs (instr, Int))
-> (RA_State freeRegs -> RA_Result freeRegs (instr, Int))
-> RegM freeRegs (instr, Int)
forall a b. (a -> b) -> a -> b
$ \RA_State freeRegs
s ->
  let (StackMap
stack1,Int
slot) = StackMap -> Unique -> (StackMap, Int)
getStackSlotFor (RA_State freeRegs -> StackMap
forall freeRegs. RA_State freeRegs -> StackMap
ra_stack RA_State freeRegs
s) Unique
temp
      instr :: instr
instr  = NCGConfig -> Reg -> Int -> Int -> instr
forall instr.
Instruction instr =>
NCGConfig -> Reg -> Int -> Int -> instr
mkSpillInstr (RA_State freeRegs -> NCGConfig
forall freeRegs. RA_State freeRegs -> NCGConfig
ra_config RA_State freeRegs
s) Reg
reg (RA_State freeRegs -> Int
forall freeRegs. RA_State freeRegs -> Int
ra_delta RA_State freeRegs
s) Int
slot
  in
  RA_State freeRegs
-> (instr, Int) -> RA_Result freeRegs (instr, Int)
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s{ra_stack :: StackMap
ra_stack=StackMap
stack1} (instr
instr,Int
slot)


loadR :: Instruction instr
      => Reg -> Int -> RegM freeRegs instr

loadR :: forall instr freeRegs.
Instruction instr =>
Reg -> Int -> RegM freeRegs instr
loadR Reg
reg Int
slot = (RA_State freeRegs -> RA_Result freeRegs instr)
-> RegM freeRegs instr
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs instr)
 -> RegM freeRegs instr)
-> (RA_State freeRegs -> RA_Result freeRegs instr)
-> RegM freeRegs instr
forall a b. (a -> b) -> a -> b
$ \RA_State freeRegs
s ->
  RA_State freeRegs -> instr -> RA_Result freeRegs instr
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s (NCGConfig -> Reg -> Int -> Int -> instr
forall instr.
Instruction instr =>
NCGConfig -> Reg -> Int -> Int -> instr
mkLoadInstr (RA_State freeRegs -> NCGConfig
forall freeRegs. RA_State freeRegs -> NCGConfig
ra_config RA_State freeRegs
s) Reg
reg (RA_State freeRegs -> Int
forall freeRegs. RA_State freeRegs -> Int
ra_delta RA_State freeRegs
s) Int
slot)

getFreeRegsR :: RegM freeRegs freeRegs
getFreeRegsR :: forall freeRegs. RegM freeRegs freeRegs
getFreeRegsR = (RA_State freeRegs -> RA_Result freeRegs freeRegs)
-> RegM freeRegs freeRegs
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs freeRegs)
 -> RegM freeRegs freeRegs)
-> (RA_State freeRegs -> RA_Result freeRegs freeRegs)
-> RegM freeRegs freeRegs
forall a b. (a -> b) -> a -> b
$ \ s :: RA_State freeRegs
s@RA_State{ra_freeregs :: forall freeRegs. RA_State freeRegs -> freeRegs
ra_freeregs = freeRegs
freeregs} ->
  RA_State freeRegs -> freeRegs -> RA_Result freeRegs freeRegs
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s freeRegs
freeregs

setFreeRegsR :: freeRegs -> RegM freeRegs ()
setFreeRegsR :: forall freeRegs. freeRegs -> RegM freeRegs ()
setFreeRegsR freeRegs
regs = (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ())
-> (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall a b. (a -> b) -> a -> b
$ \ RA_State freeRegs
s ->
  RA_State freeRegs -> () -> RA_Result freeRegs ()
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s{ra_freeregs :: freeRegs
ra_freeregs = freeRegs
regs} ()

getAssigR :: RegM freeRegs (RegMap Loc)
getAssigR :: forall freeRegs. RegM freeRegs (RegMap Loc)
getAssigR = (RA_State freeRegs -> RA_Result freeRegs (RegMap Loc))
-> RegM freeRegs (RegMap Loc)
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs (RegMap Loc))
 -> RegM freeRegs (RegMap Loc))
-> (RA_State freeRegs -> RA_Result freeRegs (RegMap Loc))
-> RegM freeRegs (RegMap Loc)
forall a b. (a -> b) -> a -> b
$ \ s :: RA_State freeRegs
s@RA_State{ra_assig :: forall freeRegs. RA_State freeRegs -> RegMap Loc
ra_assig = RegMap Loc
assig} ->
  RA_State freeRegs -> RegMap Loc -> RA_Result freeRegs (RegMap Loc)
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s RegMap Loc
assig

setAssigR :: RegMap Loc -> RegM freeRegs ()
setAssigR :: forall freeRegs. RegMap Loc -> RegM freeRegs ()
setAssigR RegMap Loc
assig = (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ())
-> (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall a b. (a -> b) -> a -> b
$ \ RA_State freeRegs
s ->
  RA_State freeRegs -> () -> RA_Result freeRegs ()
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s{ra_assig :: RegMap Loc
ra_assig=RegMap Loc
assig} ()

getBlockAssigR :: RegM freeRegs (BlockAssignment freeRegs)
getBlockAssigR :: forall freeRegs. RegM freeRegs (BlockAssignment freeRegs)
getBlockAssigR = (RA_State freeRegs
 -> RA_Result freeRegs (BlockAssignment freeRegs))
-> RegM freeRegs (BlockAssignment freeRegs)
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs
  -> RA_Result freeRegs (BlockAssignment freeRegs))
 -> RegM freeRegs (BlockAssignment freeRegs))
-> (RA_State freeRegs
    -> RA_Result freeRegs (BlockAssignment freeRegs))
-> RegM freeRegs (BlockAssignment freeRegs)
forall a b. (a -> b) -> a -> b
$ \ s :: RA_State freeRegs
s@RA_State{ra_blockassig :: forall freeRegs. RA_State freeRegs -> BlockAssignment freeRegs
ra_blockassig = BlockAssignment freeRegs
assig} ->
  RA_State freeRegs
-> BlockAssignment freeRegs
-> RA_Result freeRegs (BlockAssignment freeRegs)
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s BlockAssignment freeRegs
assig

setBlockAssigR :: BlockAssignment freeRegs -> RegM freeRegs ()
setBlockAssigR :: forall freeRegs. BlockAssignment freeRegs -> RegM freeRegs ()
setBlockAssigR BlockAssignment freeRegs
assig = (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ())
-> (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall a b. (a -> b) -> a -> b
$ \ RA_State freeRegs
s ->
  RA_State freeRegs -> () -> RA_Result freeRegs ()
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s{ra_blockassig :: BlockAssignment freeRegs
ra_blockassig = BlockAssignment freeRegs
assig} ()

setDeltaR :: Int -> RegM freeRegs ()
setDeltaR :: forall freeRegs. Int -> RegM freeRegs ()
setDeltaR Int
n = (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ())
-> (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall a b. (a -> b) -> a -> b
$ \ RA_State freeRegs
s ->
  RA_State freeRegs -> () -> RA_Result freeRegs ()
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s{ra_delta :: Int
ra_delta = Int
n} ()

getDeltaR :: RegM freeRegs Int
getDeltaR :: forall freeRegs. RegM freeRegs Int
getDeltaR = (RA_State freeRegs -> RA_Result freeRegs Int) -> RegM freeRegs Int
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs Int)
 -> RegM freeRegs Int)
-> (RA_State freeRegs -> RA_Result freeRegs Int)
-> RegM freeRegs Int
forall a b. (a -> b) -> a -> b
$ \RA_State freeRegs
s -> RA_State freeRegs -> Int -> RA_Result freeRegs Int
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s (RA_State freeRegs -> Int
forall freeRegs. RA_State freeRegs -> Int
ra_delta RA_State freeRegs
s)

getUniqueR :: RegM freeRegs Unique
getUniqueR :: forall freeRegs. RegM freeRegs Unique
getUniqueR = (RA_State freeRegs -> RA_Result freeRegs Unique)
-> RegM freeRegs Unique
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs Unique)
 -> RegM freeRegs Unique)
-> (RA_State freeRegs -> RA_Result freeRegs Unique)
-> RegM freeRegs Unique
forall a b. (a -> b) -> a -> b
$ \RA_State freeRegs
s ->
  case UniqSupply -> (Unique, UniqSupply)
takeUniqFromSupply (RA_State freeRegs -> UniqSupply
forall freeRegs. RA_State freeRegs -> UniqSupply
ra_us RA_State freeRegs
s) of
    (Unique
uniq, UniqSupply
us) -> RA_State freeRegs -> Unique -> RA_Result freeRegs Unique
forall a b. a -> b -> (# a, b #)
RA_Result RA_State freeRegs
s{ra_us :: UniqSupply
ra_us = UniqSupply
us} Unique
uniq


-- | Record that a spill instruction was inserted, for profiling.
recordSpill :: SpillReason -> RegM freeRegs ()
recordSpill :: forall freeRegs. SpillReason -> RegM freeRegs ()
recordSpill SpillReason
spill
    = (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ())
-> (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall a b. (a -> b) -> a -> b
$ \RA_State freeRegs
s -> RA_State freeRegs -> () -> RA_Result freeRegs ()
forall a b. a -> b -> (# a, b #)
RA_Result (RA_State freeRegs
s { ra_spills :: [SpillReason]
ra_spills = SpillReason
spill SpillReason -> [SpillReason] -> [SpillReason]
forall a. a -> [a] -> [a]
: RA_State freeRegs -> [SpillReason]
forall freeRegs. RA_State freeRegs -> [SpillReason]
ra_spills RA_State freeRegs
s }) ()

-- | Record a created fixup block
recordFixupBlock :: BlockId -> BlockId -> BlockId -> RegM freeRegs ()
recordFixupBlock :: forall freeRegs. BlockId -> BlockId -> BlockId -> RegM freeRegs ()
recordFixupBlock BlockId
from BlockId
between BlockId
to
    = (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall freeRegs a.
(RA_State freeRegs -> RA_Result freeRegs a) -> RegM freeRegs a
RegM ((RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ())
-> (RA_State freeRegs -> RA_Result freeRegs ()) -> RegM freeRegs ()
forall a b. (a -> b) -> a -> b
$ \RA_State freeRegs
s -> RA_State freeRegs -> () -> RA_Result freeRegs ()
forall a b. a -> b -> (# a, b #)
RA_Result (RA_State freeRegs
s { ra_fixups :: [(BlockId, BlockId, BlockId)]
ra_fixups = (BlockId
from,BlockId
between,BlockId
to) (BlockId, BlockId, BlockId)
-> [(BlockId, BlockId, BlockId)] -> [(BlockId, BlockId, BlockId)]
forall a. a -> [a] -> [a]
: RA_State freeRegs -> [(BlockId, BlockId, BlockId)]
forall freeRegs. RA_State freeRegs -> [(BlockId, BlockId, BlockId)]
ra_fixups RA_State freeRegs
s }) ()