Skip to content

Commit a1695bc

Browse files
committed
[SILCombine] Keep lexical destroys post cond_fails
Such destroys are part of the lifetime of lexical values inserted to prevent shortening lifetimes over deinit baarriers by CanonicalizeOSSALifetime. After OSSALifetimeCompletion is enabled, more instructions will need to be preserved.
1 parent aa629cc commit a1695bc

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -836,17 +836,47 @@ SILInstruction *SILCombiner::visitCondFailInst(CondFailInst *CFI) {
836836
if (!I->getValue().getBoolValue())
837837
return eraseInstFromFunction(*CFI);
838838

839-
// Remove any code that follows a (cond_fail 1) and set the block's
840-
// terminator to unreachable.
839+
// Remove non-lifetime-ending code that follows a (cond_fail 1) and set the
840+
// block's terminator to unreachable.
841841

842-
// Nothing more to do here
842+
// Are there instructions after this point to delete?
843+
844+
// First check if the next instruction is unreachable.
843845
if (isa<UnreachableInst>(std::next(SILBasicBlock::iterator(CFI))))
844846
return nullptr;
845847

846-
// Collect together all the instructions after this point
848+
// Otherwise, check if the only instructions are unreachables and destroys of
849+
// lexical values.
850+
851+
// Collect all instructions and, in OSSA, the values they define.
847852
llvm::SmallVector<SILInstruction *, 32> ToRemove;
848-
for (auto Inst = CFI->getParent()->rbegin(); &*Inst != CFI; ++Inst)
849-
ToRemove.push_back(&*Inst);
853+
ValueSet DefinedValues(CFI->getFunction());
854+
for (auto Iter = std::next(CFI->getIterator());
855+
Iter != CFI->getParent()->end(); ++Iter) {
856+
if (!CFI->getFunction()->hasOwnership()) {
857+
ToRemove.push_back(&*Iter);
858+
continue;
859+
}
860+
861+
for (auto result : Iter->getResults()) {
862+
DefinedValues.insert(result);
863+
}
864+
// Look for destroys of lexical values whose def isn't after the cond_fail.
865+
if (auto *dvi = dyn_cast<DestroyValueInst>(&*Iter)) {
866+
auto value = dvi->getOperand();
867+
if (!DefinedValues.contains(value) && value->isLexical())
868+
continue;
869+
}
870+
ToRemove.push_back(&*Iter);
871+
}
872+
873+
unsigned instructionsToDelete = ToRemove.size();
874+
// If the last instruction is an unreachable already, it needn't be deleted.
875+
if (isa<UnreachableInst>(ToRemove.back())) {
876+
--instructionsToDelete;
877+
}
878+
if (instructionsToDelete == 0)
879+
return nullptr;
850880

851881
for (auto *Inst : ToRemove) {
852882
// Replace any still-remaining uses with undef and erase.

0 commit comments

Comments
 (0)