Skip to content

Commit fc534e1

Browse files
committed
SwiftCompilerSources: better APIs for handling resilient nominal types
* add `NominalTypeDecl.isResilient` * make the return type of `Type.getNominalFields` optional and return nil in case the nominal type is resilient. This forces users of this API to think about what to do in case the nominal type is resilient.
1 parent 186f1b3 commit fc534e1

File tree

10 files changed

+45
-12
lines changed

10 files changed

+45
-12
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/InitializeStaticGlobals.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,10 @@ private func getSequenceOfElementStores(firstStore: StoreInst) -> ([StoreInst],
184184
if structAddr.type.isMoveOnly {
185185
return nil
186186
}
187-
let numElements = structAddr.type.getNominalFields(in: firstStore.parentFunction).count
187+
guard let fields = structAddr.type.getNominalFields(in: firstStore.parentFunction) else {
188+
return nil
189+
}
190+
let numElements = fields.count
188191
var elementStores = Array<StoreInst?>(repeating: nil, count: numElements)
189192
var numStoresFound = 0
190193

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjectOutliner.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ private extension AllocRefInstBase {
410410

411411
var numClassFields: Int {
412412
assert(type.isClass)
413-
return type.getNominalFields(in: parentFunction).count
413+
return type.getNominalFields(in: parentFunction)!.count
414414
}
415415

416416
var numStoresPerTailElement: Int {
@@ -475,7 +475,7 @@ private func replace(findStringCall: ApplyInst,
475475
with cachedFindStringFunc: Function,
476476
_ context: FunctionPassContext) {
477477
let cacheType = cachedFindStringFunc.argumentTypes[2].objectType
478-
let wordTy = cacheType.getNominalFields(in: findStringCall.parentFunction)[0]
478+
let wordTy = cacheType.getNominalFields(in: findStringCall.parentFunction)![0]
479479

480480
let name = context.mangleOutlinedVariable(from: findStringCall.parentFunction)
481481

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ReleaseDevirtualizer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ private extension Type {
167167
return true
168168
}
169169
if isStruct {
170-
return getNominalFields(in: function).containsSingleReference(in: function)
170+
return getNominalFields(in: function)?.containsSingleReference(in: function) ?? false
171171
} else if isTuple {
172172
return tupleElements.containsSingleReference(in: function)
173173
} else {

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBeginBorrow.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private extension ForwardingInstruction {
192192
return false
193193
}
194194
let structFields = si.struct.type.getNominalFields(in: parentFunction)
195-
return structFields.hasSingleNonTrivialElement(at: si.fieldIndex, in: parentFunction)
195+
return structFields?.hasSingleNonTrivialElement(at: si.fieldIndex, in: parentFunction) ?? false
196196
case let ti as TupleExtractInst:
197197
return ti.tuple.type.tupleElements.hasSingleNonTrivialElement(at: ti.fieldIndex, in: parentFunction)
198198
default:

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyLoad.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@ extension LoadInst : OnoneSimplifyable, SILCombineSimplifyable {
135135
case let sea as StructElementAddrInst:
136136
let structType = sea.struct.type
137137
if structType.nominal.name == "_SwiftArrayBodyStorage" {
138-
switch structType.getNominalFields(in: parentFunction).getNameOfField(withIndex: sea.fieldIndex) {
138+
guard let fields = structType.getNominalFields(in: parentFunction) else {
139+
return false
140+
}
141+
switch fields.getNameOfField(withIndex: sea.fieldIndex) {
139142
case "count":
140143
break
141144
case "_capacityAndFlags":
@@ -153,7 +156,10 @@ extension LoadInst : OnoneSimplifyable, SILCombineSimplifyable {
153156
case "__RawDictionaryStorage",
154157
"__RawSetStorage":
155158
// For Dictionary and Set we support "count" and "capacity".
156-
switch classType.getNominalFields(in: parentFunction).getNameOfField(withIndex: rea.fieldIndex) {
159+
guard let fields = classType.getNominalFields(in: parentFunction) else {
160+
return false
161+
}
162+
switch fields.getNameOfField(withIndex: rea.fieldIndex) {
157163
case "_count", "_capacity":
158164
break
159165
default:

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,10 @@ extension StoreInst {
239239
builder.createStore(source: fieldValue, destination: destFieldAddr, ownership: splitOwnership(for: fieldValue))
240240
}
241241
} else {
242-
for idx in 0..<type.getNominalFields(in: parentFunction).count {
242+
guard let fields = type.getNominalFields(in: parentFunction) else {
243+
return
244+
}
245+
for idx in 0..<fields.count {
243246
let srcField = builder.createStructExtract(struct: source, fieldIndex: idx)
244247
let fieldAddr = builder.createStructElementAddr(structAddress: destination, fieldIndex: idx)
245248
builder.createStore(source: srcField, destination: fieldAddr, ownership: splitOwnership(for: srcField))
@@ -283,7 +286,10 @@ extension LoadInst {
283286
if type.nominal.isStructWithUnreferenceableStorage {
284287
return
285288
}
286-
for idx in 0..<type.getNominalFields(in: parentFunction).count {
289+
guard let fields = type.getNominalFields(in: parentFunction) else {
290+
return
291+
}
292+
for idx in 0..<fields.count {
287293
let fieldAddr = builder.createStructElementAddr(structAddress: address, fieldIndex: idx)
288294
let splitLoad = builder.createLoad(fromAddress: fieldAddr, ownership: self.splitOwnership(for: fieldAddr))
289295
elements.append(splitLoad)

SwiftCompilerSources/Sources/SIL/SmallProjectionPath.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,9 @@ extension StringParser {
543543
if !ty.isClass && !ty.isStruct {
544544
try throwError("unknown kind of nominal type")
545545
}
546-
let nominalFields = ty.getNominalFields(in: function)
546+
guard let nominalFields = ty.getNominalFields(in: function) else {
547+
try throwError("resilient types are not supported")
548+
}
547549
guard let fieldIdx = nominalFields.getIndexOfField(withName: name) else {
548550
try throwError("field not found")
549551
}

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,14 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
9090

9191
public var tupleElements: TupleElementArray { TupleElementArray(type: self) }
9292

93-
public func getNominalFields(in function: Function) -> NominalFieldsArray {
94-
NominalFieldsArray(type: self, function: function)
93+
/// Can only be used if the type is in fact a nominal type (`isNominal` is true).
94+
/// Returns nil if the nominal is a resilient type because in this case the complete list
95+
/// of fields is not known.
96+
public func getNominalFields(in function: Function) -> NominalFieldsArray? {
97+
if nominal.isResilient(in: function) {
98+
return nil
99+
}
100+
return NominalFieldsArray(type: self, function: function)
95101
}
96102

97103
public typealias MetatypeRepresentation = BridgedType.MetatypeRepresentation
@@ -227,6 +233,10 @@ public struct NominalTypeDecl : Equatable, Hashable {
227233
hasher.combine(bridged.raw)
228234
}
229235

236+
public func isResilient(in function: Function) -> Bool {
237+
function.bridged.isResilientNominalDecl(bridged)
238+
}
239+
230240
public var isStructWithUnreferenceableStorage: Bool {
231241
bridged.isStructWithUnreferenceableStorage()
232242
}

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ struct BridgedFunction {
320320
BRIDGED_INLINE bool hasValidLinkageForFragileRef() const;
321321
BRIDGED_INLINE bool needsStackProtection() const;
322322
BRIDGED_INLINE void setNeedStackProtection(bool needSP) const;
323+
BRIDGED_INLINE bool isResilientNominalDecl(BridgedNominalTypeDecl decl) const;
323324

324325
enum class ParseEffectsMode {
325326
argumentEffectsFromSource,

include/swift/SIL/SILBridgingImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,11 @@ void BridgedFunction::setNeedStackProtection(bool needSP) const {
529529
getFunction()->setNeedStackProtection(needSP);
530530
}
531531

532+
bool BridgedFunction::isResilientNominalDecl(BridgedNominalTypeDecl decl) const {
533+
return decl.unbridged()->isResilient(getFunction()->getModule().getSwiftModule(),
534+
getFunction()->getResilienceExpansion());
535+
}
536+
532537

533538
//===----------------------------------------------------------------------===//
534539
// BridgedGlobalVar

0 commit comments

Comments
 (0)