@@ -39,28 +39,25 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
39
39
return true
40
40
}
41
41
42
- let result : Bool
43
42
if type. nominal. hasValueDeinit && !destroy. shouldDropDeinit {
44
43
guard let deinitFunc = context. lookupDeinit ( ofNominal: type. nominal) else {
45
44
return false
46
45
}
47
46
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
61
49
}
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
64
61
}
65
62
66
63
// Used to dispatch devirtualization tasks to `destroy_value` and `destroy_addr`.
@@ -79,6 +76,10 @@ private extension DevirtualizableDestroy {
79
76
guard let cases = type. getEnumCases ( in: parentFunction) else {
80
77
return false
81
78
}
79
+ defer {
80
+ context. erase ( instruction: self )
81
+ }
82
+
82
83
if cases. allPayloadsAreTrivial ( in: parentFunction) {
83
84
let builder = Builder ( before: self , context)
84
85
builder. createEndLifetime ( of: operand. value)
@@ -122,11 +123,15 @@ extension DestroyValueInst : DevirtualizableDestroy {
122
123
}
123
124
124
125
fileprivate func devirtualizeStructFields( _ context: some MutatingContext ) -> Bool {
125
- let builder = Builder ( before: self , context)
126
-
127
126
guard let fields = type. getNominalFields ( in: parentFunction) else {
128
127
return false
129
128
}
129
+
130
+ defer {
131
+ context. erase ( instruction: self )
132
+ }
133
+
134
+ let builder = Builder ( before: self , context)
130
135
if fields. allFieldsAreTrivial ( in: parentFunction) {
131
136
builder. createEndLifetime ( of: operand. value)
132
137
return true
@@ -193,6 +198,9 @@ extension DestroyAddrInst : DevirtualizableDestroy {
193
198
guard let fields = type. getNominalFields ( in: parentFunction) else {
194
199
return false
195
200
}
201
+ defer {
202
+ context. erase ( instruction: self )
203
+ }
196
204
if fields. allFieldsAreTrivial ( in: parentFunction) {
197
205
builder. createEndLifetime ( of: operand. value)
198
206
return true
0 commit comments