Skip to content

Commit 74d03b9

Browse files
authored
Merge pull request swiftlang#6659 from gottesmm/misc_semantic_sil_cleanups
2 parents ebfc16c + 0f1b8bb commit 74d03b9

File tree

6 files changed

+111
-105
lines changed

6 files changed

+111
-105
lines changed

include/swift/AST/Types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ namespace swift {
6969
struct SILArgumentConvention;
7070
enum OptionalTypeKind : unsigned;
7171
enum PointerTypeKind : unsigned;
72-
enum class ValueOwnershipKind : uint8_t;
72+
struct ValueOwnershipKind;
7373

7474
enum class TypeKind {
7575
#define TYPE(id, parent) id,

include/swift/SIL/SILBasicBlock.h

+5-11
Original file line numberDiff line numberDiff line change
@@ -174,22 +174,11 @@ public llvm::ilist_node<SILBasicBlock>, public SILAllocated<SILBasicBlock> {
174174
/// Erase a specific argument from the arg list.
175175
void eraseArgument(int Index);
176176

177-
/// Replace the \p{i}th BB arg with a new BBArg with SILType \p Ty and
178-
/// ValueDecl
179-
/// \p D.
180-
SILFunctionArgument *replaceFunctionArgument(unsigned i, SILType Ty,
181-
const ValueDecl *D = nullptr);
182-
183177
/// Allocate a new argument of type \p Ty and append it to the argument
184178
/// list. Optionally you can pass in a value decl parameter.
185179
SILFunctionArgument *createFunctionArgument(SILType Ty,
186180
const ValueDecl *D = nullptr);
187181

188-
/// Insert a new SILFunctionArgument with type \p Ty and \p Decl at position
189-
/// \p Pos.
190-
SILFunctionArgument *insertFunctionArgument(arg_iterator Pos, SILType Ty,
191-
const ValueDecl *D = nullptr);
192-
193182
SILFunctionArgument *insertFunctionArgument(unsigned Index, SILType Ty,
194183
const ValueDecl *D = nullptr) {
195184
arg_iterator Pos = ArgumentList.begin();
@@ -352,6 +341,11 @@ public llvm::ilist_node<SILBasicBlock>, public SILAllocated<SILBasicBlock> {
352341
void insertArgument(arg_iterator Iter, SILArgument *Arg) {
353342
ArgumentList.insert(Iter, Arg);
354343
}
344+
345+
/// Insert a new SILFunctionArgument with type \p Ty and \p Decl at position
346+
/// \p Pos.
347+
SILFunctionArgument *insertFunctionArgument(arg_iterator Pos, SILType Ty,
348+
const ValueDecl *D = nullptr);
355349
};
356350

357351
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,

include/swift/SIL/SILValue.h

+62-51
Original file line numberDiff line numberDiff line change
@@ -51,59 +51,70 @@ static inline llvm::hash_code hash_value(ValueKind K) {
5151

5252
/// A value representing the specific ownership semantics that a SILValue may
5353
/// have.
54-
enum class ValueOwnershipKind : uint8_t {
55-
/// A SILValue with Trivial ownership kind is an independent value that can
56-
/// not be owned. Ownership does not place any constraints on how a SILValue
57-
/// with Trivial ownership kind can be used. Other side effects (e.g. Memory
58-
/// dependencies) must still be respected. A SILValue with Trivial ownership
59-
/// kind must be of Trivial SILType (i.e. SILType::isTrivial(SILModule &) must
60-
/// return true).
61-
///
62-
/// Some examples of SIL types with Trivial ownership are: Builtin.Int32,
63-
/// Builtin.RawPointer, aggregates containing all trivial types.
64-
Trivial,
65-
66-
/// A SILValue with `Unowned` ownership kind is an independent value that has
67-
/// a lifetime that is only guaranteed to last until the next program visible
68-
/// side-effect. To maintain the lifetime of an unowned value, it must be
69-
/// converted to an owned representation via a copy_value.
70-
///
71-
/// Unowned ownership kind occurs mainly along method/function boundaries in
72-
/// between Swift and Objective-C code.
73-
Unowned,
74-
75-
/// A SILValue with `Owned` ownership kind is an independent value that has an
76-
/// ownership independent of any other ownership imbued within it. The
77-
/// SILValue must be paired with a consuming operation that ends the SSA
78-
/// value's lifetime exactly once along all paths through the program.
79-
Owned,
80-
81-
/// A SILValue with `Guaranteed` ownership kind is an independent value that
82-
/// is guaranteed to be live over a specific region of the program. This
83-
/// region can come in several forms:
84-
///
85-
/// 1. @guaranteed function argument. This guarantees that a value will
86-
/// outlive a function.
87-
///
88-
/// 2. A shared borrow region. This is a region denoted by a
89-
/// begin_borrow/load_borrow instruction and an end_borrow instruction. The
90-
/// SSA value must not be destroyed or taken inside the borrowed region.
91-
///
92-
/// Any value with guaranteed ownership must be paired with an end_borrow
93-
/// instruction exactly once along any path through the program.
94-
Guaranteed,
95-
96-
/// A SILValue with undefined ownership. It can pair with /Any/ ownership
97-
/// kinds . This means that it could take on /any/ ownership semantics. This
98-
/// is meant only to model SILUndef and to express certain situations where we
99-
/// use unqualified ownership. Expected to tighten over time.
100-
Any,
54+
struct ValueOwnershipKind {
55+
enum innerty : uint8_t {
56+
/// A SILValue with Trivial ownership kind is an independent value that can
57+
/// not be owned. Ownership does not place any constraints on how a SILValue
58+
/// with Trivial ownership kind can be used. Other side effects (e.g. Memory
59+
/// dependencies) must still be respected. A SILValue with Trivial ownership
60+
/// kind must be of Trivial SILType (i.e. SILType::isTrivial(SILModule &)
61+
/// must
62+
/// return true).
63+
///
64+
/// Some examples of SIL types with Trivial ownership are: Builtin.Int32,
65+
/// Builtin.RawPointer, aggregates containing all trivial types.
66+
Trivial,
67+
68+
/// A SILValue with `Unowned` ownership kind is an independent value that
69+
/// has
70+
/// a lifetime that is only guaranteed to last until the next program
71+
/// visible
72+
/// side-effect. To maintain the lifetime of an unowned value, it must be
73+
/// converted to an owned representation via a copy_value.
74+
///
75+
/// Unowned ownership kind occurs mainly along method/function boundaries in
76+
/// between Swift and Objective-C code.
77+
Unowned,
78+
79+
/// A SILValue with `Owned` ownership kind is an independent value that has
80+
/// an
81+
/// ownership independent of any other ownership imbued within it. The
82+
/// SILValue must be paired with a consuming operation that ends the SSA
83+
/// value's lifetime exactly once along all paths through the program.
84+
Owned,
85+
86+
/// A SILValue with `Guaranteed` ownership kind is an independent value that
87+
/// is guaranteed to be live over a specific region of the program. This
88+
/// region can come in several forms:
89+
///
90+
/// 1. @guaranteed function argument. This guarantees that a value will
91+
/// outlive a function.
92+
///
93+
/// 2. A shared borrow region. This is a region denoted by a
94+
/// begin_borrow/load_borrow instruction and an end_borrow instruction. The
95+
/// SSA value must not be destroyed or taken inside the borrowed region.
96+
///
97+
/// Any value with guaranteed ownership must be paired with an end_borrow
98+
/// instruction exactly once along any path through the program.
99+
Guaranteed,
100+
101+
/// A SILValue with undefined ownership. It can pair with /Any/ ownership
102+
/// kinds . This means that it could take on /any/ ownership semantics. This
103+
/// is meant only to model SILUndef and to express certain situations where
104+
/// we
105+
/// use unqualified ownership. Expected to tighten over time.
106+
Any,
107+
} Value;
108+
109+
ValueOwnershipKind(innerty NewValue) : Value(NewValue) {}
110+
ValueOwnershipKind(SILModule &M, SILType Type,
111+
SILArgumentConvention Convention);
112+
113+
operator innerty() const { return Value; }
114+
115+
Optional<ValueOwnershipKind> merge(ValueOwnershipKind RHS) const;
101116
};
102117

103-
Optional<ValueOwnershipKind>
104-
ValueOwnershipKindMerge(Optional<ValueOwnershipKind> LHS,
105-
Optional<ValueOwnershipKind> RHS);
106-
107118
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, ValueOwnershipKind Kind);
108119

109120
/// This is the base class of the SIL value hierarchy, which represents a

lib/SIL/SILBasicBlock.cpp

-23
Original file line numberDiff line numberDiff line change
@@ -119,29 +119,6 @@ void SILBasicBlock::cloneArgumentList(SILBasicBlock *Other) {
119119
}
120120
}
121121

122-
/// Replace the ith BB argument with a new one with type Ty (and optional
123-
/// ValueDecl D).
124-
SILFunctionArgument *
125-
SILBasicBlock::replaceFunctionArgument(unsigned i, SILType Ty,
126-
const ValueDecl *D) {
127-
assert(isEntry() && "Function Arguments can only be in the entry block");
128-
SILModule &M = getParent()->getModule();
129-
130-
assert(ArgumentList[i]->use_empty() && "Expected no uses of the old BB arg!");
131-
132-
// Notify the delete handlers that this argument is being deleted.
133-
M.notifyDeleteHandlers(ArgumentList[i]);
134-
135-
SILFunctionArgument *NewArg = new (M) SILFunctionArgument(Ty, D);
136-
NewArg->setParent(this);
137-
138-
// TODO: When we switch to malloc/free allocation we'll be leaking memory
139-
// here.
140-
ArgumentList[i] = NewArg;
141-
142-
return NewArg;
143-
}
144-
145122
SILFunctionArgument *SILBasicBlock::createFunctionArgument(SILType Ty,
146123
const ValueDecl *D) {
147124
assert(isEntry() && "Function Arguments can only be in the entry block");

lib/SIL/SILOwnershipVerifier.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ llvm::cl::opt<bool> PrintMessageInsteadOfAssert(
5353

5454
static bool compatibleOwnershipKinds(ValueOwnershipKind K1,
5555
ValueOwnershipKind K2) {
56-
return ValueOwnershipKindMerge(K1, K2).hasValue();
56+
return K1.merge(K2).hasValue();
5757
}
5858

5959
static bool isValueAddressOrTrivial(SILValue V, SILModule &M) {
@@ -316,11 +316,12 @@ OwnershipUseCheckerResult
316316
OwnershipCompatibilityUseChecker::visitForwardingInst(SILInstruction *I) {
317317
assert(I->getNumOperands() && "Expected to have non-zero operands");
318318
ArrayRef<Operand> Ops = I->getAllOperands();
319-
llvm::Optional<ValueOwnershipKind> Base = getOwnershipKind();
319+
ValueOwnershipKind Base = getOwnershipKind();
320320
for (const Operand &Op : Ops) {
321-
Base = ValueOwnershipKindMerge(Base, Op.get().getOwnershipKind());
322-
if (!Base.hasValue())
321+
auto MergedValue = Base.merge(Op.get().getOwnershipKind());
322+
if (!MergedValue.hasValue())
323323
return {false, true};
324+
Base = MergedValue.getValue();
324325
}
325326
return {true, !isAddressOrTrivialType()};
326327
}
@@ -374,10 +375,10 @@ OwnershipCompatibilityUseChecker::visitReturnInst(ReturnInst *RI) {
374375
for (const SILResultInfo &ResultInfo : Results.slice(Index + 1)) {
375376
auto RKind = ResultInfo.getOwnershipKind(M);
376377
// Ignore trivial types.
377-
if (ValueOwnershipKindMerge(RKind, ValueOwnershipKind::Trivial))
378+
if (RKind.merge(ValueOwnershipKind::Trivial))
378379
continue;
379380

380-
auto MergedValue = ValueOwnershipKindMerge(Base, RKind);
381+
auto MergedValue = Base.merge(RKind);
381382
// If we fail to merge all types in, bail. We can not come up with a proper
382383
// result type.
383384
if (!MergedValue.hasValue()) {

lib/SIL/SILValue.cpp

+36-13
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,32 @@ SILModule *ValueBase::getModule() const {
7474
// ValueOwnershipKind
7575
//===----------------------------------------------------------------------===//
7676

77+
ValueOwnershipKind::ValueOwnershipKind(SILModule &M, SILType Type,
78+
SILArgumentConvention Convention)
79+
: Value() {
80+
switch (Convention) {
81+
case SILArgumentConvention::Indirect_In:
82+
case SILArgumentConvention::Indirect_In_Guaranteed:
83+
case SILArgumentConvention::Indirect_Inout:
84+
case SILArgumentConvention::Indirect_InoutAliasable:
85+
case SILArgumentConvention::Indirect_Out:
86+
Value = ValueOwnershipKind::Trivial;
87+
return;
88+
case SILArgumentConvention::Direct_Owned:
89+
Value = ValueOwnershipKind::Owned;
90+
return;
91+
case SILArgumentConvention::Direct_Unowned:
92+
Value = Type.isTrivial(M) ? ValueOwnershipKind::Trivial
93+
: ValueOwnershipKind::Unowned;
94+
return;
95+
case SILArgumentConvention::Direct_Guaranteed:
96+
Value = ValueOwnershipKind::Guaranteed;
97+
return;
98+
case SILArgumentConvention::Direct_Deallocating:
99+
llvm_unreachable("Not handled");
100+
}
101+
}
102+
77103
llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os,
78104
ValueOwnershipKind Kind) {
79105
switch (Kind) {
@@ -91,23 +117,20 @@ llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os,
91117
}
92118

93119
Optional<ValueOwnershipKind>
94-
swift::ValueOwnershipKindMerge(Optional<ValueOwnershipKind> LHS,
95-
Optional<ValueOwnershipKind> RHS) {
96-
if (!LHS.hasValue() || !RHS.hasValue())
97-
return NoneType::None;
98-
auto LHSVal = LHS.getValue();
99-
auto RHSVal = RHS.getValue();
120+
ValueOwnershipKind::merge(ValueOwnershipKind RHS) const {
121+
auto LHSVal = Value;
122+
auto RHSVal = RHS.Value;
100123

101124
// Any merges with anything.
102125
if (LHSVal == ValueOwnershipKind::Any) {
103-
return RHSVal;
126+
return ValueOwnershipKind(RHSVal);
104127
}
105128
// Any merges with anything.
106129
if (RHSVal == ValueOwnershipKind::Any) {
107-
return LHSVal;
130+
return ValueOwnershipKind(LHSVal);
108131
}
109132

110-
return (LHSVal == RHSVal) ? LHS : None;
133+
return (LHSVal == RHSVal) ? Optional<ValueOwnershipKind>(*this) : None;
111134
}
112135

113136
//===----------------------------------------------------------------------===//
@@ -335,10 +358,10 @@ ValueOwnershipKindVisitor::visitForwardingInst(SILInstruction *I) {
335358

336359
for (const Operand &Op : Ops.slice(Index+1)) {
337360
auto OpKind = Op.get().getOwnershipKind();
338-
if (ValueOwnershipKindMerge(OpKind, ValueOwnershipKind::Trivial))
361+
if (OpKind.merge(ValueOwnershipKind::Trivial))
339362
continue;
340363

341-
auto MergedValue = ValueOwnershipKindMerge(Base, OpKind);
364+
auto MergedValue = Base.merge(OpKind.Value);
342365
if (!MergedValue.hasValue()) {
343366
llvm_unreachable("Forwarding inst with mismatching ownership kinds?!");
344367
}
@@ -440,10 +463,10 @@ ValueOwnershipKindVisitor::visitApplyInst(ApplyInst *AI) {
440463

441464
for (const SILResultInfo &ResultInfo : Results.slice(Index+1)) {
442465
auto RKind = ResultInfo.getOwnershipKind(M);
443-
if (ValueOwnershipKindMerge(RKind, ValueOwnershipKind::Trivial))
466+
if (RKind.merge(ValueOwnershipKind::Trivial))
444467
continue;
445468

446-
auto MergedValue = ValueOwnershipKindMerge(Base, RKind);
469+
auto MergedValue = Base.merge(RKind.Value);
447470
if (!MergedValue.hasValue()) {
448471
llvm_unreachable("Forwarding inst with mismatching ownership kinds?!");
449472
}

0 commit comments

Comments
 (0)