Update DCE for @guaranteed forwarding phi support

This commit is contained in:
Meghana Gupta
2022-10-05 22:34:55 -07:00
parent 9b01b87b4b
commit 5ede08ca3c
2 changed files with 147 additions and 56 deletions

View File

@@ -50,7 +50,8 @@ static bool seemsUseful(SILInstruction *I) {
// side-effects, they can be DCE'ed if they do not have useful
// dependencies/reverse dependencies
if (isa<BeginAccessInst>(I) || isa<CopyValueInst>(I) ||
isa<DestroyValueInst>(I) || isa<EndLifetimeInst>(I))
isa<DestroyValueInst>(I) || isa<EndLifetimeInst>(I) ||
isa<EndBorrowInst>(I))
return false;
// A load [copy] is okay to be DCE'ed if there are no useful dependencies
@@ -125,13 +126,13 @@ class DCE {
llvm::DenseMap<SILValue, SmallPtrSet<SILInstruction *, 4>>
ReverseDependencies;
// reborrowDependencies tracks the dependency of a reborrowed phiArg with its
// renamed base value.
// A reborrowed phiArg may have a new base value, if it's original base value
// was also passed as a branch operand. The renamed base value should then be
// live if the reborrow phiArg was also live.
// guaranteedPhiDependencies tracks the dependency of reborrows and
// @guaranteed forwarding phis with its base value.
// If the base value is also passed along as a phi operand with the reborrow
// operand/GuaranteedForwardingPhi operand, we will have a new base value
// for the reborrow phi/@guaranteed forwarding phi.
using BaseValueSet = SmallPtrSet<SILValue, 8>;
llvm::DenseMap<SILPhiArgument *, BaseValueSet> reborrowDependencies;
llvm::DenseMap<SILPhiArgument *, BaseValueSet> guaranteedPhiDependencies;
/// Tracks if the pass changed branches.
bool BranchesChanged = false;
@@ -143,9 +144,9 @@ class DCE {
/// Record a reverse dependency from \p from to \p to meaning \p to is live
/// if \p from is also live.
void addReverseDependency(SILValue from, SILInstruction *to);
/// Starting from \p borrowInst find all reborrow dependency of its reborrows
/// with their renamed base values.
void findReborrowDependencies(BeginBorrowInst *borrowInst);
/// Starting from \p borrow find all reborrow and guaranteed phi dependencies
/// along with their base values.
void findGuaranteedPhiDependencies(BorrowedValue borrow);
bool removeDead();
void computeLevelNumbers(PostDomTreeNode *root);
@@ -288,7 +289,6 @@ void DCE::markLive() {
auto *borrowInst = cast<BeginBorrowInst>(&I);
if (borrowInst->getOperand()->getOwnershipKind() ==
OwnershipKind::Guaranteed) {
markInstructionLive(borrowInst);
// Visit the end_borrows of all the borrow scopes that this
// begin_borrow could be borrowing.
SmallVector<SILValue, 4> roots;
@@ -301,8 +301,8 @@ void DCE::markLive() {
}
continue;
}
// Populate reborrowDependencies for this borrow
findReborrowDependencies(borrowInst);
// Populate guaranteedPhiDependencies for this borrow
findGuaranteedPhiDependencies(BorrowedValue(borrowInst));
// Don't optimize a borrow scope if it is lexical or has a pointer
// escape.
if (borrowInst->isLexical() ||
@@ -315,6 +315,10 @@ void DCE::markLive() {
}
break;
}
case SILInstructionKind::LoadBorrowInst: {
findGuaranteedPhiDependencies(BorrowedValue(cast<LoadBorrowInst>(&I)));
break;
}
default:
if (seemsUseful(&I))
markInstructionLive(&I);
@@ -337,19 +341,23 @@ void DCE::addReverseDependency(SILValue from, SILInstruction *to) {
ReverseDependencies[from].insert(to);
}
void DCE::findReborrowDependencies(BeginBorrowInst *borrowInst) {
LLVM_DEBUG(llvm::dbgs() << "Finding reborrow dependencies of " << borrowInst
<< "\n");
BorrowingOperand initialScopedOperand(&borrowInst->getOperandRef());
auto visitReborrowBaseValuePair = [&](SILPhiArgument *phiArg,
SILValue baseValue) {
reborrowDependencies[phiArg].insert(baseValue);
void DCE::findGuaranteedPhiDependencies(BorrowedValue borrow) {
assert(borrow.kind == BorrowedValueKind::BeginBorrow ||
borrow.kind == BorrowedValueKind::LoadBorrow);
LLVM_DEBUG(llvm::dbgs() << "Finding @guaranteed phi dependencies of "
<< borrow << "\n");
auto visitDependentPhiBaseValuePair = [&](SILPhiArgument *phiArg,
SILValue baseValue) {
guaranteedPhiDependencies[phiArg].insert(baseValue);
};
// Find all reborrow dependencies starting from \p borrowInst and populate
// them in reborrowDependencies
findTransitiveReborrowBaseValuePairs(initialScopedOperand,
borrowInst->getOperand(),
visitReborrowBaseValuePair);
// Find all dependencies starting from \p borrowInst and populate
// them in guaranteedPhiDependencies
if (borrow.kind == BorrowedValueKind::BeginBorrow) {
visitExtendedReborrowPhiBaseValuePairs(cast<BeginBorrowInst>(borrow.value),
visitDependentPhiBaseValuePair);
}
visitExtendedGuaranteedForwardingPhiBaseValuePairs(
borrow, visitDependentPhiBaseValuePair);
}
// Mark as live the terminator argument at index ArgIndex in Pred that
@@ -429,7 +437,7 @@ void DCE::propagateLiveBlockArgument(SILArgument *Arg) {
}
if (auto *phi = dyn_cast<SILPhiArgument>(Arg)) {
for (auto depVal : reborrowDependencies.lookup(phi)) {
for (auto depVal : guaranteedPhiDependencies.lookup(phi)) {
markValueLive(depVal);
}
}