@@ -193,7 +193,8 @@ removeInstructions(ArrayRef<SILInstruction*> UsersToRemove) {
193
193
194
194
// / Returns false if Inst is an instruction that would require us to keep the
195
195
// / alloc_ref alive.
196
- static bool canZapInstruction (SILInstruction *Inst, bool acceptRefCountInsts) {
196
+ static bool canZapInstruction (SILInstruction *Inst, bool acceptRefCountInsts,
197
+ bool onlyAcceptTrivialStores) {
197
198
if (isa<SetDeallocatingInst>(Inst) || isa<FixLifetimeInst>(Inst))
198
199
return true ;
199
200
@@ -204,6 +205,24 @@ static bool canZapInstruction(SILInstruction *Inst, bool acceptRefCountInsts) {
204
205
isa<DeallocPartialRefInst>(Inst))
205
206
return acceptRefCountInsts;
206
207
208
+ if (isa<InjectEnumAddrInst>(Inst))
209
+ return true ;
210
+
211
+ // We know that the destructor has no side effects so we can remove the
212
+ // deallocation instruction too.
213
+ if (isa<DeallocationInst>(Inst) || isa<AllocationInst>(Inst))
214
+ return true ;
215
+
216
+ // Much like deallocation, destroy addr is safe.
217
+ if (isa<DestroyAddrInst>(Inst))
218
+ return true ;
219
+
220
+ // The only store instructions which is guaranteed to store a trivial value
221
+ // is an inject_enum_addr witout a payload (i.e. without init_enum_data_addr).
222
+ // There can also be a 'store [trivial]', but we don't handle that yet.
223
+ if (onlyAcceptTrivialStores)
224
+ return false ;
225
+
207
226
// If we see a store here, we have already checked that we are storing into
208
227
// the pointer before we added it to the worklist, so we can skip it.
209
228
if (isa<StoreInst>(Inst))
@@ -215,15 +234,6 @@ static bool canZapInstruction(SILInstruction *Inst, bool acceptRefCountInsts) {
215
234
!isa<TermInst>(Inst))
216
235
return true ;
217
236
218
- // We know that the destructor has no side effects so we can remove the
219
- // deallocation instruction too.
220
- if (isa<DeallocationInst>(Inst))
221
- return true ;
222
-
223
- // Much like deallocation, destroy addr is safe.
224
- if (isa<DestroyAddrInst>(Inst))
225
- return true ;
226
-
227
237
// Otherwise we do not know how to handle this instruction. Be conservative
228
238
// and don't zap it.
229
239
return false ;
@@ -233,7 +243,7 @@ static bool canZapInstruction(SILInstruction *Inst, bool acceptRefCountInsts) {
233
243
// / zapping it completely.
234
244
static bool
235
245
hasUnremovableUsers (SILInstruction *AllocRef, UserList &Users,
236
- bool acceptRefCountInsts) {
246
+ bool acceptRefCountInsts, bool onlyAcceptTrivialStores ) {
237
247
SmallVector<SILInstruction *, 16 > Worklist;
238
248
Worklist.push_back (AllocRef);
239
249
@@ -252,7 +262,7 @@ hasUnremovableUsers(SILInstruction *AllocRef, UserList &Users,
252
262
}
253
263
254
264
// If we can't zap this instruction... bail...
255
- if (!canZapInstruction (I, acceptRefCountInsts)) {
265
+ if (!canZapInstruction (I, acceptRefCountInsts, onlyAcceptTrivialStores )) {
256
266
LLVM_DEBUG (llvm::dbgs () << " Found instruction we can't zap...\n " );
257
267
return true ;
258
268
}
@@ -701,7 +711,8 @@ bool DeadObjectElimination::processAllocRef(AllocRefInst *ARI) {
701
711
// escape, then we can completely remove the use graph of this alloc_ref.
702
712
UserList UsersToRemove;
703
713
if (hasUnremovableUsers (ARI, UsersToRemove,
704
- /* acceptRefCountInsts=*/ !HasSideEffects)) {
714
+ /* acceptRefCountInsts=*/ !HasSideEffects,
715
+ /* onlyAcceptTrivialStores*/ false )) {
705
716
LLVM_DEBUG (llvm::dbgs () << " Found a use that cannot be zapped...\n " );
706
717
return false ;
707
718
}
@@ -716,12 +727,11 @@ bool DeadObjectElimination::processAllocRef(AllocRefInst *ARI) {
716
727
}
717
728
718
729
bool DeadObjectElimination::processAllocStack (AllocStackInst *ASI) {
719
- // Trivial types don't have destructors. Let's try to zap this AllocStackInst.
720
- if (!ASI->getElementType ().isTrivial (ASI->getModule ()))
721
- return false ;
722
-
730
+ // Trivial types don't have destructors.
731
+ bool isTrivialType = ASI->getElementType ().isTrivial (ASI->getModule ());
723
732
UserList UsersToRemove;
724
- if (hasUnremovableUsers (ASI, UsersToRemove, /* acceptRefCountInsts=*/ true )) {
733
+ if (hasUnremovableUsers (ASI, UsersToRemove, /* acceptRefCountInsts=*/ true ,
734
+ /* onlyAcceptTrivialStores*/ !isTrivialType)) {
725
735
LLVM_DEBUG (llvm::dbgs () << " Found a use that cannot be zapped...\n " );
726
736
return false ;
727
737
}
0 commit comments