hylo
hylo copied to clipboard
Implement bundle reification
The Emitter creates a call_bundle
instruction when it sees a call to a method bundle. For example:
type A {
public var x: Int
public memberwise init
public fun foo() -> Int {
let { x.copy() }
sink { x }
}
}
public fun main() {
_ = A(x: 42).foo()
}
The IR generated for call in main
resembles the following (where %i0.1
is the address of some storage allocated for an A
):
%i0.6: &A = access [let, sink] %i0.1
%i0.7: &Int = access [set] %i0.0
call_bundle [let, sink] @MethodDecl(2311)(%i0.6) to %i0.7
end_access %i0.7
We need a mandatory IR pass that will replace call_bundle
by a simple call
to the appropriate variant, depending on the strongest capability we may request on %i0.1
. To determine what that is, we should look at all uses of %i0.1
after the definition of %i0.6
. If there are none, then we can create an access [set]
on the latter and call the sink
variant of the bundle. Note that access reification will later collapse the sequence
%i0.6: &A = access [let, sink] %i0.1
%i0.x: &A = access [sink] %i0.6