Skip to content

Commit 28b60e0

Browse files
committed
Bridge SILFunctionType LifetimeDependenceInfo
1 parent 03bda63 commit 28b60e0

File tree

8 files changed

+221
-62
lines changed

8 files changed

+221
-62
lines changed

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ public struct ArgumentConventions : Collection, CustomStringConvertible {
228228
return endIndex - 1
229229
}
230230

231+
public var resultDependencies: FunctionConvention.ResultDependencies? {
232+
return originalFunctionConvention.resultDependencies
233+
}
234+
231235
public var description: String {
232236
var str = String(taking: originalFunctionConvention.bridgedFunctionType.getDebugDescription())
233237
if let substitutedFunctionConvention {

SwiftCompilerSources/Sources/SIL/FunctionConvention.swift

Lines changed: 138 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,6 @@ public struct FunctionConvention : CustomStringConvertible {
2525
self.hasLoweredAddresses = function.hasLoweredAddresses
2626
}
2727

28-
public struct Results : Collection {
29-
let bridged: BridgedResultInfoArray
30-
let hasLoweredAddresses: Bool
31-
32-
public var startIndex: Int { 0 }
33-
34-
public var endIndex: Int { bridged.count() }
35-
36-
public func index(after index: Int) -> Int {
37-
return index + 1
38-
}
39-
40-
public subscript(_ index: Int) -> ResultInfo {
41-
return ResultInfo(bridged: bridged.at(index),
42-
hasLoweredAddresses: hasLoweredAddresses)
43-
}
44-
}
45-
4628
/// All results including the error.
4729
public var results: Results {
4830
Results(bridged: bridgedFunctionType.SILFunctionType_getResultsWithError(),
@@ -71,24 +53,6 @@ public struct FunctionConvention : CustomStringConvertible {
7153
: results.lazy.filter { $0.convention == .pack }
7254
}
7355

74-
public struct Parameters : Collection {
75-
let bridged: BridgedParameterInfoArray
76-
let hasLoweredAddresses: Bool
77-
78-
public var startIndex: Int { 0 }
79-
80-
public var endIndex: Int { bridged.count() }
81-
82-
public func index(after index: Int) -> Int {
83-
return index + 1
84-
}
85-
86-
public subscript(_ index: Int) -> ParameterInfo {
87-
return ParameterInfo(bridged: bridged.at(index),
88-
hasLoweredAddresses: hasLoweredAddresses)
89-
}
90-
}
91-
9256
public var parameters: Parameters {
9357
Parameters(bridged: bridgedFunctionType.SILFunctionType_getParameters(),
9458
hasLoweredAddresses: hasLoweredAddresses)
@@ -98,34 +62,31 @@ public struct FunctionConvention : CustomStringConvertible {
9862
bridgedFunctionType.SILFunctionType_hasSelfParam()
9963
}
10064

101-
public struct Yields : Collection {
102-
let bridged: BridgedYieldInfoArray
103-
let hasLoweredAddresses: Bool
104-
105-
public var startIndex: Int { 0 }
106-
107-
public var endIndex: Int { bridged.count() }
108-
109-
public func index(after index: Int) -> Int {
110-
return index + 1
111-
}
112-
113-
public subscript(_ index: Int) -> ParameterInfo {
114-
return ParameterInfo(bridged: bridged.at(index),
115-
hasLoweredAddresses: hasLoweredAddresses)
116-
}
117-
}
118-
11965
public var yields: Yields {
12066
Yields(bridged: bridgedFunctionType.SILFunctionType_getYields(),
12167
hasLoweredAddresses: hasLoweredAddresses)
12268
}
12369

70+
/// If the function result depends on any parameters, return a
71+
/// Collection of LifetimeDependenceConvention indexed on the
72+
/// function parameter.
73+
public var resultDependencies: ResultDependencies? {
74+
let deps = bridgedFunctionType.SILFunctionType_getLifetimeDependenceInfo()
75+
if deps.empty() {
76+
return nil
77+
}
78+
return ResultDependencies(bridged: deps, parameterCount: parameters.count,
79+
hasSelfParameter: hasSelfParameter)
80+
}
81+
12482
public var description: String {
12583
var str = String(taking: bridgedFunctionType.getDebugDescription())
12684
parameters.forEach { str += "\nparameter: " + $0.description }
12785
results.forEach { str += "\n result: " + $0.description }
12886
str += (hasLoweredAddresses ? "\n[lowered_address]" : "\n[sil_opaque]")
87+
if let deps = resultDependencies {
88+
str += "\nresult dependences \(deps)"
89+
}
12990
return str
13091
}
13192
}
@@ -160,6 +121,26 @@ public struct ResultInfo : CustomStringConvertible {
160121
}
161122
}
162123

124+
extension FunctionConvention {
125+
public struct Results : Collection {
126+
let bridged: BridgedResultInfoArray
127+
let hasLoweredAddresses: Bool
128+
129+
public var startIndex: Int { 0 }
130+
131+
public var endIndex: Int { bridged.count() }
132+
133+
public func index(after index: Int) -> Int {
134+
return index + 1
135+
}
136+
137+
public subscript(_ index: Int) -> ResultInfo {
138+
return ResultInfo(bridged: bridged.at(index),
139+
hasLoweredAddresses: hasLoweredAddresses)
140+
}
141+
}
142+
}
143+
163144
public struct ParameterInfo : CustomStringConvertible {
164145
/// The parameter type that describes the abstract calling
165146
/// convention of the parameter.
@@ -193,6 +174,109 @@ public struct ParameterInfo : CustomStringConvertible {
193174
}
194175
}
195176

177+
extension FunctionConvention {
178+
public struct Parameters : Collection {
179+
let bridged: BridgedParameterInfoArray
180+
let hasLoweredAddresses: Bool
181+
182+
public var startIndex: Int { 0 }
183+
184+
public var endIndex: Int { bridged.count() }
185+
186+
public func index(after index: Int) -> Int {
187+
return index + 1
188+
}
189+
190+
public subscript(_ index: Int) -> ParameterInfo {
191+
return ParameterInfo(bridged: bridged.at(index),
192+
hasLoweredAddresses: hasLoweredAddresses)
193+
}
194+
}
195+
}
196+
197+
extension FunctionConvention {
198+
public struct Yields : Collection {
199+
let bridged: BridgedYieldInfoArray
200+
let hasLoweredAddresses: Bool
201+
202+
public var startIndex: Int { 0 }
203+
204+
public var endIndex: Int { bridged.count() }
205+
206+
public func index(after index: Int) -> Int {
207+
return index + 1
208+
}
209+
210+
public subscript(_ index: Int) -> ParameterInfo {
211+
return ParameterInfo(bridged: bridged.at(index),
212+
hasLoweredAddresses: hasLoweredAddresses)
213+
}
214+
}
215+
}
216+
217+
public enum LifetimeDependenceConvention {
218+
case inherit
219+
case borrow
220+
case mutate
221+
}
222+
223+
extension FunctionConvention {
224+
/// Collection of LifetimeDependenceConvention? that parallels parameters.
225+
public struct ResultDependencies : Collection, CustomStringConvertible {
226+
let bridged: BridgedLifetimeDependenceInfo
227+
let paramCount: Int
228+
let hasSelfParam: Bool
229+
230+
init(bridged: BridgedLifetimeDependenceInfo, parameterCount: Int,
231+
hasSelfParameter: Bool) {
232+
assert(!bridged.empty())
233+
self.bridged = bridged
234+
self.paramCount = parameterCount
235+
self.hasSelfParam = hasSelfParameter
236+
}
237+
238+
public var startIndex: Int { 0 }
239+
240+
public var endIndex: Int { paramCount }
241+
242+
public func index(after index: Int) -> Int {
243+
return index + 1
244+
}
245+
246+
public subscript(_ index: Int) -> LifetimeDependenceConvention? {
247+
let inherit = bridged.checkInherit(bridgedIndex(parameterIndex: index))
248+
let borrow = bridged.checkBorrow(bridgedIndex(parameterIndex: index))
249+
let mutate = bridged.checkMutate(bridgedIndex(parameterIndex: index))
250+
if inherit {
251+
assert(!borrow && !mutate, "mutualy exclusive lifetime specifiers")
252+
return .inherit
253+
}
254+
if borrow {
255+
assert(!mutate, "mutualy exclusive lifetime specifiers")
256+
return .borrow
257+
}
258+
if mutate {
259+
return .mutate
260+
}
261+
return nil
262+
}
263+
264+
// In Sema's LifetimeDependenceInfo, 'self' is always index zero,
265+
// whether it exists or not. In SILFunctionType, 'self' is the
266+
// last parameter if it exists.
267+
private func bridgedIndex(parameterIndex: Int) -> Int {
268+
if hasSelfParam, parameterIndex == (paramCount - 1) {
269+
return 0
270+
}
271+
return parameterIndex + 1
272+
}
273+
274+
public var description: String {
275+
String(taking: bridged.getDebugDescription())
276+
}
277+
}
278+
}
279+
196280
public enum ResultConvention : CustomStringConvertible {
197281
/// This result is returned indirectly, i.e. by passing the address of an uninitialized object in memory. The callee is responsible for leaving an initialized object at this address. The callee may assume that the address does not alias any valid object.
198282
case indirect

include/swift/AST/LifetimeDependence.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,21 @@ class LifetimeDependenceInfo {
165165
bool hasBorrowLifetimeParamIndices() const {
166166
return scopeLifetimeParamIndices != nullptr;
167167
}
168+
169+
bool checkInherit(int index) const {
170+
assert(!empty());
171+
return inheritLifetimeParamIndices->contains(index);
172+
}
173+
174+
bool checkBorrow(int index) const {
175+
assert(!empty());
176+
return borrowLifetimeParamIndices->contains(index);
177+
}
178+
179+
bool checkMutate(int index) const {
180+
assert(!empty());
181+
return mutateLifetimeParamIndices->contains(index);
182+
}
168183

169184
std::string getString() const;
170185
void Profile(llvm::FoldingSetNodeID &ID) const;
@@ -176,4 +191,4 @@ class LifetimeDependenceInfo {
176191

177192
} // namespace swift
178193

179-
#endif
194+
#endif

include/swift/AST/Types.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5224,7 +5224,15 @@ class SILFunctionType final
52245224

52255225
ClangTypeInfo getClangTypeInfo() const;
52265226

5227-
LifetimeDependenceInfo getLifetimeDependenceInfo() const;
5227+
/// Returns nullptr for an empty dependence list.
5228+
const LifetimeDependenceInfo *getLifetimeDependenceInfoOrNull() const;
5229+
5230+
inline LifetimeDependenceInfo getLifetimeDependenceInfo() const {
5231+
if (auto *depInfo = getLifetimeDependenceInfoOrNull()) {
5232+
return *depInfo;
5233+
}
5234+
return LifetimeDependenceInfo();
5235+
}
52285236

52295237
/// Returns true if the function type stores a Clang type that cannot
52305238
/// be derived from its Swift type. Returns false otherwise, including if

include/swift/SIL/SILBridging.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class VarDecl;
6363
class TypeBase;
6464
class SwiftPassInvocation;
6565
class GenericSpecializationInformation;
66+
class LifetimeDependenceInfo;
6667
}
6768

6869
bool swiftModulesInitialized();
@@ -227,6 +228,17 @@ struct BridgedYieldInfoArray {
227228
BridgedParameterInfo at(SwiftInt resultIndex) const;
228229
};
229230

231+
struct BridgedLifetimeDependenceInfo {
232+
const swift::LifetimeDependenceInfo * _Nullable info = nullptr;
233+
234+
BRIDGED_INLINE bool empty() const;
235+
BRIDGED_INLINE bool checkInherit(SwiftInt index) const;
236+
BRIDGED_INLINE bool checkBorrow(SwiftInt index) const;
237+
BRIDGED_INLINE bool checkMutate(SwiftInt index) const;
238+
239+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedOwnedString getDebugDescription() const;
240+
};
241+
230242
// Temporary access to the AST type within SIL until ASTBridging provides it.
231243
struct BridgedASTType {
232244
swift::TypeBase * _Nullable type;
@@ -270,6 +282,8 @@ struct BridgedASTType {
270282

271283
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
272284
BridgedYieldInfoArray SILFunctionType_getYields() const;
285+
286+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedLifetimeDependenceInfo SILFunctionType_getLifetimeDependenceInfo() const;
273287
};
274288

275289
struct BridgedType {

include/swift/SIL/SILBridgingImpl.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,34 @@ BridgedParameterInfo BridgedParameterInfoArray::at(SwiftInt parameterIndex) cons
7777
return BridgedParameterInfo(unbridged()[parameterIndex]);
7878
}
7979

80+
//===----------------------------------------------------------------------===//
81+
// BridgedLifetimeDependenceInfo
82+
//===----------------------------------------------------------------------===//
83+
84+
bool BridgedLifetimeDependenceInfo::empty() const {
85+
return info == nullptr || info->empty();
86+
}
87+
88+
bool BridgedLifetimeDependenceInfo::checkInherit(SwiftInt index) const {
89+
assert(info);
90+
return info->checkInherit(index);
91+
}
92+
93+
bool BridgedLifetimeDependenceInfo::checkBorrow(SwiftInt index) const {
94+
assert(info);
95+
return info->checkBorrow(index);
96+
}
97+
98+
bool BridgedLifetimeDependenceInfo::checkMutate(SwiftInt index) const {
99+
assert(info);
100+
return info->checkMutate(index);
101+
}
102+
103+
BridgedOwnedString BridgedLifetimeDependenceInfo::getDebugDescription() const {
104+
assert(info);
105+
return BridgedOwnedString(info->getString());
106+
}
107+
80108
//===----------------------------------------------------------------------===//
81109
// BridgedASTType
82110
//===----------------------------------------------------------------------===//
@@ -134,6 +162,11 @@ BridgedYieldInfoArray BridgedASTType::SILFunctionType_getYields() const {
134162
return unbridged()->castTo<swift::SILFunctionType>()->getYields();
135163
}
136164

165+
BridgedLifetimeDependenceInfo BridgedASTType::SILFunctionType_getLifetimeDependenceInfo() const {
166+
auto fnTy = unbridged()->castTo<swift::SILFunctionType>();
167+
return {fnTy->getLifetimeDependenceInfoOrNull()};
168+
}
169+
137170
//===----------------------------------------------------------------------===//
138171
// BridgedType
139172
//===----------------------------------------------------------------------===//

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7599,9 +7599,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
75997599
}
76007600
sub->Printer << ") -> ";
76017601

7602-
auto lifetimeDependenceInfo = T->getLifetimeDependenceInfo();
7603-
if (!lifetimeDependenceInfo.empty()) {
7604-
sub->Printer << lifetimeDependenceInfo.getString() << " ";
7602+
auto *lifetimeDependenceInfo = T->getLifetimeDependenceInfo();
7603+
if (lifetimeDependenceInfo && !lifetimeDependenceInfo->empty()) {
7604+
sub->Printer << lifetimeDependenceInfo->getString() << " ";
76057605
}
76067606

76077607
bool parenthesizeResults = mustParenthesizeResults(T);

0 commit comments

Comments
 (0)