llvm-extra-0.5: src/LLVM/Extra/Multi/Vector.hs
{-# LANGUAGE TypeFamilies #-}
module LLVM.Extra.Multi.Vector where
import qualified LLVM.Extra.Multi.Value as MultiValue
import qualified LLVM.Extra.Vector as Vector
import qualified LLVM.Extra.Class as Class
import qualified LLVM.Core as LLVM
import LLVM.Core
(Value, ConstValue, valueOf, value,
IsPrimitive,
CodeGenFunction, )
import qualified Types.Data.Num as TypeNum
import qualified Data.List as List
import Data.Word (Word32, )
import Control.Monad (liftM2, liftM3, foldM, )
import Prelude hiding (zip, zip3, unzip, unzip3, )
newtype T n a = Cons (Vector n a)
instance (TypeNum.PositiveT n, C a) => Class.Undefined (T n a) where
undefTuple = undef
size :: TypeNum.PositiveT n => T n a -> Int
size =
let sz :: TypeNum.PositiveT n => n -> T n a -> Int
sz n _ = TypeNum.fromIntegerT n
in sz undefined
zip :: T n a -> T n b -> T n (a,b)
zip (Cons a) (Cons b) = Cons (a,b)
zip3 :: T n a -> T n b -> T n c -> T n (a,b,c)
zip3 (Cons a) (Cons b) (Cons c) = Cons (a,b,c)
unzip :: T n (a,b) -> (T n a, T n b)
unzip (Cons (a,b)) = (Cons a, Cons b)
unzip3 :: T n (a,b,c) -> (T n a, T n b, T n c)
unzip3 (Cons (a,b,c)) = (Cons a, Cons b, Cons c)
class C a where
type Vector n a :: *
undef :: (TypeNum.PositiveT n) => T n a
shuffleMatch ::
(TypeNum.PositiveT n) =>
ConstValue (LLVM.Vector n Word32) -> T n a -> CodeGenFunction r (T n a)
extract ::
(TypeNum.PositiveT n) =>
LLVM.Value Word32 -> T n a -> CodeGenFunction r (MultiValue.T a)
insert ::
(TypeNum.PositiveT n) =>
LLVM.Value Word32 -> MultiValue.T a ->
T n a -> CodeGenFunction r (T n a)
instance C Float where
type Vector n Float = LLVM.Value (LLVM.Vector n Float)
undef = undefPrimitive
shuffleMatch = shuffleMatchPrimitive
extract = extractPrimitive
insert = insertPrimitive
instance C Double where
type Vector n Double = LLVM.Value (LLVM.Vector n Double)
undef = undefPrimitive
shuffleMatch = shuffleMatchPrimitive
extract = extractPrimitive
insert = insertPrimitive
undefPrimitive ::
(TypeNum.PositiveT n, IsPrimitive a,
Vector n a ~ Value (LLVM.Vector n a)) =>
T n a
undefPrimitive = Cons $ LLVM.value LLVM.undef
shuffleMatchPrimitive ::
(TypeNum.PositiveT n, IsPrimitive a,
Vector n a ~ Value (LLVM.Vector n a),
Class.ValueTuple a ~ Value a) =>
ConstValue (LLVM.Vector n Word32) -> T n a -> CodeGenFunction r (T n a)
shuffleMatchPrimitive k (Cons v) =
fmap Cons $ LLVM.shufflevector v (value LLVM.undef) k
extractPrimitive ::
(TypeNum.PositiveT n, IsPrimitive a,
Vector n a ~ Value (LLVM.Vector n a),
Class.ValueTuple a ~ Value a) =>
Value Word32 -> T n a -> CodeGenFunction r (MultiValue.T a)
extractPrimitive k (Cons v) =
fmap MultiValue.Cons $ LLVM.extractelement v k
insertPrimitive ::
(TypeNum.PositiveT n, IsPrimitive a,
Vector n a ~ Value (LLVM.Vector n a),
Class.ValueTuple a ~ Value a) =>
Value Word32 ->
MultiValue.T a -> T n a -> CodeGenFunction r (T n a)
insertPrimitive k (MultiValue.Cons a) (Cons v) =
fmap Cons $ LLVM.insertelement v a k
instance (C a, C b) => C (a,b) where
type Vector n (a,b) = (Vector n a, Vector n b)
undef = zip undef undef
shuffleMatch is v =
case unzip v of
(v0,v1) ->
liftM2 zip
(shuffleMatch is v0)
(shuffleMatch is v1)
extract k v =
case unzip v of
(v0,v1) ->
liftM2 MultiValue.zip
(extract k v0)
(extract k v1)
insert k a v =
case (MultiValue.unzip a, unzip v) of
((a0,a1), (v0,v1)) ->
liftM2 zip
(insert k a0 v0)
(insert k a1 v1)
instance (C a, C b, C c) => C (a,b,c) where
type Vector n (a,b,c) = (Vector n a, Vector n b, Vector n c)
undef = zip3 undef undef undef
shuffleMatch is v =
case unzip3 v of
(v0,v1,v2) ->
liftM3 zip3
(shuffleMatch is v0)
(shuffleMatch is v1)
(shuffleMatch is v2)
extract k v =
case unzip3 v of
(v0,v1,v2) ->
liftM3 MultiValue.zip3
(extract k v0)
(extract k v1)
(extract k v2)
insert k a v =
case (MultiValue.unzip3 a, unzip3 v) of
((a0,a1,a2), (v0,v1,v2)) ->
liftM3 zip3
(insert k a0 v0)
(insert k a1 v1)
(insert k a2 v2)
assemble ::
(TypeNum.PositiveT n, C a) =>
[MultiValue.T a] -> CodeGenFunction r (T n a)
assemble =
foldM (\v (k,x) -> insert (valueOf k) x v) undef .
List.zip [0..]
dissect ::
(TypeNum.PositiveT n, C a) =>
T n a -> LLVM.CodeGenFunction r [MultiValue.T a]
dissect x =
mapM
(flip extract x . LLVM.valueOf)
(take (size x) [0..])
-- * function based on classes from Vector module
shuffleMatchGen ::
(Vector n a ~ v, Vector.Simple v, n ~ Vector.Size v) =>
ConstValue (LLVM.Vector n Word32) ->
T n a -> CodeGenFunction r (T n a)
shuffleMatchGen is (Cons v) =
fmap Cons $ Vector.shuffleMatch is v
extractGen ::
(Vector n a ~ v, Vector.Simple v, Class.ValueTuple a ~ Vector.Element v) =>
LLVM.Value Word32 -> T n a -> CodeGenFunction r (MultiValue.T a)
extractGen n (Cons v) =
fmap MultiValue.Cons $ Vector.extract n v
insertGen ::
(Vector n a ~ v, Vector.C v, Class.ValueTuple a ~ Vector.Element v) =>
LLVM.Value Word32 -> MultiValue.T a ->
T n a -> CodeGenFunction r (T n a)
insertGen n (MultiValue.Cons a) (Cons v) =
fmap Cons $ Vector.insert n a v