Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
Compute, update and handle borrowed-from instruction in various utilities and passes.
Also, used borrowed-from to simplify `gatherBorrowIntroducers` and `gatherEnclosingValues`.
Replace those utilities by `Value.getBorrowIntroducers` and `Value.getEnclosingValues`, which return a lazily computed Sequence of borrowed/enclosing values.
Adds to SemanticARCOpts a new step of removing move_value instructions
if they are redundant. A move_value is redundant if it adds no new
information or optimization opportunities.
An example of adding information: a lifetime becoming lexical. The new
lifetime's destroys cannot be hoisted over deinit barriers.
An example of adding an optimization opportunity: the original value
escapes but the value produced by the move_value does not escape. So
destroys of the new value can be hoisted more aggressively.
This bleeds into the implementation where "guaranteed" is used
everywhere to talk about optimization of guaranteed values. We need to
use mandatory to indicate we're talking about the pass pipeline.
Importantly this also lets us use the analysis framework to validate that we do
properly invalidate DeadEndBlocks, preventing bugs.
I did not thread this all over the compiler. Instead I just used it for now in
SemanticARCOpts just to add some coverage without threading it into too many
places.
Specifically, we check that all of the unowned's value uses are within the
lifetime of the unchecked_ownership_conversion's operand. If so, we eliminate
it.
This split will ensure we are testing only what a specific optimization is doing
rather than all together.
NOTE: The way I split up the tests is I first split up each of the tests by
subject area by hand that I thought were specifically testing one pass. Then any
tests where the FileCheck tests started to fail due to us not running the other
passes, I put back a copy in the original semantic-arc-opts.sil to ensure we do
not regress.
Note, the tests that I copied for each of these passes
are originally from semantic-arc-opts.sil. I left them there as well so we could
see all of the opts together. I also only copied the ones that were testing pass
specific functionality.
SemanticARCOpts for maintainance reasons is becoming a series of small
optimization passes with a little pass manager that runs them. Given that, I
want to be able to be able to run subsets of these transforms for testing
reasons while normally running them in series.
This is in preparation for landing the coroutine lifetime extender and the
auto-coroutinizer.
This patch moves state from the main SemanticARCOptVisitor struct to instead be
on a context object. Sub-transformations should not need to know about the
visitor since how it processes things is orthogonal from the transformations
themselves.
This is so I can move individual sub-optimizations on SemanticARCOptVisitor into
their own files. So for instance, there will be one file containing the load
[copy] optimization and another containing the phi optimization, etc.
SemanticARCOpts keeps on growing with various optimizations attached to a single
"optimization" manager. Move it to its own folder in prepation for splitting it
into multiple different optimizations and utility files.