Skip to content

Commit 638d5e7

Browse files
authored
Merge pull request swiftlang#34809 from gottesmm/pr-584924e29ff9f53ce445cbfbe808237ac89ac4a9
[ownership] Add a subclass for all OwnershipForwarding instructions and fix the classof to the various ownership abstract classes so isa/dyn_cast work.
2 parents b50dfef + c35ff33 commit 638d5e7

File tree

9 files changed

+229
-114
lines changed

9 files changed

+229
-114
lines changed

include/swift/SIL/OwnershipUtils.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ bool isValueAddressOrTrivial(SILValue v);
3535
/// These operations forward both owned and guaranteed ownership.
3636
bool isOwnershipForwardingValueKind(SILNodeKind kind);
3737

38-
/// Is this an instruction that can forward both owned and guaranteed ownership
38+
/// Is this an operand that can forward both owned and guaranteed ownership
3939
/// kinds.
40-
bool isOwnershipForwardingInst(SILInstruction *i);
40+
bool isOwnershipForwardingUse(Operand *op);
4141

42-
/// Is this an instruction that can forward guaranteed ownership.
43-
bool isGuaranteedForwardingInst(SILInstruction *i);
42+
/// Is this an operand that forwards guaranteed ownership from its value to a
43+
/// result of the using instruction.
44+
bool isGuaranteedForwardingUse(Operand *op);
4445

4546
/// These operations forward guaranteed ownership, but don't necessarily forward
4647
/// owned values.
@@ -54,12 +55,12 @@ bool isGuaranteedForwardingValue(SILValue value);
5455
/// forward guaranteed ownership.
5556
bool isOwnedForwardingValueKind(SILNodeKind kind);
5657

57-
/// Does this SILInstruction 'forward' owned ownership, but may not be able to
58-
/// forward guaranteed ownership.
59-
bool isOwnedForwardingInstruction(SILInstruction *inst);
60-
61-
/// Does this value 'forward' owned ownership, but may not be able to forward
58+
/// Does this operand 'forward' owned ownership, but may not be able to forward
6259
/// guaranteed ownership.
60+
bool isOwnedForwardingUse(Operand *use);
61+
62+
/// Is this value the result of an instruction that 'forward's owned ownership,
63+
/// but may not be able to forward guaranteed ownership.
6364
///
6465
/// This will be either a multiple value instruction resuilt, a single value
6566
/// instruction that forwards or an argument that forwards the ownership from a
@@ -78,6 +79,10 @@ class ForwardingOperand {
7879
void setOwnershipKind(ValueOwnershipKind newKind) const;
7980
void replaceOwnershipKind(ValueOwnershipKind oldKind,
8081
ValueOwnershipKind newKind) const;
82+
83+
OwnershipForwardingInst *getUser() const {
84+
return cast<OwnershipForwardingInst>(use->getUser());
85+
}
8186
};
8287

8388
/// Returns true if the instruction is a 'reborrow'.

include/swift/SIL/SILInstruction.h

Lines changed: 181 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -856,38 +856,95 @@ inline SingleValueInstruction *SILNode::castToSingleValueInstruction() {
856856
}
857857
}
858858

859-
#define DEFINE_ABSTRACT_SINGLE_VALUE_INST_BOILERPLATE(ID) \
860-
static bool classof(const SILNode *node) { \
861-
return node->getKind() >= SILNodeKind::First_##ID && \
862-
node->getKind() <= SILNodeKind::Last_##ID; \
863-
} \
864-
static bool classof(const SingleValueInstruction *inst) { \
865-
return inst->getKind() >= SILInstructionKind::First_##ID && \
866-
inst->getKind() <= SILInstructionKind::Last_##ID; \
859+
#define DEFINE_ABSTRACT_SINGLE_VALUE_INST_BOILERPLATE(ID) \
860+
static bool classof(const SILNode *node) { \
861+
return node->getKind() >= SILNodeKind::First_##ID && \
862+
node->getKind() <= SILNodeKind::Last_##ID; \
863+
} \
864+
static bool classof(const SingleValueInstruction *inst) { \
865+
return inst->getKind() >= SILInstructionKind::First_##ID && \
866+
inst->getKind() <= SILInstructionKind::Last_##ID; \
867+
}
868+
869+
/// Abstract base class used for isa checks on instructions to determine if they
870+
/// forward ownership and to verify that the set of ownership instructions and
871+
/// the ownership utilities stay in sync via assertions.
872+
///
873+
/// NOTE: We assume that the constructor for the instruction subclass that
874+
/// initializes the kind field on our object is run before our constructor runs.
875+
class OwnershipForwardingInst {
876+
ValueOwnershipKind ownershipKind;
877+
878+
protected:
879+
OwnershipForwardingInst(SILInstructionKind kind,
880+
ValueOwnershipKind ownershipKind)
881+
: ownershipKind(ownershipKind) {
882+
assert(classof(kind) && "Invalid subclass?!");
883+
}
884+
885+
public:
886+
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
887+
888+
void setOwnershipKind(ValueOwnershipKind newKind) { ownershipKind = newKind; }
889+
890+
static bool classof(const SILNode *node) {
891+
if (auto *i = dyn_cast<SILInstruction>(node))
892+
return classof(i);
893+
return false;
867894
}
868895

896+
// Defined inline below due to forward declaration issues.
897+
static bool classof(const SILInstruction *inst);
898+
899+
/// Define inline below due to forward declaration issues.
900+
static bool classof(SILInstructionKind kind);
901+
};
902+
869903
/// A single value inst that forwards a static ownership from one (or all) of
870904
/// its operands.
871905
///
872906
/// The ownership kind is set on construction and afterwards must be changed
873907
/// explicitly using setOwnershipKind().
874-
class OwnershipForwardingSingleValueInst : public SingleValueInstruction {
875-
ValueOwnershipKind ownershipKind;
876-
908+
class OwnershipForwardingSingleValueInst : public SingleValueInstruction,
909+
public OwnershipForwardingInst {
877910
protected:
878911
OwnershipForwardingSingleValueInst(SILInstructionKind kind,
879912
SILDebugLocation debugLoc, SILType ty,
880913
ValueOwnershipKind ownershipKind)
881914
: SingleValueInstruction(kind, debugLoc, ty),
882-
ownershipKind(ownershipKind) {
883-
assert(ownershipKind);
915+
OwnershipForwardingInst(kind, ownershipKind) {
916+
assert(classof(kind) && "classof missing new subclass?!");
884917
}
885918

886919
public:
887-
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
888-
void setOwnershipKind(ValueOwnershipKind newOwnershipKind) {
889-
ownershipKind = newOwnershipKind;
890-
assert(ownershipKind);
920+
static bool classof(const SILNode *node) {
921+
if (auto *i = dyn_cast<SILInstruction>(node))
922+
return classof(i);
923+
return false;
924+
}
925+
926+
static bool classof(SILInstructionKind kind) {
927+
switch (kind) {
928+
case SILInstructionKind::MarkUninitializedInst:
929+
case SILInstructionKind::StructInst:
930+
case SILInstructionKind::ObjectInst:
931+
case SILInstructionKind::TupleInst:
932+
case SILInstructionKind::EnumInst:
933+
case SILInstructionKind::UncheckedEnumDataInst:
934+
case SILInstructionKind::SelectValueInst:
935+
case SILInstructionKind::OpenExistentialRefInst:
936+
case SILInstructionKind::InitExistentialRefInst:
937+
case SILInstructionKind::MarkDependenceInst:
938+
case SILInstructionKind::LinearFunctionInst:
939+
case SILInstructionKind::DifferentiableFunctionInst:
940+
return true;
941+
default:
942+
return false;
943+
}
944+
}
945+
946+
static bool classof(const SILInstruction *inst) {
947+
return classof(inst->getKind());
891948
}
892949
};
893950

@@ -4430,19 +4487,42 @@ class ConversionInst : public SingleValueInstruction {
44304487

44314488
/// A conversion inst that produces a static OwnershipKind set upon the
44324489
/// instruction's construction.
4433-
class OwnershipForwardingConversionInst : public ConversionInst {
4434-
ValueOwnershipKind ownershipKind;
4435-
4490+
class OwnershipForwardingConversionInst : public ConversionInst,
4491+
public OwnershipForwardingInst {
44364492
protected:
44374493
OwnershipForwardingConversionInst(SILInstructionKind kind,
44384494
SILDebugLocation debugLoc, SILType ty,
44394495
ValueOwnershipKind ownershipKind)
4440-
: ConversionInst(kind, debugLoc, ty), ownershipKind(ownershipKind) {}
4496+
: ConversionInst(kind, debugLoc, ty),
4497+
OwnershipForwardingInst(kind, ownershipKind) {
4498+
assert(classof(kind) && "classof missing subclass?!");
4499+
}
44414500

44424501
public:
4443-
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
4444-
void setOwnershipKind(ValueOwnershipKind newOwnershipKind) {
4445-
ownershipKind = newOwnershipKind;
4502+
static bool classof(const SILNode *node) {
4503+
if (auto *i = dyn_cast<SILInstruction>(node))
4504+
return classof(i);
4505+
return false;
4506+
}
4507+
4508+
static bool classof(const SILInstruction *inst) {
4509+
return classof(inst->getKind());
4510+
}
4511+
4512+
static bool classof(SILInstructionKind kind) {
4513+
switch (kind) {
4514+
case SILInstructionKind::ConvertFunctionInst:
4515+
case SILInstructionKind::UpcastInst:
4516+
case SILInstructionKind::UncheckedRefCastInst:
4517+
case SILInstructionKind::UncheckedValueCastInst:
4518+
case SILInstructionKind::RefToBridgeObjectInst:
4519+
case SILInstructionKind::BridgeObjectToRefInst:
4520+
case SILInstructionKind::ThinToThickFunctionInst:
4521+
case SILInstructionKind::UnconditionalCheckedCastInst:
4522+
return true;
4523+
default:
4524+
return false;
4525+
}
44464526
}
44474527
};
44484528

@@ -5610,22 +5690,35 @@ class SelectEnumInstBase
56105690
};
56115691

56125692
/// A select enum inst that produces a static OwnershipKind.
5613-
class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase {
5614-
ValueOwnershipKind ownershipKind;
5615-
5693+
class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase,
5694+
public OwnershipForwardingInst {
56165695
protected:
56175696
OwnershipForwardingSelectEnumInstBase(
56185697
SILInstructionKind kind, SILDebugLocation debugLoc, SILType type,
56195698
bool defaultValue, Optional<ArrayRef<ProfileCounter>> caseCounts,
56205699
ProfileCounter defaultCount, ValueOwnershipKind ownershipKind)
56215700
: SelectEnumInstBase(kind, debugLoc, type, defaultValue, caseCounts,
56225701
defaultCount),
5623-
ownershipKind(ownershipKind) {}
5702+
OwnershipForwardingInst(kind, ownershipKind) {
5703+
assert(classof(kind) && "classof missing subclass");
5704+
}
56245705

56255706
public:
5626-
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
5627-
void setOwnershipKind(ValueOwnershipKind newOwnershipKind) {
5628-
ownershipKind = newOwnershipKind;
5707+
static bool classof(const SILNode *node) {
5708+
if (auto *i = dyn_cast<SILInstruction>(node))
5709+
return classof(i);
5710+
return false;
5711+
}
5712+
5713+
static bool classof(const SILInstruction *i) { return classof(i->getKind()); }
5714+
5715+
static bool classof(SILInstructionKind kind) {
5716+
switch (kind) {
5717+
case SILInstructionKind::SelectEnumInst:
5718+
return true;
5719+
default:
5720+
return false;
5721+
}
56295722
}
56305723
};
56315724

@@ -7327,18 +7420,31 @@ class TermInst : public NonValueInstruction {
73277420
}
73287421
};
73297422

7330-
class OwnershipForwardingTermInst : public TermInst {
7331-
ValueOwnershipKind ownershipKind;
7332-
7423+
class OwnershipForwardingTermInst : public TermInst,
7424+
public OwnershipForwardingInst {
73337425
protected:
73347426
OwnershipForwardingTermInst(SILInstructionKind kind,
73357427
SILDebugLocation debugLoc,
73367428
ValueOwnershipKind ownershipKind)
7337-
: TermInst(kind, debugLoc), ownershipKind(ownershipKind) {}
7429+
: TermInst(kind, debugLoc), OwnershipForwardingInst(kind, ownershipKind) {
7430+
assert(classof(kind));
7431+
}
73387432

73397433
public:
7340-
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
7341-
void setOwnershipKind(ValueOwnershipKind newKind) { ownershipKind = newKind; }
7434+
static bool classof(const SILNode *node) {
7435+
if (auto *i = dyn_cast<SILInstruction>(node))
7436+
return classof(i);
7437+
return false;
7438+
}
7439+
7440+
static bool classof(const SILInstruction *inst) {
7441+
return classof(inst->getKind());
7442+
}
7443+
7444+
static bool classof(SILInstructionKind kind) {
7445+
return kind == SILInstructionKind::SwitchEnumInst ||
7446+
kind == SILInstructionKind::CheckedCastBranchInst;
7447+
}
73427448
};
73437449

73447450
/// UnreachableInst - Position in the code which would be undefined to reach.
@@ -8771,19 +8877,33 @@ SILFunction *ApplyInstBase<Impl, Base, false>::getCalleeFunction() const {
87718877
}
87728878

87738879
class OwnershipForwardingMultipleValueInstruction
8774-
: public MultipleValueInstruction {
8775-
ValueOwnershipKind ownershipKind;
8776-
8880+
: public MultipleValueInstruction,
8881+
public OwnershipForwardingInst {
87778882
public:
87788883
OwnershipForwardingMultipleValueInstruction(SILInstructionKind kind,
87798884
SILDebugLocation loc,
87808885
ValueOwnershipKind ownershipKind)
8781-
: MultipleValueInstruction(kind, loc), ownershipKind(ownershipKind) {}
8886+
: MultipleValueInstruction(kind, loc),
8887+
OwnershipForwardingInst(kind, ownershipKind) {
8888+
assert(classof(kind) && "Missing subclass from classof?!");
8889+
}
87828890

8783-
/// Returns the preferred ownership kind of this multiple value instruction.
8784-
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
8785-
void setOwnershipKind(ValueOwnershipKind newOwnershipKind) {
8786-
ownershipKind = newOwnershipKind;
8891+
static bool classof(const SILNode *n) {
8892+
if (auto *i = dyn_cast<SILInstruction>(n))
8893+
return classof(i);
8894+
return false;
8895+
}
8896+
8897+
static bool classof(const SILInstruction *i) { return classof(i->getKind()); }
8898+
8899+
static bool classof(SILInstructionKind kind) {
8900+
switch (kind) {
8901+
case SILInstructionKind::DestructureTupleInst:
8902+
case SILInstructionKind::DestructureStructInst:
8903+
return true;
8904+
default:
8905+
return false;
8906+
}
87878907
}
87888908
};
87898909

@@ -8953,6 +9073,22 @@ inline bool Operand::isTypeDependent() const {
89539073
return getUser()->isTypeDependentOperand(*this);
89549074
}
89559075

9076+
inline bool OwnershipForwardingInst::classof(const SILInstruction *inst) {
9077+
return OwnershipForwardingSingleValueInst::classof(inst) ||
9078+
OwnershipForwardingTermInst::classof(inst) ||
9079+
OwnershipForwardingConversionInst::classof(inst) ||
9080+
OwnershipForwardingSelectEnumInstBase::classof(inst) ||
9081+
OwnershipForwardingMultipleValueInstruction::classof(inst);
9082+
}
9083+
9084+
inline bool OwnershipForwardingInst::classof(SILInstructionKind kind) {
9085+
return OwnershipForwardingSingleValueInst::classof(kind) ||
9086+
OwnershipForwardingTermInst::classof(kind) ||
9087+
OwnershipForwardingConversionInst::classof(kind) ||
9088+
OwnershipForwardingSelectEnumInstBase::classof(kind) ||
9089+
OwnershipForwardingMultipleValueInstruction::classof(kind);
9090+
}
9091+
89569092
} // end swift namespace
89579093

89589094
//===----------------------------------------------------------------------===//

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ FORWARD_ANY_OWNERSHIP_INST(DestructureTuple)
319319
OwnershipConstraint OwnershipConstraintClassifier::visit##INST##Inst( \
320320
INST##Inst *i) { \
321321
assert(i->getNumOperands() && "Expected to have non-zero operands"); \
322-
assert(isGuaranteedForwardingInst(i) && \
322+
assert(isGuaranteedForwardingValueKind(SILNodeKind(i->getKind())) && \
323323
"Expected an ownership forwarding inst"); \
324324
return {OwnershipKind::OWNERSHIP, \
325325
UseLifetimeConstraint::USE_LIFETIME_CONSTRAINT}; \

0 commit comments

Comments
 (0)