Skip to content

Commit 5af9572

Browse files
Merge pull request #1040 from clash-lang/appPropDeshadow
Ensure we properly deshadow in AppProp
2 parents 3d12190 + e087036 commit 5af9572

File tree

6 files changed

+110
-84
lines changed

6 files changed

+110
-84
lines changed

clash-lib/src/Clash/Core/Evaluator.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ scrutinise (Lit l) alts m = case alts of
438438
go def (_:alts1) = go def alts1
439439

440440
scrutinise (DC dc xs) alts m
441-
| altE:_ <- [substAlt altDc tvs pxs xs altE
441+
| altE:_ <- [substInAlt altDc tvs pxs xs altE
442442
| (DataPat altDc tvs pxs,altE) <- alts, altDc == dc ] ++
443443
[altE | (DefaultPat,altE) <- alts ]
444444
= setTerm altE m
@@ -468,8 +468,8 @@ scrutinise v@(PrimVal p _ vs) alts m
468468

469469
scrutinise v alts _ = error ("scrutinise: " ++ showPpr (Case (valToTerm v) (ConstTy Arrow) alts))
470470

471-
substAlt :: DataCon -> [TyVar] -> [Id] -> [Either Term Type] -> Term -> Term
472-
substAlt dc tvs xs args e = substTm "Evaluator.substAlt" subst e
471+
substInAlt :: DataCon -> [TyVar] -> [Id] -> [Either Term Type] -> Term -> Term
472+
substInAlt dc tvs xs args e = substTm "Evaluator.substInAlt" subst e
473473
where
474474
tys = rights args
475475
tms = lefts args

clash-lib/src/Clash/Core/Subst.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ module Clash.Core.Subst
3939
, extendGblSubstList
4040
-- ** Applying substitutions
4141
, substTm
42+
, substAlt
4243
-- * Variable renaming
4344
, deShadowTerm
45+
, deShadowAlt
4446
, freshenTm
4547
-- * Alpha equivalence
4648
, aeqType
@@ -491,6 +493,21 @@ substTm doc subst = go where
491493
goTick t@DeDup = t
492494
goTick t@NoDeDup = t
493495

496+
-- | Substitute within a case-alternative
497+
substAlt
498+
:: HasCallStack
499+
=> Doc ()
500+
-> Subst
501+
-- ^ The substitution
502+
-> (Pat, Term)
503+
-- ^ The alternative in which to apply the substitution
504+
-> (Pat, Term)
505+
substAlt doc subst (pat,alt) = case pat of
506+
DataPat dc tvs ids -> case List.mapAccumL substTyVarBndr' subst tvs of
507+
(subst1,tvs1) -> case List.mapAccumL substIdBndr subst1 ids of
508+
(subst2,ids1) -> (DataPat dc tvs1 ids1,substTm doc subst2 alt)
509+
_ -> (pat, substTm doc subst alt)
510+
494511
-- | Find the substitution for an 'Id' in the 'Subst'
495512
lookupIdSubst
496513
:: HasCallStack
@@ -596,6 +613,15 @@ deShadowTerm
596613
-> Term
597614
deShadowTerm is e = substTm "deShadowTerm" (mkSubst is) e
598615

616+
-- | Ensure that non of the binders in an alternative shadow each-other, nor
617+
-- conflict with the in-scope set
618+
deShadowAlt ::
619+
HasCallStack =>
620+
InScopeSet ->
621+
(Pat, Term) ->
622+
(Pat, Term)
623+
deShadowAlt is = substAlt "deShadowAlt" (mkSubst is)
624+
599625
-- | A much stronger variant of `deShadowTerm` that ensures that all bound
600626
-- variables are unique.
601627
--

clash-lib/src/Clash/Normalize.hs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import Clash.Core.FreeVars
4747
import Clash.Core.Name (nameOcc) -- TODO
4848
import Clash.Core.Pretty (showPpr, ppr)
4949
import Clash.Core.Subst
50-
(deShadowTerm, extendGblSubstList, mkSubst, substTm)
50+
(extendGblSubstList, mkSubst, substTm)
5151
import Clash.Core.Term (Term (..), collectArgsTicks)
5252
import Clash.Core.Type (Type, splitCoreFunForallTy)
5353
import Clash.Core.TyCon
@@ -321,9 +321,7 @@ flattenCallTree (CBranch (nm,(nm',sp,inl,tm)) used) = do
321321
newExpr <- case toInline of
322322
[] -> return tm
323323
_ -> do
324-
-- To have a cheap `appProp` transformation we need to
325-
-- deshadow, see also Note [AppProp no-shadow invariant]
326-
let tm1 = deShadowTerm emptyInScopeSet (substTm "flattenCallTree.flattenExpr" subst tm)
324+
let tm1 = substTm "flattenCallTree.flattenExpr" subst tm
327325
#ifdef HISTORY
328326
-- NB: When HISTORY is on, emit binary data holding the recorded rewrite steps
329327
let !_ = unsafePerformIO
@@ -347,9 +345,7 @@ flattenCallTree (CBranch (nm,(nm',sp,inl,tm)) used) = do
347345
let (toInline',allUsed') = unzip (map goCheap allUsed)
348346
subst' = extendGblSubstList (mkSubst emptyInScopeSet)
349347
(Maybe.catMaybes toInline')
350-
-- To have a cheap `appProp` transformation we need to
351-
-- deshadow, see also Note [AppProp no-shadow invariant]
352-
let tm1 = deShadowTerm emptyInScopeSet (substTm "flattenCallTree.flattenCheap" subst' newExpr)
348+
let tm1 = substTm "flattenCallTree.flattenCheap" subst' newExpr
353349
newExpr' <- rewriteExpr ("flattenCheap",flatten) (showPpr nm, tm1) (nm', sp)
354350
return (CBranch (nm,(nm',sp,inl,newExpr')) (concat allUsed'))
355351
else return (CBranch (nm,(nm',sp,inl,newExpr)) allUsed)

0 commit comments

Comments
 (0)