Commit 5b2165d7 by Zachary Snow

fix inefficiencies in unpacked array conversion

- don't evaluate AST after depth collection
- don't use State monad during rewrite
- add Scoper utility for generating accesses without inserting element
- cleanup as-patterns and unnecessary verbosity
parent 9bc946ce
...@@ -41,6 +41,8 @@ module Convert.Scoper ...@@ -41,6 +41,8 @@ module Convert.Scoper
, injectDecl , injectDecl
, lookupElem , lookupElem
, lookupElemM , lookupElemM
, localAccesses
, localAccessesM
, Access(..) , Access(..)
, ScopeKey , ScopeKey
, Scopes , Scopes
...@@ -300,11 +302,18 @@ lookupAccesses scopes accesses = do ...@@ -300,11 +302,18 @@ lookupAccesses scopes accesses = do
let side = resolveInScope (sMapping scopes) [] accesses let side = resolveInScope (sMapping scopes) [] accesses
if isNothing deep then side else deep if isNothing deep then side else deep
localAccesses :: Scopes a -> Identifier -> [Access]
localAccesses scopes ident =
foldr ((:) . toAccess) [Access ident Nil] (sCurrent scopes)
localAccessesM :: Monad m => Identifier -> ScoperT a m [Access]
localAccessesM = embedScopes localAccesses
lookupLocalIdent :: Scopes a -> Identifier -> LookupResult a lookupLocalIdent :: Scopes a -> Identifier -> LookupResult a
lookupLocalIdent scopes ident = do lookupLocalIdent scopes ident = do
(replacements, element) <- directResolve (sMapping scopes) accesses (replacements, element) <- directResolve (sMapping scopes) accesses
Just (accesses, replacements, element) Just (accesses, replacements, element)
where accesses = map toAccess (sCurrent scopes) ++ [Access ident Nil] where accesses = localAccesses scopes ident
toAccess :: Tier -> Access toAccess :: Tier -> Access
toAccess (Tier x "") = Access x Nil toAccess (Tier x "") = Access x Nil
......
...@@ -20,71 +20,57 @@ import Language.SystemVerilog.AST ...@@ -20,71 +20,57 @@ import Language.SystemVerilog.AST
type Location = [Identifier] type Location = [Identifier]
type Locations = Map.Map Location Int type Locations = Map.Map Location Int
type ST = ScoperT Decl (State Locations) type ST = ScoperT () (State Locations)
convert :: [AST] -> [AST] convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription (description @ (Part _ _ Module _ _ ports _)) = convertDescription description@(Part _ _ Module _ _ ports _) =
evalState (operation description) Map.empty partScoper (rewriteDeclM locations) return return return description
where where
locations = execState (operation description) Map.empty
operation = partScoperT operation = partScoperT
(traverseDeclM ports) traverseModuleItemM noop traverseStmtM >=> (traverseDeclM ports) traverseModuleItemM return traverseStmtM
partScoperT rewriteDeclM noop noop noop
noop = return
convertDescription other = other convertDescription other = other
-- tracks multi-dimensional unpacked array declarations -- tracks multi-dimensional unpacked array declarations
traverseDeclM :: [Identifier] -> Decl -> ST Decl traverseDeclM :: [Identifier] -> Decl -> ST Decl
traverseDeclM _ (decl @ (Variable _ _ _ [] e)) = traverseDeclM _ decl@(Variable _ _ _ [] e) =
traverseExprArgsM e >> return decl traverseExprArgsM e >> return decl
traverseDeclM ports (decl @ (Variable dir _ x _ e)) = do traverseDeclM ports decl@(Variable dir _ x _ e) = do
insertElem x decl insertElem x ()
if dir /= Local || elem x ports || e /= Nil when (dir /= Local || elem x ports || e /= Nil) $
then flatUsageM x flatUsageM x
else return ()
traverseExprArgsM e >> return decl traverseExprArgsM e >> return decl
traverseDeclM ports decl @ Net{} = traverseDeclM ports decl@Net{} =
traverseNetAsVarM (traverseDeclM ports) decl traverseNetAsVarM (traverseDeclM ports) decl
traverseDeclM _ other = return other traverseDeclM _ other = return other
-- pack decls marked for packing -- pack decls marked for packing
rewriteDeclM :: Decl -> ST Decl rewriteDeclM :: Locations -> Decl -> Scoper () Decl
rewriteDeclM (decl @ (Variable _ _ _ [] _)) = return decl rewriteDeclM _ decl@(Variable _ _ _ [] _) = return decl
rewriteDeclM (decl @ (Variable d t x a e)) = do rewriteDeclM locations decl@(Variable d t x a e) = do
insertElem x decl accesses <- localAccessesM x
details <- lookupElemM x
let Just (accesses, _, _) = details
let location = map accessName accesses let location = map accessName accesses
usedAsPacked <- lift $ gets $ Map.lookup location case Map.lookup location locations of
case usedAsPacked of
Just depth -> do Just depth -> do
let (tf, rs) = typeRanges t let (tf, rs) = typeRanges t
let (unpacked, packed) = splitAt depth a let (unpacked, packed) = splitAt depth a
let t' = tf $ packed ++ rs let t' = tf $ packed ++ rs
return $ Variable d t' x unpacked e return $ Variable d t' x unpacked e
Nothing -> return decl Nothing -> return decl
rewriteDeclM decl @ Net{} = traverseNetAsVarM rewriteDeclM decl rewriteDeclM locations decl@Net{} =
rewriteDeclM other = return other traverseNetAsVarM (rewriteDeclM locations) decl
rewriteDeclM _ other = return other
traverseModuleItemM :: ModuleItem -> ST ModuleItem traverseModuleItemM :: ModuleItem -> ST ModuleItem
traverseModuleItemM = traverseModuleItemM item@(Instance _ _ _ _ bindings) =
traverseModuleItemM' mapM_ (flatUsageM . snd) bindings >> return item
>=> traverseLHSsM traverseLHSM traverseModuleItemM item =
>=> traverseExprsM traverseExprM traverseLHSsM traverseLHSM item
>=> traverseAsgnsM traverseAsgnM >>= traverseExprsM traverseExprM
>>= traverseAsgnsM traverseAsgnM
traverseModuleItemM' :: ModuleItem -> ST ModuleItem
traverseModuleItemM' (Instance a b c d bindings) = do
bindings' <- mapM collectBinding bindings
return $ Instance a b c d bindings'
where
collectBinding :: PortBinding -> ST PortBinding
collectBinding (y, x) = do
flatUsageM x
return (y, x)
traverseModuleItemM' other = return other
traverseStmtM :: Stmt -> ST Stmt traverseStmtM :: Stmt -> ST Stmt
traverseStmtM = traverseStmtM =
...@@ -94,9 +80,9 @@ traverseStmtM = ...@@ -94,9 +80,9 @@ traverseStmtM =
traverseStmtArgsM traverseStmtArgsM
traverseStmtArgsM :: Stmt -> ST Stmt traverseStmtArgsM :: Stmt -> ST Stmt
traverseStmtArgsM stmt @ (Subroutine (Ident ('$' : _)) _) = traverseStmtArgsM stmt@(Subroutine (Ident ('$' : _)) _) =
return stmt return stmt
traverseStmtArgsM stmt @ (Subroutine _ (Args args [])) = traverseStmtArgsM stmt@(Subroutine _ (Args args [])) =
mapM_ flatUsageM args >> return stmt mapM_ flatUsageM args >> return stmt
traverseStmtArgsM stmt = return stmt traverseStmtArgsM stmt = return stmt
...@@ -106,8 +92,8 @@ traverseExprM (Range x mode i) = ...@@ -106,8 +92,8 @@ traverseExprM (Range x mode i) =
traverseExprM expr = traverseExprArgsM expr traverseExprM expr = traverseExprArgsM expr
traverseExprArgsM :: Expr -> ST Expr traverseExprArgsM :: Expr -> ST Expr
traverseExprArgsM expr @ (Call _ (Args args [])) = traverseExprArgsM expr@(Call _ (Args args [])) =
mapM_ (traverseExprArgsM >> flatUsageM) args >> return expr mapM_ (traverseExprArgsM >=> flatUsageM) args >> return expr
traverseExprArgsM expr = traverseExprArgsM expr =
traverseSinglyNestedExprsM traverseExprArgsM expr traverseSinglyNestedExprsM traverseExprArgsM expr
...@@ -150,7 +136,7 @@ flatUsageM k = do ...@@ -150,7 +136,7 @@ flatUsageM k = do
let (k', depth) = unbit k let (k', depth) = unbit k
details <- lookupElemM k' details <- lookupElemM k'
case details of case details of
Just (accesses, _, _) -> do Just (accesses, _, ()) -> do
let location = map accessName accesses let location = map accessName accesses
lift $ modify $ Map.insertWith min location depth lift $ modify $ Map.insertWith min location depth
Nothing -> return () Nothing -> return ()
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