Skip to content

Commit 33ab920

Browse files
authored
Merge pull request swiftlang#35430 from gottesmm/pr-efd34fda22c8ccd45b958b606e3ff64c25edca17
[ownership] Eliminate Optional return value APIs from OwnershipUtils in favor of an Invalid enum case.
2 parents 9b0c17e + 2ae43f9 commit 33ab920

11 files changed

+181
-123
lines changed

include/swift/SIL/OwnershipUtils.h

Lines changed: 104 additions & 67 deletions
Large diffs are not rendered by default.

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ bool swift::canOpcodeForwardOwnedValues(Operand *use) {
146146

147147
void BorrowingOperandKind::print(llvm::raw_ostream &os) const {
148148
switch (value) {
149+
case Kind::Invalid:
150+
llvm_unreachable("Using an unreachable?!");
149151
case Kind::BeginBorrow:
150152
os << "BeginBorrow";
151153
return;
@@ -190,6 +192,8 @@ llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os,
190192
bool BorrowingOperand::visitLocalEndScopeUses(
191193
function_ref<bool(Operand *)> func) const {
192194
switch (kind) {
195+
case BorrowingOperandKind::Invalid:
196+
llvm_unreachable("Using invalid case");
193197
case BorrowingOperandKind::BeginBorrow:
194198
for (auto *use : cast<BeginBorrowInst>(op->getUser())->getUses()) {
195199
if (use->isLifetimeEnding()) {
@@ -228,20 +232,24 @@ bool BorrowingOperand::visitLocalEndScopeUses(
228232
void BorrowingOperand::visitBorrowIntroducingUserResults(
229233
function_ref<void(BorrowedValue)> visitor) const {
230234
switch (kind) {
235+
case BorrowingOperandKind::Invalid:
236+
llvm_unreachable("Using invalid case");
231237
case BorrowingOperandKind::Apply:
232238
case BorrowingOperandKind::TryApply:
233239
case BorrowingOperandKind::BeginApply:
234240
case BorrowingOperandKind::Yield:
235241
llvm_unreachable("Never has borrow introducer results!");
236242
case BorrowingOperandKind::BeginBorrow: {
237-
auto value = *BorrowedValue::get(cast<BeginBorrowInst>(op->getUser()));
243+
auto value = BorrowedValue::get(cast<BeginBorrowInst>(op->getUser()));
244+
assert(value);
238245
return visitor(value);
239246
}
240247
case BorrowingOperandKind::Branch: {
241248
auto *bi = cast<BranchInst>(op->getUser());
242249
for (auto *succBlock : bi->getSuccessorBlocks()) {
243250
auto value =
244-
*BorrowedValue::get(succBlock->getArgument(op->getOperandNumber()));
251+
BorrowedValue::get(succBlock->getArgument(op->getOperandNumber()));
252+
assert(value);
245253
visitor(value);
246254
}
247255
return;
@@ -263,8 +271,8 @@ void BorrowingOperand::visitConsumingUsesOfBorrowIntroducingUserResults(
263271
// single guaranteed scope.
264272
value.visitLocalScopeEndingUses([&](Operand *valueUser) {
265273
if (auto subBorrowScopeOp = BorrowingOperand::get(valueUser)) {
266-
if (subBorrowScopeOp->isReborrow()) {
267-
subBorrowScopeOp->visitUserResultConsumingUses(func);
274+
if (subBorrowScopeOp.isReborrow()) {
275+
subBorrowScopeOp.visitUserResultConsumingUses(func);
268276
return;
269277
}
270278
}
@@ -315,6 +323,8 @@ void BorrowingOperand::getImplicitUses(
315323

316324
void BorrowedValueKind::print(llvm::raw_ostream &os) const {
317325
switch (value) {
326+
case BorrowedValueKind::Invalid:
327+
llvm_unreachable("Using invalid case?!");
318328
case BorrowedValueKind::SILFunctionArgument:
319329
os << "SILFunctionArgument";
320330
return;
@@ -342,6 +352,8 @@ void BorrowedValue::getLocalScopeEndingInstructions(
342352
assert(isLocalScope() && "Should only call this given a local scope");
343353

344354
switch (kind) {
355+
case BorrowedValueKind::Invalid:
356+
llvm_unreachable("Using invalid case?!");
345357
case BorrowedValueKind::SILFunctionArgument:
346358
llvm_unreachable("Should only call this with a local scope");
347359
case BorrowedValueKind::BeginBorrow:
@@ -361,6 +373,8 @@ void BorrowedValue::visitLocalScopeEndingUses(
361373
function_ref<void(Operand *)> visitor) const {
362374
assert(isLocalScope() && "Should only call this given a local scope");
363375
switch (kind) {
376+
case BorrowedValueKind::Invalid:
377+
llvm_unreachable("Using invalid case?!");
364378
case BorrowedValueKind::SILFunctionArgument:
365379
llvm_unreachable("Should only call this with a local scope");
366380
case BorrowedValueKind::LoadBorrow:
@@ -441,7 +455,7 @@ bool BorrowedValue::visitLocalScopeTransitiveEndingUses(
441455
continue;
442456
}
443457

444-
scopeOperand->visitConsumingUsesOfBorrowIntroducingUserResults(
458+
scopeOperand.visitConsumingUsesOfBorrowIntroducingUserResults(
445459
[&](Operand *op) {
446460
assert(op->isLifetimeEnding() && "Expected only consuming uses");
447461
// Make sure we haven't visited this consuming operand yet. If we
@@ -464,7 +478,7 @@ bool BorrowedValue::visitInteriorPointerOperands(
464478
auto *op = worklist.pop_back_val();
465479

466480
if (auto interiorPointer = InteriorPointerOperand::get(op)) {
467-
func(*interiorPointer);
481+
func(interiorPointer);
468482
continue;
469483
}
470484

@@ -617,6 +631,8 @@ bool InteriorPointerOperand::getImplicitUses(
617631

618632
void OwnedValueIntroducerKind::print(llvm::raw_ostream &os) const {
619633
switch (value) {
634+
case OwnedValueIntroducerKind::Invalid:
635+
llvm_unreachable("Using invalid case?!");
620636
case OwnedValueIntroducerKind::Apply:
621637
os << "Apply";
622638
return;
@@ -677,7 +693,7 @@ bool swift::getAllBorrowIntroducingValues(SILValue inputValue,
677693

678694
// First check if v is an introducer. If so, stash it and continue.
679695
if (auto scopeIntroducer = BorrowedValue::get(value)) {
680-
out.push_back(*scopeIntroducer);
696+
out.push_back(scopeIntroducer);
681697
continue;
682698
}
683699

@@ -716,10 +732,9 @@ bool swift::getAllBorrowIntroducingValues(SILValue inputValue,
716732
return true;
717733
}
718734

719-
Optional<BorrowedValue>
720-
swift::getSingleBorrowIntroducingValue(SILValue inputValue) {
735+
BorrowedValue swift::getSingleBorrowIntroducingValue(SILValue inputValue) {
721736
if (inputValue.getOwnershipKind() != OwnershipKind::Guaranteed)
722-
return None;
737+
return {};
723738

724739
SILValue currentValue = inputValue;
725740
while (true) {
@@ -738,7 +753,7 @@ swift::getSingleBorrowIntroducingValue(SILValue inputValue) {
738753
// this.
739754
auto begin = instOps.begin();
740755
if (std::next(begin) != instOps.end()) {
741-
return None;
756+
return {};
742757
}
743758
// Otherwise, set currentOp to the single operand and continue.
744759
currentValue = *begin;
@@ -758,7 +773,7 @@ swift::getSingleBorrowIntroducingValue(SILValue inputValue) {
758773

759774
// Otherwise, this is an introducer we do not understand. Bail and return
760775
// None.
761-
return None;
776+
return {};
762777
}
763778

764779
llvm_unreachable("Should never hit this");
@@ -777,7 +792,7 @@ bool swift::getAllOwnedValueIntroducers(
777792

778793
// First check if v is an introducer. If so, stash it and continue.
779794
if (auto introducer = OwnedValueIntroducer::get(value)) {
780-
out.push_back(*introducer);
795+
out.push_back(introducer);
781796
continue;
782797
}
783798

@@ -816,10 +831,9 @@ bool swift::getAllOwnedValueIntroducers(
816831
return true;
817832
}
818833

819-
Optional<OwnedValueIntroducer>
820-
swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
834+
OwnedValueIntroducer swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
821835
if (inputValue.getOwnershipKind() != OwnershipKind::Owned)
822-
return None;
836+
return {};
823837

824838
SILValue currentValue = inputValue;
825839
while (true) {
@@ -838,7 +852,7 @@ swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
838852
// this.
839853
auto begin = instOps.begin();
840854
if (std::next(begin) != instOps.end()) {
841-
return None;
855+
return {};
842856
}
843857
// Otherwise, set currentOp to the single operand and continue.
844858
currentValue = *begin;
@@ -859,7 +873,7 @@ swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
859873

860874
// Otherwise, this is an introducer we do not understand. Bail and return
861875
// None.
862-
return None;
876+
return {};
863877
}
864878

865879
llvm_unreachable("Should never hit this");
@@ -869,12 +883,12 @@ swift::getSingleOwnedValueIntroducer(SILValue inputValue) {
869883
// Forwarding Operand
870884
//===----------------------------------------------------------------------===//
871885

872-
Optional<ForwardingOperand> ForwardingOperand::get(Operand *use) {
886+
ForwardingOperand ForwardingOperand::get(Operand *use) {
873887
if (use->isTypeDependent())
874-
return None;
888+
return nullptr;
875889

876890
if (!OwnershipForwardingMixin::isa(use->getUser())) {
877-
return None;
891+
return nullptr;
878892
}
879893
#ifndef NDEBUG
880894
switch (use->getOperandOwnership()) {

lib/SIL/Verifier/LinearLifetimeChecker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ void State::checkForSameBlockUseAfterFree(Operand *consumingUse,
314314
continue;
315315
}
316316
} else if (auto borrowingOperand = BorrowingOperand::get(consumingUse)) {
317-
assert(borrowingOperand->isReborrow());
317+
assert(borrowingOperand.isReborrow());
318318
continue;
319319
}
320320

lib/SIL/Verifier/ReborrowVerifier.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void ReborrowVerifier::verifyReborrows(BorrowingOperand initialScopedOperand,
5454
auto *borrowLifetimeEndUser = borrowLifetimeEndOp->getUser();
5555

5656
auto borrowingOperand = BorrowingOperand::get(borrowLifetimeEndOp);
57-
if (!borrowingOperand || !borrowingOperand->isReborrow())
57+
if (!borrowingOperand || !borrowingOperand.isReborrow())
5858
continue;
5959

6060
if (isVisitedOp(borrowLifetimeEndOp, baseVal))
@@ -85,8 +85,8 @@ void ReborrowVerifier::verifyReborrows(BorrowingOperand initialScopedOperand,
8585
// Find the scope ending uses of the guaranteed phi arg and add it to the
8686
// worklist.
8787
auto scopedValue = BorrowedValue::get(phiArg);
88-
assert(scopedValue.hasValue());
89-
scopedValue->visitLocalScopeEndingUses([&](Operand *op) {
88+
assert(scopedValue);
89+
scopedValue.visitLocalScopeEndingUses([&](Operand *op) {
9090
addVisitedOp(op, newBaseVal);
9191
worklist.emplace_back(op, newBaseVal);
9292
});

lib/SIL/Verifier/SILOwnershipVerifier.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ bool SILValueOwnershipChecker::gatherNonGuaranteedUsers(
266266
<< "Initial: " << *initialScopedOperand << "\n";
267267
});
268268
};
269-
initialScopedOperand->getImplicitUses(nonLifetimeEndingUsers, &error);
270-
reborrowVerifier.verifyReborrows(initialScopedOperand.getValue(), value);
269+
initialScopedOperand.getImplicitUses(nonLifetimeEndingUsers, &error);
270+
reborrowVerifier.verifyReborrows(initialScopedOperand, value);
271271
}
272272

273273
return foundError;
@@ -354,7 +354,7 @@ bool SILValueOwnershipChecker::gatherUsers(
354354
// BorrowScopeOperand and if so, add its end scope instructions as
355355
// implicit regular users of our value.
356356
if (auto scopedOperand = BorrowingOperand::get(op)) {
357-
assert(!scopedOperand->isReborrow());
357+
assert(!scopedOperand.isReborrow());
358358

359359
std::function<void(Operand *)> onError = [&](Operand *op) {
360360
errorBuilder.handleMalformedSIL([&] {
@@ -364,8 +364,8 @@ bool SILValueOwnershipChecker::gatherUsers(
364364
});
365365
};
366366

367-
scopedOperand->getImplicitUses(nonLifetimeEndingUsers, &onError);
368-
reborrowVerifier.verifyReborrows(scopedOperand.getValue(), value);
367+
scopedOperand.getImplicitUses(nonLifetimeEndingUsers, &onError);
368+
reborrowVerifier.verifyReborrows(scopedOperand, value);
369369
}
370370

371371
// Next see if our use is an interior pointer operand. If we have an
@@ -377,11 +377,11 @@ bool SILValueOwnershipChecker::gatherUsers(
377377
llvm::errs() << "Could not recognize address user of interior "
378378
"pointer operand!\n"
379379
<< "Interior Pointer Operand: "
380-
<< *interiorPointerOperand->operand->getUser()
380+
<< *interiorPointerOperand.operand->getUser()
381381
<< "Address User: " << *op->getUser();
382382
});
383383
};
384-
foundError |= interiorPointerOperand->getImplicitUses(
384+
foundError |= interiorPointerOperand.getImplicitUses(
385385
nonLifetimeEndingUsers, &onError);
386386
}
387387

lib/SILOptimizer/SemanticARC/CopyValueOpts.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ static Operand *lookThroughSingleForwardingUse(Operand *use) {
334334
auto forwardingOperand = ForwardingOperand::get(use);
335335
if (!forwardingOperand)
336336
return nullptr;
337-
auto forwardedValue = (*forwardingOperand).getSingleForwardedValue();
337+
auto forwardedValue = forwardingOperand.getSingleForwardedValue();
338338
if (!forwardedValue)
339339
return nullptr;
340340
auto *singleConsumingUse = forwardedValue->getSingleConsumingUse();
@@ -426,7 +426,7 @@ static bool tryJoinIfDestroyConsumingUseInSameBlock(
426426
auto forwardingOperand = ForwardingOperand::get(currentForwardingUse);
427427
if (!forwardingOperand)
428428
return false;
429-
auto forwardedValue = (*forwardingOperand).getSingleForwardedValue();
429+
auto forwardedValue = forwardingOperand.getSingleForwardedValue();
430430
if (!forwardedValue)
431431
return false;
432432

@@ -478,7 +478,7 @@ static bool tryJoinIfDestroyConsumingUseInSameBlock(
478478
// singleConsumingUse (the original forwarded use) and the destroy_value. In
479479
// such a case, we must bail!
480480
if (auto operand = BorrowingOperand::get(use))
481-
if (!operand->visitLocalEndScopeUses([&](Operand *endScopeUse) {
481+
if (!operand.visitLocalEndScopeUses([&](Operand *endScopeUse) {
482482
// Return false if we did see the relevant end scope instruction
483483
// in the block. That means that we are going to exit early and
484484
// return false.

lib/SILOptimizer/SemanticARC/LoadCopyToLoadBorrowOpt.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ class StorageGuaranteesLoadVisitor
221221
// know statically that our let can not be written to in the current
222222
// function. To be conservative, assume that all other non-local scopes
223223
// write to memory.
224-
if (!value->isLocalScope()) {
225-
if (value->kind == BorrowedValueKind::SILFunctionArgument) {
224+
if (!value.isLocalScope()) {
225+
if (value.kind == BorrowedValueKind::SILFunctionArgument) {
226226
return answer(false);
227227
}
228228

@@ -233,7 +233,7 @@ class StorageGuaranteesLoadVisitor
233233

234234
// TODO: This is disabled temporarily for guaranteed phi args just for
235235
// staging purposes. Thus be conservative and assume true in these cases.
236-
if (value->kind == BorrowedValueKind::Phi) {
236+
if (value.kind == BorrowedValueKind::Phi) {
237237
return answer(true);
238238
}
239239

@@ -243,7 +243,7 @@ class StorageGuaranteesLoadVisitor
243243
// to check whether the copied value is dominated by the lifetime of the
244244
// borrow it's based on.
245245
SmallVector<Operand *, 4> endScopeInsts;
246-
value->visitLocalScopeEndingUses(
246+
value.visitLocalScopeEndingUses(
247247
[&](Operand *use) { endScopeInsts.push_back(use); });
248248

249249
SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;

lib/SILOptimizer/SemanticARC/OwnedToGuaranteedPhiOpt.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,19 @@ static bool canEliminatePhi(
6161
// to eliminate. Since we do not look through joined live ranges, we must
6262
// only have a single introducer. So look for that one and if not, bail.
6363
auto singleIntroducer = getSingleOwnedValueIntroducer(incomingValue);
64-
if (!singleIntroducer.hasValue()) {
64+
if (!singleIntroducer) {
6565
return false;
6666
}
6767

6868
// Then make sure that our owned value introducer is able to be converted to
6969
// guaranteed and that we found it to have a LiveRange that we could have
7070
// eliminated /if/ we were to get rid of this phi.
71-
if (!singleIntroducer->isConvertableToGuaranteed()) {
71+
if (!singleIntroducer.isConvertableToGuaranteed()) {
7272
return false;
7373
}
7474

7575
// Otherwise, add the introducer to our result array.
76-
ownedValueIntroducerAccumulator.push_back(*singleIntroducer);
76+
ownedValueIntroducerAccumulator.push_back(singleIntroducer);
7777
}
7878

7979
#ifndef NDEBUG

lib/SILOptimizer/SemanticARC/OwnershipLiveRange.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ using namespace swift;
1919
using namespace swift::semanticarc;
2020

2121
OwnershipLiveRange::OwnershipLiveRange(SILValue value)
22-
: introducer(*OwnedValueIntroducer::get(value)), destroyingUses(),
22+
: introducer(OwnedValueIntroducer::get(value)), destroyingUses(),
2323
ownershipForwardingUses(), unknownConsumingUses() {
24+
assert(introducer);
2425
assert(introducer.value.getOwnershipKind() == OwnershipKind::Owned);
2526

2627
SmallVector<Operand *, 32> tmpDestroyingUses;
@@ -227,7 +228,7 @@ void OwnershipLiveRange::convertOwnedGeneralForwardingUsesToGuaranteed() && {
227228
while (!ownershipForwardingUses.empty()) {
228229
auto *use = ownershipForwardingUses.back();
229230
ownershipForwardingUses = ownershipForwardingUses.drop_back();
230-
auto operand = *ForwardingOperand::get(use);
231+
auto operand = ForwardingOperand::get(use);
231232
operand.replaceOwnershipKind(OwnershipKind::Owned,
232233
OwnershipKind::Guaranteed);
233234
}
@@ -253,6 +254,8 @@ void OwnershipLiveRange::convertToGuaranteedAndRAUW(
253254
// TODO: If this is useful, move onto OwnedValueIntroducer itself?
254255
static SILValue convertIntroducerToGuaranteed(OwnedValueIntroducer introducer) {
255256
switch (introducer.kind) {
257+
case OwnedValueIntroducerKind::Invalid:
258+
llvm_unreachable("Using invalid case?!");
256259
case OwnedValueIntroducerKind::Phi: {
257260
auto *phiArg = cast<SILPhiArgument>(introducer.value);
258261
phiArg->setOwnershipKind(OwnershipKind::Guaranteed);

0 commit comments

Comments
 (0)