-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Utility functions for the llvm interface
--
-- The Low-Level Virtual-Machine is a compiler back-end with optimizer.
-- You may also call it a high-level portable assembler. This package
-- provides various utility functions for the Haskell interface to LLVM,
-- for example:
--
--
-- - arithmetic operations with more general types but better type
-- inference than the llvm interface in
-- LLVM.Extra.Arithmetic,
-- - 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,
-- - handling of termination by a custom monad on top of
-- CodeGenFunction in LLVM.Extra.MaybeContinuation
-- - various kinds of loops (while) and condition structures
-- (if-then-else) in LLVM.Extra.Control
-- - automatic adaption to target specific extensions, currently used
-- for access of vector operations that are specific to an SSE level on
-- x86 processors in LLVM.Extra.Extension (On x86 architectures we
-- depend on the cpuid package that is needed for automatic detection of
-- available features.)
-- - advanced vector operations such as sum of all vector elements,
-- cumulative sum, floor, non-negative fraction, absolute value in
-- LLVM.Extra.Vector
-- - type classes for handling scalar and vector operations in a
-- uniform way in LLVM.Extra.ScalarOrVector
-- - a Makefile and a description of how to run LLVM code from within
-- GHCi.
--
@package llvm-extra
@version 0.5
module LLVM.Extra.Extension
-- | This is an Applicative functor that registers, what extensions are
-- needed in order to run the contained instructions. You can escape from
-- the functor by calling run and providing a generic
-- implementation.
--
-- We use an applicative functor since with a monadic interface we had to
-- create the specialised code in every case, in order to see which
-- extensions where used in the course of creating the instructions.
--
-- We use only one (unparameterized) type for all extensions, since this
-- is the most simple solution. Alternatively we could use a type
-- parameter where class constraints show what extensions are needed.
-- This would be just like exceptions that are explicit in the type
-- signature as in the control-monad-exception package. However we would
-- still need to lift all basic LLVM instructions to the new monad.
data T a
-- | Analogous to FunctionArgs
--
-- The type parameter r and its functional dependency are
-- necessary since g must be a function of the form a ->
-- ... -> c -> CodeGenFunction r d and we must ensure that the
-- explicit r and the implicit r in the g do
-- match.
class CallArgs g
data Subtarget
Subtarget :: String -> String -> (forall r. CodeGenFunction r Bool) -> Subtarget
-- | Declare that a certain plain LLVM instruction depends on a particular
-- extension. This can be useful if you rely on the data layout of a
-- certain architecture when doing a bitcast, or if you know that LLVM
-- translates a certain generic operation to something especially optimal
-- for the declared extension.
wrap :: Subtarget -> a -> T a
-- | Create an intrinsic and register the needed extension. We cannot
-- immediately check whether the signature matches or whether the right
-- extension is given. However, when resolving intrinsics LLVM will not
-- find the intrinsic if the extension is wrong, and it also checks the
-- signature.
intrinsic :: (IsFunction f, CallArgs f g (Result g), CallArgs g) => Subtarget -> String -> T g
intrinsicAttr :: (IsFunction f, CallArgs f g (Result g), CallArgs g) => [Attribute] -> Subtarget -> String -> T g
-- | run generic specific generates the specific code if
-- the required extensions are available on the host processor and
-- generic otherwise.
run :: CodeGenFunction r a -> T (CodeGenFunction r a) -> CodeGenFunction r a
-- | Convenient variant of run: Only run the code with extended
-- instructions if an additional condition is satisfied.
runWhen :: Bool -> CodeGenFunction r a -> T (CodeGenFunction r a) -> CodeGenFunction r a
-- | Only for debugging purposes.
runUnsafe :: T a -> a
with :: Functor f => f a -> (a -> b) -> f b
with2 :: Applicative f => f a -> f b -> (a -> b -> c) -> f c
with3 :: Applicative f => f a -> f b -> f c -> (a -> b -> c -> d) -> f d
instance Functor T
instance Applicative T
instance CallArgs (CodeGenFunction r (Value a))
instance CallArgs g => CallArgs (Value a -> g)
module LLVM.Extra.ExtensionCheck.X86
sse1 :: Subtarget
sse2 :: Subtarget
sse3 :: Subtarget
ssse3 :: Subtarget
sse41 :: Subtarget
sse42 :: Subtarget
avx :: Subtarget
avx2 :: Subtarget
fma3 :: Subtarget
fma4 :: Subtarget
amd3dnow :: Subtarget
amd3dnowa :: Subtarget
aes :: Subtarget
-- | These functions work in arbitrary monads but are especially helpful
-- when working with the CodeGenFunction monad.
module LLVM.Extra.Monad
chain :: Monad m => [a -> m a] -> (a -> m a)
liftR2 :: Monad m => (a -> b -> m c) -> m a -> m b -> m c
liftR3 :: Monad m => (a -> b -> c -> m d) -> m a -> m b -> m c -> m d
-- | Useful control structures additionally to those in
-- LLVM.Util.Loop.
module LLVM.Extra.Control
arrayLoop :: (Phi a, IsType b, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i, CmpResult i ~ Bool) => Value i -> Value (Ptr b) -> a -> (Value (Ptr b) -> a -> CodeGenFunction r a) -> CodeGenFunction r a
arrayLoop2 :: (Phi s, IsType a, IsType b, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i, CmpResult i ~ Bool) => Value i -> Value (Ptr a) -> Value (Ptr b) -> s -> (Value (Ptr a) -> Value (Ptr b) -> s -> CodeGenFunction r s) -> CodeGenFunction r s
arrayLoopWithExit :: (Phi s, IsType a, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i, CmpResult i ~ Bool) => Value i -> Value (Ptr a) -> s -> (Value (Ptr a) -> s -> CodeGenFunction r (Value Bool, s)) -> CodeGenFunction r (Value i, s)
arrayLoop2WithExit :: (Phi s, IsType a, IsType b, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i, CmpResult i ~ Bool) => Value i -> Value (Ptr a) -> Value (Ptr b) -> s -> (Value (Ptr a) -> Value (Ptr b) -> s -> CodeGenFunction r (Value Bool, s)) -> CodeGenFunction r (Value i, s)
fixedLengthLoop :: (Phi s, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i, CmpResult i ~ Bool) => Value i -> s -> (s -> CodeGenFunction r s) -> CodeGenFunction r s
whileLoop :: Phi a => a -> (a -> CodeGenFunction r (Value Bool)) -> (a -> CodeGenFunction r a) -> CodeGenFunction r a
-- | This is a variant of whileLoop that may be more convient,
-- because you only need one lambda expression for both loop condition
-- and loop body.
whileLoopShared :: Phi a => a -> (a -> (CodeGenFunction r (Value Bool), CodeGenFunction r a)) -> CodeGenFunction r a
loopWithExit :: Phi a => a -> (a -> CodeGenFunction r (Value Bool, b)) -> (b -> CodeGenFunction r a) -> CodeGenFunction r b
-- | This construct starts new blocks, so be prepared when continueing
-- after an ifThenElse.
ifThenElse :: Phi a => Value Bool -> CodeGenFunction r a -> CodeGenFunction r a -> CodeGenFunction r a
ifThen :: Phi a => Value Bool -> a -> CodeGenFunction r a -> CodeGenFunction r a
class Phi a => Select a
select :: Select a => Value Bool -> a -> a -> CodeGenFunction r a
selectTraversable :: (Select a, Traversable f, Applicative f) => Value Bool -> f a -> f a -> CodeGenFunction r (f a)
-- | Branch-free variant of ifThen that is faster if the enclosed
-- block is very simply, say, if it contains at most two instructions. It
-- can only be used as alternative to ifThen if the enclosed block
-- is free of side effects.
ifThenSelect :: Select a => Value Bool -> a -> CodeGenFunction r a -> CodeGenFunction r a
instance (Select a, Select b, Select c) => Select (a, b, c)
instance (Select a, Select b) => Select (a, b)
instance Select ()
instance (IsFirstClass a, CmpRet a, CmpResult a ~ Bool) => Select (Value a)
module LLVM.Extra.Class
class Undefined a
undefTuple :: Undefined a => a
class Zero a
zeroTuple :: Zero a => a
zeroTuplePointed :: (Zero a, Applicative f) => f a
class Undefined (ValueTuple haskellValue) => MakeValueTuple haskellValue where type family ValueTuple haskellValue :: *
valueTupleOf :: MakeValueTuple haskellValue => haskellValue -> ValueTuple haskellValue
undefTuplePointed :: (Undefined a, Applicative f) => f a
valueTupleOfFunctor :: (MakeValueTuple h, Functor f) => f h -> f (ValueTuple h)
phisTraversable :: (Phi a, Traversable f) => BasicBlock -> f a -> CodeGenFunction r (f a)
addPhisFoldable :: (Phi a, Foldable f, Applicative f) => BasicBlock -> f a -> f a -> CodeGenFunction r ()
instance (PositiveT n, IsPrimitive a, IsConst a) => MakeValueTuple (Vector n a)
instance MakeValueTuple (StablePtr a)
instance IsType a => MakeValueTuple (Ptr a)
instance MakeValueTuple ()
instance MakeValueTuple Word64
instance MakeValueTuple Word32
instance MakeValueTuple Word16
instance MakeValueTuple Word8
instance MakeValueTuple Int64
instance MakeValueTuple Int32
instance MakeValueTuple Int16
instance MakeValueTuple Int8
instance MakeValueTuple Bool
instance MakeValueTuple Double
instance MakeValueTuple Float
instance (MakeValueTuple a, MakeValueTuple b) => MakeValueTuple (Either a b)
instance MakeValueTuple a => MakeValueTuple (Maybe a)
instance (MakeValueTuple ah, MakeValueTuple bh, MakeValueTuple ch) => MakeValueTuple (ah, bh, ch)
instance (MakeValueTuple ah, MakeValueTuple bh) => MakeValueTuple (ah, bh)
instance (Zero a, Zero b, Zero c) => Zero (a, b, c)
instance (Zero a, Zero b) => Zero (a, b)
instance IsFirstClass a => Zero (ConstValue a)
instance IsFirstClass a => Zero (Value a)
instance Zero ()
instance (Undefined a, Undefined b) => Undefined (T a b)
instance Undefined a => Undefined (T a)
instance (Undefined a, Undefined b, Undefined c) => Undefined (a, b, c)
instance (Undefined a, Undefined b) => Undefined (a, b)
instance IsFirstClass a => Undefined (ConstValue a)
instance IsFirstClass a => Undefined (Value a)
instance Undefined ()
module LLVM.Extra.Array
size :: NaturalT n => Value (Array n a) -> Int
-- | construct an array out of single elements
--
-- You must assert that the length of the list matches the array size.
--
-- This can be considered the inverse of extractAll.
assemble :: (NaturalT n, IsFirstClass a, IsSized a) => [Value a] -> CodeGenFunction r (Value (Array n a))
-- | provide the elements of an array as a list of individual virtual
-- registers
--
-- This can be considered the inverse of assemble.
extractAll :: (NaturalT n, IsFirstClass a, IsSized a) => Value (Array n a) -> CodeGenFunction r [Value a]
-- | The loop is unrolled, since insertvalue and extractvalue
-- expect constant indices.
map :: (NaturalT n, IsFirstClass a, IsSized a, IsFirstClass b, IsSized b) => (Value a -> CodeGenFunction r (Value b)) -> (Value (Array n a) -> CodeGenFunction r (Value (Array n b)))
-- | LLVM counterpart to Maybe datatype.
module LLVM.Extra.Maybe
-- | If isJust = False, then fromJust is an
-- undefTuple.
data T a
Cons :: Value Bool -> a -> T a
isJust :: T a -> Value Bool
fromJust :: T a -> a
-- | counterpart to maybe
run :: Phi b => T a -> CodeGenFunction r b -> (a -> CodeGenFunction r b) -> CodeGenFunction r b
for :: T a -> (a -> CodeGenFunction r ()) -> CodeGenFunction r ()
-- | counterpart to fromMaybe with swapped arguments
select :: Select a => T a -> a -> CodeGenFunction r a
alternative :: Select a => T a -> T a -> CodeGenFunction r (T a)
-- | counterpart to Data.Maybe.HT.toMaybe
fromBool :: Value Bool -> a -> T a
toBool :: T a -> (Value Bool, a)
getIsNothing :: T a -> CodeGenFunction r (Value Bool)
just :: a -> T a
nothing :: Undefined a => T a
sequence :: T (CodeGenFunction r a) -> CodeGenFunction r (T a)
traverse :: (a -> CodeGenFunction r b) -> T a -> CodeGenFunction r (T b)
lift2 :: (a -> b -> c) -> T a -> T b -> CodeGenFunction r (T c)
liftM2 :: (a -> b -> CodeGenFunction r c) -> T a -> T b -> CodeGenFunction r (T c)
loopWithExit :: Phi a => a -> (a -> CodeGenFunction r (T c, b)) -> ((c, b) -> CodeGenFunction r a) -> CodeGenFunction r b
module LLVM.Extra.Multi.Value
newtype T a
Cons :: (ValueTuple a) -> T a
valueOf :: MakeValueTuple a => a -> T a
undef :: (Undefined al, al ~ ValueTuple a) => T a
zip :: T a -> T b -> T (a, b)
zip3 :: T a -> T b -> T c -> T (a, b, c)
unzip :: T (a, b) -> (T a, T b)
unzip3 :: T (a, b, c) -> (T a, T b, T c)
-- | LLVM counterpart to Either datatype.
module LLVM.Extra.Either
-- | If isRight, then fromLeft is an undefTuple.
-- If not isRight, then fromRight is an
-- undefTuple. I would prefer a union type, but it was
-- temporarily removed in LLVM-2.8 and did not return since then.
data T a b
Cons :: Value Bool -> a -> b -> T a b
isRight :: T a b -> Value Bool
fromLeft :: T a b -> a
fromRight :: T a b -> b
-- | counterpart to either
run :: Phi c => T a b -> (a -> CodeGenFunction r c) -> (b -> CodeGenFunction r c) -> CodeGenFunction r c
getIsLeft :: T a b -> CodeGenFunction r (Value Bool)
mapLeft :: (a0 -> a1) -> T a0 b -> T a1 b
mapRight :: (b0 -> b1) -> T a b0 -> T a b1
left :: Undefined b => a -> T a b
right :: Undefined a => b -> T a b
-- | Some special operations on X86 processors. If you want to use them in
-- algorithms you will always have to prepare an alternative
-- implementation in terms of plain LLVM instructions. You will then run
-- them with run and this driver function then selects the most
-- advanced of both implementations. Functions that are written this way
-- can be found in LLVM.Extra.Vector. Availability of extensions
-- is checked with the CPUID instruction. However this does only
-- work if you compile code for the host machine, that is cross
-- compilation will fail! For cross compilation we would need access to
-- the SubTarget detection of LLVM that is only available in the C++
-- interface in version 2.6.
module LLVM.Extra.Extension.X86
maxss :: T (V4Float -> V4Float -> CodeGenFunction r (V4Float))
minss :: T (V4Float -> V4Float -> CodeGenFunction r (V4Float))
maxps :: T (V4Float -> V4Float -> CodeGenFunction r (V4Float))
minps :: T (V4Float -> V4Float -> CodeGenFunction r (V4Float))
maxsd :: T (V2Double -> V2Double -> CodeGenFunction r (V2Double))
minsd :: T (V2Double -> V2Double -> CodeGenFunction r (V2Double))
maxpd :: T (V2Double -> V2Double -> CodeGenFunction r (V2Double))
minpd :: T (V2Double -> V2Double -> CodeGenFunction r (V2Double))
cmpss :: T (FPPredicate -> V4Float -> V4Float -> CodeGenFunction r V4Int32)
cmpps :: T (FPPredicate -> V4Float -> V4Float -> CodeGenFunction r V4Int32)
cmpsd :: T (FPPredicate -> V2Double -> V2Double -> CodeGenFunction r V2Int64)
cmppd :: T (FPPredicate -> V2Double -> V2Double -> CodeGenFunction r V2Int64)
cmpps256 :: T (FPPredicate -> V8Float -> V8Float -> CodeGenFunction r V8Int32)
cmppd256 :: T (FPPredicate -> V4Double -> V4Double -> CodeGenFunction r V4Int64)
pcmpgtb :: T (V16Int8 -> V16Int8 -> CodeGenFunction r V16Int8)
pcmpgtw :: T (V8Int16 -> V8Int16 -> CodeGenFunction r V8Int16)
pcmpgtd :: T (V4Int32 -> V4Int32 -> CodeGenFunction r V4Int32)
pcmpgtq :: T (V2Int64 -> V2Int64 -> CodeGenFunction r V2Int64)
pcmpugtb :: T (V16Word8 -> V16Word8 -> CodeGenFunction r V16Word8)
pcmpugtw :: T (V8Word16 -> V8Word16 -> CodeGenFunction r V8Word16)
pcmpugtd :: T (V4Word32 -> V4Word32 -> CodeGenFunction r V4Word32)
pcmpugtq :: T (V2Word64 -> V2Word64 -> CodeGenFunction r V2Word64)
pminsb :: T (V16Int8 -> V16Int8 -> CodeGenFunction r V16Int8)
pminsw :: T (V8Int16 -> V8Int16 -> CodeGenFunction r V8Int16)
pminsd :: T (V4Int32 -> V4Int32 -> CodeGenFunction r V4Int32)
pmaxsb :: T (V16Int8 -> V16Int8 -> CodeGenFunction r V16Int8)
pmaxsw :: T (V8Int16 -> V8Int16 -> CodeGenFunction r V8Int16)
pmaxsd :: T (V4Int32 -> V4Int32 -> CodeGenFunction r V4Int32)
pminub :: T (V16Word8 -> V16Word8 -> CodeGenFunction r V16Word8)
pminuw :: T (V8Word16 -> V8Word16 -> CodeGenFunction r V8Word16)
pminud :: T (V4Word32 -> V4Word32 -> CodeGenFunction r V4Word32)
pmaxub :: T (V16Word8 -> V16Word8 -> CodeGenFunction r V16Word8)
pmaxuw :: T (V8Word16 -> V8Word16 -> CodeGenFunction r V8Word16)
pmaxud :: T (V4Word32 -> V4Word32 -> CodeGenFunction r V4Word32)
pabsb :: T (V16Int8 -> CodeGenFunction r V16Int8)
pabsw :: T (V8Int16 -> CodeGenFunction r V8Int16)
pabsd :: T (V4Int32 -> CodeGenFunction r V4Int32)
pmuludq :: T (V4Word32 -> V4Word32 -> CodeGenFunction r V2Word64)
pmuldq :: T (V4Int32 -> V4Int32 -> CodeGenFunction r V2Int64)
pmulld :: T (V4Word32 -> V4Word32 -> CodeGenFunction r V4Word32)
cvtps2dq :: T (V4Float -> CodeGenFunction r V4Int32)
-- | the upper two integers are set to zero, there is no instruction that
-- converts to Int64
cvtpd2dq :: T (V2Double -> CodeGenFunction r V4Int32)
cvtdq2ps :: T (V4Int32 -> CodeGenFunction r V4Float)
-- | the upper two integers are ignored, there is no instruction that
-- converts from Int64
cvtdq2pd :: T (V4Int32 -> CodeGenFunction r V2Double)
-- | MXCSR is not really supported by LLVM-2.6. LLVM does not know about
-- the dependency of all floating point operations on this status
-- register.
ldmxcsr :: T (Value (Ptr Word32) -> CodeGenFunction r ())
stmxcsr :: T (Value (Ptr Word32) -> CodeGenFunction r ())
withMXCSR :: Word32 -> T (CodeGenFunction r a -> CodeGenFunction r a)
haddps :: T (V4Float -> V4Float -> CodeGenFunction r (V4Float))
haddpd :: T (V2Double -> V2Double -> CodeGenFunction r (V2Double))
dpps :: T (V4Float -> V4Float -> Value Int32 -> CodeGenFunction r (V4Float))
dppd :: T (V2Double -> V2Double -> Value Int32 -> CodeGenFunction r (V2Double))
roundss :: T (V4Float -> Value Word32 -> CodeGenFunction r V4Float)
roundps :: T (V4Float -> Value Word32 -> CodeGenFunction r (V4Float))
roundsd :: T (V2Double -> Value Word32 -> CodeGenFunction r V2Double)
roundpd :: T (V2Double -> Value Word32 -> CodeGenFunction r (V2Double))
absss :: T (V4Float -> CodeGenFunction r V4Float)
abssd :: T (V2Double -> CodeGenFunction r V2Double)
absps :: PositiveT n => T (Value (Vector n Float) -> CodeGenFunction r (Value (Vector n Float)))
abspd :: PositiveT n => T (Value (Vector n Double) -> CodeGenFunction r (Value (Vector n Double)))
module LLVM.Extra.Vector
class (PositiveT (Size v), Phi v, Undefined v) => Simple v where type family Element v :: * type family Size v :: *
shuffleMatch :: Simple v => ConstValue (Vector (Size v) Word32) -> v -> CodeGenFunction r v
extract :: Simple v => Value Word32 -> v -> CodeGenFunction r (Element v)
-- | Allow to work on records of vectors as if they are vectors of records.
-- This is a reasonable approach for records of different element types
-- since processor vectors can only be built from elements of the same
-- type. But also, say, for chunked stereo signal this makes sense. In
-- this case we would work on Stereo (Value a).
--
-- Formerly we used a two-way dependency Vector - (Element, Size).
-- Now we have only the dependency Vector -> (Element, Size). This
-- means that we need some more type annotations as in
-- umul32to64/assemble, on the other hand we can allow multiple vector
-- types with respect to the same element type. E.g. we can provide a
-- vector type with pair elements where the pair elements are interleaved
-- in the vector.
class Simple v => C v
insert :: C v => Value Word32 -> Element v -> v -> CodeGenFunction r v
class (n ~ Size (Construct n a), a ~ Element (Construct n a), C (Construct n a)) => Canonical n a where type family Construct n a :: *
size :: PositiveT n => Value (Vector n a) -> Int
sizeInTuple :: Simple v => v -> Int
-- | Manually assemble a vector of equal values. Better use
-- ScalarOrVector.replicate.
replicate :: C v => Element v -> CodeGenFunction r v
iterate :: C v => (Element v -> CodeGenFunction r (Element v)) -> Element v -> CodeGenFunction r v
-- | construct a vector out of single elements
--
-- You must assert that the length of the list matches the vector size.
--
-- This can be considered the inverse of extractAll.
assemble :: C v => [Element v] -> CodeGenFunction r v
-- | Manually implement vector shuffling using insertelement and
-- extractelement. In contrast to LLVM's built-in instruction it supports
-- distinct vector sizes, but it allows only one input vector (or a tuple
-- of vectors, but we cannot shuffle between them). For more complex
-- shuffling we recommend extractAll and assemble.
shuffle :: (C v, C w, Element v ~ Element w) => v -> ConstValue (Vector (Size w) Word32) -> CodeGenFunction r w
-- | Rotate one element towards the higher elements.
--
-- I don't want to call it rotateLeft or rotateRight, because there is no
-- prefered layout for the vector elements. In Intel's instruction manual
-- vector elements are indexed like the bits, that is from right to left.
-- However, when working with Haskell list and enumeration syntax, the
-- start index is left.
rotateUp :: Simple v => v -> CodeGenFunction r v
rotateDown :: Simple v => v -> CodeGenFunction r v
reverse :: Simple v => v -> CodeGenFunction r v
shiftUp :: C v => Element v -> v -> CodeGenFunction r (Element v, v)
shiftDown :: C v => Element v -> v -> CodeGenFunction r (Element v, v)
shiftUpMultiZero :: (C v, Zero (Element v)) => Int -> v -> CodeGenFunction r v
shiftDownMultiZero :: (C v, Zero (Element v)) => Int -> v -> CodeGenFunction r v
shuffleMatchTraversable :: (Simple v, Traversable f) => ConstValue (Vector (Size v) Word32) -> f v -> CodeGenFunction r (f v)
-- | Implement the shuffleMatch method using the methods of the
-- C class.
shuffleMatchAccess :: C v => ConstValue (Vector (Size v) Word32) -> v -> CodeGenFunction r v
shuffleMatchPlain1 :: (PositiveT n, IsPrimitive a) => Value (Vector n a) -> ConstValue (Vector n Word32) -> CodeGenFunction r (Value (Vector n a))
shuffleMatchPlain2 :: (PositiveT n, IsPrimitive a) => Value (Vector n a) -> Value (Vector n a) -> ConstValue (Vector n Word32) -> CodeGenFunction r (Value (Vector n a))
insertTraversable :: (C v, Traversable f, Applicative f) => Value Word32 -> f (Element v) -> f v -> CodeGenFunction r (f v)
extractTraversable :: (Simple v, Traversable f) => Value Word32 -> f v -> CodeGenFunction r (f (Element v))
-- | provide the elements of a vector as a list of individual virtual
-- registers
--
-- This can be considered the inverse of assemble.
extractAll :: Simple v => v -> CodeGenFunction r [Element v]
data Constant n a
constant :: PositiveT n => a -> Constant n a
insertChunk :: (C c, C v, Element c ~ Element v) => Int -> c -> v -> CodeGenFunction r v
modify :: C v => Value Word32 -> (Element v -> CodeGenFunction r (Element v)) -> (v -> CodeGenFunction r v)
-- | Like LLVM.Util.Loop.mapVector but the loop is unrolled, which is
-- faster since it can be packed by the code generator.
map :: (C v, C w, Size v ~ Size w) => (Element v -> CodeGenFunction r (Element w)) -> (v -> CodeGenFunction r w)
mapChunks :: (C ca, C cb, Size ca ~ Size cb, C va, C vb, Size va ~ Size vb, Element ca ~ Element va, Element cb ~ Element vb) => (ca -> CodeGenFunction r cb) -> (va -> CodeGenFunction r vb)
zipChunksWith :: (C ca, C cb, C cc, Size ca ~ Size cb, Size cb ~ Size cc, C va, C vb, C vc, Size va ~ Size vb, Size vb ~ Size vc, Element ca ~ Element va, Element cb ~ Element vb, Element cc ~ Element vc) => (ca -> cb -> CodeGenFunction r cc) -> (va -> vb -> CodeGenFunction r vc)
-- | If the target vector type is a native type then the chop operation
-- produces no actual machine instruction. (nop) If the vector cannot be
-- evenly divided into chunks the last chunk will be padded with
-- undefined values.
chop :: (C c, C v, Element c ~ Element v) => v -> [CodeGenFunction r c]
-- | The target size is determined by the type. If the chunk list provides
-- more data, the exceeding data is dropped. If the chunk list provides
-- too few data, the target vector is filled with undefined elements.
concat :: (C c, C v, Element c ~ Element v) => [c] -> CodeGenFunction r v
-- | LLVM.select on boolean vectors cannot be translated to X86 code in
-- LLVM-2.6, thus I code my own version that calls select on all
-- elements. This is slow but works. When this issue is fixed, this
-- function will be replaced by LLVM.select.
select :: (IsFirstClass a, IsPrimitive a, PositiveT n, CmpRet a, CmpResult a ~ Bool) => Value (Vector n Bool) -> Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a))
signedFraction :: (IsFloating a, IsConst a, Real a, PositiveT n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a))
-- | Needs (log n) vector additions
cumulate1 :: (IsArithmetic a, IsPrimitive a, PositiveT n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a))
umul32to64 :: PositiveT n => Value (Vector n Word32) -> Value (Vector n Word32) -> CodeGenFunction r (Value (Vector n Word64))
-- | The order of addition is chosen for maximum efficiency. We do not try
-- to prevent cancelations.
class (IsArithmetic a, IsPrimitive a) => Arithmetic a where sum = sumGeneric sumToPair = sumToPairGeneric sumInterleavedToPair v = getLowestPair =<< reduceSumInterleaved 2 v cumulate = cumulateGeneric dotProduct x y = dotProductPartial (size x) x y mul = mul
sum :: (Arithmetic a, PositiveT n) => Value (Vector n a) -> CodeGenFunction r (Value a)
sumToPair :: (Arithmetic a, PositiveT n) => Value (Vector n a) -> CodeGenFunction r (Value a, Value a)
sumInterleavedToPair :: (Arithmetic a, PositiveT n) => Value (Vector n a) -> CodeGenFunction r (Value a, Value a)
cumulate :: (Arithmetic a, PositiveT n) => Value a -> Value (Vector n a) -> CodeGenFunction r (Value a, Value (Vector n a))
dotProduct :: (Arithmetic a, PositiveT n) => Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value a)
mul :: (Arithmetic a, PositiveT n) => Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a))
-- | Attention: The rounding and fraction functions only work for floating
-- point values with maximum magnitude of maxBound :: Int32.
-- This way we safe expensive handling of possibly seldom cases.
class (Arithmetic a, CmpRet a, CmpResult a ~ Bool, IsConst a) => Real a
min, max :: (Real a, PositiveT n) => Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a))
abs :: (Real a, PositiveT n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a))
signum :: (Real a, PositiveT n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a))
truncate, fraction, floor :: (Real a, PositiveT n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a))
instance Real Word64
instance Real Word32
instance Real Word16
instance Real Word8
instance Real Int64
instance Real Int32
instance Real Int16
instance Real Int8
instance Real Double
instance Real Float
instance Arithmetic Word32
instance Arithmetic Word64
instance Arithmetic Word16
instance Arithmetic Word8
instance Arithmetic Int64
instance Arithmetic Int32
instance Arithmetic Int16
instance Arithmetic Int8
instance Arithmetic Double
instance Arithmetic Float
instance Maskable Double
instance Maskable Float
instance Maskable Word64
instance Maskable Word32
instance Maskable Word16
instance Maskable Word8
instance Maskable Int64
instance Maskable Int32
instance Maskable Int16
instance Maskable Int8
instance (Canonical n a0, Canonical n a1, Canonical n a2) => Canonical n (a0, a1, a2)
instance (Canonical n a0, Canonical n a1) => Canonical n (a0, a1)
instance (PositiveT n, IsPrimitive a) => Canonical n (Value a)
instance (PositiveT n, Phi a, Undefined a) => Simple (Constant n a)
instance Undefined a => Undefined (Constant n a)
instance Phi a => Phi (Constant n a)
instance Traversable (Constant n)
instance Foldable (Constant n)
instance Applicative (Constant n)
instance Functor (Constant n)
instance (C v0, C v1, C v2, Size v0 ~ Size v1, Size v1 ~ Size v2) => C (v0, v1, v2)
instance (Simple v0, Simple v1, Simple v2, Size v0 ~ Size v1, Size v1 ~ Size v2) => Simple (v0, v1, v2)
instance (C v0, C v1, Size v0 ~ Size v1) => C (v0, v1)
instance (Simple v0, Simple v1, Size v0 ~ Size v1) => Simple (v0, v1)
instance (PositiveT n, IsPrimitive a) => C (Value (Vector n a))
instance (PositiveT n, IsPrimitive a) => Simple (Value (Vector n a))
-- | Support for unified handling of scalars and vectors.
--
-- Attention: The rounding and fraction functions only work for floating
-- point values with maximum magnitude of maxBound :: Int32.
-- This way we save expensive handling of possibly seldom cases.
module LLVM.Extra.ScalarOrVector
class (Real a, IsFloating a) => Fraction a
truncate :: Fraction a => Value a -> CodeGenFunction r (Value a)
fraction :: Fraction a => Value a -> CodeGenFunction r (Value a)
-- | The fraction has the same sign as the argument. This is not particular
-- useful but fast on IEEE implementations.
signedFraction :: Fraction a => Value a -> CodeGenFunction r (Value a)
-- | increment (first operand) may be negative, phase must always be
-- non-negative
addToPhase :: Fraction a => Value a -> Value a -> CodeGenFunction r (Value a)
-- | both increment and phase must be non-negative
incPhase :: Fraction a => Value a -> Value a -> CodeGenFunction r (Value a)
class Replicate vector
replicate :: Replicate vector => Value (Scalar vector) -> CodeGenFunction r (Value vector)
replicateConst :: Replicate vector => ConstValue (Scalar vector) -> ConstValue vector
replicateOf :: (IsConst (Scalar v), Replicate v) => Scalar v -> Value v
class IsArithmetic a => Real a
min :: Real a => Value a -> Value a -> CodeGenFunction r (Value a)
max :: Real a => Value a -> Value a -> CodeGenFunction r (Value a)
abs :: Real a => Value a -> CodeGenFunction r (Value a)
signum :: Real a => Value a -> CodeGenFunction r (Value a)
class (IsArithmetic (Scalar v), IsArithmetic v) => PseudoModule v
scale :: (PseudoModule v, a ~ Scalar v) => Value a -> Value v -> CodeGenFunction r (Value v)
scaleConst :: (PseudoModule v, a ~ Scalar v) => ConstValue a -> ConstValue v -> CodeGenFunction r (ConstValue v)
class IsConst a => IntegerConstant a
constFromInteger :: IntegerConstant a => Integer -> ConstValue a
class IntegerConstant a => RationalConstant a
constFromRational :: RationalConstant a => Rational -> ConstValue a
class RationalConstant a => TranscendentalConstant a
constPi :: TranscendentalConstant a => ConstValue a
instance (TranscendentalConstant a, IsPrimitive a, PositiveT n) => TranscendentalConstant (Vector n a)
instance TranscendentalConstant Double
instance TranscendentalConstant Float
instance (RationalConstant a, IsPrimitive a, PositiveT n) => RationalConstant (Vector n a)
instance RationalConstant Double
instance RationalConstant Float
instance (IntegerConstant a, IsPrimitive a, PositiveT n) => IntegerConstant (Vector n a)
instance IntegerConstant Double
instance IntegerConstant Float
instance IntegerConstant Int64
instance IntegerConstant Int32
instance IntegerConstant Int16
instance IntegerConstant Int8
instance IntegerConstant Word64
instance IntegerConstant Word32
instance IntegerConstant Word16
instance IntegerConstant Word8
instance (IsArithmetic a, IsPrimitive a, PositiveT n) => PseudoModule (Vector n a)
instance PseudoModule Double
instance PseudoModule Float
instance PseudoModule Int64
instance PseudoModule Int32
instance PseudoModule Int16
instance PseudoModule Int8
instance PseudoModule Word64
instance PseudoModule Word32
instance PseudoModule Word16
instance PseudoModule Word8
instance (PositiveT n, Real a) => Real (Vector n a)
instance Real Word64
instance Real Word32
instance Real Word16
instance Real Word8
instance Real Int64
instance Real Int32
instance Real Int16
instance Real Int8
instance Real FP128
instance Real Double
instance Real Float
instance (PositiveT n, IsPrimitive a) => Replicate (Vector n a)
instance Replicate Word64
instance Replicate Word32
instance Replicate Word16
instance Replicate Word8
instance Replicate Int64
instance Replicate Int32
instance Replicate Int16
instance Replicate Int8
instance Replicate Bool
instance Replicate FP128
instance Replicate Double
instance Replicate Float
instance (PositiveT n, Real a, IsFloating a, IsConst a) => Fraction (Vector n a)
instance Fraction Double
instance Fraction Float
module LLVM.Extra.Memory
-- | An implementation of both MakeValueTuple and 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 must be the same as accessing haskellValue by
-- Storable methods. ToDo: In future we may also require
-- Storable constraint for llvmStruct.
--
-- We use a functional dependency in order to let type inference work
-- nicely.
class (Phi llvmValue, Undefined llvmValue, IsType (Struct llvmValue), IsSized (Struct llvmValue)) => C llvmValue where type family Struct llvmValue :: * load ptr = decompose =<< load ptr store r ptr = flip store ptr =<< compose r
load :: C llvmValue => Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue
store :: C llvmValue => llvmValue -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()
decompose :: C llvmValue => Value (Struct llvmValue) -> CodeGenFunction r llvmValue
compose :: C llvmValue => llvmValue -> CodeGenFunction r (Value (Struct llvmValue))
modify :: C llvmValue => (llvmValue -> CodeGenFunction r llvmValue) -> Value (Ptr (Struct llvmValue)) -> CodeGenFunction r ()
castStorablePtr :: (MakeValueTuple haskellValue, C (ValueTuple haskellValue)) => Ptr haskellValue -> Ptr (Struct (ValueTuple haskellValue))
type Record r o v = Element r o v v
data Element r o v x
element :: (C x, GetValue o n, ValueType o n ~ Struct x, GetElementPtr o (n, ()), ElementPtrType o (n, ()) ~ Struct x) => (v -> x) -> n -> Element r o v x
loadRecord :: Record r o llvmValue -> Value (Ptr o) -> CodeGenFunction r llvmValue
storeRecord :: Record r o llvmValue -> llvmValue -> Value (Ptr o) -> CodeGenFunction r ()
decomposeRecord :: Record r o llvmValue -> Value o -> CodeGenFunction r llvmValue
composeRecord :: IsType o => Record r o llvmValue -> llvmValue -> CodeGenFunction r (Value o)
loadNewtype :: C a => (a -> llvmValue) -> Value (Ptr (Struct a)) -> CodeGenFunction r llvmValue
storeNewtype :: C a => (llvmValue -> a) -> llvmValue -> Value (Ptr (Struct a)) -> CodeGenFunction r ()
decomposeNewtype :: C a => (a -> llvmValue) -> Value (Struct a) -> CodeGenFunction r llvmValue
composeNewtype :: C a => (llvmValue -> a) -> llvmValue -> CodeGenFunction r (Value (Struct a))
class (IsFirstClass llvmType, IsType (Stored llvmType)) => FirstClass llvmType where type family Stored llvmType :: *
instance C ()
instance (FirstClass a, IsSized (Stored a)) => C (Value a)
instance (sm ~ StoredStruct s, IsType (Struct s), IsType (Struct sm)) => ConvertStruct s i ()
instance (sm ~ StoredStruct s, GetValue (Struct s) i, ValueType (Struct s) i ~ a, GetValue (Struct sm) i, ValueType (Struct sm) i ~ am, FirstClass a, am ~ Stored a, ConvertStruct s (Succ i) rem) => ConvertStruct s i (a, rem)
instance (IsFirstClass (Struct s), IsType (Struct (StoredStruct s)), ConvertStruct s D0 s) => FirstClass (Struct s)
instance FirstClass (StablePtr a)
instance IsType a => FirstClass (Ptr a)
instance (NaturalT n, IsFirstClass (Stored a), FirstClass a, IsSized a, IsSized (Stored a)) => FirstClass (Array n a)
instance (PositiveT n, IsPrimitive a, IsPrimitive (Stored a), FirstClass a) => FirstClass (Vector n a)
instance FirstClass Bool
instance FirstClass Word64
instance FirstClass Word32
instance FirstClass Word16
instance FirstClass Word8
instance FirstClass Int64
instance FirstClass Int32
instance FirstClass Int16
instance FirstClass Int8
instance FirstClass Double
instance FirstClass Float
instance (C a, C b) => C (T a b)
instance C a => C (T a)
instance (C a, C b, C c) => C (a, b, c)
instance (C a, C b) => C (a, b)
instance Applicative (Element r o v)
instance Functor (Element r o v)
module LLVM.Extra.ForeignPtr
newInit :: FunPtr (Ptr a -> IO ()) -> FunPtr (IO (Ptr a)) -> IO (ForeignPtr a)
newParam :: (Storable b, MakeValueTuple b, C (ValueTuple b)) => FunPtr (Ptr a -> IO ()) -> FunPtr (Ptr (Struct (ValueTuple b)) -> IO (Ptr a)) -> b -> IO (ForeignPtr a)
-- | Adding the finalizer to a ForeignPtr seems to be the only way that
-- warrants execution of the finalizer (not too early and not never).
-- However, the normal ForeignPtr finalizers must be independent from
-- Haskell runtime. In contrast to ForeignPtr finalizers, addFinalizer
-- adds finalizers to boxes, that are optimized away. Thus finalizers are
-- run too early or not at all. Concurrent.ForeignPtr and using threaded
-- execution is the only way to get finalizers in Haskell IO.
new :: Storable a => IO () -> a -> IO (ForeignPtr a)
with :: (Storable a, MakeValueTuple a, C (ValueTuple a)) => ForeignPtr a -> (Ptr (Struct (ValueTuple a)) -> IO b) -> IO b
module LLVM.Extra.Multi.Vector
newtype T n a
Cons :: (Vector n a) -> T n a
size :: PositiveT n => T n a -> Int
zip :: T n a -> T n b -> T n (a, b)
zip3 :: T n a -> T n b -> T n c -> T n (a, b, c)
unzip :: T n (a, b) -> (T n a, T n b)
unzip3 :: T n (a, b, c) -> (T n a, T n b, T n c)
class C a where type family Vector n a :: *
undef :: (C a, PositiveT n) => T n a
shuffleMatch :: (C a, PositiveT n) => ConstValue (Vector n Word32) -> T n a -> CodeGenFunction r (T n a)
extract :: (C a, PositiveT n) => Value Word32 -> T n a -> CodeGenFunction r (T a)
insert :: (C a, PositiveT n) => Value Word32 -> T a -> T n a -> CodeGenFunction r (T n a)
undefPrimitive :: (PositiveT n, IsPrimitive a, Vector n a ~ Value (Vector n a)) => T n a
shuffleMatchPrimitive :: (PositiveT n, IsPrimitive a, Vector n a ~ Value (Vector n a), ValueTuple a ~ Value a) => ConstValue (Vector n Word32) -> T n a -> CodeGenFunction r (T n a)
extractPrimitive :: (PositiveT n, IsPrimitive a, Vector n a ~ Value (Vector n a), ValueTuple a ~ Value a) => Value Word32 -> T n a -> CodeGenFunction r (T a)
insertPrimitive :: (PositiveT n, IsPrimitive a, Vector n a ~ Value (Vector n a), ValueTuple a ~ Value a) => Value Word32 -> T a -> T n a -> CodeGenFunction r (T n a)
assemble :: (PositiveT n, C a) => [T a] -> CodeGenFunction r (T n a)
dissect :: (PositiveT n, C a) => T n a -> CodeGenFunction r [T a]
shuffleMatchGen :: (Vector n a ~ v, Simple v, n ~ Size v) => ConstValue (Vector n Word32) -> T n a -> CodeGenFunction r (T n a)
extractGen :: (Vector n a ~ v, Simple v, ValueTuple a ~ Element v) => Value Word32 -> T n a -> CodeGenFunction r (T a)
insertGen :: (Vector n a ~ v, C v, ValueTuple a ~ Element v) => Value Word32 -> T a -> T n a -> CodeGenFunction r (T n a)
instance (C a, C b, C c) => C (a, b, c)
instance (C a, C b) => C (a, b)
instance C Double
instance C Float
instance (PositiveT n, C a) => Undefined (T n a)
module LLVM.Extra.Arithmetic
-- | This and the following type classes are intended for arithmetic
-- operations on wrappers around LLVM types. E.g. you might define a
-- fixed point fraction type by
--
--
-- newtype Fixed = Fixed Int32
--
--
-- and then use the same methods for floating point and fixed point
-- arithmetic.
--
-- In contrast to the arithmetic methods in the llvm wrapper, in
-- our methods the types of operands and result match. Advantage: Type
-- inference determines most of the types automatically. Disadvantage:
-- You cannot use constant values directly, but you have to convert them
-- all to Value.
class Zero a => Additive a
zero :: Additive a => a
add :: Additive a => a -> a -> CodeGenFunction r a
sub :: Additive a => a -> a -> CodeGenFunction r a
neg :: Additive a => a -> CodeGenFunction r a
one :: IntegerConstant a => a
inc :: (IsArithmetic a, IsConst a, Num a) => Value a -> CodeGenFunction r (Value a)
dec :: (IsArithmetic a, IsConst a, Num a) => Value a -> CodeGenFunction r (Value a)
class Additive a => PseudoRing a
mul :: PseudoRing a => a -> a -> CodeGenFunction r a
square :: PseudoRing a => a -> CodeGenFunction r a
class (PseudoRing (Scalar v), Additive v) => PseudoModule v
scale :: PseudoModule v => Scalar v -> v -> CodeGenFunction r v
class PseudoRing a => Field a
fdiv :: Field a => a -> a -> CodeGenFunction r a
class IntegerConstant a
fromInteger' :: IntegerConstant a => Integer -> a
class IntegerConstant a => RationalConstant a
fromRational' :: RationalConstant a => Rational -> a
idiv :: IsInteger a => Value a -> Value a -> CodeGenFunction r (Value a)
irem :: IsInteger a => Value a -> Value a -> CodeGenFunction r (Value a)
fcmp :: (IsFloating a, CmpRet a, CmpResult a ~ b) => FPPredicate -> Value a -> Value a -> CodeGenFunction r (Value b)
cmp :: (CmpRet a, CmpResult a ~ b) => CmpPredicate -> Value a -> Value a -> CodeGenFunction r (Value b)
data CmpPredicate :: *
-- | equal
CmpEQ :: CmpPredicate
-- | not equal
CmpNE :: CmpPredicate
-- | greater than
CmpGT :: CmpPredicate
-- | greater or equal
CmpGE :: CmpPredicate
-- | less than
CmpLT :: CmpPredicate
-- | less or equal
CmpLE :: CmpPredicate
and :: IsInteger a => Value a -> Value a -> CodeGenFunction r (Value a)
or :: IsInteger a => Value a -> Value a -> CodeGenFunction r (Value a)
class Additive a => Real a
min :: Real a => a -> a -> CodeGenFunction r a
max :: Real a => a -> a -> CodeGenFunction r a
abs :: Real a => a -> CodeGenFunction r a
signum :: Real a => a -> CodeGenFunction r a
class Real a => Fraction a
truncate :: Fraction a => a -> CodeGenFunction r a
fraction :: Fraction a => a -> CodeGenFunction r a
signedFraction :: Fraction a => a -> CodeGenFunction r a
addToPhase :: Fraction a => a -> a -> CodeGenFunction r a
-- | both increment and phase must be non-negative
incPhase :: Fraction a => a -> a -> CodeGenFunction r a
advanceArrayElementPtr :: Value (Ptr a) -> CodeGenFunction r (Value (Ptr a))
class Field a => Algebraic a
sqrt :: Algebraic a => a -> CodeGenFunction r a
class Algebraic a => Transcendental a
pi :: Transcendental a => CodeGenFunction r a
sin, log, exp, cos :: Transcendental a => a -> CodeGenFunction r a
pow :: Transcendental a => a -> a -> CodeGenFunction r a
instance (IsFloating a, TranscendentalConstant a) => Transcendental (Value a)
instance IsFloating a => Algebraic (Value a)
instance Fraction a => Fraction (Value a)
instance Real a => Real (Value a)
instance RationalConstant a => RationalConstant (Value a)
instance RationalConstant a => RationalConstant (ConstValue a)
instance IsFloating v => Field (ConstValue v)
instance IsFloating v => Field (Value v)
instance IntegerConstant a => IntegerConstant (Value a)
instance IntegerConstant a => IntegerConstant (ConstValue a)
instance PseudoModule v => PseudoModule (ConstValue v)
instance PseudoModule v => PseudoModule (Value v)
instance IsArithmetic v => PseudoRing (ConstValue v)
instance IsArithmetic v => PseudoRing (Value v)
instance (Additive a, Additive b, Additive c) => Additive (a, b, c)
instance (Additive a, Additive b) => Additive (a, b)
instance IsArithmetic a => Additive (ConstValue a)
instance IsArithmetic a => Additive (Value a)
-- | Maybe transformer datatype implemented in continuation passing style.
module LLVM.Extra.MaybeContinuation
-- | Isomorphic to ReaderT (CodeGenFunction r z) (ContT z
-- (CodeGenFunction r)) a, where the reader provides the block for
-- Nothing and the continuation part manages the Just.
newtype T r z a
Cons :: (CodeGenFunction r z -> (a -> CodeGenFunction r z) -> CodeGenFunction r z) -> T r z a
resolve :: T r z a -> CodeGenFunction r z -> (a -> CodeGenFunction r z) -> CodeGenFunction r z
map :: (a -> CodeGenFunction r b) -> T r z a -> T r z b
-- | counterpart to Data.Maybe.HT.toMaybe
withBool :: Phi z => Value Bool -> CodeGenFunction r a -> T r z a
fromBool :: Phi z => CodeGenFunction r (Value Bool, a) -> T r z a
toBool :: Undefined a => T r (Value Bool, a) a -> CodeGenFunction r (Value Bool, a)
fromMaybe :: Phi z => CodeGenFunction r (T a) -> T r z a
toMaybe :: Undefined a => T r (T a) a -> CodeGenFunction r (T a)
isJust :: T r (Value Bool) a -> CodeGenFunction r (Value Bool)
lift :: CodeGenFunction r a -> T r z a
guard :: Phi z => Value Bool -> T r z ()
bind :: T r z a -> (a -> T r z b) -> T r z b
-- | Run an exception handler if the Maybe-action fails. The exception is
-- propagated. That is, the handler is intended for a cleanup procedure.
onFail :: CodeGenFunction r () -> T r z a -> T r z a
-- | Run the first action and if that fails run the second action. If both
-- actions fail, then the composed action fails, too.
alternative :: (Phi z, Undefined a) => T r (T a) a -> T r (T a) a -> T r z a
fixedLengthLoop :: (Phi s, Undefined s, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i, CmpResult i ~ Bool) => Value i -> s -> (s -> T r (T s) s) -> CodeGenFunction r (Value i, T s)
-- | If the returned position is smaller than the array size, then returned
-- final state is nothing.
arrayLoop :: (Phi s, Undefined s, IsType a, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i, CmpResult i ~ Bool) => Value i -> Value (Ptr a) -> s -> (Value (Ptr a) -> s -> T r (T (Value (Ptr a), s)) s) -> CodeGenFunction r (Value i, T s)
arrayLoop2 :: (Phi s, Undefined s, IsType a, IsType b, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i, CmpResult i ~ Bool) => Value i -> Value (Ptr a) -> Value (Ptr b) -> s -> (Value (Ptr a) -> Value (Ptr b) -> s -> T r (T (Value (Ptr a), (Value (Ptr b), s))) s) -> CodeGenFunction r (Value i, T s)
instance MonadIO (T r z)
instance Monad (T r z)
instance Applicative (T r z)
instance Functor (T r z)
module LLVM.Extra.Scalar
-- | The entire purpose of this datatype is to mark a type as scalar,
-- although it might also be interpreted as vector. This way you can
-- write generic operations for vectors using the PseudoModule
-- class, and specialise them to scalar types with respect to the
-- PseudoRing class. From another perspective you can consider the
-- T type constructor a marker where the Scalar type
-- function stops reducing nested vector types to scalar types.
newtype T a
Cons :: a -> T a
decons :: T a -> a
liftM :: Monad m => (a -> m b) -> T a -> m (T b)
liftM2 :: Monad m => (a -> b -> m c) -> T a -> T b -> m (T c)
unliftM :: Monad m => (T a -> m (T r)) -> a -> m r
unliftM2 :: Monad m => (T a -> T b -> m (T r)) -> a -> b -> m r
unliftM3 :: Monad m => (T a -> T b -> T c -> m (T r)) -> a -> b -> c -> m r
unliftM4 :: Monad m => (T a -> T b -> T c -> T d -> m (T r)) -> a -> b -> c -> d -> m r
unliftM5 :: Monad m => (T a -> T b -> T c -> T d -> T e -> m (T r)) -> a -> b -> c -> d -> e -> m r
instance Transcendental a => Transcendental (T a)
instance Algebraic a => Algebraic (T a)
instance Fraction a => Fraction (T a)
instance Real a => Real (T a)
instance PseudoRing a => PseudoModule (T a)
instance Field a => Field (T a)
instance PseudoRing a => PseudoRing (T a)
instance Additive a => Additive (T a)
instance RationalConstant a => RationalConstant (T a)
instance IntegerConstant a => IntegerConstant (T a)
instance Zero a => Zero (T a)
module LLVM.Extra.Multi.Class
class C value where type family Size value :: *
switch :: C value => f T -> f (T (Size value)) -> f value
newtype Undef a value
Undef :: value a -> Undef a value
getUndef :: Undef a value -> value a
undef :: (C value, Size value ~ n, PositiveT n, MakeValueTuple a, C a) => value a
newtype Add r a value
Add :: (value a -> value a -> CodeGenFunction r (value a)) -> Add r a value
runAdd :: Add r a value -> value a -> value a -> CodeGenFunction r (value a)
add :: (C value, Additive al, al ~ ValueTuple a, Additive vl, vl ~ Vector n a, n ~ Size value) => value a -> value a -> CodeGenFunction r (value a)
instance PositiveT n => C (T n)
instance C T