Implements (extended) λPure and λRc proposed in the article "Counting Immutable Beans", Sebastian Ullrich and Leonardo de Moura.
The Lean to IR transformation produces λPure code, and this part is implemented in C++. The procedures described in the paper above are implemented in Lean.
Function identifier
Equations
Variable identifier
- idx : Index
Equations
- Lean.IR.instInhabitedVarId = { default := { idx := default } }
Equations
- Lean.IR.instReprVarId = { reprPrec := Lean.IR.reprVarId✝ }
Equations
- Lean.IR.instInhabitedJoinPointId = { default := { idx := default } }
Equations
- Lean.IR.instReprJoinPointId = { reprPrec := Lean.IR.reprJoinPointId✝ }
Equations
- Lean.IR.instBEqVarId = { beq := fun (a b : Lean.IR.VarId) => a.idx == b.idx }
Equations
- Lean.IR.instToStringVarId = { toString := fun (a : Lean.IR.VarId) => "x_" ++ toString a.idx }
Equations
- Lean.IR.instToFormatVarId = { format := fun (a : Lean.IR.VarId) => Std.Format.text (toString a) }
Equations
- Lean.IR.instHashableVarId = { hash := fun (a : Lean.IR.VarId) => hash a.idx }
Equations
- Lean.IR.instBEqJoinPointId = { beq := fun (a b : Lean.IR.JoinPointId) => a.idx == b.idx }
Equations
- Lean.IR.instToStringJoinPointId = { toString := fun (a : Lean.IR.JoinPointId) => "block_" ++ toString a.idx }
Equations
- Lean.IR.instToFormatJoinPointId = { format := fun (a : Lean.IR.JoinPointId) => Std.Format.text (toString a) }
Equations
- Lean.IR.instHashableJoinPointId = { hash := fun (a : Lean.IR.JoinPointId) => hash a.idx }
Equations
- Lean.IR.MData.empty = { entries := [] }
Low Level IR types. Most are self explanatory.
usize
represents the C++size_t
Type. We have it here because it is 32-bit in 32-bit machines, and 64-bit in 64-bit machines, and we want the C++ backend for our Compiler to generate platform independent code.irrelevant
for Lean types, propositions and proofs.object
a pointer to a value in the heap.tobject
a pointer to a value in the heap or tagged pointer (i.e., the least significant bit is 1) storing a scalar value.struct
andunion
are used to return small values (e.g.,Option
,Prod
,Except
) on the stack.
Remark: the RC operations for tobject
are slightly more expensive because we
first need to test whether the tobject
is really a pointer or not.
Remark: the Lean runtime assumes that sizeof(void*) == sizeof(sizeT). Lean cannot be compiled on old platforms where this is not True.
Since values of type struct
and union
are only used to return values,
We assume they must be used/consumed "linearly". We use the term "linear" here
to mean "exactly once" in each execution. That is, given x : S
, where S
is a struct,
then one of the following must hold in each (execution) branch.
1- x
occurs only at a single ret x
instruction. That is, it is being consumed by being returned.
2- x
occurs only at a single ctor
. That is, it is being "consumed" by being stored into another struct/union
.
3- We extract (aka project) every single field of x
exactly once. That is, we are consuming x
by consuming each
of one of its components. Minor refinement: we don't need to consume scalar fields or struct/union
fields that do not contain object fields.
Equations
- Lean.IR.instInhabitedIRType = { default := Lean.IR.IRType.float }
Equations
- Lean.IR.instReprIRType = { reprPrec := Lean.IR.reprIRType✝ }
Equations
- Lean.IR.IRType.instBEq = { beq := Lean.IR.IRType.beq }
Equations
Arguments to applications, constructors, etc.
We use irrelevant
for Lean types, propositions and proofs that have been erased.
Recall that for a Function f
, we also generate f._rarg
which does not take
irrelevant
arguments. However, f._rarg
is only safe to be used in full applications.
Equations
- Lean.IR.instInhabitedArg = { default := Lean.IR.Arg.var default }
Equations
- (Lean.IR.Arg.var x_2).beq (Lean.IR.Arg.var y) = (x_2 == y)
- Lean.IR.Arg.irrelevant.beq Lean.IR.Arg.irrelevant = true
- x✝¹.beq x✝ = false
Equations
- Lean.IR.mkVarArg id = Lean.IR.Arg.var id
Instances For
Equations
- (Lean.IR.LitVal.num v₁).beq (Lean.IR.LitVal.num v₂) = (v₁ == v₂)
- (Lean.IR.LitVal.str v₁).beq (Lean.IR.LitVal.str v₂) = (v₁ == v₂)
- x✝¹.beq x✝ = false
Equations
- Lean.IR.instBEqLitVal = { beq := Lean.IR.LitVal.beq }
Constructor information.
name
is the Name of the Constructor in Lean.cidx
is the Constructor index (aka tag).size
is the number of arguments of typeobject/tobject
.usize
is the number of arguments of typeusize
.ssize
is the number of bytes used to store scalar values.
Recall that a Constructor object contains a header, then a sequence of
pointers to other Lean objects, a sequence of USize
(i.e., size_t
)
scalar values, and a sequence of other scalar values.
Equations
- Lean.IR.instReprCtorInfo = { reprPrec := Lean.IR.reprCtorInfo✝ }
Equations
- One or more equations did not get rendered due to their size.
Equations
- Lean.IR.instBEqCtorInfo = { beq := Lean.IR.CtorInfo.beq }
- ctor (i : CtorInfo) (ys : Array Arg) : Expr
- reset (n : Nat) (x : VarId) : Expr
- reuse (x : VarId) (i : CtorInfo) (updtHeader : Bool) (ys : Array Arg) : Expr
- proj (i : Nat) (x : VarId) : Expr
- uproj
(i : Nat)
(x : VarId)
: Expr
Extract the
Usize
value at Positionsizeof(void*)*i
fromx
. - sproj
(n offset : Nat)
(x : VarId)
: Expr
Extract the scalar value at Position
sizeof(void*)*n + offset
fromx
. - fap
(c : FunId)
(ys : Array Arg)
: Expr
Full application.
- pap
(c : FunId)
(ys : Array Arg)
: Expr
Partial application that creates a
pap
value (aka closure in our nonstandard terminology). - ap (x : VarId) (ys : Array Arg) : Expr
- box (ty : IRType) (x : VarId) : Expr
- unbox
(x : VarId)
: Expr
Given
x : [t]object
, obtain the scalar value. - lit (v : LitVal) : Expr
Equations
- Lean.IR.mkCtorExpr n cidx size usize ssize ys = Lean.IR.Expr.ctor { name := n, cidx := cidx, size := size, usize := usize, ssize := ssize } ys
Equations
- Lean.IR.mkProjExpr i x = Lean.IR.Expr.proj i x
Equations
- Lean.IR.mkUProjExpr i x = Lean.IR.Expr.uproj i x
Equations
- Lean.IR.mkSProjExpr n offset x = Lean.IR.Expr.sproj n offset x
Equations
- Lean.IR.mkFAppExpr c ys = Lean.IR.Expr.fap c ys
Equations
- Lean.IR.mkPAppExpr c ys = Lean.IR.Expr.pap c ys
Equations
- Lean.IR.mkAppExpr x ys = Lean.IR.Expr.ap x ys
Equations
Equations
Equations
- Lean.IR.instInhabitedParam = { default := { x := default, borrow := default, ty := default } }
Equations
- Lean.IR.instReprParam = { reprPrec := Lean.IR.reprParam✝ }
Equations
- Lean.IR.mkParam x borrow ty = { x := x, borrow := borrow, ty := ty }
- vdecl (x : VarId) (ty : IRType) (e : Expr) (b : FnBody) : FnBody
- jdecl
(j : JoinPointId)
(xs : Array Param)
(v b : FnBody)
: FnBody
Join point Declaration
block_j (xs) := e; b
- set (x : VarId) (i : Nat) (y : Arg) (b : FnBody) : FnBody
- setTag (x : VarId) (cidx : Nat) (b : FnBody) : FnBody
- uset (x : VarId) (i : Nat) (y : VarId) (b : FnBody) : FnBody
- sset (x : VarId) (i offset : Nat) (y : VarId) (ty : IRType) (b : FnBody) : FnBody
- inc (x : VarId) (n : Nat) (c persistent : Bool) (b : FnBody) : FnBody
- dec (x : VarId) (n : Nat) (c persistent : Bool) (b : FnBody) : FnBody
- del (x : VarId) (b : FnBody) : FnBody
- mdata (d : MData) (b : FnBody) : FnBody
- case (tid : Name) (x : VarId) (xType : IRType) (cs : Array (AltCore FnBody)) : FnBody
- ret (x : Arg) : FnBody
- jmp
(j : JoinPointId)
(ys : Array Arg)
: FnBody
Jump to join point
j
- unreachable : FnBody
Equations
- Lean.IR.instInhabitedFnBody = { default := Lean.IR.FnBody.unreachable }
Equations
- Lean.IR.mkVDecl x ty e b = Lean.IR.FnBody.vdecl x ty e b
Equations
- Lean.IR.mkJDecl j xs v b = Lean.IR.FnBody.jdecl j xs v b
Equations
- Lean.IR.mkUSet x i y b = Lean.IR.FnBody.uset x i y b
Equations
- Lean.IR.mkSSet x i offset y ty b = Lean.IR.FnBody.sset x i offset y ty b
Equations
- Lean.IR.mkCase tid x cs = Lean.IR.FnBody.case tid x Lean.IR.IRType.object cs
Equations
Equations
- Lean.IR.mkJmp j ys = Lean.IR.FnBody.jmp j ys
Equations
Equations
Instances For
Equations
Equations
Equations
- Lean.IR.instInhabitedAlt = { default := Lean.IR.Alt.default default }
Equations
- (Lean.IR.FnBody.case tid x_1 xType cs).isTerminal = true
- (Lean.IR.FnBody.ret x_1).isTerminal = true
- (Lean.IR.FnBody.jmp j ys).isTerminal = true
- Lean.IR.FnBody.unreachable.isTerminal = true
- x✝.isTerminal = false
Equations
- (Lean.IR.FnBody.vdecl x_1 ty e b).body = b
- (Lean.IR.FnBody.jdecl j xs v b).body = b
- (Lean.IR.FnBody.set x_1 i y b).body = b
- (Lean.IR.FnBody.uset x_1 i y b).body = b
- (Lean.IR.FnBody.sset x_1 i offset y ty b).body = b
- (Lean.IR.FnBody.setTag x_1 cidx b).body = b
- (Lean.IR.FnBody.inc x_1 n c persistent b).body = b
- (Lean.IR.FnBody.dec x_1 n c persistent b).body = b
- (Lean.IR.FnBody.del x_1 b).body = b
- (Lean.IR.FnBody.mdata d b).body = b
- x✝.body = x✝
Equations
- (Lean.IR.FnBody.vdecl x_2 t v b).setBody x✝ = Lean.IR.FnBody.vdecl x_2 t v x✝
- (Lean.IR.FnBody.jdecl j xs v b).setBody x✝ = Lean.IR.FnBody.jdecl j xs v x✝
- (Lean.IR.FnBody.set x_2 i y b).setBody x✝ = Lean.IR.FnBody.set x_2 i y x✝
- (Lean.IR.FnBody.uset x_2 i y b).setBody x✝ = Lean.IR.FnBody.uset x_2 i y x✝
- (Lean.IR.FnBody.sset x_2 i o y t b).setBody x✝ = Lean.IR.FnBody.sset x_2 i o y t x✝
- (Lean.IR.FnBody.setTag x_2 i b).setBody x✝ = Lean.IR.FnBody.setTag x_2 i x✝
- (Lean.IR.FnBody.inc x_2 n c p b).setBody x✝ = Lean.IR.FnBody.inc x_2 n c p x✝
- (Lean.IR.FnBody.dec x_2 n c p b).setBody x✝ = Lean.IR.FnBody.dec x_2 n c p x✝
- (Lean.IR.FnBody.del x_2 b).setBody x✝ = Lean.IR.FnBody.del x_2 x✝
- (Lean.IR.FnBody.mdata d b).setBody x✝ = Lean.IR.FnBody.mdata d x✝
- x✝¹.setBody x✝ = x✝¹
Equations
Equations
- (Lean.IR.AltCore.ctor info b).body = b
- (Lean.IR.AltCore.default b).body = b
Equations
- (Lean.IR.AltCore.ctor c b).setBody x✝ = Lean.IR.Alt.ctor c x✝
- (Lean.IR.AltCore.default b).setBody x✝ = Lean.IR.Alt.default x✝
Equations
- Lean.IR.AltCore.modifyBody f (Lean.IR.AltCore.ctor c b) = Lean.IR.Alt.ctor c (f b)
- Lean.IR.AltCore.modifyBody f (Lean.IR.AltCore.default b) = Lean.IR.Alt.default (f b)
Equations
Equations
- Lean.IR.reshape bs term = Lean.IR.reshapeAux bs bs.size term
Equations
- Lean.IR.modifyJPs bs f = Array.map (fun (b : Lean.IR.FnBody) => match b with | Lean.IR.FnBody.jdecl j xs v k => Lean.IR.FnBody.jdecl j xs (f v) k | other => other) bs
Equations
- Lean.IR.mkAlt n cidx size usize ssize b = Lean.IR.Alt.ctor { name := n, cidx := cidx, size := size, usize := usize, ssize := ssize } b
Extra information associated with a declaration.
If
some <blame>
, then declaration depends on<blame>
which uses asorry
axiom.
Equations
- Lean.IR.instInhabitedDecl = { default := Lean.IR.Decl.extern default default default default }
Equations
- (Lean.IR.Decl.fdecl f xs type body info).name = f
- (Lean.IR.Decl.extern f xs type ext).name = f
Equations
- (Lean.IR.Decl.fdecl f xs type body info).params = xs
- (Lean.IR.Decl.extern f xs type ext).params = xs
Equations
- (Lean.IR.Decl.fdecl f xs type body info).resultType = type
- (Lean.IR.Decl.extern f xs type ext).resultType = type
Equations
- (Lean.IR.Decl.fdecl f xs type body info).updateBody! bNew = Lean.IR.Decl.fdecl f xs type bNew info
- d.updateBody! bNew = panicWithPosWithDecl "Lean.Compiler.IR.Basic" "Lean.IR.Decl.updateBody!" 433 9 "expected definition"
Equations
- Lean.IR.mkDecl f xs ty b = Lean.IR.Decl.fdecl f xs ty b { sorryDep? := none }
Equations
- Lean.IR.mkExternDecl f xs ty e = Lean.IR.Decl.extern f xs ty e
Equations
- Lean.IR.mkDummyExternDecl f xs ty = Lean.IR.Decl.fdecl f xs ty Lean.IR.FnBody.unreachable { sorryDep? := none }
Set of variable and join point names
Equations
Instances For
Equations
- Lean.IR.instInhabitedIndexSet = { default := ∅ }
Equations
- Lean.IR.mkIndexSet idx = Lean.RBTree.empty.insert idx
- param : IRType → LocalContextEntry
- localVar : IRType → Expr → LocalContextEntry
- joinPoint : Array Param → FnBody → LocalContextEntry
Equations
- ctx.addLocal x t v = Lean.RBMap.insert ctx x.idx (Lean.IR.LocalContextEntry.localVar t v)
Equations
- ctx.addJP j xs b = Lean.RBMap.insert ctx j.idx (Lean.IR.LocalContextEntry.joinPoint xs b)
Equations
- ctx.addParam p = Lean.RBMap.insert ctx p.x.idx (Lean.IR.LocalContextEntry.param p.ty)
Equations
- ctx.addParams ps = Array.foldl Lean.IR.LocalContext.addParam ctx ps
Equations
- ctx.isJP idx = match Lean.RBMap.find? ctx idx with | some (Lean.IR.LocalContextEntry.joinPoint a a_1) => true | x => false
Equations
- ctx.getJPBody j = match Lean.RBMap.find? ctx j.idx with | some (Lean.IR.LocalContextEntry.joinPoint a b) => some b | x => none
Equations
- ctx.getJPParams j = match Lean.RBMap.find? ctx j.idx with | some (Lean.IR.LocalContextEntry.joinPoint ys a) => some ys | x => none
Equations
- ctx.isParam idx = match Lean.RBMap.find? ctx idx with | some (Lean.IR.LocalContextEntry.param a) => true | x => false
Equations
- ctx.isLocalVar idx = match Lean.RBMap.find? ctx idx with | some (Lean.IR.LocalContextEntry.localVar a a_1) => true | x => false
Equations
- ctx.contains idx = Lean.RBMap.contains ctx idx
Equations
- ctx.eraseJoinPointDecl j = Lean.RBMap.erase ctx j.idx
Equations
- ctx.getType x = match Lean.RBMap.find? ctx x.idx with | some (Lean.IR.LocalContextEntry.param t) => some t | some (Lean.IR.LocalContextEntry.localVar t a) => some t | x => none
Equations
- ctx.getValue x = match Lean.RBMap.find? ctx x.idx with | some (Lean.IR.LocalContextEntry.localVar a v) => some v | x => none
- aeqv : IndexRenaming → α → α → Bool
Equations
- Lean.IR.VarId.alphaEqv ρ v₁ v₂ = match Lean.RBMap.find? ρ v₁.idx with | some v => v == v₂.idx | none => v₁ == v₂
Equations
- Lean.IR.instAlphaEqvVarId = { aeqv := Lean.IR.VarId.alphaEqv }
Equations
- Lean.IR.Arg.alphaEqv ρ (Lean.IR.Arg.var x_2) (Lean.IR.Arg.var y) = Lean.IR.aeqv ρ x_2 y
- Lean.IR.Arg.alphaEqv ρ Lean.IR.Arg.irrelevant Lean.IR.Arg.irrelevant = true
- Lean.IR.Arg.alphaEqv ρ x✝¹ x✝ = false
Equations
- Lean.IR.instAlphaEqvArg = { aeqv := Lean.IR.Arg.alphaEqv }
Equations
- Lean.IR.args.alphaEqv ρ args₁ args₂ = args₁.isEqv args₂ fun (a b : Lean.IR.Arg) => Lean.IR.aeqv ρ a b
Equations
- Lean.IR.instAlphaEqvArrayArg = { aeqv := Lean.IR.args.alphaEqv }
Equations
- Lean.IR.instAlphaEqvExpr = { aeqv := Lean.IR.Expr.alphaEqv }
Equations
- Lean.IR.addVarRename ρ x₁ x₂ = if (x₁ == x₂) = true then ρ else Lean.RBMap.insert ρ x₁ x₂
Equations
- One or more equations did not get rendered due to their size.
Equations
- b₁.beq b₂ = Lean.IR.FnBody.alphaEqv ∅ b₁ b₂
Equations
- Lean.IR.instBEqFnBody = { beq := Lean.IR.FnBody.beq }
Equations
- Lean.IR.VarIdSet = Lean.RBTree Lean.IR.VarId fun (x y : Lean.IR.VarId) => compare x.idx y.idx
Instances For
Equations
- Lean.IR.instInhabitedVarIdSet = { default := ∅ }
Equations
- One or more equations did not get rendered due to their size.
Equations
- Lean.IR.getUnboxOpName Lean.IR.IRType.usize = "lean_unbox_usize"
- Lean.IR.getUnboxOpName Lean.IR.IRType.uint32 = "lean_unbox_uint32"
- Lean.IR.getUnboxOpName Lean.IR.IRType.uint64 = "lean_unbox_uint64"
- Lean.IR.getUnboxOpName Lean.IR.IRType.float = "lean_unbox_float"
- Lean.IR.getUnboxOpName Lean.IR.IRType.float32 = "lean_unbox_float32"
- Lean.IR.getUnboxOpName t = "lean_unbox"