@@ -39,28 +39,25 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
3939 return true
4040 }
4141
42- let result : Bool
4342 if type. nominal. hasValueDeinit && !destroy. shouldDropDeinit {
4443 guard let deinitFunc = context. lookupDeinit ( ofNominal: type. nominal) else {
4544 return false
4645 }
4746 destroy. createDeinitCall ( to: deinitFunc, context)
48- result = true
49- } else {
50- // If there is no deinit to be called for the original type we have to recursively visit
51- // the struct fields or enum cases.
52- if type. isStruct {
53- result = destroy. devirtualizeStructFields ( context)
54- } else if type. isEnum {
55- result = destroy. devirtualizeEnumPayloads ( context)
56- } else {
57- precondition ( type. isClass, " unknown non-copyable type " )
58- // A class reference cannot be further de-composed.
59- return true
60- }
47+ context. erase ( instruction: destroy)
48+ return true
6149 }
62- context. erase ( instruction: destroy)
63- return result
50+ // If there is no deinit to be called for the original type we have to recursively visit
51+ // the struct fields or enum cases.
52+ if type. isStruct {
53+ return destroy. devirtualizeStructFields ( context)
54+ }
55+ if type. isEnum {
56+ return destroy. devirtualizeEnumPayloads ( context)
57+ }
58+ precondition ( type. isClass, " unknown non-copyable type " )
59+ // A class reference cannot be further de-composed.
60+ return true
6461}
6562
6663// Used to dispatch devirtualization tasks to `destroy_value` and `destroy_addr`.
@@ -79,6 +76,10 @@ private extension DevirtualizableDestroy {
7976 guard let cases = type. getEnumCases ( in: parentFunction) else {
8077 return false
8178 }
79+ defer {
80+ context. erase ( instruction: self )
81+ }
82+
8283 if cases. allPayloadsAreTrivial ( in: parentFunction) {
8384 let builder = Builder ( before: self , context)
8485 builder. createEndLifetime ( of: operand. value)
@@ -122,11 +123,15 @@ extension DestroyValueInst : DevirtualizableDestroy {
122123 }
123124
124125 fileprivate func devirtualizeStructFields( _ context: some MutatingContext ) -> Bool {
125- let builder = Builder ( before: self , context)
126-
127126 guard let fields = type. getNominalFields ( in: parentFunction) else {
128127 return false
129128 }
129+
130+ defer {
131+ context. erase ( instruction: self )
132+ }
133+
134+ let builder = Builder ( before: self , context)
130135 if fields. allFieldsAreTrivial ( in: parentFunction) {
131136 builder. createEndLifetime ( of: operand. value)
132137 return true
@@ -193,6 +198,9 @@ extension DestroyAddrInst : DevirtualizableDestroy {
193198 guard let fields = type. getNominalFields ( in: parentFunction) else {
194199 return false
195200 }
201+ defer {
202+ context. erase ( instruction: self )
203+ }
196204 if fields. allFieldsAreTrivial ( in: parentFunction) {
197205 builder. createEndLifetime ( of: operand. value)
198206 return true
0 commit comments