Skip to content

Commit c20abdb

Browse files
committed
[ownership] Give better names to methods on OwnershipLifetimeExtender.
Specifically, copyAndExtendForLifetimeEndingRAUW -> createPlusOneCopy(value, oldConsumingUse) copyAndExtendForNonLifetimeEndingRAUW -> createPlusZeroCopy(value, nonLifetimeEndingUses) copyBorrowAndExtendForRAUW -> createPlusZeroBorrow(value, nonLifetimeEndingUses) Beyond being shorter, the PlusOne vs PlusZero mnemonic is telling the caller whether or not the caller is responsible for cleaning up the returned copy_value. In the PlusZero cases, we assume that all uses are non-lifetime ending and we need to insert all destroy_value at the liveness points of the value. In the PlusOne case in contrast, we are supposed to make a copy of value and the complete oldConsumingUse's block into a joint post-dominance set of blocks. Then we insert destroy_values for our new copy into the completion blocks that we found and leave cleaning up value along paths through oldConsumingUse to our user. In this sense the value is a PlusOne value that our user must clean up for us (sorta makes me think about ManagedValue).
1 parent b7d00b0 commit c20abdb

File tree

1 file changed

+45
-81
lines changed

1 file changed

+45
-81
lines changed

lib/SILOptimizer/Utils/OwnershipOptUtils.cpp

Lines changed: 45 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "swift/SIL/SILBuilder.h"
2929
#include "swift/SIL/SILInstruction.h"
3030
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
31+
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
3132
#include "swift/SILOptimizer/Utils/ValueLifetime.h"
3233

3334
using namespace swift;
@@ -167,39 +168,48 @@ namespace {
167168
struct OwnershipLifetimeExtender {
168169
OwnershipFixupContext &ctx;
169170

170-
/// Lifetime extend newValue over owned oldValue assuming that our copy will
171-
/// have its lifetime ended by oldValue's lifetime ending uses after RAUWing.
172-
CopyValueInst *
173-
copyAndExtendForLifetimeEndingRAUW(SILValue value,
174-
SILInstruction *consumingPoint);
175-
176-
CopyValueInst *
177-
copyAndExtendForNonLifetimeEndingRAUW(SILValue value,
178-
ArrayRef<Operand *> range) {
179-
return copyAndExtendForNonLifetimeEndingRAUW<ArrayRef<Operand *>>(value,
180-
range);
171+
/// Create a new copy of \p value assuming that our caller will clean up the
172+
/// copy along all paths that go through consuming point. Operationally this
173+
/// means that the API will insert compensating destroy_value on the copy
174+
/// along all paths that do not go through consuming point.
175+
///
176+
/// DISCUSSION: If \p consumingPoint is an instruction that forwards \p value,
177+
/// calling this and then RAUWing with \p value guarantee that \p value will
178+
/// be consumed by the forwarding instruction's results consuming uses.
179+
CopyValueInst *createPlusOneCopy(SILValue value,
180+
SILInstruction *consumingPoint);
181+
182+
/// Create a copy of \p value that covers all of \p range and insert all
183+
/// needed destroy_values. We assume that no uses in \p range consume \p
184+
/// value.
185+
CopyValueInst *createPlusZeroCopy(SILValue value, ArrayRef<Operand *> range) {
186+
return createPlusZeroCopy<ArrayRef<Operand *>>(value, range);
181187
}
182188

189+
/// Create a copy of \p value that covers all of \p range and insert all
190+
/// needed destroy_values. We assume that all uses in \p range do not consume
191+
/// \p value.
192+
///
193+
/// We return our copy_value to the user at +0 to show that they do not need
194+
/// to insert cleanup destroys.
183195
template <typename RangeTy>
184-
CopyValueInst *copyAndExtendForNonLifetimeEndingRAUW(SILValue value,
185-
const RangeTy &range);
196+
CopyValueInst *createPlusZeroCopy(SILValue value, const RangeTy &range);
186197

198+
/// Create a new borrow scope for \p newValue that contains all uses in \p
199+
/// useRange. We assume that \p useRange does not contain any lifetime ending
200+
/// uses.
187201
template <typename RangeTy>
188-
BeginBorrowInst *copyBorrowAndExtendForRAUW(SILValue newValue,
189-
RangeTy useRange);
190-
191-
/// We are copy/borrowing new value to be over the same lifetime as old
192-
/// value. We know that oldValue is dominated by newValue.
193-
BeginBorrowInst *copyBorrowAndExtendForLifetimeEndingRAUW(SILValue newValue,
194-
SILValue oldValue);
202+
BeginBorrowInst *createPlusZeroBorrow(SILValue newValue, RangeTy useRange);
195203
};
196204

197205
} // end anonymous namespace
198206

199-
/// Lifetime extend newValue over owned oldValue assuming that our copy will
200-
/// have its lifetime ended by oldValue's lifetime ending uses after RAUWing.
201-
CopyValueInst *OwnershipLifetimeExtender::copyAndExtendForLifetimeEndingRAUW(
202-
SILValue value, SILInstruction *consumingPoint) {
207+
// Lifetime extend newValue over owned oldValue assuming that our copy will have
208+
// its lifetime ended by oldValue's lifetime ending uses after RAUWing by our
209+
// caller.
210+
CopyValueInst *
211+
OwnershipLifetimeExtender::createPlusOneCopy(SILValue value,
212+
SILInstruction *consumingPoint) {
203213
auto *newValInsertPt = value->getDefiningInsertionPoint();
204214
assert(newValInsertPt);
205215
CopyValueInst *copy;
@@ -242,9 +252,12 @@ CopyValueInst *OwnershipLifetimeExtender::copyAndExtendForLifetimeEndingRAUW(
242252
return result;
243253
}
244254

255+
// A copy_value that we lifetime extend with destroy_value over range. We assume
256+
// all instructions passed into range do not consume value.
245257
template <typename RangeTy>
246-
CopyValueInst *OwnershipLifetimeExtender::copyAndExtendForNonLifetimeEndingRAUW(
247-
SILValue value, const RangeTy &range) {
258+
CopyValueInst *
259+
OwnershipLifetimeExtender::createPlusZeroCopy(SILValue value,
260+
const RangeTy &range) {
248261
auto *newValInsertPt = value->getDefiningInsertionPoint();
249262
assert(newValInsertPt);
250263

@@ -281,8 +294,8 @@ CopyValueInst *OwnershipLifetimeExtender::copyAndExtendForNonLifetimeEndingRAUW(
281294

282295
template <typename RangeTy>
283296
BeginBorrowInst *
284-
OwnershipLifetimeExtender::copyBorrowAndExtendForRAUW(SILValue newValue,
285-
RangeTy useRange) {
297+
OwnershipLifetimeExtender::createPlusZeroBorrow(SILValue newValue,
298+
RangeTy useRange) {
286299
auto *newValInsertPt = newValue->getDefiningInsertionPoint();
287300
assert(newValInsertPt);
288301

@@ -326,52 +339,6 @@ OwnershipLifetimeExtender::copyBorrowAndExtendForRAUW(SILValue newValue,
326339
return borrow;
327340
}
328341

329-
/// We are copy/borrowing new value to be over the same lifetime as old
330-
/// value. We know that oldValue is dominated by newValue.
331-
BeginBorrowInst *
332-
OwnershipLifetimeExtender::copyBorrowAndExtendForLifetimeEndingRAUW(
333-
SILValue newValue, SILValue oldValue) {
334-
auto *newValInsertPt = newValue->getDefiningInsertionPoint();
335-
assert(newValInsertPt);
336-
337-
CopyValueInst *copy = nullptr;
338-
if (!isa<SILArgument>(newValue)) {
339-
SILBuilderWithScope::insertAfter(newValInsertPt, [&](SILBuilder &builder) {
340-
auto loc = builder.getInsertionPointLoc();
341-
copy = builder.createCopyValue(loc, newValue);
342-
});
343-
} else {
344-
SILBuilderWithScope builder(newValInsertPt);
345-
auto loc = newValInsertPt->getLoc();
346-
copy = builder.createCopyValue(loc, newValue);
347-
}
348-
349-
// Then insert the begin_borrow at the old value point. We are going to RAUW
350-
// this in our caller.
351-
auto *oldValInsertPt = oldValue->getDefiningInsertionPoint();
352-
assert(oldValInsertPt);
353-
auto *borrow = SILBuilderWithScope(oldValInsertPt)
354-
.createBeginBorrow(oldValInsertPt->getLoc(), copy);
355-
356-
auto &callbacks = ctx.callbacks;
357-
callbacks.createdNewInst(borrow);
358-
359-
ValueLifetimeAnalysis lifetimeAnalysis(copy, oldValue->getUses());
360-
decltype(lifetimeAnalysis)::Frontier frontier;
361-
bool result = lifetimeAnalysis.computeFrontier(
362-
frontier, ValueLifetimeAnalysis::DontModifyCFG, &ctx.deBlocks);
363-
assert(result);
364-
365-
while (!frontier.empty()) {
366-
auto *insertPt = frontier.pop_back_val();
367-
SILBuilderWithScope frontierBuilder(insertPt);
368-
auto *dvi = frontierBuilder.createDestroyValue(insertPt->getLoc(), copy);
369-
callbacks.createdNewInst(dvi);
370-
}
371-
372-
return borrow;
373-
}
374-
375342
//===----------------------------------------------------------------------===//
376343
// Reborrow Elimination
377344
//===----------------------------------------------------------------------===//
@@ -577,7 +544,7 @@ SILBasicBlock::iterator OwnershipRAUWUtility::handleUnowned() {
577544
}
578545
auto extender = getLifetimeExtender();
579546
SILValue borrow =
580-
extender.copyBorrowAndExtendForRAUW(newValue, oldValue->getUses());
547+
extender.createPlusZeroBorrow(newValue, oldValue->getUses());
581548
SILBuilderWithScope builder(oldValue);
582549
auto *newInst = builder.createUncheckedOwnershipConversion(
583550
oldValue->getLoc(), borrow, OwnershipKind::Unowned);
@@ -608,8 +575,7 @@ SILBasicBlock::iterator OwnershipRAUWUtility::handleUnowned() {
608575
}
609576
}
610577
auto extender = getLifetimeExtender();
611-
SILValue copy = extender.copyAndExtendForNonLifetimeEndingRAUW(
612-
newValue, oldValue->getUses());
578+
SILValue copy = extender.createPlusZeroCopy(newValue, oldValue->getUses());
613579
SILBuilderWithScope builder(oldValue);
614580
auto *newInst = builder.createUncheckedOwnershipConversion(
615581
oldValue->getLoc(), copy, OwnershipKind::Unowned);
@@ -644,8 +610,7 @@ SILBasicBlock::iterator OwnershipRAUWUtility::handleGuaranteed() {
644610

645611
auto extender = getLifetimeExtender();
646612
SILValue newBorrowedValue =
647-
extender.copyBorrowAndExtendForRAUW<ArrayRef<Operand *>>(newValue,
648-
usePoints);
613+
extender.createPlusZeroBorrow<ArrayRef<Operand *>>(newValue, usePoints);
649614

650615
// Now we need to handle reborrows by eliminating the reborrows from any
651616
// borrowing operands that use old value as well as from oldvalue itself. We
@@ -706,8 +671,7 @@ SILBasicBlock::iterator OwnershipRAUWUtility::perform() {
706671
// lifetimeEnding RAUW, then RAUW the value, and insert a destroy_value on
707672
// the original value.
708673
auto extender = getLifetimeExtender();
709-
SILValue copy =
710-
extender.copyAndExtendForLifetimeEndingRAUW(newValue, oldValue);
674+
SILValue copy = extender.createPlusOneCopy(newValue, oldValue);
711675
cleanupOperandsBeforeDeletion(oldValue, ctx.callbacks);
712676
auto result = replaceAllUsesAndErase(oldValue, copy, ctx.callbacks);
713677
return result;

0 commit comments

Comments
 (0)