mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Insert end_borrow for dead phi operands only when required
DCE inserts end_borrow at phi operands when a guaranteed phi becomes dead. This should be done for reborrows which end the lifetime of the incoming value. The existing check was not accurate and ended up inserting end_borrow for forwarded values as well. Fixes rdar://139283745
This commit is contained in:
@@ -187,9 +187,8 @@ class DCE {
|
||||
llvm::SmallPtrSetImpl<SILBasicBlock *> &);
|
||||
SILBasicBlock *nearestUsefulPostDominator(SILBasicBlock *Block);
|
||||
void replaceBranchWithJump(SILInstruction *Inst, SILBasicBlock *Block);
|
||||
/// If \p value is live, insert a lifetime ending operation in ossa.
|
||||
/// destroy_value for @owned value and end_borrow for a @guaranteed value.
|
||||
void endLifetimeOfLiveValue(SILValue value, SILInstruction *insertPt);
|
||||
/// Insert lifetime ending instruction if defining value of \p op is live.
|
||||
void endLifetimeOfLiveValue(Operand *op, SILInstruction *insertPt);
|
||||
|
||||
public:
|
||||
DCE(SILFunction *F, PostDominanceInfo *PDT)
|
||||
@@ -585,7 +584,8 @@ void DCE::replaceBranchWithJump(SILInstruction *Inst, SILBasicBlock *Block) {
|
||||
(void)Branch;
|
||||
}
|
||||
|
||||
void DCE::endLifetimeOfLiveValue(SILValue value, SILInstruction *insertPt) {
|
||||
void DCE::endLifetimeOfLiveValue(Operand *op, SILInstruction *insertPt) {
|
||||
auto value = op->get();
|
||||
if (SILInstruction *inst = value->getDefiningInstruction()) {
|
||||
if (!LiveInstructions.contains(inst))
|
||||
return;
|
||||
@@ -593,15 +593,15 @@ void DCE::endLifetimeOfLiveValue(SILValue value, SILInstruction *insertPt) {
|
||||
if (!LiveArguments.contains(arg))
|
||||
return;
|
||||
}
|
||||
|
||||
assert(op->isLifetimeEnding());
|
||||
SILBuilderWithScope builder(insertPt);
|
||||
if (value->getOwnershipKind() == OwnershipKind::Owned) {
|
||||
builder.emitDestroyOperation(RegularLocation::getAutoGeneratedLocation(),
|
||||
value);
|
||||
builder.createDestroyValue(RegularLocation::getAutoGeneratedLocation(),
|
||||
value);
|
||||
}
|
||||
BorrowedValue borrow(lookThroughBorrowedFromDef(value));
|
||||
if (borrow && borrow.isLocalScope()) {
|
||||
builder.emitEndBorrowOperation(RegularLocation::getAutoGeneratedLocation(),
|
||||
value);
|
||||
if (value->getOwnershipKind() == OwnershipKind::Guaranteed) {
|
||||
builder.createEndBorrow(RegularLocation::getAutoGeneratedLocation(), value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,7 +657,7 @@ bool DCE::removeDead() {
|
||||
for (auto *pred : BB.getPredecessorBlocks()) {
|
||||
auto *predTerm = pred->getTerminator();
|
||||
SILInstruction *insertPt = predTerm;
|
||||
if (phiArg->getOwnershipKind() == OwnershipKind::Guaranteed) {
|
||||
if (phiArg->isReborrow()) {
|
||||
// If the phiArg is dead and had reborrow dependencies, its baseValue
|
||||
// may also have been dead and a destroy_value of its baseValue may
|
||||
// have been inserted before the pred's terminator. Make sure to
|
||||
@@ -677,8 +677,10 @@ bool DCE::removeDead() {
|
||||
insertPt = &predInst;
|
||||
}
|
||||
}
|
||||
|
||||
endLifetimeOfLiveValue(phiArg->getIncomingPhiValue(pred), insertPt);
|
||||
auto *predOp = phiArg->getIncomingPhiOperand(pred);
|
||||
if (predOp->isLifetimeEnding()) {
|
||||
endLifetimeOfLiveValue(predOp, insertPt);
|
||||
}
|
||||
}
|
||||
erasePhiArgument(&BB, i, /*cleanupDeadPhiOps=*/true,
|
||||
InstModCallbacks().onCreateNewInst(
|
||||
@@ -702,7 +704,7 @@ bool DCE::removeDead() {
|
||||
|
||||
for (auto &op : termInst->getAllOperands()) {
|
||||
if (op.isLifetimeEnding()) {
|
||||
endLifetimeOfLiveValue(op.get(), termInst);
|
||||
endLifetimeOfLiveValue(&op, termInst);
|
||||
}
|
||||
}
|
||||
LLVM_DEBUG(llvm::dbgs() << "Replacing branch: ");
|
||||
@@ -725,7 +727,7 @@ bool DCE::removeDead() {
|
||||
if (F->hasOwnership()) {
|
||||
for (auto &Op : Inst->getAllOperands()) {
|
||||
if (Op.isLifetimeEnding()) {
|
||||
endLifetimeOfLiveValue(Op.get(), Inst);
|
||||
endLifetimeOfLiveValue(&Op, Inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user