Skip to content

Commit ce2a7cf

Browse files
committed
Clearly discriminate OperandOwnership::NonUse and TrivialUse.
A NonUse operand does not use the value itself, so it ignores ownership and does not require liveness. This is for operands that represent dependence on a type but are not actually passed the value of that type (e.g. they may refer an open_existential). This could be used for other dependence-only operands in the future. A TrivialUse operand has undefined ownership semantics aside from requiring liveness. Therefore it is only legal to pass the use a value with ownership None (a trivial value). Contrast this with things like InstantaneousUse or BitwiseEscape, which just don't care about ownership (i.e. they have no ownership semantics. All of the explicitly listed operations in this category require trivially typed operands. So the meaning is obvious to anyone adding SIL operations and updating OperandOwnership.cpp, without needing to decifer the value ownership kinds.
1 parent 949b0c0 commit ce2a7cf

File tree

4 files changed

+111
-91
lines changed

4 files changed

+111
-91
lines changed

include/swift/SIL/SILValue.h

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,18 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
116116
/// statically. Thus we treat Any as representing an invalid
117117
/// value. ValueOwnershipKinds can only perform a meet operation to determine
118118
/// if two ownership kinds are compatible with a merge of Any showing the
119-
/// merge is impossible since values can not have any ownership.
119+
/// merge is impossible since values can not have any ownership. Values with
120+
/// ownership None are statically proven to be trivial values, often because
121+
/// they are trivially typed, but sometimes because of path-sensitive
122+
/// information like knowledge of an enum case. Trivial values have no
123+
/// ownership semantics.
120124
///
121125
/// * OperandConstraint: This represents a constraint on the values that can be
122-
/// used by a specific operand. Here Any is valid.
126+
/// used by a specific operand. Here Any is valid and is used for operands
127+
/// that don't care about the ownership kind (lack ownership constraints). In
128+
/// contrast, a constraint of None is the most restrictive. It requires a
129+
/// trivial value. An Unowned, Owned, or Guaranteed constraint requires either
130+
/// a value with the named ownership, or a trivial value.
123131
struct OwnershipKind {
124132
enum innerty : uint8_t {
125133
/// An ownership kind that models an ownership that is unknown statically at
@@ -159,10 +167,12 @@ struct OwnershipKind {
159167
Guaranteed,
160168

161169
/// A SILValue with None ownership kind is an independent value outside of
162-
/// the ownership system. It is used to model trivially typed values as well
170+
/// the ownership system. It is used to model values that are statically
171+
/// determined to be trivial. This includes trivially typed values as well
163172
/// as trivial cases of non-trivial enums. Naturally None can be merged with
164173
/// any ValueOwnershipKind allowing us to naturally model merge and branch
165-
/// points in the SSA graph.
174+
/// points in the SSA graph, where more information about the value is
175+
/// statically available on some control flow paths.
166176
None,
167177

168178
LastValueOwnershipKind = None,
@@ -626,9 +636,15 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
626636
/// lifetime constraints.
627637
struct OperandOwnership {
628638
enum innerty : uint8_t {
629-
/// Uses of ownership None. These uses are incompatible with values that
630-
/// have ownership but are otherwise not verified.
631-
None,
639+
/// Operands that do not use the value. They only represent a dependence
640+
/// on a dominating definition and do not require liveness.
641+
/// (type-dependent operands)
642+
NonUse,
643+
644+
/// Uses that can only handle trivial values. The operand value must have
645+
/// None ownership. These uses require liveness but are otherwise
646+
/// unverified.
647+
TrivialUse,
632648

633649
/// Use the value only for the duration of the operation, which may have
634650
/// side effects. Requires an owned or guaranteed value.
@@ -726,8 +742,9 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
726742
/// Defined inline so the switch is eliminated for constant OperandOwnership.
727743
inline OwnershipConstraint OperandOwnership::getOwnershipConstraint() {
728744
switch (value) {
729-
case OperandOwnership::None:
745+
case OperandOwnership::TrivialUse:
730746
return {OwnershipKind::None, UseLifetimeConstraint::NonLifetimeEnding};
747+
case OperandOwnership::NonUse:
731748
case OperandOwnership::InstantaneousUse:
732749
case OperandOwnership::UnownedInstantaneousUse:
733750
case OperandOwnership::ForwardingUnowned:
@@ -770,7 +787,7 @@ ValueOwnershipKind::getForwardingOperandOwnership(bool allowUnowned) const {
770787
}
771788
llvm_unreachable("invalid value ownership");
772789
case OwnershipKind::None:
773-
return OperandOwnership::None;
790+
return OperandOwnership::TrivialUse;
774791
case OwnershipKind::Guaranteed:
775792
return OperandOwnership::ForwardingBorrow;
776793
case OwnershipKind::Owned:

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 77 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -121,63 +121,63 @@ SHOULD_NEVER_VISIT_INST(GetAsyncContinuation)
121121
}
122122

123123
// Instructions that require trivial operands.
124-
OPERAND_OWNERSHIP(None, AwaitAsyncContinuation)
125-
OPERAND_OWNERSHIP(None, AbortApply)
126-
OPERAND_OWNERSHIP(None, AddressToPointer)
127-
OPERAND_OWNERSHIP(None, AllocRef) // with tail operand
128-
OPERAND_OWNERSHIP(None, AllocRefDynamic) // with tail operand
129-
OPERAND_OWNERSHIP(None, BeginAccess)
130-
OPERAND_OWNERSHIP(None, BeginUnpairedAccess)
131-
OPERAND_OWNERSHIP(None, BindMemory)
132-
OPERAND_OWNERSHIP(None, CheckedCastAddrBranch)
133-
OPERAND_OWNERSHIP(None, CondBranch)
134-
OPERAND_OWNERSHIP(None, CondFail)
135-
OPERAND_OWNERSHIP(None, CopyAddr)
136-
OPERAND_OWNERSHIP(None, DeallocStack)
137-
OPERAND_OWNERSHIP(None, DebugValueAddr)
138-
OPERAND_OWNERSHIP(None, DeinitExistentialAddr)
139-
OPERAND_OWNERSHIP(None, DestroyAddr)
140-
OPERAND_OWNERSHIP(None, EndAccess)
141-
OPERAND_OWNERSHIP(None, EndApply)
142-
OPERAND_OWNERSHIP(None, EndUnpairedAccess)
143-
OPERAND_OWNERSHIP(None, GetAsyncContinuationAddr)
144-
OPERAND_OWNERSHIP(None, IndexAddr)
145-
OPERAND_OWNERSHIP(None, IndexRawPointer)
146-
OPERAND_OWNERSHIP(None, InitBlockStorageHeader)
147-
OPERAND_OWNERSHIP(None, InitEnumDataAddr)
148-
OPERAND_OWNERSHIP(None, InitExistentialAddr)
149-
OPERAND_OWNERSHIP(None, InitExistentialMetatype)
150-
OPERAND_OWNERSHIP(None, InjectEnumAddr)
151-
OPERAND_OWNERSHIP(None, IsUnique)
152-
OPERAND_OWNERSHIP(None, Load)
153-
OPERAND_OWNERSHIP(None, LoadBorrow)
154-
OPERAND_OWNERSHIP(None, MarkFunctionEscape)
155-
OPERAND_OWNERSHIP(None, ObjCExistentialMetatypeToObject)
156-
OPERAND_OWNERSHIP(None, ObjCMetatypeToObject)
157-
OPERAND_OWNERSHIP(None, ObjCToThickMetatype)
158-
OPERAND_OWNERSHIP(None, OpenExistentialAddr)
159-
OPERAND_OWNERSHIP(None, OpenExistentialMetatype)
160-
OPERAND_OWNERSHIP(None, PointerToAddress)
161-
OPERAND_OWNERSHIP(None, PointerToThinFunction)
162-
OPERAND_OWNERSHIP(None, ProjectBlockStorage)
163-
OPERAND_OWNERSHIP(None, ProjectValueBuffer)
164-
OPERAND_OWNERSHIP(None, RawPointerToRef)
165-
OPERAND_OWNERSHIP(None, SelectEnumAddr)
166-
OPERAND_OWNERSHIP(None, SelectValue)
167-
OPERAND_OWNERSHIP(None, StructElementAddr)
168-
OPERAND_OWNERSHIP(None, SwitchEnumAddr)
169-
OPERAND_OWNERSHIP(None, SwitchValue)
170-
OPERAND_OWNERSHIP(None, TailAddr)
171-
OPERAND_OWNERSHIP(None, ThickToObjCMetatype)
172-
OPERAND_OWNERSHIP(None, ThinFunctionToPointer)
173-
OPERAND_OWNERSHIP(None, ThinToThickFunction)
174-
OPERAND_OWNERSHIP(None, TupleElementAddr)
175-
OPERAND_OWNERSHIP(None, UncheckedAddrCast)
176-
OPERAND_OWNERSHIP(None, UncheckedRefCastAddr)
177-
OPERAND_OWNERSHIP(None, UncheckedTakeEnumDataAddr)
178-
OPERAND_OWNERSHIP(None, UnconditionalCheckedCastAddr)
179-
OPERAND_OWNERSHIP(None, AllocValueBuffer)
180-
OPERAND_OWNERSHIP(None, DeallocValueBuffer)
124+
OPERAND_OWNERSHIP(TrivialUse, AwaitAsyncContinuation)
125+
OPERAND_OWNERSHIP(TrivialUse, AbortApply)
126+
OPERAND_OWNERSHIP(TrivialUse, AddressToPointer)
127+
OPERAND_OWNERSHIP(TrivialUse, AllocRef) // with tail operand
128+
OPERAND_OWNERSHIP(TrivialUse, AllocRefDynamic) // with tail operand
129+
OPERAND_OWNERSHIP(TrivialUse, BeginAccess)
130+
OPERAND_OWNERSHIP(TrivialUse, BeginUnpairedAccess)
131+
OPERAND_OWNERSHIP(TrivialUse, BindMemory)
132+
OPERAND_OWNERSHIP(TrivialUse, CheckedCastAddrBranch)
133+
OPERAND_OWNERSHIP(TrivialUse, CondBranch)
134+
OPERAND_OWNERSHIP(TrivialUse, CondFail)
135+
OPERAND_OWNERSHIP(TrivialUse, CopyAddr)
136+
OPERAND_OWNERSHIP(TrivialUse, DeallocStack)
137+
OPERAND_OWNERSHIP(TrivialUse, DebugValueAddr)
138+
OPERAND_OWNERSHIP(TrivialUse, DeinitExistentialAddr)
139+
OPERAND_OWNERSHIP(TrivialUse, DestroyAddr)
140+
OPERAND_OWNERSHIP(TrivialUse, EndAccess)
141+
OPERAND_OWNERSHIP(TrivialUse, EndApply)
142+
OPERAND_OWNERSHIP(TrivialUse, EndUnpairedAccess)
143+
OPERAND_OWNERSHIP(TrivialUse, GetAsyncContinuationAddr)
144+
OPERAND_OWNERSHIP(TrivialUse, IndexAddr)
145+
OPERAND_OWNERSHIP(TrivialUse, IndexRawPointer)
146+
OPERAND_OWNERSHIP(TrivialUse, InitBlockStorageHeader)
147+
OPERAND_OWNERSHIP(TrivialUse, InitEnumDataAddr)
148+
OPERAND_OWNERSHIP(TrivialUse, InitExistentialAddr)
149+
OPERAND_OWNERSHIP(TrivialUse, InitExistentialMetatype)
150+
OPERAND_OWNERSHIP(TrivialUse, InjectEnumAddr)
151+
OPERAND_OWNERSHIP(TrivialUse, IsUnique)
152+
OPERAND_OWNERSHIP(TrivialUse, Load)
153+
OPERAND_OWNERSHIP(TrivialUse, LoadBorrow)
154+
OPERAND_OWNERSHIP(TrivialUse, MarkFunctionEscape)
155+
OPERAND_OWNERSHIP(TrivialUse, ObjCExistentialMetatypeToObject)
156+
OPERAND_OWNERSHIP(TrivialUse, ObjCMetatypeToObject)
157+
OPERAND_OWNERSHIP(TrivialUse, ObjCToThickMetatype)
158+
OPERAND_OWNERSHIP(TrivialUse, OpenExistentialAddr)
159+
OPERAND_OWNERSHIP(TrivialUse, OpenExistentialMetatype)
160+
OPERAND_OWNERSHIP(TrivialUse, PointerToAddress)
161+
OPERAND_OWNERSHIP(TrivialUse, PointerToThinFunction)
162+
OPERAND_OWNERSHIP(TrivialUse, ProjectBlockStorage)
163+
OPERAND_OWNERSHIP(TrivialUse, ProjectValueBuffer)
164+
OPERAND_OWNERSHIP(TrivialUse, RawPointerToRef)
165+
OPERAND_OWNERSHIP(TrivialUse, SelectEnumAddr)
166+
OPERAND_OWNERSHIP(TrivialUse, SelectValue)
167+
OPERAND_OWNERSHIP(TrivialUse, StructElementAddr)
168+
OPERAND_OWNERSHIP(TrivialUse, SwitchEnumAddr)
169+
OPERAND_OWNERSHIP(TrivialUse, SwitchValue)
170+
OPERAND_OWNERSHIP(TrivialUse, TailAddr)
171+
OPERAND_OWNERSHIP(TrivialUse, ThickToObjCMetatype)
172+
OPERAND_OWNERSHIP(TrivialUse, ThinFunctionToPointer)
173+
OPERAND_OWNERSHIP(TrivialUse, ThinToThickFunction)
174+
OPERAND_OWNERSHIP(TrivialUse, TupleElementAddr)
175+
OPERAND_OWNERSHIP(TrivialUse, UncheckedAddrCast)
176+
OPERAND_OWNERSHIP(TrivialUse, UncheckedRefCastAddr)
177+
OPERAND_OWNERSHIP(TrivialUse, UncheckedTakeEnumDataAddr)
178+
OPERAND_OWNERSHIP(TrivialUse, UnconditionalCheckedCastAddr)
179+
OPERAND_OWNERSHIP(TrivialUse, AllocValueBuffer)
180+
OPERAND_OWNERSHIP(TrivialUse, DeallocValueBuffer)
181181

182182
// Use an owned or guaranteed value only for the duration of the operation.
183183
OPERAND_OWNERSHIP(InstantaneousUse, ExistentialMetatype)
@@ -263,13 +263,14 @@ OPERAND_OWNERSHIP(ForwardingBorrow, OpenExistentialBoxValue)
263263
OPERAND_OWNERSHIP(EndBorrow, EndBorrow)
264264

265265
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
266-
OPERAND_OWNERSHIP(None, Load##Name)
266+
OPERAND_OWNERSHIP(TrivialUse, Load##Name)
267267
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
268268
OPERAND_OWNERSHIP(DestroyingConsume, Name##Release)
269269
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
270270
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, "...") \
271271
ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, "...")
272-
#define UNCHECKED_REF_STORAGE(Name, ...) OPERAND_OWNERSHIP(None, Name##ToRef)
272+
#define UNCHECKED_REF_STORAGE(Name, ...) \
273+
OPERAND_OWNERSHIP(TrivialUse, Name##ToRef)
273274
#include "swift/AST/ReferenceStorage.def"
274275

275276
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
@@ -345,7 +346,7 @@ OperandOwnershipClassifier::visitBeginBorrowInst(BeginBorrowInst *borrow) {
345346
case OwnershipKind::Any:
346347
llvm_unreachable("invalid value ownership");
347348
case OwnershipKind::None:
348-
return OperandOwnership::None;
349+
return OperandOwnership::TrivialUse;
349350
case OwnershipKind::Unowned:
350351
// FIXME: disallow borrowing an Unowned value. Temporarily model it as an
351352
// instantaneous use until SILGenFunction::emitClassMemberDestruction is
@@ -365,7 +366,7 @@ visitDeallocPartialRefInst(DeallocPartialRefInst *i) {
365366
if (getValue() == i->getInstance()) {
366367
return OperandOwnership::DestroyingConsume;
367368
}
368-
return OperandOwnership::None;
369+
return OperandOwnership::TrivialUse;
369370
}
370371

371372
OperandOwnership
@@ -395,7 +396,7 @@ OperandOwnershipClassifier::visitStoreBorrowInst(StoreBorrowInst *i) {
395396
if (getValue() == i->getSrc()) {
396397
return OperandOwnership::ForwardingBorrow;
397398
}
398-
return OperandOwnership::None;
399+
return OperandOwnership::TrivialUse;
399400
}
400401

401402
static OperandOwnership getFunctionArgOwnership(SILArgumentConvention argConv) {
@@ -428,7 +429,7 @@ OperandOwnershipClassifier::visitFullApply(FullApplySite apply) {
428429
// Before considering conventions, filter all (trivial) indirect
429430
// arguments. This also rules out result arguments.
430431
if (getValue()->getType().isAddress()) {
431-
return OperandOwnership::None;
432+
return OperandOwnership::TrivialUse;
432433
}
433434
SILArgumentConvention argConv = apply.isCalleeOperand(op)
434435
? SILArgumentConvention(apply.getSubstCalleeType()->getCalleeConvention())
@@ -472,7 +473,7 @@ OperandOwnershipClassifier::visitPartialApplyInst(PartialApplyInst *i) {
472473
OperandOwnership OperandOwnershipClassifier::visitYieldInst(YieldInst *i) {
473474
// Before considering conventions, filter all indirect arguments.
474475
if (getValue()->getType().isAddress()) {
475-
return OperandOwnership::None;
476+
return OperandOwnership::TrivialUse;
476477
}
477478
auto fnType = i->getFunction()->getLoweredFunctionType();
478479
SILArgumentConvention argConv(
@@ -486,7 +487,7 @@ OperandOwnership OperandOwnershipClassifier::visitReturnInst(ReturnInst *i) {
486487
case OwnershipKind::Guaranteed:
487488
llvm_unreachable("invalid value ownership");
488489
case OwnershipKind::None:
489-
return OperandOwnership::None;
490+
return OperandOwnership::TrivialUse;
490491
case OwnershipKind::Unowned:
491492
return OperandOwnership::UnownedInstantaneousUse;
492493
case OwnershipKind::Owned:
@@ -496,7 +497,7 @@ OperandOwnership OperandOwnershipClassifier::visitReturnInst(ReturnInst *i) {
496497

497498
OperandOwnership OperandOwnershipClassifier::visitAssignInst(AssignInst *i) {
498499
if (getValue() != i->getSrc()) {
499-
return OperandOwnership::None;
500+
return OperandOwnership::TrivialUse;
500501
}
501502
return OperandOwnership::DestroyingConsume;
502503
}
@@ -507,14 +508,14 @@ OperandOwnershipClassifier::visitAssignByWrapperInst(AssignByWrapperInst *i) {
507508
return OperandOwnership::DestroyingConsume;
508509
}
509510
if (getValue() == i->getDest()) {
510-
return OperandOwnership::None;
511+
return OperandOwnership::TrivialUse;
511512
}
512513
return OperandOwnership::InstantaneousUse; // initializer/setter closure
513514
}
514515

515516
OperandOwnership OperandOwnershipClassifier::visitStoreInst(StoreInst *i) {
516517
if (getValue() != i->getSrc()) {
517-
return OperandOwnership::None;
518+
return OperandOwnership::TrivialUse;
518519
}
519520
return OperandOwnership::DestroyingConsume;
520521
}
@@ -560,7 +561,7 @@ struct OperandOwnershipBuiltinClassifier
560561
OperandOwnership visitLLVMIntrinsic(BuiltinInst *bi, llvm::Intrinsic::ID id) {
561562
// LLVM intrinsics do not traffic in ownership, so if we have a result, it
562563
// must be trivial.
563-
return OperandOwnership::None;
564+
return OperandOwnership::TrivialUse;
564565
}
565566

566567
// BUILTIN_TYPE_CHECKER_OPERATION does not live past the type checker.
@@ -741,10 +742,10 @@ BUILTIN_OPERAND_OWNERSHIP(ForwardingBorrow, AutoDiffAllocateSubcontext)
741742
BUILTIN_OPERAND_OWNERSHIP(ForwardingBorrow, AutoDiffProjectTopLevelSubcontext)
742743

743744
// FIXME: ConvertTaskToJob is documented as taking NativePointer. It's operand's
744-
// ownership should be 'None'.
745+
// ownership should be 'TrivialUse'.
745746
BUILTIN_OPERAND_OWNERSHIP(ForwardingConsume, ConvertTaskToJob)
746747

747-
BUILTIN_OPERAND_OWNERSHIP(None, AutoDiffCreateLinearMapContext)
748+
BUILTIN_OPERAND_OWNERSHIP(TrivialUse, AutoDiffCreateLinearMapContext)
748749

749750
#undef BUILTIN_OPERAND_OWNERSHIP
750751

@@ -776,14 +777,12 @@ OperandOwnership OperandOwnershipClassifier::visitBuiltinInst(BuiltinInst *bi) {
776777
//===----------------------------------------------------------------------===//
777778

778779
OperandOwnership Operand::getOperandOwnership() const {
779-
// We consider type dependent uses to be instantaneous uses.
780-
//
781-
// NOTE: We could instead try to exclude type dependent uses from our system,
782-
// but that adds a bunch of Optionals and unnecessary types. This doesn't hurt
783-
// anything and allows us to eliminate Optionals and thus confusion in between
784-
// Optional::None and OwnershipKind::None.
780+
// NOTE: NonUse distinguishes itself from InstantaneousUse because it does not
781+
// require liveness. Discrimating such uses in the enum avoids the need to
782+
// return an Optional<OperandOwnership>::None, which could be confused with
783+
// OwnershipKind::None.
785784
if (isTypeDependent())
786-
return OperandOwnership::InstantaneousUse;
785+
return OperandOwnership::NonUse;
787786

788787
// If we do not have ownership enabled, just return any. This ensures that we
789788
// do not have any consuming uses and everything from an ownership perspective

lib/SIL/IR/SILValue.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,13 @@ SILFunction *Operand::getParentFunction() const {
322322
/// Return true if this use can accept Unowned values.
323323
static bool canAcceptUnownedValue(OperandOwnership operandOwnership) {
324324
switch (operandOwnership) {
325+
case OperandOwnership::NonUse:
325326
case OperandOwnership::UnownedInstantaneousUse:
326327
case OperandOwnership::ForwardingUnowned:
327328
case OperandOwnership::PointerEscape:
328329
case OperandOwnership::BitwiseEscape:
329330
return true;
330-
case OperandOwnership::None:
331+
case OperandOwnership::TrivialUse:
331332
case OperandOwnership::InstantaneousUse:
332333
case OperandOwnership::Borrow:
333334
case OperandOwnership::DestroyingConsume:
@@ -391,8 +392,10 @@ llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os,
391392

392393
StringRef OperandOwnership::asString() const {
393394
switch (value) {
394-
case OperandOwnership::None:
395-
return "none";
395+
case OperandOwnership::NonUse:
396+
return "non-use";
397+
case OperandOwnership::TrivialUse:
398+
return "trivial-use";
396399
case OperandOwnership::InstantaneousUse:
397400
return "instantaneous";
398401
case OperandOwnership::UnownedInstantaneousUse:

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,11 +878,12 @@ Optional<ForwardingOperand> ForwardingOperand::get(Operand *use) {
878878
}
879879
#ifndef NDEBUG
880880
switch (use->getOperandOwnership()) {
881-
case OperandOwnership::None:
882881
case OperandOwnership::ForwardingUnowned:
883882
case OperandOwnership::ForwardingConsume:
884883
case OperandOwnership::ForwardingBorrow:
885884
break;
885+
case OperandOwnership::NonUse:
886+
case OperandOwnership::TrivialUse:
886887
case OperandOwnership::InstantaneousUse:
887888
case OperandOwnership::UnownedInstantaneousUse:
888889
case OperandOwnership::PointerEscape:

0 commit comments

Comments
 (0)