Skip to content

Commit 41697b0

Browse files
committed
DeadObjectElimination: Handle non-trivial stores while processing alloc_stack
1 parent 7020cf3 commit 41697b0

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

lib/SILOptimizer/Transforms/DeadObjectElimination.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,6 @@ static bool canZapInstruction(SILInstruction *Inst, bool acceptRefCountInsts,
270270
// If we see a store here, we have already checked that we are storing into
271271
// the pointer before we added it to the worklist, so we can skip it.
272272
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.
275273
return !onlyAcceptTrivialStores ||
276274
store->getSrc()->getType().isTrivial(*store->getFunction());
277275
}
@@ -397,7 +395,6 @@ hasUnremovableUsers(SILInstruction *allocation, UserList *Users,
397395
LLVM_DEBUG(llvm::dbgs() << " Already seen skipping...\n");
398396
continue;
399397
}
400-
401398
if (auto *rea = dyn_cast<RefElementAddrInst>(I)) {
402399
if (!rea->getType().isTrivial(*rea->getFunction()))
403400
refElementAddrs.push_back(rea);
@@ -751,10 +748,11 @@ class DeadObjectElimination : public SILFunctionTransform {
751748
DeadEndBlocks DEBlocks(&Fn);
752749
DestructorAnalysisCache.clear();
753750

751+
LLVM_DEBUG(llvm::dbgs() << "Processing " << Fn.getName() << "\n");
752+
754753
bool Changed = false;
755754

756755
for (auto &BB : Fn) {
757-
758756
for (SILInstruction &inst : BB.deletableInstructions()) {
759757
if (auto *A = dyn_cast<AllocRefInstBase>(&inst))
760758
Changed |= processAllocRef(A);
@@ -773,10 +771,6 @@ class DeadObjectElimination : public SILFunctionTransform {
773771
}
774772

775773
void run() override {
776-
// FIXME: We should support ownership eventually.
777-
if (getFunction()->hasOwnership())
778-
return;
779-
780774
assert(!domInfo);
781775

782776
if (processFunction(*getFunction())) {
@@ -859,13 +853,28 @@ bool DeadObjectElimination::processAllocRef(AllocRefInstBase *ARI) {
859853
bool DeadObjectElimination::processAllocStack(AllocStackInst *ASI) {
860854
// Trivial types don't have destructors.
861855
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;
862860
UserList UsersToRemove;
863-
if (hasUnremovableUsers(ASI, &UsersToRemove, /*acceptRefCountInsts=*/ true,
864-
/*onlyAcceptTrivialStores*/!isTrivialType)) {
861+
if (hasUnremovableUsers(ASI, &UsersToRemove, /*acceptRefCountInsts=*/true,
862+
onlyAcceptTrivialStores)) {
865863
LLVM_DEBUG(llvm::dbgs() << " Found a use that cannot be zapped...\n");
866864
return false;
867865
}
868866

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+
869878
// Remove the AllocRef and all of its users.
870879
removeInstructions(
871880
ArrayRef<SILInstruction*>(UsersToRemove.begin(), UsersToRemove.end()));

0 commit comments

Comments
 (0)