feat: LCNF.simp .let case
This commit is contained in:
parent
7b161d33d1
commit
ca80bc52dc
3 changed files with 33 additions and 8 deletions
|
|
@ -16,7 +16,6 @@ structure State where
|
|||
map : Std.PHashMap Expr FVarId := {}
|
||||
subst : FVarSubst := {}
|
||||
|
||||
|
||||
abbrev M := StateRefT State CompilerM
|
||||
|
||||
instance : MonadFVarSubst M where
|
||||
|
|
@ -29,16 +28,13 @@ instance : MonadFVarSubst M where
|
|||
@[inline] def addEntry (value : Expr) (fvarId : FVarId) : M Unit :=
|
||||
modify fun s => { s with map := s.map.insert value fvarId }
|
||||
|
||||
@[inline] def addSubst (fvarId fvarId' : FVarId) : M Unit :=
|
||||
modify fun s => { s with subst := s.subst.insert fvarId (.fvar fvarId') }
|
||||
|
||||
@[inline] def withNewScope (x : M α) : M α := do
|
||||
let map := (← get).map
|
||||
try x finally modify fun s => { s with map }
|
||||
|
||||
def replaceFVar (fvarId fvarId' : FVarId) : M Unit := do
|
||||
eraseFVar fvarId
|
||||
addSubst fvarId fvarId'
|
||||
addFVarSubst fvarId fvarId'
|
||||
|
||||
end CSE
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ partial def elimDead (code : Code) : M Code := do
|
|||
match code with
|
||||
| .let decl k =>
|
||||
let k ← elimDead k
|
||||
if (← get).contains decl.fvarId then
|
||||
if !decl.pure || (← get).contains decl.fvarId then
|
||||
/- Remark: we don't need to collect `decl.type` because LCNF local declarations do not occur in types. -/
|
||||
collectExprM decl.value
|
||||
return code.updateCont! k
|
||||
|
|
|
|||
|
|
@ -199,18 +199,47 @@ def incVisited : SimpM Unit :=
|
|||
def markUsedFVar (fvarId : FVarId) : SimpM Unit :=
|
||||
modify fun s => { s with used := s.used.insert fvarId }
|
||||
|
||||
def markUsedExpr (e : Expr) : SimpM Unit :=
|
||||
modify fun s => { s with used := collectLocalDecls s.used e }
|
||||
|
||||
def markUsedLetDecl (letDecl : LetDecl) : SimpM Unit :=
|
||||
markUsedExpr letDecl.value
|
||||
|
||||
def isUsed (fvarId : FVarId) : SimpM Bool :=
|
||||
return (← get).used.contains fvarId
|
||||
|
||||
def eraseLetDecl (decl : LetDecl) : SimpM Unit := do
|
||||
eraseFVar decl.fvarId
|
||||
markSimplified
|
||||
|
||||
mutual
|
||||
|
||||
partial def simp (code : Code) : SimpM Code := do
|
||||
-- TODO
|
||||
incVisited
|
||||
match code with
|
||||
| .let decl k =>
|
||||
let decl ← normLetDecl decl
|
||||
if decl.value.isFVar then
|
||||
/- Eliminate `let _x_i := _x_j;` -/
|
||||
addSubst decl.fvarId decl.value
|
||||
eraseLetDecl decl
|
||||
simp k
|
||||
else
|
||||
/- TODO: simple value simplifications & inlining -/
|
||||
let k ← simp k
|
||||
if !decl.pure || (← isUsed decl.fvarId) then
|
||||
markUsedLetDecl decl
|
||||
return code.updateLet! decl k
|
||||
else
|
||||
/- Dead variable elimination -/
|
||||
eraseLetDecl decl
|
||||
return k
|
||||
| .return fvarId =>
|
||||
let fvarId ← normFVar fvarId
|
||||
markUsedFVar fvarId
|
||||
return code.updateReturn! fvarId
|
||||
| .unreach .. => return code
|
||||
| _ => return code
|
||||
| _ => return code -- TODO: implement other cases
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue