module Feldspar.Core.Interpretation
( module Language.Syntactic.Constructs.Decoration
, module Feldspar.Core.Interpretation.Typed
, targetSpecialization
, Sharable (..)
, SizeProp (..)
, sizePropDefault
, resultType
, SourceInfo
, Info (..)
, mkInfo
, mkInfoTy
, infoRange
, LatticeSize1 (..)
, viewLiteral
, literal
, literalDecor
, constFold
, SomeInfo (..)
, SomeType (..)
, Env (..)
, FeldOpts (..)
, Target (..)
, inTarget
, defaultFeldOpts
, localVar
, localSource
, Opt
, Optimize (..)
, OptimizeSuper
, constructFeat
, optimizeM
, optimize
, constructFeatUnOptDefaultTyp
, constructFeatUnOptDefault
, optimizeFeatDefault
, prjF
, c'
, Monotonic (..)
, viewMonotonicInc
, viewMonotonicDec
) where
import Control.Monad.Reader
import Data.Map as Map
import Data.Typeable (Typeable)
import Language.Syntactic
import Language.Syntactic.Constructs.Decoration
import Language.Syntactic.Constructs.Literal
import Language.Syntactic.Constructs.Binding
import Feldspar.Lattice
import Feldspar.Core.Types
import Feldspar.Core.Interpretation.Typed
targetSpecialization :: BitWidth n -> ASTF dom a -> ASTF dom a
targetSpecialization _ = id
class Sharable dom
where
sharable :: dom a -> Bool
sharable _ = True
hoistOver :: dom a -> Bool
hoistOver _ = True
instance (Sharable sub1, Sharable sub2) => Sharable (sub1 :+: sub2)
where
sharable (InjL a) = sharable a
sharable (InjR a) = sharable a
hoistOver (InjL a) = hoistOver a
hoistOver (InjR a) = hoistOver a
instance Sharable sym => Sharable (sym :|| pred)
where
sharable (C' s) = sharable s
hoistOver (C' s) = hoistOver s
instance Sharable sym => Sharable (SubConstr2 c sym p1 p2)
where
sharable (SubConstr2 s) = sharable s
hoistOver (SubConstr2 s) = hoistOver s
instance Sharable dom => Sharable (Decor Info dom)
where
sharable = sharable . decorExpr
hoistOver = hoistOver . decorExpr
instance Sharable Empty
class SizeProp feature
where
sizeProp :: feature a -> Args (WrapFull Info) a -> Size (DenResult a)
sizePropDefault :: (Type (DenResult a))
=> feature a -> Args (WrapFull Info) a -> Size (DenResult a)
sizePropDefault _ _ = universal
resultType :: Type (DenResult a) => c a -> TypeRep (DenResult a)
resultType _ = typeRep
data SomeType
where
SomeType :: TypeRep a -> SomeType
type VarInfo = Map VarId SomeType
type SourceInfo = String
data Info a
where
Info
:: (Show (Size a), Lattice (Size a))
=> { infoType :: TypeRep a
, infoSize :: Size a
, infoVars :: VarInfo
, infoSource :: SourceInfo
}
-> Info a
instance Show (Info a)
where
show i@(Info {}) = show (infoType i) ++ szStr ++ srcStr
where
szStr = case show (infoSize i) of
"AnySize" -> ""
str -> " | " ++ str
srcStr = case infoSource i of
"" -> ""
src -> " | " ++ src
mkInfo :: Type a => Size a -> Info a
mkInfo sz = Info typeRep sz Map.empty ""
mkInfoTy :: (Show (Size a), Lattice (Size a)) => TypeRep a -> Info a
mkInfoTy t = Info t universal Map.empty ""
infoRange :: Type a => Info a -> RangeSet a
infoRange = sizeToRange . infoSize
class LatticeSize1 m
where
mergeSize :: Lattice (Size a) =>
Info (m a) -> Size (m a) -> Size (m a) -> Size (m a)
instance LatticeSize1 Mut
where
mergeSize _ = (\/)
data SomeInfo
where
SomeInfo :: Typeable a => Info a -> SomeInfo
data Env = Env
{ varEnv :: [(VarId, SomeInfo)]
, sourceEnv :: SourceInfo
}
data Target = RegionInf | SICS
deriving Eq
data FeldOpts = FeldOpts
{ targets :: [Target]
}
defaultFeldOpts :: FeldOpts
defaultFeldOpts = FeldOpts { targets = [] }
inTarget :: Target -> FeldOpts -> Bool
inTarget t opts = t `elem` (targets opts)
initEnv :: Env
initEnv = Env [] ""
localVar :: Typeable b => VarId -> Info b -> Opt a -> Opt a
localVar v info = local $ \env -> env {varEnv = (v, SomeInfo info):varEnv env}
localSource :: SourceInfo -> Opt a -> Opt a
localSource src = local $ \env -> env {sourceEnv = src}
viewLiteral :: forall info dom a. ((Literal :|| Type) :<: dom)
=> ASTF (Decor info (dom :|| Typeable)) a -> Maybe a
viewLiteral (prjF -> Just (C' (Literal a))) = Just a
viewLiteral _ = Nothing
prjF :: Project (sub :|| Type) sup => sup sig -> Maybe ((sub :|| Type) sig)
prjF = prj
literal :: (Type a, (Literal :|| Type) :<: dom) =>
a -> ASTF (dom :|| Typeable) a
literal a = Sym $ C' $ inj $ c' $ Literal a
literalDecorSrc :: (Type a, (Literal :|| Type) :<: dom) =>
SourceInfo -> a -> ASTF (Decor Info (dom :|| Typeable)) a
literalDecorSrc src a = Sym $ Decor
((mkInfo (sizeOf a)) {infoSource = src})
(C' $ inj $ c' $ Literal a)
c' :: (Type (DenResult sig)) => feature sig -> (feature :|| Type) sig
c' = C'
literalDecor :: (Type a, (Literal :|| Type) :<: dom) =>
a -> ASTF (Decor Info (dom :|| Typeable)) a
literalDecor = literalDecorSrc ""
constFold :: (Typed dom, (Literal :|| Type) :<: dom)
=> SourceInfo -> ASTF (Decor Info (dom :|| Typeable)) a
-> a
-> ASTF (Decor Info (dom :|| Typeable)) a
constFold src expr a
| Just Dict <- typeDict expr
= literalDecorSrc src a
constFold _ expr _ = expr
type Opt = Reader Env
class Optimize feature dom
where
optimizeFeat
:: ( Typeable (DenResult a)
, OptimizeSuper dom
)
=> FeldOpts -> feature a
-> Args (AST (dom :|| Typeable)) a
-> Opt (ASTF (Decor Info (dom :|| Typeable)) (DenResult a))
optimizeFeat = optimizeFeatDefault
constructFeatOpt
:: ( Typeable (DenResult a))
=> FeldOpts -> feature a
-> Args (AST (Decor Info (dom :|| Typeable))) a
-> Opt (ASTF (Decor Info (dom :|| Typeable)) (DenResult a))
constructFeatOpt = constructFeatUnOpt
constructFeatUnOpt
:: ( Typeable (DenResult a))
=> FeldOpts -> feature a
-> Args (AST (Decor Info (dom :|| Typeable))) a
-> Opt (ASTF (Decor Info (dom :|| Typeable)) (DenResult a))
instance Optimize Empty dom
where
constructFeatUnOpt = error "Not implemented: constructFeatUnOpt for Empty"
class
( AlphaEq dom dom (dom :|| Typeable) [(VarId, VarId)]
, AlphaEq dom dom (Decor Info (dom :|| Typeable)) [(VarId, VarId)]
, EvalBind dom
, (Literal :|| Type) :<: dom
, Typed dom
, Render dom
, Constrained dom
, Optimize dom dom
) =>
OptimizeSuper dom
instance
( AlphaEq dom dom (dom :|| Typeable) [(VarId, VarId)]
, AlphaEq dom dom (Decor Info (dom :|| Typeable)) [(VarId, VarId)]
, EvalBind dom
, (Literal :|| Type) :<: dom
, Typed dom
, Render dom
, Constrained dom
, Optimize dom dom
) =>
OptimizeSuper dom
constructFeat :: ( Typeable (DenResult a)
, Optimize feature dom)
=> FeldOpts -> feature a
-> Args (AST (Decor Info (dom :|| Typeable))) a
-> Opt (ASTF (Decor Info (dom :|| Typeable)) (DenResult a))
constructFeat opts a args = do
aUnOpt <- constructFeatUnOpt opts a args
aOpt <- constructFeatOpt opts a args
return $ updateDecor
(\info -> info {infoSize = infoSize (getInfo aUnOpt)})
aOpt
instance
( Optimize sub1 dom
, Optimize sub2 dom
) =>
Optimize (sub1 :+: sub2) dom
where
optimizeFeat opts (InjL a) = optimizeFeat opts a
optimizeFeat opts (InjR a) = optimizeFeat opts a
constructFeatOpt opts (InjL a) = constructFeatOpt opts a
constructFeatOpt opts (InjR a) = constructFeatOpt opts a
constructFeatUnOpt opts (InjL a) = constructFeatUnOpt opts a
constructFeatUnOpt opts (InjR a) = constructFeatUnOpt opts a
optimizeM :: (OptimizeSuper dom)
=> FeldOpts -> ASTF (dom :|| Typeable) a -> Opt (ASTF (Decor Info (dom :|| Typeable)) a)
optimizeM opts a
| Dict <- exprDict a
= do
aOpt <- matchTrans (\(C' x) -> optimizeFeat opts x) a
let vars = infoVars $ getInfo aOpt
value = evalBind aOpt
src = infoSource $ getInfo aOpt
if Map.null vars
then return $ constFold src aOpt value
else return aOpt
optimize :: ( Typeable a
, OptimizeSuper dom
)
=> FeldOpts -> ASTF (dom :|| Typeable) a -> ASTF (Decor Info (dom :|| Typeable)) a
optimize opts = flip runReader initEnv . optimizeM opts
constructFeatUnOptDefaultTyp
:: ( feature :<: dom
, SizeProp feature
, Typeable (DenResult a)
, Show (Size (DenResult a))
, Lattice (Size (DenResult a))
)
=> FeldOpts -> TypeRep (DenResult a)
-> feature a
-> Args (AST (Decor Info (dom :|| Typeable))) a
-> Opt (ASTF (Decor Info (dom :|| Typeable)) (DenResult a))
constructFeatUnOptDefaultTyp _ typ feat args
= do
src <- asks sourceEnv
let sz = sizeProp feat $ mapArgs (WrapFull . getInfo) args
vars = Map.unions $ listArgs (infoVars . getInfo) args
return $ appArgs (Sym $ Decor (Info typ sz vars src) $ C' $ inj feat) args
constructFeatUnOptDefault
:: ( feature :<: dom
, SizeProp feature
, Type (DenResult a)
)
=> FeldOpts -> feature a
-> Args (AST (Decor Info (dom :|| Typeable))) a
-> Opt (ASTF (Decor Info (dom :|| Typeable)) (DenResult a))
constructFeatUnOptDefault _ feat args
= do
src <- asks sourceEnv
let sz = sizeProp feat $ mapArgs (WrapFull . getInfo) args
vars = Map.unions $ listArgs (infoVars . getInfo) args
return $ appArgs (Sym $ Decor (Info typeRep sz vars src) $ C' $ inj feat) args
optimizeFeatDefault
:: ( Optimize feature dom
, Typeable (DenResult a)
, OptimizeSuper dom
)
=> FeldOpts -> feature a
-> Args (AST (dom :|| Typeable)) a
-> Opt (ASTF (Decor Info (dom :|| Typeable)) (DenResult a))
optimizeFeatDefault opts feat args
= constructFeat opts feat =<< mapArgsM (optimizeM opts) args
class Monotonic feature where
monotonicInc :: feature a
-> Args (AST (Decor Info (dom :|| Typeable))) a
-> [ASTF (Decor Info (dom :|| Typeable)) (DenResult a)]
monotonicInc _ _ = []
monotonicDec :: feature a
-> Args (AST (Decor Info (dom :|| Typeable))) a
-> [ASTF (Decor Info (dom :|| Typeable)) (DenResult a)]
monotonicDec _ _ = []
instance (Monotonic sub1, Monotonic sub2) => Monotonic (sub1 :+: sub2) where
monotonicInc (InjL a) = monotonicInc a
monotonicInc (InjR a) = monotonicInc a
monotonicDec (InjL a) = monotonicDec a
monotonicDec (InjR a) = monotonicDec a
instance (Monotonic sym) => Monotonic (sym :|| pred) where
monotonicInc (C' s) = monotonicInc s
monotonicDec (C' s) = monotonicDec s
instance (Monotonic sym) => Monotonic (SubConstr2 c sym p1 p2) where
monotonicInc (SubConstr2 s) = monotonicInc s
monotonicDec (SubConstr2 s) = monotonicDec s
instance (Monotonic dom) => Monotonic (Decor Info dom) where
monotonicInc = monotonicInc . decorExpr
monotonicDec = monotonicDec . decorExpr
instance Monotonic Empty
viewMonotonicInc :: (Monotonic dom)
=> ASTF (Decor Info (dom :|| Typeable)) a
-> [ASTF (Decor Info (dom :|| Typeable)) a]
viewMonotonicInc = simpleMatch monotonicInc
viewMonotonicDec :: (Monotonic dom)
=> ASTF (Decor Info (dom :|| Typeable)) a
-> [ASTF (Decor Info (dom :|| Typeable)) a]
viewMonotonicDec = simpleMatch monotonicDec