Added code to handle whole channels being passed to PROCs in the usage checking, and made sure they still obey the SHARED pragma
This commit is contained in:
parent
3bdc5d0ff6
commit
68f808583b
|
@ -299,19 +299,34 @@ foldUnionVarsBK
|
||||||
checkPlainVarUsage :: forall m. (MonadIO m, Die m, CSMR m) => NameAttr -> (Meta, ParItems (BK, UsageLabel)) -> m ()
|
checkPlainVarUsage :: forall m. (MonadIO m, Die m, CSMR m) => NameAttr -> (Meta, ParItems (BK, UsageLabel)) -> m ()
|
||||||
checkPlainVarUsage sharedAttr (m, p) = check p
|
checkPlainVarUsage sharedAttr (m, p) = check p
|
||||||
where
|
where
|
||||||
addBK :: BK -> Vars -> VarsBK
|
addBK :: BK -> Vars -> m VarsBK
|
||||||
addBK bk vs = VarsBK (Map.fromAscList $ zip (Set.toAscList $ readVars vs) (repeat bk))
|
addBK bk vs
|
||||||
((Map.map (\me -> (maybeToList me, bk)) $ writtenVars vs)
|
= do let read = Map.fromAscList $ zip (Set.toAscList $ readVars vs) (repeat bk)
|
||||||
`Map.union` Map.fromAscList (zip (Set.toAscList $ usedVars
|
splitUsed <- splitEnds' $ Set.toList $ usedVars vs
|
||||||
vs) (repeat ([], bk))))
|
splitWritten <- concatMapM splitEnds (Map.toList $ writtenVars vs) >>* Map.fromList
|
||||||
|
let used = Map.fromList (zip splitUsed (repeat ([], bk)))
|
||||||
|
return $ VarsBK read
|
||||||
|
((Map.map (\me -> (maybeToList me, bk)) splitWritten)
|
||||||
|
`Map.union` used)
|
||||||
|
|
||||||
|
splitEnds' = liftM (map fst) . concatMapM splitEnds . flip zip (repeat ())
|
||||||
|
|
||||||
|
splitEnds :: (Var, a) -> m [(Var, a)]
|
||||||
|
splitEnds (Var v, x)
|
||||||
|
= do t <- astTypeOf v
|
||||||
|
case t of
|
||||||
|
A.Chan {} -> return
|
||||||
|
[(Var $ A.DirectedVariable (findMeta v) dir v, x)
|
||||||
|
| dir <- [A.DirInput, A.DirOutput]]
|
||||||
|
_ -> return [(Var v, x)]
|
||||||
|
|
||||||
reps (RepParItem r p) = r : reps p
|
reps (RepParItem r p) = r : reps p
|
||||||
reps (SeqItems _) = []
|
reps (SeqItems _) = []
|
||||||
reps (ParItems ps) = concatMap reps ps
|
reps (ParItems ps) = concatMap reps ps
|
||||||
|
|
||||||
getVars :: ParItems (BK, UsageLabel) -> Map.Map Var (Maybe BK, Maybe BK)
|
getVars :: ParItems (BK, UsageLabel) -> m (Map.Map Var (Maybe BK, Maybe BK))
|
||||||
getVars (SeqItems ss) = foldUnionVarsBK $ [addBK bk $ nodeVars u | (bk, u) <- ss]
|
getVars (SeqItems ss) = liftM foldUnionVarsBK $ sequence [addBK bk $ nodeVars u | (bk, u) <- ss]
|
||||||
getVars (ParItems ps) = foldl (Map.unionWith join) Map.empty (map getVars ps)
|
getVars (ParItems ps) = liftM (foldl (Map.unionWith join) Map.empty) (mapM getVars ps)
|
||||||
where
|
where
|
||||||
join a b = (f (fst a) (fst b), f (snd a) (snd b))
|
join a b = (f (fst a) (fst b), f (snd a) (snd b))
|
||||||
f Nothing x = x
|
f Nothing x = x
|
||||||
|
@ -344,13 +359,21 @@ checkPlainVarUsage sharedAttr (m, p) = check p
|
||||||
-- A quick way to do this is to do a fold-union across all the maps, turning
|
-- A quick way to do this is to do a fold-union across all the maps, turning
|
||||||
-- the values into lists that can then be scanned for any problems.
|
-- the values into lists that can then be scanned for any problems.
|
||||||
check (ParItems ps)
|
check (ParItems ps)
|
||||||
= do sharedNames <- getCompState >>* csNameAttr >>* Map.filter (Set.member sharedAttr)
|
= do rawSharedNames <- getCompState >>* csNameAttr >>* Map.filter (Set.member sharedAttr)
|
||||||
>>* Map.keysSet >>* (Set.map $ UsageCheckUtils.Var . A.Variable emptyMeta . A.Name emptyMeta)
|
>>* Map.keysSet
|
||||||
|
-- We add in the directed versions of each (channel or not) so that
|
||||||
|
-- we make sure to ignore c? when c is shared:
|
||||||
|
let allSharedNames
|
||||||
|
= Set.fromList $ concatMap (map UsageCheckUtils.Var .
|
||||||
|
flip applyAll [id, A.DirectedVariable emptyMeta A.DirInput
|
||||||
|
, A.DirectedVariable emptyMeta A.DirOutput]
|
||||||
|
. A.Variable emptyMeta . A.Name emptyMeta) $ Set.toList rawSharedNames
|
||||||
let decl = concatMap getDecl ps
|
let decl = concatMap getDecl ps
|
||||||
filt <- filterPlain
|
filt <- filterPlain
|
||||||
|
vars <- mapM getVars ps
|
||||||
let examineVars =
|
let examineVars =
|
||||||
map (filterMapByKey filt . (`difference` (Set.fromList decl `Set.union` sharedNames)))
|
map (filterMapByKey filt . (`difference` (Set.fromList decl `Set.union` allSharedNames)))
|
||||||
(map getVars ps)
|
vars
|
||||||
checkCREW examineVars
|
checkCREW examineVars
|
||||||
where
|
where
|
||||||
difference m s = m `Map.difference` (Map.fromAscList $ zip (Set.toAscList
|
difference m s = m `Map.difference` (Map.fromAscList $ zip (Set.toAscList
|
||||||
|
|
|
@ -147,6 +147,8 @@ checkConstants = occamOnlyPass "Check mandatory constants"
|
||||||
return o
|
return o
|
||||||
doOption o = return o
|
doOption o = return o
|
||||||
|
|
||||||
|
-- | Turns things like cs[0]? into cs?[0], which helps later on in the usage checking
|
||||||
|
-- (as we can consider cs? a different array than cs!).
|
||||||
pushUpDirections :: Pass
|
pushUpDirections :: Pass
|
||||||
pushUpDirections = occamOnlyPass "Push up direction specifiers on arrays"
|
pushUpDirections = occamOnlyPass "Push up direction specifiers on arrays"
|
||||||
[] []
|
[] []
|
||||||
|
|
|
@ -769,6 +769,8 @@ inferTypes = occamOnlyPass "Infer types"
|
||||||
A.Array _ (A.ChanEnd dir _ _) ->
|
A.Array _ (A.ChanEnd dir _ _) ->
|
||||||
do v'' <- makeEnd m dir v'
|
do v'' <- makeEnd m dir v'
|
||||||
return (t', v'')
|
return (t', v'')
|
||||||
|
-- TODO infer direction of IS channel type
|
||||||
|
-- We will need the body!
|
||||||
_ -> return (t', v')
|
_ -> return (t', v')
|
||||||
return $ A.Is m am' t'' v''
|
return $ A.Is m am' t'' v''
|
||||||
A.IsExpr m am t e ->
|
A.IsExpr m am t e ->
|
||||||
|
|
Loading…
Reference in New Issue
Block a user