mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Update DCE for @guaranteed forwarding phi support
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user