<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hello everyone.<br class=""><br class="">Attached below inline is a proposal for High Level ARC Value operations. Additionally a formatted version of this proposal is available here:<br class=""><br class=""><a href="https://gottesmm.github.io/proposals/high-level-arc-value-operations.html" class="">https://gottesmm.github.io/proposals/high-level-arc-value-operations.html</a><br class=""><br class="">TLDR: This is a very straightforward proposal that just proposes the instructions copy_value, destroy_value, and copy_unowned_value. These are just the use-def versions of strong_retain, retain_value, strong_release, release_value, and strong_retain_unowned.<br class=""><br class="">Michael<br class=""><br class="">----<br class=""><br class=""># Summary<br class=""><br class="">This document proposes:<br class=""><br class="">1. removing the `strong_retain`, `retain_value`, `unowned_retain`, and<br class=""> `strong_retain_unowned` instructions.<br class="">2. adding the `copy_value` and `copy_unowned_value` instructions.<br class="">3. removing the `strong_release`, `release_value`, `unowned_release`<br class=""> instructions.<br class="">4. adding the `destroy_value` instruction.<br class=""><br class="">This will allow for the SIL IR to express ownership conventions via SSA use-def<br class="">chains.<br class=""><br class=""># Definitions<br class=""><br class="">## copy_value<br class=""><br class="">Define a `copy_value` as follows:<br class=""><br class=""> %y = copy_value %x : $*C<br class=""> use(%y)<br class=""><br class=""> =><br class=""><br class=""> retain_value %x : $C<br class=""> use(%x)<br class=""><br class="">## copy_unowned_value<br class=""><br class="">Define a `copy_unowned_value` as:<br class=""><br class=""> %y = copy_unowned_value %x : $@unowned T<br class=""><br class=""> =><br class=""><br class=""> strong_retain_unowned %x : $@unowned T<br class=""><br class="">where `%y` has type `$T`. This is necessary to enable the strong reference count<br class="">associated with the `copy_unowned_value` to be balanced by a<br class="">`destroy_addr`. Thus normally one will see this instruction used as follows:<br class=""><br class=""> %y = copy_unowned_value %x : $@unowned T<br class=""> ...<br class=""> destroy_value %y : $T<br class=""><br class="">## destroy_value<br class=""><br class="">Define a `destroy_value` as follows:<br class=""><br class=""> destroy_value %x : $C<br class=""><br class=""> =><br class=""><br class=""> release_value %x : $C<br class=""><br class=""># Implementation<br class=""><br class="">## Plan<br class=""><br class="">We assume that<br class="">the [High Level ARC Memory Operations](high-level-arc-memory-operations)<br class="">proposal has been implemented. First we perform the following preliminary work:<br class=""><br class="">1. `copy_value`, `destroy_value`, `copy_unowned_value` support will be added to<br class=""> SIL, IRGen, serialization, printing, SIL parsing. SILGen will not be modified<br class=""> at this stage.<br class=""><br class="">2. The "OwnershipModelEliminator" will be taught to transform `copy_value`,<br class=""> `copy_unowned_value`, `destroy_value` into their constituant operations.<br class=""><br class="">Then we wire up the building blocks:<br class=""><br class="">1. SILGen will be taught to emit `copy_value`, `copy_unowned_value`, and<br class=""> `destroy_value` instead of `strong_retain`, `retain_value`, `strong_release`,<br class=""> `release_value`, and `strong_retain_unowned`.<br class=""><br class="">2. The pass manager will not require any changes due to previous work<br class=""> in [High Level ARC Memory Operations](high-level-arc-memory-operations).<br class=""><br class="">3. The verifier when in EnforceSILOwnershipMode will verify that none of the<br class=""> instructions that we wish to remove are in the IR.<br class=""><br class="">## Optimizer Changes<br class=""><br class="">Since the SILOwnershipModel eliminator will eliminate the `copy_value`,<br class="">`copy_unowned_value`, and `destroy_value` operations right after ownership<br class="">verification, there will be no immediate effects on the optimizer and thus the<br class="">optimizer changes can be done in parallel with the rest of the SIL Ownership<br class="">work. But in the long run, we want these instructions to be lowered by IRGen<br class="">implying that we must consider how this will affect the rest of the optimizer<br class="">pipeline.<br class=""><br class="">We now go through all of the passes that will need updating to handle these<br class="">changes:<br class=""><br class="">### ARC Optimizer<br class=""><br class="">Since the ARC optimizer does not perform code motion any more, only minimal<br class="">changes will be required. Specifically, all we must do is recognize copy_value<br class="">as a retain instruction and destroy_value as a release instruction. Everything<br class="">then will *just* work.<br class=""><br class="">### ARC Code Motion and Function Signature Optimization<br class=""><br class="">Both of these passes will need to recognize `copy_value`, `destroy_value`<br class="">instructions as retain, release and be changed to emit `copy_value` or<br class="">`destroy_value` instead of retain, release instructions. In the case of ARC code<br class="">motion rather than just re-emitting retain, release instructions without<br class="">considering use-def lists, it must now consider such issues to ensure that we do<br class="">not violate use-def dominance.<br class=""><br class="">### Misc compiler Peepholes: SILCombine, Mandatory Inlining, etc.<br class=""><br class="">There are many peepholes in the compiler that emit retain, release instructions<br class="">for ARC optimizations to clean up later. These must be updated to use the new<br class="">instructions. This will be mechanical.<br class=""><br class="">### Side Effects<br class=""><br class="">The side effects subsystem needs to be updated to handle copy_value like it does<br class="">a retain and destroy_value like it does a release. This should be mechanical.</body></html>