Skip to content

Commit 14b985d

Browse files
committed
Swift SIL: support ownership
* add the `Ownership` enum and the `Value.ownership` getter * add `Function.hasOwnership`
1 parent cd456fa commit 14b985d

File tree

5 files changed

+100
-0
lines changed

5 files changed

+100
-0
lines changed

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ final public class Function : CustomStringConvertible, HasShortDescription {
2727

2828
public var shortDescription: String { name.string }
2929

30+
public var hasOwnership: Bool { SILFunction_hasOwnership(bridged) != 0 }
31+
3032
public var entryBlock: BasicBlock {
3133
SILFunction_firstBlock(bridged).block!
3234
}

SwiftCompilerSources/Sources/SIL/Value.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,60 @@ import SILBridging
1616
public protocol Value : AnyObject, CustomStringConvertible {
1717
var uses: UseList { get }
1818
var type: Type { get }
19+
var ownership: Ownership { get }
1920
var definingInstruction: Instruction? { get }
2021
}
2122

23+
public enum Ownership {
24+
/// A Value with `unowned` ownership kind is an independent value that
25+
/// has a lifetime that is only guaranteed to last until the next program
26+
/// visible side-effect. To maintain the lifetime of an unowned value, it
27+
/// must be converted to an owned representation via a copy_value.
28+
///
29+
/// Unowned ownership kind occurs mainly along method/function boundaries in
30+
/// between Swift and Objective-C code.
31+
case unowned
32+
33+
/// A Value with `owned` ownership kind is an independent value that has
34+
/// an ownership independent of any other ownership imbued within it. The
35+
/// Value must be paired with a consuming operation that ends the SSA
36+
/// value's lifetime exactly once along all paths through the program.
37+
case owned
38+
39+
/// A Value with `guaranteed` ownership kind is an independent value that
40+
/// is guaranteed to be live over a specific region of the program. This
41+
/// region can come in several forms:
42+
///
43+
/// 1. @guaranteed function argument. This guarantees that a value will
44+
/// outlive a function.
45+
///
46+
/// 2. A shared borrow region. This is a region denoted by a
47+
/// begin_borrow/load_borrow instruction and an end_borrow instruction. The
48+
/// SSA value must not be destroyed or taken inside the borrowed region.
49+
///
50+
/// Any value with guaranteed ownership must be paired with an end_borrow
51+
/// instruction exactly once along any path through the program.
52+
case guaranteed
53+
54+
/// A Value with `none` ownership kind is an independent value outside of
55+
/// the ownership system. It is used to model values that are statically
56+
/// determined to be trivial. This includes trivially typed values as well
57+
/// as trivial cases of non-trivial enums. Naturally `none` can be merged with
58+
/// any ownership, allowing us to naturally model merge and branch
59+
/// points in the SSA graph, where more information about the value is
60+
/// statically available on some control flow paths.
61+
case none
62+
63+
public var _bridged: BridgedOwnership {
64+
switch self {
65+
case .unowned: return Ownership_Unowned
66+
case .owned: return Ownership_Owned
67+
case .guaranteed: return Ownership_Guaranteed
68+
case .none: return Ownership_None
69+
}
70+
}
71+
}
72+
2273
extension Value {
2374
public var description: String {
2475
var s = SILNode_debugDescription(bridgedNode)
@@ -55,6 +106,7 @@ extension Value {
55106
}
56107
return nil
57108
}
109+
public var ownership: Ownership { SILValue_getOwnership(bridged).ownership }
58110

59111
public var hashable: HashableValue { ObjectIdentifier(self) }
60112

@@ -111,3 +163,16 @@ final class PlaceholderValue : Value {
111163
extension OptionalBridgedValue {
112164
var value: Value? { obj.getAs(AnyObject.self) as? Value }
113165
}
166+
167+
extension BridgedOwnership {
168+
var ownership: Ownership {
169+
switch self {
170+
case Ownership_Unowned: return .unowned
171+
case Ownership_Owned: return .owned
172+
case Ownership_Guaranteed: return .guaranteed
173+
case Ownership_None: return .none
174+
default:
175+
fatalError("unsupported ownership")
176+
}
177+
}
178+
}

include/swift/SIL/SILBridging.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ typedef enum {
134134
MayHaveSideEffectsBehavior
135135
} BridgedMemoryBehavior;
136136

137+
typedef enum {
138+
Ownership_Unowned,
139+
Ownership_Owned,
140+
Ownership_Guaranteed,
141+
Ownership_None
142+
} BridgedOwnership;
143+
137144
// AST bridging
138145

139146
typedef struct {
@@ -179,6 +186,7 @@ void PassContext_eraseInstruction(BridgedPassContext passContext,
179186

180187
BridgedStringRef SILFunction_getName(BridgedFunction function);
181188
std::string SILFunction_debugDescription(BridgedFunction function);
189+
SwiftInt SILFunction_hasOwnership(BridgedFunction function);
182190
OptionalBridgedBasicBlock SILFunction_firstBlock(BridgedFunction function);
183191
OptionalBridgedBasicBlock SILFunction_lastBlock(BridgedFunction function);
184192
SwiftInt SILFunction_numIndirectResultArguments(BridgedFunction function);
@@ -213,6 +221,7 @@ std::string SILNode_debugDescription(BridgedNode node);
213221
BridgedFunction SILNode_getFunction(BridgedNode node);
214222
OptionalBridgedOperand SILValue_firstUse(BridgedValue value);
215223
BridgedType SILValue_getType(BridgedValue value);
224+
BridgedOwnership SILValue_getOwnership(BridgedValue value);
216225

217226
BridgedStringRef SILType_debugDescription(BridgedType);
218227
SwiftInt SILType_isAddress(BridgedType);

include/swift/SIL/SILBridgingUtils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ inline SILGlobalVariable *castToGlobal(BridgedGlobalVar global) {
8080
return static_cast<SILGlobalVariable *>(global.obj);
8181
}
8282

83+
inline ValueOwnershipKind castToOwnership(BridgedOwnership ownership) {
84+
switch (ownership) {
85+
case Ownership_Unowned: return OwnershipKind::Unowned;
86+
case Ownership_Owned: return OwnershipKind::Owned;
87+
case Ownership_Guaranteed: return OwnershipKind::Guaranteed;
88+
case Ownership_None: return OwnershipKind::None;
89+
}
90+
}
91+
8392
ArrayRef<SILValue> getSILValues(BridgedValueArray values,
8493
SmallVectorImpl<SILValue> &storage);
8594

lib/SIL/Utils/SILBridging.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ std::string SILFunction_debugDescription(BridgedFunction function) {
158158
return str;
159159
}
160160

161+
SwiftInt SILFunction_hasOwnership(BridgedFunction function) {
162+
return castToFunction(function)->hasOwnership() ? 1 : 0;
163+
}
164+
161165
OptionalBridgedBasicBlock SILFunction_firstBlock(BridgedFunction function) {
162166
SILFunction *f = castToFunction(function);
163167
if (f->empty())
@@ -351,6 +355,17 @@ BridgedType SILValue_getType(BridgedValue value) {
351355
return { castToSILValue(value)->getType().getOpaqueValue() };
352356
}
353357

358+
BridgedOwnership SILValue_getOwnership(BridgedValue value) {
359+
switch (castToSILValue(value)->getOwnershipKind()) {
360+
case OwnershipKind::Any:
361+
llvm_unreachable("Invalid ownership for value");
362+
case OwnershipKind::Unowned: return Ownership_Unowned;
363+
case OwnershipKind::Owned: return Ownership_Owned;
364+
case OwnershipKind::Guaranteed: return Ownership_Guaranteed;
365+
case OwnershipKind::None: return Ownership_None;
366+
}
367+
}
368+
354369
//===----------------------------------------------------------------------===//
355370
// SILType
356371
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)