@@ -270,8 +270,6 @@ static bool canZapInstruction(SILInstruction *Inst, bool acceptRefCountInsts,
270
270
// If we see a store here, we have already checked that we are storing into
271
271
// the pointer before we added it to the worklist, so we can skip it.
272
272
if (auto *store = dyn_cast<StoreInst>(Inst)) {
273
- // TODO: when we have OSSA, we can also accept stores of non trivial values:
274
- // just replace the store with a destroy_value.
275
273
return !onlyAcceptTrivialStores ||
276
274
store->getSrc ()->getType ().isTrivial (*store->getFunction ());
277
275
}
@@ -397,7 +395,6 @@ hasUnremovableUsers(SILInstruction *allocation, UserList *Users,
397
395
LLVM_DEBUG (llvm::dbgs () << " Already seen skipping...\n " );
398
396
continue ;
399
397
}
400
-
401
398
if (auto *rea = dyn_cast<RefElementAddrInst>(I)) {
402
399
if (!rea->getType ().isTrivial (*rea->getFunction ()))
403
400
refElementAddrs.push_back (rea);
@@ -751,10 +748,11 @@ class DeadObjectElimination : public SILFunctionTransform {
751
748
DeadEndBlocks DEBlocks (&Fn);
752
749
DestructorAnalysisCache.clear ();
753
750
751
+ LLVM_DEBUG (llvm::dbgs () << " Processing " << Fn.getName () << " \n " );
752
+
754
753
bool Changed = false ;
755
754
756
755
for (auto &BB : Fn) {
757
-
758
756
for (SILInstruction &inst : BB.deletableInstructions ()) {
759
757
if (auto *A = dyn_cast<AllocRefInstBase>(&inst))
760
758
Changed |= processAllocRef (A);
@@ -773,10 +771,6 @@ class DeadObjectElimination : public SILFunctionTransform {
773
771
}
774
772
775
773
void run () override {
776
- // FIXME: We should support ownership eventually.
777
- if (getFunction ()->hasOwnership ())
778
- return ;
779
-
780
774
assert (!domInfo);
781
775
782
776
if (processFunction (*getFunction ())) {
@@ -859,13 +853,28 @@ bool DeadObjectElimination::processAllocRef(AllocRefInstBase *ARI) {
859
853
bool DeadObjectElimination::processAllocStack (AllocStackInst *ASI) {
860
854
// Trivial types don't have destructors.
861
855
bool isTrivialType = ASI->getElementType ().isTrivial (*ASI->getFunction ());
856
+ // In non-ossa, only accept trivial stores if we have a non-trivial
857
+ // alloc_stack
858
+ bool onlyAcceptTrivialStores =
859
+ ASI->getFunction ()->hasOwnership () ? false : !isTrivialType;
862
860
UserList UsersToRemove;
863
- if (hasUnremovableUsers (ASI, &UsersToRemove, /* acceptRefCountInsts=*/ true ,
864
- /* onlyAcceptTrivialStores*/ !isTrivialType )) {
861
+ if (hasUnremovableUsers (ASI, &UsersToRemove, /* acceptRefCountInsts=*/ true ,
862
+ onlyAcceptTrivialStores)) {
865
863
LLVM_DEBUG (llvm::dbgs () << " Found a use that cannot be zapped...\n " );
866
864
return false ;
867
865
}
868
866
867
+ if (ASI->getFunction ()->hasOwnership ()) {
868
+ for (auto *user : UsersToRemove) {
869
+ auto *store = dyn_cast<StoreInst>(user);
870
+ if (!store ||
871
+ store->getOwnershipQualifier () == StoreOwnershipQualifier::Trivial)
872
+ continue ;
873
+ SILBuilderWithScope (store).createDestroyValue (store->getLoc (),
874
+ store->getSrc ());
875
+ }
876
+ }
877
+
869
878
// Remove the AllocRef and all of its users.
870
879
removeInstructions (
871
880
ArrayRef<SILInstruction*>(UsersToRemove.begin (), UsersToRemove.end ()));
0 commit comments