[ownership] Add a new API to OwnershipFixupContext::replaceAllAddressUsesFixingInteriorPointerOwnership.

In OSSA, we enforce that addresses from interior pointer instructions are scoped
within a borrow scope. This means that it is invalid to use such an address
outside of its parent borrow scope and as a result one can not just RAUW an
address value by a dominating address value since the latter may be invalid at
the former. I foresee that I am going to have to solve this problem and so I
decided to write this API to handle the vast majority of cases.

The way this API works is that it:

1. Computes an access path with base for the new value. If we do not have a base
value and a valid access path with root, we bail.

2. Then we check if our base value is the result of an interior pointer
instruction. If it isn't, we are immediately done and can RAUW without further
delay.

3. If we do have an interior pointer instruction, we see if the immediate
guaranteed value we projected from has a single borrow introducer value. If not,
we bail. I think this is reasonable since with time, all guaranteed values will
always only have a single borrow introducing value (once struct, tuple,
destructure_struct, destructure_tuple become reborrows).

4. Then we gather up all inner uses of our access path. If for some reason that
fails, we bail.

5. Then we see if all of those uses are within our borrow scope. If so, we can
RAUW without any further worry.

6. Otherwise, we perform a copy+borrow of our interior pointer's operand value
at the interior pointer, create a copy of the interior pointer instruction upon
this new borrow and then RAUW oldValue with that instead. By construction all
uses of oldValue will be within this new interior pointer scope.
This commit is contained in:
Michael Gottesman
2021-01-01 12:44:46 -08:00
parent fe4c345d0d
commit 73ba521e56
7 changed files with 393 additions and 113 deletions

View File

@@ -583,7 +583,7 @@ public:
DeadEndBlocks &DeadEndBBs;
OwnershipRAUWHelper &RAUWHelper;
OwnershipFixupContext &RAUWFixupContext;
/// The set of calls to lazy property getters which can be replace by a direct
/// load of the property value.
@@ -591,9 +591,10 @@ public:
CSE(bool RunsOnHighLevelSil, SideEffectAnalysis *SEA,
SILOptFunctionBuilder &FuncBuilder, DeadEndBlocks &DeadEndBBs,
OwnershipRAUWHelper &RAUWHelper)
OwnershipFixupContext &RAUWFixupContext)
: SEA(SEA), FuncBuilder(FuncBuilder), DeadEndBBs(DeadEndBBs),
RAUWHelper(RAUWHelper), RunsOnHighLevelSil(RunsOnHighLevelSil) {}
RAUWFixupContext(RAUWFixupContext),
RunsOnHighLevelSil(RunsOnHighLevelSil) {}
bool processFunction(SILFunction &F, DominanceInfo *DT);
@@ -1017,14 +1018,14 @@ bool CSE::processNode(DominanceInfoNode *Node) {
// extend it here as well
if (!isa<SingleValueInstruction>(Inst))
continue;
if (!OwnershipRAUWHelper::canFixUpOwnershipForRAUW(
cast<SingleValueInstruction>(Inst),
cast<SingleValueInstruction>(AvailInst)))
OwnershipRAUWHelper helper(RAUWFixupContext,
cast<SingleValueInstruction>(Inst),
cast<SingleValueInstruction>(AvailInst));
if (!helper.isValid())
continue;
// Replace SingleValueInstruction using OSSA RAUW here
nextI = RAUWHelper.replaceAllUsesAndErase(
cast<SingleValueInstruction>(Inst),
cast<SingleValueInstruction>(AvailInst));
nextI = helper.perform();
Changed = true;
++NumCSE;
continue;
@@ -1399,8 +1400,7 @@ class SILCSE : public SILFunctionTransform {
JointPostDominanceSetComputer Computer(DeadEndBBs);
InstModCallbacks callbacks;
OwnershipFixupContext FixupCtx{callbacks, DeadEndBBs, Computer};
OwnershipRAUWHelper RAUWHelper(FixupCtx);
CSE C(RunsOnHighLevelSil, SEA, FuncBuilder, DeadEndBBs, RAUWHelper);
CSE C(RunsOnHighLevelSil, SEA, FuncBuilder, DeadEndBBs, FixupCtx);
bool Changed = false;
// Perform the traditional CSE.