packages feed

csound-expression-dynamic 0.0.4 → 0.0.5

raw patch · 4 files changed

+165/−5 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

csound-expression-dynamic.cabal view
@@ -1,5 +1,5 @@ Name:          csound-expression-dynamic-Version:       0.0.4+Version:       0.0.5 Cabal-Version: >= 1.6 License:       BSD3 License-file:  LICENSE@@ -45,6 +45,7 @@    Other-Modules:     Csound.Dynamic.Tfm.DeduceTypes+    Csound.Dynamic.Tfm.Liveness     Csound.Dynamic.Tfm.UnfoldMultiOuts     Csound.Dynamic.Render.Pretty     Csound.Dynamic.Render.Instr
src/Csound/Dynamic/Render/Instr.hs view
@@ -15,6 +15,7 @@  import Csound.Dynamic.Tfm.DeduceTypes import Csound.Dynamic.Tfm.UnfoldMultiOuts+import Csound.Dynamic.Tfm.Liveness  import Csound.Dynamic.Types hiding (Var) import Csound.Dynamic.Build(getRates, isMultiOutSignature)@@ -49,8 +50,9 @@ clearEmptyResults (res, expr) = (filter ((/= Xr) . ratedVarRate) res, expr)          collectRates :: Dag RatedExp -> [([RatedVar], Exp RatedVar)]-collectRates dag = fmap (second ratedExpExp) res-    where res = unfoldMultiOuts unfoldSpec lastFreshId dag1  +collectRates dag = fmap (second ratedExpExp) res2+    where res2 = liveness lastFreshId1 res1+          (res1, lastFreshId1)= unfoldMultiOuts unfoldSpec lastFreshId dag1             (dag1, lastFreshId) = rateGraph dag  -----------------------------------------------------------
+ src/Csound/Dynamic/Tfm/Liveness.hs view
@@ -0,0 +1,157 @@+module Csound.Dynamic.Tfm.Liveness (+    liveness+) where++import Prelude hiding (mapM, mapM_)++import Control.Monad.Trans.State.Strict+import Data.Traversable+import Data.Foldable+import qualified Data.Map as M++import Control.Monad.Trans.Class+import Control.Monad hiding (mapM, mapM_)+import Control.Monad.ST+import qualified Data.Array.Unboxed as A+import qualified Data.Array.MArray as A+import qualified Data.Array.ST as A++import qualified Csound.Dynamic.Tfm.DeduceTypes as D+import Csound.Dynamic.Tfm.DeduceTypes(varType, varId)+import Csound.Dynamic.Types.Exp(Rate(..))++liveness :: Traversable f => Int -> Dag f -> Dag f+liveness lastFreshId as = runST $ do+	st <- initSt lastFreshId $ analyse lastFreshId as+	evalStateT (mapM substExp $ countLines $ as) st++type LineNumber = Int++countLines :: [a] -> [(LineNumber, a)]+countLines = zip [0 ..]++type Var  = D.Var Rate++type Lhs   = [Var]+type Rhs f = f Var+type Exp f = (Lhs, Rhs f)++type Dag f = [Exp f]++-----------------------------------------------++data IdList = IdList+    [Int] -- fresh ids+    Int   -- the biggest used id++allocId :: IdList -> (Int, IdList)+allocId (IdList is lastId) = (head is, IdList (tail is) (max (head is) lastId))++freeId :: Int -> IdList -> IdList +freeId  n (IdList is lastId) = IdList (insertSorted n is) lastId1+	where lastId1 = if (n == lastId) then (lastId - 1) else lastId++insertSorted :: Int -> [Int] -> [Int]+insertSorted n (a:as) +	| n < a  = n : a : as+	| n == a = a : as+	| otherwise = a : insertSorted n as +insertSorted n [] = [n]++-----------------------------------------------++type StArr s = A.STUArray s Int Int++type LivenessTable = A.UArray Int Int+type SubstTable s  = StArr s++data Registers s = Registers +	{ registers 	:: M.Map Rate IdList+	, livenessTable :: LivenessTable+	, substTable 	:: SubstTable s+	}++type Memory s a = StateT (Registers s) (ST s) a++onRegs ::  (M.Map Rate IdList -> M.Map Rate IdList) -> (Registers s -> Registers s)+onRegs f rs = rs { registers = f $ registers rs }++initRegs :: M.Map Rate IdList+initRegs = M.fromList $ fmap (\x -> (x, initIdList)) [(minBound :: Rate) .. maxBound]+	where initIdList = IdList [0..] 0++isAlive :: LineNumber -> Var -> Memory s Bool+isAlive lineNum v = do+	tab <- fmap livenessTable get+	return $ lineNum < tab A.! (varId v)++lookUpSubst :: Int -> Memory s Int+lookUpSubst i = do+	tab <- fmap substTable get+	lift $ A.readArray tab i++saveSubst :: Int -> Int -> Memory s ()+saveSubst from to = do+	tab <- fmap substTable get +	lift $ A.writeArray tab from to++substLhs :: Var -> Memory s Var+substLhs v = do+	v1 <- alloc $ varType v+	saveSubst (varId v) (varId v1)+	return v1++substRhs :: LineNumber -> Var -> Memory s Var+substRhs lineNum v = do+	i1 <- lookUpSubst (varId v)+	let v1 = D.Var i1 (varType v)+	b <- isAlive lineNum v+	unless b $ free v1+	return v1++alloc :: Rate -> Memory s Var+alloc rate = state $ \mem -> +	let (i, mem1) = allocRegister rate mem+	in  (D.Var i rate, mem1)+	where +		allocRegister :: Rate -> Registers s -> (Int, Registers s)+		allocRegister r mem = (i, onRegs (M.update (const $ Just is) r) mem) +			where (i, is) = allocId $ registers mem M.! r++free :: Var -> Memory s ()+free v = state $ \mem ->+	let mem1 = freeRegister (varType v) (varId v) mem+	in  ((), mem1)+	where+		freeRegister :: Rate -> Int -> Registers s -> Registers s+		freeRegister rate i = onRegs $ M.update (Just . freeId i) rate++--------------------------------------------------------------------------++analyse :: Traversable f => Int -> Dag f -> LivenessTable+analyse lastFreshId as = A.runSTUArray $ do+	arr <- A.newArray (0, lastFreshId) 0+	mapM_ (go arr) $ countLines as+	return arr+	where +		go :: Traversable f => StArr s -> (LineNumber, Exp f) -> ST s ()+		go arr (lineNum, (_, rhs)) =  mapM (countVar arr lineNum) rhs >> return ()++		countVar :: StArr s  -> LineNumber -> Var -> ST s ()+		countVar arr lineNum v = do+			val <- A.readArray arr i+			A.writeArray arr i (val `max` lineNum)+			where i = varId v++substExp :: Traversable f => (LineNumber, Exp f) -> Memory s (Exp f)+substExp (lineNum, (lhs, rhs)) = do+	freshLhs <- traverse substLhs lhs+	freshRhs <- traverse (substRhs lineNum) rhs+	return (freshLhs, freshRhs)++initSt :: Int -> LivenessTable -> ST s (Registers s)+initSt lastFreshId livenessTab = fmap (Registers initRegs livenessTab) (initSubstTable lastFreshId)++initSubstTable :: Int ->  ST s (SubstTable s)+initSubstTable n = A.newListArray (0, n) [0 .. n]+
src/Csound/Dynamic/Tfm/UnfoldMultiOuts.hs view
@@ -36,8 +36,8 @@     getSelector    :: f (Var a) -> Maybe (Selector a),     getParentTypes :: f (Var a) -> Maybe [a] } -unfoldMultiOuts :: UnfoldMultiOuts f a -> Int -> [SingleStmt f a] -> [MultiStmt f a]-unfoldMultiOuts algSpec lastFreshId stmts = evalState st lastFreshId+unfoldMultiOuts :: UnfoldMultiOuts f a -> Int -> [SingleStmt f a] -> ([MultiStmt f a], Int)+unfoldMultiOuts algSpec lastFreshId stmts = runState st lastFreshId     where selectors = mapMaybe (\(lhs, rhs) -> fmap (lhs,) $ getSelector algSpec rhs) stmts           st = mapM (unfoldStmt algSpec $ mkChildrenMap selectors) $ dropSelectors stmts           dropSelectors = filter (isNothing . getSelector algSpec . snd)