packages feed

clash-lib 0.5.11 → 0.5.12

raw patch · 13 files changed

+371/−48 lines, 13 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ CLaSH.Core.Util: extractElems :: DataCon -> Type -> Char -> Int -> Term -> [(Term, [LetBinding])]
+ CLaSH.Core.Util: mkVec :: DataCon -> DataCon -> Type -> Int -> [Term] -> Term
+ CLaSH.Normalize.Transformations: reduceNonRepPrim :: NormRewrite
+ CLaSH.Rewrite.Util: isUntranslatableType :: Type -> RewriteMonad extra Bool
- CLaSH.Driver: generateHDL :: Backend backend => BindingMap -> Maybe backend -> PrimMap -> HashMap TyConName TyCon -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> (HashMap TyConName TyCon -> Term -> Term) -> Maybe TopEntity -> CLaSHOpts -> IO ()
+ CLaSH.Driver: generateHDL :: Backend backend => BindingMap -> Maybe backend -> PrimMap -> HashMap TyConName TyCon -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> (HashMap TyConName TyCon -> Bool -> Term -> Term) -> Maybe TopEntity -> CLaSHOpts -> IO ()
- CLaSH.Driver.TestbenchGen: genTestBench :: CLaSHOpts -> Supply -> PrimMap -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> (HashMap TyConName TyCon -> Term -> Term) -> Int -> HashMap TmName (Type, Term) -> Maybe TmName -> Maybe TmName -> String -> [(String, FilePath)] -> Component -> IO ([Component], [(String, FilePath)])
+ CLaSH.Driver.TestbenchGen: genTestBench :: CLaSHOpts -> Supply -> PrimMap -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> (HashMap TyConName TyCon -> Bool -> Term -> Term) -> Int -> HashMap TmName (Type, Term) -> Maybe TmName -> Maybe TmName -> String -> [(String, FilePath)] -> Component -> IO ([Component], [(String, FilePath)])
- CLaSH.Normalize: runNormalization :: CLaSHOpts -> Supply -> HashMap TmName (Type, Term) -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> (HashMap TyConName TyCon -> Term -> Term) -> NormalizeSession a -> a
+ CLaSH.Normalize: runNormalization :: CLaSHOpts -> Supply -> HashMap TmName (Type, Term) -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> (HashMap TyConName TyCon -> Bool -> Term -> Term) -> NormalizeSession a -> a
- CLaSH.Normalize.Util: specializeNorm :: Bool -> NormRewrite
+ CLaSH.Normalize.Util: specializeNorm :: NormRewrite
- CLaSH.Rewrite.Types: RewriteEnv :: DebugLevel -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> (HashMap TyConName TyCon -> Term -> Term) -> RewriteEnv
+ CLaSH.Rewrite.Types: RewriteEnv :: DebugLevel -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> (HashMap TyConName TyCon -> Bool -> Term -> Term) -> RewriteEnv
- CLaSH.Rewrite.Types: [_evaluator] :: RewriteEnv -> HashMap TyConName TyCon -> Term -> Term
+ CLaSH.Rewrite.Types: [_evaluator] :: RewriteEnv -> HashMap TyConName TyCon -> Bool -> Term -> Term
- CLaSH.Rewrite.Types: bindings :: Lens' (RewriteState extra_a3ttu) (HashMap TmName (Type, Term))
+ CLaSH.Rewrite.Types: bindings :: Lens' (RewriteState extra_a3uG2) (HashMap TmName (Type, Term))
- CLaSH.Rewrite.Types: curFun :: Lens' (RewriteState extra_a3ttu) TmName
+ CLaSH.Rewrite.Types: curFun :: Lens' (RewriteState extra_a3uG2) TmName
- CLaSH.Rewrite.Types: evaluator :: Lens' RewriteEnv (HashMap TyConName TyCon -> Term -> Term)
+ CLaSH.Rewrite.Types: evaluator :: Lens' RewriteEnv (HashMap TyConName TyCon -> Bool -> Term -> Term)
- CLaSH.Rewrite.Types: extra :: Lens (RewriteState extra_a3ttu) (RewriteState extra_a3twR) extra_a3ttu extra_a3twR
+ CLaSH.Rewrite.Types: extra :: Lens (RewriteState extra_a3uG2) (RewriteState extra_a3uJp) extra_a3uG2 extra_a3uJp
- CLaSH.Rewrite.Types: nameCounter :: Lens' (RewriteState extra_a3ttu) Int
+ CLaSH.Rewrite.Types: nameCounter :: Lens' (RewriteState extra_a3uG2) Int
- CLaSH.Rewrite.Types: transformCounter :: Lens' (RewriteState extra_a3ttu) Int
+ CLaSH.Rewrite.Types: transformCounter :: Lens' (RewriteState extra_a3uG2) Int
- CLaSH.Rewrite.Types: uniqSupply :: Lens' (RewriteState extra_a3ttu) Supply
+ CLaSH.Rewrite.Types: uniqSupply :: Lens' (RewriteState extra_a3uG2) Supply
- CLaSH.Rewrite.Util: specialise :: Lens' extra (Map (TmName, Int, Either Term Type) (TmName, Type)) -> Lens' extra (HashMap TmName Int) -> Lens' extra Int -> Bool -> Rewrite extra
+ CLaSH.Rewrite.Util: specialise :: Lens' extra (Map (TmName, Int, Either Term Type) (TmName, Type)) -> Lens' extra (HashMap TmName Int) -> Lens' extra Int -> Rewrite extra
- CLaSH.Rewrite.Util: specialise' :: Lens' extra (Map (TmName, Int, Either Term Type) (TmName, Type)) -> Lens' extra (HashMap TmName Int) -> Lens' extra Int -> Bool -> [CoreContext] -> Term -> (Term, [Either Term Type]) -> Either Term Type -> RewriteMonad extra Term
+ CLaSH.Rewrite.Util: specialise' :: Lens' extra (Map (TmName, Int, Either Term Type) (TmName, Type)) -> Lens' extra (HashMap TmName Int) -> Lens' extra Int -> [CoreContext] -> Term -> (Term, [Either Term Type]) -> Either Term Type -> RewriteMonad extra Term

Files

CHANGELOG.md view
@@ -1,5 +1,16 @@ # Changelog for the [`clash-lib`](http://hackage.haskell.org/package/clash-lib) package +## 0.5.12 *September 14th 2015*+* New features:+  * Completely unroll "definitions" of some higher-order primitives with non-representable argument or result vectors:+    It is now possible to translate e.g. `f xs ys = zipWith ($) (map (+) xs) ys :: Vec 4 Int -> Vec 4 Int -> Vec 4 Int`++* Fixes bugs:+  * `topLet` transformation erroneously not performed in a top-down traversal+  * Specialisation limit unchecked on types and constants+  * Vector of functions cannot be translated [#25](https://github.com/clash-lang/clash-compiler/issues/25 )+  * CLaSH fails to generate VHDL when map is applied [#78](https://github.com/clash-lang/clash-compiler/issues/78)+ ## 0.5.11 *September 7th 2015* * Fixes bugs:   * Clash running out of memory on Simple-ish project [#70](https://github.com/clash-lang/clash-compiler/issues/70)
clash-lib.cabal view
@@ -1,5 +1,5 @@ Name:                 clash-lib-Version:              0.5.11+Version:              0.5.12 Synopsis:             CAES Language for Synchronous Hardware - As a Library Description:   CλaSH (pronounced ‘clash’) is a functional hardware description language that
src/CLaSH/Core/Util.hs view
@@ -1,21 +1,26 @@-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}  -- | Smart constructor and destructor functions for CoreHW module CLaSH.Core.Util where  import Data.HashMap.Lazy                       (HashMap)-import Unbound.Generics.LocallyNameless        (Fresh, bind, embed, unbind, unembed,+import Unbound.Generics.LocallyNameless        (Fresh, bind, embed, rebind,+                                                string2Name, unbind, unembed,                                                 unrebind, unrec) import Unbound.Generics.LocallyNameless.Unsafe (unsafeUnbind) -import CLaSH.Core.DataCon                      (dcType)+import CLaSH.Core.DataCon                      (DataCon, dcType, dataConInstArgTys) import CLaSH.Core.Literal                      (literalType) import CLaSH.Core.Pretty                       (showDoc)-import CLaSH.Core.Term                         (Pat (..), Term (..), TmName)-import CLaSH.Core.Type                         (Kind, TyName, Type (..), applyTy,+import CLaSH.Core.Term                         (LetBinding, Pat (..), Term (..),+                                                TmName)+import CLaSH.Core.Type                         (Kind, LitTy (..), TyName,+                                                Type (..), applyTy,                                                 isFunTy, isPolyFunCoreTy, mkFunTy,                                                 splitFunTy) import CLaSH.Core.TyCon                        (TyCon, TyConName)+import CLaSH.Core.TysPrim                      (typeNatKind) import CLaSH.Core.Var                          (Id, TyVar, Var (..), varType) import CLaSH.Util @@ -219,3 +224,67 @@ termSize (Case subj _ alts) = let subjSz = termSize subj                                   altSzs = map (termSize . snd . unsafeUnbind) alts                               in  sum (subjSz:altSzs)++-- | Create a vector of supplied elements+mkVec :: DataCon -- ^ The Nil constructor+      -> DataCon -- ^ The Cons (:>) constructor+      -> Type    -- ^ Element type+      -> Int     -- ^ Length of the vector+      -> [Term]  -- ^ Elements to put in the vector+      -> Term+mkVec nilCon consCon resTy = go+  where+    go _ [] = mkApps (Data nilCon) [Right (LitTy (NumTy 0))+                                   ,Right resTy+                                   ,Left  (Prim "_CO_" nilCoTy)+                                   ]++    go n (x:xs) = mkApps (Data consCon) [Right (LitTy (NumTy n))+                                        ,Right resTy+                                        ,Right (LitTy (NumTy (n-1)))+                                        ,Left (Prim "_CO_" (consCoTy n))+                                        ,Left x+                                        ,Left (go (n-1) xs)]++    nilCoTy    = head (dataConInstArgTys nilCon  [(LitTy (NumTy 0)),resTy])+    consCoTy n = head (dataConInstArgTys consCon [(LitTy (NumTy n))+                                                 ,resTy+                                                 ,(LitTy (NumTy (n-1)))])++-- | Create let-bindings with case-statements that select elements out of a+-- vector. Returns both the variables to which element-selections are bound+-- and the let-bindings+extractElems :: DataCon -- ^ The Cons (:>) constructor+             -> Type    -- ^ The element type+             -> Char    -- ^ Char to append to the bound variable names+             -> Int     -- ^ Length of the vector+             -> Term    -- ^ The vector+             -> [(Term,[LetBinding])]+extractElems consCon resTy s maxN = go maxN+  where+    go :: Int -> Term -> [(Term,[LetBinding])]+    go 0 _ = []+    go n e = (elVar+             ,[(Id elBNm (embed resTy) ,embed lhs)+              ,(Id restBNm (embed restTy),embed rhs)+              ]+             ) :+             go (n-1) (Var restTy restBNm)++      where+        elBNm     = string2Name ("el" ++ s:show (maxN-n))+        restBNm   = string2Name ("rest" ++ s:show (maxN-n))+        elVar     = Var resTy elBNm+        pat       = DataPat (embed consCon) (rebind [mTV] [co,el,rest])+        elPatNm   = string2Name "el"+        restPatNm = string2Name "rest"+        lhs       = Case e resTy  [bind pat (Var resTy  elPatNm)]+        rhs       = Case e restTy [bind pat (Var restTy restPatNm)]++        mName = string2Name "m"+        mTV   = TyVar mName (embed typeNatKind)+        tys   = [(LitTy (NumTy n)),resTy,(LitTy (NumTy (n-1)))]+        idTys = dataConInstArgTys consCon tys+        [co,el,rest] = zipWith Id [string2Name "_co_",elPatNm, restPatNm]+                                  (map embed idTys)+        restTy = last $ dataConInstArgTys consCon tys
src/CLaSH/Driver.hs view
@@ -42,7 +42,7 @@             -> PrimMap -- ^ Primitive / BlackBox Definitions             -> HashMap TyConName TyCon -- ^ TyCon cache             -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -- ^ Hardcoded 'Type' -> 'HWType' translator-            -> (HashMap TyConName TyCon -> Term -> Term) -- ^ Hardcoded evaluator (delta-reduction)+            -> (HashMap TyConName TyCon -> Bool -> Term -> Term) -- ^ Hardcoded evaluator (delta-reduction)             -> Maybe TopEntity             -> CLaSHOpts -- ^ Debug information level for the normalization process             -> IO ()
src/CLaSH/Driver/TestbenchGen.hs view
@@ -40,7 +40,7 @@              -> PrimMap                      -- ^ Primitives              -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType))              -> HashMap TyConName TyCon-             -> (HashMap TyConName TyCon -> Term -> Term)+             -> (HashMap TyConName TyCon -> Bool -> Term -> Term)              -> Int              -> HashMap TmName (Type,Term)   -- ^ Global binders              -> Maybe TmName                 -- ^ Stimuli
src/CLaSH/Driver/TopWrapper.hs view
@@ -177,7 +177,7 @@         netdecl = NetDecl iName hwty         assigns = zipWith                     (\id_ n -> Assignment id_-                                 (Identifier iName (Just (Indexed (hwty,1,n)))))+                                 (Identifier iName (Just (Indexed (hwty,10,n)))))                     ids                     [0..]     in  (nms',(ports',(netdecl:assigns ++ decls',iName)))
src/CLaSH/Netlist.hs view
@@ -20,6 +20,7 @@                                                   unrebind)  import           CLaSH.Core.DataCon               (DataCon (..))+import           CLaSH.Core.FreeVars              (typeFreeVars) import           CLaSH.Core.Literal               (Literal (..)) import           CLaSH.Core.Pretty                (showDoc) import           CLaSH.Core.Term                  (Pat (..), Term (..), TmName)@@ -184,10 +185,14 @@   let dstId    = mkBasicId . Text.pack . name2String $ varName bndr       altVarId = mkBasicId . Text.pack $ name2String varTm       modifier = case pat of-        DataPat (Embed dc) ids -> let tms = case unrebind ids of-                                              ([],tms') -> tms'-                                              _         -> error $ $(curLoc) ++ "Not in normal form: Pattern binds existential variables: " ++ showDoc e-                                  in case elemIndex (Id varTm (Embed varTy)) tms of+        DataPat (Embed dc) ids -> let (exts,tms) = unrebind ids+                                      tmsTys     = map (unembed . varType) tms+                                      tmsFVs     = concatMap (Lens.toListOf typeFreeVars) tmsTys+                                      extNms     = map varName exts+                                      tms'       = if any (`elem` tmsFVs) extNms+                                                      then error $ $(curLoc) ++ "Not in normal form: Pattern binds existential variables: " ++ showDoc e+                                                      else tms+                                  in case elemIndex (Id varTm (Embed varTy)) tms' of                                        Nothing -> Nothing                                        Just fI                                         | sHwTy /= vHwTy -> Just (Indexed (sHwTy,dcTag dc - 1,fI))
src/CLaSH/Normalize.hs view
@@ -51,7 +51,7 @@                  -- ^ Hardcoded Type -> HWType translator                  -> HashMap TyConName TyCon                  -- ^ TyCon cache-                 -> (HashMap TyConName TyCon -> Term -> Term)+                 -> (HashMap TyConName TyCon -> Bool -> Term -> Term)                  -- ^ Hardcoded evaluator (delta-reduction)                  -> NormalizeSession a                  -- ^ NormalizeSession to run@@ -219,7 +219,7 @@   let (toInline,il_used) = unzip il_ct   newExpr <- case toInline of                [] -> return tm-               _  -> rewriteExpr ("bindConstants",(repeatR (topdownR $ (bindConstantVar >-> caseCon >-> reduceConst))) !-> topLet) (showDoc nm, substTms toInline tm)+               _  -> rewriteExpr ("bindConstants",(repeatR (topdownR $ (bindConstantVar >-> caseCon >-> reduceConst))) !-> topdownSucR topLet) (showDoc nm, substTms toInline tm)   return (CBranch (nm,(ty,newExpr)) (newUsed ++ (concat il_used)))  callTreeToList :: [TmName]
src/CLaSH/Normalize/Strategy.hs view
@@ -38,10 +38,11 @@                  ]      transBUP :: [(String,NormRewrite)]-    transBUP = [ ("inlineClosed", inlineClosed)-               , ("inlineSmall" , inlineSmall)-               , ("inlineNonRep", inlineNonRep)-               , ("bindNonRep"  , bindNonRep) -- See: [Note] bindNonRep before liftNonRep+    transBUP = [ ("inlineClosed"    , inlineClosed)+               , ("inlineSmall"     , inlineSmall)+               , ("inlineNonRep"    , inlineNonRep)+               , ("bindNonRep"      , bindNonRep) -- See: [Note] bindNonRep before liftNonRep+               , ("reduceNonRepPrim", reduceNonRepPrim)                ]      specRws :: [(String,NormRewrite)]
src/CLaSH/Normalize/Transformations.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE TemplateHaskell  #-}-{-# LANGUAGE ViewPatterns     #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+{-# LANGUAGE ViewPatterns      #-}  -- | Transformations of the Normalization process module CLaSH.Normalize.Transformations@@ -25,6 +26,7 @@   , inlineSmall   , simpleCSE   , reduceConst+  , reduceNonRepPrim   ) where @@ -37,23 +39,27 @@ import qualified Data.Maybe                  as Maybe import           Unbound.Generics.LocallyNameless     (Bind, Embed (..), bind, embed,                                               rec, unbind, unembed, unrebind,-                                              unrec, name2String)+                                              unrec, name2String, string2Name,+                                              rebind) import           Unbound.Generics.LocallyNameless.Unsafe (unsafeUnbind) -import           CLaSH.Core.DataCon          (DataCon, dcName, dcTag,-                                              dcUnivTyVars)+import           CLaSH.Core.DataCon          (DataCon (..), dataConInstArgTys) import           CLaSH.Core.FreeVars         (termFreeIds, termFreeTyVars,                                               typeFreeVars) import           CLaSH.Core.Pretty           (showDoc) import           CLaSH.Core.Subst            (substTm, substTms, substTyInTm,                                               substTysinTm) import           CLaSH.Core.Term             (LetBinding, Pat (..), Term (..))-import           CLaSH.Core.Type             (TypeView (..), applyFunTy,-                                              applyTy, splitFunTy, typeKind, tyView)-import           CLaSH.Core.Util             (collectArgs, idToVar, isCon,+import           CLaSH.Core.Type             (TypeView (..), Type (..),+                                              LitTy (..), applyFunTy,+                                              applyTy, splitFunTy, typeKind,+                                              tyView, mkTyConApp, mkFunTy)+import           CLaSH.Core.TyCon            (TyConName, tyConDataCons)+import           CLaSH.Core.Util             (collectArgs, extractElems,+                                              idToVar, isCon,                                               isFun, isLet, isPolyFun, isPrim,                                               isVar, mkApps, mkLams, mkTmApps,-                                              termSize,termType)+                                              mkVec, termSize,termType) import           CLaSH.Core.Var              (Id, Var (..)) import           CLaSH.Netlist.Util          (representableType,                                               splitNormalized)@@ -98,7 +104,7 @@   | (Var _ _,  args) <- collectArgs e1   , null $ Lens.toListOf typeFreeVars ty   , (_, []) <- Either.partitionEithers args-  = specializeNorm False ctx e+  = specializeNorm ctx e  typeSpec _ e = return e @@ -113,7 +119,7 @@        localVar <- isLocalVar e2        nonRepE2 <- not <$> (representableType <$> Lens.view typeTranslator <*> Lens.view tcCache <*> pure e2Ty)        if nonRepE2 && not localVar-         then specializeNorm True ctx e+         then specializeNorm ctx e          else return e  nonRepSpec _ e = return e@@ -226,7 +232,7 @@     tcm <- Lens.view tcCache     lvl <- Lens.view dbgLevel     reduceConstant <- Lens.view evaluator-    case reduceConstant tcm subj of+    case reduceConstant tcm True subj of       Literal l -> caseCon ctx (Case (Literal l) ty alts)       subj'@(collectArgs -> (Data _,_)) -> caseCon ctx (Case subj' ty alts)       subj' -> traceIf (lvl > DebugNone) ("Irreducible constant as case subject: " ++ showDoc subj ++ "\nCan be reduced to: " ++ showDoc subj') (caseOneAlt e)@@ -261,8 +267,8 @@     case (untranslatable,arg) of       (True,Letrec b) -> do (binds,body) <- unbind b                             changed (Letrec (bind binds (App appConPrim body)))-      (True,Case {})  -> specializeNorm True ctx e-      (True,Lam _)    -> specializeNorm True ctx e+      (True,Case {})  -> specializeNorm ctx e+      (True,Lam _)    -> specializeNorm ctx e       _               -> return e  nonRepANF _ e = return e@@ -395,7 +401,7 @@   , (_, [])     <- Either.partitionEithers args   , null $ Lens.toListOf termFreeTyVars e2   , isConstant e2-  = specializeNorm False ctx e+  = specializeNorm ctx e  constantSpec _ e = return e @@ -693,9 +699,229 @@   = do     tcm <- Lens.view tcCache     reduceConstant <- Lens.view evaluator-    case reduceConstant tcm e of+    case reduceConstant tcm False e of       e'@(Data _)    -> changed e'       e'@(Literal _) -> changed e'       _              -> return e  reduceConst _ e = return e++-- | Replace primitives by their "definition" if they would lead to let-bindings+-- with a non-representable type when a function is in ANF. This happens for+-- example when CLaSH.Size.Vector.map consumes or produces a vector of+-- non-representable elements.+--+-- Basically what this transformation does is replace a primitive the completely+-- unrolled recursive definition that it represents. e.g.+--+-- > zipWith ($) (xs :: Vec 2 (Int -> Int)) (ys :: Vec 2 Int)+--+-- is replaced by:+--+-- > let (x0  :: (Int -> Int))       = case xs  of (:>) _ x xr -> x+-- >     (xr0 :: Vec 1 (Int -> Int)) = case xs  of (:>) _ x xr -> xr+-- >     (x1  :: (Int -> Int)(       = case xr0 of (:>) _ x xr -> x+-- >     (y0  :: Int)                = case ys  of (:>) _ y yr -> y+-- >     (yr0 :: Vec 1 Int)          = case ys  of (:>) _ y yr -> xr+-- >     (y1  :: Int                 = case yr0 of (:>) _ y yr -> y+-- > in  (($) x0 y0 :> ($) x1 y1 :> Nil)+--+-- Currently, it only handles the following functions:+--+-- * CLaSH.Sized.Vector.map+-- * CLaSH.Sized.Vector.zipWith+-- * CLaSH.Sized.Vector.traverse#+reduceNonRepPrim :: NormRewrite+reduceNonRepPrim _ e@(App _ _)+  | (Prim f _, args) <- collectArgs e+  = case f of+      "CLaSH.Sized.Vector.zipWith" | length args == 7 -> do+        let [lhsElTy,rhsElty,resElTy,nTy] = Either.rights args+        case nTy of+          (LitTy (NumTy n)) -> do+            untranslatableTys <- mapM isUntranslatableType [lhsElTy,rhsElty,resElTy]+            if or untranslatableTys+               then let [fun,lhsArg,rhsArg] = Either.lefts args+                    in  reduceZipWith n lhsElTy rhsElty resElTy fun lhsArg rhsArg+               else return e+          _ -> return e+      "CLaSH.Sized.Vector.map" | length args == 5 -> do+        let [argElTy,resElTy,nTy] = Either.rights args+        case nTy of+          (LitTy (NumTy n)) -> do+            untranslatableTys <- mapM isUntranslatableType [argElTy,resElTy]+            if or untranslatableTys+               then let [fun,arg] = Either.lefts args+                    in  reduceMap n argElTy resElTy fun arg+               else return e+          _ -> return e+      "CLaSH.Sized.Vector.traverse#" | length args == 7 ->+        let [aTy,fTy,bTy,nTy] = Either.rights args+        in  case nTy of+          (LitTy (NumTy n)) ->+            let [dict,fun,arg] = Either.lefts args+            in  reduceTraverse n aTy fTy bTy dict fun arg+          _ -> return e+      _ -> return e++reduceNonRepPrim _ e = return e++-- | Replace an application of @CLaSH.Sized.Vector.zipWith@ primitive on vectors+-- of a known length @n@, by the fully unrolled recursive "definition" of of+-- @CLaSH.Sized.Vector.zipWith@+reduceZipWith :: Int  -- ^ Length of the vector(s)+              -> Type -- ^ Type of the lhs of the function+              -> Type -- ^ Type of the rhs of the function+              -> Type -- ^ Type of the result of the function+              -> Term -- ^ The zipWith'd functions+              -> Term -- ^ The 1st vector argument+              -> Term -- ^ The 2nd vector argument+              -> NormalizeSession Term+reduceZipWith n lhsElTy rhsElTy resElTy fun lhsArg rhsArg = do+  tcm <- Lens.view tcCache+  (TyConApp vecTcNm _) <- tyView <$> termType tcm lhsArg+  let (Just vecTc)     = HashMap.lookup vecTcNm tcm+      [nilCon,consCon] = tyConDataCons vecTc+      (varsL,elemsL)   = second concat . unzip $ extractElems consCon lhsElTy 'L' n lhsArg+      (varsR,elemsR)   = second concat . unzip $ extractElems consCon rhsElTy 'R' n rhsArg+      funApps          = zipWith (\l r -> mkApps fun [Left l,Left r]) varsL varsR+      lbody            = mkVec nilCon consCon resElTy n funApps+      lb               = Letrec (bind (rec (init elemsL ++ init elemsR)) lbody)+  changed lb++-- | Replace an application of @CLaSH.Sized.Vector.map@ primitive on vectors+-- of a known length @n@, by the fully unrolled recursive "definition" of of+-- @CLaSH.Sized.Vector.map@+reduceMap :: Int  -- ^ Length of the vector+          -> Type -- ^ Argument type of the function+          -> Type -- ^ Result type of the function+          -> Term -- ^ The map'd function+          -> Term -- ^ The map'd over vector+          -> NormalizeSession Term+reduceMap n argElTy resElTy fun arg = do+  tcm <- Lens.view tcCache+  (TyConApp vecTcNm _) <- tyView <$> termType tcm arg+  let (Just vecTc)     = HashMap.lookup vecTcNm tcm+      [nilCon,consCon] = tyConDataCons vecTc+      (vars,elems)     = second concat . unzip $ extractElems consCon argElTy 'A' n arg+      funApps          = map (fun `App`) vars+      lbody            = mkVec nilCon consCon resElTy n funApps+      lb               = Letrec (bind (rec (init elems)) lbody)+  changed lb++-- | Replace an application of @CLaSH.Sized.Vector.traverse#@ primitive on+-- vectors of a known length @n@, by the fully unrolled recursive "definition"+-- of @CLaSH.Sized.Vector.map@+reduceTraverse :: Int  -- ^ Length of the vector+               -> Type -- ^ Element type of the argument vector+               -> Type -- ^ The type of the applicative+               -> Type -- ^ Element type of the result vector+               -> Term -- ^ The @Applicative@ dictionary+               -> Term -- ^ The function to traverse with+               -> Term -- ^ The argument vector+               -> NormalizeSession Term+reduceTraverse n aTy fTy bTy dict fun arg = do+  tcm <- Lens.view tcCache+  (TyConApp vecTcNm    _) <- tyView <$> termType tcm arg+  (TyConApp apDictTcNm _) <- tyView <$> termType tcm dict+  let (Just apDictTc)    = HashMap.lookup apDictTcNm tcm+      [apDictCon]        = tyConDataCons apDictTc+      apDictIdTys        = dataConInstArgTys apDictCon [fTy]+      apDictIds          = zipWith Id (map string2Name ["functorDict"+                                                       ,"pure"+                                                       ,"ap"+                                                       ,"apConstL"+                                                       ,"apConstR"])+                                      (map embed apDictIdTys)++      (TyConApp funcDictTcNm _) = tyView (head apDictIdTys)+      (Just funcDictTc) = HashMap.lookup funcDictTcNm tcm+      [funcDictCon] = tyConDataCons funcDictTc+      funcDictIdTys = dataConInstArgTys funcDictCon [fTy]+      funcDicIds    = zipWith Id (map string2Name ["fmap","fmapConst"])+                                 (map embed funcDictIdTys)++      apPat    = DataPat (embed apDictCon) (rebind [] apDictIds)+      fnPat    = DataPat (embed funcDictCon) (rebind [] funcDicIds)++      -- Extract the 'pure' function from the Applicative dictionary+      pureTy = apDictIdTys!!1+      pureTm = Case dict pureTy [bind apPat (Var pureTy (string2Name "pure"))]++      -- Extract the '<*>' function from the Applicative dictionary+      apTy   = apDictIdTys!!2+      apTm   = Case dict apTy [bind apPat (Var apTy (string2Name "ap"))]++      -- Extract the Functor dictionary from the Applicative dictionary+      funcTy = (head apDictIdTys)+      funcTm = Case dict funcTy+                         [bind apPat (Var funcTy (string2Name "functorDict"))]++      -- Extract the 'fmap' function from the Functor dictionary+      fmapTy = (head funcDictIdTys)+      fmapTm = Case (Var funcTy (string2Name "functorDict")) fmapTy+                    [bind fnPat (Var fmapTy (string2Name "fmap"))]++      (Just vecTc)     = HashMap.lookup vecTcNm tcm+      [nilCon,consCon] = tyConDataCons vecTc+      (vars,elems)     = second concat . unzip+                                       $ extractElems consCon aTy 'T' n arg++      funApps = map (fun `App`) vars++      lbody   = mkTravVec vecTcNm nilCon consCon (idToVar (apDictIds!!1))+                                                 (idToVar (apDictIds!!2))+                                                 (idToVar (funcDicIds!!0))+                                                 bTy n funApps++      lb      = Letrec (bind (rec ([((apDictIds!!0),embed funcTm)+                                   ,((apDictIds!!1),embed pureTm)+                                   ,((apDictIds!!2),embed apTm)+                                   ,((funcDicIds!!0),embed fmapTm)+                                   ] ++ init elems)) lbody)+  changed lb++-- | Create the traversable vector+--+-- e.g. for a length '2' input vector, we get+--+-- > (:>) <$> x0 <*> ((:>) <$> x1 <*> pure Nil)+mkTravVec :: TyConName -- ^ Vec tcon+          -> DataCon   -- ^ Nil con+          -> DataCon   -- ^ Cons con+          -> Term      -- ^ 'pure' term+          -> Term      -- ^ '<*>' term+          -> Term      -- ^ 'fmap' term+          -> Type      -- ^ 'b' ty+          -> Int       -- ^ Length of the vector+          -> [Term]    -- ^ Elements of the vector+          -> Term+mkTravVec vecTc nilCon consCon pureTm apTm fmapTm bTy = go+  where+    go :: Int -> [Term] -> Term+    go _ [] = mkApps pureTm [Right (mkTyConApp vecTc [LitTy (NumTy 0),bTy])+                            ,Left  (mkApps (Data nilCon)+                                           [Right (LitTy (NumTy 0))+                                           ,Right bTy+                                           ,Left  (Prim "_CO_" nilCoTy)])]++    go n (x:xs) = mkApps apTm+      [Right (mkTyConApp vecTc [LitTy (NumTy (n-1)),bTy])+      ,Right (mkTyConApp vecTc [LitTy (NumTy n),bTy])+      ,Left (mkApps fmapTm [Right bTy+                           ,Right (mkFunTy (mkTyConApp vecTc [LitTy (NumTy (n-1)),bTy])+                                           (mkTyConApp vecTc [LitTy (NumTy n),bTy]))+                           ,Left  (mkApps (Data consCon)+                                          [Right (LitTy (NumTy n))+                                          ,Right bTy+                                          ,Right (LitTy (NumTy (n-1)))+                                          ,Left  (Prim "_CO_" (consCoTy n))+                                          ])+                           ,Left  x])+      ,Left (go (n-1) xs)]++    nilCoTy = head (dataConInstArgTys nilCon [(LitTy (NumTy 0)),bTy])++    consCoTy n = head (dataConInstArgTys consCon [(LitTy (NumTy n))+                                                 ,bTy+                                                 ,(LitTy (NumTy (n-1)))])
src/CLaSH/Normalize/Util.hs view
@@ -47,7 +47,7 @@                      (HashMap.singleton f 1)  -- | Specialize under the Normalization Monad-specializeNorm :: Bool -> NormRewrite+specializeNorm :: NormRewrite specializeNorm = specialise specialisationCache specialisationHistory specialisationLimit  -- | Determine if a term is closed
src/CLaSH/Rewrite/Types.hs view
@@ -77,7 +77,7 @@   -- ^ Hardcode Type -> HWType translator   , _tcCache        :: HashMap TyConName TyCon   -- ^ TyCon cache-  , _evaluator      :: HashMap TyConName TyCon -> Term -> Term+  , _evaluator      :: HashMap TyConName TyCon -> Bool -> Term -> Term   -- ^ Hardcoded evaluator (delta-reduction)}   } 
src/CLaSH/Rewrite/Util.hs view
@@ -405,13 +405,25 @@   $ Lens.use bindings isLocalVar _ = return False +{-# INLINE isUntranslatable #-} -- | Determine if a term cannot be represented in hardware isUntranslatable :: Term                  -> RewriteMonad extra Bool isUntranslatable tm = do   tcm <- Lens.view tcCache-  not <$> (representableType <$> Lens.view typeTranslator <*> pure tcm <*> termType tcm tm)+  not <$> (representableType <$> Lens.view typeTranslator+                             <*> pure tcm+                             <*> termType tcm tm) +{-# INLINE isUntranslatableType #-}+-- | Determine if a type cannot be represented in hardware+isUntranslatableType :: Type+                     -> RewriteMonad extra Bool+isUntranslatableType ty =+  not <$> (representableType <$> Lens.view typeTranslator+                             <*> Lens.view tcCache+                             <*> pure ty)+ -- | Is the Context a Lambda/Term-abstraction context? isLambdaBodyCtx :: CoreContext                 -> Bool@@ -460,24 +472,22 @@ specialise :: Lens' extra (Map.Map (TmName, Int, Either Term Type) (TmName,Type)) -- ^ Lens into previous specialisations            -> Lens' extra (HashMap TmName Int) -- ^ Lens into the specialisation history            -> Lens' extra Int -- ^ Lens into the specialisation limit-           -> Bool            -> Rewrite extra-specialise specMapLbl specHistLbl specLimitLbl doCheck ctx e = case e of-  (TyApp e1 ty) -> specialise' specMapLbl specHistLbl specLimitLbl False ctx e (collectArgs e1) (Right ty)-  (App e1 e2)   -> specialise' specMapLbl specHistLbl specLimitLbl doCheck ctx e (collectArgs e1) (Left  e2)+specialise specMapLbl specHistLbl specLimitLbl ctx e = case e of+  (TyApp e1 ty) -> specialise' specMapLbl specHistLbl specLimitLbl ctx e (collectArgs e1) (Right ty)+  (App e1 e2)   -> specialise' specMapLbl specHistLbl specLimitLbl ctx e (collectArgs e1) (Left  e2)   _             -> return e  -- | Specialise an application on its argument specialise' :: Lens' extra (Map.Map (TmName, Int, Either Term Type) (TmName,Type)) -- ^ Lens into previous specialisations             -> Lens' extra (HashMap TmName Int) -- ^ Lens into specialisation history             -> Lens' extra Int -- ^ Lens into the specialisation limit-            -> Bool -- ^ Perform specialisation limit check             -> [CoreContext] -- Transformation context             -> Term -- ^ Original term             -> (Term, [Either Term Type]) -- ^ Function part of the term, split into root and applied arguments             -> Either Term Type -- ^ Argument to specialize on             -> RewriteMonad extra Term-specialise' specMapLbl specHistLbl specLimitLbl doCheck ctx e (Var _ f, args) specArg = do+specialise' specMapLbl specHistLbl specLimitLbl ctx e (Var _ f, args) specArg = do   lvl <- Lens.view dbgLevel   -- Create binders and variable references for free variables in 'specArg'   (specBndrs,specVars) <- specArgBndrsAndVars ctx specArg@@ -499,7 +509,7 @@           -- Determine if we see a sequence of specialisations on a growing argument           specHistM <- HML.lookup f <$> Lens.use (extra.specHistLbl)           specLim   <- Lens.use (extra . specLimitLbl)-          if doCheck && maybe False (> specLim) specHistM+          if maybe False (> specLim) specHistM             then fail $ unlines [ "Hit specialisation limit " ++ show specLim ++ " on function `" ++ showDoc f ++ "'.\n"                                 , "The function `" ++ showDoc f ++ "' is most likely recursive, and looks like it is being indefinitely specialized on a growing argument.\n"                                 , "Body of `" ++ showDoc f ++ "':\n" ++ showDoc bodyTm ++ "\n"@@ -522,19 +532,20 @@               newf `deepseq` changed newExpr         Nothing -> return e -specialise' _ _ _ _ ctx _ (appE,args) (Left specArg) = do+specialise' _ _ _ ctx _ (appE,args) (Left specArg) = do   -- Create binders and variable references for free variables in 'specArg'   (specBndrs,specVars) <- specArgBndrsAndVars ctx (Left specArg)   -- Create specialized function   let newBody = mkAbstraction specArg specBndrs-  newf <- mkFunction (string2Name "specF") newBody+  cf   <- Lens.use curFun+  newf <- mkFunction (string2Name (name2String cf ++ "_" ++ "specF")) newBody   -- Create specialized argument   let newArg  = Left $ mkApps ((uncurry . flip) Var newf) specVars   -- Use specialized argument   let newExpr = mkApps appE (args ++ [newArg])   changed newExpr -specialise' _ _ _ _ _ e _ _ = return e+specialise' _ _ _ _ e _ _ = return e  -- | Create binders and variable references for free variables in 'specArg' specArgBndrsAndVars :: [CoreContext]