Safe Haskell  None 

 data T p a
 ($#) :: (T p a > b) > a > b
 get :: T p a > p > a
 valueTuple :: (Value tuple, ValueOf tuple ~ value) => T p tuple > value > value
 multiValue :: C a => T p a > T a > T a
 with :: MV b => (b > T b) > T p b > (forall parameters. MV parameters => (p > parameters) > (T parameters > T b) > a) > a
 withValue :: (C tuple, ValueOf tuple ~ value) => T p tuple > (forall parameters. C parameters => (p > parameters) > (ValueOf parameters > value) > a) > a
 withMulti :: MV b => T p b > (forall parameters. MV parameters => (p > parameters) > (T parameters > T b) > a) > a
 data Tunnel p a = forall t . MV t => Tunnel (p > t) (T t > T a)
 tunnel :: MV a => (a > T a) > T p a > Tunnel p a
 class Tuple tuple where
 withTuple :: (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) => (tuple > f p) > f p
 withTuple1 :: (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) => (tuple > f p a) > f p a
 withTuple2 :: (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) => (tuple > f p a b) > f p a b
 wordInt :: T p Int > T p Word
Documentation
This data type is for parameters of parameterized LLVM code.
It is better than using plain functions of type p > a
since it allows for numeric instances
and we can make explicit,
whether a parameter is constant.
We recommend to use parameters for atomic types.
Although a parameter of type T p (a,b)
is possible,
it means that the whole parameter is variable
if only one of the pair elements is variable.
This way you may miss opportunities for constant folding.
Arrow T 

Category T 

Monad (T p)  
Functor (T p)  Useful for splitting 
Applicative (T p)  Useful for combining 
Floating a => Floating (T p a)  
Fractional a => Fractional (T p a)  
Num a => Num (T p a)  
C a => C (T p a)  
C a => C (T p a)  
C a => C (T p a)  
C a => C (T p a)  
C a => C (T p a)  
Tuple (T p a) 
valueTuple :: (Value tuple, ValueOf tuple ~ value) => T p tuple > value > valueSource
The call value param v
requires
that v
represents the same value as valueTupleOf (get param p)
for some p
.
However v
might be the result of a load operation
and param
might be a constant.
In this case it is more efficient to use valueTupleOf (get param undefined)
since the constant is translated to an LLVM constant
that allows for certain optimizations.
This is the main function for taking advantage of a constant parameter
in lowlevel implementations.
For simplicity we do not omit constant parameters in the parameter struct
since this would mean to construct types at runtime and might become ugly.
Instead we just check using value
at the according places in LLVM code
whether a parameter is constant
and ignore the parameter from the struct in this case.
In many cases there will be no speed benefit
because the parameter will be loaded to a register anyway.
It can only lead to speedup if subsequent optimizations
can precompute constant expressions.
Another example is drop
where a loop with constant loop count can be generated.
For small loop counts and simple loop bodies the loop might get unrolled.
with :: MV b => (b > T b) > T p b > (forall parameters. MV parameters => (p > parameters) > (T parameters > T b) > a) > aSource
withValue :: (C tuple, ValueOf tuple ~ value) => T p tuple > (forall parameters. C parameters => (p > parameters) > (ValueOf parameters > value) > a) > aSource
This function provides specialised variants of get
and value
,
that use the unit type for constants
and thus save space in parameter structures.
withMulti :: MV b => T p b > (forall parameters. MV parameters => (p > parameters) > (T parameters > T b) > a) > aSource
withTuple :: (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) => (tuple > f p) > f pSource
Provide all elements of a nested tuple as separate parameters.
If you do not use one of the tuple elements,
you will get a type error like
Couldn't match type `Param.Composed t0' with
.
The problem is that the type checker cannot infer
that an element is a Int
Parameter.T
if it remains unused.
withTuple1 :: (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) => (tuple > f p a) > f p aSource
withTuple2 :: (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) => (tuple > f p a b) > f p a bSource