synthesizer-llvm-1.2: src/Synthesizer/LLVM/Frame/SerialVector/Code.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Synthesizer.LLVM.Frame.SerialVector.Code (
T(Cons), Value, size,
fromOrdinary, toOrdinary,
fromNiceVector, toNiceVector,
extract, insert, modify,
assemble, dissect,
assemble1, dissect1,
upsample, subsample, last,
reverse, shiftUp, shiftUpMultiZero, shiftDown,
cumulate, iterate,
scale,
) where
import qualified LLVM.Extra.Nice.Vector.Instance as NiceVectorInst
import qualified LLVM.Extra.Nice.Vector as NiceVector
import qualified LLVM.Extra.Nice.Value.Storable as Storable
import qualified LLVM.Extra.Nice.Value.Marshal as Marshal
import qualified LLVM.Extra.Nice.Value.Vector as NiceValueVec
import qualified LLVM.Extra.Nice.Value as NiceValue
import qualified LLVM.Extra.Arithmetic as A
import qualified LLVM.Core as LLVM
import qualified Type.Data.Num.Decimal as TypeNum
import qualified Foreign.Storable as Store
import Foreign.Storable (Storable)
import Foreign.Ptr (castPtr)
import Control.Applicative ((<$>))
import qualified Data.NonEmpty as NonEmpty
import Data.Word (Word32)
import Data.Tuple.HT (mapSnd)
import Prelude as P hiding (last, reverse, iterate)
newtype T n a = Cons (LLVM.Vector n a)
deriving (Eq, Num)
type Value n a = NiceValue.T (T n a)
instance (TypeNum.Positive n, NiceVector.C a) => NiceValue.C (T n a) where
type Repr (T n a) = NiceVector.Repr n a
cons (Cons v) = fromOrdinary $ NiceValue.cons v
undef = fromOrdinary NiceValue.undef
zero = fromOrdinary NiceValue.zero
phi bb = fmap fromOrdinary . NiceValue.phi bb . toOrdinary
addPhi bb a b = NiceValue.addPhi bb (toOrdinary a) (toOrdinary b)
instance (Marshal.Vector n a) => Marshal.C (T n a) where
pack (Cons v) = Marshal.pack v
unpack = Cons . Marshal.unpack
instance (TypeNum.Positive n, Storable a) => Storable (T n a) where
sizeOf (Cons v) = Store.sizeOf v
alignment (Cons v) = Store.alignment v
poke ptr (Cons v) = Store.poke (castPtr ptr) v
peek ptr = Cons <$> Store.peek (castPtr ptr)
instance
(TypeNum.Positive n, Storable.Vector a, NiceVector.C a) =>
Storable.C (T n a) where
load ptr = fmap fromOrdinary $ Storable.load =<< LLVM.bitcast ptr
store v ptr = Storable.store (toOrdinary v) =<< LLVM.bitcast ptr
instance
(TypeNum.Positive n, NiceVector.IntegerConstant a) =>
NiceValue.IntegerConstant (T n a) where
fromInteger' = fromNiceVector . NiceVector.fromInteger'
instance
(TypeNum.Positive n, NiceVector.RationalConstant a) =>
NiceValue.RationalConstant (T n a) where
fromRational' = fromNiceVector . NiceVector.fromRational'
instance
(TypeNum.Positive n, NiceVector.Additive a) =>
NiceValue.Additive (T n a) where
add = lift2 NiceVector.add
sub = lift2 NiceVector.sub
neg = lift1 NiceVector.neg
instance
(TypeNum.Positive n, NiceVector.PseudoRing a) =>
NiceValue.PseudoRing (T n a) where
mul = lift2 NiceVector.mul
scale ::
(TypeNum.Positive n, NiceVector.PseudoRing a) =>
NiceValue.T a -> Value n a -> LLVM.CodeGenFunction r (Value n a)
scale = lift1 . NiceVector.scale
instance
(TypeNum.Positive n, NiceVector.Real a) =>
NiceValue.Real (T n a) where
min = lift2 NiceVector.min
max = lift2 NiceVector.max
abs = lift1 NiceVector.abs
signum = lift1 NiceVector.signum
instance
(TypeNum.Positive n, NiceVector.Fraction a) =>
NiceValue.Fraction (T n a) where
truncate = lift1 NiceVector.truncate
fraction = lift1 NiceVector.fraction
instance
(TypeNum.Positive n, NiceVector.Field a) =>
NiceValue.Field (T n a) where
fdiv = lift2 NiceVector.fdiv
instance
(TypeNum.Positive n, NiceVector.Algebraic a) =>
NiceValue.Algebraic (T n a) where
sqrt = lift1 NiceVector.sqrt
instance
(TypeNum.Positive n, NiceVector.Transcendental a) =>
NiceValue.Transcendental (T n a) where
pi = fmap fromNiceVector NiceVector.pi
sin = lift1 NiceVector.sin
log = lift1 NiceVector.log
exp = lift1 NiceVector.exp
cos = lift1 NiceVector.cos
pow = lift2 NiceVector.pow
instance
(TypeNum.Positive n, n ~ m,
NiceVector.NativeInteger n a ar,
NiceValue.NativeInteger a ar) =>
NiceValueVec.NativeInteger (T n a) (LLVM.Vector m ar) where
instance
(TypeNum.Positive n, n ~ m,
NiceVector.NativeFloating n a ar,
NiceValue.NativeFloating a ar) =>
NiceValueVec.NativeFloating (T n a) (LLVM.Vector m ar) where
lift1 ::
(Functor f) =>
(NiceVector.T n a -> f (NiceVector.T m b)) ->
(Value n a -> f (Value m b))
lift1 f a = fromNiceVector <$> f (toNiceVector a)
lift2 ::
(Functor f) =>
(NiceVector.T n a -> NiceVector.T m b -> f (NiceVector.T k c)) ->
(Value n a -> Value m b -> f (Value k c))
lift2 f a b = fromNiceVector <$> f (toNiceVector a) (toNiceVector b)
extract ::
(TypeNum.Positive n,
NiceVector.C x, NiceValue.T x ~ a, Value n x ~ v) =>
LLVM.Value Word32 -> v -> LLVM.CodeGenFunction r a
extract i v = NiceVector.extract i (toNiceVector v)
insert ::
(TypeNum.Positive n,
NiceVector.C x, NiceValue.T x ~ a, Value n x ~ v) =>
LLVM.Value Word32 -> a -> v -> LLVM.CodeGenFunction r v
insert i a v =
fromNiceVector <$> NiceVector.insert i a (toNiceVector v)
modify ::
(TypeNum.Positive n,
NiceVector.C x, NiceValue.T x ~ a, Value n x ~ v) =>
LLVM.Value Word32 ->
(a -> LLVM.CodeGenFunction r a) ->
v -> LLVM.CodeGenFunction r v
modify k f v = flip (insert k) v =<< f =<< extract k v
assemble ::
(TypeNum.Positive n, NiceVector.C a) =>
[NiceValue.T a] ->
LLVM.CodeGenFunction r (Value n a)
assemble = fmap fromNiceVector . NiceVector.assemble
dissect ::
(TypeNum.Positive n, NiceVector.C a) =>
Value n a ->
LLVM.CodeGenFunction r [NiceValue.T a]
dissect = NiceVector.dissect . toNiceVector
assemble1 ::
(TypeNum.Positive n, NiceVector.C a) =>
NonEmpty.T [] (NiceValue.T a) ->
LLVM.CodeGenFunction r (Value n a)
assemble1 = fmap fromNiceVector . NiceVector.assemble1
dissect1 ::
(TypeNum.Positive n, NiceVector.C a) =>
Value n a ->
LLVM.CodeGenFunction r (NonEmpty.T [] (NiceValue.T a))
dissect1 = NiceVector.dissect1 . toNiceVector
sizeS :: TypeNum.Positive n => Value n a -> TypeNum.Singleton n
sizeS _ = TypeNum.singleton
size :: (TypeNum.Positive n, P.Integral i) => Value n a -> i
size = TypeNum.integralFromSingleton . sizeS
last ::
(TypeNum.Positive n, NiceVector.C a) =>
Value n a -> LLVM.CodeGenFunction r (NiceValue.T a)
last v = extract (LLVM.valueOf (size v - 1 :: Word32)) v
subsample ::
(TypeNum.Positive n, NiceVector.C a) =>
Value n a -> LLVM.CodeGenFunction r (NiceValue.T a)
subsample = extract (A.zero :: LLVM.Value Word32)
upsample ::
(TypeNum.Positive n, NiceVector.C a) =>
NiceValue.T a -> LLVM.CodeGenFunction r (Value n a)
upsample = fmap fromOrdinary . NiceValueVec.replicate
reverse ::
(TypeNum.Positive n, NiceVector.C a) =>
Value n a -> LLVM.CodeGenFunction r (Value n a)
reverse =
fmap fromNiceVector . NiceVector.reverse . toNiceVector
shiftUp ::
(TypeNum.Positive n, NiceVector.C x,
NiceValue.T x ~ a, Value n x ~ v) =>
a -> v -> LLVM.CodeGenFunction r (a, v)
shiftUp a v =
mapSnd fromNiceVector <$> NiceVector.shiftUp a (toNiceVector v)
shiftUpMultiZero ::
(TypeNum.Positive n, NiceVector.C x, Value n x ~ v) =>
Int -> v -> LLVM.CodeGenFunction r v
shiftUpMultiZero k v =
fromNiceVector <$> NiceVector.shiftUpMultiZero k (toNiceVector v)
shiftDown ::
(TypeNum.Positive n, NiceVector.C x,
NiceValue.T x ~ a, Value n x ~ v) =>
a -> v -> LLVM.CodeGenFunction r (a, v)
shiftDown a v =
mapSnd fromNiceVector <$> NiceVector.shiftDown a (toNiceVector v)
iterate ::
(TypeNum.Positive n, NiceVector.C a) =>
(NiceValue.T a -> LLVM.CodeGenFunction r (NiceValue.T a)) ->
NiceValue.T a -> LLVM.CodeGenFunction r (Value n a)
iterate f = fmap fromOrdinary . NiceValueVec.iterate f
cumulate ::
(TypeNum.Positive n, NiceVector.Additive a) =>
NiceValue.T a -> Value n a ->
LLVM.CodeGenFunction r (NiceValue.T a, Value n a)
cumulate a =
fmap (mapSnd fromNiceVector) . NiceVector.cumulate a . toNiceVector
fromOrdinary :: NiceValue.T (LLVM.Vector n a) -> Value n a
fromOrdinary = NiceValue.cast
toOrdinary :: Value n a -> NiceValue.T (LLVM.Vector n a)
toOrdinary = NiceValue.cast
fromNiceVector :: NiceVector.T n a -> Value n a
fromNiceVector = fromOrdinary . NiceVectorInst.toNiceValue
toNiceVector :: Value n a -> NiceVector.T n a
toNiceVector = NiceVectorInst.fromNiceValue . toOrdinary