Skip to content

Commit a2fac95

Browse files
committed
OSSA ownership optimization RAUW utility fixes.
Verify that the OwnershipRAUWUtility always preserves the original borrow scope by exhaustively switching over OperandOwnership. And related cleanup.
1 parent 1f1123f commit a2fac95

File tree

7 files changed

+138
-104
lines changed

7 files changed

+138
-104
lines changed

include/swift/SIL/OwnershipUtils.h

+13-14
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,10 @@ inline bool isForwardingConsume(SILValue value) {
7676
}
7777

7878
class ForwardingOperand {
79-
Operand *use;
80-
81-
ForwardingOperand(Operand *use) : use(use) {}
79+
Operand *use = nullptr;
8280

8381
public:
84-
static ForwardingOperand get(Operand *use);
82+
explicit ForwardingOperand(Operand *use);
8583

8684
OwnershipConstraint getOwnershipConstraint() const {
8785
// We use a force unwrap since a ForwardingOperand should always have an
@@ -665,25 +663,26 @@ struct InteriorPointerOperand {
665663
llvm_unreachable("Covered switch isn't covered?!");
666664
}
667665

668-
/// Compute the list of implicit uses that this interior pointer operand puts
669-
/// on its parent guaranted value.
666+
/// Transitively compute the list of uses that this interior pointer operand
667+
/// puts on its parent guaranted value.
670668
///
671669
/// Example: Uses of a ref_element_addr can not occur outside of the lifetime
672670
/// of the instruction's operand. The uses of that address act as liveness
673671
/// requirements to ensure that the underlying class is alive at all use
674672
/// points.
675-
bool getImplicitUses(SmallVectorImpl<Operand *> &foundUses,
676-
std::function<void(Operand *)> *onError = nullptr) {
677-
return getImplicitUsesForAddress(getProjectedAddress(), foundUses, onError);
673+
bool findTransitiveUses(SmallVectorImpl<Operand *> &foundUses,
674+
std::function<void(Operand *)> *onError = nullptr) {
675+
return findTransitiveUsesForAddress(getProjectedAddress(), foundUses,
676+
onError);
678677
}
679678

680679
/// The algorithm that is used to determine what the verifier will consider to
681-
/// be implicit uses of the given address. Used to implement \see
682-
/// getImplicitUses.
680+
/// be transitive uses of the given address. Used to implement \see
681+
/// findTransitiveUses.
683682
static bool
684-
getImplicitUsesForAddress(SILValue address,
685-
SmallVectorImpl<Operand *> &foundUses,
686-
std::function<void(Operand *)> *onError = nullptr);
683+
findTransitiveUsesForAddress(SILValue address,
684+
SmallVectorImpl<Operand *> &foundUses,
685+
std::function<void(Operand *)> *onError = nullptr);
687686

688687
Operand *operator->() { return operand; }
689688
const Operand *operator->() const { return operand; }

include/swift/SILOptimizer/Utils/OwnershipOptUtils.h

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ struct OwnershipFixupContext {
3838
DeadEndBlocks &deBlocks;
3939
JointPostDominanceSetComputer &jointPostDomSetComputer;
4040

41+
SmallVector<Operand *, 8> transitiveBorrowedUses;
42+
SmallVector<BorrowingOperand, 8> recursiveReborrows;
43+
4144
/// Extra state initialized by OwnershipRAUWFixupHelper::get() that we use
4245
/// when RAUWing addresses. This ensures we do not need to recompute this
4346
/// state when we perform the actual RAUW.
@@ -67,6 +70,8 @@ struct OwnershipFixupContext {
6770

6871
void clear() {
6972
jointPostDomSetComputer.clear();
73+
transitiveBorrowedUses.clear();
74+
recursiveReborrows.clear();
7075
extraAddressFixupInfo.allAddressUsesFromOldValue.clear();
7176
extraAddressFixupInfo.intPtrOp = InteriorPointerOperand();
7277
}

lib/SIL/Utils/OwnershipUtils.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ bool BorrowedValue::visitInteriorPointerOperands(
520520
// InteriorPointerOperand
521521
//===----------------------------------------------------------------------===//
522522

523-
bool InteriorPointerOperand::getImplicitUsesForAddress(
523+
bool InteriorPointerOperand::findTransitiveUsesForAddress(
524524
SILValue projectedAddress, SmallVectorImpl<Operand *> &foundUses,
525525
std::function<void(Operand *)> *onError) {
526526
SmallVector<Operand *, 8> worklist(projectedAddress->getUses());
@@ -882,12 +882,12 @@ OwnedValueIntroducer swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
882882
// Forwarding Operand
883883
//===----------------------------------------------------------------------===//
884884

885-
ForwardingOperand ForwardingOperand::get(Operand *use) {
885+
ForwardingOperand::ForwardingOperand(Operand *use) {
886886
if (use->isTypeDependent())
887-
return nullptr;
887+
return;
888888

889889
if (!OwnershipForwardingMixin::isa(use->getUser())) {
890-
return nullptr;
890+
return;
891891
}
892892
#ifndef NDEBUG
893893
switch (use->getOperandOwnership()) {
@@ -909,7 +909,7 @@ ForwardingOperand ForwardingOperand::get(Operand *use) {
909909
llvm_unreachable("this isn't the operand being forwarding!");
910910
}
911911
#endif
912-
return {use};
912+
this->use = use;
913913
}
914914

915915
ValueOwnershipKind ForwardingOperand::getOwnershipKind() const {
@@ -1008,7 +1008,7 @@ void ForwardingOperand::setOwnershipKind(ValueOwnershipKind newKind) const {
10081008
return;
10091009
}
10101010

1011-
llvm_unreachable("Out of sync with ForwardingOperand::get?!");
1011+
llvm_unreachable("Out of sync with OperandOwnership");
10121012
}
10131013

10141014
void ForwardingOperand::replaceOwnershipKind(ValueOwnershipKind oldKind,
@@ -1075,7 +1075,7 @@ void ForwardingOperand::replaceOwnershipKind(ValueOwnershipKind oldKind,
10751075
return;
10761076
}
10771077

1078-
llvm_unreachable("Missing Case! Out of sync with ForwardingOperand::get?!");
1078+
llvm_unreachable("Missing Case! Out of sync with OperandOwnership");
10791079
}
10801080

10811081
SILValue ForwardingOperand::getSingleForwardedValue() const {

lib/SIL/Verifier/SILOwnershipVerifier.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ bool SILValueOwnershipChecker::gatherUsers(
381381
<< "Address User: " << *op->getUser();
382382
});
383383
};
384-
foundError |= interiorPointerOperand.getImplicitUses(
384+
foundError |= interiorPointerOperand.findTransitiveUses(
385385
nonLifetimeEndingUsers, &onError);
386386
}
387387

lib/SILOptimizer/SemanticARC/CopyValueOpts.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ static bool canJoinIfCopyDiesInFunctionExitingBlock(
331331
}
332332

333333
static Operand *lookThroughSingleForwardingUse(Operand *use) {
334-
auto forwardingOperand = ForwardingOperand::get(use);
334+
ForwardingOperand forwardingOperand(use);
335335
if (!forwardingOperand)
336336
return nullptr;
337337
auto forwardedValue = forwardingOperand.getSingleForwardedValue();
@@ -423,7 +423,7 @@ static bool tryJoinIfDestroyConsumingUseInSameBlock(
423423
// If not, see if this use did have a forwardedValue but that forwardedValue
424424
// has multiple end lifetime uses. In that case, we can optimize if there
425425
// aren't any uses/etc
426-
auto forwardingOperand = ForwardingOperand::get(currentForwardingUse);
426+
ForwardingOperand forwardingOperand(currentForwardingUse);
427427
if (!forwardingOperand)
428428
return false;
429429
auto forwardedValue = forwardingOperand.getSingleForwardedValue();

lib/SILOptimizer/SemanticARC/OwnershipLiveRange.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ void OwnershipLiveRange::convertOwnedGeneralForwardingUsesToGuaranteed() && {
228228
while (!ownershipForwardingUses.empty()) {
229229
auto *use = ownershipForwardingUses.back();
230230
ownershipForwardingUses = ownershipForwardingUses.drop_back();
231-
auto operand = ForwardingOperand::get(use);
231+
ForwardingOperand operand(use);
232232
operand.replaceOwnershipKind(OwnershipKind::Owned,
233233
OwnershipKind::Guaranteed);
234234
}

0 commit comments

Comments
 (0)