The optimization replaces a `load [copy]` with a `load_borrow` if possible.
```
%1 = load [copy] %0
// no writes to %0
destroy_value %1
```
->
```
%1 = load_borrow %0
// no writes to %0
end_borrow %1
```
The new implementation uses alias-analysis (instead of a simple def-use walk), which is much more powerful.
rdar://115315849
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.
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 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.
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.