Skip to content

Commit 809e67c

Browse files
authored
Merge pull request #61776 from tshortli/break-cycle-extend-store-borrow
2 parents e3cd2ab + 4f8d33f commit 809e67c

File tree

5 files changed

+75
-72
lines changed

5 files changed

+75
-72
lines changed

include/swift/SIL/ScopedAddressUtils.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,6 @@ bool hasOtherStoreBorrowsInLifetime(StoreBorrowInst *sbi,
137137
SSAPrunedLiveness *liveness,
138138
DeadEndBlocks *deadEndBlocks);
139139

140-
/// Extend the store_borrow \p sbi's scope such that it encloses \p newUsers.
141-
bool extendStoreBorrow(StoreBorrowInst *sbi,
142-
SmallVectorImpl<Operand *> &newUses,
143-
DeadEndBlocks *deadEndBlocks,
144-
InstModCallbacks callbacks = InstModCallbacks());
145140
} // namespace swift
146141

147142
#endif

include/swift/SILOptimizer/Utils/OwnershipOptUtils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,12 @@ struct LoadOperation {
404404
}
405405
};
406406

407+
/// Extend the store_borrow \p sbi's scope such that it encloses \p newUsers.
408+
bool extendStoreBorrow(StoreBorrowInst *sbi,
409+
SmallVectorImpl<Operand *> &newUses,
410+
DeadEndBlocks *deadEndBlocks,
411+
InstModCallbacks callbacks = InstModCallbacks());
412+
407413
} // namespace swift
408414

409415
#endif

lib/SIL/Utils/ScopedAddressUtils.cpp

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -182,73 +182,6 @@ bool swift::hasOtherStoreBorrowsInLifetime(StoreBorrowInst *storeBorrow,
182182
return false;
183183
}
184184

185-
bool swift::extendStoreBorrow(StoreBorrowInst *sbi,
186-
SmallVectorImpl<Operand *> &newUses,
187-
DeadEndBlocks *deadEndBlocks,
188-
InstModCallbacks callbacks) {
189-
ScopedAddressValue scopedAddress(sbi);
190-
191-
SmallVector<SILBasicBlock *, 4> discoveredBlocks;
192-
SSAPrunedLiveness storeBorrowLiveness(&discoveredBlocks);
193-
194-
// FIXME: if OSSA lifetimes are complete, then we don't need transitive
195-
// liveness here.
196-
AddressUseKind useKind =
197-
scopedAddress.computeTransitiveLiveness(storeBorrowLiveness);
198-
199-
// If all new uses are within store_borrow boundary, no need for extension.
200-
if (storeBorrowLiveness.areUsesWithinBoundary(newUses, deadEndBlocks)) {
201-
return true;
202-
}
203-
204-
if (useKind != AddressUseKind::NonEscaping) {
205-
return false;
206-
}
207-
208-
// store_borrow extension is possible only when there are no other
209-
// store_borrows to the same destination within the store_borrow's lifetime
210-
// built from newUsers.
211-
if (hasOtherStoreBorrowsInLifetime(sbi, &storeBorrowLiveness,
212-
deadEndBlocks)) {
213-
return false;
214-
}
215-
216-
InstModCallbacks tempCallbacks = callbacks;
217-
InstructionDeleter deleter(std::move(tempCallbacks));
218-
GuaranteedOwnershipExtension borrowExtension(deleter, *deadEndBlocks,
219-
sbi->getFunction());
220-
auto status = borrowExtension.checkBorrowExtension(
221-
BorrowedValue(sbi->getSrc()), newUses);
222-
if (status == GuaranteedOwnershipExtension::Invalid) {
223-
return false;
224-
}
225-
226-
borrowExtension.transform(status);
227-
228-
SmallVector<Operand *, 4> endBorrowUses;
229-
// Collect old scope-ending instructions.
230-
scopedAddress.visitScopeEndingUses([&](Operand *op) {
231-
endBorrowUses.push_back(op);
232-
return true;
233-
});
234-
235-
for (auto *use : newUses) {
236-
// Update newUsers as non-lifetime ending.
237-
storeBorrowLiveness.updateForUse(use->getUser(),
238-
/* lifetimeEnding */ false);
239-
}
240-
241-
// Add new scope-ending instructions.
242-
scopedAddress.endScopeAtLivenessBoundary(&storeBorrowLiveness);
243-
244-
// Remove old scope-ending instructions.
245-
for (auto *endBorrowUse : endBorrowUses) {
246-
callbacks.deleteInst(endBorrowUse->getUser());
247-
}
248-
249-
return true;
250-
}
251-
252185
void ScopedAddressValue::print(llvm::raw_ostream &os) const {
253186
os << "ScopedAddressIntroducingValue:\n"
254187
"Kind: "

lib/SILOptimizer/Utils/OwnershipOptUtils.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/SIL/MemAccessUtils.h"
2626
#include "swift/SIL/OwnershipUtils.h"
2727
#include "swift/SIL/Projection.h"
28+
#include "swift/SIL/ScopedAddressUtils.h"
2829
#include "swift/SIL/SILArgument.h"
2930
#include "swift/SIL/SILBuilder.h"
3031
#include "swift/SIL/SILInstruction.h"
@@ -1848,3 +1849,70 @@ bool swift::createBorrowScopeForPhiOperands(SILPhiArgument *newPhi) {
18481849
}
18491850
return GuaranteedPhiBorrowFixup().createExtendedNestedBorrowScope(newPhi);
18501851
}
1852+
1853+
bool swift::extendStoreBorrow(StoreBorrowInst *sbi,
1854+
SmallVectorImpl<Operand *> &newUses,
1855+
DeadEndBlocks *deadEndBlocks,
1856+
InstModCallbacks callbacks) {
1857+
ScopedAddressValue scopedAddress(sbi);
1858+
1859+
SmallVector<SILBasicBlock *, 4> discoveredBlocks;
1860+
SSAPrunedLiveness storeBorrowLiveness(&discoveredBlocks);
1861+
1862+
// FIXME: if OSSA lifetimes are complete, then we don't need transitive
1863+
// liveness here.
1864+
AddressUseKind useKind =
1865+
scopedAddress.computeTransitiveLiveness(storeBorrowLiveness);
1866+
1867+
// If all new uses are within store_borrow boundary, no need for extension.
1868+
if (storeBorrowLiveness.areUsesWithinBoundary(newUses, deadEndBlocks)) {
1869+
return true;
1870+
}
1871+
1872+
if (useKind != AddressUseKind::NonEscaping) {
1873+
return false;
1874+
}
1875+
1876+
// store_borrow extension is possible only when there are no other
1877+
// store_borrows to the same destination within the store_borrow's lifetime
1878+
// built from newUsers.
1879+
if (hasOtherStoreBorrowsInLifetime(sbi, &storeBorrowLiveness,
1880+
deadEndBlocks)) {
1881+
return false;
1882+
}
1883+
1884+
InstModCallbacks tempCallbacks = callbacks;
1885+
InstructionDeleter deleter(std::move(tempCallbacks));
1886+
GuaranteedOwnershipExtension borrowExtension(deleter, *deadEndBlocks,
1887+
sbi->getFunction());
1888+
auto status = borrowExtension.checkBorrowExtension(
1889+
BorrowedValue(sbi->getSrc()), newUses);
1890+
if (status == GuaranteedOwnershipExtension::Invalid) {
1891+
return false;
1892+
}
1893+
1894+
borrowExtension.transform(status);
1895+
1896+
SmallVector<Operand *, 4> endBorrowUses;
1897+
// Collect old scope-ending instructions.
1898+
scopedAddress.visitScopeEndingUses([&](Operand *op) {
1899+
endBorrowUses.push_back(op);
1900+
return true;
1901+
});
1902+
1903+
for (auto *use : newUses) {
1904+
// Update newUsers as non-lifetime ending.
1905+
storeBorrowLiveness.updateForUse(use->getUser(),
1906+
/* lifetimeEnding */ false);
1907+
}
1908+
1909+
// Add new scope-ending instructions.
1910+
scopedAddress.endScopeAtLivenessBoundary(&storeBorrowLiveness);
1911+
1912+
// Remove old scope-ending instructions.
1913+
for (auto *endBorrowUse : endBorrowUses) {
1914+
callbacks.deleteInst(endBorrowUse->getUser());
1915+
}
1916+
1917+
return true;
1918+
}

lib/SILOptimizer/Utils/PartialApplyCombiner.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "swift/SIL/SILValue.h"
1414
#include "swift/SIL/ScopedAddressUtils.h"
1515
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
16+
#include "swift/SILOptimizer/Utils/OwnershipOptUtils.h"
1617
#include "swift/SILOptimizer/Utils/ValueLifetime.h"
1718

1819
using namespace swift;

0 commit comments

Comments
 (0)