Commit acebba58 by Zachary Snow

struct conversion omits unused packing functions

parent d5a369ba
...@@ -12,6 +12,7 @@ import Data.List (elemIndex, sortOn) ...@@ -12,6 +12,7 @@ import Data.List (elemIndex, sortOn)
import Data.Tuple (swap) import Data.Tuple (swap)
import Control.Monad.Writer import Control.Monad.Writer
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -20,17 +21,33 @@ type TypeFunc = [Range] -> Type ...@@ -20,17 +21,33 @@ type TypeFunc = [Range] -> Type
type StructInfo = (Type, Map.Map Identifier (Range, Expr)) type StructInfo = (Type, Map.Map Identifier (Range, Expr))
type Structs = Map.Map TypeFunc StructInfo type Structs = Map.Map TypeFunc StructInfo
type Types = Map.Map Identifier Type type Types = Map.Map Identifier Type
type Idents = Set.Set Identifier
convert :: AST -> AST convert :: AST -> AST
convert = traverseDescriptions convertDescription convert = traverseDescriptions convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription description = convertDescription description =
traverseModuleItems (traverseExprs $ traverseNestedExprs $ convertOnlyExpr structs types) $ case description' of
traverseModuleItems (traverseTypes $ convertType structs) $ Part extern kw lifetime name ports items ->
traverseModuleItems (traverseAsgns $ convertAsgn structs types) $ Part extern kw lifetime name ports (items ++ funcs)
description' where
funcs = map packerFn usedStructs
usedStructs = filter (isNeeded . fst) $ Map.toList structs
isNeeded tf = Set.member (packerFnName tf) calledPackedFuncs
other ->
if Set.null calledPackedFuncs
then other
-- TODO: Add support for top-level TFs which use struct literals
else error $ "top-level TF cannot use a struct literal, yet: "
++ show other
where where
description' =
traverseModuleItems (traverseExprs $ traverseNestedExprs $ convertOnlyExpr structs types) $
traverseModuleItems (traverseTypes $ convertType structs) $
traverseModuleItems (traverseAsgns $ convertAsgn structs types) $
description
-- collect information about this description
structs = execWriter $ collectModuleItemsM structs = execWriter $ collectModuleItemsM
(collectTypesM collectType) description (collectTypesM collectType) description
typesA = execWriter $ collectModuleItemsM typesA = execWriter $ collectModuleItemsM
...@@ -38,18 +55,22 @@ convertDescription description = ...@@ -38,18 +55,22 @@ convertDescription description =
typesB = execWriter $ collectModuleItemsM typesB = execWriter $ collectModuleItemsM
collectFunction description collectFunction description
types = Map.union typesA typesB types = Map.union typesA typesB
description' = -- determine which of the packer functions we actually need
case description of calledFuncs = execWriter $ collectModuleItemsM
Part extern kw lifetime name ports items -> (collectExprsM $ collectNestedExprsM collectCalls) description'
Part extern kw lifetime name ports (items ++ funcs) packerFuncs = Set.map packerFnName $ Map.keysSet structs
where funcs = map packerFn $ Map.keys structs calledPackedFuncs = Set.intersection calledFuncs packerFuncs
other -> other
-- writes down the names of called functions
collectCalls :: Expr -> Writer Idents ()
collectCalls (Call f _) = tell $ Set.singleton f
collectCalls _ = return ()
-- produces a function -- produces a function which packs the components of a struct literal
packerFn :: TypeFunc -> ModuleItem packerFn :: (TypeFunc, StructInfo) -> ModuleItem
packerFn structTf = packerFn (structTf, (flatType, _)) =
MIPackageItem $ MIPackageItem $
Function Nothing (structTf []) fnName decls [retStmt] Function Nothing flatType fnName decls [retStmt]
where where
Struct (Packed _) fields [] = structTf [] Struct (Packed _) fields [] = structTf []
toInput (t, x) = Variable Input t x [] Nothing toInput (t, x) = Variable Input t x [] Nothing
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment