Centralize and document low-level OSSA utilities

...for handling borrow scopes:

- find[Extended]TransitiveGuaranteedUses

- BorrowingOperand::visit[Extended]ScopeEndingUses

- BorrowedValue BorrowingOperand::getBorrowIntroducingUserResult()

And document the logic.

Mostly NFC in this commit, but more RAUW cases should be correctly
handled now.

Particularly, ensure that we can cleanly handle all manner of
reborrows. This is necessary to ensure both CanonicalizeOSSA and
replace-all-uses higher-level utilities handle all cases.

This generalizes some of the logic in CanonicalizeOSSA so it can be
shared by other high-level OSSA utilities.

These utilities extend the fundamental BorrowingOperand and
BorrowedValue functionality that has been designed recently. It builds
on and replaces a mix of piece-meal functionality that was needed
during bootstrapping. These APIs are now consistent with the more
recently designed code. It should be obvious what they mean and how to
use them, should be very hard to use them incorrectly, and should be
as efficient as possible, since they're fundamental to other
higher-level utilities.

Most importantly, there were several very subtle correctness issues
that were not handled cleanly in a centralized way. There are now a
mix of higher-level utilities trying to use this underlying
functionality, but it was hard to tell if all those higher-level
utilities were covering all the subtle cases:

- checking for PointerEscapes everywhere we need to

- the differences between uses of borrow introducers and other
  guaranteed values

- handling the uses of nested borrow scopes

- transitively handling reborrows

- the difference between nested and top-level reborrows

- forwarding destructures (which can cause exponential explosion)

In short, I was fundamentally confused and getting things wrong before
designing these utilities.
This commit is contained in:
Andrew Trick
2021-01-30 19:26:13 -08:00
parent 6780f3d8c7
commit caefb9afaa
7 changed files with 395 additions and 244 deletions

View File

@@ -241,7 +241,7 @@ public:
// borrow it's based on.
SmallVector<Operand *, 4> endScopeInsts;
value.visitLocalScopeEndingUses(
[&](Operand *use) { endScopeInsts.push_back(use); });
[&](Operand *use) { endScopeInsts.push_back(use); return true; });
LinearLifetimeChecker checker(ctx.getDeadEndBlocks());