llvm-extra 0.9.1 → 0.10
raw patch · 37 files changed
+2133/−1389 lines, 37 filesdep +base-orphansdep +fixed-lengthdep +storable-recorddep ~llvm-tfdep ~utility-ht
Dependencies added: base-orphans, fixed-length, storable-record
Dependency ranges changed: llvm-tf, utility-ht
Files
- Changes.md +17/−0
- llvm-extra.cabal +22/−9
- private/LLVM/Extra/ArithmeticPrivate.hs +4/−5
- private/LLVM/Extra/ScalarOrVectorPrivate.hs +5/−1
- src/Array.hs +12/−10
- src/LLVM/Extra/Arithmetic.hs +2/−2
- src/LLVM/Extra/Array.hs +2/−2
- src/LLVM/Extra/Class.hs +0/−220
- src/LLVM/Extra/Control.hs +47/−38
- src/LLVM/Extra/Either.hs +5/−5
- src/LLVM/Extra/EitherPrivate.hs +12/−6
- src/LLVM/Extra/FastMath.hs +18/−9
- src/LLVM/Extra/Iterator.hs +28/−24
- src/LLVM/Extra/Marshal.hs +211/−127
- src/LLVM/Extra/Maybe.hs +4/−5
- src/LLVM/Extra/MaybeContinuation.hs +21/−23
- src/LLVM/Extra/MaybePrivate.hs +10/−7
- src/LLVM/Extra/Memory.hs +92/−66
- src/LLVM/Extra/MemoryPrivate.hs +2/−4
- src/LLVM/Extra/Multi/Iterator.hs +3/−3
- src/LLVM/Extra/Multi/Value/Memory.hs +0/−257
- src/LLVM/Extra/Multi/Value/Private.hs +246/−154
- src/LLVM/Extra/Multi/Value/Vector.hs +33/−52
- src/LLVM/Extra/Multi/Vector.hs +136/−107
- src/LLVM/Extra/Multi/Vector/Instance.hs +2/−5
- src/LLVM/Extra/Multi/Vector/Memory.hs +0/−172
- src/LLVM/Extra/Scalar.hs +8/−11
- src/LLVM/Extra/ScalarOrVector.hs +11/−1
- src/LLVM/Extra/Storable.hs +47/−0
- src/LLVM/Extra/Storable/Array.hs +75/−0
- src/LLVM/Extra/Storable/Private.hs +499/−0
- src/LLVM/Extra/Tuple.hs +246/−0
- src/LLVM/Extra/TuplePrivate.hs +140/−0
- src/LLVM/Extra/Vector.hs +40/−22
- test/Main.hs +4/−1
- test/Test/Storable.hs +99/−0
- test/Test/Vector.hs +30/−41
Changes.md view
@@ -1,5 +1,22 @@ # Change log for the `llvm-extra` package +## 0.10++* `Memory`: Attention!+ Memory layout is no longer compatible with `Foreign.Storable`.+ E.g. `Bool` now takes 1 byte space like LLVM does,+ but no longer 4 byte like `Foreign.Storable`.+ A `Foreign.Storable`-compliant layout+ is provided by `LLVM.Extra.Storable` now.++* `Marshal`: Now based on `Memory.load` and `Memory.store`.+ Does not need `Proxy` anymore.++* `Class` -> `Tuple`,+ `Tuple.Vector` class added.+ Pro: `valueOf vector` is no longer restricted to `IsPrimitive` elements.+ Cons: type inference works less well than before+ ## 0.9 * `Extension`: Move to new package `llvm-extension`.
llvm-extra.cabal view
@@ -1,6 +1,6 @@ Cabal-Version: 2.2 Name: llvm-extra-Version: 0.9.1+Version: 0.10 License: BSD-3-Clause License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>@@ -21,9 +21,15 @@ * a type class for loading and storing sets of values with one command (macro) in "LLVM.Extra.Memory", .- * support instance declarations of LLVM classes- in "LLVM.Extra.Class",+ * storing and reading Haskell values in an LLVM compatible format+ in "LLVM.Extra.Marshal", .+ * LLVM functions for loading and storing values in Haskell's @Storable@ format+ in "LLVM.Extra.Storable",+ .+ * support value tuples and instance declarations of LLVM classes+ in "LLVM.Extra.Tuple",+ . * handling of termination by a custom monad on top of @CodeGenFunction@ in "LLVM.Extra.MaybeContinuation" .@@ -55,7 +61,7 @@ default: False Source-Repository this- Tag: 0.9.1+ Tag: 0.10 Type: darcs Location: http://code.haskell.org/~thielema/llvm-extra/ @@ -66,17 +72,20 @@ Library Build-Depends: private,- llvm-tf >=9.1 && <9.2,+ llvm-tf >=9.2 && <9.3, tfp >=1.0 && <1.1, non-empty >=0.2.1 && <0.4,+ fixed-length >=0.2.1 && <0.3, containers >=0.1 && <0.7, enumset >=0.0.5 && <0.1,+ storable-record >=0.0.5 && <0.1, storable-enum >=0.0 && <0.1, bool8 >=0.0 && <0.1, transformers >=0.1.1 && <0.6, tagged >=0.7 && <0.9,- utility-ht >=0.0.11 && <0.1,+ utility-ht >=0.0.15 && <0.1, prelude-compat >=0.0 && <0.0.1,+ base-orphans >= 0.5 && <1, base >=3 && <5 Default-Language: Haskell98@@ -87,10 +96,11 @@ LLVM.Extra.Monad LLVM.Extra.Memory LLVM.Extra.Marshal+ LLVM.Extra.Storable LLVM.Extra.Maybe LLVM.Extra.MaybeContinuation LLVM.Extra.Either- LLVM.Extra.Class+ LLVM.Extra.Tuple LLVM.Extra.Control LLVM.Extra.Array LLVM.Extra.Scalar@@ -100,13 +110,14 @@ LLVM.Extra.Iterator LLVM.Extra.Multi.Iterator LLVM.Extra.Multi.Value- LLVM.Extra.Multi.Value.Memory LLVM.Extra.Multi.Value.Vector LLVM.Extra.Multi.Vector- LLVM.Extra.Multi.Vector.Memory LLVM.Extra.Multi.Vector.Instance LLVM.Extra.Multi.Class Other-Modules:+ LLVM.Extra.Storable.Array+ LLVM.Extra.Storable.Private+ LLVM.Extra.TuplePrivate LLVM.Extra.MaybePrivate LLVM.Extra.EitherPrivate LLVM.Extra.MemoryPrivate@@ -152,6 +163,7 @@ llvm-extra, llvm-tf, tfp,+ storable-record, utility-ht >=0.0.1 && <0.1, base >=3 && <5 Default-Language: Haskell98@@ -159,5 +171,6 @@ Hs-Source-Dirs: test Main-Is: Main.hs Other-Modules:+ Test.Storable Test.Vector LLVM.Extra.VectorAlt
private/LLVM/Extra/ArithmeticPrivate.hs view
@@ -10,7 +10,6 @@ IsConst, IsPrimitive, IsArithmetic, IsInteger, IsFloating, getElementPtr, ) -import Foreign.Ptr (Ptr, ) import Data.Word (Word32, ) import Data.Int (Int32, ) @@ -39,14 +38,14 @@ dec x = sub x (valueOf 1) advanceArrayElementPtr ::- Value (Ptr a) ->- CodeGenFunction r (Value (Ptr a))+ Value (LLVM.Ptr a) ->+ CodeGenFunction r (Value (LLVM.Ptr a)) advanceArrayElementPtr p = getElementPtr p (valueOf 1 :: Value Word32, ()) decreaseArrayElementPtr ::- Value (Ptr a) ->- CodeGenFunction r (Value (Ptr a))+ Value (LLVM.Ptr a) ->+ CodeGenFunction r (Value (LLVM.Ptr a)) decreaseArrayElementPtr p = getElementPtr p (valueOf (-1) :: Value Int32, ())
private/LLVM/Extra/ScalarOrVectorPrivate.hs view
@@ -14,7 +14,7 @@ IsConst, IsInteger, CodeGenFunction) import qualified Data.NonEmpty as NonEmpty-import Data.Word (Word8, Word16, Word32, Word64)+import Data.Word (Word8, Word16, Word32, Word64, Word) import Data.Int (Int8, Int16, Int32, Int64) import Prelude hiding (replicate)@@ -26,10 +26,12 @@ type instance Scalar Double = Double type instance Scalar FP128 = FP128 type instance Scalar Bool = Bool+type instance Scalar Int = Int type instance Scalar Int8 = Int8 type instance Scalar Int16 = Int16 type instance Scalar Int32 = Int32 type instance Scalar Int64 = Int64+type instance Scalar Word = Word type instance Scalar Word8 = Word8 type instance Scalar Word16 = Word16 type instance Scalar Word32 = Word32@@ -48,10 +50,12 @@ instance Replicate Double where replicate = return; replicateConst = id; instance Replicate FP128 where replicate = return; replicateConst = id; instance Replicate Bool where replicate = return; replicateConst = id;+instance Replicate Int where replicate = return; replicateConst = id; instance Replicate Int8 where replicate = return; replicateConst = id; instance Replicate Int16 where replicate = return; replicateConst = id; instance Replicate Int32 where replicate = return; replicateConst = id; instance Replicate Int64 where replicate = return; replicateConst = id;+instance Replicate Word where replicate = return; replicateConst = id; instance Replicate Word8 where replicate = return; replicateConst = id; instance Replicate Word16 where replicate = return; replicateConst = id; instance Replicate Word32 where replicate = return; replicateConst = id;
src/Array.hs view
@@ -7,17 +7,18 @@ import qualified LLVM.Extra.Vector as Vector import qualified LLVM.Extra.Iterator as Iter-import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.Arithmetic as A-import LLVM.Extra.Control (arrayLoop, )+import LLVM.Extra.Storable (arrayLoop, store)+import LLVM.Extra.Control (ret) import qualified LLVM.ExecutionEngine as EE import qualified LLVM.Core as LLVM import LLVM.ExecutionEngine (simpleFunction, ) import LLVM.Core (Value, valueOf, value, constOf, undef, zero, add, sub, mul, frem,- createFunction, Function, Linkage(ExternalLinkage), ret,- CodeGenModule, CodeGenFunction, store,+ createFunction, Function, Linkage(ExternalLinkage),+ CodeGenModule, CodeGenFunction, Vector, extractelement, insertelement, shufflevector, ) import qualified System.IO as IO @@ -42,7 +43,7 @@ constVec :: Float -> CodeGenFunction r (Value (Vector D4 Float)) constVec x =- return $ valueOf $ LLVM.toVector (x,x,x,x)+ return $ valueOf $ LLVM.consVector x x x x constVecInsert :: Float -> CodeGenFunction r (Value (Vector D4 Float))@@ -68,7 +69,7 @@ This call fill (fromIntegral len) ptr- (LLVM.toVector (0.01003, 0.01001, 0.00999, 0.00997)) >>+ (LLVM.consVector 0.01003 0.01001 0.00999 0.00997) >> would not work, because Vector is not of type Generic. -}@@ -164,7 +165,7 @@ liftA2 (\ptri phase -> flip store ptri =<< mixGeneric =<< add const1 =<< mul const2 phase)- (Iter.arrayPtrs ptr)+ (Iter.storableArrayPtrs ptr) (Iter.iterate (Vector.fraction <=< A.add freq) (value (zero :: Vec))) ret (value zero :: Value Float) @@ -174,7 +175,8 @@ A.sub (valueOf 1) =<< A.mul (valueOf 2) t -osciSaw :: Value Float -> Value Float -> CodeGenFunction r (Value Float, Value Float)+osciSaw ::+ Value Float -> Value Float -> CodeGenFunction r (Value Float, Value Float) osciSaw freq phase = liftM2 (,) (waveSaw phase) (SoV.incPhase freq phase) @@ -184,7 +186,7 @@ (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float)) mChorus = createFunction ExternalLinkage $ \ size ptr f0 f1 f2 f3 -> do- s <- arrayLoop size ptr Class.zeroTuple $+ s <- arrayLoop size ptr Tuple.zero $ \ ptri ((phase0, phase1), (phase2, phase3)) -> do (y0, phase0') <- osciSaw f0 phase0 (y1, phase1') <- osciSaw f1 phase1@@ -230,7 +232,7 @@ (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float)) mChorusMonadic = createFunction ExternalLinkage $ \ size ptr f0 f1 f2 f3 -> do- s <- arrayLoop size ptr Class.zeroTuple $+ s <- arrayLoop size ptr Tuple.zero $ \ ptri phases -> do (y, phases') <- flip runStateT phases $
src/LLVM/Extra/Arithmetic.hs view
@@ -29,7 +29,7 @@ import LLVM.Extra.ArithmeticPrivate (inc, dec, advanceArrayElementPtr, decreaseArrayElementPtr, ) -import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.ScalarOrVector as SoV import qualified LLVM.Core as LLVM import LLVM.Core@@ -58,7 +58,7 @@ Disadvantage: You cannot use constant values directly, but you have to convert them all to 'Value'. -}-class (Class.Zero a) => Additive a where+class (Tuple.Zero a) => Additive a where zero :: a add :: a -> a -> CodeGenFunction r a sub :: a -> a -> CodeGenFunction r a
src/LLVM/Extra/Array.hs view
@@ -5,7 +5,7 @@ map, ) where -import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Core as LLVM import LLVM.Core (Value, Array, CodeGenFunction, )@@ -44,7 +44,7 @@ (TypeNum.Natural n, LLVM.IsFirstClass a, LLVM.IsSized a) => [Value a] -> CodeGenFunction r (Value (Array n a)) assemble =- foldM (\v (k,x) -> LLVM.insertvalue v x (k::Word32)) Class.undefTuple .+ foldM (\v (k,x) -> LLVM.insertvalue v x (k::Word32)) Tuple.undef . List.zip [0..] {- |
− src/LLVM/Extra/Class.hs
@@ -1,220 +0,0 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE FlexibleContexts #-}-module LLVM.Extra.Class where--import qualified LLVM.Extra.EitherPrivate as Either-import qualified LLVM.Extra.MaybePrivate as Maybe-import qualified LLVM.Core as LLVM-import LLVM.Core- (Value, value, valueOf, undef,- ConstValue,- Vector,- IsConst, IsType, IsFirstClass, IsPrimitive,- CodeGenFunction, BasicBlock, )-import LLVM.Util.Loop (Phi, phis, addPhis, )-import qualified Type.Data.Num.Decimal as TypeNum--import qualified Control.Applicative as App-import Control.Applicative (pure, liftA2, )--import qualified Data.Foldable as Fold-import qualified Data.Traversable as Trav--import Foreign.StablePtr (StablePtr, )-import Foreign.Ptr (FunPtr, Ptr, )--import Data.Word (Word8, Word16, Word32, Word64, )-import Data.Int (Int8, Int16, Int32, Int64, )--import Prelude2010 hiding (and, iterate, map, zipWith, writeFile, )-import Prelude ()----- * class for tuples of undefined values--class Undefined a where- undefTuple :: a--instance Undefined () where- undefTuple = ()--instance (IsFirstClass a) => Undefined (Value a) where- undefTuple = value undef--instance (IsFirstClass a) => Undefined (ConstValue a) where- undefTuple = undef--instance (Undefined a, Undefined b) => Undefined (a, b) where- undefTuple = (undefTuple, undefTuple)--instance (Undefined a, Undefined b, Undefined c) => Undefined (a, b, c) where- undefTuple = (undefTuple, undefTuple, undefTuple)--instance (Undefined a) => Undefined (Maybe.T a) where- undefTuple = Maybe.Cons undefTuple undefTuple--instance (Undefined a, Undefined b) => Undefined (Either.T a b) where- undefTuple = Either.Cons undefTuple undefTuple undefTuple----- * class for tuples of zero values--class Zero a where- zeroTuple :: a--instance Zero () where- zeroTuple = ()--instance (LLVM.IsFirstClass a) => Zero (Value a) where- zeroTuple = LLVM.value LLVM.zero--instance (LLVM.IsFirstClass a) => Zero (ConstValue a) where- zeroTuple = LLVM.zero--instance (Zero a, Zero b) => Zero (a, b) where- zeroTuple = (zeroTuple, zeroTuple)--instance (Zero a, Zero b, Zero c) => Zero (a, b, c) where- zeroTuple = (zeroTuple, zeroTuple, zeroTuple)--zeroTuplePointed ::- (Zero a, App.Applicative f) =>- f a-zeroTuplePointed =- pure zeroTuple----- * class for creating tuples of constant values--class (Undefined (ValueTuple haskellValue)) =>- MakeValueTuple haskellValue where- type ValueTuple haskellValue :: *- valueTupleOf :: haskellValue -> ValueTuple haskellValue--instance (MakeValueTuple ah, MakeValueTuple bh) =>- MakeValueTuple (ah,bh) where- type ValueTuple (ah,bh) = (ValueTuple ah, ValueTuple bh)- valueTupleOf ~(a,b) = (valueTupleOf a, valueTupleOf b)--instance (MakeValueTuple ah, MakeValueTuple bh, MakeValueTuple ch) =>- MakeValueTuple (ah,bh,ch) where- type ValueTuple (ah,bh,ch) = (ValueTuple ah, ValueTuple bh, ValueTuple ch)- valueTupleOf ~(a,b,c) = (valueTupleOf a, valueTupleOf b, valueTupleOf c)--instance (MakeValueTuple a) => MakeValueTuple (Maybe a) where- type ValueTuple (Maybe a) = Maybe.T (ValueTuple a)- valueTupleOf = maybe (Maybe.nothing undefTuple) (Maybe.just . valueTupleOf)--instance- (MakeValueTuple a, MakeValueTuple b) =>- MakeValueTuple (Either a b) where- type ValueTuple (Either a b) = Either.T (ValueTuple a) (ValueTuple b)- valueTupleOf =- either- (Either.left undefTuple . valueTupleOf)- (Either.right undefTuple . valueTupleOf)--instance MakeValueTuple Float where type ValueTuple Float = Value Float ; valueTupleOf = valueOf-instance MakeValueTuple Double where type ValueTuple Double = Value Double ; valueTupleOf = valueOf--- instance MakeValueTuple FP128 where type ValueTuple FP128 = Value FP128 ; valueTupleOf = valueOf-instance MakeValueTuple Bool where type ValueTuple Bool = Value Bool ; valueTupleOf = valueOf-instance MakeValueTuple Int8 where type ValueTuple Int8 = Value Int8 ; valueTupleOf = valueOf-instance MakeValueTuple Int16 where type ValueTuple Int16 = Value Int16 ; valueTupleOf = valueOf-instance MakeValueTuple Int32 where type ValueTuple Int32 = Value Int32 ; valueTupleOf = valueOf-instance MakeValueTuple Int64 where type ValueTuple Int64 = Value Int64 ; valueTupleOf = valueOf-instance MakeValueTuple Word8 where type ValueTuple Word8 = Value Word8 ; valueTupleOf = valueOf-instance MakeValueTuple Word16 where type ValueTuple Word16 = Value Word16 ; valueTupleOf = valueOf-instance MakeValueTuple Word32 where type ValueTuple Word32 = Value Word32 ; valueTupleOf = valueOf-instance MakeValueTuple Word64 where type ValueTuple Word64 = Value Word64 ; valueTupleOf = valueOf-instance MakeValueTuple () where type ValueTuple () = () ; valueTupleOf = id--{--I'm not sure about this instance.-Maybe it is better to convert the pointer target type-according to a class that maps Haskell tuples to LLVM structs.--}-instance IsType a => MakeValueTuple (Ptr a) where- type ValueTuple (Ptr a) = Value (Ptr a)- valueTupleOf = valueOf--instance LLVM.IsFunction a => MakeValueTuple (FunPtr a) where- type ValueTuple (FunPtr a) = Value (FunPtr a)- valueTupleOf = valueOf--instance MakeValueTuple (StablePtr a) where- type ValueTuple (StablePtr a) = Value (StablePtr a)- valueTupleOf = valueOf--{--instance (MakeValueTuple haskellValue llvmValue, Memory llvmValue llvmStruct) =>- MakeValueTuple (Ptr haskellValue) (Value (Ptr llvmStruct)) where- valueTupleOf = valueOf . castTuplePtr--instance (Pos n) => MakeValueTuple (IntN n) where- type ValueTuple (IntN n) = (Value (IntN n))-instance (Pos n) => MakeValueTuple (WordN n) where- type ValueTuple (WordN n) = (Value (WordN n))--}-instance (TypeNum.Positive n, IsPrimitive a, IsConst a) =>- MakeValueTuple (Vector n a) where- type ValueTuple (Vector n a) = Value (Vector n a)- valueTupleOf = valueOf----- * default methods for LLVM classes--{--buildTupleTraversable ::- (Undefined a, Trav.Traversable f, App.Applicative f) =>- FunctionRef -> State Int (f a)-buildTupleTraversable f =- Trav.sequence (pure (buildTuple f))--}-{--buildTupleTraversable ::- (Trav.Traversable f, App.Applicative f) =>- State Int a ->- State Int (f a)-buildTupleTraversable build =- Trav.sequence (pure build)--}-{- this is the version I used-buildTupleTraversable ::- (Monad m, Trav.Traversable f, App.Applicative f) =>- m a ->- m (f a)-buildTupleTraversable build =- Trav.sequence (pure build)--}--undefTuplePointed ::- (Undefined a, App.Applicative f) =>- f a-undefTuplePointed =- pure undefTuple--valueTupleOfFunctor ::- (MakeValueTuple h, Functor f) =>- f h -> f (ValueTuple h)-valueTupleOfFunctor =- fmap valueTupleOf--{--tupleDescFoldable ::- (IsTuple a, Fold.Foldable f) =>- f a -> [TypeDesc]-tupleDescFoldable =- Fold.foldMap tupleDesc--}--phisTraversable ::- (Phi a, Trav.Traversable f) =>- BasicBlock -> f a -> CodeGenFunction r (f a)-phisTraversable bb x =- Trav.mapM (phis bb) x--addPhisFoldable ::- (Phi a, Fold.Foldable f, App.Applicative f) =>- BasicBlock -> f a -> f a -> CodeGenFunction r ()-addPhisFoldable bb x y =- Fold.sequence_ (liftA2 (addPhis bb) x y)
src/LLVM/Extra/Control.hs view
@@ -16,13 +16,15 @@ Select(select), selectTraversable, ifThenSelect,+ ret,+ retVoid, ) where -import LLVM.Extra.ArithmeticPrivate- (cmp, sub, dec, advanceArrayElementPtr, ) import qualified LLVM.Extra.ArithmeticPrivate as A+import qualified LLVM.Extra.TuplePrivate as Tuple+import LLVM.Extra.ArithmeticPrivate (cmp, sub, dec, advanceArrayElementPtr)+ import qualified LLVM.Core as LLVM-import LLVM.Util.Loop (Phi, phis, addPhis, ) import LLVM.Core (getCurrentBasicBlock, newBasicBlock, defineBasicBlock, br, condBr,@@ -33,8 +35,6 @@ CodeGenFunction, CodeGenModule, newModule, defineModule, writeBitcodeToFile, ) -import Foreign.Ptr (Ptr, )- import qualified Control.Applicative as App import qualified Data.Traversable as Trav import Control.Monad (liftM3, liftM2, )@@ -46,14 +46,14 @@ -- * control structures {--I had to export Phi's methods in llvm-0.6.8+I had to export Tuple.Phi's methods in llvm-0.6.8 in order to be able to implement this function. -} arrayLoop ::- (Phi a, IsType b,+ (Tuple.Phi a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>- Value i -> Value (Ptr b) -> a ->- (Value (Ptr b) -> a -> CodeGenFunction r a) ->+ Value i -> Value (LLVM.Ptr b) -> a ->+ (Value (LLVM.Ptr b) -> a -> CodeGenFunction r a) -> CodeGenFunction r a arrayLoop len ptr start loopBody = fmap snd $@@ -63,10 +63,10 @@ (loopBody p s) arrayLoop2 ::- (Phi s, IsType a, IsType b,+ (Tuple.Phi s, IsType a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>- Value i -> Value (Ptr a) -> Value (Ptr b) -> s ->- (Value (Ptr a) -> Value (Ptr b) -> s -> CodeGenFunction r s) ->+ Value i -> Value (LLVM.Ptr a) -> Value (LLVM.Ptr b) -> s ->+ (Value (LLVM.Ptr a) -> Value (LLVM.Ptr b) -> s -> CodeGenFunction r s) -> CodeGenFunction r s arrayLoop2 len ptrA ptrB start loopBody = fmap snd $@@ -78,10 +78,10 @@ arrayLoopWithExit ::- (Phi s, IsType a,+ (Tuple.Phi s, IsType a, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>- Value i -> Value (Ptr a) -> s ->- (Value (Ptr a) -> s -> CodeGenFunction r (Value Bool, s)) ->+ Value i -> Value (LLVM.Ptr a) -> s ->+ (Value (LLVM.Ptr a) -> s -> CodeGenFunction r (Value Bool, s)) -> CodeGenFunction r (Value i, s) arrayLoopWithExit len ptr start loopBody = do ((_, vars), (i,_)) <-@@ -106,10 +106,10 @@ than manual decrement, zero test and conditional branch. -} _arrayLoopWithExitDecLoop ::- (Phi a, IsType b,+ (Tuple.Phi a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>- Value i -> Value (Ptr b) -> a ->- (Value (Ptr b) -> a -> CodeGenFunction r (Value Bool, a)) ->+ Value i -> Value (LLVM.Ptr b) -> a ->+ (Value (LLVM.Ptr b) -> a -> CodeGenFunction r (Value Bool, a)) -> CodeGenFunction r (Value i, a) _arrayLoopWithExitDecLoop len ptr start loopBody = do top <- getCurrentBasicBlock@@ -126,14 +126,14 @@ defineBasicBlock checkEnd i <- phi [(len, top)] p <- phi [(ptr, top)]- vars <- phis top start+ vars <- Tuple.phi top start t <- phi [(t0, top)] condBr t loop exit defineBasicBlock loop (cont, vars') <- loopBody p vars- addPhis next vars vars'+ Tuple.addPhi next vars vars' condBr cont next exit defineBasicBlock next@@ -152,10 +152,10 @@ arrayLoop2WithExit ::- (Phi s, IsType a, IsType b,+ (Tuple.Phi s, IsType a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>- Value i -> Value (Ptr a) -> Value (Ptr b) -> s ->- (Value (Ptr a) -> Value (Ptr b) -> s -> CodeGenFunction r (Value Bool, s)) ->+ Value i -> Value (LLVM.Ptr a) -> Value (LLVM.Ptr b) -> s ->+ (Value (LLVM.Ptr a) -> Value (LLVM.Ptr b) -> s -> CodeGenFunction r (Value Bool, s)) -> CodeGenFunction r (Value i, s) arrayLoop2WithExit len ptrA ptrB start loopBody = fmap (mapSnd snd) $@@ -167,7 +167,7 @@ fixedLengthLoop ::- (Phi s,+ (Tuple.Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) => Value i -> s -> (s -> CodeGenFunction r s) ->@@ -180,7 +180,7 @@ whileLoop, _whileLoop ::- Phi a =>+ Tuple.Phi a => a -> (a -> CodeGenFunction r (Value Bool)) -> (a -> CodeGenFunction r a) ->@@ -198,13 +198,13 @@ br loop defineBasicBlock loop- state <- phis top start+ state <- Tuple.phi top start b <- check state condBr b cont exit defineBasicBlock cont res <- body state cont' <- getCurrentBasicBlock- addPhis cont' state res+ Tuple.addPhi cont' state res br loop defineBasicBlock exit@@ -216,7 +216,7 @@ The @Bool@ value indicates whether the loop shall be continued. -} loopWithExit ::- Phi a =>+ Tuple.Phi a => a -> (a -> CodeGenFunction r (Value Bool, b)) -> (b -> CodeGenFunction r a) ->@@ -229,13 +229,13 @@ br loop defineBasicBlock loop- state <- phis top start+ state <- Tuple.phi top start (contB,b) <- check state condBr contB cont exit defineBasicBlock cont a <- body b cont' <- getCurrentBasicBlock- addPhis cont' state a+ Tuple.addPhi cont' state a br loop defineBasicBlock exit@@ -248,7 +248,7 @@ for both loop condition and loop body. -} whileLoopShared ::- Phi a =>+ Tuple.Phi a => a -> (a -> (CodeGenFunction r (Value Bool),@@ -264,7 +264,7 @@ so be prepared when continueing after an 'ifThenElse'. -} ifThenElse ::- Phi a =>+ Tuple.Phi a => Value Bool -> CodeGenFunction r a -> CodeGenFunction r a ->@@ -286,13 +286,13 @@ br mergeBlock defineBasicBlock mergeBlock- a2 <- phis thenBlock' a0- addPhis elseBlock' a2 a1+ a2 <- Tuple.phi thenBlock' a0+ Tuple.addPhi elseBlock' a2 a1 return a2 ifThen ::- Phi a =>+ Tuple.Phi a => Value Bool -> a -> CodeGenFunction r a ->@@ -309,12 +309,12 @@ br mergeBlock defineBasicBlock mergeBlock- a1 <- phis defltBlock deflt- addPhis thenBlock' a1 a0+ a1 <- Tuple.phi defltBlock deflt+ Tuple.addPhi thenBlock' a1 a0 return a1 -class Phi a => Select a where+class Tuple.Phi a => Select a where select :: Value Bool -> a -> a -> CodeGenFunction r a instance (CmpRet a, IsPrimitive a) => Select (Value a) where@@ -359,6 +359,15 @@ ifThenSelect cond deflt thenCode = do thenResult <- thenCode select cond thenResult deflt+++-- * return with better type inference++ret :: Value a -> CodeGenFunction a ()+ret = LLVM.ret++retVoid :: CodeGenFunction () ()+retVoid = LLVM.ret () -- * debugging
src/LLVM/Extra/Either.hs view
@@ -13,11 +13,11 @@ ) where import qualified LLVM.Extra.EitherPrivate as Either-import LLVM.Extra.Class (Undefined, undefTuple, )+import qualified LLVM.Extra.Tuple as Tuple -left :: (Undefined b) => a -> Either.T a b-left = Either.left undefTuple+left :: (Tuple.Undefined b) => a -> Either.T a b+left = Either.left Tuple.undef -right :: (Undefined a) => b -> Either.T a b-right = Either.right undefTuple+right :: (Tuple.Undefined a) => b -> Either.T a b+right = Either.right Tuple.undef
src/LLVM/Extra/EitherPrivate.hs view
@@ -1,11 +1,11 @@ {-# LANGUAGE TypeFamilies #-} module LLVM.Extra.EitherPrivate where +import qualified LLVM.Extra.TuplePrivate as Tuple import LLVM.Extra.Control (ifThenElse, ) import qualified LLVM.Core as LLVM import LLVM.Core (Value, valueOf, CodeGenFunction, )-import LLVM.Util.Loop (Phi, phis, addPhis, ) import Control.Monad (liftM3, ) @@ -19,17 +19,23 @@ data T a b = Cons {isRight :: Value Bool, fromLeft :: a, fromRight :: b} -instance (Phi a, Phi b) => Phi (T a b) where- phis bb (Cons r a b) = liftM3 Cons (phis bb r) (phis bb a) (phis bb b)- addPhis bb (Cons r0 a0 b0) (Cons r1 a1 b1) =- addPhis bb r0 r1 >> addPhis bb a0 a1 >> addPhis bb b0 b1+instance+ (Tuple.Undefined a, Tuple.Undefined b) =>+ Tuple.Undefined (T a b) where+ undef = Cons Tuple.undef Tuple.undef Tuple.undef +instance (Tuple.Phi a, Tuple.Phi b) => Tuple.Phi (T a b) where+ phi bb (Cons r a b) =+ liftM3 Cons (Tuple.phi bb r) (Tuple.phi bb a) (Tuple.phi bb b)+ addPhi bb (Cons r0 a0 b0) (Cons r1 a1 b1) =+ Tuple.addPhi bb r0 r1 >> Tuple.addPhi bb a0 a1 >> Tuple.addPhi bb b0 b1 + {- | counterpart to 'either' -} run ::- (Phi c) =>+ (Tuple.Phi c) => T a b -> (a -> CodeGenFunction r c) -> (b -> CodeGenFunction r c) ->
src/LLVM/Extra/FastMath.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module LLVM.Extra.FastMath ( @@ -36,7 +38,7 @@ import qualified LLVM.Extra.Multi.Vector as MultiVector import qualified LLVM.Extra.Multi.Value.Private as MV import qualified LLVM.Extra.Arithmetic as A-import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Core as LLVM import LLVM.Util.Proxy (Proxy(Proxy)) @@ -91,13 +93,16 @@ getNumber :: flags -> Number flags a -> a getNumber _ (Number a) = a +instance (Tuple.Value a) => Tuple.Value (Number flags a) where+ type ValueOf (Number flags a) = Tuple.ValueOf a+ valueOf = Tuple.valueOf . deconsNumber+ instance MultiValue a => MV.C (Number flags a) where- type Repr f (Number flags a) = MV.Repr f a cons = mvNumber . MV.cons . deconsNumber undef = mvNumber MV.undef zero = mvNumber MV.zero- phis bb = fmap mvNumber . MV.phis bb . mvDenumber- addPhis bb a b = MV.addPhis bb (mvDenumber a) (mvDenumber b)+ phi bb = fmap mvNumber . MV.phi bb . mvDenumber+ addPhi bb a b = MV.addPhi bb (mvDenumber a) (mvDenumber b) mvNumber :: MV.T a -> MV.T (Number flags a) mvNumber (MV.Cons a) = MV.Cons a@@ -281,12 +286,16 @@ attachMultiVectorFlags $ Monad.lift mvecNumber $ f (mvecDenumber a) (mvecDenumber b) +instance (Tuple.VectorValue n a) => Tuple.VectorValue n (Number flags a) where+ type VectorValueOf n (Number flags a) = Tuple.VectorValueOf n a+ vectorValueOf = Tuple.vectorValueOf . fmap deconsNumber+ instance (Flags flags, MultiVector a) => MultiVector.C (Number flags a) where cons = mvecNumber . MultiVector.cons . fmap deconsNumber undef = mvecNumber MultiVector.undef zero = mvecNumber MultiVector.zero- phis bb = fmap mvecNumber . MultiVector.phis bb . mvecDenumber- addPhis bb a b = MultiVector.addPhis bb (mvecDenumber a) (mvecDenumber b)+ phi bb = fmap mvecNumber . MultiVector.phi bb . mvecDenumber+ addPhi bb a b = MultiVector.addPhi bb (mvecDenumber a) (mvecDenumber b) shuffle ks a b = fmap mvecNumber $ MultiVector.shuffle ks (mvecDenumber a) (mvecDenumber b) extract k = fmap mvNumber . MultiVector.extract k . mvecDenumber@@ -390,9 +399,9 @@ proxyFromContext (Context _) = Proxy instance- (Flags flags, Class.Zero a, Tuple a) =>- Class.Zero (Context flags a) where- zeroTuple = Context Class.zeroTuple+ (Flags flags, Tuple.Zero a, Tuple a) =>+ Tuple.Zero (Context flags a) where+ zero = Context Tuple.zero instance (Flags flags, Tuple a, A.Additive a) =>
src/LLVM/Extra/Iterator.hs view
@@ -15,6 +15,7 @@ iterate, countDown, arrayPtrs,+ storableArrayPtrs, -- * modifiers mapM, mapMaybe,@@ -33,11 +34,11 @@ import qualified LLVM.Extra.MaybeContinuation as MaybeCont import qualified LLVM.Extra.Maybe as Maybe +import qualified LLVM.Extra.Storable as Storable import qualified LLVM.Extra.ArithmeticPrivate as A-import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.Control as C import qualified LLVM.Core as LLVM-import LLVM.Util.Loop (Phi, ) import LLVM.Core (CodeGenFunction, Value, value, valueOf, CmpRet, IsInteger, IsType, IsConst, IsPrimitive)@@ -60,8 +61,8 @@ Simulates a non-strict list. -} data T r a =- forall s. (Phi s, Class.Undefined s) =>- Cons s (forall z. (Phi z) => s -> MaybeCont.T r z (a,s))+ forall s. (Tuple.Phi s, Tuple.Undefined s) =>+ Cons s (forall z. (Tuple.Phi z) => s -> MaybeCont.T r z (a,s)) mapM_ :: (a -> CodeGenFunction r ()) -> T r a -> CodeGenFunction r () mapM_ f (Cons s next) =@@ -74,7 +75,7 @@ return mapState_ ::- (Phi t) =>+ (Tuple.Phi t) => (a -> t -> CodeGenFunction r t) -> T r a -> t -> CodeGenFunction r t mapState_ f (Cons s next) t =@@ -87,7 +88,7 @@ return mapStateM_ ::- (Phi t) =>+ (Tuple.Phi t) => (a -> MS.StateT t (CodeGenFunction r) ()) -> T r a -> MS.StateT t (CodeGenFunction r) () mapStateM_ f xs =@@ -96,7 +97,7 @@ mapWhileState_ ::- (Phi t) =>+ (Tuple.Phi t) => (a -> t -> CodeGenFunction r (Value Bool, t)) -> T r a -> t -> CodeGenFunction r t mapWhileState_ f (Cons s next) t =@@ -118,7 +119,7 @@ (valueOf True) (\running -> MaybeCont.guard running >> return (a, valueOf False)) -cons :: (Phi a, Class.Undefined a) => a -> T r a -> T r a+cons :: (Tuple.Phi a, Tuple.Undefined a) => a -> T r a -> T r a cons a0 (Cons s next) = Cons Maybe.nothing (fmap (mapSnd Maybe.just) .@@ -154,11 +155,11 @@ mapM f (Cons s next) = Cons s (MaybeCont.lift . FuncHT.mapFst f <=< next) mapMaybe ::- (Phi b, Class.Undefined b) =>+ (Tuple.Phi b, Tuple.Undefined b) => (a -> CodeGenFunction r (Maybe.T b)) -> T r a -> T r b mapMaybe f = catMaybes . mapM f -catMaybes :: (Phi a, Class.Undefined a) => T r (Maybe.T a) -> T r a+catMaybes :: (Tuple.Phi a, Tuple.Undefined a) => T r (Maybe.T a) -> T r a catMaybes (Cons s next) = Cons s (\s0 ->@@ -188,12 +189,12 @@ make sure that accessing one more pointer is legal. -} iterate ::- (Phi a, Class.Undefined a) => (a -> CodeGenFunction r a) -> a -> T r a+ (Tuple.Phi a, Tuple.Undefined a) => (a -> CodeGenFunction r a) -> a -> T r a iterate f a = Cons a (\a0 -> MaybeCont.lift $ fmap ((,) a0) $ f a0) cartesianAux ::- (Phi a, Phi b, Class.Undefined a, Class.Undefined b) =>+ (Tuple.Phi a, Tuple.Phi b, Tuple.Undefined a, Tuple.Undefined b) => T r a -> T r b -> T r (Maybe.T (a,b)) cartesianAux (Cons sa nextA) (Cons sb nextB) = Cons (Maybe.nothing,sa,sb)@@ -209,7 +210,7 @@ return (Maybe.just (a1,b1), (Maybe.just a1, sa1, sb1)))) cartesian ::- (Phi a, Phi b, Class.Undefined a, Class.Undefined b) =>+ (Tuple.Phi a, Tuple.Phi b, Tuple.Undefined a, Tuple.Undefined b) => T r a -> T r b -> T r (a,b) cartesian as bs = catMaybes $ cartesianAux as bs @@ -224,14 +225,17 @@ Value i -> T r a -> T r a take len xs = liftA2 const xs (countDown len) -arrayPtrs :: (IsType a) => Value (Ptr a) -> T r (Value (Ptr a))+arrayPtrs :: (IsType a) => Value (LLVM.Ptr a) -> T r (Value (LLVM.Ptr a)) arrayPtrs = iterate A.advanceArrayElementPtr +storableArrayPtrs :: (Storable.C a) => Value (Ptr a) -> T r (Value (Ptr a))+storableArrayPtrs = iterate Storable.incrementPtr + -- * examples fixedLengthLoop ::- (Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>+ (Tuple.Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) => Value i -> s -> (s -> CodeGenFunction r s) -> CodeGenFunction r s@@ -239,17 +243,17 @@ mapState_ (const loopBody) (countDown len) start arrayLoop ::- (Phi a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>- Value i -> Value (Ptr b) -> a ->- (Value (Ptr b) -> a -> CodeGenFunction r a) ->+ (Tuple.Phi a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>+ Value i -> Value (LLVM.Ptr b) -> a ->+ (Value (LLVM.Ptr b) -> a -> CodeGenFunction r a) -> CodeGenFunction r a arrayLoop len ptr start loopBody = mapState_ loopBody (take len $ arrayPtrs ptr) start arrayLoopWithExit ::- (Phi s, IsType a, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>- Value i -> Value (Ptr a) -> s ->- (Value (Ptr a) -> s -> CodeGenFunction r (Value Bool, s)) ->+ (Tuple.Phi s, IsType a, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>+ Value i -> Value (LLVM.Ptr a) -> s ->+ (Value (LLVM.Ptr a) -> s -> CodeGenFunction r (Value Bool, s)) -> CodeGenFunction r (Value i, s) arrayLoopWithExit len ptr0 start loopBody = do (i, end) <-@@ -261,9 +265,9 @@ return (pos, end) arrayLoop2 ::- (Phi s, IsType a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>- Value i -> Value (Ptr a) -> Value (Ptr b) -> s ->- (Value (Ptr a) -> Value (Ptr b) -> s -> CodeGenFunction r s) ->+ (Tuple.Phi s, IsType a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) =>+ Value i -> Value (LLVM.Ptr a) -> Value (LLVM.Ptr b) -> s ->+ (Value (LLVM.Ptr a) -> Value (LLVM.Ptr b) -> s -> CodeGenFunction r s) -> CodeGenFunction r s arrayLoop2 len ptrA ptrB start loopBody = mapState_ (uncurry loopBody)
src/LLVM/Extra/Marshal.hs view
@@ -1,180 +1,264 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {- | Transfer values between Haskell and JIT generated code in an LLVM-compatible format.-E.g. 'Bool' is stored as 'i1' and Haskell tuples are stored as LLVM structs.+E.g. 'Bool' is stored as 'i1' and occupies a byte,+@'Vector' n 'Bool'@ is stored as a bit vector,+@'Vector' n 'Word8'@ is stored in an order depending on machine endianess,+and Haskell tuples are stored as LLVM structs. -}-module LLVM.Extra.Marshal where+module LLVM.Extra.Marshal (+ C(..),+ Struct,+ peek,+ poke,+ MV, -import qualified LLVM.Extra.Class as Class-import qualified LLVM.Util.Proxy as LP+ VectorStruct,+ Vector(..),++ with,+ EE.alloca,+ ) where++import qualified LLVM.Extra.Multi.Value as MultiValue+import qualified LLVM.Extra.Memory as Memory+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.ExecutionEngine as EE import qualified LLVM.Core as LLVM-import LLVM.Core (CodeGenFunction, Value) import qualified Type.Data.Num.Decimal as TypeNum +import qualified Control.Functor.HT as FuncHT import Control.Applicative (liftA2, liftA3, (<$>)) -import Foreign.Marshal.Alloc (allocaBytes)-import Foreign.Ptr (Ptr)+import Foreign.Storable (Storable)+import Foreign.StablePtr (StablePtr)+import Foreign.Ptr (FunPtr, Ptr) -import Data.Tuple.HT (fst3, snd3, thd3)-import Data.Word (Word8, Word16, Word32, Word64, )-import Data.Int (Int8, Int16, Int32, Int64, )+import Data.Word (Word8, Word16, Word32, Word64, Word)+import Data.Int (Int8, Int16, Int32, Int64) -peek :: (C a, Struct a ~ struct, EE.Marshal struct) => Ptr struct -> IO a+peek ::+ (C a, Struct a ~ struct, EE.Marshal struct) => LLVM.Ptr struct -> IO a peek ptr = unpack <$> EE.peek ptr -poke :: (C a, Struct a ~ struct, EE.Marshal struct) => Ptr struct -> a -> IO ()+poke ::+ (C a, Struct a ~ struct, EE.Marshal struct) => LLVM.Ptr struct -> a -> IO () poke ptr = EE.poke ptr . pack -load ::- (C a, Struct a ~ struct, EE.Marshal struct) =>- LP.Proxy a ->- Value (Ptr struct) -> CodeGenFunction r (Class.ValueTuple a)-load proxy ptr = decompose proxy =<< LLVM.load ptr -store ::- (C a, Struct a ~ struct, EE.Marshal struct) =>- LP.Proxy a ->- Class.ValueTuple a -> Value (Ptr struct) -> CodeGenFunction r ()-store proxy tuple ptr = flip LLVM.store ptr =<< compose proxy tuple-+type Struct a = Memory.Struct (Tuple.ValueOf a) class- (Class.MakeValueTuple a, EE.Marshal (Struct a), LLVM.IsSized (Struct a)) =>+ (Tuple.Value a, Memory.C (Tuple.ValueOf a),+ EE.Marshal (Struct a), LLVM.IsSized (Struct a)) => C a where- type Struct a pack :: a -> Struct a unpack :: Struct a -> a- compose ::- LP.Proxy a ->- Class.ValueTuple a -> CodeGenFunction r (Value (Struct a))- decompose ::- LP.Proxy a ->- Value (Struct a) -> CodeGenFunction r (Class.ValueTuple a) -instance C Bool where- type Struct Bool = Bool- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+instance C Bool where pack = id; unpack = id+instance C Float where pack = id; unpack = id+instance C Double where pack = id; unpack = id+instance C Word where pack = id; unpack = id+instance C Word8 where pack = id; unpack = id+instance C Word16 where pack = id; unpack = id+instance C Word32 where pack = id; unpack = id+instance C Word64 where pack = id; unpack = id+instance C Int where pack = id; unpack = id+instance C Int8 where pack = id; unpack = id+instance C Int16 where pack = id; unpack = id+instance C Int32 where pack = id; unpack = id+instance C Int64 where pack = id; unpack = id -instance C Float where- type Struct Float = Float- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+instance (Storable a) => C (Ptr a) where pack = id; unpack = id+instance (LLVM.IsType a) => C (LLVM.Ptr a) where pack = id; unpack = id+instance (LLVM.IsFunction a) => C (FunPtr a) where pack = id; unpack = id+instance C (StablePtr a) where pack = id; unpack = id -instance C Double where- type Struct Double = Double- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+instance C () where+ pack = LLVM.Struct+ unpack (LLVM.Struct unit) = unit -instance C Word8 where- type Struct Word8 = Word8- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+instance+ (LLVM.IsSized (Struct a), LLVM.IsSized (Struct b), C a, C b) =>+ C (a,b) where+ pack (a,b) = LLVM.consStruct (pack a) (pack b)+ unpack = LLVM.uncurryStruct $ \a b -> (unpack a, unpack b) -instance C Word16 where- type Struct Word16 = Word16- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+instance+ (LLVM.IsSized (Struct a), LLVM.IsSized (Struct b), LLVM.IsSized (Struct c),+ C a, C b, C c) =>+ C (a,b,c) where+ pack (a,b,c) = LLVM.consStruct (pack a) (pack b) (pack c)+ unpack = LLVM.uncurryStruct $ \a b c -> (unpack a, unpack b, unpack c) -instance C Word32 where- type Struct Word32 = Word32- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+instance+ (LLVM.IsSized (Struct a), LLVM.IsSized (Struct b),+ LLVM.IsSized (Struct c), LLVM.IsSized (Struct d),+ C a, C b, C c, C d) =>+ C (a,b,c,d) where+ pack (a,b,c,d) = LLVM.consStruct (pack a) (pack b) (pack c) (pack d)+ unpack =+ LLVM.uncurryStruct $ \a b c d -> (unpack a, unpack b, unpack c, unpack d) -instance C Word64 where- type Struct Word64 = Word64- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return -instance C Int8 where- type Struct Int8 = Int8- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return -instance C Int16 where- type Struct Int16 = Int16- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return--instance C Int32 where- type Struct Int32 = Int32- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return--instance C Int64 where- type Struct Int64 = Int64- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+type VectorStruct n a = Memory.Struct (Tuple.VectorValueOf n a) -instance (LLVM.IsType a) => C (Ptr a) where- type Struct (Ptr a) = Ptr a- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+class+ (TypeNum.Positive n,+ Tuple.VectorValue n a, Memory.C (Tuple.VectorValueOf n a),+ EE.Marshal (VectorStruct n a), LLVM.IsSized (VectorStruct n a)) =>+ Vector n a where+ packVector :: LLVM.Vector n a -> VectorStruct n a+ unpackVector :: VectorStruct n a -> LLVM.Vector n a instance (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: LLVM.SizeOf a),- EE.Marshal a, LLVM.IsConst a, LLVM.IsPrimitive a, LLVM.IsSized a) =>+ Vector n a) => C (LLVM.Vector n a) where- type Struct (LLVM.Vector n a) = LLVM.Vector n a- pack = id; compose LP.Proxy = return- unpack = id; decompose LP.Proxy = return+ pack = packVector; unpack = unpackVector -instance C () where- type Struct () = LLVM.Struct ()- pack = LLVM.Struct- unpack (LLVM.Struct unit) = unit- compose LP.Proxy () = return $ LLVM.valueOf $ LLVM.Struct ()- decompose LP.Proxy _ = return () instance- (LLVM.IsSized (Struct a), LLVM.IsSized (Struct b), C a, C b) =>- C (a,b) where- type Struct (a,b) = LLVM.Struct (Struct a, (Struct b, ()))- pack (a,b) = LLVM.Struct (pack a, (pack b, ()))- unpack (LLVM.Struct (a,(b,()))) = (unpack a, unpack b)- compose proxy (a,b) = do- ac <- compose (fst <$> proxy) a- bc <- compose (snd <$> proxy) b- struct0 <- LLVM.insertvalue (LLVM.value LLVM.undef) ac TypeNum.d0- LLVM.insertvalue struct0 bc TypeNum.d1- decompose proxy struct =- liftA2 (,)- (decompose (fst <$> proxy) =<< LLVM.extractvalue struct TypeNum.d0)- (decompose (snd <$> proxy) =<< LLVM.extractvalue struct TypeNum.d1)+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D1)) =>+ Vector n Bool where+ packVector = id+ unpackVector = id instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D32)) =>+ Vector n Float where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D64)) =>+ Vector n Double where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: LLVM.IntSize)) =>+ Vector n Word where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D8)) =>+ Vector n Word8 where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D16)) =>+ Vector n Word16 where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D32)) =>+ Vector n Word32 where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D64)) =>+ Vector n Word64 where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: LLVM.IntSize)) =>+ Vector n Int where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D8)) =>+ Vector n Int8 where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D16)) =>+ Vector n Int16 where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D32)) =>+ Vector n Int32 where+ packVector = id+ unpackVector = id++instance+ (TypeNum.Positive n, TypeNum.Natural (n TypeNum.:*: TypeNum.D64)) =>+ Vector n Int64 where+ packVector = id+ unpackVector = id++instance (Vector n a, Vector n b) => Vector n (a,b) where+ packVector x =+ case FuncHT.unzip x of+ (a,b) -> LLVM.consStruct (packVector a) (packVector b)+ unpackVector = LLVM.uncurryStruct $ \a b ->+ liftA2 (,) (unpackVector a) (unpackVector b)++instance (Vector n a, Vector n b, Vector n c) => Vector n (a,b,c) where+ packVector x =+ case FuncHT.unzip3 x of+ (a,b,c) -> LLVM.consStruct (packVector a) (packVector b) (packVector c)+ unpackVector = LLVM.uncurryStruct $ \a b c ->+ liftA3 (,,) (unpackVector a) (unpackVector b) (unpackVector c)++++class (C a, MultiValue.C a) => MV a where++instance MV Float where+instance MV Double where+instance MV Word where+instance MV Word8 where+instance MV Word16 where+instance MV Word32 where+instance MV Word64 where+instance MV Int where+instance MV Int8 where+instance MV Int16 where+instance MV Int32 where+instance MV Int64 where++instance (Storable a) => MV (Ptr a) where+instance (LLVM.IsType a) => MV (LLVM.Ptr a) where+instance (LLVM.IsFunction a) => MV (FunPtr a) where+instance MV (StablePtr a) where++instance MV () where++instance+ (LLVM.IsSized (Struct a), LLVM.IsSized (Struct b), MV a, MV b) =>+ MV (a,b) where++instance (LLVM.IsSized (Struct a), LLVM.IsSized (Struct b), LLVM.IsSized (Struct c),- C a, C b, C c) =>- C (a,b,c) where- type Struct (a,b,c) = LLVM.Struct (Struct a, (Struct b, (Struct c, ())))- pack (a,b,c) = LLVM.Struct (pack a, (pack b, (pack c, ())))- unpack (LLVM.Struct (a,(b,(c,())))) = (unpack a, unpack b, unpack c)- compose proxy (a,b,c) = do- ac <- compose (fst3 <$> proxy) a- bc <- compose (snd3 <$> proxy) b- cc <- compose (thd3 <$> proxy) c- struct0 <- LLVM.insertvalue (LLVM.value LLVM.undef) ac TypeNum.d0- struct1 <- LLVM.insertvalue struct0 bc TypeNum.d1- LLVM.insertvalue struct1 cc TypeNum.d2- decompose proxy struct =- liftA3 (,,)- (decompose (fst3 <$> proxy) =<< LLVM.extractvalue struct TypeNum.d0)- (decompose (snd3 <$> proxy) =<< LLVM.extractvalue struct TypeNum.d1)- (decompose (thd3 <$> proxy) =<< LLVM.extractvalue struct TypeNum.d2)+ MV a, MV b, MV c) =>+ MV (a,b,c) where +instance+ (LLVM.IsSized (Struct a), LLVM.IsSized (Struct b),+ LLVM.IsSized (Struct c), LLVM.IsSized (Struct d),+ MV a, MV b, MV c, MV d) =>+ MV (a,b,c,d) where -with :: (C a) => a -> (Ptr (Struct a) -> IO b) -> IO b-with a act = alloca LP.Proxy $ \ptr -> poke ptr a >> act ptr -alloca ::- (LLVM.IsType struct) => LP.Proxy struct -> (Ptr struct -> IO b) -> IO b-alloca proxy = allocaBytes (EE.sizeOf proxy)+with :: (C a) => a -> (LLVM.Ptr (Struct a) -> IO b) -> IO b+with a act = EE.alloca $ \ptr -> poke ptr a >> act ptr
src/LLVM/Extra/Maybe.hs view
@@ -21,20 +21,19 @@ loopWithExit, ) where +import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.MaybePrivate as Maybe import qualified LLVM.Extra.Control as C-import LLVM.Extra.Class (Undefined, undefTuple, ) -import LLVM.Util.Loop (Phi, ) import LLVM.Core (CodeGenFunction, ) -nothing :: (Undefined a) => Maybe.T a-nothing = Maybe.nothing undefTuple+nothing :: (Tuple.Undefined a) => Maybe.T a+nothing = Maybe.nothing Tuple.undef loopWithExit ::- Phi a =>+ Tuple.Phi a => a -> (a -> CodeGenFunction r (Maybe.T c, b)) -> ((c,b) -> CodeGenFunction r a) ->
src/LLVM/Extra/MaybeContinuation.hs view
@@ -5,23 +5,21 @@ module LLVM.Extra.MaybeContinuation where import qualified LLVM.Extra.Maybe as Maybe+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.Arithmetic as A import qualified LLVM.Extra.Control as C import LLVM.Extra.Control (ifThenElse, )-import LLVM.Extra.Class (Undefined, undefTuple, ) import qualified LLVM.Core as LLVM import LLVM.Core (CodeGenFunction, Value, value, valueOf, IsConst, IsType, IsPrimitive, IsInteger, CmpRet)-import LLVM.Util.Loop (Phi, ) -- (phis, addPhis, ) import qualified Control.Monad as M import qualified Control.Applicative as App import Control.Monad.IO.Class (MonadIO(liftIO), ) import Control.Monad.HT ((<=<), ) -import Foreign.Ptr (Ptr, ) import Data.Tuple.HT (mapSnd, ) import Prelude hiding (map, )@@ -62,7 +60,7 @@ counterpart to Data.Maybe.HT.toMaybe -} withBool ::- (Phi z) =>+ (Tuple.Phi z) => Value Bool -> CodeGenFunction r a -> T r z a withBool b a = guard b >> lift a@@ -72,7 +70,7 @@ -} fromBool ::- (Phi z) =>+ (Tuple.Phi z) => CodeGenFunction r (Value Bool, a) -> T r z a fromBool m = do@@ -81,20 +79,20 @@ return a toBool ::- (Undefined a) =>+ (Tuple.Undefined a) => T r (Value Bool, a) a -> CodeGenFunction r (Value Bool, a) toBool (Cons m) =- m (return (valueOf False, undefTuple)) (return . (,) (valueOf True))+ m (return (valueOf False, Tuple.undef)) (return . (,) (valueOf True)) -fromPlainMaybe :: (Phi z) => Maybe.T a -> T r z a+fromPlainMaybe :: (Tuple.Phi z) => Maybe.T a -> T r z a fromPlainMaybe (Maybe.Cons b a) = guard b >> return a -fromMaybe :: (Phi z) => CodeGenFunction r (Maybe.T a) -> T r z a+fromMaybe :: (Tuple.Phi z) => CodeGenFunction r (Maybe.T a) -> T r z a fromMaybe m = lift m >>= fromPlainMaybe toMaybe ::- (Undefined a) =>+ (Tuple.Undefined a) => T r (Maybe.T a) a -> CodeGenFunction r (Maybe.T a) toMaybe (Cons m) = m (return Maybe.nothing) (return . Maybe.just)@@ -109,7 +107,7 @@ lift a = Cons $ \ _n j -> j =<< a guard ::- (Phi z) =>+ (Tuple.Phi z) => Value Bool -> T r z () guard b = Cons $ \n j -> ifThenElse b (j ()) n@@ -140,14 +138,14 @@ If both actions fail, then the composed action fails, too. -} alternative ::- (Phi z, Undefined a) =>+ (Tuple.Phi z, Tuple.Undefined a) => T r (Maybe.T a) a -> T r (Maybe.T a) a -> T r z a alternative x y = fromMaybe $ resolve x (toMaybe y) (return . Maybe.just) fixedLengthLoop ::- (Phi s, Undefined s,+ (Tuple.Phi s, Tuple.Undefined s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) => Value i -> s -> (s -> T r (Maybe.T s) s) ->@@ -172,11 +170,11 @@ then returned final state is 'Maybe.nothing'. -} arrayLoop ::- (Phi s, Undefined s, IsType a,+ (Tuple.Phi s, Tuple.Undefined s, IsType a, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) => Value i ->- Value (Ptr a) -> s ->- (Value (Ptr a) -> s -> T r (Maybe.T (Value (Ptr a), s)) s) ->+ Value (LLVM.Ptr a) -> s ->+ (Value (LLVM.Ptr a) -> s -> T r (Maybe.T (Value (LLVM.Ptr a), s)) s) -> CodeGenFunction r (Value i, Maybe.T s) arrayLoop len ptr start loopBody = fmap (mapSnd (fmap snd)) $@@ -187,12 +185,12 @@ arrayLoop2 ::- (Phi s, Undefined s, IsType a, IsType b,+ (Tuple.Phi s, Tuple.Undefined s, IsType a, IsType b, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i) => Value i ->- Value (Ptr a) -> Value (Ptr b) -> s ->- (Value (Ptr a) -> Value (Ptr b) -> s ->- T r (Maybe.T (Value (Ptr a), (Value (Ptr b), s))) s) ->+ Value (LLVM.Ptr a) -> Value (LLVM.Ptr b) -> s ->+ (Value (LLVM.Ptr a) -> Value (LLVM.Ptr b) -> s ->+ T r (Maybe.T (Value (LLVM.Ptr a), (Value (LLVM.Ptr b), s))) s) -> CodeGenFunction r (Value i, Maybe.T s) arrayLoop2 len ptrA ptrB start loopBody = fmap (mapSnd (fmap snd)) $@@ -208,7 +206,7 @@ and we could just propagate a Nothing. whileLoop ::- Phi a =>+ Tuple.Phi a => a -> (a -> T r z a) -> CodeGenFunction r a@@ -220,13 +218,13 @@ br loop defineBasicBlock loop- state <- phis top start+ state <- phi top start b <- check state condBr b cont exit defineBasicBlock cont res <- body state cont' <- getCurrentBasicBlock- addPhis cont' state res+ addPhi cont' state res br loop defineBasicBlock exit
src/LLVM/Extra/MaybePrivate.hs view
@@ -1,12 +1,12 @@ {-# LANGUAGE TypeFamilies #-} module LLVM.Extra.MaybePrivate where +import qualified LLVM.Extra.TuplePrivate as Tuple import qualified LLVM.Extra.Control as C import LLVM.Extra.Control (ifThenElse, ) import qualified LLVM.Core as LLVM import LLVM.Core (Value, valueOf, CodeGenFunction, )-import LLVM.Util.Loop (Phi, phis, addPhis, ) import qualified Control.Monad as Monad @@ -22,17 +22,20 @@ instance Functor T where fmap f (Cons b a) = Cons b (f a) -instance (Phi a) => Phi (T a) where- phis bb (Cons b a) = Monad.liftM2 Cons (phis bb b) (phis bb a)- addPhis bb (Cons b0 a0) (Cons b1 a1) =- addPhis bb b0 b1 >> addPhis bb a0 a1+instance (Tuple.Undefined a) => Tuple.Undefined (T a) where+ undef = Cons Tuple.undef Tuple.undef +instance (Tuple.Phi a) => Tuple.Phi (T a) where+ phi bb (Cons b a) = Monad.liftM2 Cons (Tuple.phi bb b) (Tuple.phi bb a)+ addPhi bb (Cons b0 a0) (Cons b1 a1) =+ Tuple.addPhi bb b0 b1 >> Tuple.addPhi bb a0 a1 + {- | counterpart to 'maybe' -} run ::- (Phi b) =>+ (Tuple.Phi b) => T a -> CodeGenFunction r b -> (a -> CodeGenFunction r b) ->@@ -106,7 +109,7 @@ maybeArg ::- (Phi b) =>+ (Tuple.Phi b) => b -> (a -> CodeGenFunction r (T b)) -> T a -> CodeGenFunction r (T b)
src/LLVM/Extra/Memory.hs view
@@ -1,34 +1,31 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} module LLVM.Extra.Memory (- C(load, store, decompose, compose), modify, castStorablePtr, castTuplePtr,+ C(load, store, decompose, compose), modify, Struct, Record, Element, element, loadRecord, storeRecord, decomposeRecord, composeRecord, loadNewtype, storeNewtype, decomposeNewtype, composeNewtype,- FirstClass, Stored, ) where -import LLVM.Extra.Class (MakeValueTuple, ValueTuple, Undefined, ) import LLVM.Extra.MemoryPrivate (decomposeFromLoad, composeFromStore, ) -import qualified LLVM.Extra.Multi.Vector.Memory as MultiVectorMemory-import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory import qualified LLVM.Extra.Multi.Vector as MultiVector import qualified LLVM.Extra.Multi.Value as MultiValue import qualified LLVM.Extra.ArithmeticPrivate as A import qualified LLVM.Extra.Vector as Vector import qualified LLVM.Extra.Scalar as Scalar import qualified LLVM.Extra.Array as Array+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.Either as Either import qualified LLVM.Extra.Maybe as Maybe import qualified LLVM.Util.Proxy as LP import qualified LLVM.Core as LLVM-import LLVM.Util.Loop (Phi, ) import LLVM.Core (getElementPtr0, extractvalue, insertvalue,@@ -37,27 +34,30 @@ CodeGenFunction, ) import qualified Type.Data.Num.Decimal as TypeNum-import Type.Data.Num.Decimal (d0, d1, d2, )+import qualified Type.Data.Num.Unary as Unary+import Type.Data.Num.Decimal (d0, d1, d2, d3) import Type.Base.Proxy (Proxy(Proxy), ) import Foreign.StablePtr (StablePtr, )-import Foreign.Ptr (FunPtr, Ptr, castPtr, )+import Foreign.Ptr (FunPtr) -import Data.Word (Word8, Word16, Word32, Word64, )+import qualified Data.Traversable as Trav+import qualified Data.Foldable as Fold+import qualified Data.FixedLength as FixedLength+import Data.Tuple.HT (fst3, snd3, thd3, )+import Data.Word (Word8, Word16, Word32, Word64, Word) import Data.Int (Int8, Int16, Int32, Int64, ) -import qualified Control.Applicative as App-import Control.Monad (ap, )-import Control.Applicative (pure, liftA2, liftA3, )--import Data.Tuple.HT (fst3, snd3, thd3, )+import qualified Control.Applicative.HT as App+import Control.Monad (ap, (<=<))+import Control.Applicative (Applicative, pure, liftA2, liftA3, (<*>)) import Prelude2010 hiding (maybe, either, ) import Prelude () {- |-An implementation of both 'MakeValueTuple' and 'Memory.C'+An implementation of both 'Tuple.Value' and 'Memory.C' must ensure that @haskellValue@ is compatible with @Stored (Struct haskellValue)@ (which we want to call @llvmStruct@). That is, writing and reading @llvmStruct@ by LLVM@@ -66,13 +66,13 @@ We use a functional dependency in order to let type inference work nicely. -}-class (Phi llvmValue, Undefined llvmValue, IsType (Struct llvmValue), IsSized (Struct llvmValue)) =>+class (Tuple.Phi llvmValue, Tuple.Undefined llvmValue, IsType (Struct llvmValue), IsSized (Struct llvmValue)) => C llvmValue where {-# MINIMAL (load|decompose), (store|compose) #-} type Struct llvmValue :: *- load :: Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue+ load :: Value (LLVM.Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue load ptr = decompose =<< LLVM.load ptr- store :: llvmValue -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()+ store :: llvmValue -> Value (LLVM.Ptr (Struct llvmValue)) -> CodeGenFunction r () store r ptr = flip LLVM.store ptr =<< compose r decompose :: Value (Struct llvmValue) -> CodeGenFunction r llvmValue decompose = decomposeFromLoad load@@ -82,7 +82,7 @@ modify :: (C llvmValue) => (llvmValue -> CodeGenFunction r llvmValue) ->- Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()+ Value (LLVM.Ptr (Struct llvmValue)) -> CodeGenFunction r () modify f ptr = flip store ptr =<< f =<< load ptr @@ -99,8 +99,8 @@ data Element r o v x = Element {- loadElement :: Value (Ptr o) -> CodeGenFunction r x,- storeElement :: Value (Ptr o) -> v -> CodeGenFunction r (),+ loadElement :: Value (LLVM.Ptr o) -> CodeGenFunction r x,+ storeElement :: Value (LLVM.Ptr o) -> v -> CodeGenFunction r (), extractElement :: Value o -> CodeGenFunction r x, insertElement :: v -> Value o -> CodeGenFunction r (Value o) -- State.Monoid@@ -128,7 +128,7 @@ insertElement = insertElement m } -instance App.Applicative (Element r o v) where+instance Applicative (Element r o v) where pure x = Element { loadElement = \ _ptr -> return x,@@ -147,12 +147,12 @@ loadRecord :: Record r o llvmValue ->- Value (Ptr o) -> CodeGenFunction r llvmValue+ Value (LLVM.Ptr o) -> CodeGenFunction r llvmValue loadRecord = loadElement storeRecord :: Record r o llvmValue ->- llvmValue -> Value (Ptr o) -> CodeGenFunction r ()+ llvmValue -> Value (LLVM.Ptr o) -> CodeGenFunction r () storeRecord m y ptr = storeElement m ptr y decomposeRecord ::@@ -204,16 +204,58 @@ compose = composeRecord triple +quadruple ::+ (C a, C b, C c, C d) =>+ Record r+ (LLVM.Struct (Struct a, (Struct b, (Struct c, (Struct d, ())))))+ (a, b, c, d)+quadruple =+ App.lift4 (,,,)+ (element (\(x,_,_,_) -> x) d0)+ (element (\(_,x,_,_) -> x) d1)+ (element (\(_,_,x,_) -> x) d2)+ (element (\(_,_,_,x) -> x) d3)++instance (C a, C b, C c, C d) => C (a, b, c, d) where+ type Struct (a, b, c, d) =+ LLVM.Struct (Struct a, (Struct b, (Struct c, (Struct d, ()))))+ load = loadRecord quadruple+ store = storeRecord quadruple+ decompose = decomposeRecord quadruple+ compose = composeRecord quadruple+++instance+ (Unary.Natural n, C a,+ TypeNum.Natural (TypeNum.FromUnary n),+ TypeNum.Natural (TypeNum.FromUnary n TypeNum.:*: LLVM.SizeOf (Struct a)),+ LLVM.IsFirstClass (Struct a)) =>+ C (FixedLength.T n a) where+ type Struct (FixedLength.T n a) =+ LLVM.Array (TypeNum.FromUnary n) (Struct a)+ compose xs =+ Fold.foldlM+ (\arr (x,i) -> compose x >>= \xc -> LLVM.insertvalue arr xc i)+ (LLVM.value LLVM.undef) $+ FixedLength.zipWith (,) xs $ iterateTrav (1+) (0::Word64)+ decompose arr =+ Trav.mapM (decompose <=< LLVM.extractvalue arr) $+ iterateTrav (1+) (0::Word64)++iterateTrav :: (Applicative t, Trav.Traversable t) => (a -> a) -> a -> t a+iterateTrav f a0 = snd $ Trav.mapAccumL (\a () -> (f a, a)) a0 $ pure ()++ maybe :: (C a) =>- Record r (LLVM.Struct (Word32, (Struct a, ()))) (Maybe.T a)+ Record r (LLVM.Struct (Bool, (Struct a, ()))) (Maybe.T a) maybe = liftA2 Maybe.Cons (element Maybe.isJust d0) (element Maybe.fromJust d1) instance (C a) => C (Maybe.T a) where- type Struct (Maybe.T a) = LLVM.Struct (Word32, (Struct a, ()))+ type Struct (Maybe.T a) = LLVM.Struct (Bool, (Struct a, ())) load = loadRecord maybe store = storeRecord maybe decompose = decomposeRecord maybe@@ -222,7 +264,7 @@ either :: (C a, C b) =>- Record r (LLVM.Struct (Word32, (Struct a, (Struct b, ())))) (Either.T a b)+ Record r (LLVM.Struct (Bool, (Struct a, (Struct b, ())))) (Either.T a b) either = liftA3 Either.Cons (element Either.isRight d0)@@ -230,7 +272,7 @@ (element Either.fromRight d2) instance (C a, C b) => C (Either.T a b) where- type Struct (Either.T a b) = LLVM.Struct (Word32, (Struct a, (Struct b, ())))+ type Struct (Either.T a b) = LLVM.Struct (Bool, (Struct a, (Struct b, ()))) load = loadRecord either store = storeRecord either decompose = decomposeRecord either@@ -246,17 +288,12 @@ compose = composeNewtype Scalar.decons -{--This would not work for Booleans,-since on x86 LLVM's @i1@ type uses one byte in memory,-whereas Storable uses 4 byte and 4 byte alignment.--instance (LLVM.IsFirstClass a) => C (Value a) a where+instance (IsSized a, LLVM.IsFirstClass a) => C (Value a) where+ type Struct (Value a) = a load = LLVM.load store = LLVM.store decompose = return compose = return--} class (LLVM.IsFirstClass llvmType, IsType (Stored llvmType)) =>@@ -267,10 +304,12 @@ instance FirstClass Float where type Stored Float = Float ; fromStorable = return; toStorable = return instance FirstClass Double where type Stored Double = Double ; fromStorable = return; toStorable = return+instance FirstClass Int where type Stored Int = Int ; fromStorable = return; toStorable = return instance FirstClass Int8 where type Stored Int8 = Int8 ; fromStorable = return; toStorable = return instance FirstClass Int16 where type Stored Int16 = Int16 ; fromStorable = return; toStorable = return instance FirstClass Int32 where type Stored Int32 = Int32 ; fromStorable = return; toStorable = return instance FirstClass Int64 where type Stored Int64 = Int64 ; fromStorable = return; toStorable = return+instance FirstClass Word where type Stored Word = Word ; fromStorable = return; toStorable = return instance FirstClass Word8 where type Stored Word8 = Word8 ; fromStorable = return; toStorable = return instance FirstClass Word16 where type Stored Word16 = Word16 ; fromStorable = return; toStorable = return instance FirstClass Word32 where type Stored Word32 = Word32 ; fromStorable = return; toStorable = return@@ -293,8 +332,8 @@ fromStorable = Array.map fromStorable toStorable = Array.map toStorable -instance (IsType a) => FirstClass (Ptr a) where- type Stored (Ptr a) = Ptr a+instance (IsType a) => FirstClass (LLVM.Ptr a) where+ type Stored (LLVM.Ptr a) = LLVM.Ptr a fromStorable = return; toStorable = return instance (LLVM.IsFunction a) => FirstClass (FunPtr a) where type Stored (FunPtr a) = FunPtr a@@ -367,48 +406,35 @@ return (LLVM.value LLVM.undef) -instance (FirstClass a, IsSized (Stored a)) => C (Value a) where- type Struct (Value a) = Stored a- decompose = fromStorable- compose = toStorable---instance (MultiValueMemory.C a) => C (MultiValue.T a) where- type Struct (MultiValue.T a) = MultiValueMemory.Struct a- load = MultiValueMemory.load- store = MultiValueMemory.store- decompose = MultiValueMemory.decompose- compose = MultiValueMemory.compose---instance (MultiVectorMemory.C n a) => C (MultiVector.T n a) where- type Struct (MultiVector.T n a) = MultiVectorMemory.Struct n a- load = MultiVectorMemory.load- store = MultiVectorMemory.store- decompose = MultiVectorMemory.decompose- compose = MultiVectorMemory.compose-+instance (MultiValue.C a, C (Tuple.ValueOf a)) => C (MultiValue.T a) where+ type Struct (MultiValue.T a) = Struct (Tuple.ValueOf a)+ load = fmap MultiValue.Cons . load+ store (MultiValue.Cons a) = store a+ decompose = fmap MultiValue.Cons . decompose+ compose (MultiValue.Cons a) = compose a -{-# DEPRECATED castStorablePtr "use castTuplePtr instead" #-}-castStorablePtr, castTuplePtr ::- (MakeValueTuple haskellValue, C (ValueTuple haskellValue)) =>- Ptr haskellValue -> Ptr (Struct (ValueTuple haskellValue))-castStorablePtr = castPtr-castTuplePtr = castPtr+instance+ (TypeNum.Positive n, MultiVector.C a, C (Tuple.VectorValueOf n a)) =>+ C (MultiVector.T n a) where+ type Struct (MultiVector.T n a) = Struct (Tuple.VectorValueOf n a)+ load = fmap MultiVector.Cons . load+ store (MultiVector.Cons a) = store a+ decompose = fmap MultiVector.Cons . decompose+ compose (MultiVector.Cons a) = compose a loadNewtype :: (C a) => (a -> llvmValue) ->- Value (Ptr (Struct a)) -> CodeGenFunction r llvmValue+ Value (LLVM.Ptr (Struct a)) -> CodeGenFunction r llvmValue loadNewtype wrap ptr = fmap wrap $ load ptr storeNewtype :: (C a) => (llvmValue -> a) ->- llvmValue -> Value (Ptr (Struct a)) -> CodeGenFunction r ()+ llvmValue -> Value (LLVM.Ptr (Struct a)) -> CodeGenFunction r () storeNewtype unwrap y ptr = store (unwrap y) ptr
src/LLVM/Extra/MemoryPrivate.hs view
@@ -3,12 +3,10 @@ import qualified LLVM.Core as LLVM import LLVM.Core (CodeGenFunction, Value, ) -import Foreign.Ptr (Ptr, ) - decomposeFromLoad :: LLVM.IsSized struct =>- (Value (Ptr struct) -> CodeGenFunction r a) ->+ (Value (LLVM.Ptr struct) -> CodeGenFunction r a) -> Value struct -> CodeGenFunction r a decomposeFromLoad loadStruct struct = do ptr <- LLVM.alloca@@ -17,7 +15,7 @@ composeFromStore :: LLVM.IsSized struct =>- (a -> Value (Ptr struct) -> CodeGenFunction r ()) ->+ (a -> Value (LLVM.Ptr struct) -> CodeGenFunction r ()) -> a -> CodeGenFunction r (Value struct) composeFromStore storeStruct x = do ptr <- LLVM.alloca
src/LLVM/Extra/Multi/Iterator.hs view
@@ -9,10 +9,10 @@ import qualified LLVM.Extra.Multi.Value as MultiValue import qualified LLVM.Extra.Iterator as Iter import qualified LLVM.Extra.ScalarOrVector as SoV+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.MaybePrivate as Maybe import qualified LLVM.Extra.Arithmetic as A import qualified LLVM.Extra.Control as C-import LLVM.Extra.Class (undefTuple) import qualified LLVM.Core as LLVM import LLVM.Core (CodeGenFunction)@@ -67,7 +67,7 @@ -} enumFromTo from to = Iter.takeWhileJust $- Iter.iterate (Maybe.maybeArg undefTuple (succMax to)) (Maybe.just from)+ Iter.iterate (Maybe.maybeArg Tuple.undef (succMax to)) (Maybe.just from) succMax :: (LLVM.IsInteger w, SoV.IntegerConstant w, Num w,@@ -77,7 +77,7 @@ LLVM.CodeGenFunction r (Maybe.T (MultiValue.T (Enum.T w e))) succMax to e = do MultiValue.Cons less <- MultiValue.cmpEnum A.CmpLT e to- C.ifThen less (Maybe.nothing undefTuple) $+ C.ifThen less (Maybe.nothing Tuple.undef) $ fmap Maybe.just $ MultiValue.succ e {- |
− src/LLVM/Extra/Multi/Value/Memory.hs
@@ -1,257 +0,0 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE FlexibleContexts #-}-module LLVM.Extra.Multi.Value.Memory where--import qualified LLVM.Extra.Multi.Value as MultiValue-import LLVM.Extra.ArithmeticPrivate as A-import LLVM.Extra.MemoryPrivate (decomposeFromLoad, composeFromStore, )--import qualified LLVM.Core as LLVM-import LLVM.Core (CodeGenFunction, Value, )--import qualified Type.Data.Num.Decimal as TypeNum--import Foreign.StablePtr (StablePtr, )-import Foreign.Ptr (Ptr, FunPtr, castPtr, )--import Data.Tagged (Tagged)-import Data.Complex (Complex, )-import Data.Word (Word8, Word16, Word32, Word64, )-import Data.Int (Int8, Int16, Int32, Int64, )-import Data.Bool8 (Bool8)--import Control.Applicative (pure, liftA2, liftA3, (<*>), )--import Prelude2010-import Prelude ()--class (MultiValue.C a, LLVM.IsSized (Struct a)) => C a where- {-# MINIMAL (load|decompose), (store|compose) #-}- type Struct a :: *- load :: Value (Ptr (Struct a)) -> CodeGenFunction r (MultiValue.T a)- load ptr = decompose =<< LLVM.load ptr- store :: MultiValue.T a -> Value (Ptr (Struct a)) -> CodeGenFunction r ()- store r ptr = flip LLVM.store ptr =<< compose r- decompose :: Value (Struct a) -> CodeGenFunction r (MultiValue.T a)- decompose = decomposeFromLoad load- compose :: MultiValue.T a -> CodeGenFunction r (Value (Struct a))- compose = composeFromStore store--instance C Bool8 where- type Struct Bool8 = Word8- decompose = fmap MultiValue.Cons . A.cmp LLVM.CmpNE (LLVM.valueOf 0)- compose (MultiValue.Cons b) = LLVM.select b (LLVM.valueOf 1) (LLVM.valueOf 0)--instance C Float where- type Struct Float = Float- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Double where- type Struct Double = Double- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Word8 where- type Struct Word8 = Word8- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Word16 where- type Struct Word16 = Word16- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Word32 where- type Struct Word32 = Word32- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Word64 where- type Struct Word64 = Word64- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Int8 where- type Struct Int8 = Int8- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Int16 where- type Struct Int16 = Int16- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Int32 where- type Struct Int32 = Int32- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C Int64 where- type Struct Int64 = Int64- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance (LLVM.IsType a) => C (Ptr a) where- type Struct (Ptr a) = Ptr a- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance (LLVM.IsFunction a) => C (FunPtr a) where- type Struct (FunPtr a) = FunPtr a- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive--instance C (StablePtr a) where- type Struct (StablePtr a) = StablePtr a- load = loadPrimitive- store = storePrimitive- decompose = decomposePrimitive- compose = composePrimitive---loadPrimitive ::- (MultiValue.Repr Value a ~ Value al) =>- Value (Ptr al) -> CodeGenFunction r (MultiValue.T a)-loadPrimitive = fmap MultiValue.Cons . LLVM.load--storePrimitive ::- (MultiValue.Repr Value a ~ Value al) =>- MultiValue.T a -> Value (Ptr al) -> CodeGenFunction r ()-storePrimitive (MultiValue.Cons a) = LLVM.store a--decomposePrimitive ::- (MultiValue.Repr Value a ~ Value al) =>- Value al -> CodeGenFunction r (MultiValue.T a)-decomposePrimitive = return . MultiValue.Cons--composePrimitive ::- (MultiValue.Repr Value a ~ Value al) =>- MultiValue.T a -> CodeGenFunction r (Value al)-composePrimitive (MultiValue.Cons a) = return a---instance C () where- type Struct () = LLVM.Struct ()- load = loadUnit- store = storeUnit- decompose = decomposeUnit- compose = composeUnit--loadUnit ::- (MultiValue.Repr Value a ~ ()) =>- Value (Ptr (LLVM.Struct ())) -> CodeGenFunction r (MultiValue.T a)-loadUnit _ = return $ MultiValue.Cons ()--storeUnit ::- MultiValue.T a -> Value (Ptr (LLVM.Struct ())) -> CodeGenFunction r ()-storeUnit _ _ = return ()--decomposeUnit ::- (MultiValue.Repr Value a ~ ()) =>- Value (LLVM.Struct ()) -> CodeGenFunction r (MultiValue.T a)-decomposeUnit _ = return $ MultiValue.Cons ()--composeUnit ::- MultiValue.T a -> CodeGenFunction r (Value (LLVM.Struct ()))-composeUnit _ = return (LLVM.value $ LLVM.constStruct ())---instance (C a) => C (Tagged tag a) where- type Struct (Tagged tag a) = Struct a- decompose = fmap MultiValue.tag . decompose- compose = compose . MultiValue.untag--instance (C a) => C (Complex a) where- type Struct (Complex a) = LLVM.Struct (Struct a, (Struct a, ()))- decompose c =- liftA2 MultiValue.consComplex- (decompose =<< LLVM.extractvalue c TypeNum.d0)- (decompose =<< LLVM.extractvalue c TypeNum.d1)- compose c =- case MultiValue.deconsComplex c of- (r,i) -> do- sr <- compose r- si <- compose i- rr <- LLVM.insertvalue (LLVM.value LLVM.undef) sr TypeNum.d0- LLVM.insertvalue rr si TypeNum.d1---instance (C a, C b) => C (a,b) where- type Struct (a,b) = LLVM.Struct (Struct a, (Struct b, ()))- decompose ab =- liftA2 MultiValue.zip- (decompose =<< LLVM.extractvalue ab TypeNum.d0)- (decompose =<< LLVM.extractvalue ab TypeNum.d1)- compose ab =- case MultiValue.unzip ab of- (a,b) -> do- sa <- compose a- sb <- compose b- ra <- LLVM.insertvalue (LLVM.value LLVM.undef) sa TypeNum.d0- LLVM.insertvalue ra sb TypeNum.d1--instance (C a, C b, C c) => C (a,b,c) where- type Struct (a,b,c) = LLVM.Struct (Struct a, (Struct b, (Struct c, ())))- decompose abc =- liftA3 MultiValue.zip3- (decompose =<< LLVM.extractvalue abc TypeNum.d0)- (decompose =<< LLVM.extractvalue abc TypeNum.d1)- (decompose =<< LLVM.extractvalue abc TypeNum.d2)- compose abc =- case MultiValue.unzip3 abc of- (a,b,c) -> do- sa <- compose a- sb <- compose b- sc <- compose c- ra <- LLVM.insertvalue (LLVM.value LLVM.undef) sa TypeNum.d0- rb <- LLVM.insertvalue ra sb TypeNum.d1- LLVM.insertvalue rb sc TypeNum.d2--instance (C a, C b, C c, C d) => C (a,b,c,d) where- type Struct (a,b,c,d) = LLVM.Struct (Struct a, (Struct b, (Struct c, (Struct d, ()))))- decompose abcd =- pure MultiValue.zip4- <*> (decompose =<< LLVM.extractvalue abcd TypeNum.d0)- <*> (decompose =<< LLVM.extractvalue abcd TypeNum.d1)- <*> (decompose =<< LLVM.extractvalue abcd TypeNum.d2)- <*> (decompose =<< LLVM.extractvalue abcd TypeNum.d3)- compose abcd =- case MultiValue.unzip4 abcd of- (a,b,c,d) -> do- sa <- compose a- sb <- compose b- sc <- compose c- sd <- compose d- ra <- LLVM.insertvalue (LLVM.value LLVM.undef) sa TypeNum.d0- rb <- LLVM.insertvalue ra sb TypeNum.d1- rc <- LLVM.insertvalue rb sc TypeNum.d2- LLVM.insertvalue rc sd TypeNum.d3---castStructPtr :: Ptr a -> Ptr (Struct a)-castStructPtr = castPtr
src/LLVM/Extra/Multi/Value/Private.hs view
@@ -7,15 +7,15 @@ import qualified LLVM.Extra.ScalarOrVector as SoV import qualified LLVM.Extra.Arithmetic as A import qualified LLVM.Extra.Control as C-import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple+import qualified LLVM.Extra.MaybePrivate as Maybe import qualified LLVM.Core as LLVM-import qualified LLVM.Util.Loop as Loop-import LLVM.Util.Loop (Phi, ) import LLVM.Core (WordN, IntN, ) import qualified Type.Data.Num.Decimal.Number as Dec +import qualified Foreign.Storable.Record.Tuple as StoreTuple import Foreign.StablePtr (StablePtr, ) import Foreign.Ptr (Ptr, FunPtr, ) @@ -25,7 +25,7 @@ import Data.Functor (Functor, ) import qualified Data.Tuple.HT as TupleHT-import qualified Data.Tuple as Tuple+import qualified Data.Tuple as Tup import qualified Data.EnumBitSet as EnumBitSet import qualified Data.Enum.Storable as Enum import qualified Data.Bool8 as Bool8@@ -35,212 +35,239 @@ import Data.Tuple.HT (uncurry3, ) import Data.Maybe (Maybe(Nothing,Just), ) import Data.Bool (Bool(False,True), )-import Data.Word (Word8, Word16, Word32, Word64, )-import Data.Int (Int8, Int16, Int32, Int64, )+import Data.Word (Word8, Word16, Word32, Word64, Word)+import Data.Int (Int8, Int16, Int32, Int64, Int) import Data.Bool8 (Bool8) import qualified Prelude as P import Prelude (Float, Double, Integer, Rational, ) -newtype T a = Cons (Repr LLVM.Value a)+newtype T a = Cons (Tuple.ValueOf a) class C a where- type Repr (f :: * -> *) a :: * cons :: a -> T a undef :: T a zero :: T a- phis :: LLVM.BasicBlock -> T a -> LLVM.CodeGenFunction r (T a)- addPhis :: LLVM.BasicBlock -> T a -> T a -> LLVM.CodeGenFunction r ()+ phi :: LLVM.BasicBlock -> T a -> LLVM.CodeGenFunction r (T a)+ addPhi :: LLVM.BasicBlock -> T a -> T a -> LLVM.CodeGenFunction r () instance C Bool where- type Repr f Bool = f Bool cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C Float where- type Repr f Float = f Float cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C Double where- type Repr f Double = f Double cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive +instance C Word where+ cons = consPrimitive+ undef = undefPrimitive+ zero = zeroPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive+ instance C Word8 where- type Repr f Word8 = f Word8 cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C Word16 where- type Repr f Word16 = f Word16 cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C Word32 where- type Repr f Word32 = f Word32 cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C Word64 where- type Repr f Word64 = f Word64 cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance (Dec.Positive n) => C (LLVM.WordN n) where- type Repr f (LLVM.WordN n) = f (LLVM.WordN n) cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive +instance C Int where+ cons = consPrimitive+ undef = undefPrimitive+ zero = zeroPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive+ instance C Int8 where- type Repr f Int8 = f Int8 cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C Int16 where- type Repr f Int16 = f Int16 cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C Int32 where- type Repr f Int32 = f Int32 cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C Int64 where- type Repr f Int64 = f Int64 cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance (Dec.Positive n) => C (LLVM.IntN n) where- type Repr f (LLVM.IntN n) = f (LLVM.IntN n) cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive -instance (LLVM.IsType a) => C (Ptr a) where- -- Do we also have to convert the pointer target type?- type Repr f (Ptr a) = f (Ptr a)+instance (LLVM.IsType a) => C (LLVM.Ptr a) where cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive +instance C (Ptr a) where+ cons = consPrimitive+ undef = undefPrimitive+ zero = zeroPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive+ instance (LLVM.IsFunction a) => C (FunPtr a) where- type Repr f (FunPtr a) = f (FunPtr a) cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance C (StablePtr a) where- type Repr f (StablePtr a) = f (StablePtr a) cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive consPrimitive ::- (LLVM.IsConst al, LLVM.Value al ~ Repr LLVM.Value a) =>+ (LLVM.IsConst al, LLVM.Value al ~ Tuple.ValueOf a) => al -> T a consPrimitive = Cons . LLVM.valueOf undefPrimitive, zeroPrimitive ::- (LLVM.IsType al, LLVM.Value al ~ Repr LLVM.Value a) =>+ (LLVM.IsType al, LLVM.Value al ~ Tuple.ValueOf a) => T a undefPrimitive = Cons $ LLVM.value LLVM.undef zeroPrimitive = Cons $ LLVM.value LLVM.zero -phisPrimitive ::- (LLVM.IsFirstClass al, LLVM.Value al ~ Repr LLVM.Value a) =>+phiPrimitive ::+ (LLVM.IsFirstClass al, LLVM.Value al ~ Tuple.ValueOf a) => LLVM.BasicBlock -> T a -> LLVM.CodeGenFunction r (T a)-phisPrimitive bb (Cons a) = fmap Cons $ Loop.phis bb a+phiPrimitive bb (Cons a) = fmap Cons $ Tuple.phi bb a -addPhisPrimitive ::- (LLVM.IsFirstClass al, LLVM.Value al ~ Repr LLVM.Value a) =>+addPhiPrimitive ::+ (LLVM.IsFirstClass al, LLVM.Value al ~ Tuple.ValueOf a) => LLVM.BasicBlock -> T a -> T a -> LLVM.CodeGenFunction r ()-addPhisPrimitive bb (Cons a) (Cons b) = Loop.addPhis bb a b+addPhiPrimitive bb (Cons a) (Cons b) = Tuple.addPhi bb a b +consTuple ::+ (Tuple.Value a) =>+ a -> T a+consTuple = Cons . Tuple.valueOf++undefTuple ::+ (Tuple.Value a, Tuple.ValueOf a ~ al, Tuple.Undefined al) =>+ T a+undefTuple = Cons Tuple.undef++zeroTuple ::+ (Tuple.Value a, Tuple.ValueOf a ~ al, Tuple.Zero al) =>+ T a+zeroTuple = Cons Tuple.zero++phiTuple ::+ (Tuple.Value a, Tuple.ValueOf a ~ al, Tuple.Phi al) =>+ LLVM.BasicBlock -> T a -> LLVM.CodeGenFunction r (T a)+phiTuple bb (Cons a) = fmap Cons $ Tuple.phi bb a++addPhiTuple ::+ (Tuple.Value a, Tuple.ValueOf a ~ al, Tuple.Phi al) =>+ LLVM.BasicBlock -> T a -> T a -> LLVM.CodeGenFunction r ()+addPhiTuple bb (Cons a) (Cons b) = Tuple.addPhi bb a b++ instance C () where- type Repr f () = () cons = consUnit undef = undefUnit zero = zeroUnit- phis = phisUnit- addPhis = addPhisUnit+ phi = phiUnit+ addPhi = addPhiUnit -consUnit :: (Repr LLVM.Value a ~ ()) => a -> T a+consUnit :: (Tuple.ValueOf a ~ ()) => a -> T a consUnit _ = Cons () -undefUnit :: (Repr LLVM.Value a ~ ()) => T a+undefUnit :: (Tuple.ValueOf a ~ ()) => T a undefUnit = Cons () -zeroUnit :: (Repr LLVM.Value a ~ ()) => T a+zeroUnit :: (Tuple.ValueOf a ~ ()) => T a zeroUnit = Cons () -phisUnit ::- (Repr LLVM.Value a ~ ()) =>+phiUnit ::+ (Tuple.ValueOf a ~ ()) => LLVM.BasicBlock -> T a -> LLVM.CodeGenFunction r (T a)-phisUnit _bb (Cons ()) = return $ Cons ()+phiUnit _bb (Cons ()) = return $ Cons () -addPhisUnit ::- (Repr LLVM.Value a ~ ()) =>+addPhiUnit ::+ (Tuple.ValueOf a ~ ()) => LLVM.BasicBlock -> T a -> T a -> LLVM.CodeGenFunction r ()-addPhisUnit _bb (Cons ()) (Cons ()) = return ()+addPhiUnit _bb (Cons ()) (Cons ()) = return () instance C Bool8 where- type Repr f Bool8 = f Bool cons = consPrimitive . Bool8.toBool undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive boolPFrom8 :: T Bool8 -> T Bool boolPFrom8 (Cons b) = Cons b@@ -259,20 +286,19 @@ instance (LLVM.IsInteger w, LLVM.IsConst w, P.Num w, P.Enum e) => C (Enum.T w e) where- type Repr f (Enum.T w e) = f w cons = consPrimitive . P.fromIntegral . P.fromEnum . Enum.toPlain undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive toEnum ::- (Repr LLVM.Value w ~ LLVM.Value w) =>+ (Tuple.ValueOf w ~ LLVM.Value w) => T w -> T (Enum.T w e) toEnum (Cons w) = Cons w fromEnum ::- (Repr LLVM.Value w ~ LLVM.Value w) =>+ (Tuple.ValueOf w ~ LLVM.Value w) => T (Enum.T w e) -> T w fromEnum (Cons w) = Cons w @@ -301,34 +327,32 @@ instance (LLVM.IsInteger w, LLVM.IsConst w) => C (EnumBitSet.T w i) where- type Repr f (EnumBitSet.T w i) = f w cons = consPrimitive . EnumBitSet.decons undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive instance (C a) => C (Maybe a) where- type Repr f (Maybe a) = (f Bool, Repr f a) cons Nothing = nothing cons (Just a) = just $ cons a undef = toMaybe undef undef zero = toMaybe (cons False) zero- phis bb ma =+ phi bb ma = case splitMaybe ma of- (b,a) -> Monad.lift2 toMaybe (phis bb b) (phis bb a)- addPhis bb x y =+ (b,a) -> Monad.lift2 toMaybe (phi bb b) (phi bb a)+ addPhi bb x y = case (splitMaybe x, splitMaybe y) of ((xb,xa), (yb,ya)) ->- addPhis bb xb yb >>- addPhis bb xa ya+ addPhi bb xb yb >>+ addPhi bb xa ya splitMaybe :: T (Maybe a) -> (T Bool, T a)-splitMaybe (Cons (b,a)) = (Cons b, Cons a)+splitMaybe (Cons (Maybe.Cons b a)) = (Cons b, Cons a) toMaybe :: T Bool -> T a -> T (Maybe a)-toMaybe (Cons b) (Cons a) = Cons (b,a)+toMaybe (Cons b) (Cons a) = Cons (Maybe.Cons b a) nothing :: (C a) => T (Maybe a) nothing = toMaybe (cons False) undef@@ -338,52 +362,49 @@ instance (C a, C b) => C (a,b) where- type Repr f (a, b) = (Repr f a, Repr f b) cons (a,b) = zip (cons a) (cons b) undef = zip undef undef zero = zip zero zero- phis bb a =+ phi bb a = case unzip a of (a0,a1) ->- Monad.lift2 zip (phis bb a0) (phis bb a1)- addPhis bb a b =+ Monad.lift2 zip (phi bb a0) (phi bb a1)+ addPhi bb a b = case (unzip a, unzip b) of ((a0,a1), (b0,b1)) ->- addPhis bb a0 b0 >>- addPhis bb a1 b1+ addPhi bb a0 b0 >>+ addPhi bb a1 b1 instance (C a, C b, C c) => C (a,b,c) where- type Repr f (a, b, c) = (Repr f a, Repr f b, Repr f c) cons (a,b,c) = zip3 (cons a) (cons b) (cons c) undef = zip3 undef undef undef zero = zip3 zero zero zero- phis bb a =+ phi bb a = case unzip3 a of (a0,a1,a2) ->- Monad.lift3 zip3 (phis bb a0) (phis bb a1) (phis bb a2)- addPhis bb a b =+ Monad.lift3 zip3 (phi bb a0) (phi bb a1) (phi bb a2)+ addPhi bb a b = case (unzip3 a, unzip3 b) of ((a0,a1,a2), (b0,b1,b2)) ->- addPhis bb a0 b0 >>- addPhis bb a1 b1 >>- addPhis bb a2 b2+ addPhi bb a0 b0 >>+ addPhi bb a1 b1 >>+ addPhi bb a2 b2 instance (C a, C b, C c, C d) => C (a,b,c,d) where- type Repr f (a, b, c, d) = (Repr f a, Repr f b, Repr f c, Repr f d) cons (a,b,c,d) = zip4 (cons a) (cons b) (cons c) (cons d) undef = zip4 undef undef undef undef zero = zip4 zero zero zero zero- phis bb a =+ phi bb a = case unzip4 a of (a0,a1,a2,a3) ->- Monad.lift4 zip4 (phis bb a0) (phis bb a1) (phis bb a2) (phis bb a3)- addPhis bb a b =+ Monad.lift4 zip4 (phi bb a0) (phi bb a1) (phi bb a2) (phi bb a3)+ addPhi bb a b = case (unzip4 a, unzip4 b) of ((a0,a1,a2,a3), (b0,b1,b2,b3)) ->- addPhis bb a0 b0 >>- addPhis bb a1 b1 >>- addPhis bb a2 b2 >>- addPhis bb a3 b3+ addPhi bb a0 b0 >>+ addPhi bb a1 b1 >>+ addPhi bb a2 b2 >>+ addPhi bb a3 b3 fst :: T (a,b) -> T a@@ -396,23 +417,23 @@ curry f a b = f $ zip a b uncurry :: (T a -> T b -> c) -> (T (a,b) -> c)-uncurry f = Tuple.uncurry f . unzip+uncurry f = Tup.uncurry f . unzip mapFst :: (T a0 -> T a1) -> T (a0,b) -> T (a1,b)-mapFst f = Tuple.uncurry zip . TupleHT.mapFst f . unzip+mapFst f = Tup.uncurry zip . TupleHT.mapFst f . unzip mapSnd :: (T b0 -> T b1) -> T (a,b0) -> T (a,b1)-mapSnd f = Tuple.uncurry zip . TupleHT.mapSnd f . unzip+mapSnd f = Tup.uncurry zip . TupleHT.mapSnd f . unzip mapFstF :: (Functor f) => (T a0 -> f (T a1)) -> T (a0,b) -> f (T (a1,b))-mapFstF f = fmap (Tuple.uncurry zip) . FuncHT.mapFst f . unzip+mapFstF f = fmap (Tup.uncurry zip) . FuncHT.mapFst f . unzip mapSndF :: (Functor f) => (T b0 -> f (T b1)) -> T (a,b0) -> f (T (a,b1))-mapSndF f = fmap (Tuple.uncurry zip) . FuncHT.mapSnd f . unzip+mapSndF f = fmap (Tup.uncurry zip) . FuncHT.mapSnd f . unzip swap :: T (a,b) -> T (b,a)-swap = Tuple.uncurry zip . TupleHT.swap . unzip+swap = Tup.uncurry zip . TupleHT.swap . unzip fst3 :: T (a,b,c) -> T a@@ -463,13 +484,26 @@ unzip4 (Cons (a,b,c,d)) = (Cons a, Cons b, Cons c, Cons d) +instance (C tuple) => C (StoreTuple.Tuple tuple) where+ cons = tuple . cons . StoreTuple.getTuple+ undef = tuple undef+ zero = tuple zero+ phi bb = fmap tuple . phi bb . untuple+ addPhi bb a b = addPhi bb (untuple a) (untuple b)++tuple :: T tuple -> T (StoreTuple.Tuple tuple)+tuple (Cons a) = Cons a++untuple :: T (StoreTuple.Tuple tuple) -> T tuple+untuple (Cons a) = Cons a++ instance C a => C (Tagged tag a) where- type Repr f (Tagged tag a) = Repr f a cons = tag . cons . unTagged undef = tag undef zero = tag zero- phis bb = fmap tag . phis bb . untag- addPhis bb a b = addPhis bb (untag a) (untag b)+ phi bb = fmap tag . phi bb . untag+ addPhi bb a b = addPhi bb (untag a) (untag b) tag :: T a -> T (Tagged tag a) tag (Cons a) = Cons a@@ -489,19 +523,18 @@ instance (C a) => C (Complex a) where- type Repr f (Complex a) = Complex (Repr f a) cons (a:+b) = consComplex (cons a) (cons b) undef = consComplex undef undef zero = consComplex zero zero- phis bb a =+ phi bb a = case deconsComplex a of (a0,a1) ->- Monad.lift2 consComplex (phis bb a0) (phis bb a1)- addPhis bb a b =+ Monad.lift2 consComplex (phi bb a0) (phi bb a1)+ addPhi bb a b = case (deconsComplex a, deconsComplex b) of ((a0,a1), (b0,b1)) ->- addPhis bb a0 b0 >>- addPhis bb a1 b1+ addPhi bb a0 b0 >>+ addPhi bb a1 b1 consComplex :: T a -> T a -> T (Complex a) consComplex (Cons a) (Cons b) = Cons (a:+b)@@ -603,7 +636,7 @@ instance (Compose a, Compose b) => Compose (a,b) where type Composed (a,b) = (Composed a, Composed b)- compose = Tuple.uncurry zip . TupleHT.mapPair (compose, compose)+ compose = Tup.uncurry zip . TupleHT.mapPair (compose, compose) instance (Decompose pa, Decompose pb) => Decompose (pa,pb) where decompose (pa,pb) =@@ -646,6 +679,19 @@ (PatternTuple pa, PatternTuple pb, PatternTuple pc, PatternTuple pd) +instance (Compose tuple) => Compose (StoreTuple.Tuple tuple) where+ type Composed (StoreTuple.Tuple tuple) = StoreTuple.Tuple (Composed tuple)+ compose = tuple . compose . StoreTuple.getTuple++instance (Decompose p) => Decompose (StoreTuple.Tuple p) where+ decompose (StoreTuple.Tuple p) = StoreTuple.Tuple . decompose p . untuple++type instance Decomposed f (StoreTuple.Tuple p) =+ StoreTuple.Tuple (Decomposed f p)+type instance PatternTuple (StoreTuple.Tuple p) =+ StoreTuple.Tuple (PatternTuple p)++ instance (Compose a) => Compose (Tagged tag a) where type Composed (Tagged tag a) = Tagged tag (Composed a) compose = tag . compose . unTagged@@ -663,7 +709,7 @@ instance (Decompose pa) => Decompose (Complex pa) where decompose (pa:+pb) =- Tuple.uncurry (:+) .+ Tup.uncurry (:+) . TupleHT.mapPair (decompose pa, decompose pb) . deconsComplex type instance Decomposed f (Complex pa) = Complex (Decomposed f pa)@@ -675,44 +721,44 @@ -lift1 :: (Repr LLVM.Value a -> Repr LLVM.Value b) -> T a -> T b+lift1 :: (Tuple.ValueOf a -> Tuple.ValueOf b) -> T a -> T b lift1 f (Cons a) = Cons $ f a liftM0 :: (Monad m) =>- m (Repr LLVM.Value a) ->+ m (Tuple.ValueOf a) -> m (T a) liftM0 f = Monad.lift Cons f liftM :: (Monad m) =>- (Repr LLVM.Value a -> m (Repr LLVM.Value b)) ->+ (Tuple.ValueOf a -> m (Tuple.ValueOf b)) -> T a -> m (T b) liftM f (Cons a) = Monad.lift Cons $ f a liftM2 :: (Monad m) =>- (Repr LLVM.Value a -> Repr LLVM.Value b -> m (Repr LLVM.Value c)) ->+ (Tuple.ValueOf a -> Tuple.ValueOf b -> m (Tuple.ValueOf c)) -> T a -> T b -> m (T c) liftM2 f (Cons a) (Cons b) = Monad.lift Cons $ f a b liftM3 :: (Monad m) =>- (Repr LLVM.Value a -> Repr LLVM.Value b -> Repr LLVM.Value c ->- m (Repr LLVM.Value d)) ->+ (Tuple.ValueOf a -> Tuple.ValueOf b -> Tuple.ValueOf c ->+ m (Tuple.ValueOf d)) -> T a -> T b -> T c -> m (T d) liftM3 f (Cons a) (Cons b) (Cons c) = Monad.lift Cons $ f a b c -instance (C a) => Class.Zero (T a) where- zeroTuple = zero+instance (C a) => Tuple.Zero (T a) where+ zero = zero -instance (C a) => Class.Undefined (T a) where- undefTuple = undef+instance (C a) => Tuple.Undefined (T a) where+ undef = undef -instance (C a) => Phi (T a) where- phis = phis- addPhis = addPhis+instance (C a) => Tuple.Phi (T a) where+ phi = phi+ addPhi = addPhi class (C a) => IntegerConstant a where@@ -724,11 +770,13 @@ instance IntegerConstant Float where fromInteger' = Cons . LLVM.value . SoV.constFromInteger instance IntegerConstant Double where fromInteger' = Cons . LLVM.value . SoV.constFromInteger +instance IntegerConstant Word where fromInteger' = Cons . LLVM.value . SoV.constFromInteger instance IntegerConstant Word8 where fromInteger' = Cons . LLVM.value . SoV.constFromInteger instance IntegerConstant Word16 where fromInteger' = Cons . LLVM.value . SoV.constFromInteger instance IntegerConstant Word32 where fromInteger' = Cons . LLVM.value . SoV.constFromInteger instance IntegerConstant Word64 where fromInteger' = Cons . LLVM.value . SoV.constFromInteger +instance IntegerConstant Int where fromInteger' = Cons . LLVM.value . SoV.constFromInteger instance IntegerConstant Int8 where fromInteger' = Cons . LLVM.value . SoV.constFromInteger instance IntegerConstant Int16 where fromInteger' = Cons . LLVM.value . SoV.constFromInteger instance IntegerConstant Int32 where fromInteger' = Cons . LLVM.value . SoV.constFromInteger@@ -769,6 +817,11 @@ sub = liftM2 LLVM.sub neg = liftM LLVM.neg +instance Additive Word where+ add = liftM2 LLVM.add+ sub = liftM2 LLVM.sub+ neg = liftM LLVM.neg+ instance Additive Word8 where add = liftM2 LLVM.add sub = liftM2 LLVM.sub@@ -789,6 +842,11 @@ sub = liftM2 LLVM.sub neg = liftM LLVM.neg +instance Additive Int where+ add = liftM2 LLVM.add+ sub = liftM2 LLVM.sub+ neg = liftM LLVM.neg+ instance Additive Int8 where add = liftM2 LLVM.add sub = liftM2 LLVM.sub@@ -841,10 +899,12 @@ instance PseudoRing Float where mul = liftM2 LLVM.mul instance PseudoRing Double where mul = liftM2 LLVM.mul+instance PseudoRing Word where mul = liftM2 LLVM.mul instance PseudoRing Word8 where mul = liftM2 LLVM.mul instance PseudoRing Word16 where mul = liftM2 LLVM.mul instance PseudoRing Word32 where mul = liftM2 LLVM.mul instance PseudoRing Word64 where mul = liftM2 LLVM.mul+instance PseudoRing Int where mul = liftM2 LLVM.mul instance PseudoRing Int8 where mul = liftM2 LLVM.mul instance PseudoRing Int16 where mul = liftM2 LLVM.mul instance PseudoRing Int32 where mul = liftM2 LLVM.mul@@ -913,6 +973,12 @@ abs = liftM A.abs signum = liftM A.signum +instance Real Word where+ min = liftM2 A.min+ max = liftM2 A.max+ abs = liftM A.abs+ signum = liftM A.signum+ instance Real Word8 where min = liftM2 A.min max = liftM2 A.max@@ -937,6 +1003,12 @@ abs = liftM A.abs signum = liftM A.signum +instance Real Int where+ min = liftM2 A.min+ max = liftM2 A.max+ abs = liftM A.abs+ signum = liftM A.signum+ instance Real Int8 where min = liftM2 A.min max = liftM2 A.max@@ -1008,17 +1080,19 @@ class- (Repr LLVM.Value i ~ LLVM.Value ir,+ (Tuple.ValueOf i ~ LLVM.Value ir, LLVM.IsInteger ir, SoV.IntegerConstant ir, LLVM.CmpRet ir, LLVM.IsPrimitive ir) => NativeInteger i ir where -instance NativeInteger Word8 Word8 where+instance NativeInteger Word Word where+instance NativeInteger Word8 Word8 where instance NativeInteger Word16 Word16 where instance NativeInteger Word32 Word32 where instance NativeInteger Word64 Word64 where -instance NativeInteger Int8 Int8 where+instance NativeInteger Int Int where+instance NativeInteger Int8 Int8 where instance NativeInteger Int16 Int16 where instance NativeInteger Int32 Int32 where instance NativeInteger Int64 Int64 where@@ -1027,7 +1101,7 @@ class- (Repr LLVM.Value a ~ LLVM.Value ar,+ (Tuple.ValueOf a ~ LLVM.Value ar, LLVM.IsFloating ar, SoV.RationalConstant ar, LLVM.CmpRet ar, LLVM.IsPrimitive ar) => NativeFloating a ar where@@ -1114,10 +1188,12 @@ instance Select Bool8 where select = liftM3 LLVM.select instance Select Float where select = liftM3 LLVM.select instance Select Double where select = liftM3 LLVM.select+instance Select Word where select = liftM3 LLVM.select instance Select Word8 where select = liftM3 LLVM.select instance Select Word16 where select = liftM3 LLVM.select instance Select Word32 where select = liftM3 LLVM.select instance Select Word64 where select = liftM3 LLVM.select+instance Select Int where select = liftM3 LLVM.select instance Select Int8 where select = liftM3 LLVM.select instance Select Int16 where select = liftM3 LLVM.select instance Select Int32 where select = liftM3 LLVM.select@@ -1161,11 +1237,13 @@ instance Comparison Float where cmp = liftM2 . LLVM.cmp instance Comparison Double where cmp = liftM2 . LLVM.cmp +instance Comparison Int where cmp = liftM2 . LLVM.cmp instance Comparison Int8 where cmp = liftM2 . LLVM.cmp instance Comparison Int16 where cmp = liftM2 . LLVM.cmp instance Comparison Int32 where cmp = liftM2 . LLVM.cmp instance Comparison Int64 where cmp = liftM2 . LLVM.cmp +instance Comparison Word where cmp = liftM2 . LLVM.cmp instance Comparison Word8 where cmp = liftM2 . LLVM.cmp instance Comparison Word16 where cmp = liftM2 . LLVM.cmp instance Comparison Word32 where cmp = liftM2 . LLVM.cmp@@ -1254,6 +1332,9 @@ shl :: T a -> T a -> LLVM.CodeGenFunction r (T a) shr :: T a -> T a -> LLVM.CodeGenFunction r (T a) +instance BitShift Word where+ shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr+ instance BitShift Word8 where shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr @@ -1266,6 +1347,9 @@ instance BitShift Word64 where shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr +instance BitShift Int where+ shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr+ instance BitShift Int8 where shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr @@ -1284,11 +1368,19 @@ idiv :: T a -> T a -> LLVM.CodeGenFunction r (T a) irem :: T a -> T a -> LLVM.CodeGenFunction r (T a) +instance Integral Word where+ idiv = liftM2 LLVM.idiv+ irem = liftM2 LLVM.irem+ instance Integral Word32 where idiv = liftM2 LLVM.idiv irem = liftM2 LLVM.irem instance Integral Word64 where+ idiv = liftM2 LLVM.idiv+ irem = liftM2 LLVM.irem++instance Integral Int where idiv = liftM2 LLVM.idiv irem = liftM2 LLVM.irem
src/LLVM/Extra/Multi/Value/Vector.hs view
@@ -20,6 +20,7 @@ import qualified LLVM.Extra.Multi.Vector.Instance as Inst import qualified LLVM.Extra.Multi.Vector as MultiVector import qualified LLVM.Extra.Multi.Value.Private as MultiValue+import LLVM.Extra.Multi.Vector.Instance (MVVector) import qualified LLVM.Core as LLVM @@ -34,133 +35,113 @@ cons :: (TypeNum.Positive n, MultiVector.C a) =>- LLVM.Vector n a -> MultiValue.T (LLVM.Vector n a)+ LLVM.Vector n a -> MVVector n a cons = Inst.toMultiValue . MultiVector.cons -fst :: MultiValue.T (LLVM.Vector n (a,b)) -> MultiValue.T (LLVM.Vector n a)+fst :: MVVector n (a,b) -> MVVector n a fst = MultiValue.lift1 Tuple.fst -snd :: MultiValue.T (LLVM.Vector n (a,b)) -> MultiValue.T (LLVM.Vector n b)+snd :: MVVector n (a,b) -> MVVector n b snd = MultiValue.lift1 Tuple.snd -swap :: MultiValue.T (LLVM.Vector n (a,b)) -> MultiValue.T (LLVM.Vector n (b,a))+swap :: MVVector n (a,b) -> MVVector n (b,a) swap = MultiValue.lift1 TupleHT.swap mapFst ::- (MultiValue.T (LLVM.Vector n a0) -> MultiValue.T (LLVM.Vector n a1)) ->- MultiValue.T (LLVM.Vector n (a0,b)) -> MultiValue.T (LLVM.Vector n (a1,b))+ (MVVector n a0 -> MVVector n a1) ->+ MVVector n (a0,b) -> MVVector n (a1,b) mapFst f = Tuple.uncurry zip . TupleHT.mapFst f . unzip mapSnd ::- (MultiValue.T (LLVM.Vector n b0) -> MultiValue.T (LLVM.Vector n b1)) ->- MultiValue.T (LLVM.Vector n (a,b0)) -> MultiValue.T (LLVM.Vector n (a,b1))+ (MVVector n b0 -> MVVector n b1) ->+ MVVector n (a,b0) -> MVVector n (a,b1) mapSnd f = Tuple.uncurry zip . TupleHT.mapSnd f . unzip -fst3 :: MultiValue.T (LLVM.Vector n (a,b,c)) -> MultiValue.T (LLVM.Vector n a)+fst3 :: MVVector n (a,b,c) -> MVVector n a fst3 = MultiValue.lift1 TupleHT.fst3 -snd3 :: MultiValue.T (LLVM.Vector n (a,b,c)) -> MultiValue.T (LLVM.Vector n b)+snd3 :: MVVector n (a,b,c) -> MVVector n b snd3 = MultiValue.lift1 TupleHT.snd3 -thd3 :: MultiValue.T (LLVM.Vector n (a,b,c)) -> MultiValue.T (LLVM.Vector n c)+thd3 :: MVVector n (a,b,c) -> MVVector n c thd3 = MultiValue.lift1 TupleHT.thd3 mapFst3 ::- (MultiValue.T (LLVM.Vector n a0) -> MultiValue.T (LLVM.Vector n a1)) ->- MultiValue.T (LLVM.Vector n (a0,b,c)) ->- MultiValue.T (LLVM.Vector n (a1,b,c))+ (MVVector n a0 -> MVVector n a1) ->+ MVVector n (a0,b,c) -> MVVector n (a1,b,c) mapFst3 f = TupleHT.uncurry3 zip3 . TupleHT.mapFst3 f . unzip3 mapSnd3 ::- (MultiValue.T (LLVM.Vector n b0) -> MultiValue.T (LLVM.Vector n b1)) ->- MultiValue.T (LLVM.Vector n (a,b0,c)) ->- MultiValue.T (LLVM.Vector n (a,b1,c))+ (MVVector n b0 -> MVVector n b1) ->+ MVVector n (a,b0,c) -> MVVector n (a,b1,c) mapSnd3 f = TupleHT.uncurry3 zip3 . TupleHT.mapSnd3 f . unzip3 mapThd3 ::- (MultiValue.T (LLVM.Vector n c0) -> MultiValue.T (LLVM.Vector n c1)) ->- MultiValue.T (LLVM.Vector n (a,b,c0)) ->- MultiValue.T (LLVM.Vector n (a,b,c1))+ (MVVector n c0 -> MVVector n c1) ->+ MVVector n (a,b,c0) -> MVVector n (a,b,c1) mapThd3 f = TupleHT.uncurry3 zip3 . TupleHT.mapThd3 f . unzip3 -zip ::- MultiValue.T (LLVM.Vector n a) ->- MultiValue.T (LLVM.Vector n b) ->- MultiValue.T (LLVM.Vector n (a,b))+zip :: MVVector n a -> MVVector n b -> MVVector n (a,b) zip (MultiValue.Cons a) (MultiValue.Cons b) = MultiValue.Cons (a,b) -zip3 ::- MultiValue.T (LLVM.Vector n a) ->- MultiValue.T (LLVM.Vector n b) ->- MultiValue.T (LLVM.Vector n c) ->- MultiValue.T (LLVM.Vector n (a,b,c))+zip3 :: MVVector n a -> MVVector n b -> MVVector n c -> MVVector n (a,b,c) zip3 (MultiValue.Cons a) (MultiValue.Cons b) (MultiValue.Cons c) = MultiValue.Cons (a,b,c) -unzip ::- MultiValue.T (LLVM.Vector n (a,b)) ->- (MultiValue.T (LLVM.Vector n a),- MultiValue.T (LLVM.Vector n b))+unzip :: MVVector n (a,b) -> (MVVector n a, MVVector n b) unzip (MultiValue.Cons (a,b)) = (MultiValue.Cons a, MultiValue.Cons b) -unzip3 ::- MultiValue.T (LLVM.Vector n (a,b,c)) ->- (MultiValue.T (LLVM.Vector n a),- MultiValue.T (LLVM.Vector n b),- MultiValue.T (LLVM.Vector n c))+unzip3 :: MVVector n (a,b,c) -> (MVVector n a, MVVector n b, MVVector n c) unzip3 (MultiValue.Cons (a,b,c)) = (MultiValue.Cons a, MultiValue.Cons b, MultiValue.Cons c) extract :: (TypeNum.Positive n, MultiVector.C a) =>- LLVM.Value Word32 -> MultiValue.T (LLVM.Vector n a) ->+ LLVM.Value Word32 -> MVVector n a -> LLVM.CodeGenFunction r (MultiValue.T a) extract k v = MultiVector.extract k (Inst.fromMultiValue v) insert :: (TypeNum.Positive n, MultiVector.C a) => LLVM.Value Word32 -> MultiValue.T a ->- MultiValue.T (LLVM.Vector n a) ->- LLVM.CodeGenFunction r (MultiValue.T (LLVM.Vector n a))+ MVVector n a -> LLVM.CodeGenFunction r (MVVector n a) insert k a = Inst.liftMultiValueM (MultiVector.insert k a) replicate :: (TypeNum.Positive n, MultiVector.C a) =>- MultiValue.T a -> LLVM.CodeGenFunction r (MultiValue.T (LLVM.Vector n a))+ MultiValue.T a -> LLVM.CodeGenFunction r (MVVector n a) replicate = fmap Inst.toMultiValue . MultiVector.replicate take :: (TypeNum.Positive n, TypeNum.Positive m, MultiVector.C a) =>- MultiValue.T (LLVM.Vector n a) ->- LLVM.CodeGenFunction r (MultiValue.T (LLVM.Vector m a))+ MVVector n a -> LLVM.CodeGenFunction r (MVVector m a) take = Inst.liftMultiValueM MultiVector.take takeRev :: (TypeNum.Positive n, TypeNum.Positive m, MultiVector.C a) =>- MultiValue.T (LLVM.Vector n a) ->- LLVM.CodeGenFunction r (MultiValue.T (LLVM.Vector m a))+ MVVector n a -> LLVM.CodeGenFunction r (MVVector m a) takeRev = Inst.liftMultiValueM MultiVector.takeRev dissect :: (TypeNum.Positive n, MultiVector.C a) =>- MultiValue.T (LLVM.Vector n a) -> LLVM.CodeGenFunction r [MultiValue.T a]+ MVVector n a -> LLVM.CodeGenFunction r [MultiValue.T a] dissect = MultiVector.dissect . Inst.fromMultiValue select :: (TypeNum.Positive n, MultiVector.Select a) =>- MultiValue.T (LLVM.Vector n Bool) ->- MultiValue.T (LLVM.Vector n a) -> MultiValue.T (LLVM.Vector n a) ->- LLVM.CodeGenFunction r (MultiValue.T (LLVM.Vector n a))+ MVVector n Bool ->+ MVVector n a -> MVVector n a ->+ LLVM.CodeGenFunction r (MVVector n a) select = Inst.liftMultiValueM3 MultiVector.select cmp :: (TypeNum.Positive n, MultiVector.Comparison a) => LLVM.CmpPredicate ->- MultiValue.T (LLVM.Vector n a) -> MultiValue.T (LLVM.Vector n a) ->- LLVM.CodeGenFunction r (MultiValue.T (LLVM.Vector n Bool))+ MVVector n a -> MVVector n a ->+ LLVM.CodeGenFunction r (MVVector n Bool) cmp = Inst.liftMultiValueM2 . MultiVector.cmp
src/LLVM/Extra/Multi/Vector.hs view
@@ -57,12 +57,9 @@ import qualified LLVM.Extra.Multi.Value.Private as MultiValue import qualified LLVM.Extra.ScalarOrVector as SoV import qualified LLVM.Extra.Arithmetic as A-import qualified LLVM.Extra.Class as Class-import LLVM.Extra.Multi.Value.Private (Repr, )+import qualified LLVM.Extra.Tuple as Tuple -import qualified LLVM.Util.Loop as Loop import qualified LLVM.Core as LLVM-import LLVM.Util.Loop (Phi, ) import LLVM.Core (CodeGenFunction, IsPrimitive, valueOf, value, ) import qualified Type.Data.Num.Decimal as TypeNum@@ -72,22 +69,20 @@ import qualified Data.NonEmpty as NonEmpty import qualified Data.List as List import qualified Data.Bool8 as Bool8-import Data.Functor.Compose (Compose(Compose), ) import Data.Traversable (mapM, sequence, )-import Data.Functor ((<$>), ) import Data.NonEmpty ((!:), ) import Data.Function (flip, (.), ($), )-import Data.Tuple.HT (fst3, snd3, thd3, )-import Data.Tuple (fst, snd, )+import Data.Tuple (snd, ) import Data.Maybe (maybe, ) import Data.Ord ((<), )-import Data.Word (Word8, Word16, Word32, Word64, )+import Data.Word (Word8, Word16, Word32, Word64, Word) import Data.Int (Int8, Int16, Int32, Int64, ) import Data.Bool8 (Bool8) import Data.Bool (Bool, ) import qualified Control.Monad.HT as Monad import qualified Control.Applicative as App+import qualified Control.Functor.HT as FuncHT import Control.Monad.HT ((<=<), ) import Control.Monad (Monad, foldM, fmap, return, (>>), (=<<), ) import Control.Applicative (liftA2, )@@ -97,31 +92,31 @@ fromIntegral, asTypeOf, (-), (+), error, ) -newtype T n a = Cons (Repr (Value n) a)+newtype T n a = Cons (Tuple.VectorValueOf n a) -type Value n = Compose LLVM.Value (LLVM.Vector n)+type Value n a = LLVM.Value (LLVM.Vector n a) consPrim ::- (Repr (Value n) a ~ Value n a) =>+ (Tuple.VectorValueOf n a ~ Value n a) => LLVM.Value (LLVM.Vector n a) -> T n a-consPrim = Cons . Compose+consPrim = Cons deconsPrim ::- (Repr (Value n) a ~ Value n a) =>+ (Tuple.VectorValueOf n a ~ Value n a) => T n a -> LLVM.Value (LLVM.Vector n a)-deconsPrim (Cons (Compose a)) = a+deconsPrim (Cons a) = a -instance (TypeNum.Positive n, C a) => Class.Undefined (T n a) where- undefTuple = undef+instance (TypeNum.Positive n, C a) => Tuple.Undefined (T n a) where+ undef = undef -instance (TypeNum.Positive n, C a) => Class.Zero (T n a) where- zeroTuple = zero+instance (TypeNum.Positive n, C a) => Tuple.Zero (T n a) where+ zero = zero -instance (TypeNum.Positive n, C a) => Phi (T n a) where- phis = phis- addPhis = addPhis+instance (TypeNum.Positive n, C a) => Tuple.Phi (T n a) where+ phi = phi+ addPhi = addPhi size :: TypeNum.Positive n => T n a -> Int@@ -148,10 +143,10 @@ cons :: (TypeNum.Positive n) => LLVM.Vector n a -> T n a undef :: (TypeNum.Positive n) => T n a zero :: (TypeNum.Positive n) => T n a- phis ::+ phi :: (TypeNum.Positive n) => LLVM.BasicBlock -> T n a -> LLVM.CodeGenFunction r (T n a)- addPhis ::+ addPhi :: (TypeNum.Positive n) => LLVM.BasicBlock -> T n a -> T n a -> LLVM.CodeGenFunction r () @@ -171,8 +166,8 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -181,8 +176,8 @@ cons = consPrimitive . fmap Bool8.toBool undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -191,8 +186,8 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -201,18 +196,28 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive +instance C Int where+ cons = consPrimitive+ undef = undefPrimitive+ zero = zeroPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive+ shuffle = shufflePrimitive+ extract = extractPrimitive+ insert = insertPrimitive+ instance C Int8 where cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -221,8 +226,8 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -231,8 +236,8 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -241,18 +246,28 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive +instance C Word where+ cons = consPrimitive+ undef = undefPrimitive+ zero = zeroPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive+ shuffle = shufflePrimitive+ extract = extractPrimitive+ insert = insertPrimitive+ instance C Word8 where cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -261,8 +276,8 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -271,8 +286,8 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive@@ -281,85 +296,81 @@ cons = consPrimitive undef = undefPrimitive zero = zeroPrimitive- phis = phisPrimitive- addPhis = addPhisPrimitive+ phi = phiPrimitive+ addPhi = addPhiPrimitive shuffle = shufflePrimitive extract = extractPrimitive insert = insertPrimitive consPrimitive ::- (TypeNum.Positive n, LLVM.IsConst al, IsPrimitive al,- Repr (Value n) a ~ Value n al) =>+ (TypeNum.Positive n,+ LLVM.IsConst al, IsPrimitive al, Tuple.VectorValueOf n a ~ Value n al) => LLVM.Vector n al -> T n a-consPrimitive = Cons . Compose . LLVM.valueOf+consPrimitive = Cons . LLVM.valueOf undefPrimitive ::- (TypeNum.Positive n, IsPrimitive al,- Repr (Value n) a ~ Value n al) =>+ (TypeNum.Positive n, IsPrimitive al, Tuple.VectorValueOf n a ~ Value n al) => T n a-undefPrimitive = Cons $ Compose $ LLVM.value LLVM.undef+undefPrimitive = Cons $ LLVM.value LLVM.undef zeroPrimitive ::- (TypeNum.Positive n, IsPrimitive al,- Repr (Value n) a ~ Value n al) =>+ (TypeNum.Positive n, IsPrimitive al, Tuple.VectorValueOf n a ~ Value n al) => T n a-zeroPrimitive = Cons $ Compose $ LLVM.value LLVM.zero+zeroPrimitive = Cons $ LLVM.value LLVM.zero -phisPrimitive ::- (TypeNum.Positive n, IsPrimitive al, Repr (Value n) a ~ Value n al) =>+phiPrimitive ::+ (TypeNum.Positive n, IsPrimitive al, Tuple.VectorValueOf n a ~ Value n al) => LLVM.BasicBlock -> T n a -> LLVM.CodeGenFunction r (T n a)-phisPrimitive bb (Cons (Compose a)) = fmap (Cons . Compose) $ Loop.phis bb a+phiPrimitive bb (Cons a) = fmap Cons $ Tuple.phi bb a -addPhisPrimitive ::- (TypeNum.Positive n, IsPrimitive al, Repr (Value n) a ~ Value n al) =>+addPhiPrimitive ::+ (TypeNum.Positive n, IsPrimitive al, Tuple.VectorValueOf n a ~ Value n al) => LLVM.BasicBlock -> T n a -> T n a -> LLVM.CodeGenFunction r ()-addPhisPrimitive bb (Cons (Compose a)) (Cons (Compose b)) = Loop.addPhis bb a b+addPhiPrimitive bb (Cons a) (Cons b) = Tuple.addPhi bb a b shufflePrimitive :: (TypeNum.Positive n, TypeNum.Positive m, IsPrimitive al,- Repr LLVM.Value a ~ LLVM.Value al,- Repr (Value n) a ~ Value n al,- Repr (Value m) a ~ Value m al) =>+ Tuple.ValueOf a ~ LLVM.Value al,+ Tuple.VectorValueOf n a ~ Value n al,+ Tuple.VectorValueOf m a ~ Value m al) => LLVM.ConstValue (LLVM.Vector m Word32) -> T n a -> T n a -> CodeGenFunction r (T m a)-shufflePrimitive k (Cons (Compose u)) (Cons (Compose v)) =- fmap (Cons . Compose) $ LLVM.shufflevector u v k+shufflePrimitive k (Cons u) (Cons v) =+ fmap Cons $ LLVM.shufflevector u v k extractPrimitive :: (TypeNum.Positive n, IsPrimitive al,- Repr LLVM.Value a ~ LLVM.Value al,- Repr (Value n) a ~ Value n al) =>+ Tuple.ValueOf a ~ LLVM.Value al,+ Tuple.VectorValueOf n a ~ Value n al) => LLVM.Value Word32 -> T n a -> CodeGenFunction r (MultiValue.T a)-extractPrimitive k (Cons (Compose v)) =+extractPrimitive k (Cons v) = fmap MultiValue.Cons $ LLVM.extractelement v k insertPrimitive :: (TypeNum.Positive n, IsPrimitive al,--- this constraint is accepted, but does not help--- Repr f a ~ f a,- Repr LLVM.Value a ~ LLVM.Value al,- Repr (Value n) a ~ Value n al) =>+ Tuple.ValueOf a ~ LLVM.Value al,+ Tuple.VectorValueOf n a ~ Value n al) => LLVM.Value Word32 -> MultiValue.T a -> T n a -> CodeGenFunction r (T n a)-insertPrimitive k (MultiValue.Cons a) (Cons (Compose v)) =- fmap (Cons . Compose) $ LLVM.insertelement v a k+insertPrimitive k (MultiValue.Cons a) (Cons v) =+ fmap Cons $ LLVM.insertelement v a k instance (C a, C b) => C (a,b) where- cons v = zip (cons (fst <$> v)) (cons (snd <$> v))+ cons v = case FuncHT.unzip v of (a,b) -> zip (cons a) (cons b) undef = zip undef undef zero = zip zero zero - phis bb a =+ phi bb a = case unzip a of (a0,a1) ->- Monad.lift2 zip (phis bb a0) (phis bb a1)- addPhis bb a b =+ Monad.lift2 zip (phi bb a0) (phi bb a1)+ addPhi bb a b = case (unzip a, unzip b) of ((a0,a1), (b0,b1)) ->- addPhis bb a0 b0 >>- addPhis bb a1 b1+ addPhi bb a0 b0 >>+ addPhi bb a1 b1 shuffle is u v = case (unzip u, unzip v) of@@ -384,20 +395,20 @@ instance (C a, C b, C c) => C (a,b,c) where- cons v = zip3 (cons (fst3 <$> v)) (cons (snd3 <$> v)) (cons (thd3 <$> v))+ cons v = case FuncHT.unzip3 v of (a,b,c) -> zip3 (cons a) (cons b) (cons c) undef = zip3 undef undef undef zero = zip3 zero zero zero - phis bb a =+ phi bb a = case unzip3 a of (a0,a1,a2) ->- Monad.lift3 zip3 (phis bb a0) (phis bb a1) (phis bb a2)- addPhis bb a b =+ Monad.lift3 zip3 (phi bb a0) (phi bb a1) (phi bb a2)+ addPhi bb a b = case (unzip3 a, unzip3 b) of ((a0,a1,a2), (b0,b1,b2)) ->- addPhis bb a0 b0 >>- addPhis bb a1 b1 >>- addPhis bb a2 b2+ addPhi bb a0 b0 >>+ addPhi bb a1 b1 >>+ addPhi bb a2 b2 shuffle is u v = case (unzip3 u, unzip3 v) of@@ -434,10 +445,12 @@ instance IntegerConstant Float where fromInteger' = fromIntegerPrimitive instance IntegerConstant Double where fromInteger' = fromIntegerPrimitive+instance IntegerConstant Word where fromInteger' = fromIntegerPrimitive instance IntegerConstant Word8 where fromInteger' = fromIntegerPrimitive instance IntegerConstant Word16 where fromInteger' = fromIntegerPrimitive instance IntegerConstant Word32 where fromInteger' = fromIntegerPrimitive instance IntegerConstant Word64 where fromInteger' = fromIntegerPrimitive+instance IntegerConstant Int where fromInteger' = fromIntegerPrimitive instance IntegerConstant Int8 where fromInteger' = fromIntegerPrimitive instance IntegerConstant Int16 where fromInteger' = fromIntegerPrimitive instance IntegerConstant Int32 where fromInteger' = fromIntegerPrimitive@@ -445,18 +458,18 @@ fromIntegerPrimitive :: (TypeNum.Positive n, IsPrimitive a, SoV.IntegerConstant a,- Repr (Value n) a ~ Value n a) =>+ Tuple.VectorValueOf n a ~ Value n a) => Integer -> T n a-fromIntegerPrimitive = Cons . Compose . LLVM.value . SoV.constFromInteger+fromIntegerPrimitive = Cons . LLVM.value . SoV.constFromInteger instance RationalConstant Float where fromRational' = fromRationalPrimitive instance RationalConstant Double where fromRational' = fromRationalPrimitive fromRationalPrimitive :: (TypeNum.Positive n, IsPrimitive a, SoV.RationalConstant a,- Repr (Value n) a ~ Value n a) =>+ Tuple.VectorValueOf n a ~ Value n a) => Rational -> T n a-fromRationalPrimitive = Cons . Compose . LLVM.value . SoV.constFromRational+fromRationalPrimitive = Cons . LLVM.value . SoV.constFromRational instance (TypeNum.Positive n, IntegerConstant a) =>@@ -520,7 +533,7 @@ (TypeNum.Positive n, C a) => (MultiValue.T a -> CodeGenFunction r (MultiValue.T a)) -> MultiValue.T a -> CodeGenFunction r (T n a)-iterate f x = fmap snd $ iterateCore f x Class.undefTuple+iterate f x = fmap snd $ iterateCore f x Tuple.undef iterateCore :: (TypeNum.Positive n, C a) =>@@ -694,45 +707,45 @@ type PrimValue n a = LLVM.Value (LLVM.Vector n a) -lift1 :: (Repr (Value n) a -> Repr (Value n) b) -> T n a -> T n b+lift1 :: (Tuple.VectorValueOf n a -> Tuple.VectorValueOf n b) -> T n a -> T n b lift1 f (Cons a) = Cons $ f a _liftM0 :: (Monad m) =>- m (Repr (Value n) a) ->+ m (Tuple.VectorValueOf n a) -> m (T n a) _liftM0 f = Monad.lift Cons f liftM0 :: (Monad m,- Repr (Value n) a ~ Value n a) =>+ Tuple.VectorValueOf n a ~ Value n a) => m (PrimValue n a) -> m (T n a) liftM0 f = Monad.lift consPrim f liftM :: (Monad m,- Repr (Value n) a ~ Value n a,- Repr (Value n) b ~ Value n b) =>+ Tuple.VectorValueOf n a ~ Value n a,+ Tuple.VectorValueOf n b ~ Value n b) => (PrimValue n a -> m (PrimValue n b)) -> T n a -> m (T n b) liftM f a = Monad.lift consPrim $ f (deconsPrim a) liftM2 :: (Monad m,- Repr (Value n) a ~ Value n a,- Repr (Value n) b ~ Value n b,- Repr (Value n) c ~ Value n c) =>+ Tuple.VectorValueOf n a ~ Value n a,+ Tuple.VectorValueOf n b ~ Value n b,+ Tuple.VectorValueOf n c ~ Value n c) => (PrimValue n a -> PrimValue n b -> m (PrimValue n c)) -> T n a -> T n b -> m (T n c) liftM2 f a b = Monad.lift consPrim $ f (deconsPrim a) (deconsPrim b) liftM3 :: (Monad m,- Repr (Value n) a ~ Value n a,- Repr (Value n) b ~ Value n b,- Repr (Value n) c ~ Value n c,- Repr (Value n) d ~ Value n d) =>+ Tuple.VectorValueOf n a ~ Value n a,+ Tuple.VectorValueOf n b ~ Value n b,+ Tuple.VectorValueOf n c ~ Value n c,+ Tuple.VectorValueOf n d ~ Value n d) => (PrimValue n a -> PrimValue n b -> PrimValue n c -> m (PrimValue n d)) -> T n a -> T n b -> T n c -> m (T n d) liftM3 f a b c =@@ -757,6 +770,9 @@ instance Additive Double where add = liftM2 LLVM.add; sub = liftM2 LLVM.sub; neg = liftM LLVM.neg +instance Additive Int where+ add = liftM2 LLVM.add; sub = liftM2 LLVM.sub; neg = liftM LLVM.neg+ instance Additive Int8 where add = liftM2 LLVM.add; sub = liftM2 LLVM.sub; neg = liftM LLVM.neg @@ -769,6 +785,9 @@ instance Additive Int64 where add = liftM2 LLVM.add; sub = liftM2 LLVM.sub; neg = liftM LLVM.neg +instance Additive Word where+ add = liftM2 LLVM.add; sub = liftM2 LLVM.sub; neg = liftM LLVM.neg+ instance Additive Word8 where add = liftM2 LLVM.add; sub = liftM2 LLVM.sub; neg = liftM LLVM.neg @@ -933,10 +952,12 @@ instance Select Float where select = liftM3 LLVM.select instance Select Double where select = liftM3 LLVM.select instance Select Bool where select = liftM3 LLVM.select+instance Select Word where select = liftM3 LLVM.select instance Select Word8 where select = liftM3 LLVM.select instance Select Word16 where select = liftM3 LLVM.select instance Select Word32 where select = liftM3 LLVM.select instance Select Word64 where select = liftM3 LLVM.select+instance Select Int where select = liftM3 LLVM.select instance Select Int8 where select = liftM3 LLVM.select instance Select Int16 where select = liftM3 LLVM.select instance Select Int32 where select = liftM3 LLVM.select@@ -969,10 +990,12 @@ instance Comparison Float where cmp = liftM2 . LLVM.cmp instance Comparison Double where cmp = liftM2 . LLVM.cmp+instance Comparison Word where cmp = liftM2 . LLVM.cmp instance Comparison Word8 where cmp = liftM2 . LLVM.cmp instance Comparison Word16 where cmp = liftM2 . LLVM.cmp instance Comparison Word32 where cmp = liftM2 . LLVM.cmp instance Comparison Word64 where cmp = liftM2 . LLVM.cmp+instance Comparison Int where cmp = liftM2 . LLVM.cmp instance Comparison Int8 where cmp = liftM2 . LLVM.cmp instance Comparison Int16 where cmp = liftM2 . LLVM.cmp instance Comparison Int32 where cmp = liftM2 . LLVM.cmp@@ -1041,6 +1064,9 @@ shl :: (TypeNum.Positive n) => T n a -> T n a -> LLVM.CodeGenFunction r (T n a) shr :: (TypeNum.Positive n) => T n a -> T n a -> LLVM.CodeGenFunction r (T n a) +instance BitShift Word where+ shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr+ instance BitShift Word8 where shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr @@ -1052,6 +1078,9 @@ instance BitShift Word64 where shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr++instance BitShift Int where+ shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr instance BitShift Int8 where shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
src/LLVM/Extra/Multi/Vector/Instance.hs view
@@ -5,13 +5,11 @@ import qualified LLVM.Extra.Multi.Vector as Vector import qualified LLVM.Extra.Multi.Value.Private as MultiValue-import LLVM.Extra.Multi.Value.Private (Repr, ) import qualified LLVM.Core as LLVM import qualified Type.Data.Num.Decimal as TypeNum -import Data.Functor.Compose (Compose, ) import Data.Functor ((<$>), ) import Prelude2010@@ -50,12 +48,11 @@ instance (TypeNum.Positive n, Vector.C a) => MultiValue.C (LLVM.Vector n a) where- type Repr f (LLVM.Vector n a) = Repr (Compose f (LLVM.Vector n)) a cons = toMultiValue . Vector.cons undef = toMultiValue Vector.undef zero = toMultiValue Vector.zero- phis = liftMultiValueM . Vector.phis- addPhis bb x y = Vector.addPhis bb (fromMultiValue x) (fromMultiValue y)+ phi = liftMultiValueM . Vector.phi+ addPhi bb x y = Vector.addPhi bb (fromMultiValue x) (fromMultiValue y) instance (TypeNum.Positive n, Vector.IntegerConstant a) =>
− src/LLVM/Extra/Multi/Vector/Memory.hs
@@ -1,172 +0,0 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeOperators #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-module LLVM.Extra.Multi.Vector.Memory where--import qualified LLVM.Extra.Multi.Vector as MultiVector-import qualified LLVM.Extra.Multi.Vector.Instance as Inst-import qualified LLVM.Extra.Multi.Value.Memory as MultiMem-import LLVM.Extra.MemoryPrivate (decomposeFromLoad, composeFromStore, )--import qualified LLVM.Core as LLVM-import LLVM.Core (CodeGenFunction, Value, )--import qualified Type.Data.Num.Decimal as TypeNum-import Type.Data.Num.Decimal ((:*:), )--import Foreign.Ptr (Ptr, )--import Control.Applicative (liftA2, liftA3, )--import Data.Word (Word8, Word16, Word32, Word64)-import Data.Int (Int8, Int16, Int32, Int64)---class- (TypeNum.Positive n, MultiVector.C a, LLVM.IsSized (Struct n a)) =>- C n a where- {-# MINIMAL (load|decompose), (store|compose) #-}- type Struct n a :: *- load :: Value (Ptr (Struct n a)) -> CodeGenFunction r (MultiVector.T n a)- load ptr = decompose =<< LLVM.load ptr- store :: MultiVector.T n a -> Value (Ptr (Struct n a)) -> CodeGenFunction r ()- store r ptr = flip LLVM.store ptr =<< compose r- decompose :: Value (Struct n a) -> CodeGenFunction r (MultiVector.T n a)- decompose = decomposeFromLoad load- compose :: MultiVector.T n a -> CodeGenFunction r (Value (Struct n a))- compose = composeFromStore store--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D8)) =>- C n Word8 where- type Struct n Word8 = LLVM.Vector n Word8- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D16)) =>- C n Word16 where- type Struct n Word16 = LLVM.Vector n Word16- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D32)) =>- C n Word32 where- type Struct n Word32 = LLVM.Vector n Word32- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D64)) =>- C n Word64 where- type Struct n Word64 = LLVM.Vector n Word64- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D8)) =>- C n Int8 where- type Struct n Int8 = LLVM.Vector n Int8- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D16)) =>- C n Int16 where- type Struct n Int16 = LLVM.Vector n Int16- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D32)) =>- C n Int32 where- type Struct n Int32 = LLVM.Vector n Int32- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D64)) =>- C n Int64 where- type Struct n Int64 = LLVM.Vector n Int64- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D32)) =>- C n Float where- type Struct n Float = LLVM.Vector n Float- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance- (TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D64)) =>- C n Double where- type Struct n Double = LLVM.Vector n Double- load = fmap MultiVector.consPrim . LLVM.load- store = LLVM.store . MultiVector.deconsPrim- decompose = return . MultiVector.consPrim- compose = return . MultiVector.deconsPrim--instance (C n a, C n b) => C n (a,b) where- type Struct n (a,b) = (LLVM.Struct (Struct n a, (Struct n b, ())))- decompose ab =- liftA2 MultiVector.zip- (decompose =<< LLVM.extractvalue ab TypeNum.d0)- (decompose =<< LLVM.extractvalue ab TypeNum.d1)- compose ab =- case MultiVector.unzip ab of- (a,b) -> do- sa <- compose a- sb <- compose b- ra <- LLVM.insertvalue (LLVM.value LLVM.undef) sa TypeNum.d0- LLVM.insertvalue ra sb TypeNum.d1--instance (C n a, C n b, C n c) => C n (a,b,c) where- type Struct n (a,b,c) =- (LLVM.Struct (Struct n a, (Struct n b, (Struct n c, ()))))- decompose abc =- liftA3 MultiVector.zip3- (decompose =<< LLVM.extractvalue abc TypeNum.d0)- (decompose =<< LLVM.extractvalue abc TypeNum.d1)- (decompose =<< LLVM.extractvalue abc TypeNum.d2)- compose abc =- case MultiVector.unzip3 abc of- (a,b,c) -> do- sa <- compose a- sb <- compose b- sc <- compose c- ra <- LLVM.insertvalue (LLVM.value LLVM.undef) sa TypeNum.d0- rb <- LLVM.insertvalue ra sb TypeNum.d1- LLVM.insertvalue rb sc TypeNum.d2----- orphan-instance (C n a) => MultiMem.C (LLVM.Vector n a) where- type Struct (LLVM.Vector n a) = Struct n a- load = fmap Inst.toMultiValue . load- store = store . Inst.fromMultiValue- decompose = fmap Inst.toMultiValue . decompose- compose = compose . Inst.fromMultiValue
src/LLVM/Extra/Scalar.hs view
@@ -1,12 +1,9 @@ {-# LANGUAGE TypeFamilies #-} module LLVM.Extra.Scalar where -import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.Arithmetic as A -import qualified LLVM.Util.Loop as Loop-import LLVM.Util.Loop (Phi, )- import qualified Control.Monad as Monad @@ -66,15 +63,15 @@ Monad.liftM decons $ f (Cons a) (Cons b) (Cons c) (Cons d) (Cons e) -instance (Class.Zero a) => Class.Zero (T a) where- zeroTuple = Cons Class.zeroTuple+instance (Tuple.Zero a) => Tuple.Zero (T a) where+ zero = Cons Tuple.zero -instance (Class.Undefined a) => Class.Undefined (T a) where- undefTuple = Cons Class.undefTuple+instance (Tuple.Undefined a) => Tuple.Undefined (T a) where+ undef = Cons Tuple.undef -instance (Phi a) => Phi (T a) where- phis bb = fmap Cons . Loop.phis bb . decons- addPhis bb (Cons a) (Cons b) = Loop.addPhis bb a b+instance (Tuple.Phi a) => Tuple.Phi (T a) where+ phi bb = fmap Cons . Tuple.phi bb . decons+ addPhi bb (Cons a) (Cons b) = Tuple.addPhi bb a b instance (A.IntegerConstant a) => A.IntegerConstant (T a) where fromInteger' = Cons . A.fromInteger'
src/LLVM/Extra/ScalarOrVector.hs view
@@ -49,7 +49,7 @@ import qualified Type.Data.Num.Decimal as TypeNum -import Data.Word (Word8, Word16, Word32, Word64, )+import Data.Word (Word8, Word16, Word32, Word64, Word) import Data.Int (Int8, Int16, Int32, Int64, ) import Data.Maybe (fromMaybe) @@ -228,10 +228,12 @@ A.signumGen minusOne one x +instance Real Int where min = A.min; max = A.max; signum = A.signum; abs = A.abs; instance Real Int8 where min = A.min; max = A.max; signum = A.signum; abs = A.abs; instance Real Int16 where min = A.min; max = A.max; signum = A.signum; abs = A.abs; instance Real Int32 where min = A.min; max = A.max; signum = A.signum; abs = A.abs; instance Real Int64 where min = A.min; max = A.max; signum = A.signum; abs = A.abs;+instance Real Word where min = A.min; max = A.max; signum = A.signum; abs = return; instance Real Word8 where min = A.min; max = A.max; signum = A.signum; abs = return; instance Real Word16 where min = A.min; max = A.max; signum = A.signum; abs = return; instance Real Word32 where min = A.min; max = A.max; signum = A.signum; abs = return;@@ -254,6 +256,8 @@ class (IsInteger a) => Saturated a where addSat, subSat :: Value a -> Value a -> CodeGenFunction r (Value a) +instance Saturated Int where+ addSat = addSatProxy LP.Proxy; subSat = subSatProxy LP.Proxy; instance Saturated Int8 where addSat = addSatProxy LP.Proxy; subSat = subSatProxy LP.Proxy; instance Saturated Int16 where@@ -262,6 +266,8 @@ addSat = addSatProxy LP.Proxy; subSat = subSatProxy LP.Proxy; instance Saturated Int64 where addSat = addSatProxy LP.Proxy; subSat = subSatProxy LP.Proxy;+instance Saturated Word where+ addSat = addSatProxy LP.Proxy; subSat = subSatProxy LP.Proxy; instance Saturated Word8 where addSat = addSatProxy LP.Proxy; subSat = subSatProxy LP.Proxy; instance Saturated Word16 where@@ -302,10 +308,12 @@ scale :: (a ~ Scalar v) => Value a -> Value v -> CodeGenFunction r (Value v) scaleConst :: (a ~ Scalar v) => ConstValue a -> ConstValue v -> CodeGenFunction r (ConstValue v) +instance PseudoModule Word where scale = LLVM.mul; scaleConst = LLVM.mul instance PseudoModule Word8 where scale = LLVM.mul; scaleConst = LLVM.mul instance PseudoModule Word16 where scale = LLVM.mul; scaleConst = LLVM.mul instance PseudoModule Word32 where scale = LLVM.mul; scaleConst = LLVM.mul instance PseudoModule Word64 where scale = LLVM.mul; scaleConst = LLVM.mul+instance PseudoModule Int where scale = LLVM.mul; scaleConst = LLVM.mul instance PseudoModule Int8 where scale = LLVM.mul; scaleConst = LLVM.mul instance PseudoModule Int16 where scale = LLVM.mul; scaleConst = LLVM.mul instance PseudoModule Int32 where scale = LLVM.mul; scaleConst = LLVM.mul@@ -322,10 +330,12 @@ class (LLVM.IsConst a) => IntegerConstant a where constFromInteger :: Integer -> ConstValue a +instance IntegerConstant Word where constFromInteger = constOf . fromInteger instance IntegerConstant Word8 where constFromInteger = constOf . fromInteger instance IntegerConstant Word16 where constFromInteger = constOf . fromInteger instance IntegerConstant Word32 where constFromInteger = constOf . fromInteger instance IntegerConstant Word64 where constFromInteger = constOf . fromInteger+instance IntegerConstant Int where constFromInteger = constOf . fromInteger instance IntegerConstant Int8 where constFromInteger = constOf . fromInteger instance IntegerConstant Int16 where constFromInteger = constOf . fromInteger instance IntegerConstant Int32 where constFromInteger = constOf . fromInteger
+ src/LLVM/Extra/Storable.hs view
@@ -0,0 +1,47 @@+{- |+Transfer values between Haskell and JIT generated code+in a Haskell-compatible format as dictated by the 'Foreign.Storable' class.+E.g. instance 'Bool' may use more than a byte (e.g. Word32).+For tuples, you may use the @Tuple@ wrapper from the @storable-record@ package.+The 'Storable' instance for 'Vector's is compatible with arrays,+i.e. indices always count upwards irrespective of machine endianess+and tuple elements are interleaved.+-}+module LLVM.Extra.Storable (+ -- * Basic class+ Store.C(..),+ Store.storeNext,+ Store.modify,++ -- * Classes for tuples and vectors+ Store.Tuple(..),+ Store.Vector(..),+ Store.TupleVector(..),++ -- * MultiValue support+ Store.loadMultiValue,+ Store.storeMultiValue,+ Store.storeNextMultiValue,+ Store.modifyMultiValue,++ -- * Standard method implementations+ Store.loadNewtype,+ Store.storeNewtype,+ Store.loadTraversable,+ Store.loadApplicative,+ Store.storeFoldable,++ -- * Pointer handling+ Store.advancePtr,+ Store.incrementPtr,+ Store.decrementPtr,++ -- * Loops over Storable arrays+ Array.arrayLoop,+ Array.arrayLoop2,+ Array.arrayLoopMaybeCont,+ Array.arrayLoopMaybeCont2,+ ) where++import qualified LLVM.Extra.Storable.Private as Store+import qualified LLVM.Extra.Storable.Array as Array
+ src/LLVM/Extra/Storable/Array.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE TypeFamilies #-}+{- |+Loops over Storable arrays.+-}+module LLVM.Extra.Storable.Array where++import qualified LLVM.Extra.Storable.Private as Storable+import qualified LLVM.Extra.MaybeContinuation as MaybeCont+import qualified LLVM.Extra.Maybe as Maybe+import qualified LLVM.Extra.Tuple as Tuple+import qualified LLVM.Extra.Control as C+import LLVM.Core+ (CodeGenFunction, Value, CmpRet, IsInteger, IsConst, IsPrimitive)++import Foreign.Ptr (Ptr)++import Control.Monad (liftM2)++import Data.Tuple.HT (mapSnd)+++arrayLoop ::+ (Tuple.Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,+ Storable.C a, Value (Ptr a) ~ ptrA) =>+ Value i -> ptrA -> s ->+ (ptrA -> s -> CodeGenFunction r s) ->+ CodeGenFunction r s+arrayLoop len ptr start body =+ fmap snd $+ C.fixedLengthLoop len (ptr, start) $ \(p,s) ->+ liftM2 (,) (Storable.incrementPtr p) (body p s)++arrayLoop2 ::+ (Tuple.Phi s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,+ Storable.C a, Value (Ptr a) ~ ptrA,+ Storable.C b, Value (Ptr b) ~ ptrB) =>+ Value i -> ptrA -> ptrB -> s ->+ (ptrA -> ptrB -> s -> CodeGenFunction r s) ->+ CodeGenFunction r s+arrayLoop2 len ptrA ptrB start body =+ fmap snd $+ arrayLoop len ptrA (ptrB,start) $ \pa (pb,s) ->+ liftM2 (,) (Storable.incrementPtr pb) (body pa pb s)+++arrayLoopMaybeCont ::+ (Tuple.Phi s, Tuple.Undefined s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,+ Storable.C a, Value (Ptr a) ~ ptrA,+ Maybe.T (ptrA, s) ~ z) =>+ Value i ->+ ptrA -> s ->+ (ptrA -> s -> MaybeCont.T r z s) ->+ CodeGenFunction r (Value i, Maybe.T s)+arrayLoopMaybeCont len ptr start body =+ fmap (mapSnd (fmap snd)) $+ MaybeCont.fixedLengthLoop len (ptr,start) $ \(ptr0,s0) ->+ liftM2 (,)+ (MaybeCont.lift $ Storable.incrementPtr ptr0)+ (body ptr0 s0)++arrayLoopMaybeCont2 ::+ (Tuple.Phi s, Tuple.Undefined s, Num i, IsConst i, IsInteger i, CmpRet i, IsPrimitive i,+ Storable.C a, Value (Ptr a) ~ ptrA,+ Storable.C b, Value (Ptr b) ~ ptrB,+ Maybe.T (ptrA, (ptrB, s)) ~ z) =>+ Value i ->+ ptrA -> ptrB -> s ->+ (ptrA -> ptrB -> s -> MaybeCont.T r z s) ->+ CodeGenFunction r (Value i, Maybe.T s)+arrayLoopMaybeCont2 len ptrA ptrB start body =+ fmap (mapSnd (fmap snd)) $+ arrayLoopMaybeCont len ptrA (ptrB,start) $ \ptrAi (ptrB0,s0) ->+ liftM2 (,)+ (MaybeCont.lift $ Storable.incrementPtr ptrB0)+ (body ptrAi ptrB0 s0)
+ src/LLVM/Extra/Storable/Private.hs view
@@ -0,0 +1,499 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE UndecidableInstances #-}+module LLVM.Extra.Storable.Private where++import qualified LLVM.Extra.Multi.Value as MultiValue+import qualified LLVM.Extra.Tuple as Tuple+import qualified LLVM.Extra.ArithmeticPrivate as A+import qualified LLVM.Util.Proxy as LP+import qualified LLVM.Core as LLVM+import LLVM.Core (CodeGenFunction, Value)++import qualified Type.Data.Num.Decimal as TypeNum++import qualified Control.Monad.Trans.Class as MT+import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS+import qualified Control.Applicative.HT as App+import qualified Control.Functor.HT as FuncHT+import Control.Monad (foldM, replicateM, replicateM_, (<=<))+import Control.Applicative (Applicative, pure)++import qualified Foreign.Storable.Record.Tuple as StoreTuple+import qualified Foreign.Storable as Store+import Foreign.Storable.FixedArray (roundUp)+import Foreign.Ptr (Ptr)++import qualified Data.NonEmpty.Class as NonEmptyC+import qualified Data.Traversable as Trav+import qualified Data.Foldable as Fold+import Data.Orphans ()+import Data.Complex (Complex)+import Data.Word (Word8, Word16, Word32, Word64, Word)+import Data.Int (Int8, Int16, Int32, Int64)+import Data.Bool8 (Bool8)++++class+ (Store.Storable a, Tuple.Value a,+ Tuple.Phi (Tuple.ValueOf a), Tuple.Undefined (Tuple.ValueOf a)) =>+ C a where++ {-+ Not all Storable types have a compatible LLVM type,+ or even more, one LLVM type that is compatible on all platforms.+ -}+ load :: Value (Ptr a) -> CodeGenFunction r (Tuple.ValueOf a)+ store :: Tuple.ValueOf a -> Value (Ptr a) -> CodeGenFunction r ()++storeNext ::+ (C a, Tuple.ValueOf a ~ al, Value (Ptr a) ~ ptr) =>+ al -> ptr -> CodeGenFunction r ptr+storeNext a ptr = store a ptr >> incrementPtr ptr++modify ::+ (C a, Tuple.ValueOf a ~ al) =>+ (al -> CodeGenFunction r al) ->+ Value (Ptr a) -> CodeGenFunction r ()+modify f ptr = flip store ptr =<< f =<< load ptr+++loadMultiValue ::+ (C a) => Value (Ptr a) -> CodeGenFunction r (MultiValue.T a)+loadMultiValue ptr = fmap MultiValue.Cons $ load ptr++storeMultiValue ::+ (C a) => MultiValue.T a -> Value (Ptr a) -> CodeGenFunction r ()+storeMultiValue (MultiValue.Cons a) ptr = store a ptr++storeNextMultiValue ::+ (C a) => MultiValue.T a -> Value (Ptr a) -> CodeGenFunction r (Value (Ptr a))+storeNextMultiValue (MultiValue.Cons a) ptr =+ store a ptr >> incrementPtr ptr++modifyMultiValue ::+ (C a) =>+ (MultiValue.T a -> CodeGenFunction r (MultiValue.T a)) ->+ Value (Ptr a) -> CodeGenFunction r ()+modifyMultiValue f ptr =+ flip storeMultiValue ptr =<< f =<< loadMultiValue ptr+++loadPrimitive ::+ (LLVM.Storable a) => Value (Ptr a) -> CodeGenFunction r (Value a)+loadPrimitive ptr = LLVM.load =<< LLVM.bitcast ptr++storePrimitive ::+ (LLVM.Storable a) => Value a -> Value (Ptr a) -> CodeGenFunction r ()+storePrimitive a ptr = LLVM.store a =<< LLVM.bitcast ptr++instance C Float where+ load = loadPrimitive; store = storePrimitive++instance C Double where+ load = loadPrimitive; store = storePrimitive++instance C Word where+ load = loadPrimitive; store = storePrimitive++instance C Word8 where+ load = loadPrimitive; store = storePrimitive++instance C Word16 where+ load = loadPrimitive; store = storePrimitive++instance C Word32 where+ load = loadPrimitive; store = storePrimitive++instance C Word64 where+ load = loadPrimitive; store = storePrimitive++instance C Int where+ load = loadPrimitive; store = storePrimitive++instance C Int8 where+ load = loadPrimitive; store = storePrimitive++instance C Int16 where+ load = loadPrimitive; store = storePrimitive++instance C Int32 where+ load = loadPrimitive; store = storePrimitive++instance C Int64 where+ load = loadPrimitive; store = storePrimitive++{- |+Not very efficient implementation+because we want to adapt to @sizeOf Bool@ dynamically.+Unfortunately, LLVM-9's optimizer does not recognize the instruction pattern.+Better use 'Bool8' for booleans.+-}+instance C Bool where+ load ptr = do+ bytePtr <- castToBytePtr ptr+ bytes <-+ flip MS.evalStateT bytePtr $+ replicateM (Store.sizeOf (False :: Bool))+ (MT.lift . LLVM.load =<< incPtrState)+ let zero = LLVM.valueOf 0+ mask <- foldM A.or zero bytes+ A.cmp LLVM.CmpNE mask zero+ store b ptr = do+ bytePtr <- castToBytePtr ptr+ byte <- LLVM.sext b+ flip MS.evalStateT bytePtr $+ replicateM_ (Store.sizeOf (False :: Bool))+ (MT.lift . LLVM.store byte =<< incPtrState)++incPtrState :: MS.StateT BytePtr (CodeGenFunction r) BytePtr+incPtrState = update A.advanceArrayElementPtr++instance C Bool8 where+ load ptr =+ A.cmp LLVM.CmpNE (LLVM.valueOf 0) =<< LLVM.load =<< castToBytePtr ptr+ store b ptr = do+ byte <- LLVM.zext b+ LLVM.store byte =<< castToBytePtr ptr++instance (C a) => C (Complex a) where+ load = loadApplicative; store = storeFoldable++++instance (Tuple tuple) => C (StoreTuple.Tuple tuple) where+ load = loadTuple+ store = storeTuple++class+ (StoreTuple.Storable tuple, Tuple.Value tuple,+ Tuple.Phi (Tuple.ValueOf tuple), Tuple.Undefined (Tuple.ValueOf tuple)) =>+ Tuple tuple where+ loadTuple ::+ Value (Ptr (StoreTuple.Tuple tuple)) ->+ CodeGenFunction r (Tuple.ValueOf tuple)+ storeTuple ::+ Tuple.ValueOf tuple ->+ Value (Ptr (StoreTuple.Tuple tuple)) ->+ CodeGenFunction r ()++instance (C a, C b) => Tuple (a,b) where+ loadTuple ptr =+ runElements ptr $+ App.mapPair (loadElement, loadElement) $+ FuncHT.unzip $ proxyFromElement3 ptr+ storeTuple (a,b) ptr =+ case FuncHT.unzip $ proxyFromElement3 ptr of+ (pa,pb) -> runElements ptr $ storeElement pa a >> storeElement pb b++instance (C a, C b, C c) => Tuple (a,b,c) where+ loadTuple ptr =+ runElements ptr $+ App.mapTriple (loadElement, loadElement, loadElement) $+ FuncHT.unzip3 $ proxyFromElement3 ptr+ storeTuple (a,b,c) ptr =+ case FuncHT.unzip3 $ proxyFromElement3 ptr of+ (pa,pb,pc) ->+ runElements ptr $+ storeElement pa a >> storeElement pb b >> storeElement pc c++runElements ::+ Value (Ptr a) ->+ MR.ReaderT BytePtr (MS.StateT Int (CodeGenFunction r)) c ->+ CodeGenFunction r c+runElements ptr act = do+ bytePtr <- castToBytePtr ptr+ flip MS.evalStateT 0 $ flip MR.runReaderT bytePtr act++loadElement ::+ (C a) =>+ LP.Proxy a ->+ MR.ReaderT BytePtr (MS.StateT Int (CodeGenFunction r)) (Tuple.ValueOf a)+loadElement proxy =+ MT.lift . MT.lift . load =<< elementPtr proxy++storeElement ::+ (C a) =>+ LP.Proxy a -> Tuple.ValueOf a ->+ MR.ReaderT BytePtr (MS.StateT Int (CodeGenFunction r)) ()+storeElement proxy a =+ MT.lift . MT.lift . store a =<< elementPtr proxy++elementPtr ::+ (C a) =>+ LP.Proxy a ->+ MR.ReaderT BytePtr+ (MS.StateT Int (CodeGenFunction r)) (LLVM.Value (Ptr a))+elementPtr proxy = do+ ptr <- MR.ask+ MT.lift $ do+ offset <- elementOffset proxy+ MT.lift $ castFromBytePtr =<< LLVM.getElementPtr ptr (offset, ())++elementOffset ::+ (Monad m, Store.Storable a) => LP.Proxy a -> MS.StateT Int m Int+elementOffset proxy = do+ let dummy = elementFromProxy proxy+ MS.modify (roundUp $ Store.alignment dummy)+ offset <- MS.get+ MS.modify (+ Store.sizeOf dummy)+ return offset+++instance+ (TypeNum.Positive n, Vector a, Tuple.VectorValue n a,+ Tuple.Phi (Tuple.VectorValueOf n a)) =>+ C (LLVM.Vector n a) where+ load ptr =+ assembleVector (proxyFromElement3 ptr) =<< loadApplicative ptr+ store a ptr =+ flip storeFoldable ptr+ =<< disassembleVector (proxyFromElement3 ptr) a++class (C a) => Vector a where+ assembleVector ::+ (TypeNum.Positive n) =>+ LP.Proxy a -> LLVM.Vector n (Tuple.ValueOf a) ->+ CodeGenFunction r (Tuple.VectorValueOf n a)+ disassembleVector ::+ (TypeNum.Positive n) =>+ LP.Proxy a -> Tuple.VectorValueOf n a ->+ CodeGenFunction r (LLVM.Vector n (Tuple.ValueOf a))++assemblePrimitive ::+ (TypeNum.Positive n, LLVM.IsPrimitive a) =>+ LLVM.Vector n (Value a) -> CodeGenFunction r (Value (LLVM.Vector n a))+assemblePrimitive =+ foldM+ (\v (i,x) -> LLVM.insertelement v x (LLVM.valueOf i))+ (LLVM.value LLVM.undef)+ . zip [0..] . Fold.toList++disassemblePrimitive ::+ (TypeNum.Positive n, LLVM.IsPrimitive a) =>+ Value (LLVM.Vector n a) -> CodeGenFunction r (LLVM.Vector n (Value a))+disassemblePrimitive v =+ Trav.mapM (LLVM.extractelement v . LLVM.valueOf) indices++indices :: (Applicative f, Trav.Traversable f) => f Word32+indices =+ flip MS.evalState 0 $ Trav.sequenceA $ pure $ MS.state (\k -> (k,k+1))++instance Vector Float where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Double where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Word where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Word8 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Word16 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Word32 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Word64 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Int where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Int8 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Int16 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Int32 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Int64 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Bool where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive++instance Vector Bool8 where+ assembleVector LP.Proxy = assemblePrimitive+ disassembleVector LP.Proxy = disassemblePrimitive+++instance+ (Tuple tuple, TupleVector tuple) =>+ Vector (StoreTuple.Tuple tuple) where+ assembleVector = deinterleave . fmap StoreTuple.getTuple+ disassembleVector = interleave . fmap StoreTuple.getTuple+++class TupleVector a where+ deinterleave ::+ (TypeNum.Positive n) =>+ LP.Proxy a -> LLVM.Vector n (Tuple.ValueOf a) ->+ CodeGenFunction r (Tuple.VectorValueOf n a)+ interleave ::+ (TypeNum.Positive n) =>+ LP.Proxy a -> Tuple.VectorValueOf n a ->+ CodeGenFunction r (LLVM.Vector n (Tuple.ValueOf a))++instance (Vector a, Vector b) => TupleVector (a,b) where+ deinterleave = FuncHT.uncurry $ \pa pb -> FuncHT.uncurry $ \a b ->+ App.lift2 (,) (assembleVector pa a) (assembleVector pb b)+ interleave = FuncHT.uncurry $ \pa pb (a,b) ->+ App.lift2 (App.lift2 (,))+ (disassembleVector pa a) (disassembleVector pb b)++instance (Vector a, Vector b, Vector c) => TupleVector (a,b,c) where+ deinterleave = FuncHT.uncurry3 $ \pa pb pc -> FuncHT.uncurry3 $ \a b c ->+ App.lift3 (,,)+ (assembleVector pa a)+ (assembleVector pb b)+ (assembleVector pc c)+ interleave = FuncHT.uncurry3 $ \pa pb pc (a,b,c) ->+ App.lift3 (App.lift3 (,,))+ (disassembleVector pa a)+ (disassembleVector pb b)+ (disassembleVector pc c)+++{-+instance Storable () available since base-4.9/GHC-8.0.+Before we need Data.Orphans.+-}+instance C () where+ load _ptr = return ()+ store () _ptr = return ()+++loadNewtype ::+ (C a, Tuple.ValueOf a ~ al) =>+ (a -> wrapped) ->+ (al -> wrappedl) ->+ Value (Ptr wrapped) -> CodeGenFunction r wrappedl+loadNewtype wrap wrapl =+ fmap wrapl . load <=< rmapPtr wrap++storeNewtype ::+ (C a, Tuple.ValueOf a ~ al) =>+ (a -> wrapped) ->+ (wrappedl -> al) ->+ wrappedl -> Value (Ptr wrapped) -> CodeGenFunction r ()+storeNewtype wrap unwrapl y =+ store (unwrapl y) <=< rmapPtr wrap++rmapPtr :: (a -> b) -> Value (Ptr b) -> CodeGenFunction r (Value (Ptr a))+rmapPtr _f = LLVM.bitcast+++loadTraversable ::+ (NonEmptyC.Repeat f, Trav.Traversable f, C a, Tuple.ValueOf a ~ al) =>+ Value (Ptr (f a)) -> CodeGenFunction r (f al)+loadTraversable =+ (MS.evalStateT $ Trav.sequence $ NonEmptyC.repeat $ loadState)+ <=< castElementPtr++loadApplicative ::+ (Applicative f, Trav.Traversable f, C a, Tuple.ValueOf a ~ al) =>+ Value (Ptr (f a)) -> CodeGenFunction r (f al)+loadApplicative =+ (MS.evalStateT $ Trav.sequence $ pure loadState) <=< castElementPtr++loadState ::+ (C a, Tuple.ValueOf a ~ al) =>+ MS.StateT (Value (Ptr a)) (CodeGenFunction r) al+loadState = MT.lift . load =<< advancePtrState+++storeFoldable ::+ (Fold.Foldable f, C a, Tuple.ValueOf a ~ al) =>+ f al -> Value (Ptr (f a)) -> CodeGenFunction r ()+storeFoldable xs = MS.evalStateT (Fold.mapM_ storeState xs) <=< castElementPtr++storeState ::+ (C a, Tuple.ValueOf a ~ al) =>+ al -> MS.StateT (Value (Ptr a)) (CodeGenFunction r) ()+storeState a = MT.lift . store a =<< advancePtrState+++update :: (Monad m) => (a -> m a) -> MS.StateT a m a+update f = MS.StateT $ \a0 -> do a1 <- f a0; return (a0,a1)++advancePtrState ::+ (C a, Tuple.ValueOf a ~ al, Value (Ptr a) ~ ptr) =>+ MS.StateT ptr (CodeGenFunction r) ptr+advancePtrState = update $ advancePtrStatic 1++advancePtr ::+ (Store.Storable a, Value (Ptr a) ~ ptr) =>+ Value Int -> ptr -> CodeGenFunction r ptr+advancePtr n ptr = do+ size <- A.mul n $ LLVM.valueOf $ Store.sizeOf (elementFromPtr ptr)+ addPointer size ptr++advancePtrStatic ::+ (Store.Storable a, Value (Ptr a) ~ ptr) =>+ Int -> ptr -> CodeGenFunction r ptr+advancePtrStatic n ptr =+ addPointer (LLVM.valueOf (Store.sizeOf (elementFromPtr ptr) * n)) ptr++incrementPtr ::+ (Store.Storable a, Value (Ptr a) ~ ptr) =>+ ptr -> CodeGenFunction r ptr+incrementPtr = advancePtrStatic 1++decrementPtr ::+ (Store.Storable a, Value (Ptr a) ~ ptr) =>+ ptr -> CodeGenFunction r ptr+decrementPtr = advancePtrStatic (-1)++addPointer :: Value Int -> Value (Ptr a) -> CodeGenFunction r (Value (Ptr a))+addPointer k ptr = do+ bytePtr <- castToBytePtr ptr+ castFromBytePtr =<< LLVM.getElementPtr bytePtr (k, ())++type BytePtr = Value (LLVM.Ptr Word8)++castToBytePtr :: Value (Ptr a) -> CodeGenFunction r BytePtr+castToBytePtr = LLVM.bitcast++castFromBytePtr :: BytePtr -> CodeGenFunction r (Value (Ptr a))+castFromBytePtr = LLVM.bitcast++castElementPtr :: Value (Ptr (f a)) -> CodeGenFunction r (Value (Ptr a))+castElementPtr = LLVM.bitcast+++sizeOf :: (Store.Storable a) => LP.Proxy a -> Int+sizeOf = Store.sizeOf . elementFromProxy++elementFromPtr :: LLVM.Value (Ptr a) -> a+elementFromPtr _ = error "elementFromProxy"++elementFromProxy :: LP.Proxy a -> a+elementFromProxy LP.Proxy = error "elementFromProxy"++proxyFromElement2 :: f (g a) -> LP.Proxy a+proxyFromElement2 _ = LP.Proxy++proxyFromElement3 :: f (g (h a)) -> LP.Proxy a+proxyFromElement3 _ = LP.Proxy
+ src/LLVM/Extra/Tuple.hs view
@@ -0,0 +1,246 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+module LLVM.Extra.Tuple (+ Phi(..), phiTraversable, addPhiFoldable,+ Undefined(..), undefPointed,+ Zero(..), zeroPointed,+ Value(..), valueOfFunctor,+ VectorValue(..),+ ) where++import LLVM.Extra.TuplePrivate (+ Phi(..), phiTraversable, addPhiFoldable,+ Undefined(..), undefPointed,+ Zero(..), zeroPointed,+ )+import qualified LLVM.Extra.EitherPrivate as Either+import qualified LLVM.Extra.MaybePrivate as Maybe+import qualified LLVM.Core as LLVM+import LLVM.Core (IsType, Vector)++import qualified Type.Data.Num.Decimal as TypeNum+import Type.Data.Num.Decimal ((:*:))++import qualified Control.Monad.Trans.State as MS+import qualified Control.Applicative as App+import qualified Control.Functor.HT as FuncHT++import qualified Data.Foldable as Fold+import qualified Data.Traversable as Trav++import qualified Foreign.Storable.Record.Tuple as StoreTuple+import Foreign.StablePtr (StablePtr, )+import Foreign.Ptr (FunPtr, Ptr, )++import qualified Data.EnumBitSet as EnumBitSet+import qualified Data.Enum.Storable as Enum+import qualified Data.Bool8 as Bool8+import Data.Complex (Complex((:+)))+import Data.Tagged (Tagged(unTagged))+import Data.Word (Word8, Word16, Word32, Word64, Word)+import Data.Int (Int8, Int16, Int32, Int64, )+import Data.Bool8 (Bool8)++import Prelude2010+import Prelude ()+++-- * class for creating tuples of constant values++class (Undefined (ValueOf a)) => Value a where+ type ValueOf a+ valueOf :: a -> ValueOf a++instance (Value a, Value b) => Value (a,b) where+ type ValueOf (a,b) = (ValueOf a, ValueOf b)+ valueOf ~(a,b) = (valueOf a, valueOf b)++instance (Value a, Value b, Value c) => Value (a,b,c) where+ type ValueOf (a,b,c) = (ValueOf a, ValueOf b, ValueOf c)+ valueOf ~(a,b,c) = (valueOf a, valueOf b, valueOf c)++instance (Value a, Value b, Value c, Value d) => Value (a,b,c,d) where+ type ValueOf (a,b,c,d) = (ValueOf a, ValueOf b, ValueOf c, ValueOf d)+ valueOf ~(a,b,c,d) = (valueOf a, valueOf b, valueOf c, valueOf d)++instance (Value tuple) => Value (StoreTuple.Tuple tuple) where+ type ValueOf (StoreTuple.Tuple tuple) = ValueOf tuple+ valueOf (StoreTuple.Tuple a) = valueOf a++instance (Value a) => Value (Maybe a) where+ type ValueOf (Maybe a) = Maybe.T (ValueOf a)+ valueOf = maybe (Maybe.nothing undef) (Maybe.just . valueOf)++instance (Value a, Value b) => Value (Either a b) where+ type ValueOf (Either a b) = Either.T (ValueOf a) (ValueOf b)+ valueOf =+ either+ (Either.left undef . valueOf)+ (Either.right undef . valueOf)++instance Value Float where type ValueOf Float = LLVM.Value Float ; valueOf = LLVM.valueOf+instance Value Double where type ValueOf Double = LLVM.Value Double ; valueOf = LLVM.valueOf+-- instance Value FP128 where type ValueOf FP128 = LLVM.Value FP128 ; valueOf = LLVM.valueOf+instance Value Bool where type ValueOf Bool = LLVM.Value Bool ; valueOf = LLVM.valueOf+instance Value Bool8 where type ValueOf Bool8 = LLVM.Value Bool ; valueOf = LLVM.valueOf . Bool8.toBool+instance Value Int where type ValueOf Int = LLVM.Value Int ; valueOf = LLVM.valueOf+instance Value Int8 where type ValueOf Int8 = LLVM.Value Int8 ; valueOf = LLVM.valueOf+instance Value Int16 where type ValueOf Int16 = LLVM.Value Int16 ; valueOf = LLVM.valueOf+instance Value Int32 where type ValueOf Int32 = LLVM.Value Int32 ; valueOf = LLVM.valueOf+instance Value Int64 where type ValueOf Int64 = LLVM.Value Int64 ; valueOf = LLVM.valueOf+instance Value Word where type ValueOf Word = LLVM.Value Word ; valueOf = LLVM.valueOf+instance Value Word8 where type ValueOf Word8 = LLVM.Value Word8 ; valueOf = LLVM.valueOf+instance Value Word16 where type ValueOf Word16 = LLVM.Value Word16 ; valueOf = LLVM.valueOf+instance Value Word32 where type ValueOf Word32 = LLVM.Value Word32 ; valueOf = LLVM.valueOf+instance Value Word64 where type ValueOf Word64 = LLVM.Value Word64 ; valueOf = LLVM.valueOf+instance Value () where type ValueOf () = () ; valueOf = id+++instance (TypeNum.Positive n) => Value (LLVM.IntN n) where+ type ValueOf (LLVM.IntN n) = LLVM.Value (LLVM.IntN n)+ valueOf = LLVM.valueOf++instance (TypeNum.Positive n) => Value (LLVM.WordN n) where+ type ValueOf (LLVM.WordN n) = LLVM.Value (LLVM.WordN n)+ valueOf = LLVM.valueOf+++instance Value (Ptr a) where+ type ValueOf (Ptr a) = LLVM.Value (Ptr a)+ valueOf = LLVM.valueOf++instance IsType a => Value (LLVM.Ptr a) where+ type ValueOf (LLVM.Ptr a) = LLVM.Value (LLVM.Ptr a)+ valueOf = LLVM.valueOf++instance LLVM.IsFunction a => Value (FunPtr a) where+ type ValueOf (FunPtr a) = LLVM.Value (FunPtr a)+ valueOf = LLVM.valueOf++instance Value (StablePtr a) where+ type ValueOf (StablePtr a) = LLVM.Value (StablePtr a)+ valueOf = LLVM.valueOf++instance+ (TypeNum.Positive n, VectorValue n a, Undefined (VectorValueOf n a)) =>+ Value (Vector n a) where+ type ValueOf (Vector n a) = VectorValueOf n a+ valueOf = vectorValueOf+++instance Value a => Value (Tagged tag a) where+ type ValueOf (Tagged tag a) = ValueOf a+ valueOf = valueOf . unTagged++instance+ (LLVM.IsInteger w, LLVM.IsConst w, Num w, Enum e) =>+ Value (Enum.T w e) where+ type ValueOf (Enum.T w e) = LLVM.Value w+ valueOf = LLVM.valueOf . fromIntegral . fromEnum . Enum.toPlain++instance (LLVM.IsInteger w, LLVM.IsConst w) => Value (EnumBitSet.T w i) where+ type ValueOf (EnumBitSet.T w i) = LLVM.Value w+ valueOf = LLVM.valueOf . EnumBitSet.decons++instance (Value a) => Value (Complex a) where+ type ValueOf (Complex a) = Complex (ValueOf a)+ valueOf (a:+b) = valueOf a :+ valueOf b+++-- * class for vectors of tuples and other complex types++class+ (TypeNum.Positive n, Undefined (VectorValueOf n a)) =>+ VectorValue n a where+ type VectorValueOf n a+ vectorValueOf :: Vector n a -> VectorValueOf n a++-- may be simplified using a fake proof of TypeNum.Positive (n :*: m)+instance+ (TypeNum.Positive n, TypeNum.Positive m, TypeNum.Positive (n :*: m),+ Undefined (Vector (n :*: m) a)) =>+ VectorValue n (Vector m a) where+ type VectorValueOf n (Vector m a) = Vector (n :*: m) a+ vectorValueOf = vectorFromList . Fold.foldMap Fold.toList++vectorFromList :: (TypeNum.Positive n) => [a] -> Vector n a+vectorFromList =+ MS.evalState $ Trav.sequence $ App.pure $ MS.state $ \(y:ys) -> (y,ys)++instance (VectorValue n a, VectorValue n b) => VectorValue n (a,b) where+ type VectorValueOf n (a,b) = (VectorValueOf n a, VectorValueOf n b)+ vectorValueOf v =+ case FuncHT.unzip v of+ (a,b) -> (vectorValueOf a, vectorValueOf b)++instance+ (VectorValue n a, VectorValue n b, VectorValue n c) =>+ VectorValue n (a,b,c) where+ type VectorValueOf n (a,b,c) =+ (VectorValueOf n a, VectorValueOf n b, VectorValueOf n c)+ vectorValueOf v =+ case FuncHT.unzip3 v of+ (a,b,c) -> (vectorValueOf a, vectorValueOf b, vectorValueOf c)++instance (VectorValue n tuple) => VectorValue n (StoreTuple.Tuple tuple) where+ type VectorValueOf n (StoreTuple.Tuple tuple) = VectorValueOf n tuple+ vectorValueOf = vectorValueOf . fmap StoreTuple.getTuple++instance (TypeNum.Positive n) => VectorValue n Float where+ type VectorValueOf n Float = LLVM.Value (Vector n Float)+ vectorValueOf = LLVM.valueOf++instance (TypeNum.Positive n) => VectorValue n Double where+ type VectorValueOf n Double = LLVM.Value (Vector n Double)+ vectorValueOf = LLVM.valueOf+{-+instance (TypeNum.Positive n) => VectorValue n FP128 where+ type VectorValueOf n FP128 = LLVM.Value (Vector n FP128)+ vectorValueOf = LLVM.valueOf+-}+instance (TypeNum.Positive n) => VectorValue n Bool where+ type VectorValueOf n Bool = LLVM.Value (Vector n Bool)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Bool8 where+ type VectorValueOf n Bool8 = LLVM.Value (Vector n Bool)+ vectorValueOf = LLVM.valueOf . fmap Bool8.toBool+instance (TypeNum.Positive n) => VectorValue n Int where+ type VectorValueOf n Int = LLVM.Value (Vector n Int)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Int8 where+ type VectorValueOf n Int8 = LLVM.Value (Vector n Int8)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Int16 where+ type VectorValueOf n Int16 = LLVM.Value (Vector n Int16)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Int32 where+ type VectorValueOf n Int32 = LLVM.Value (Vector n Int32)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Int64 where+ type VectorValueOf n Int64 = LLVM.Value (Vector n Int64)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Word where+ type VectorValueOf n Word = LLVM.Value (Vector n Word)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Word8 where+ type VectorValueOf n Word8 = LLVM.Value (Vector n Word8)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Word16 where+ type VectorValueOf n Word16 = LLVM.Value (Vector n Word16)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Word32 where+ type VectorValueOf n Word32 = LLVM.Value (Vector n Word32)+ vectorValueOf = LLVM.valueOf+instance (TypeNum.Positive n) => VectorValue n Word64 where+ type VectorValueOf n Word64 = LLVM.Value (Vector n Word64)+ vectorValueOf = LLVM.valueOf+++-- * default methods for LLVM classes++valueOfFunctor :: (Value h, Functor f) => f h -> f (ValueOf h)+valueOfFunctor = fmap valueOf
+ src/LLVM/Extra/TuplePrivate.hs view
@@ -0,0 +1,140 @@+module LLVM.Extra.TuplePrivate where++import qualified LLVM.Core as LLVM++import qualified Data.FixedLength as FixedLength+import Data.Complex (Complex)++import qualified Type.Data.Num.Unary as Unary++import qualified Control.Applicative.HT as App+import Control.Applicative (Applicative, liftA2, pure)++import qualified Data.Traversable as Trav+import qualified Data.Foldable as Fold++import Data.Orphans ()++++-- * class for phi operating on value tuples++class Phi a where+ phi :: LLVM.BasicBlock -> a -> LLVM.CodeGenFunction r a+ addPhi :: LLVM.BasicBlock -> a -> a -> LLVM.CodeGenFunction r ()++instance Phi () where+ phi _ _ = return ()+ addPhi _ _ _ = return ()++instance (LLVM.IsFirstClass a) => Phi (LLVM.Value a) where+ phi bb a = LLVM.phi [(a, bb)]+ addPhi bb a a' = LLVM.addPhiInputs a [(a', bb)]++instance (Phi a, Phi b) => Phi (a, b) where+ phi bb = App.mapPair (phi bb, phi bb)+ addPhi bb (a0,b0) (a1,b1) = do+ addPhi bb a0 a1+ addPhi bb b0 b1++instance (Phi a, Phi b, Phi c) => Phi (a, b, c) where+ phi bb = App.mapTriple (phi bb, phi bb, phi bb)+ addPhi bb (a0,b0,c0) (a1,b1,c1) = do+ addPhi bb a0 a1+ addPhi bb b0 b1+ addPhi bb c0 c1++instance (Phi a, Phi b, Phi c, Phi d) => Phi (a, b, c, d) where+ phi bb (a,b,c,d) =+ App.lift4 (,,,) (phi bb a) (phi bb b) (phi bb c) (phi bb d)+ addPhi bb (a0,b0,c0,d0) (a1,b1,c1,d1) = do+ addPhi bb a0 a1+ addPhi bb b0 b1+ addPhi bb c0 c1+ addPhi bb d0 d1++instance (Phi a) => Phi (Complex a) where+ phi = phiTraversable+ addPhi = addPhiFoldable++instance (Unary.Natural n, Phi a) => Phi (FixedLength.T n a) where+ phi = phiTraversable+ addPhi = addPhiFoldable++phiTraversable ::+ (Phi a, Trav.Traversable f) =>+ LLVM.BasicBlock -> f a -> LLVM.CodeGenFunction r (f a)+phiTraversable bb x = Trav.mapM (phi bb) x++addPhiFoldable ::+ (Phi a, Fold.Foldable f, Applicative f) =>+ LLVM.BasicBlock -> f a -> f a -> LLVM.CodeGenFunction r ()+addPhiFoldable bb x y = Fold.sequence_ (liftA2 (addPhi bb) x y)+++-- * class for tuples of undefined values++class Undefined a where+ undef :: a++instance Undefined () where+ undef = ()++instance (LLVM.IsFirstClass a) => Undefined (LLVM.Value a) where+ undef = LLVM.value LLVM.undef++instance (LLVM.IsFirstClass a) => Undefined (LLVM.ConstValue a) where+ undef = LLVM.undef++instance (Undefined a, Undefined b) => Undefined (a, b) where+ undef = (undef, undef)++instance (Undefined a, Undefined b, Undefined c) => Undefined (a, b, c) where+ undef = (undef, undef, undef)++instance+ (Undefined a, Undefined b, Undefined c, Undefined d) =>+ Undefined (a, b, c, d) where+ undef = (undef, undef, undef, undef)++instance (Undefined a) => Undefined (Complex a) where+ undef = undefPointed++instance (Unary.Natural n, Undefined a) => Undefined (FixedLength.T n a) where+ undef = undefPointed++undefPointed :: (Undefined a, Applicative f) => f a+undefPointed = pure undef+++-- * class for tuples of zero values++class Zero a where+ zero :: a++instance Zero () where+ zero = ()++instance (LLVM.IsFirstClass a) => Zero (LLVM.Value a) where+ zero = LLVM.value LLVM.zero++instance (LLVM.IsFirstClass a) => Zero (LLVM.ConstValue a) where+ zero = LLVM.zero++instance (Zero a, Zero b) => Zero (a, b) where+ zero = (zero, zero)++instance (Zero a, Zero b, Zero c) => Zero (a, b, c) where+ zero = (zero, zero, zero)++instance (Zero a, Zero b, Zero c, Zero d) => Zero (a, b, c, d) where+ zero = (zero, zero, zero, zero)++instance (Zero a) => Zero (Complex a) where+ zero = zeroPointed++instance (Unary.Natural n, Zero a) => Zero (FixedLength.T n a) where+ zero = zeroPointed++zeroPointed :: (Zero a, Applicative f) => f a+zeroPointed = pure zero
src/LLVM/Extra/Vector.hs view
@@ -40,12 +40,11 @@ truncate, floor, fraction), ) where -import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.Extra.ArithmeticPrivate as A import qualified LLVM.Util.Intrinsic as Intrinsic import qualified LLVM.Core as LLVM-import LLVM.Util.Loop (Phi(phis, addPhis), ) import LLVM.Core (Value, ConstValue, valueOf, value, constOf, undef, Vector, insertelement, extractelement,@@ -70,9 +69,8 @@ import qualified Data.List as List import Data.NonEmpty ((!:), ) --- import qualified Data.Bits as Bit import Data.Int (Int8, Int16, Int32, Int64, )-import Data.Word (Word8, Word16, Word32, Word64, )+import Data.Word (Word8, Word16, Word32, Word64, Word) import Prelude hiding (Real, truncate, floor, round,@@ -101,7 +99,7 @@ insert :: Value Word32 -> Element v -> v -> CodeGenFunction r v class- (TypeNum.Positive (Size v), Phi v, Class.Undefined v) =>+ (TypeNum.Positive (Size v), Tuple.Phi v, Tuple.Undefined v) => Simple v where type Element v :: *@@ -210,14 +208,14 @@ {-# INLINE sequenceA #-} sequenceA (Constant a) = fmap Constant a -instance (Phi a) => Phi (Constant n a) where- phis = Class.phisTraversable- addPhis = Class.addPhisFoldable+instance (Tuple.Phi a) => Tuple.Phi (Constant n a) where+ phi = Tuple.phiTraversable+ addPhi = Tuple.addPhiFoldable -instance (Class.Undefined a) => Class.Undefined (Constant n a) where- undefTuple = Class.undefTuplePointed+instance (Tuple.Undefined a) => Tuple.Undefined (Constant n a) where+ undef = Tuple.undefPointed -instance (TypeNum.Positive n, Phi a, Class.Undefined a) => Simple (Constant n a) where+instance (TypeNum.Positive n, Tuple.Phi a, Tuple.Undefined a) => Simple (Constant n a) where type Element (Constant n a) = a type Size (Constant n a) = n@@ -277,10 +275,10 @@ (C v) => [Element v] -> CodeGenFunction r v assemble =- foldM (\v (k,x) -> insert (valueOf k) x v) Class.undefTuple .+ foldM (\v (k,x) -> insert (valueOf k) x v) Tuple.undef . List.zip [0..] {- sends GHC into an infinite loop- foldM (\(k,x) -> insert (valueOf k) x) Class.undefTuple .+ foldM (\(k,x) -> insert (valueOf k) x) Tuple.undef . List.zip [0..] -} @@ -303,7 +301,7 @@ Element v -> CodeGenFunction r v iterate f x = fmap snd $- iterateCore f x Class.undefTuple+ iterateCore f x Tuple.undef iterateCore :: (C v) =>@@ -413,18 +411,18 @@ (insert (LLVM.valueOf (fromIntegral (sizeInTuple x) - 1)) x0 y) shiftUpMultiZero ::- (C v, Class.Zero (Element v)) =>+ (C v, Tuple.Zero (Element v)) => Int -> v -> LLVM.CodeGenFunction r v shiftUpMultiZero n v = assemble . take (sizeInTuple v) .- (List.replicate n Class.zeroTuple ++) =<< extractAll v+ (List.replicate n Tuple.zero ++) =<< extractAll v shiftDownMultiZero ::- (C v, Class.Zero (Element v)) =>+ (C v, Tuple.Zero (Element v)) => Int -> v -> LLVM.CodeGenFunction r v shiftDownMultiZero n v = assemble . take (sizeInTuple v) .- (++ List.repeat Class.zeroTuple) . List.drop n+ (++ List.repeat Tuple.zero) . List.drop n =<< extractAll v @@ -522,7 +520,7 @@ extract (valueOf n) a >>= f >>= flip (insert (valueOf n)) b)- Class.undefTuple+ Tuple.undef (take (sizeInTuple a) [0..]) mapChunks ::@@ -537,7 +535,7 @@ am >>= \ac -> f ac >>= \bc -> insertChunk (k * sizeInTuple ac) bc b)- Class.undefTuple $+ Tuple.undef $ List.zip (chop a) [0..] zipChunksWith ::@@ -653,7 +651,7 @@ insert (valueOf j) x v) v0 $ List.zip [0..] js)- Class.undefTuple $+ Tuple.undef $ List.zip (ListHT.sliceVertical (sizeInTuple (head xs)) [0..]) xs@@ -754,7 +752,7 @@ a1 <- A.add a0 =<< extract (valueOf k) x y1 <- insert (valueOf k) a0 y0 return (a1,y1))- (a, Class.undefTuple)+ (a, Tuple.undef) (take (sizeInTuple x) $ [0..]) cumulateGeneric =@@ -929,10 +927,12 @@ instance Arithmetic Float where instance Arithmetic Double where +instance Arithmetic Int where instance Arithmetic Int8 where instance Arithmetic Int16 where instance Arithmetic Int32 where instance Arithmetic Int64 where+instance Arithmetic Word where instance Arithmetic Word8 where instance Arithmetic Word16 where instance Arithmetic Word32 where@@ -981,6 +981,15 @@ floor = Intrinsic.floor fraction = A.fraction +instance Real Int where+ min = A.min+ max = A.max+ abs = A.abs+ signum = signumIntGeneric+ truncate = return+ floor = return+ fraction = const $ return (value LLVM.zero)+ instance Real Int8 where min = A.min max = A.max@@ -1013,6 +1022,15 @@ max = A.max abs = A.abs signum = signumIntGeneric+ truncate = return+ floor = return+ fraction = const $ return (value LLVM.zero)++instance Real Word where+ min = A.min+ max = A.max+ abs = return+ signum = signumWordGeneric truncate = return floor = return fraction = const $ return (value LLVM.zero)
test/Main.hs view
@@ -1,5 +1,6 @@ module Main where +import qualified Test.Storable as Storable import qualified Test.Vector as Vector import qualified LLVM.Core as LLVM@@ -14,4 +15,6 @@ LLVM.initializeNativeTarget mapM_ (\(msg,prop) -> putStr (msg++": ") >> prop >>= QC.quickCheck) $- map (mapFst ("Vector."++)) Vector.tests+ map (mapFst ("Storable."++)) Storable.tests +++ map (mapFst ("Vector."++)) Vector.tests +++ []
+ test/Test/Storable.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE TypeFamilies #-}+module Test.Storable (tests) where++import qualified LLVM.Extra.Storable as Storable+import qualified LLVM.Extra.Tuple as Tuple++import qualified LLVM.ExecutionEngine as EE+import qualified LLVM.Core as LLVM++import qualified Type.Data.Num.Decimal as TypeNum++import qualified Foreign+import Foreign.Storable.Record.Tuple (Tuple(Tuple))+import Foreign.Ptr (FunPtr, Ptr)++import Data.Complex (Complex)+import Data.Word (Word16, Word32)+import Data.Int (Int8, Int16, Int32)+import Data.Tuple.HT (mapFst)++import qualified Test.QuickCheck.Monadic as QCMon+import qualified Test.QuickCheck as QC++++type Importer func = FunPtr func -> func++generateFunction ::+ EE.ExecutionFunction f =>+ Importer f -> LLVM.CodeGenModule (LLVM.Function f) -> IO f+generateFunction imprt code = do+ m <- LLVM.newModule+ fn <- do+ func <- LLVM.defineModule m $ LLVM.setTarget LLVM.hostTriple >> code+ EE.runEngineAccessWithModule m $ EE.getExecutionFunction imprt func+ LLVM.writeBitcodeToFile "test-storable.bc" m+ return fn+++foreign import ccall safe "dynamic" derefTestCasePtr ::+ Importer (Ptr inp -> Ptr out -> IO ())++modul ::+ (Storable.C a, Tuple.ValueOf a ~ al) =>+ (Storable.C b, Tuple.ValueOf b ~ bl) =>+ (al -> LLVM.CodeGenFunction () bl) ->+ LLVM.CodeGenModule (LLVM.Function (Ptr a -> Ptr b -> IO ()))+modul codegen =+ LLVM.createFunction LLVM.ExternalLinkage $ \aPtr bPtr -> do+ flip Storable.store bPtr =<< codegen =<< Storable.load aPtr+ LLVM.ret ()++run ::+ (Show a) =>+ (Storable.C a, Tuple.ValueOf a ~ al) =>+ (Storable.C b, Tuple.ValueOf b ~ bl) =>+ QC.Gen a ->+ (al -> LLVM.CodeGenFunction () bl) ->+ (a -> b -> Bool) ->+ IO QC.Property+run qcgen codegen predicate = do+ funIO <- generateFunction derefTestCasePtr $ modul codegen+ return $ QC.forAll qcgen $ \a ->+ QCMon.monadicIO $ do+ b <-+ QCMon.run $+ Foreign.with a $ \aPtr ->+ Foreign.alloca $ \bPtr -> do+ funIO aPtr bPtr+ Foreign.peek bPtr+ QCMon.assert $ predicate a b+++roundTrip ::+ (Show a, Eq a, Storable.C a) =>+ QC.Gen a -> IO QC.Property+roundTrip qcgen = run qcgen return (==)+++tests :: [(String, IO QC.Property)]+tests =+ map (mapFst ("RoundTrip." ++)) $+ ("()",+ roundTrip (QC.arbitrary :: QC.Gen ())) :+ ("Float",+ roundTrip (QC.arbitrary :: QC.Gen Float)) :+ ("(Word16,Float)",+ roundTrip (fmap Tuple (QC.arbitrary :: QC.Gen (Word16,Float)))) :+ ("(Int8,Bool,Double)",+ roundTrip (fmap Tuple (QC.arbitrary :: QC.Gen (Int8,Bool,Double)))) :+ ("Complex Float",+ roundTrip (QC.arbitrary :: QC.Gen (Complex Float))) :+ ("Vector D3 Int32",+ roundTrip (QC.arbitrary :: QC.Gen (LLVM.Vector TypeNum.D3 Int32))) :+ ("Vector D7 (Int16,Word32)",+ roundTrip (fmap (fmap Tuple)+ (QC.arbitrary :: QC.Gen (LLVM.Vector TypeNum.D7 (Int16,Word32))))) :+ []
test/Test/Vector.hs view
@@ -1,23 +1,23 @@ {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-} module Test.Vector where import qualified LLVM.Extra.ScalarOrVectorPrivate as SoVPriv import qualified LLVM.Extra.ScalarOrVector as SoV import qualified LLVM.Extra.VectorAlt as VectorAlt import qualified LLVM.Extra.Vector as Vector+import qualified LLVM.Extra.Memory as Memory import qualified LLVM.Extra.Marshal as Marshal-import qualified LLVM.Extra.Class as Class+import qualified LLVM.Extra.Tuple as Tuple import qualified LLVM.ExecutionEngine as EE-import qualified LLVM.Util.Proxy as LP import qualified LLVM.Core as LLVM import qualified Type.Data.Num.Decimal as TypeNum import Type.Base.Proxy (Proxy(Proxy)) -import qualified Foreign.Marshal as Marsh-import Foreign.Ptr (FunPtr, Ptr)+import Foreign.Ptr (FunPtr) import qualified Data.Traversable as Trav import qualified Data.Foldable as Fold@@ -50,49 +50,39 @@ fn <- do func <- LLVM.defineModule m $ LLVM.setTarget LLVM.hostTriple >> code EE.runEngineAccessWithModule m $ EE.getExecutionFunction imprt func- LLVM.writeBitcodeToFile "test.bc" m+ LLVM.writeBitcodeToFile "test-vector.bc" m return fn foreign import ccall safe "dynamic" derefTestCasePtr ::- Importer (Ptr inp -> Ptr out -> IO ())+ Importer (LLVM.Ptr inp -> LLVM.Ptr out -> IO ()) modul ::- (Marshal.C inp, Marshal.Struct inp ~ minp, LLVM.IsType minp,- Marshal.C out, Marshal.Struct out ~ mout, LLVM.IsType mout,- Class.ValueTuple inp ~ linp, Class.ValueTuple out ~ lout) =>- (LP.Proxy inp, LP.Proxy out) ->+ (Memory.C linp, Memory.Struct linp ~ minp, LLVM.IsType minp,+ Memory.C lout, Memory.Struct lout ~ mout, LLVM.IsType mout) => (linp -> LLVM.CodeGenFunction () lout) ->- LLVM.CodeGenModule (LLVM.Function (Ptr minp -> Ptr mout -> IO ()))-modul (xProxy,yProxy) codegen =+ LLVM.CodeGenModule (LLVM.Function (LLVM.Ptr minp -> LLVM.Ptr mout -> IO ()))+modul codegen = LLVM.createFunction LLVM.ExternalLinkage $ \xPtr yPtr -> do- flip (Marshal.store yProxy) yPtr =<< codegen =<< Marshal.load xProxy xPtr+ flip Memory.store yPtr =<< codegen =<< Memory.load xPtr LLVM.ret () -proxies :: (inp -> out -> Bool) -> (LP.Proxy inp, LP.Proxy out)-proxies _ = (LP.Proxy, LP.Proxy)--alloca :: (LLVM.IsType a) => LP.Proxy a -> (Ptr a -> IO b) -> IO b-alloca proxy = Marsh.allocaBytes (EE.sizeOf proxy)- run :: (Marshal.C inp, Marshal.Struct inp ~ minp, LLVM.IsType minp, Marshal.C out, Marshal.Struct out ~ mout, LLVM.IsType mout,- Class.ValueTuple inp ~ linp, Class.ValueTuple out ~ lout) =>+ Tuple.ValueOf inp ~ linp, Tuple.ValueOf out ~ lout) => (Show inp, QC.Arbitrary inp) => (linp -> LLVM.CodeGenFunction () lout) -> (inp -> out -> Bool) -> IO QC.Property run codegen predicate = do- funIO <-- generateFunction derefTestCasePtr $ modul (proxies predicate) codegen+ funIO <- generateFunction derefTestCasePtr $ modul codegen return $ QC.property $ \x -> QCMon.monadicIO $ do y <- QCMon.run $- alloca LP.Proxy $ \xPtr ->- alloca LP.Proxy $ \yPtr -> do- Marshal.poke xPtr x+ Marshal.with x $ \xPtr ->+ Marshal.alloca $ \yPtr -> do funIO xPtr yPtr Marshal.peek yPtr QCMon.assert $ predicate x y@@ -119,10 +109,9 @@ binop :: ((TypeNum.D4 TypeNum.:*: LLVM.SizeOf a) ~ size, TypeNum.Natural size,- QC.Arbitrary a, Show a, Eq a, EE.Marshal a,- LLVM.IsConst a, LLVM.IsSized a, LLVM.IsPrimitive a) =>- (LLVM.Value (V4 a) -> LLVM.Value (V4 a) ->- LLVM.CodeGenFunction () (LLVM.Value (V4 a))) ->+ QC.Arbitrary a, Show a, Eq a,+ Marshal.Vector TypeNum.D4 a, Tuple.VectorValueOf TypeNum.D4 a ~ v) =>+ (v -> v -> LLVM.CodeGenFunction () v) -> (a -> a -> a) -> IO QC.Property binop codegen fun =@@ -130,8 +119,8 @@ (\(x,y) z -> liftA2 fun (vec4 x) (vec4 y) == vec4 z) binopInt ::- (LLVM.Value V4Int32 -> LLVM.Value V4Int32 ->- LLVM.CodeGenFunction () (LLVM.Value V4Int32)) ->+ (LLVM.Value V4Int32 ~ v) =>+ (v -> v -> LLVM.CodeGenFunction () v) -> (Int32 -> Int32 -> Int32) -> IO QC.Property binopInt = binop@@ -179,10 +168,10 @@ unpackWord3 = unpackWords 8 binopV4I2 ::- (Eq a, LLVM.IsPrimitive a, LLVM.IsSized a, LLVM.SizeOf a ~ TypeNum.D2) =>+ (Eq a, LLVM.IsPrimitive a, LLVM.IsSized a, LLVM.SizeOf a ~ TypeNum.D2,+ LLVM.Value (V4 a) ~ v) => (Word8 -> V4 a) ->- (LLVM.Value (V4 a) -> LLVM.Value (V4 a) ->- LLVM.CodeGenFunction () (LLVM.Value (V4 a))) ->+ (v -> v -> LLVM.CodeGenFunction () v) -> (a -> a -> a) -> IO QC.Property binopV4I2 unpackBits codegen fun =@@ -198,10 +187,10 @@ type Code15 r = LLVM.CodeGenFunction r (LLVM.Value (LLVM.WordN TypeNum.D15)) binopV5I3 ::- (Eq a, LLVM.IsPrimitive a, LLVM.IsSized a, LLVM.SizeOf a ~ TypeNum.D3) =>+ (Eq a, LLVM.IsPrimitive a, LLVM.IsSized a, LLVM.SizeOf a ~ TypeNum.D3,+ LLVM.Value (V5 a) ~ v) => (Word16 -> V5 a) ->- (LLVM.Value (V5 a) -> LLVM.Value (V5 a) ->- LLVM.CodeGenFunction () (LLVM.Value (V5 a))) ->+ (v -> v -> LLVM.CodeGenFunction () v) -> (a -> a -> a) -> IO QC.Property binopV5I3 unpackBits codegen fun =@@ -215,15 +204,15 @@ liftA2 fun (unpackBits x) (unpackBits y) == unpackBits z) binopInt8 ::- (LLVM.Value (V4 Int8) -> LLVM.Value (V4 Int8) ->- LLVM.CodeGenFunction () (LLVM.Value (V4 Int8))) ->+ (LLVM.Value (V4 Int8) ~ v) =>+ (v -> v -> LLVM.CodeGenFunction () v) -> (Int8 -> Int8 -> Int8) -> IO QC.Property binopInt8 = binop binopWord8 ::- (LLVM.Value (V4 Word8) -> LLVM.Value (V4 Word8) ->- LLVM.CodeGenFunction () (LLVM.Value (V4 Word8))) ->+ (LLVM.Value (V4 Word8) ~ v) =>+ (v -> v -> LLVM.CodeGenFunction () v) -> (Word8 -> Word8 -> Word8) -> IO QC.Property binopWord8 = binop