Copyright  (C) 20122016 University of Twente 2016 Myrtle Software Ltd 2017 Google Inc. 

License  BSD2 (see the file LICENSE) 
Maintainer  Christiaan Baaij <christiaan.baaij@gmail.com> 
Safe Haskell  None 
Language  Haskell2010 
Utilities for rewriting: e.g. inlining, specialisation, etc.
Synopsis
 zoomExtra :: State extra a > RewriteMonad extra a
 findAccidentialShadows :: Term > [[Id]]
 apply :: String > Rewrite extra > Rewrite extra
 applyDebug :: DebugLevel > Set String > String > Term > Bool > Term > RewriteMonad extra Term
 runRewrite :: String > InScopeSet > Rewrite extra > Term > RewriteMonad extra Term
 runRewriteSession :: RewriteEnv > RewriteState extra > RewriteMonad extra a > a
 setChanged :: RewriteMonad extra ()
 changed :: a > RewriteMonad extra a
 closestLetBinder :: Context > Maybe Id
 mkDerivedName :: TransformContext > OccName > TmName
 mkTmBinderFor :: (MonadUnique m, MonadFail m) => InScopeSet > TyConMap > Name a > Term > m Id
 mkBinderFor :: (MonadUnique m, MonadFail m) => InScopeSet > TyConMap > Name a > Either Term Type > m (Either Id TyVar)
 mkInternalVar :: MonadUnique m => InScopeSet > OccName > KindOrType > m Id
 inlineBinders :: (Term > LetBinding > RewriteMonad extra Bool) > Rewrite extra
 isJoinPointIn :: Id > Term > Bool
 tailCalls :: Id > Term > Maybe Int
 isVoidWrapper :: Term > Bool
 substituteBinders :: InScopeSet > [LetBinding] > [LetBinding] > Term > ([LetBinding], ([LetBinding], Term))
 liftAndSubsituteBinders :: InScopeSet > [LetBinding] > [LetBinding] > Term > RewriteMonad extra ([LetBinding], Term)
 isWorkFree :: Term > Bool
 isFromInt :: Text > Bool
 isConstant :: Term > Bool
 isConstantNotClockReset :: Term > RewriteMonad extra Bool
 isWorkFreeClockOrResetOrEnable :: TyConMap > Term > Maybe Bool
 isWorkFreeIsh :: Term > RewriteMonad extra Bool
 inlineOrLiftBinders :: (LetBinding > RewriteMonad extra Bool) > (Term > LetBinding > Bool) > Rewrite extra
 liftBinding :: LetBinding > RewriteMonad extra LetBinding
 uniqAwayBinder :: BindingMap > Name a > Name a
 mkFunction :: TmName > SrcSpan > InlineSpec > Term > RewriteMonad extra Id
 addGlobalBind :: TmName > Type > SrcSpan > InlineSpec > Term > RewriteMonad extra ()
 cloneNameWithInScopeSet :: MonadUnique m => InScopeSet > Name a > m (Name a)
 cloneNameWithBindingMap :: MonadUnique m => BindingMap > Name a > m (Name a)
 isUntranslatable :: Bool > Term > RewriteMonad extra Bool
 isUntranslatableType :: Bool > Type > RewriteMonad extra Bool
 mkWildValBinder :: MonadUnique m => InScopeSet > Type > m Id
 mkSelectorCase :: HasCallStack => (Functor m, MonadUnique m) => String > InScopeSet > TyConMap > Term > Int > Int > m Term
 specialise :: Lens' extra (Map (Id, Int, Either Term Type) Id) > Lens' extra (VarEnv Int) > Lens' extra Int > Rewrite extra
 specialise' :: Lens' extra (Map (Id, Int, Either Term Type) Id) > Lens' extra (VarEnv Int) > Lens' extra Int > TransformContext > Term > (Term, [Either Term Type], [TickInfo]) > Either Term Type > RewriteMonad extra Term
 normalizeTermTypes :: TyConMap > Term > Term
 normalizeId :: TyConMap > Id > Id
 specArgBndrsAndVars :: Either Term Type > ([Either Id TyVar], [Either Term Type])
 whnfRW :: Bool > TransformContext > Term > Rewrite extra > RewriteMonad extra Term
 bindPureHeap :: TyConMap > PureHeap > Rewrite extra > Rewrite extra
Documentation
zoomExtra :: State extra a > RewriteMonad extra a Source #
Lift an action working in the _extra
state to the RewriteMonad
findAccidentialShadows :: Term > [[Id]] Source #
Some transformations might erroneously introduce shadowing. For example, a transformation might result in:
let a = ... b = ... a = ...
where the last a
, shadows the first, while Clash assumes that this can't
happen. This function finds those constructs and a list of found duplicates.
Record if a transformation is successfully applied
:: DebugLevel  The current debugging level 
> Set String  Transformations to debug 
> String  Name of the transformation 
> Term  Original expression 
> Bool  Whether the rewrite indicated change 
> Term  New expression 
> RewriteMonad extra Term 
:: String  Name of the transformation 
> InScopeSet  
> Rewrite extra  Transformation to perform 
> Term  Term to transform 
> RewriteMonad extra Term 
Perform a transformation on a Term
runRewriteSession :: RewriteEnv > RewriteState extra > RewriteMonad extra a > a Source #
Evaluate a RewriteSession to its inner monad.
setChanged :: RewriteMonad extra () Source #
Notify that a transformation has changed the expression
changed :: a > RewriteMonad extra a Source #
Identity function that additionally notifies that a transformation has changed the expression
mkDerivedName :: TransformContext > OccName > TmName Source #
:: (MonadUnique m, MonadFail m)  
=> InScopeSet  
> TyConMap  TyCon cache 
> Name a  Name of the new binder 
> Term  Term to bind 
> m Id 
Make a new binder and variable reference for a term
:: (MonadUnique m, MonadFail m)  
=> InScopeSet  
> TyConMap  TyCon cache 
> Name a  Name of the new binder 
> Either Term Type  Type or Term to bind 
> m (Either Id TyVar) 
Make a new binder and variable reference for either a term or a type
:: MonadUnique m  
=> InScopeSet  
> OccName  Name of the identifier 
> KindOrType  
> m Id 
Make a new, unique, identifier
:: (Term > LetBinding > RewriteMonad extra Bool)  Property test 
> Rewrite extra 
Inline the binders in a letbinding that have a certain property
Determine whether a binder is a joinpoint created for a complex case expression.
A joinpoint is when a local function only occurs in tailcall positions, and when it does, more than once.
Count the number of (only) tail calls of a function in an expression.
Nothing
indicates that the function was used in a nontail call position.
isVoidWrapper :: Term > Bool Source #
Determines whether a function has the following shape:
\(w :: Void) > f a b c
i.e. is a wrapper around a (partially) applied function f
, where the
introduced argument w
is not used by f
:: InScopeSet  
> [LetBinding]  Letbinders to substitute 
> [LetBinding]  Letbinders where substitution takes place 
> Term  Body where substitution takes place 
> ([LetBinding], ([LetBinding], Term)) 

Inline the first set of binder into the second set of binders and into the body of the original let expression.
liftAndSubsituteBinders Source #
:: InScopeSet  
> [LetBinding]  Letbinders to lift, and substitute the lifted result 
> [LetBinding]  Lefbinders where substitution takes place 
> Term  Body where substitution takes place 
> RewriteMonad extra ([LetBinding], Term) 
Lift the first set of binders to the level of global bindings, and substitute these lifted bindings into the second set of binders and the body of the original let expression.
isWorkFree :: Term > Bool Source #
Determine whether a term does any work, i.e. adds to the size of the circuit
isConstant :: Term > Bool Source #
Determine if a term represents a constant
isConstantNotClockReset :: Term > RewriteMonad extra Bool Source #
isWorkFreeIsh :: Term > RewriteMonad extra Bool Source #
A conservative version of isWorkFree
. Is used to determine in bindConstantVar
to determine whether an expression can be "bound" (locally inlined). While
binding workfree expressions won't result in extra work for the circuit, it
might very well cause extra work for Clash. In fact, using isWorkFree
in
bindConstantVar
makes Clash two orders of magnitude slower for some of our
test cases.
In effect, this function is a version of isConstant
that also considers
references to clocks and resets constant. This allows us to bind
HiddenClock(ResetEnable) constructs, allowing Clash to constant spec
subconstants  most notably KnownDomain. Doing that enables Clash to
eliminate any caseconstructs on it.
:: (LetBinding > RewriteMonad extra Bool)  Property test 
> (Term > LetBinding > Bool)  Test whether to lift or inline

> Rewrite extra 
liftBinding :: LetBinding > RewriteMonad extra LetBinding Source #
Create a global function for a Letbinding and return a Letbinding where the RHS is a reference to the new global function applied to the free variables of the original RHS
uniqAwayBinder :: BindingMap > Name a > Name a Source #
Ensure that the Unique
of a variable does not occur in the BindingMap
:: TmName  Name of the function 
> SrcSpan  
> InlineSpec  
> Term  Term bound to the function 
> RewriteMonad extra Id  Name with a proper unique and the type of the function 
Make a global function for a nameterm tuple
addGlobalBind :: TmName > Type > SrcSpan > InlineSpec > Term > RewriteMonad extra () Source #
Add a function to the set of global binders
cloneNameWithInScopeSet :: MonadUnique m => InScopeSet > Name a > m (Name a) Source #
Create a new name out of the given name, but with another unique. Resulting unique is guaranteed to not be in the given InScopeSet.
cloneNameWithBindingMap :: MonadUnique m => BindingMap > Name a > m (Name a) Source #
Create a new name out of the given name, but with another unique. Resulting unique is guaranteed to not be in the given BindingMap.
:: Bool  String representable 
> Term  
> RewriteMonad extra Bool 
Determine if a term cannot be represented in hardware
:: Bool  String representable 
> Type  
> RewriteMonad extra Bool 
Determine if a type cannot be represented in hardware
mkWildValBinder :: MonadUnique m => InScopeSet > Type > m Id Source #
Make a binder that should not be referenced
:: HasCallStack  
=> (Functor m, MonadUnique m)  
=> String  Name of the caller of this function 
> InScopeSet  
> TyConMap  TyCon cache 
> Term  Subject of the casecomposition 
> Int  
> Int  
> m Term 
Make a casedecomposition that extracts a field out of a (Sumof)Product type
:: Lens' extra (Map (Id, Int, Either Term Type) Id)  Lens into previous specialisations 
> Lens' extra (VarEnv Int)  Lens into the specialisation history 
> Lens' extra Int  Lens into the specialisation limit 
> Rewrite extra 
Specialise an application on its argument
:: Lens' extra (Map (Id, Int, Either Term Type) Id)  Lens into previous specialisations 
> Lens' extra (VarEnv Int)  Lens into specialisation history 
> Lens' extra Int  Lens into the specialisation limit 
> TransformContext  
> Term  Original term 
> (Term, [Either Term Type], [TickInfo])  Function part of the term, split into root and applied arguments 
> Either Term Type  Argument to specialize on 
> RewriteMonad extra Term 
Specialise an application on its argument
specArgBndrsAndVars :: Either Term Type > ([Either Id TyVar], [Either Term Type]) Source #
Create binders and variable references for free variables in specArg
:: Bool  Whether the expression we're reducing to WHNF is the subject of a case expression. 
> TransformContext  
> Term  
> Rewrite extra  
> RewriteMonad extra Term 
Evaluate an expression to weakhead normal form (WHNF), and apply a transformation on the expression in WHNF.