{-# LANGUAGE CPP #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_HADDOCK hide #-}
module Data.Array.Accelerate.LLVM.CodeGen.Environment
where
import Data.IntMap ( IntMap )
import Data.String
import Text.Printf
import qualified Data.IntMap as IM
import Data.Array.Accelerate.AST ( Idx(..), idxToInt )
import Data.Array.Accelerate.Error ( internalError )
import Data.Array.Accelerate.Array.Sugar ( Array, Shape, Elt )
import Data.Array.Accelerate.LLVM.CodeGen.IR
import LLVM.AST.Type.Name
data Val env where
Empty :: Val ()
Push :: Val env -> IR t -> Val (env, t)
prj :: Idx env t -> Val env -> IR t
prj ZeroIdx (Push _ v) = v
prj (SuccIdx ix) (Push val _) = prj ix val
#if __GLASGOW_HASKELL__ < 800
prj _ _ = $internalError "prj" "inconsistent valuation"
#endif
type Gamma aenv = IntMap (Label, Idx' aenv)
data Idx' aenv where
Idx' :: (Shape sh, Elt e) => Idx aenv (Array sh e) -> Idx' aenv
aprj :: Idx aenv t -> Gamma aenv -> Name t
aprj ix aenv =
case IM.lookup (idxToInt ix) aenv of
Nothing -> $internalError "aprj" "free variable not registered"
Just (Label n,_) -> Name n
makeGamma :: IntMap (Idx' aenv) -> Gamma aenv
makeGamma = snd . IM.mapAccum (\n ix -> (n+1, toAval n ix)) 0
where
toAval :: Int -> Idx' aenv -> (Label, Idx' aenv)
toAval n ix = (fromString (printf "fv%d" n), ix)
freevar :: (Shape sh, Elt e) => Idx aenv (Array sh e) -> IntMap (Idx' aenv)
freevar ix = IM.singleton (idxToInt ix) (Idx' ix)