-- | From the [Kempe compiler](http://vmchale.com/original/compiler.pdf) with
-- improvements.
module Asm.X86.CF ( mkControlFlow
                  , expand, udd
                  , uses, defs
                  , defsF
                  ) where

import           Asm.BB
import           Asm.CF
import           Asm.X86      as X86
import           CF
-- seems to pretty clearly be faster
import           Class.E      as E
import           Data.Functor (void, ($>))
import qualified Data.IntSet  as IS

mkControlFlow :: (E reg, E freg) => [BB X86 reg freg f2reg () ()] -> [BB X86 reg freg f2reg () ControlAnn]
mkControlFlow :: forall reg freg f2reg.
(E reg, E freg) =>
[BB X86 reg freg f2reg () ()]
-> [BB X86 reg freg f2reg () ControlAnn]
mkControlFlow [BB X86 reg freg f2reg () ()]
isns = FreshM [BB X86 reg freg f2reg () ControlAnn]
-> [BB X86 reg freg f2reg () ControlAnn]
forall a. FreshM a -> a
runFreshM ([BB X86 reg freg f2reg () ()] -> FreshM ()
forall reg freg f2reg a. [BB X86 reg freg f2reg a ()] -> FreshM ()
broadcasts [BB X86 reg freg f2reg () ()]
isns FreshM ()
-> FreshM [BB X86 reg freg f2reg () ControlAnn]
-> FreshM [BB X86 reg freg f2reg () ControlAnn]
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [BB X86 reg freg f2reg () ()]
-> FreshM [BB X86 reg freg f2reg () ControlAnn]
forall reg freg f2reg.
(E reg, E freg) =>
[BB X86 reg freg f2reg () ()]
-> FreshM [BB X86 reg freg f2reg () ControlAnn]
addControlFlow [BB X86 reg freg f2reg () ()]
isns)

expand :: (E reg, E freg) => BB X86 reg freg f2reg () Liveness -> [X86 reg freg f2reg Liveness]
expand :: forall reg freg f2reg.
(E reg, E freg) =>
BB X86 reg freg f2reg () Liveness -> [X86 reg freg f2reg Liveness]
expand (BB asms :: [X86 reg freg f2reg ()]
asms@(X86 reg freg f2reg ()
_:[X86 reg freg f2reg ()]
_) Liveness
li) = (X86 reg freg f2reg ()
 -> X86 reg freg f2reg Liveness -> X86 reg freg f2reg Liveness)
-> X86 reg freg f2reg Liveness
-> [X86 reg freg f2reg ()]
-> [X86 reg freg f2reg Liveness]
forall a b. (a -> b -> b) -> b -> [a] -> [b]
scanr (\X86 reg freg f2reg ()
n X86 reg freg f2reg Liveness
p -> X86 reg freg f2reg () -> Liveness -> X86 reg freg f2reg Liveness
forall {freg} {reg} {f2reg} {a}.
(E freg, E reg) =>
X86 reg freg f2reg a -> Liveness -> X86 reg freg f2reg Liveness
lN X86 reg freg f2reg ()
n (X86 reg freg f2reg Liveness -> Liveness
forall reg freg f2 a. X86 reg freg f2 a -> a
ann X86 reg freg f2reg Liveness
p)) X86 reg freg f2reg Liveness
lS [X86 reg freg f2reg ()]
iasms
    where lN :: X86 reg freg f2reg a -> Liveness -> X86 reg freg f2reg Liveness
lN X86 reg freg f2reg a
a Liveness
s =
            let ai :: IntSet
ai=X86 reg freg f2reg a -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
uses X86 reg freg f2reg a
a IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<> (IntSet
ao IntSet -> IntSet -> IntSet
IS.\\ X86 reg freg f2reg a -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
defs X86 reg freg f2reg a
a)
                ao :: IntSet
ao=Liveness -> IntSet
ins Liveness
s
                aif :: IntSet
aif=X86 reg freg f2reg a -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
usesF X86 reg freg f2reg a
a IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<> (IntSet
aof IntSet -> IntSet -> IntSet
IS.\\ X86 reg freg f2reg a -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
defsF X86 reg freg f2reg a
a)
                aof :: IntSet
aof=Liveness -> IntSet
fins Liveness
s
            in X86 reg freg f2reg a
a X86 reg freg f2reg a -> Liveness -> X86 reg freg f2reg Liveness
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> IntSet -> IntSet -> IntSet -> IntSet -> Liveness
Liveness IntSet
ai IntSet
ao IntSet
aif IntSet
aof
          lS :: X86 reg freg f2reg Liveness
lS = let ao :: IntSet
ao=Liveness -> IntSet
out Liveness
li
                   aof :: IntSet
aof=Liveness -> IntSet
fout Liveness
li
               in X86 reg freg f2reg ()
asm X86 reg freg f2reg () -> Liveness -> X86 reg freg f2reg Liveness
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> IntSet -> IntSet -> IntSet -> IntSet -> Liveness
Liveness (X86 reg freg f2reg () -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
uses X86 reg freg f2reg ()
asm IntSet -> IntSet -> IntSet
`IS.union` (IntSet
ao IntSet -> IntSet -> IntSet
`IS.difference` X86 reg freg f2reg () -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
defs X86 reg freg f2reg ()
asm)) IntSet
ao (X86 reg freg f2reg () -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
usesF X86 reg freg f2reg ()
asm IntSet -> IntSet -> IntSet
`IS.union` (IntSet
aof IntSet -> IntSet -> IntSet
`IS.difference` X86 reg freg f2reg () -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
defsF X86 reg freg f2reg ()
asm)) IntSet
aof
          ([X86 reg freg f2reg ()]
iasms, X86 reg freg f2reg ()
asm) = ([X86 reg freg f2reg ()] -> [X86 reg freg f2reg ()]
forall a. HasCallStack => [a] -> [a]
init [X86 reg freg f2reg ()]
asms, [X86 reg freg f2reg ()] -> X86 reg freg f2reg ()
forall a. HasCallStack => [a] -> a
last [X86 reg freg f2reg ()]
asms)
expand BB X86 reg freg f2reg () Liveness
_ = []

{-# SCC addControlFlow #-}
-- | Annotate instructions with a unique node name and a list of all possible
-- destinations.
addControlFlow :: (E reg, E freg) => [BB X86 reg freg f2reg () ()] -> FreshM [BB X86 reg freg f2reg () ControlAnn]
addControlFlow :: forall reg freg f2reg.
(E reg, E freg) =>
[BB X86 reg freg f2reg () ()]
-> FreshM [BB X86 reg freg f2reg () ControlAnn]
addControlFlow [] = [BB X86 reg freg f2reg () ControlAnn]
-> StateT
     (N, Map Label N, Map Label [N])
     Identity
     [BB X86 reg freg f2reg () ControlAnn]
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
addControlFlow (BB [X86 reg freg f2reg ()]
asms ()
_:[BB X86 reg freg f2reg () ()]
bbs) = do
    { i <- case [X86 reg freg f2reg ()]
asms of
        (Label ()
_ Label
l:[X86 reg freg f2reg ()]
_) -> Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
l
        [X86 reg freg f2reg ()]
_             -> StateT (N, Map Label N, Map Label [N]) Identity N
getFresh
    ; (f, bbs') <- next bbs
    ; acc <- case last asms of
            J ()
_ Label
    -> do {l_i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
; pure [l_i]}
            Je ()
_ Label
   -> do {l_i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
; pure (f [l_i])}
            Jle ()
_ Label
  -> do {l_i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
; pure (f [l_i])}
            Jl ()
_ Label
   -> do {l_i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
; pure (f [l_i])}
            Jg ()
_ Label
   -> do {l_i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
; pure (f [l_i])}
            Jge ()
_ Label
  -> do {l_i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
; pure (f [l_i])}
            Jne ()
_ Label
  -> do {l_i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
; pure (f [l_i])}
            C ()
_ Label
    -> do {l_i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
lookupLabel Label
; pure [l_i]}
            RetL ()
_ Label
 -> Label -> StateT (N, Map Label N, Map Label [N]) Identity [N]
lC Label

            X86 reg freg f2reg ()
_         -> [N] -> StateT (N, Map Label N, Map Label [N]) Identity [N]
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([N] -> [N]
f [])
    ; pure (BB asms (ControlAnn i acc (ubb asms)) : bbs')
    }

ubb :: [X86 reg freg f2reg a] -> UD
ubb [X86 reg freg f2reg a]
asm = IntSet -> IntSet -> IntSet -> IntSet -> UD
UD ([X86 reg freg f2reg a] -> IntSet
forall reg freg f2reg a. E reg => [X86 reg freg f2reg a] -> IntSet
uBB [X86 reg freg f2reg a]
asm) ([X86 reg freg f2reg a] -> IntSet
forall freg reg f2reg a. E freg => [X86 reg freg f2reg a] -> IntSet
uBBF [X86 reg freg f2reg a]
asm) ([X86 reg freg f2reg a] -> IntSet
forall reg freg f2reg a. E reg => [X86 reg freg f2reg a] -> IntSet
dBB [X86 reg freg f2reg a]
asm) ([X86 reg freg f2reg a] -> IntSet
forall freg reg f2reg a. E freg => [X86 reg freg f2reg a] -> IntSet
dBBF [X86 reg freg f2reg a]
asm)
udd :: X86 reg freg f2reg ann -> UD
udd X86 reg freg f2reg ann
asm = IntSet -> IntSet -> IntSet -> IntSet -> UD
UD (X86 reg freg f2reg ann -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
uses X86 reg freg f2reg ann
asm) (X86 reg freg f2reg ann -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
usesF X86 reg freg f2reg ann
asm) (X86 reg freg f2reg ann -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
defs X86 reg freg f2reg ann
asm) (X86 reg freg f2reg ann -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
defsF X86 reg freg f2reg ann
asm)

uBB, dBB :: E reg => [X86 reg freg f2reg a] -> IS.IntSet
uBB :: forall reg freg f2reg a. E reg => [X86 reg freg f2reg a] -> IntSet
uBB = (X86 reg freg f2reg a -> IntSet -> IntSet)
-> IntSet -> [X86 reg freg f2reg a] -> IntSet
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\X86 reg freg f2reg a
p IntSet
n -> X86 reg freg f2reg a -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
uses X86 reg freg f2reg a
p IntSet -> IntSet -> IntSet
`IS.union` (IntSet
n IntSet -> IntSet -> IntSet
IS.\\ X86 reg freg f2reg a -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
defs X86 reg freg f2reg a
p)) IntSet
IS.empty
dBB :: forall reg freg f2reg a. E reg => [X86 reg freg f2reg a] -> IntSet
dBB = (X86 reg freg f2reg a -> IntSet)
-> [X86 reg freg f2reg a] -> IntSet
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap X86 reg freg f2reg a -> IntSet
forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
defs

uBBF, dBBF :: E freg => [X86 reg freg f2reg a] -> IS.IntSet
uBBF :: forall freg reg f2reg a. E freg => [X86 reg freg f2reg a] -> IntSet
uBBF = (X86 reg freg f2reg a -> IntSet -> IntSet)
-> IntSet -> [X86 reg freg f2reg a] -> IntSet
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\X86 reg freg f2reg a
p IntSet
n -> X86 reg freg f2reg a -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
usesF X86 reg freg f2reg a
p IntSet -> IntSet -> IntSet
`IS.union` (IntSet
n IntSet -> IntSet -> IntSet
IS.\\ X86 reg freg f2reg a -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
defsF X86 reg freg f2reg a
p)) IntSet
IS.empty
dBBF :: forall freg reg f2reg a. E freg => [X86 reg freg f2reg a] -> IntSet
dBBF = (X86 reg freg f2reg a -> IntSet)
-> [X86 reg freg f2reg a] -> IntSet
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap X86 reg freg f2reg a -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
defsF

uA :: E reg => Addr reg -> IS.IntSet
uA :: forall reg. E reg => Addr reg -> IntSet
uA (R reg
r)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uA (RC32 reg
r Int32
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uA (RC reg
r Int8
_)      = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uA (RS reg
b Scale
_ reg
i)    = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
b,reg
i]
uA (RSD reg
b Scale
_ reg
i Int8
_) = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
b,reg
i]

usesF :: E freg => X86 reg freg f2reg ann -> IS.IntSet
usesF :: forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
usesF (Movapd ann
_ freg
_ freg
r)            = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
usesF (Vmulsd ann
_ freg
_ freg
r0 freg
r1)        = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Vaddsd ann
_ freg
_ freg
r0 freg
r1)        = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Vsubsd ann
_ freg
_ freg
r0 freg
r1)        = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Vdivsd ann
_ freg
_ freg
r0 freg
r1)        = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (VaddsdA ann
_ freg
_ freg
r Addr reg
_)         = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
usesF (Mulsd ann
_ freg
r0 freg
r1)           = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Divsd ann
_ freg
r0 freg
r1)           = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Addsd ann
_ freg
r0 freg
r1)           = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Subsd ann
_ freg
r0 freg
r1)           = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Vfmadd231sd ann
_ freg
r0 freg
r1 freg
r2)  = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1, freg
r2]
usesF (Vfmnadd231sd ann
_ freg
r0 freg
r1 freg
r2) = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1, freg
r2]
usesF (Vfmadd231sdA ann
_ freg
r0 freg
r1 Addr reg
_)  = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Sqrtsd ann
_ freg
_ freg
r)            = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
usesF (Vmaxsd ann
_ freg
_ freg
r0 freg
r1)        = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Vminsd ann
_ freg
_ freg
r0 freg
r1)        = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (VmaxsdA ann
_ freg
_ freg
r Addr reg
_)         = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
usesF (Maxsd ann
_ freg
r0 freg
r1)           = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Minsd ann
_ freg
r0 freg
r1)           = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (Roundsd ann
_ freg
_ freg
r RoundMode
_)         = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
usesF (Cvttsd2si ann
_ reg
_ freg
r)         = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
usesF (MovqAX ann
_ Addr reg
_ freg
x)            = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
x
usesF MovqXR{}                  = IntSet
IS.empty
usesF IAddRR{}                  = IntSet
IS.empty
usesF IAddRI{}                  = IntSet
IS.empty
usesF ISubRR{}                  = IntSet
IS.empty
usesF MovRI{}                   = IntSet
IS.empty
usesF MovRR{}                   = IntSet
IS.empty
usesF MovRL{}                   = IntSet
IS.empty
usesF CmpRR{}                   = IntSet
IS.empty
usesF CmpRI{}                   = IntSet
IS.empty
usesF Cvtsi2sd{}                = IntSet
IS.empty
usesF MovRA{}                   = IntSet
IS.empty
usesF MovAR{}                   = IntSet
IS.empty
usesF Fldln2{}                  = IntSet
IS.empty
usesF ISubRI{}                  = IntSet
IS.empty
usesF IMulRR{}                  = IntSet
IS.empty
usesF IMulRA{}                  = IntSet
IS.empty
usesF Sal{}                     = IntSet
IS.empty
usesF Sar{}                     = IntSet
IS.empty
usesF Fscale{}                  = IntSet
IS.empty
usesF Call{}                    = IntSet
IS.empty
usesF Cmovnle{}                 = IntSet
IS.empty
usesF Cmovnl{}                  = IntSet
IS.empty
usesF Cmovne{}                  = IntSet
IS.empty
usesF Cmove{}                   = IntSet
IS.empty
usesF Cmovle{}                  = IntSet
IS.empty
usesF Cmovl{}                   = IntSet
IS.empty
usesF Fstp{}                    = IntSet
IS.empty
usesF MovqXA{}                  = IntSet
IS.empty
usesF Fyl2x{}                   = IntSet
IS.empty
usesF Fld{}                     = IntSet
IS.empty
usesF MovAI32{}                 = IntSet
IS.empty
usesF Faddp{}                   = IntSet
IS.empty
usesF F2xm1{}                   = IntSet
IS.empty
usesF Fprem{}                   = IntSet
IS.empty
usesF Fmulp{}                   = IntSet
IS.empty
usesF FldS{}                    = IntSet
IS.empty
usesF Fld1{}                    = IntSet
IS.empty
usesF Fldl2e{}                  = IntSet
IS.empty
usesF Fninit{}                  = IntSet
IS.empty
usesF TestI{}                   = IntSet
IS.empty
usesF (Vcmppd ann
_ freg
_ freg
r0 freg
r1 Pred
_)      = [freg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [freg
r0, freg
r1]
usesF (MovqRX ann
_ reg
_ freg
xr)           = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
xr
usesF Fsin{}                    = IntSet
IS.empty
usesF Fcos{}                    = IntSet
IS.empty
usesF XorRR{}                   = IntSet
IS.empty
usesF Fxch{}                    = IntSet
IS.empty
usesF IDiv{}                    = IntSet
IS.empty
usesF Test{}                    = IntSet
IS.empty
usesF Push{}                    = IntSet
IS.empty
usesF Pop{}                     = IntSet
IS.empty
usesF Rdrand{}                  = IntSet
IS.empty
usesF Neg{}                     = IntSet
IS.empty
usesF J{}                       = IntSet
IS.empty
usesF Je{}                      = IntSet
IS.empty
usesF Label{}                   = IntSet
IS.empty
usesF Jne{}                     = IntSet
IS.empty
usesF Jge{}                     = IntSet
IS.empty
usesF Jg{}                      = IntSet
IS.empty
usesF Jl{}                      = IntSet
IS.empty
usesF Jle{}                     = IntSet
IS.empty
usesF C{}                       = IntSet
IS.empty
usesF RetL{}                    = IntSet
IS.empty
usesF Ret{}                     = [FAbsReg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [FAbsReg
FRet0, FAbsReg
FRet1]

uses :: E reg => X86 reg freg f2reg ann -> IS.IntSet
uses :: forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
uses (MovRR ann
_ reg
_ reg
r)          = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses MovRL{}                = IntSet
IS.empty
uses (And ann
_ reg
r0 reg
r1)          = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
r0, reg
r1]
uses (IAddRR ann
_ reg
r0 reg
r1)       = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
r0, reg
r1]
uses (IAddRI ann
_ reg
r Int64
_)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (ISubRR ann
_ reg
r0 reg
r1)       = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
r0, reg
r1]
uses (ISubRI ann
_ reg
r Int64
_)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (IMulRR ann
_ reg
r0 reg
r1)       = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
r0, reg
r1]
uses (IMulRA ann
_ reg
r Addr reg
a)         = N -> IntSet -> IntSet
IS.insert (reg -> N
forall a. E a => a -> N
E.toInt reg
r) (IntSet -> IntSet) -> IntSet -> IntSet
forall a b. (a -> b) -> a -> b
$ Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses (CmpRR ann
_ reg
r0 reg
r1)        = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
r0, reg
r1]
uses MovRI{}                = IntSet
IS.empty
uses (CmpRI ann
_ reg
r Int32
_)          = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (MovqXR ann
_ freg
_ reg
r)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Cvtsi2sd ann
_ freg
_ reg
r)       = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (MovqXA ann
_ freg
_ Addr reg
a)         = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses (MovqAX ann
_ Addr reg
a freg
_)         = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses Fldl2e{}               = IntSet
IS.empty
uses Fldln2{}               = IntSet
IS.empty
uses (Fld ann
_ Addr reg
a)              = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses Fyl2x{}                = IntSet
IS.empty
uses F2xm1{}                = IntSet
IS.empty
uses Fmulp{}                = IntSet
IS.empty
uses (Fstp ann
_ Addr reg
a)             = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses (MovRA ann
_ reg
_ Addr reg
a)          = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses (IDiv ann
_ reg
r)             = N -> IntSet -> IntSet
IS.insert (reg -> N
forall a. E a => a -> N
E.toInt reg
r) (IntSet -> IntSet) -> IntSet -> IntSet
forall a b. (a -> b) -> a -> b
$ [AbsReg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [AbsReg
Quot, AbsReg
Rem]
uses (MovAR ann
_ Addr reg
a reg
r)          = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<> reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Sal ann
_ reg
r Int8
_)            = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Sar ann
_ reg
r Int8
_)            = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Call ann
_ CFunc
Malloc)        = [AbsReg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [AbsReg
CArg0]
uses (Call ann
_ CFunc
Free)          = [AbsReg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [AbsReg
CArg0]
uses (Call ann
_ CFunc
DR)            = IntSet
IS.empty
uses (MovAI32 ann
_ Addr reg
a Int32
_)        = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses Fld1{}                 = IntSet
IS.empty
uses FldS{}                 = IntSet
IS.empty
uses Fprem{}                = IntSet
IS.empty
uses Faddp{}                = IntSet
IS.empty
uses Fsin{}                 = IntSet
IS.empty
uses Fcos{}                 = IntSet
IS.empty
uses Fscale{}               = IntSet
IS.empty
uses Fxch{}                 = IntSet
IS.empty
uses (Not ann
_ reg
r)              = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Cmovnle ann
_ reg
_ reg
r)        = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Cmovnl ann
_ reg
_ reg
r)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Cmovne ann
_ reg
_ reg
r)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Cmove ann
_ reg
_ reg
r)          = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Cmovle ann
_ reg
_ reg
r)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses (Cmovl ann
_ reg
_ reg
r)          = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses Vmulsd{}               = IntSet
IS.empty
uses Vaddsd{}               = IntSet
IS.empty
uses (VaddsdA ann
_ freg
_ freg
_ Addr reg
a)      = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses Vdivsd{}               = IntSet
IS.empty
uses Vsubsd{}               = IntSet
IS.empty
uses Vmaxsd{}               = IntSet
IS.empty
uses Vminsd{}               = IntSet
IS.empty
uses (VmaxsdA ann
_ freg
_ freg
_ Addr reg
a)      = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses Addsd{}                = IntSet
IS.empty
uses Subsd{}                = IntSet
IS.empty
uses Roundsd{}              = IntSet
IS.empty
uses Mulsd{}                = IntSet
IS.empty
uses Divsd{}                = IntSet
IS.empty
uses Movapd{}               = IntSet
IS.empty
uses Vfmadd231sd{}          = IntSet
IS.empty
uses Vfmnadd231sd{}         = IntSet
IS.empty
uses (Vfmadd231sdA ann
_ freg
_ freg
_ Addr reg
a) = Addr reg -> IntSet
forall reg. E reg => Addr reg -> IntSet
uA Addr reg
a
uses Cvttsd2si{}            = IntSet
IS.empty
uses Sqrtsd{}               = IntSet
IS.empty
uses Rdrand{}               = IntSet
IS.empty
uses Fninit{}               = IntSet
IS.empty
uses (TestI ann
_ reg
r Int32
_)          = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses Vcmppd{}               = IntSet
IS.empty
uses MovqRX{}               = IntSet
IS.empty
uses (XorRR ann
_ reg
r0 reg
r1)        = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
r0, reg
r1]
uses (Test ann
_ reg
r0 reg
r1)         = [reg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [reg
r0, reg
r1]
uses (Push ann
_ reg
r)             = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses Pop{}                  = IntSet
IS.empty
uses (Neg ann
_ reg
r)              = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
uses J{}                    = IntSet
IS.empty
uses Je{}                   = IntSet
IS.empty
uses Label{}                = IntSet
IS.empty
uses Jne{}                  = IntSet
IS.empty
uses Jge{}                  = IntSet
IS.empty
uses Jg{}                   = IntSet
IS.empty
uses Jl{}                   = IntSet
IS.empty
uses Jle{}                  = IntSet
IS.empty
uses C{}                    = IntSet
IS.empty
uses RetL{}                 = IntSet
IS.empty
uses Ret{}                  = AbsReg -> IntSet
forall reg. E reg => reg -> IntSet
singleton AbsReg
CRet

defsF :: E freg => X86 reg freg f2reg ann -> IS.IntSet
defsF :: forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
defsF (Movapd ann
_ freg
r freg
_)         = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vmulsd ann
_ freg
r freg
_ freg
_)       = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vaddsd ann
_ freg
r freg
_ freg
_)       = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (VaddsdA ann
_ freg
r freg
_ Addr reg
_)      = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vsubsd ann
_ freg
r freg
_ freg
_)       = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vdivsd ann
_ freg
r freg
_ freg
_)       = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (MovqXR ann
_ freg
r reg
_)         = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Addsd ann
_ freg
r freg
_)          = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Subsd ann
_ freg
r freg
_)          = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Divsd ann
_ freg
r freg
_)          = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Mulsd ann
_ freg
r freg
_)          = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (MovqXA ann
_ freg
r Addr reg
_)         = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF MovqAX{}               = IntSet
IS.empty
defsF (Sqrtsd ann
_ freg
r freg
_)         = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vmaxsd ann
_ freg
r freg
_ freg
_)       = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (VmaxsdA ann
_ freg
r freg
_ Addr reg
_)      = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vminsd ann
_ freg
r freg
_ freg
_)       = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Minsd ann
_ freg
r freg
_)          = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Maxsd ann
_ freg
r freg
_)          = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vfmadd231sd ann
_ freg
r freg
_ freg
_)  = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vfmnadd231sd ann
_ freg
r freg
_ freg
_) = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Vfmadd231sdA ann
_ freg
r freg
_ Addr reg
_) = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Roundsd ann
_ freg
r freg
_ RoundMode
_)      = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF (Cvtsi2sd ann
_ freg
r reg
_)       = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF IAddRR{}               = IntSet
IS.empty
defsF IAddRI{}               = IntSet
IS.empty
defsF ISubRR{}               = IntSet
IS.empty
defsF ISubRI{}               = IntSet
IS.empty
defsF IMulRR{}               = IntSet
IS.empty
defsF IMulRA{}               = IntSet
IS.empty
defsF MovRR{}                = IntSet
IS.empty
defsF MovRL{}                = IntSet
IS.empty
defsF MovRA{}                = IntSet
IS.empty
defsF MovAR{}                = IntSet
IS.empty
defsF MovAI32{}              = IntSet
IS.empty
defsF MovRI{}                = IntSet
IS.empty
defsF Fld{}                  = IntSet
IS.empty
defsF FldS{}                 = IntSet
IS.empty
defsF Fldl2e{}               = IntSet
IS.empty
defsF Fldln2{}               = IntSet
IS.empty
defsF Fld1{}                 = IntSet
IS.empty
defsF Fsin{}                 = IntSet
IS.empty
defsF Fcos{}                 = IntSet
IS.empty
defsF Fyl2x{}                = IntSet
IS.empty
defsF Fstp{}                 = IntSet
IS.empty
defsF F2xm1{}                = IntSet
IS.empty
defsF Fmulp{}                = IntSet
IS.empty
defsF Fprem{}                = IntSet
IS.empty
defsF Faddp{}                = IntSet
IS.empty
defsF Fscale{}               = IntSet
IS.empty
defsF Fxch{}                 = IntSet
IS.empty
defsF CmpRR{}                = IntSet
IS.empty
defsF CmpRI{}                = IntSet
IS.empty
defsF Sal{}                  = IntSet
IS.empty
defsF Sar{}                  = IntSet
IS.empty
defsF Cmovnle{}              = IntSet
IS.empty
defsF Cmovnl{}               = IntSet
IS.empty
defsF Cmovne{}               = IntSet
IS.empty
defsF Cmove{}                = IntSet
IS.empty
defsF Cmovle{}               = IntSet
IS.empty
defsF Cmovl{}                = IntSet
IS.empty
defsF (Call ann
_ CFunc
DR)            = N -> IntSet
IS.singleton (FAbsReg -> N
X86.fToInt FAbsReg
FRet0)
defsF Call{}                 = IntSet
IS.empty
defsF Cvttsd2si{}            = IntSet
IS.empty
defsF Fninit{}               = IntSet
IS.empty
defsF TestI{}                = IntSet
IS.empty
defsF (Vcmppd ann
_ freg
r freg
_ freg
_ Pred
_)     = freg -> IntSet
forall reg. E reg => reg -> IntSet
singleton freg
r
defsF MovqRX{}               = IntSet
IS.empty
defsF XorRR{}                = IntSet
IS.empty
defsF IDiv{}                 = IntSet
IS.empty
defsF Test{}                 = IntSet
IS.empty
defsF Pop{}                  = IntSet
IS.empty
defsF Push{}                 = IntSet
IS.empty
defsF Rdrand{}               = IntSet
IS.empty
defsF Neg{}                  = IntSet
IS.empty
defsF J{}                    = IntSet
IS.empty
defsF Je{}                   = IntSet
IS.empty
defsF Label{}                = IntSet
IS.empty
defsF Jne{}                  = IntSet
IS.empty
defsF Jge{}                  = IntSet
IS.empty
defsF Jg{}                   = IntSet
IS.empty
defsF Jl{}                   = IntSet
IS.empty
defsF Jle{}                  = IntSet
IS.empty
defsF C{}                    = IntSet
IS.empty
defsF RetL{}                 = IntSet
IS.empty
defsF Ret{}                  = IntSet
IS.empty

defs :: (E reg) => X86 reg freg f2reg ann -> IS.IntSet
defs :: forall reg freg f2reg ann.
E reg =>
X86 reg freg f2reg ann -> IntSet
defs (MovRR ann
_ reg
r reg
_)     = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (MovRL ann
_ reg
r N
_)     = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs MovqXR{}          = IntSet
IS.empty
defs MovqXA{}          = IntSet
IS.empty
defs MovqAX{}          = IntSet
IS.empty
defs (IAddRR ann
_ reg
r reg
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (And ann
_ reg
r reg
_)       = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (IAddRI ann
_ reg
r Int64
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (ISubRR ann
_ reg
r reg
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (ISubRI ann
_ reg
r Int64
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (IMulRR ann
_ reg
r reg
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (IMulRA ann
_ reg
r Addr reg
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs CmpRR{}           = IntSet
IS.empty
defs (MovRI ann
_ reg
r Int64
_)     = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Cvttsd2si ann
_ reg
r freg
_) = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs CmpRI{}           = IntSet
IS.empty
defs Fldl2e{}          = IntSet
IS.empty
defs Fldln2{}          = IntSet
IS.empty
defs Fyl2x{}           = IntSet
IS.empty
defs Fstp{}            = IntSet
IS.empty
defs Fsin{}            = IntSet
IS.empty
defs Fcos{}            = IntSet
IS.empty
defs Fld{}             = IntSet
IS.empty
defs F2xm1{}           = IntSet
IS.empty
defs Fmulp{}           = IntSet
IS.empty
defs (MovRA ann
_ reg
r Addr reg
_)     = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs IDiv{}            = [AbsReg] -> IntSet
forall reg. E reg => [reg] -> IntSet
fromList [AbsReg
Quot, AbsReg
Rem]
defs MovAR{}           = IntSet
IS.empty
defs (Sal ann
_ reg
r Int8
_)       = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Sar ann
_ reg
r Int8
_)       = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Call ann
_ CFunc
Malloc)   = N -> IntSet
IS.singleton (AbsReg -> N
X86.toInt AbsReg
CRet)
defs (Call ann
_ CFunc
Free)     = IntSet
IS.empty
defs (Call ann
_ CFunc
DR)       = IntSet
IS.empty
defs MovAI32{}         = IntSet
IS.empty
defs Fld1{}            = IntSet
IS.empty
defs FldS{}            = IntSet
IS.empty
defs Fprem{}           = IntSet
IS.empty
defs Faddp{}           = IntSet
IS.empty
defs Fscale{}          = IntSet
IS.empty
defs Fxch{}            = IntSet
IS.empty
defs (Not ann
_ reg
r)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Cmovnle ann
_ reg
r reg
_)   = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Cmovnl ann
_ reg
r reg
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Cmovne ann
_ reg
r reg
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Cmove ann
_ reg
r reg
_)     = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Cmovl ann
_ reg
r reg
_)     = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Cmovle ann
_ reg
r reg
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs Vmulsd{}          = IntSet
IS.empty
defs Vdivsd{}          = IntSet
IS.empty
defs Vaddsd{}          = IntSet
IS.empty
defs Vsubsd{}          = IntSet
IS.empty
defs Vmaxsd{}          = IntSet
IS.empty
defs Vminsd{}          = IntSet
IS.empty
defs VmaxsdA{}         = IntSet
IS.empty
defs VaddsdA{}         = IntSet
IS.empty
defs Addsd{}           = IntSet
IS.empty
defs Subsd{}           = IntSet
IS.empty
defs Mulsd{}           = IntSet
IS.empty
defs Divsd{}           = IntSet
IS.empty
defs Movapd{}          = IntSet
IS.empty
defs Cvtsi2sd{}        = IntSet
IS.empty
defs Vfmadd231sd{}     = IntSet
IS.empty
defs Vfmadd231sdA{}    = IntSet
IS.empty
defs Vfmnadd231sd{}    = IntSet
IS.empty
defs Roundsd{}         = IntSet
IS.empty
defs Sqrtsd{}          = IntSet
IS.empty
defs (Rdrand ann
_ reg
r)      = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs Fninit{}          = IntSet
IS.empty
defs TestI{}           = IntSet
IS.empty
defs Vcmppd{}          = IntSet
IS.empty
defs (MovqRX ann
_ reg
r freg
_)    = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (XorRR ann
_ reg
r reg
_)     = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs Test{}            = IntSet
IS.empty
defs Push{}            = IntSet
IS.empty
defs (Pop ann
_ reg
r)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs (Neg ann
_ reg
r)         = reg -> IntSet
forall reg. E reg => reg -> IntSet
singleton reg
r
defs J{}               = IntSet
IS.empty
defs Je{}              = IntSet
IS.empty
defs Label{}           = IntSet
IS.empty
defs Jne{}             = IntSet
IS.empty
defs Jge{}             = IntSet
IS.empty
defs Jg{}              = IntSet
IS.empty
defs Jl{}              = IntSet
IS.empty
defs Jle{}             = IntSet
IS.empty
defs C{}               = IntSet
IS.empty
defs RetL{}            = IntSet
IS.empty
defs Ret{}             = IntSet
IS.empty

next :: (E reg, E freg) => [BB X86 reg freg f2reg () ()] -> FreshM ([Int] -> [Int], [BB X86 reg freg f2reg () ControlAnn])
next :: forall reg freg f2reg.
(E reg, E freg) =>
[BB X86 reg freg f2reg () ()]
-> FreshM ([N] -> [N], [BB X86 reg freg f2reg () ControlAnn])
next [BB X86 reg freg f2reg () ()]
asms = do
    nextAsms <- [BB X86 reg freg f2reg () ()]
-> FreshM [BB X86 reg freg f2reg () ControlAnn]
forall reg freg f2reg.
(E reg, E freg) =>
[BB X86 reg freg f2reg () ()]
-> FreshM [BB X86 reg freg f2reg () ControlAnn]
addControlFlow [BB X86 reg freg f2reg () ()]
asms
    case nextAsms of
        []      -> ([N] -> [N], [BB X86 reg freg f2reg () ControlAnn])
-> StateT
     (N, Map Label N, Map Label [N])
     Identity
     ([N] -> [N], [BB X86 reg freg f2reg () ControlAnn])
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([N] -> [N]
forall a. a -> a
id, [])
        (BB X86 reg freg f2reg () ControlAnn
asm:[BB X86 reg freg f2reg () ControlAnn]
_) -> ([N] -> [N], [BB X86 reg freg f2reg () ControlAnn])
-> StateT
     (N, Map Label N, Map Label [N])
     Identity
     ([N] -> [N], [BB X86 reg freg f2reg () ControlAnn])
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((ControlAnn -> N
node (BB X86 reg freg f2reg () ControlAnn -> ControlAnn
forall (arch :: * -> * -> * -> * -> *) reg freg f2reg a b.
BB arch reg freg f2reg a b -> b
caBB BB X86 reg freg f2reg () ControlAnn
asm) N -> [N] -> [N]
forall a. a -> [a] -> [a]
:), [BB X86 reg freg f2reg () ControlAnn]
nextAsms)

-- | Construct map assigning labels to their node name.
broadcasts :: [BB X86 reg freg f2reg a ()] -> FreshM ()
broadcasts :: forall reg freg f2reg a. [BB X86 reg freg f2reg a ()] -> FreshM ()
broadcasts [] = () -> FreshM ()
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
broadcasts ((BB asms :: [X86 reg freg f2reg a]
asms@(X86 reg freg f2reg a
asm:[X86 reg freg f2reg a]
_) ()
_):bbs :: [BB X86 reg freg f2reg a ()]
bbs@((BB (Label a
_ Label
retL:[X86 reg freg f2reg a]
_) ()
_):[BB X86 reg freg f2reg a ()]
_)) | C a
_ Label
l <- [X86 reg freg f2reg a] -> X86 reg freg f2reg a
forall a. HasCallStack => [a] -> a
last [X86 reg freg f2reg a]
asms = do
    { i <- Label -> StateT (N, Map Label N, Map Label [N]) Identity N
fm Label
retL; b3 i l
    ; case asm of {Label a
_ Label
 -> StateT (N, Map Label N, Map Label [N]) Identity N -> FreshM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (StateT (N, Map Label N, Map Label [N]) Identity N -> FreshM ())
-> StateT (N, Map Label N, Map Label [N]) Identity N -> FreshM ()
forall a b. (a -> b) -> a -> b
$ Label -> StateT (N, Map Label N, Map Label [N]) Identity N
fm Label
; X86 reg freg f2reg a
_ -> () -> FreshM ()
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()}
    ; broadcasts bbs
    }
broadcasts ((BB (Label a
_ Label
l:[X86 reg freg f2reg a]
_) ()
_):[BB X86 reg freg f2reg a ()]
bbs) = Label -> StateT (N, Map Label N, Map Label [N]) Identity N
fm Label
l StateT (N, Map Label N, Map Label [N]) Identity N
-> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [BB X86 reg freg f2reg a ()] -> FreshM ()
forall reg freg f2reg a. [BB X86 reg freg f2reg a ()] -> FreshM ()
broadcasts [BB X86 reg freg f2reg a ()]
bbs
broadcasts (BB X86 reg freg f2reg a ()
_:[BB X86 reg freg f2reg a ()]
bbs) = [BB X86 reg freg f2reg a ()] -> FreshM ()
forall reg freg f2reg a. [BB X86 reg freg f2reg a ()] -> FreshM ()
broadcasts [BB X86 reg freg f2reg a ()]
bbs