DeadObjectElimination: handle objects for which the destructor is de-virtualized and inlined

Also: add an additional DeadObjectElimination pass in the low level pipeline because
redundant load elimination (which runs before) can turn an object into a dead object.
This commit is contained in:
Erik Eckstein
2018-01-17 13:51:56 -08:00
parent 44aafd950c
commit 80a734ab30
5 changed files with 34 additions and 14 deletions

View File

@@ -193,11 +193,16 @@ removeInstructions(ArrayRef<SILInstruction*> UsersToRemove) {
/// Returns false if Inst is an instruction that would require us to keep the
/// alloc_ref alive.
static bool canZapInstruction(SILInstruction *Inst) {
static bool canZapInstruction(SILInstruction *Inst, bool acceptRefCountInsts) {
if (isa<SetDeallocatingInst>(Inst) || isa<FixLifetimeInst>(Inst))
return true;
// It is ok to eliminate various retains/releases. We are either removing
// everything or nothing.
if (isa<RefCountingInst>(Inst) || isa<StrongPinInst>(Inst))
return true;
if (isa<RefCountingInst>(Inst) || isa<StrongPinInst>(Inst) ||
// dealloc_partial_ref invokes releases implicitly
isa<DeallocPartialRefInst>(Inst))
return acceptRefCountInsts;
// If we see a store here, we have already checked that we are storing into
// the pointer before we added it to the worklist, so we can skip it.
@@ -227,7 +232,8 @@ static bool canZapInstruction(SILInstruction *Inst) {
/// Analyze the use graph of AllocRef for any uses that would prevent us from
/// zapping it completely.
static bool
hasUnremovableUsers(SILInstruction *AllocRef, UserList &Users) {
hasUnremovableUsers(SILInstruction *AllocRef, UserList &Users,
bool acceptRefCountInsts) {
SmallVector<SILInstruction *, 16> Worklist;
Worklist.push_back(AllocRef);
@@ -246,7 +252,7 @@ hasUnremovableUsers(SILInstruction *AllocRef, UserList &Users) {
}
// If we can't zap this instruction... bail...
if (!canZapInstruction(I)) {
if (!canZapInstruction(I, acceptRefCountInsts)) {
DEBUG(llvm::dbgs() << " Found instruction we can't zap...\n");
return true;
}
@@ -695,15 +701,11 @@ bool DeadObjectElimination::processAllocRef(AllocRefInst *ARI) {
DestructorAnalysisCache[Type] = HasSideEffects;
}
if (HasSideEffects) {
DEBUG(llvm::dbgs() << " Destructor had side effects. \n");
return false;
}
// Our destructor has no side effects, so if we can prove that no loads
// escape, then we can completely remove the use graph of this alloc_ref.
UserList UsersToRemove;
if (hasUnremovableUsers(ARI, UsersToRemove)) {
if (hasUnremovableUsers(ARI, UsersToRemove,
/*acceptRefCountInsts=*/ !HasSideEffects)) {
DEBUG(llvm::dbgs() << " Found a use that cannot be zapped...\n");
return false;
}
@@ -723,7 +725,7 @@ bool DeadObjectElimination::processAllocStack(AllocStackInst *ASI) {
return false;
UserList UsersToRemove;
if (hasUnremovableUsers(ASI, UsersToRemove)) {
if (hasUnremovableUsers(ASI, UsersToRemove, /*acceptRefCountInsts=*/ true)) {
DEBUG(llvm::dbgs() << " Found a use that cannot be zapped...\n");
return false;
}