module Asm.X86.Opt ( optX86 ) where
import Asm.L
import Asm.X86 hiding (toInt)
import Asm.X86.CF
import CF
import Class.E
import Data.Functor (void)
import qualified Data.IntSet as IS
{-# SCC optAddr #-}
optAddr :: Addr reg -> Addr reg
optAddr :: forall reg. Addr reg -> Addr reg
optAddr (RC reg
r Int8
0) = reg -> Addr reg
forall reg. reg -> Addr reg
R reg
r
optAddr (RSD reg
b Scale
s reg
i Int8
0) = reg -> Scale -> reg -> Addr reg
forall reg. reg -> Scale -> reg -> Addr reg
RS reg
b Scale
s reg
i
optAddr Addr reg
a = Addr reg
a
occ :: E reg => reg -> Addr reg -> Bool
occ :: forall reg. E reg => reg -> Addr reg -> Bool
occ reg
r Addr reg
a = reg -> Int
forall a. E a => a -> Int
toInt reg
r Int -> IntSet -> Bool
`IS.member` (reg -> IntSet) -> Addr reg -> IntSet
forall m a. Monoid m => (a -> m) -> Addr a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Int -> IntSet
IS.singleton(Int -> IntSet) -> (reg -> Int) -> reg -> IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.reg -> Int
forall a. E a => a -> Int
toInt) Addr reg
a
optX86 :: (E reg, E freg, Eq reg, Eq freg) => [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
optX86 :: forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
optX86 = [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt([X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()])
-> ([X86 reg freg f2 ()] -> [X86 reg freg f2 Liveness])
-> [X86 reg freg f2 ()]
-> [X86 reg freg f2 ()]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[X86 reg freg f2 ()] -> [X86 reg freg f2 Liveness]
forall (arch :: * -> * -> * -> * -> *) reg freg f2.
Arch arch reg freg f2 =>
[arch reg freg f2 ()] -> [arch reg freg f2 Liveness]
mkLive
opt :: (E reg, E freg, Eq reg, Eq freg) => [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt :: forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [] = []
opt (ISubRI Liveness
_ reg
_ Int64
0:[X86 reg freg f2 Liveness]
asms) = [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt (MovqXA Liveness
_ freg
xrϵ Addr reg
a:Vfmadd231sd Liveness
l freg
xr0 freg
xr1 freg
xr2:[X86 reg freg f2 Liveness]
asms) | freg
xr2 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
xrϵ Bool -> Bool -> Bool
&& (freg -> Int
forall a. E a => a -> Int
toInt freg
xr2 Int -> IntSet -> Bool
`IS.notMember` Liveness -> IntSet
fout Liveness
l) = () -> freg -> freg -> Addr reg -> X86 reg freg f2 ()
forall reg freg f2 a.
a -> freg -> freg -> Addr reg -> X86 reg freg f2 a
Vfmadd231sdA () freg
xr0 freg
xr1 (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a)X86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt (MovqXA Liveness
_ freg
xrϵ Addr reg
a:Vmaxsd Liveness
l freg
xr0 freg
xr1 freg
xr2:[X86 reg freg f2 Liveness]
asms) | freg
xr2 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
xrϵ Bool -> Bool -> Bool
&& (freg -> Int
forall a. E a => a -> Int
toInt freg
xr2 Int -> IntSet -> Bool
`IS.notMember` Liveness -> IntSet
fout Liveness
l) = () -> freg -> freg -> Addr reg -> X86 reg freg f2 ()
forall reg freg f2 a.
a -> freg -> freg -> Addr reg -> X86 reg freg f2 a
VmaxsdA () freg
xr0 freg
xr1 (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a)X86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt (MovqXA Liveness
_ freg
xrϵ Addr reg
a:Vaddsd Liveness
l freg
xr0 freg
xr1 freg
xr2:[X86 reg freg f2 Liveness]
asms) | freg
xr2 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
xrϵ Bool -> Bool -> Bool
&& (freg -> Int
forall a. E a => a -> Int
toInt freg
xr2 Int -> IntSet -> Bool
`IS.notMember` Liveness -> IntSet
fout Liveness
l) = () -> freg -> freg -> Addr reg -> X86 reg freg f2 ()
forall reg freg f2 a.
a -> freg -> freg -> Addr reg -> X86 reg freg f2 a
VaddsdA () freg
xr0 freg
xr1 (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a)X86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt (MovqXA Liveness
_ freg
xr0 Addr reg
a:Vaddsd Liveness
_ freg
xr1 freg
xr2 freg
xr3:[X86 reg freg f2 Liveness]
asms) | freg
xr0 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
xr1 Bool -> Bool -> Bool
&& freg
xr0 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
xr3 = () -> freg -> freg -> Addr reg -> X86 reg freg f2 ()
forall reg freg f2 a.
a -> freg -> freg -> Addr reg -> X86 reg freg f2 a
VaddsdA () freg
xr1 freg
xr2 (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a)X86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt (MovqXA Liveness
_ freg
xr0 Addr reg
a:X86 reg freg f2 Liveness
asm:Vaddsd Liveness
_ freg
xr1 freg
xr2 freg
xr3:[X86 reg freg f2 Liveness]
asms) | freg
xr0 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
xr2 Bool -> Bool -> Bool
&& (freg -> Int
forall a. E a => a -> Int
toInt freg
xr0 Int -> IntSet -> Bool
`IS.notMember` X86 reg freg f2 Liveness -> IntSet
forall freg reg f2reg ann.
E freg =>
X86 reg freg f2reg ann -> IntSet
defsF X86 reg freg f2 Liveness
asm) = X86 reg freg f2 Liveness -> X86 reg freg f2 ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void X86 reg freg f2 Liveness
asmX86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:() -> freg -> freg -> Addr reg -> X86 reg freg f2 ()
forall reg freg f2 a.
a -> freg -> freg -> Addr reg -> X86 reg freg f2 a
VaddsdA () freg
xr1 freg
xr3 (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a)X86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt ((MovqAX Liveness
_ Addr reg
a freg
r):[X86 reg freg f2 Liveness]
asms) = () -> Addr reg -> freg -> X86 reg freg f2 ()
forall reg freg f2 a. a -> Addr reg -> freg -> X86 reg freg f2 a
MovqAX () (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a) freg
rX86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt ((MovqXA Liveness
_ freg
r Addr reg
a):[X86 reg freg f2 Liveness]
asms) = () -> freg -> Addr reg -> X86 reg freg f2 ()
forall reg freg f2 a. a -> freg -> Addr reg -> X86 reg freg f2 a
MovqXA () freg
r (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a)X86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt (isn :: X86 reg freg f2 Liveness
isn@(MovRA Liveness
_ reg
r0 Addr reg
a0):MovAR Liveness
_ Addr reg
a1 reg
r1:[X86 reg freg f2 Liveness]
asms) | reg
r0 reg -> reg -> Bool
forall a. Eq a => a -> a -> Bool
== reg
r1 Bool -> Bool -> Bool
&& Bool -> Bool
not (reg -> Addr reg -> Bool
forall reg. E reg => reg -> Addr reg -> Bool
occ reg
r0 Addr reg
a0) Bool -> Bool -> Bool
&& Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a0 Addr reg -> Addr reg -> Bool
forall a. Eq a => a -> a -> Bool
== Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a1 = [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt (X86 reg freg f2 Liveness
isnX86 reg freg f2 Liveness
-> [X86 reg freg f2 Liveness] -> [X86 reg freg f2 Liveness]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness]
asms)
opt (isn :: X86 reg freg f2 Liveness
isn@(MovRA Liveness
_ reg
r0 Addr reg
a0):MovRA Liveness
_ reg
r1 Addr reg
a1:[X86 reg freg f2 Liveness]
asms) | reg
r0 reg -> reg -> Bool
forall a. Eq a => a -> a -> Bool
== reg
r1 Bool -> Bool -> Bool
&& Bool -> Bool
not (reg -> Addr reg -> Bool
forall reg. E reg => reg -> Addr reg -> Bool
occ reg
r0 Addr reg
a0) Bool -> Bool -> Bool
&& Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a0 Addr reg -> Addr reg -> Bool
forall a. Eq a => a -> a -> Bool
== Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a1 = [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt (X86 reg freg f2 Liveness
isnX86 reg freg f2 Liveness
-> [X86 reg freg f2 Liveness] -> [X86 reg freg f2 Liveness]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness]
asms)
opt (isn :: X86 reg freg f2 Liveness
isn@(MovAR Liveness
_ Addr reg
a0 reg
r0):MovRA Liveness
_ reg
r1 Addr reg
a1:[X86 reg freg f2 Liveness]
asms) | Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a0 Addr reg -> Addr reg -> Bool
forall a. Eq a => a -> a -> Bool
== Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a1 = [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt (X86 reg freg f2 Liveness
isnX86 reg freg f2 Liveness
-> [X86 reg freg f2 Liveness] -> [X86 reg freg f2 Liveness]
forall a. a -> [a] -> [a]
:Liveness -> reg -> reg -> X86 reg freg f2 Liveness
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
MovRR Liveness
forall a. HasCallStack => a
undefined reg
r1 reg
r0X86 reg freg f2 Liveness
-> [X86 reg freg f2 Liveness] -> [X86 reg freg f2 Liveness]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness]
asms)
opt ((MovAR Liveness
_ Addr reg
a reg
r):[X86 reg freg f2 Liveness]
asms) = () -> Addr reg -> reg -> X86 reg freg f2 ()
forall reg freg f2 a. a -> Addr reg -> reg -> X86 reg freg f2 a
MovAR () (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a) reg
rX86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt ((MovRA Liveness
_ reg
r Addr reg
a):[X86 reg freg f2 Liveness]
asms) = () -> reg -> Addr reg -> X86 reg freg f2 ()
forall reg freg f2 a. a -> reg -> Addr reg -> X86 reg freg f2 a
MovRA () reg
r (Addr reg -> Addr reg
forall reg. Addr reg -> Addr reg
optAddr Addr reg
a)X86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt ((MovRR Liveness
_ reg
r0 reg
r1):[X86 reg freg f2 Liveness]
asms) | reg
r0 reg -> reg -> Bool
forall a. Eq a => a -> a -> Bool
== reg
r1 = [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt ((Movapd Liveness
_ freg
r0 freg
r1):[X86 reg freg f2 Liveness]
asms) | freg
r0 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
r1 = [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms
opt (isn :: X86 reg freg f2 Liveness
isn@(Movapd Liveness
_ freg
r0 freg
r1):(Movapd Liveness
_ freg
r0' freg
r1'):[X86 reg freg f2 Liveness]
asms) | freg
r0 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
r1' Bool -> Bool -> Bool
&& freg
r1 freg -> freg -> Bool
forall a. Eq a => a -> a -> Bool
== freg
r0' = [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt (X86 reg freg f2 Liveness
isnX86 reg freg f2 Liveness
-> [X86 reg freg f2 Liveness] -> [X86 reg freg f2 Liveness]
forall a. a -> [a] -> [a]
:[X86 reg freg f2 Liveness]
asms)
opt (X86 reg freg f2 Liveness
asm:[X86 reg freg f2 Liveness]
asms) = X86 reg freg f2 Liveness -> X86 reg freg f2 ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void X86 reg freg f2 Liveness
asm X86 reg freg f2 () -> [X86 reg freg f2 ()] -> [X86 reg freg f2 ()]
forall a. a -> [a] -> [a]
: [X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
forall reg freg f2.
(E reg, E freg, Eq reg, Eq freg) =>
[X86 reg freg f2 Liveness] -> [X86 reg freg f2 ()]
opt [X86 reg freg f2 Liveness]
asms