{-# LANGUAGE DisambiguateRecordFields #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
module Clash.Normalize.Strategy.Spec
( normalizationSpec
, constantPropagationSpec
, flattenSpec
) where
import Language.Haskell.TH.Syntax (Name)
import Clash.Normalize.Transformations
import Clash.Rewrite.StrategyDSL
normalizationSpec :: Name -> Strat
normalizationSpec :: Name -> Strat
normalizationSpec Name
constantPropagationName =
Strat
rmDeadcode Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
multPrim Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Name -> Strat
callStrategy Name
constantPropagationName Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
rmUnusedExpr Strat -> Strat -> Strat
>-!-> Strat
anf Strat -> Strat -> Strat
>-!-> Strat
rmDeadcode Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
bindConst Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
letTL
Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
evalConst
Strat -> Strat -> Strat
>-!-> Strat
cse Strat -> Strat -> Strat
>-!-> Strat
cleanup Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
elimCaseBigNum Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
xOptim Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
rmDeadcode Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
cleanup Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
bindSimIO Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
recLetRec Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
splitArgs
where
multPrim :: Strat
multPrim = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
setupMultiResultPrim
anf :: Strat
anf = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
nonRepANF Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> String -> Name -> Strat
pass String
"ANF" 'makeANF Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
caseCon
letTL :: Strat
letTL = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdownSuc Transformation
topLet
recLetRec :: Strat
recLetRec = String -> Name -> Strat
pass String
"recToLetRec" 'recToLetRec
rmUnusedExpr :: Strat
rmUnusedExpr = Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
removeUnusedExpr
rmDeadcode :: Strat
rmDeadcode = Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup (String -> Transformation -> Transformation
named String
"deadcode" Transformation
deadCode)
bindConst :: Strat
bindConst = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
bindConstantVar
evalConst :: Strat
evalConst = Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
reduceConst
cse :: Strat
cse = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
simpleCSE
elimCaseBigNum :: Strat
elimCaseBigNum = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
elimCaseBigNumInternals
xOptim :: Strat
xOptim = Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
xOptimize
cleanup :: Strat
cleanup = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
etaExpandSyn Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Transformation -> Strat
forall s. ToStep s => s -> Strat
topdownSuc Transformation
inlineCleanup Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
!->
Step -> Strat
forall s. ToStep s => s -> Strat
innerMost ([Transformation] -> Step
chain [ Transformation
caseCon
, Transformation
bindConstantVar
, String -> Transformation -> Transformation
named String
"letFlat" Transformation
flattenLet
])
Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
rmDeadcode Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
letTL
splitArgs :: Strat
splitArgs = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
separateArguments Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
!->
Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
caseCon
bindSimIO :: Strat
bindSimIO = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
inlineSimIO
constantPropagationSpec :: Strat
constantPropagationSpec :: Strat
constantPropagationSpec =
Strat
inlineAndPropagate Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
caseFlattening Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
etaTL Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
dec Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
spec Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
dec Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
conSpec
where
etaTL :: Strat
etaTL = String -> Name -> Strat
pass String
"etaTL" 'etaExpansionTL Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
!-> Transformation -> Strat
forall s. ToStep s => s -> Strat
topdown Transformation
appProp
inlineAndPropagate :: Strat
inlineAndPropagate = Strat -> Strat
repeatR (Step -> Strat
forall s. ToStep s => s -> Strat
topdown Step
transPropagateAndInline Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-> Strat
inlineNR)
spec :: Strat
spec = Step -> Strat
forall s. ToStep s => s -> Strat
bottomup Step
specTransformations
caseFlattening :: Strat
caseFlattening = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdownFix Transformation
caseFlat
dec :: Strat
dec = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdownFix Transformation
disjointExpressionConsolidation
conSpec :: Strat
conSpec = Step -> Strat
forall s. ToStep s => s -> Strat
bottomup ((Transformation -> Step
one (String -> Transformation -> Transformation
named String
"appPropCS" Transformation
appProp) Step -> Step -> Step
forall a. Strategic a => a -> a -> a
!->
Strat -> Step
nested (Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
constantSpec)) Step -> Step -> Step
forall a. Strategic a => a -> a -> a
>-!
Transformation -> Step
one Transformation
constantSpec)
transPropagateAndInline :: Step
transPropagateAndInline :: Step
transPropagateAndInline = [Transformation] -> Step
chain
[ Transformation
appProp
, Transformation
bindConstantVar
, Transformation
caseLet
, Transformation
caseCase
, Transformation
caseCon
, Transformation
caseDataToTag
, Transformation
elimExistentials
, Transformation
caseEliminateNonReachable
, Transformation
removeUnusedExpr
, Transformation
inlineWorkFree
, Transformation
inlineSmall
, Transformation
inlineOrLiftNonRep
, Transformation
reducePrim
, Transformation
caseCast
, Transformation
letCast
, Transformation
splitCastWork
, Transformation
argCastSpec
, Transformation
inlineCast
, Transformation
elimCastCast
]
inlineNR :: Strat
inlineNR :: Strat
inlineNR =
Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
deadCode
Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>-! String -> Name -> Strat
pass String
"inlineNonRep" 'inlineNonRep
specTransformations :: Step
specTransformations :: Step
specTransformations = [Transformation] -> Step
chain
[ Transformation
typeSpec
, Transformation
nonRepSpec
, Transformation
zeroWidthSpec
]
flattenSpec :: Strat
flattenSpec :: Strat
flattenSpec =
Strat -> Strat
repeatR (Step -> Strat
forall s. ToStep s => s -> Strat
bottomup (Transformation -> Step
one Transformation
flattenLet Step -> Step -> Step
forall a. Strategic a => a -> a -> a
>->
(Transformation -> Step
one Transformation
reduceConst Step -> Step -> Step
forall a. Strategic a => a -> a -> a
!-> Transformation -> Step
one Transformation
deadCode) Step -> Step -> Step
forall a. Strategic a => a -> a -> a
>->
[Transformation] -> Step
chain [ Transformation
reducePrim
, Transformation
removeUnusedExpr
]) Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Step -> Strat
forall s. ToStep s => s -> Strat
topdownFix ([Transformation] -> Step
chain [ String -> Transformation -> Transformation
named String
"appProp" Transformation
appProp
, Transformation
bindConstantVar
, Transformation
caseCon
])) Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
!->
Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
deadCode Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
letTL Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Transformation -> Strat
forall s. ToStep s => s -> Strat
topdownSuc Transformation
collapseRHSNoops Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Transformation -> Strat
forall s. ToStep s => s -> Strat
topdownSuc Transformation
inlineCleanup Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
caseCon Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
flattenLet Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Transformation -> Strat
forall s. ToStep s => s -> Strat
bottomup Transformation
bindConstantVar Strat -> Strat -> Strat
forall a. Strategic a => a -> a -> a
>->
Strat
letTL
where
letTL :: Strat
letTL = Transformation -> Strat
forall s. ToStep s => s -> Strat
topdownSuc Transformation
topLet