In preparation for adding OwnershipLiveness.
Rename Simple LiveRangeSummary to LiveRangeSummary.
Add initializeDefNode helpers to avoid confusion about the argument
type.
Add defBegin/defEnd iterators in MultiDefPrunedLiveness.
We already have entry points for creating an ExtendedASTNodeLoc with an empty
location for diagnostics and a location for debugging. This does the inverse so
one can emit diagnostics that point at a terminator sourceloc without needing to
add a ReturnInst to the instruction which is illegal and would cause the
SILVerifier to assert.
Specifically:
1. I added to the documentation at the top of the file that our representation
allows for partial init/reinit of structs/tuples from parts.
2. I renamed SubElementNumber to SubElementOffset. This I think fits the actual
use case better and makes it clearer what one is working with (the offset inside
a type of a subelement of the type).
3. I added some small helpers to TypeSubElementCount and SubElementOffset for
adding/subtracting from them.
4. I added the ability to iterate over just consuming/nonconsuming users in
FieldSensitivePrunedLiveness. Just a useful little helper.
When emitting debug info that references into a macro expansion, dump
the macro expansion buffer into a file on disk (in the temporary
directory) so that one can see the macro expansion buffers in the
source files themselves.
The test here validates that the generated LLVM IR looks correct, but
I'm having a problem getting LLDB to actually locate the source code
correctly.
In a sense, liveness is wrong for dead guaranteed phis that aren't
enclosed in a separate borrow scope:
left: // live-within
br merge(%v)
right: // live-within
br merge(%v)
merge(%deadPhi) // dead
But this is the way that liveness layering works. PrunedLiveness
simply doesn't know which phis will "end" liveness. This will be the
job of OwnershipLiveness, which will have safe APIs for situations
where this weirdness matters.
The first is a default constructor that initializes both startEltOffset and
endEltOffset to 0. This is used to ensure that we can use certain standard
algorithms that expect to be able to perform a default constructor when
inserting an initial value into a collection.
The second adds the ability to construct a TypeTreeLeafTypeRange for a
SILType/SILFunction if one has a type without an actual value.
This just calls:
```
SILType::getFieldType(VarDecl *, SILModule &, TypeExpansionContext) const
```
using the state in the SILFunction to handle the SILModule and
TypeExpansionContext parameters.
Just trimming down a larger commit into smaller commits.
I did this by doing the following:
1. I renamed computeUseBlockLiveness to computeScalarUseBlockLiveness and
changed it to take a specific bit that it is testing for.
2. I changed the logic that already existed in this code path that worked scalar
by scalar to use scalar logic rather than call the broken multi-bit at a time
code path.
3. We took advantage of resultingFoundLiveness now only returning the requested
bits instead of all bits. This ensures that we do not run
computeScalarUseBlockLiveness for those unneeded dead bits resulting in liveness
being inappropriately propagated into predecessors.
Previously, we would pan the array with isDead. The thinking is that this would
make it easier to bitmask directly against. In practice, this usage was a minor
use case and doing this lead to a bunch of logic mistakes in forthcoming code.
These APIs are essential for complete OSSA liveness analysis. The
existing ad-hoc OSSA logic always misses some of the cases handled by
these new utilities. We need to start replacing that ad-hoc logic with
new utilities built on top of these APIs to define away potential
latent bugs.
Add FIXMEs to the inverse API: visitAdjacentBorrowsOfPhi. It should
probably be redesigned in terms of these new APIs.
Factors a mess of code in MemAccessUtils to handle forwarding
instruction types into a simpler utility. This utility is also needed
for ownership APIs, which need to be extended to handle these cases.