Optimizer: eliminate `struct_extract`s of an owned `struct` where the `struct_extract`s are inside a borrow scope
This is done by splitting the `begin_borrow` of the whole struct into individual borrows of the fields (for trivial fields no borrow is needed).
And then sinking the `struct` to it's consuming use(s).
```
%3 = struct $S(%nonTrivialField, %trivialField) // owned
...
%4 = begin_borrow %3
%5 = struct_extract %4, #S.nonTrivialField
%6 = struct_extract %4, #S.trivialField
use %5, %6
end_borrow %4
...
end_of_lifetime %3
```
->
```
...
%5 = begin_borrow %nonTrivialField
use %5, %trivialField
end_borrow %5
...
%3 = struct $S(%nonTrivialField, %trivialField)
end_of_lifetime %3
```
This optimization is important for Array code where the Array buffer is constantly wrapped into structs and then extracted again to access the buffer.