fix: potential Array.get!Internal leaks part 1 (#13147)
This PR fixes theoretical leaks in the handling of `Array.get!Internal`
in the code generator.
Currently, the code generator assumes that the value returned by
`get!Internal` is derived from the
`Array` argument. However, this does not generally hold up as we might
also return the `Inhabited`
value in case of an out of bounds access (recall that we continue
execution after panics by
default). This means that we sometimes convert an `Array.get!Internal`
to
`Array.get!InternalBorrowed` when we are not allowed to do so because in
the panic case the
`Inhabited` instance can be returned and if it is an owned value it is
going to leak.
The fix consists of adapting several components to this change:
1. `PropagateBorrow` will only mark the derived value as forcibly
borrowed if both the `Inhabited`
and `Array` argument are forcibly borrowed.
2. `InferBorrow` will do the same for its data flow analysis
3. The derived value analysis of `ExplicitRC` is extended from a derived
value tree to a derived
value graph where a value may have more than one parent. We only
consider a value borrowed if all
of its parents are still accessible. Then `get!Internal` is equipped
with both its `Inhabited`
and its `Array` parent.
These changes are sufficient for correctness on their own. However, they
are going to break
`get!Internal` to `get!InternalBorrowed` conversion in most places. This
happens because almost all
`Inhabited` instances are going to be constants. Currently reads from
constants yield semantically
owned values and thus block the `get!InternalBorrowed` conversion. We
would thus prefer for these
constants to be treated as borrows instead.
The owned return is implemented in two ways at the moment:
1. In the C code emitter we do not need to do anything as constants are
marked persistent to begin
with
2. In the interpreter whenever a constant is pulled from the constant
cache it is `inc`-ed and then
later `dec`-ed somewhere (potentially using a `dec[persistent]` which is
a no-op in C)
This PR changes the semantics of constant reads to instead be borrows
from the constant (they can be
cutely interpreted as "being borrowed from the world"). This enables
many `get!Internal` to have
both their arguments be marked as borrowed and thus still converted to
`get!InternalBorrowed`. Note
that this PR does not yet change the semantics of the interpreter to
account for this
(it will be done in a part 2) and thus introduces (very minor) leaks
temporarily.
Furthermore, we observed code with signatures such as the following:
```lean
@[specialize]
def foo {a : Type} [inst : Inhabited a] (xs : Array a) (f : a -> a -> Bool) ... :=
...
let x := Array.get!Internal inst xs i
...
```
being instantiated with `a := UInt32`. This poses a challenge because
`Inhabited` is currently
marked as `nospecialize`, meaning that we are sometimes going to end up
with code such as:
```
def foo._spec (inst : UInt32) (xs : @&Array UInt32) ... :=
...
let inst := box inst
let x := Array.get!Internal inst xs i
dec inst
...
```
Here `xs` itself was inferred as borrowed, however, the `UInt32`
`Inhabited` instance was not
specialized for (as `Inhabited` is marked `nospecialize`) and thus needs
to be boxed. This causes
the `inst` parameter to `get!Internal` to be owned and thus
`get!InternalBorrowed` conversion fails.
This PR marks `Inhabited` as `weak_specialize` which will make it get
specialized for in this case,
yielding code such as:
```
def foo._spec (xs : @&Array UInt32) ... :=
...
let inst := instInhabitedUInt32
let inst := box inst
let x := Array.get!Internal inst xs i
dec inst
...
```
Fortunately the closed term extractor has support for precisely this
feature and thus produces:
```
def inst.boxed_const :=
let inst := instInhabitedUInt32
let inst := box inst
return inst
def foo._spec (xs : @&Array UInt32) ... :=
...
let inst := inst.boxed_const
let x := Array.get!Internal inst xs i
...
```
As described above reads from constants are now interpreted as borrows
and thus the conversion to
`get!InternalBorrowed` becomes legal again.
This commit is contained in:
parent
f8f12fdbc8
commit
f9c8b5e93d
15 changed files with 282 additions and 132 deletions
|
|
@ -3673,7 +3673,7 @@ def panic {α : Sort u} [Inhabited α] (msg : String) : α :=
|
|||
panicCore msg
|
||||
|
||||
-- TODO: this be applied directly to `Inhabited`'s definition when we remove the above workaround
|
||||
attribute [nospecialize] Inhabited
|
||||
attribute [weak_specialize] Inhabited
|
||||
|
||||
/--
|
||||
The `>>=` operator is overloaded via instances of `bind`.
|
||||
|
|
|
|||
|
|
@ -31,9 +31,12 @@ namespace Lean.Compiler.LCNF
|
|||
open ImpureType
|
||||
|
||||
/-!
|
||||
The following section contains the derived value analysis. It figures out a dependency tree of
|
||||
The following section contains the derived value analysis. It figures out a dependency graph of
|
||||
values that were derived from other values through projections or `Array` accesses. This information
|
||||
is later used in the derived borrow analysis to reduce reference counting pressure.
|
||||
|
||||
When a derived value has more than one parent, it is derived from one of the parent values but we
|
||||
cannot statically determine which one.
|
||||
-/
|
||||
|
||||
/--
|
||||
|
|
@ -41,10 +44,10 @@ Contains information about values derived through various forms of projection fr
|
|||
-/
|
||||
structure DerivedValInfo where
|
||||
/--
|
||||
The variable this value was derived from. This is always set except for parameters as they have no
|
||||
value to be derived from.
|
||||
The set of variables this value may derive from. This is always set except for parameters as they
|
||||
have no value to be derived from.
|
||||
-/
|
||||
parent? : Option FVarId
|
||||
parents : Array FVarId
|
||||
/--
|
||||
The set of variables that were derived from this value.
|
||||
-/
|
||||
|
|
@ -56,59 +59,75 @@ abbrev DerivedValMap := Std.HashMap FVarId DerivedValInfo
|
|||
namespace CollectDerivedValInfo
|
||||
|
||||
structure State where
|
||||
/--
|
||||
The dependency graph of values.
|
||||
-/
|
||||
varMap : DerivedValMap := {}
|
||||
borrowedParams : FVarIdHashSet := {}
|
||||
/--
|
||||
The set of values that are to be interpreted as being borrowed by nature. This currently includes:
|
||||
- borrowed parameters
|
||||
- variables that are initialized from constants
|
||||
-/
|
||||
borrowedValues : FVarIdHashSet := {}
|
||||
|
||||
abbrev M := StateRefT State CompilerM
|
||||
|
||||
@[inline]
|
||||
def visitParam (p : Param .impure) : M Unit :=
|
||||
def addDerivedValue (parents : Array FVarId) (child : FVarId) : M Unit := do
|
||||
modify fun s => { s with
|
||||
varMap := s.varMap.insert p.fvarId {
|
||||
parent? := none
|
||||
children := {}
|
||||
}
|
||||
borrowedParams :=
|
||||
if p.borrow && p.type.isPossibleRef then
|
||||
s.borrowedParams.insert p.fvarId
|
||||
else
|
||||
s.borrowedParams
|
||||
varMap :=
|
||||
let varMap := parents.foldl (init := s.varMap)
|
||||
(·.modify · (fun info => { info with children := info.children.insert child }))
|
||||
varMap.insert child { parents := parents, children := {} }
|
||||
}
|
||||
|
||||
@[inline]
|
||||
def addDerivedValue (parent : FVarId) (child : FVarId) : M Unit := do
|
||||
modify fun s => { s with
|
||||
varMap :=
|
||||
s.varMap
|
||||
|>.modify parent (fun info => { info with children := info.children.insert child })
|
||||
|>.insert child { parent? := some parent, children := {} }
|
||||
}
|
||||
def addBorrowedValue (fvarId : FVarId) : M Unit := do
|
||||
modify fun s => { s with borrowedValues := s.borrowedValues.insert fvarId }
|
||||
|
||||
def removeFromParent (child : FVarId) : M Unit := do
|
||||
if let some parent := (← get).varMap.get? child |>.bind (·.parent?) then
|
||||
modify fun s => { s with
|
||||
varMap := s.varMap.modify parent fun info =>
|
||||
{ info with children := info.children.erase child }
|
||||
}
|
||||
@[inline]
|
||||
def visitParam (p : Param .impure) : M Unit := do
|
||||
addDerivedValue #[] p.fvarId
|
||||
if p.borrow && p.type.isPossibleRef then
|
||||
addBorrowedValue p.fvarId
|
||||
|
||||
def removeFromParents (child : FVarId) : M Unit := do
|
||||
if let some entry := (← get).varMap.get? child then
|
||||
for parent in entry.parents do
|
||||
modify fun s => { s with
|
||||
varMap := s.varMap.modify parent fun info =>
|
||||
{ info with children := info.children.erase child }
|
||||
}
|
||||
|
||||
partial def collectCode (code : Code .impure) : M Unit := do
|
||||
match code with
|
||||
| .let decl k =>
|
||||
match decl.value with
|
||||
| .oproj _ parent =>
|
||||
addDerivedValue parent decl.fvarId
|
||||
addDerivedValue #[parent] decl.fvarId
|
||||
-- Keep in sync with PropagateBorrow, InferBorrow
|
||||
| .fap ``Array.getInternal args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
addDerivedValue parent decl.fvarId
|
||||
addDerivedValue #[parent] decl.fvarId
|
||||
| .fap ``Array.get!Internal args =>
|
||||
let mut parents := #[]
|
||||
/-
|
||||
Because execution may continue after a panic, the value resulting from a get!InternalBorrowed
|
||||
may be derived from either the `Inhabited` instance or the `Array` argument.
|
||||
-/
|
||||
if let .fvar parent := args[1]! then
|
||||
parents := parents.push parent
|
||||
if let .fvar parent := args[2]! then
|
||||
addDerivedValue parent decl.fvarId
|
||||
parents := parents.push parent
|
||||
addDerivedValue parents decl.fvarId
|
||||
| .fap ``Array.uget args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
addDerivedValue parent decl.fvarId
|
||||
addDerivedValue #[parent] decl.fvarId
|
||||
| .fap _ #[] =>
|
||||
addDerivedValue #[] decl.fvarId
|
||||
addBorrowedValue decl.fvarId
|
||||
| .reset _ target =>
|
||||
removeFromParent target
|
||||
removeFromParents target
|
||||
| _ => pure ()
|
||||
collectCode k
|
||||
| .jp decl k =>
|
||||
|
|
@ -125,8 +144,8 @@ Collect the derived value tree as well as the set of parameters that take object
|
|||
-/
|
||||
def collect (ps : Array (Param .impure)) (code : Code .impure) :
|
||||
CompilerM (DerivedValMap × FVarIdHashSet) := do
|
||||
let ⟨_, { varMap, borrowedParams }⟩ ← go |>.run {}
|
||||
return ⟨varMap, borrowedParams⟩
|
||||
let ⟨_, { varMap, borrowedValues }⟩ ← go |>.run {}
|
||||
return ⟨varMap, borrowedValues⟩
|
||||
where
|
||||
go : M Unit := do
|
||||
ps.forM visitParam
|
||||
|
|
@ -170,13 +189,21 @@ def LiveVars.erase (liveVars : LiveVars) (fvarId : FVarId) : LiveVars :=
|
|||
let borrows := liveVars.borrows.erase fvarId
|
||||
{ vars, borrows }
|
||||
|
||||
@[inline]
|
||||
def LiveVars.insertBorrow (liveVars : LiveVars) (fvarId : FVarId) : LiveVars :=
|
||||
{ liveVars with borrows := liveVars.borrows.insert fvarId }
|
||||
|
||||
@[inline]
|
||||
def LiveVars.insertLive (liveVars : LiveVars) (fvarId : FVarId) : LiveVars :=
|
||||
{ liveVars with vars := liveVars.vars.insert fvarId }
|
||||
|
||||
abbrev JPLiveVarMap := FVarIdMap LiveVars
|
||||
|
||||
structure Context where
|
||||
/--
|
||||
The set of all parameters that are borrowed and take potential objects as arguments.
|
||||
The set of all values that are borrowed and potentially objects
|
||||
-/
|
||||
borrowedParams : FVarIdHashSet
|
||||
borrowedValues : FVarIdHashSet
|
||||
/--
|
||||
The derived value tree.
|
||||
-/
|
||||
|
|
@ -277,18 +304,21 @@ def withCollectLiveVars (x : RcM α) : RcM (α × LiveVars) := do
|
|||
return (ret, collected)
|
||||
|
||||
/--
|
||||
Traverse the transitive closure of values derived from `fvarId` and add them to `s` if they pass
|
||||
`shouldAdd`.
|
||||
Traverse the transitive closure of values derived from `fvarId` and add them to `s` if:
|
||||
- they pass `shouldAdd`.
|
||||
- all their parents are accessible
|
||||
-/
|
||||
@[specialize]
|
||||
partial def addDescendants (fvarId : FVarId) (derivedValMap : DerivedValMap) (s : FVarIdHashSet)
|
||||
(shouldAdd : FVarId → Bool := fun _ => true) : FVarIdHashSet :=
|
||||
partial def addDescendants (fvarId : FVarId) (derivedValMap : DerivedValMap) (liveVars : LiveVars)
|
||||
(shouldAdd : FVarId → Bool := fun _ => true) : LiveVars :=
|
||||
if let some info := derivedValMap.get? fvarId then
|
||||
info.children.fold (init := s) fun s child =>
|
||||
let s := if shouldAdd child then s.insert child else s
|
||||
addDescendants child derivedValMap s shouldAdd
|
||||
info.children.fold (init := liveVars) fun liveVars child =>
|
||||
let cinfo := derivedValMap.get! child
|
||||
let parentsOk := cinfo.parents.all fun fvarId => (liveVars.vars.contains fvarId || liveVars.borrows.contains fvarId)
|
||||
let liveVars := if parentsOk && shouldAdd child then liveVars.insertBorrow child else liveVars
|
||||
addDescendants child derivedValMap liveVars shouldAdd
|
||||
else
|
||||
s
|
||||
liveVars
|
||||
|
||||
/--
|
||||
Mark `fvarId` as live from here on out and if there are any derived values that are not live anymore
|
||||
|
|
@ -299,20 +329,21 @@ alive after all).
|
|||
def useVar (fvarId : FVarId) (shouldBorrow : FVarId → Bool := fun _ => true) : RcM Unit := do
|
||||
if !(← isLive fvarId) then
|
||||
let derivedValMap := (← read).derivedValMap
|
||||
modifyLive fun liveVars => { liveVars with vars := liveVars.vars.insert fvarId }
|
||||
modifyLive fun liveVars =>
|
||||
{ liveVars with
|
||||
borrows := addDescendants fvarId derivedValMap liveVars.borrows fun y =>
|
||||
!liveVars.vars.contains y && shouldBorrow y
|
||||
vars := liveVars.vars.insert fvarId
|
||||
}
|
||||
addDescendants fvarId derivedValMap liveVars fun y =>
|
||||
!liveVars.vars.contains y && shouldBorrow y
|
||||
|
||||
def useArgs (args : Array (Arg .impure)) : RcM Unit := do
|
||||
args.forM fun arg =>
|
||||
match arg with
|
||||
| .fvar fvarId =>
|
||||
useVar fvarId fun y =>
|
||||
-- If a value is used as an argument we are going to mark it live anyways so don't mark it
|
||||
-- as borrowed.
|
||||
/-
|
||||
If we are in a situation like `f x y` where `x` would imply that `y` remains borrowed we are
|
||||
going to mark `y` as being live instead of borrowed later on anyways. Instead we skip this
|
||||
intermediate state and don't even begin to consider it as borrowed.
|
||||
-/
|
||||
args.all fun arg =>
|
||||
match arg with
|
||||
| .fvar z => y != z
|
||||
|
|
@ -341,9 +372,9 @@ def setRetLiveVars : RcM Unit := do
|
|||
let derivedValMap := (← read).derivedValMap
|
||||
-- At the end of a function no values are live and all borrows derived from parameters will still
|
||||
-- be around.
|
||||
let borrows := (← read).borrowedParams.fold (init := {}) fun borrows x =>
|
||||
addDescendants x derivedValMap (borrows.insert x)
|
||||
modifyLive fun _ => { vars := {}, borrows }
|
||||
let liveVars := (← read).borrowedValues.fold (init := {}) fun liveVars x =>
|
||||
addDescendants x derivedValMap (liveVars.insertBorrow x)
|
||||
modifyLive (fun _ => liveVars)
|
||||
|
||||
@[inline]
|
||||
def addInc (fvarId : FVarId) (k : Code .impure) (n : Nat := 1) : RcM (Code .impure) := do
|
||||
|
|
@ -625,9 +656,9 @@ partial def Code.explicitRc (code : Code .impure) : RcM (Code .impure) := do
|
|||
def Decl.explicitRc (decl : Decl .impure) :
|
||||
CompilerM (Decl .impure) := do
|
||||
let value ← decl.value.mapCodeM fun code => do
|
||||
let ⟨derivedValMap, borrowedParams⟩ ← CollectDerivedValInfo.collect decl.params code
|
||||
let ⟨derivedValMap, borrowedValues⟩ ← CollectDerivedValInfo.collect decl.params code
|
||||
go code |>.run {
|
||||
borrowedParams,
|
||||
borrowedValues,
|
||||
derivedValMap,
|
||||
} |>.run' {}
|
||||
return { decl with value }
|
||||
|
|
|
|||
|
|
@ -384,6 +384,8 @@ where
|
|||
if let .fvar parent := args[1]! then
|
||||
if ← isOwned parent then ownFVar z (.forwardProjectionProp z)
|
||||
| .fap ``Array.get!Internal args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
if ← isOwned parent then ownFVar z (.forwardProjectionProp z)
|
||||
if let .fvar parent := args[2]! then
|
||||
if ← isOwned parent then ownFVar z (.forwardProjectionProp z)
|
||||
| .fap ``Array.uget args =>
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ where
|
|||
let parentVal ← getOwnedness parent
|
||||
join z parentVal
|
||||
| .fap ``Array.get!Internal args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
let parentVal ← getOwnedness parent
|
||||
join z parentVal
|
||||
if let .fvar parent := args[2]! then
|
||||
let parentVal ← getOwnedness parent
|
||||
join z parentVal
|
||||
|
|
|
|||
|
|
@ -178,10 +178,11 @@ partial def compileToSimpleGroundExpr (code : Code .impure) : CompilerM (Option
|
|||
where
|
||||
go (code : Code .impure) : DetectM SimpleGroundExpr := do
|
||||
match code with
|
||||
| .let decl (.return fvarId) =>
|
||||
| .let decl (.return fvarId) | .let decl (.inc _ _ _ true (.return fvarId)) =>
|
||||
guard <| decl.fvarId == fvarId
|
||||
compileFinalLet decl.value
|
||||
| .let decl k => compileNonFinalLet decl k
|
||||
| .inc (persistent := true) (k := k) .. => go k
|
||||
| _ => failure
|
||||
|
||||
@[inline]
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ options get_default_options() {
|
|||
opts = opts.update({"debug", "terminalTacticsAsSorry"}, false);
|
||||
// switch to `true` for ABI-breaking changes affecting meta code;
|
||||
// see also next option!
|
||||
opts = opts.update({"interpreter", "prefer_native"}, false);
|
||||
opts = opts.update({"interpreter", "prefer_native"}, true);
|
||||
// switch to `false` when enabling `prefer_native` should also affect use
|
||||
// of built-in parsers in quotations; this is usually the case, but setting
|
||||
// both to `true` may be necessary for handling non-builtin parsers with
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ true
|
|||
let _x.1 := 1;
|
||||
let _x.2 := Bool.repr._redArg _x.1;
|
||||
return _x.2
|
||||
[Compiler.result] size: 1
|
||||
[Compiler.result] size: 2
|
||||
def _private.elab.«9806».0._eval : tobj :=
|
||||
let _x.1 := _private.elab.«9806».0._eval._closed_0;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
|
|
|
|||
|
|
@ -3619,7 +3619,7 @@ def panic {α : Sort u} [Inhabited α] (msg : String) : α :=
|
|||
panicCore msg
|
||||
|
||||
-- TODO: this be applied directly to `Inhabited`'s definition when we remove the above workaround
|
||||
attribute [nospecialize] Inhabited
|
||||
attribute [weak_specialize] Inhabited
|
||||
|
||||
/--
|
||||
The `>>=` operator is overloaded via instances of `bind`.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ trace: [Compiler.IR] [result]
|
|||
ret x_1
|
||||
def instSemiringUInt8 : obj :=
|
||||
let x_1 : obj := instSemiringUInt8._closed_0;
|
||||
inc x_1;
|
||||
ret x_1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
|
|||
|
|
@ -3,19 +3,19 @@ module
|
|||
public section
|
||||
|
||||
|
||||
|
||||
/--
|
||||
trace: [Compiler.explicitRc] size: 1
|
||||
def test1._closed_0 : obj :=
|
||||
let _x.1 := "";
|
||||
return _x.1
|
||||
[Compiler.explicitRc] size: 8
|
||||
[Compiler.explicitRc] size: 7
|
||||
def test1 @&xs : obj :=
|
||||
let _x.1 := test1._closed_0;
|
||||
let _x.2 := 0;
|
||||
let _x.3 := Array.get!InternalBorrowed ◾ _x.1 xs _x.2;
|
||||
let _x.4 := 1;
|
||||
let _x.5 := Array.get!InternalBorrowed ◾ _x.1 xs _x.4;
|
||||
dec[persistent][ref] _x.1;
|
||||
inc _x.3;
|
||||
let _x.6 := String.append _x.3 _x.5;
|
||||
return _x.6
|
||||
|
|
@ -77,7 +77,7 @@ trace: [Compiler.explicitRc] size: 4
|
|||
dec[ref] xs;
|
||||
let r := box res;
|
||||
return r
|
||||
[Compiler.explicitRc] size: 23
|
||||
[Compiler.explicitRc] size: 21
|
||||
def test3 @&xs : obj :=
|
||||
let _x.1 := test1._closed_0;
|
||||
jp _jp.2 _y.3 : obj :=
|
||||
|
|
@ -86,12 +86,10 @@ trace: [Compiler.explicitRc] size: 4
|
|||
cases _x.5 : obj
|
||||
| Bool.false =>
|
||||
let _x.6 := outOfBounds._redArg _x.1;
|
||||
dec[persistent][ref] _x.1;
|
||||
let _x.7 := String.append _y.3 _x.6;
|
||||
dec _x.6;
|
||||
return _x.7
|
||||
| Bool.true =>
|
||||
dec[persistent][ref] _x.1;
|
||||
let _x.8 := Array.ugetBorrowed ◾ xs _x.4 ◾;
|
||||
let _x.9 := String.append _y.3 _x.8;
|
||||
return _x.9;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ inductive NAryTree where
|
|||
deriving Inhabited
|
||||
|
||||
/--
|
||||
trace: [Compiler.explicitRc] size: 20
|
||||
trace: [Compiler.explicitRc] size: 21
|
||||
def followPath @&tree @&path : obj :=
|
||||
cases tree : obj
|
||||
| NAryTree.tip =>
|
||||
|
|
@ -21,6 +21,7 @@ trace: [Compiler.explicitRc] size: 20
|
|||
return x.1
|
||||
| _ =>
|
||||
let _x.2 := instInhabitedNAryTree.default._closed_0;
|
||||
inc[persistent][ref] _x.2;
|
||||
return _x.2
|
||||
| NAryTree.node =>
|
||||
cases path : obj
|
||||
|
|
@ -30,11 +31,11 @@ trace: [Compiler.explicitRc] size: 20
|
|||
let tail.5 := oproj[1] path;
|
||||
let _x.6 := instInhabitedNAryTree.default;
|
||||
let _x.7 := Array.get!InternalBorrowed ◾ _x.6 ys.3 head.4;
|
||||
dec[persistent][ref] _x.6;
|
||||
let _x.8 := followPath _x.7 tail.5;
|
||||
return _x.8
|
||||
| _ =>
|
||||
let _x.9 := instInhabitedNAryTree.default._closed_0;
|
||||
inc[persistent][ref] _x.9;
|
||||
return _x.9
|
||||
[Compiler.explicitRc] size: 3
|
||||
def followPath._boxed tree path : obj :=
|
||||
|
|
|
|||
|
|
@ -281,12 +281,12 @@
|
|||
def f._closed_1 : tobj :=
|
||||
let x_1 : tagged := ctor_5[Exp.a4._impl];
|
||||
let x_2 : tobj := f._closed_0;
|
||||
inc x_2;
|
||||
let x_3 : tobj := Exp.app._override x_2 x_1;
|
||||
ret x_3
|
||||
def f._closed_2 : u64 :=
|
||||
let x_1 : tobj := f._closed_1;
|
||||
let x_2 : u64 := Exp.hash._override x_1;
|
||||
dec x_1;
|
||||
ret x_2
|
||||
def f : u64 :=
|
||||
let x_1 : u64 := f._closed_2;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ trace: [Compiler.IR] [result]
|
|||
ret x_1
|
||||
def test1 : obj :=
|
||||
let x_1 : obj := test1._closed_0;
|
||||
inc x_1;
|
||||
ret x_1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -32,6 +33,7 @@ trace: [Compiler.IR] [result]
|
|||
ret x_5
|
||||
def test2 : obj :=
|
||||
let x_1 : obj := test2._closed_0;
|
||||
inc x_1;
|
||||
ret x_1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ trace: [Compiler.IR] [result]
|
|||
ret x_3
|
||||
def f : obj :=
|
||||
let x_1 : obj := f._closed_0;
|
||||
inc x_1;
|
||||
ret x_1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ trace: [Compiler.simpleGround] Marked stringTest1._closed_0 as simple ground exp
|
|||
def stringTest1._closed_0 : obj :=
|
||||
let _x.1 := "literal";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def stringTest1 : obj :=
|
||||
let _x.1 := stringTest1._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -39,27 +40,33 @@ trace: [Compiler.simpleGround] Marked stringTest2._closed_0 as simple ground exp
|
|||
def stringTest2._closed_2 : obj :=
|
||||
let _x.1 := "C";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 4
|
||||
def stringTest2._closed_3 : tobj :=
|
||||
let _x.1 := ctor_0[List.nil];
|
||||
let _x.2 := stringTest2._closed_2;
|
||||
inc[persistent][ref] _x.2;
|
||||
let _x.3 := ctor_1[List.cons] _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def stringTest2._closed_4 : tobj :=
|
||||
let _x.1 := stringTest2._closed_3;
|
||||
let _x.2 := stringTest2._closed_1;
|
||||
inc[persistent] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
let _x.3 := ctor_1[List.cons] _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def stringTest2._closed_5 : tobj :=
|
||||
let _x.1 := stringTest2._closed_4;
|
||||
let _x.2 := stringTest2._closed_0;
|
||||
inc[persistent] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
let _x.3 := ctor_1[List.cons] _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def stringTest2 : tobj :=
|
||||
let _x.1 := stringTest2._closed_5;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -72,14 +79,16 @@ open Lean
|
|||
/--
|
||||
trace: [Compiler.simpleGround] Marked nameTest1._closed_0 as simple ground expr
|
||||
[Compiler.simpleGround] Marked nameTest1 as simple ground expr
|
||||
[Compiler.saveImpure] size: 2
|
||||
[Compiler.saveImpure] size: 3
|
||||
def nameTest1._closed_0 : tobj :=
|
||||
let _x.1 := stringTest2._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
let _x.2 := Lean.Name.mkStr1 _x.1;
|
||||
return _x.2
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest1 : tobj :=
|
||||
let _x.1 := nameTest1._closed_0;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -90,15 +99,18 @@ def nameTest1 : Name := `A
|
|||
/--
|
||||
trace: [Compiler.simpleGround] Marked nameTest2._closed_0 as simple ground expr
|
||||
[Compiler.simpleGround] Marked nameTest2 as simple ground expr
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest2._closed_0 : tobj :=
|
||||
let _x.1 := stringTest2._closed_1;
|
||||
let _x.2 := stringTest2._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
let _x.3 := Lean.Name.mkStr2 _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest2 : tobj :=
|
||||
let _x.1 := nameTest2._closed_0;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -109,16 +121,20 @@ def nameTest2 : Name := `A.B
|
|||
/--
|
||||
trace: [Compiler.simpleGround] Marked nameTest3._closed_0 as simple ground expr
|
||||
[Compiler.simpleGround] Marked nameTest3 as simple ground expr
|
||||
[Compiler.saveImpure] size: 4
|
||||
[Compiler.saveImpure] size: 7
|
||||
def nameTest3._closed_0 : tobj :=
|
||||
let _x.1 := stringTest2._closed_2;
|
||||
let _x.2 := stringTest2._closed_1;
|
||||
let _x.3 := stringTest2._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
inc[persistent][ref] _x.3;
|
||||
let _x.4 := Lean.Name.mkStr3 _x.3 _x.2 _x.1;
|
||||
return _x.4
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest3 : tobj :=
|
||||
let _x.1 := nameTest3._closed_0;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -134,17 +150,22 @@ trace: [Compiler.simpleGround] Marked nameTest4._closed_0 as simple ground expr
|
|||
def nameTest4._closed_0 : obj :=
|
||||
let _x.1 := "D";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 5
|
||||
[Compiler.saveImpure] size: 9
|
||||
def nameTest4._closed_1 : tobj :=
|
||||
let _x.1 := nameTest4._closed_0;
|
||||
let _x.2 := stringTest2._closed_2;
|
||||
let _x.3 := stringTest2._closed_1;
|
||||
let _x.4 := stringTest2._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
inc[persistent][ref] _x.3;
|
||||
inc[persistent][ref] _x.4;
|
||||
let _x.5 := Lean.Name.mkStr4 _x.4 _x.3 _x.2 _x.1;
|
||||
return _x.5
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest4 : tobj :=
|
||||
let _x.1 := nameTest4._closed_1;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -160,18 +181,24 @@ trace: [Compiler.simpleGround] Marked nameTest5._closed_0 as simple ground expr
|
|||
def nameTest5._closed_0 : obj :=
|
||||
let _x.1 := "E";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 6
|
||||
[Compiler.saveImpure] size: 11
|
||||
def nameTest5._closed_1 : tobj :=
|
||||
let _x.1 := nameTest5._closed_0;
|
||||
let _x.2 := nameTest4._closed_0;
|
||||
let _x.3 := stringTest2._closed_2;
|
||||
let _x.4 := stringTest2._closed_1;
|
||||
let _x.5 := stringTest2._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
inc[persistent][ref] _x.3;
|
||||
inc[persistent][ref] _x.4;
|
||||
inc[persistent][ref] _x.5;
|
||||
let _x.6 := Lean.Name.mkStr5 _x.5 _x.4 _x.3 _x.2 _x.1;
|
||||
return _x.6
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest5 : tobj :=
|
||||
let _x.1 := nameTest5._closed_1;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -187,7 +214,7 @@ trace: [Compiler.simpleGround] Marked nameTest6._closed_0 as simple ground expr
|
|||
def nameTest6._closed_0 : obj :=
|
||||
let _x.1 := "F";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 7
|
||||
[Compiler.saveImpure] size: 13
|
||||
def nameTest6._closed_1 : tobj :=
|
||||
let _x.1 := nameTest6._closed_0;
|
||||
let _x.2 := nameTest5._closed_0;
|
||||
|
|
@ -195,11 +222,18 @@ trace: [Compiler.simpleGround] Marked nameTest6._closed_0 as simple ground expr
|
|||
let _x.4 := stringTest2._closed_2;
|
||||
let _x.5 := stringTest2._closed_1;
|
||||
let _x.6 := stringTest2._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
inc[persistent][ref] _x.3;
|
||||
inc[persistent][ref] _x.4;
|
||||
inc[persistent][ref] _x.5;
|
||||
inc[persistent][ref] _x.6;
|
||||
let _x.7 := Lean.Name.mkStr6 _x.6 _x.5 _x.4 _x.3 _x.2 _x.1;
|
||||
return _x.7
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest6 : tobj :=
|
||||
let _x.1 := nameTest6._closed_1;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -215,7 +249,7 @@ trace: [Compiler.simpleGround] Marked nameTest7._closed_0 as simple ground expr
|
|||
def nameTest7._closed_0 : obj :=
|
||||
let _x.1 := "G";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 8
|
||||
[Compiler.saveImpure] size: 15
|
||||
def nameTest7._closed_1 : tobj :=
|
||||
let _x.1 := nameTest7._closed_0;
|
||||
let _x.2 := nameTest6._closed_0;
|
||||
|
|
@ -224,11 +258,19 @@ trace: [Compiler.simpleGround] Marked nameTest7._closed_0 as simple ground expr
|
|||
let _x.5 := stringTest2._closed_2;
|
||||
let _x.6 := stringTest2._closed_1;
|
||||
let _x.7 := stringTest2._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
inc[persistent][ref] _x.3;
|
||||
inc[persistent][ref] _x.4;
|
||||
inc[persistent][ref] _x.5;
|
||||
inc[persistent][ref] _x.6;
|
||||
inc[persistent][ref] _x.7;
|
||||
let _x.8 := Lean.Name.mkStr7 _x.7 _x.6 _x.5 _x.4 _x.3 _x.2 _x.1;
|
||||
return _x.8
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest7 : tobj :=
|
||||
let _x.1 := nameTest7._closed_1;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -244,7 +286,7 @@ trace: [Compiler.simpleGround] Marked nameTest8._closed_0 as simple ground expr
|
|||
def nameTest8._closed_0 : obj :=
|
||||
let _x.1 := "H";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 9
|
||||
[Compiler.saveImpure] size: 17
|
||||
def nameTest8._closed_1 : tobj :=
|
||||
let _x.1 := nameTest8._closed_0;
|
||||
let _x.2 := nameTest7._closed_0;
|
||||
|
|
@ -254,11 +296,20 @@ trace: [Compiler.simpleGround] Marked nameTest8._closed_0 as simple ground expr
|
|||
let _x.6 := stringTest2._closed_2;
|
||||
let _x.7 := stringTest2._closed_1;
|
||||
let _x.8 := stringTest2._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent][ref] _x.2;
|
||||
inc[persistent][ref] _x.3;
|
||||
inc[persistent][ref] _x.4;
|
||||
inc[persistent][ref] _x.5;
|
||||
inc[persistent][ref] _x.6;
|
||||
inc[persistent][ref] _x.7;
|
||||
inc[persistent][ref] _x.8;
|
||||
let _x.9 := Lean.Name.mkStr8 _x.8 _x.7 _x.6 _x.5 _x.4 _x.3 _x.2 _x.1;
|
||||
return _x.9
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest8 : tobj :=
|
||||
let _x.1 := nameTest8._closed_1;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -278,67 +329,85 @@ trace: [Compiler.simpleGround] Marked nameTest9._closed_0 as simple ground expr
|
|||
[Compiler.simpleGround] Marked nameTest9._closed_8 as simple ground expr
|
||||
[Compiler.simpleGround] Marked nameTest9._closed_9 as simple ground expr
|
||||
[Compiler.simpleGround] Marked nameTest9 as simple ground expr
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 4
|
||||
def nameTest9._closed_0 : tobj :=
|
||||
let _x.1 := stringTest2._closed_0;
|
||||
let _x.2 := ctor_0[Lean.Name.anonymous._impl];
|
||||
inc[persistent][ref] _x.1;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest9._closed_1 : tobj :=
|
||||
let _x.1 := stringTest2._closed_1;
|
||||
let _x.2 := nameTest9._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest9._closed_2 : tobj :=
|
||||
let _x.1 := stringTest2._closed_2;
|
||||
let _x.2 := nameTest9._closed_1;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest9._closed_3 : tobj :=
|
||||
let _x.1 := nameTest4._closed_0;
|
||||
let _x.2 := nameTest9._closed_2;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest9._closed_4 : tobj :=
|
||||
let _x.1 := nameTest5._closed_0;
|
||||
let _x.2 := nameTest9._closed_3;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest9._closed_5 : tobj :=
|
||||
let _x.1 := nameTest6._closed_0;
|
||||
let _x.2 := nameTest9._closed_4;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest9._closed_6 : tobj :=
|
||||
let _x.1 := nameTest7._closed_0;
|
||||
let _x.2 := nameTest9._closed_5;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest9._closed_7 : tobj :=
|
||||
let _x.1 := nameTest8._closed_0;
|
||||
let _x.2 := nameTest9._closed_6;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
def nameTest9._closed_8 : obj :=
|
||||
let _x.1 := "I";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest9._closed_9 : tobj :=
|
||||
let _x.1 := nameTest9._closed_8;
|
||||
let _x.2 := nameTest9._closed_7;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest9 : tobj :=
|
||||
let _x.1 := nameTest9._closed_9;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -349,15 +418,17 @@ def nameTest9 : Name := `A.B.C.D.E.F.G.H.I
|
|||
/--
|
||||
trace: [Compiler.simpleGround] Marked nameTest10._closed_0 as simple ground expr
|
||||
[Compiler.simpleGround] Marked nameTest10 as simple ground expr
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 4
|
||||
def nameTest10._closed_0 : tobj :=
|
||||
let _x.1 := 1;
|
||||
let _x.2 := nameTest3._closed_0;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.num._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest10 : tobj :=
|
||||
let _x.1 := nameTest10._closed_0;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -373,15 +444,18 @@ trace: [Compiler.simpleGround] Marked nameTest11._closed_0 as simple ground expr
|
|||
def nameTest11._closed_0 : obj :=
|
||||
let _x.1 := "AHHHH";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def nameTest11._closed_1 : tobj :=
|
||||
let _x.1 := nameTest11._closed_0;
|
||||
let _x.2 := nameTest3._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
inc[persistent] _x.2;
|
||||
let _x.3 := Lean.Name.str._override _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def nameTest11 : tobj :=
|
||||
let _x.1 := nameTest11._closed_1;
|
||||
inc[persistent] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -404,22 +478,24 @@ trace: [Compiler.simpleGround] Marked testWithScalars._closed_0 as simple ground
|
|||
def testWithScalars._closed_0 : obj :=
|
||||
let _x.1 := "W";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 10
|
||||
[Compiler.saveImpure] size: 11
|
||||
def testWithScalars._closed_1 : obj :=
|
||||
let _x.1 := 3;
|
||||
let _x.2 := 2;
|
||||
let _x.3 := 1;
|
||||
let _x.4 := 0;
|
||||
let _x.5 := testWithScalars._closed_0;
|
||||
inc[persistent][ref] _x.5;
|
||||
let _x.6 := ctor_0.0.15[WithScalars.mk] _x.5;
|
||||
sset _x.6[1, 0] := _x.4;
|
||||
sset _x.6[1, 8] := _x.3;
|
||||
sset _x.6[1, 12] := _x.2;
|
||||
sset _x.6[1, 14] := _x.1;
|
||||
return _x.6
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def testWithScalars : obj :=
|
||||
let _x.1 := testWithScalars._closed_1;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -439,16 +515,18 @@ trace: [Compiler.simpleGround] Marked testWithUSize._closed_0 as simple ground e
|
|||
def testWithUSize._closed_0 : obj :=
|
||||
let _x.1 := "U";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 4
|
||||
[Compiler.saveImpure] size: 5
|
||||
def testWithUSize._closed_1 : obj :=
|
||||
let _x.1 := 0;
|
||||
let _x.2 := testWithUSize._closed_0;
|
||||
inc[persistent][ref] _x.2;
|
||||
let _x.3 := ctor_0.1.0[WithUSize.mk] _x.2;
|
||||
uset _x.3[1] := _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def testWithUSize : obj :=
|
||||
let _x.1 := testWithUSize._closed_1;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -472,7 +550,7 @@ trace: [Compiler.simpleGround] Marked testWithUSizeAndScalars._closed_0 as simpl
|
|||
def testWithUSizeAndScalars._closed_0 : obj :=
|
||||
let _x.1 := "WUAS";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 12
|
||||
[Compiler.saveImpure] size: 13
|
||||
def testWithUSizeAndScalars._closed_1 : obj :=
|
||||
let _x.1 := 4;
|
||||
let _x.2 := 3;
|
||||
|
|
@ -480,6 +558,7 @@ trace: [Compiler.simpleGround] Marked testWithUSizeAndScalars._closed_0 as simpl
|
|||
let _x.4 := 1;
|
||||
let _x.5 := 0;
|
||||
let _x.6 := testWithUSizeAndScalars._closed_0;
|
||||
inc[persistent][ref] _x.6;
|
||||
let _x.7 := ctor_0.1.15[WithUSizeAndScalars.mk] _x.6;
|
||||
sset _x.7[2, 0] := _x.5;
|
||||
sset _x.7[2, 8] := _x.4;
|
||||
|
|
@ -487,9 +566,10 @@ trace: [Compiler.simpleGround] Marked testWithUSizeAndScalars._closed_0 as simpl
|
|||
sset _x.7[2, 14] := _x.2;
|
||||
uset _x.7[1] := _x.1;
|
||||
return _x.7
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def testWithUSizeAndScalars : obj :=
|
||||
let _x.1 := testWithUSizeAndScalars._closed_1;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -509,9 +589,10 @@ trace: [Compiler.simpleGround] Marked uint8Pair._closed_0 as simple ground expr
|
|||
let _x.4 := box _x.1;
|
||||
let _x.5 := ctor_0[Prod.mk] _x.3 _x.4;
|
||||
return _x.5
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def uint8Pair : obj :=
|
||||
let _x.1 := uint8Pair._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -531,9 +612,10 @@ trace: [Compiler.simpleGround] Marked uint16Pair._closed_0 as simple ground expr
|
|||
let _x.4 := box _x.1;
|
||||
let _x.5 := ctor_0[Prod.mk] _x.3 _x.4;
|
||||
return _x.5
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def uint16Pair : obj :=
|
||||
let _x.1 := uint16Pair._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -559,15 +641,18 @@ trace: [Compiler.simpleGround] Marked uint64Pair._closed_0._boxed_const_1 as sim
|
|||
let _x.1 := 3;
|
||||
let _x.2 := box _x.1;
|
||||
return _x.2
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def uint64Pair._closed_0 : obj :=
|
||||
let _x.1 := uint64Pair._closed_0._boxed_const_1;
|
||||
let _x.2 := uint64Pair._closed_0._boxed_const_2;
|
||||
inc[persistent] _x.2;
|
||||
inc[persistent] _x.1;
|
||||
let _x.3 := ctor_0[Prod.mk] _x.1 _x.2;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def uint64Pair : obj :=
|
||||
let _x.1 := uint64Pair._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -591,15 +676,18 @@ trace: [Compiler.simpleGround] Marked usizePair._closed_0._boxed_const_1 as simp
|
|||
let _x.1 := 3;
|
||||
let _x.2 := box _x.1;
|
||||
return _x.2
|
||||
[Compiler.saveImpure] size: 3
|
||||
[Compiler.saveImpure] size: 5
|
||||
def usizePair._closed_0 : obj :=
|
||||
let _x.1 := usizePair._closed_0._boxed_const_1;
|
||||
let _x.2 := usizePair._closed_0._boxed_const_2;
|
||||
inc[persistent] _x.2;
|
||||
inc[persistent] _x.1;
|
||||
let _x.3 := ctor_0[Prod.mk] _x.1 _x.2;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def usizePair : obj :=
|
||||
let _x.1 := usizePair._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -620,9 +708,10 @@ trace: [Compiler.simpleGround] Marked arrayNatTest._closed_0 as simple ground ex
|
|||
let _x.6 := Array.push ◾ _x.5 _x.1;
|
||||
let _x.7 := Array.push ◾ _x.6 _x.3;
|
||||
return _x.7
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def arrayNatTest : obj :=
|
||||
let _x.1 := arrayNatTest._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -638,9 +727,10 @@ trace: [Compiler.simpleGround] Marked emptyArrayTest._closed_0 as simple ground
|
|||
let _x.1 := 0;
|
||||
let _x.2 := Array.mkEmpty ◾ _x.1;
|
||||
return _x.2
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def emptyArrayTest : obj :=
|
||||
let _x.1 := emptyArrayTest._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -661,18 +751,21 @@ trace: [Compiler.simpleGround] Marked arrayStringTest._closed_0 as simple ground
|
|||
def arrayStringTest._closed_1 : obj :=
|
||||
let _x.1 := "world";
|
||||
return _x.1
|
||||
[Compiler.saveImpure] size: 6
|
||||
[Compiler.saveImpure] size: 8
|
||||
def arrayStringTest._closed_2 : obj :=
|
||||
let _x.1 := arrayStringTest._closed_1;
|
||||
let _x.2 := arrayStringTest._closed_0;
|
||||
let _x.3 := 2;
|
||||
let _x.4 := Array.mkEmpty ◾ _x.3;
|
||||
inc[persistent][ref] _x.2;
|
||||
let _x.5 := Array.push ◾ _x.4 _x.2;
|
||||
inc[persistent][ref] _x.1;
|
||||
let _x.6 := Array.push ◾ _x.5 _x.1;
|
||||
return _x.6
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def arrayStringTest : obj :=
|
||||
let _x.1 := arrayStringTest._closed_2;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -697,9 +790,10 @@ trace: [Compiler.simpleGround] Marked arrayUInt8Test._closed_0 as simple ground
|
|||
let _x.10 := box _x.1;
|
||||
let _x.11 := Array.push ◾ _x.9 _x.10;
|
||||
return _x.11
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def arrayUInt8Test : obj :=
|
||||
let _x.1 := arrayUInt8Test._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -724,9 +818,10 @@ trace: [Compiler.simpleGround] Marked arrayUInt16Test._closed_0 as simple ground
|
|||
let _x.10 := box _x.1;
|
||||
let _x.11 := Array.push ◾ _x.9 _x.10;
|
||||
return _x.11
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def arrayUInt16Test : obj :=
|
||||
let _x.1 := arrayUInt16Test._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -755,20 +850,24 @@ trace: [Compiler.simpleGround] Marked arrayUInt64._closed_0._boxed_const_1 as si
|
|||
let _x.1 := 11;
|
||||
let _x.2 := box _x.1;
|
||||
return _x.2
|
||||
[Compiler.saveImpure] size: 8
|
||||
[Compiler.saveImpure] size: 11
|
||||
def arrayUInt64._closed_0 : obj :=
|
||||
let _x.1 := 3;
|
||||
let _x.2 := Array.mkEmpty ◾ _x.1;
|
||||
let _x.3 := arrayUInt64._closed_0._boxed_const_3;
|
||||
inc[persistent] _x.3;
|
||||
let _x.4 := Array.push ◾ _x.2 _x.3;
|
||||
let _x.5 := arrayUInt64._closed_0._boxed_const_2;
|
||||
inc[persistent] _x.5;
|
||||
let _x.6 := Array.push ◾ _x.4 _x.5;
|
||||
let _x.7 := arrayUInt64._closed_0._boxed_const_1;
|
||||
inc[persistent] _x.7;
|
||||
let _x.8 := Array.push ◾ _x.6 _x.7;
|
||||
return _x.8
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def arrayUInt64 : obj :=
|
||||
let _x.1 := arrayUInt64._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -797,20 +896,24 @@ trace: [Compiler.simpleGround] Marked arrayUSize._closed_0._boxed_const_1 as sim
|
|||
let _x.1 := 17;
|
||||
let _x.2 := box _x.1;
|
||||
return _x.2
|
||||
[Compiler.saveImpure] size: 8
|
||||
[Compiler.saveImpure] size: 11
|
||||
def arrayUSize._closed_0 : obj :=
|
||||
let _x.1 := 3;
|
||||
let _x.2 := Array.mkEmpty ◾ _x.1;
|
||||
let _x.3 := arrayUSize._closed_0._boxed_const_3;
|
||||
inc[persistent] _x.3;
|
||||
let _x.4 := Array.push ◾ _x.2 _x.3;
|
||||
let _x.5 := arrayUSize._closed_0._boxed_const_2;
|
||||
inc[persistent] _x.5;
|
||||
let _x.6 := Array.push ◾ _x.4 _x.5;
|
||||
let _x.7 := arrayUSize._closed_0._boxed_const_1;
|
||||
inc[persistent] _x.7;
|
||||
let _x.8 := Array.push ◾ _x.6 _x.7;
|
||||
return _x.8
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def arrayUSize : obj :=
|
||||
let _x.1 := arrayUSize._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -835,18 +938,21 @@ trace: [Compiler.simpleGround] Marked arrayNatPair._closed_0 as simple ground ex
|
|||
let _x.2 := 3;
|
||||
let _x.3 := ctor_0[Prod.mk] _x.2 _x.1;
|
||||
return _x.3
|
||||
[Compiler.saveImpure] size: 6
|
||||
[Compiler.saveImpure] size: 8
|
||||
def arrayNatPair._closed_2 : obj :=
|
||||
let _x.1 := arrayNatPair._closed_1;
|
||||
let _x.2 := arrayNatPair._closed_0;
|
||||
let _x.3 := 2;
|
||||
let _x.4 := Array.mkEmpty ◾ _x.3;
|
||||
inc[persistent][ref] _x.2;
|
||||
let _x.5 := Array.push ◾ _x.4 _x.2;
|
||||
inc[persistent][ref] _x.1;
|
||||
let _x.6 := Array.push ◾ _x.5 _x.1;
|
||||
return _x.6
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def arrayNatPair : obj :=
|
||||
let _x.1 := arrayNatPair._closed_2;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -872,9 +978,10 @@ trace: [Compiler.simpleGround] Marked byteArrayTest._closed_0 as simple ground e
|
|||
let _x.11 := Array.push ◾ _x.9 _x.10;
|
||||
let _x.12 := ByteArray.mk _x.11;
|
||||
return _x.12
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def byteArrayTest : obj :=
|
||||
let _x.1 := byteArrayTest._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
@ -891,14 +998,16 @@ trace: [Compiler.simpleGround] Marked emptyByteArrayTest._closed_0 as simple gro
|
|||
let _x.1 := 0;
|
||||
let _x.2 := Array.mkEmpty ◾ _x.1;
|
||||
return _x.2
|
||||
[Compiler.saveImpure] size: 2
|
||||
[Compiler.saveImpure] size: 3
|
||||
def emptyByteArrayTest._closed_1 : obj :=
|
||||
let _x.1 := emptyByteArrayTest._closed_0;
|
||||
inc[persistent][ref] _x.1;
|
||||
let _x.2 := ByteArray.mk _x.1;
|
||||
return _x.2
|
||||
[Compiler.saveImpure] size: 1
|
||||
[Compiler.saveImpure] size: 2
|
||||
def emptyByteArrayTest : obj :=
|
||||
let _x.1 := emptyByteArrayTest._closed_1;
|
||||
inc[persistent][ref] _x.1;
|
||||
return _x.1
|
||||
-/
|
||||
#guard_msgs in
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue