Skip to content

Commit 586f8a4

Browse files
committed
Revert "InitializeStaticGlobals: support non-loadable enums"
This reverts commit eaf38da. rdar://160143339
1 parent b396bd0 commit 586f8a4

File tree

3 files changed

+16
-220
lines changed

3 files changed

+16
-220
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/InitializeStaticGlobals.swift

Lines changed: 16 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,8 @@ private indirect enum GlobalInitValue {
8080
// For example, a struct or vector which is initialized by storing its elements.
8181
case aggregate([GlobalInitValue])
8282

83-
// An enum case without a payload of an address-only enum.
84-
case enumCase(caseIndex: Int)
85-
86-
// An enum case which is not a SIL "constant", e.g. because it's address-only
87-
case enumCaseWithPayload(caseIndex: Int, payload: GlobalInitValue)
83+
// An enum with a payload which is not a SIL "constant".
84+
case enumCase(caseIndex: Int, payload: GlobalInitValue)
8885

8986
init?(of globalInitFunction: Function, _ context: FunctionPassContext) {
9087
self = .undefined
@@ -136,44 +133,20 @@ private indirect enum GlobalInitValue {
136133
self = builder.initValue
137134
}
138135

139-
enum InitValue {
140-
// The common case
141-
case value(Value)
142-
143-
// For payload-less cases of address-only enums. Such cases are initialized purely with an `inject_enum_addr`,
144-
// and we don't have a `Value` which represents the resulting enum(-case).
145-
case enumCaseWithoutPayload(InjectEnumAddrInst)
146-
147-
var parentFunction: Function {
148-
switch self {
149-
case .value(let value): return value.parentFunction
150-
case .enumCaseWithoutPayload(let iea): return iea.parentFunction
151-
}
152-
}
153-
}
154-
155136
// Sets an element in the constant tree.
156137
// Returns true if this was successful. One reason for being not successful is if a certain
157138
// element is set twice, i.e. does not have a single defined value.
158-
mutating func setElement(to value: InitValue, at path: SmallProjectionPath, type: Type) -> Bool {
139+
mutating func setElement(to value: Value, at path: SmallProjectionPath, type: Type) -> Bool {
159140
let (kind, index, subPath) = path.pop()
160141
switch kind {
161142
case .root:
162143
guard case .undefined = self else {
163144
// The element was set twice.
164145
return false
165146
}
166-
switch value {
167-
case .value(let value):
168-
self = .constant(value)
169-
case .enumCaseWithoutPayload:
170-
fatalError("should have been handled in the .enumCase of the SmallProjectionPath below")
171-
}
147+
self = .constant(value)
172148
return true
173149

174-
case .enumCase:
175-
return setEnumCase(to: value, at: subPath, index: index, type: type)
176-
177150
case .structField:
178151
guard let structFields = type.getNominalFields(in: value.parentFunction) else {
179152
return false
@@ -213,7 +186,7 @@ private indirect enum GlobalInitValue {
213186
}
214187

215188
private mutating func setField(
216-
to value: InitValue, at path: SmallProjectionPath,
189+
to value: Value, at path: SmallProjectionPath,
217190
index: Int, type: Type, numFields: Int
218191
) -> Bool {
219192
if case .undefined = self {
@@ -232,43 +205,6 @@ private indirect enum GlobalInitValue {
232205
return false
233206
}
234207

235-
private mutating func setEnumCase(to value: InitValue, at path: SmallProjectionPath, index: Int, type: Type) -> Bool {
236-
switch value {
237-
238-
case .enumCaseWithoutPayload(let iea):
239-
guard case .undefined = self else {
240-
// The enum was set twice.
241-
return false
242-
}
243-
assert(index == iea.caseIndex)
244-
self = .enumCase(caseIndex: index)
245-
246-
case .value:
247-
guard let payloadType = type.getEnumCases(in: value.parentFunction)!.getPayloadType(ofCaseIndex: index) else {
248-
return false
249-
}
250-
switch self {
251-
case .undefined:
252-
// It's the first time we set the payload or a sub-field of it.
253-
var payload = GlobalInitValue.undefined
254-
if !payload.setElement(to: value, at: path, type: payloadType) {
255-
return false
256-
}
257-
self = .enumCaseWithPayload(caseIndex: index, payload: payload)
258-
case .enumCaseWithPayload(let existingIndex, var payload) where index == existingIndex:
259-
// Some sub-field of the enum-payload was already set.
260-
self = .undefined // avoid copy-on-write
261-
if !payload.setElement(to: value, at: path, type: payloadType) {
262-
return false
263-
}
264-
self = .enumCaseWithPayload(caseIndex: index, payload: payload)
265-
default:
266-
return false
267-
}
268-
}
269-
return true
270-
}
271-
272208
/// Creates SIL for this global init value in the initializer of the `global`.
273209
func materialize(into global: GlobalVariable, from function: Function, _ context: FunctionPassContext) {
274210
var cloner = Cloner(cloneToGlobal: global, context)
@@ -312,11 +248,8 @@ private indirect enum GlobalInitValue {
312248
}
313249
return builder.createVector(type: type, arguments: elementValues)
314250

315-
case .enumCase(let caseIndex):
316-
return builder.createEnum(caseIndex: caseIndex, payload: nil, enumType: type)
317-
318-
case .enumCaseWithPayload(let caseIndex, let payload):
319-
let payloadType = type.getEnumCases(in: function)!.getPayloadType(ofCaseIndex: caseIndex)!
251+
case .enumCase(let caseIndex, let payload):
252+
let payloadType = type.getEnumCases(in: function)!.first(where: { $0.index == caseIndex })!.payload!
320253
let payloadValue = payload.materializeRecursively(type: payloadType, &cloner, builder, function)
321254
return builder.createEnum(caseIndex: caseIndex, payload: payloadValue, enumType: type)
322255
}
@@ -339,7 +272,7 @@ private indirect enum GlobalInitValue {
339272
_ context: FunctionPassContext
340273
) {
341274
switch self {
342-
case .undefined, .enumCase:
275+
case .undefined:
343276
break
344277
case .constant(let value):
345278
if value.containsLoad(context) {
@@ -348,7 +281,7 @@ private indirect enum GlobalInitValue {
348281
self = .aggregate((value as! Instruction).operands.lazy.map { .constant($0.value) })
349282
resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context)
350283
case let ei as EnumInst:
351-
self = .enumCaseWithPayload(caseIndex: ei.caseIndex, payload: .constant(ei.payload!))
284+
self = .enumCase(caseIndex: ei.caseIndex, payload: .constant(ei.payload!))
352285
resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context)
353286
case let li as LoadInst:
354287
guard let allocStack = li.address as? AllocStackInst,
@@ -373,9 +306,10 @@ private indirect enum GlobalInitValue {
373306
newFields[i].resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context)
374307
}
375308
self = .aggregate(newFields)
376-
case .enumCaseWithPayload(let caseIndex, var payload):
377-
payload.resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context)
378-
self = .enumCaseWithPayload(caseIndex: caseIndex, payload: payload)
309+
case .enumCase(let caseIndex, let payload):
310+
var newPayload = payload
311+
newPayload.resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context)
312+
self = .enumCase(caseIndex: caseIndex, payload: newPayload)
379313
}
380314
}
381315

@@ -387,9 +321,7 @@ private indirect enum GlobalInitValue {
387321
return value.isValidGlobalInitValue(context)
388322
case .aggregate(let fields):
389323
return fields.allSatisfy { $0.isValid(context) }
390-
case .enumCase:
391-
return true
392-
case .enumCaseWithPayload(_, let payload):
324+
case .enumCase(_, let payload):
393325
return payload.isValid(context)
394326
}
395327
}
@@ -429,7 +361,7 @@ private struct InitValueBuilder: AddressDefUseWalker {
429361
let accessPath = store.destination.lookThroughRawLayoutAddress.constantAccessPath
430362
switch accessPath.base {
431363
case .global, .stack:
432-
if !initValue.setElement(to: .value(store.source), at: accessPath.projectionPath, type: originalAddress.type) {
364+
if !initValue.setElement(to: store.source, at: accessPath.projectionPath, type: originalAddress.type) {
433365
return .abortWalk
434366
}
435367
return .continueWalk
@@ -444,35 +376,13 @@ private struct InitValueBuilder: AddressDefUseWalker {
444376
return .abortWalk
445377
}
446378
// The `nonConstAccessPath` now contains a single `.anyIndexedElement`.
447-
if !initValue.setElement(to: .value(store.source), at: nonConstAccessPath.projectionPath, type: originalAddress.type) {
379+
if !initValue.setElement(to: store.source, at: nonConstAccessPath.projectionPath, type: originalAddress.type) {
448380
return .abortWalk
449381
}
450382
return .continueWalk
451383
default:
452384
fatalError("could not compute access path")
453385
}
454-
case let injectEnum as InjectEnumAddrInst:
455-
if injectEnum.element.hasAssociatedValues {
456-
if !injectEnum.operand.value.type.isLoadable(in: injectEnum.parentFunction) {
457-
// TODO: we don't support non-loadable enum cases with payload yet, because IRGen support is missing.
458-
// e.g. `var global: Atomic<Int>? = Atomic<Int>(0)`
459-
// FixedTypeInfo (= used for non-loadable types) is missing the ability to pack a payload into an enum.
460-
return .abortWalk
461-
}
462-
return .continueWalk
463-
}
464-
let accessPath = injectEnum.enum.getAccessPath(fromInitialPath: SmallProjectionPath(.enumCase,
465-
index: injectEnum.caseIndex))
466-
switch accessPath.base {
467-
case .global, .stack:
468-
if !initValue.setElement(to: .enumCaseWithoutPayload(injectEnum), at: accessPath.projectionPath, type: originalAddress.type) {
469-
return .abortWalk
470-
}
471-
return .continueWalk
472-
default:
473-
return .abortWalk
474-
}
475-
476386
case is LoadInst, is DeallocStackInst:
477387
return .continueWalk
478388
case let bi as BuiltinInst:
@@ -567,8 +477,6 @@ private extension Function {
567477
return false
568478
case let store as StoreInst:
569479
return !store.destination.lookThroughRawLayoutAddress.isAddressOfStack(orGlobal: global)
570-
case let injectEnum as InjectEnumAddrInst:
571-
return !injectEnum.enum.isAddressOfStack(orGlobal: global)
572480
case let bi as BuiltinInst where bi.id == .PrepareInitialization:
573481
return false
574482
default:
@@ -625,9 +533,3 @@ private extension Value {
625533
return self
626534
}
627535
}
628-
629-
private extension EnumCases {
630-
func getPayloadType(ofCaseIndex caseIndex: Int) -> Type? {
631-
return first(where: { $0.index == caseIndex })!.payload
632-
}
633-
}

test/SILOptimizer/init_static_globals.sil

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -168,21 +168,6 @@ sil_global [let] @graw2: $Raw
168168
// CHECK-LABEL: sil_global [let] @grawArray : $RawArray{{$}}
169169
sil_global [let] @grawArray: $RawArray
170170

171-
// CHECK-LABEL: sil_global [let] @gIndirectNone : $Optional<TwoFields> = {
172-
// CHECK-NEXT: %initval = enum $Optional<TwoFields>, #Optional.none!enumelt
173-
// CHECK-NEXT: }
174-
sil_global [let] @gIndirectNone: $Optional<TwoFields>
175-
176-
// CHECK-LABEL: sil_global [let] @gIndirectSome : $Optional<TwoFields> = {
177-
// CHECK-NEXT: %0 = integer_literal $Builtin.Int32, 11
178-
// CHECK-NEXT: %1 = struct $Int32 (%0)
179-
// CHECK-NEXT: %2 = integer_literal $Builtin.Int32, 10
180-
// CHECK-NEXT: %3 = struct $Int32 (%2)
181-
// CHECK-NEXT: %4 = struct $TwoFields (%1, %3)
182-
// CHECK-NEXT: %initval = enum $Optional<TwoFields>, #Optional.some!enumelt, %4
183-
// CHECK-NEXT: }
184-
sil_global [let] @gIndirectSome: $Optional<TwoFields>
185-
186171
sil @unknownfunc : $@convention(thin) () -> ()
187172

188173
// CHECK-LABEL: sil [global_init_once_fn] [ossa] @globalinit_trivialglobal_func :
@@ -594,29 +579,3 @@ bb0(%0 : $Builtin.RawPointer):
594579
return %21
595580
}
596581

597-
sil [global_init_once_fn] [ossa] @globalinit_indirect_none: $@convention(c) (Builtin.RawPointer) -> () {
598-
bb0(%0 : $Builtin.RawPointer):
599-
alloc_global @gIndirectNone
600-
%2 = global_addr @gIndirectNone : $*Optional<TwoFields>
601-
inject_enum_addr %2, #Optional.none!enumelt
602-
%21 = tuple ()
603-
return %21
604-
}
605-
606-
sil [global_init_once_fn] [ossa] @globalinit_indirect_some : $@convention(c) () -> () {
607-
bb0:
608-
alloc_global @gIndirectSome
609-
%1 = global_addr @gIndirectSome : $*Optional<TwoFields>
610-
%2 = init_enum_data_addr %1, #Optional.some!enumelt
611-
%3 = integer_literal $Builtin.Int32, 10
612-
%4 = struct $Int32 (%3)
613-
%5 = struct_element_addr %2, #TwoFields.b
614-
store %4 to [trivial] %5
615-
%7 = integer_literal $Builtin.Int32, 11
616-
%8 = struct $Int32 (%7)
617-
%9 = struct_element_addr %2, #TwoFields.a
618-
store %8 to [trivial] %9
619-
%10 = tuple ()
620-
return %10 : $()
621-
}
622-

test/SILOptimizer/static_atomics.swift

Lines changed: 0 additions & 65 deletions
This file was deleted.

0 commit comments

Comments
 (0)