@@ -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- }
0 commit comments