blob: 63f73393f0cf1a6d16e71bd37fce05ac862f1218 [file]
/-
Copyright (c) 2019 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Lean.Compiler.IR.Basic
import Lean.Compiler.IR.FreeVars
import Lean.Compiler.IR.NormIds
namespace Lean.IR
partial def pushProjs (bs : Array FnBody) (alts : Array Alt) (altsF : Array IndexSet) (ctx : Array FnBody) (ctxF : IndexSet) : Array FnBody × Array Alt :=
if bs.isEmpty then (ctx.reverse, alts)
else
let b := bs.back
let bs := bs.pop
let done (_ : Unit) := (bs.push b ++ ctx.reverse, alts)
let skip (_ : Unit) := pushProjs bs alts altsF (ctx.push b) (b.collectFreeIndices ctxF)
let push (x : VarId) :=
if !ctxF.contains x.idx then
let alts := alts.mapIdx fun i alt => alt.modifyBody fun b' =>
if (altsF.get! i).contains x.idx then b.setBody b'
else b'
let altsF := altsF.map fun s => if s.contains x.idx then b.collectFreeIndices s else s
pushProjs bs alts altsF ctx ctxF
else
skip ()
match b with
| FnBody.vdecl x _ v _ =>
match v with
| Expr.proj _ _ => push x
| Expr.uproj _ _ => push x
| Expr.sproj _ _ _ => push x
| Expr.isShared _ => skip ()
| _ => done ()
| _ => done ()
partial def FnBody.pushProj (b : FnBody) : FnBody :=
let (bs, term) := b.flatten
let bs := modifyJPs bs pushProj
match term with
| .case tid x xType alts =>
let altsF := alts.map fun alt => alt.body.freeIndices
let (bs, alts) := pushProjs bs alts altsF #[] (mkIndexSet x.idx)
let alts := alts.map fun alt => alt.modifyBody pushProj
let term := FnBody.case tid x xType alts
reshape bs term
| _ => reshape bs term
/-- Push projections inside `case` branches. -/
def Decl.pushProj (d : Decl) : Decl :=
match d with
| .fdecl (body := b) .. => d.updateBody! b.pushProj |>.normalizeIds
| other => other
end Lean.IR