Skip to content

Commit 184e83e

Browse files
authored
Merge pull request #61464 from nate-chandler/branch/rdar99618502/OnoneLifetimes
[CanonicalizeOSSALifetime] Extend Onone lifetimes.
2 parents 18c04b5 + 03253db commit 184e83e

File tree

9 files changed

+1076
-92
lines changed

9 files changed

+1076
-92
lines changed

include/swift/SILOptimizer/Utils/CanonicalizeOSSALifetime.h

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ void diagnoseRequiredCopyOfMoveOnly(Operand *use,
130130
///
131131
/// This result remains valid during copy rewriting. The only instructions
132132
/// referenced it contains are consumes that cannot be deleted.
133-
class CanonicalOSSAConsumeInfo {
133+
class CanonicalOSSAConsumeInfo final {
134134
/// Map blocks on the lifetime boundary to the last consuming instruction.
135135
llvm::SmallDenseMap<SILBasicBlock *, SILInstruction *, 4> finalBlockConsumes;
136136

@@ -159,6 +159,10 @@ class CanonicalOSSAConsumeInfo {
159159
return false;
160160
}
161161

162+
CanonicalOSSAConsumeInfo() {}
163+
CanonicalOSSAConsumeInfo(CanonicalOSSAConsumeInfo const &) = delete;
164+
CanonicalOSSAConsumeInfo &
165+
operator=(CanonicalOSSAConsumeInfo const &) = delete;
162166
SWIFT_ASSERT_ONLY_DECL(void dump() const LLVM_ATTRIBUTE_USED);
163167
};
164168

@@ -169,7 +173,7 @@ class CanonicalOSSAConsumeInfo {
169173
///
170174
/// TODO: Move all the private per-definition members into an implementation
171175
/// class in the .cpp file.
172-
class CanonicalizeOSSALifetime {
176+
class CanonicalizeOSSALifetime final {
173177
public:
174178
/// Find the original definition of a potentially copied value. \p copiedValue
175179
/// must be an owned value. It is usually a copy but may also be a destroy.
@@ -205,6 +209,10 @@ class CanonicalizeOSSALifetime {
205209
/// liveness may be pruned during canonicalization.
206210
bool pruneDebugMode;
207211

212+
/// If true, lifetimes will not be shortened except when necessary to avoid
213+
/// copies.
214+
bool maximizeLifetime;
215+
208216
/// If true and we are processing a value of move_only type, emit a diagnostic
209217
/// when-ever we need to insert a copy_value.
210218
std::function<void(Operand *)> moveOnlyCopyValueNotification;
@@ -240,8 +248,8 @@ class CanonicalizeOSSALifetime {
240248
/// Visited set for general def-use traversal that prevents revisiting values.
241249
GraphNodeWorklist<SILValue, 8> defUseWorklist;
242250

243-
/// Visited set general CFG traversal that prevents revisiting blocks.
244-
GraphNodeWorklist<SILBasicBlock *, 8> blockWorklist;
251+
/// The blocks that were discovered by PrunedLiveness.
252+
SmallVector<SILBasicBlock *, 32> discoveredBlocks;
245253

246254
/// Pruned liveness for the extended live range including copies. For this
247255
/// purpose, only consuming instructions are considered "lifetime
@@ -251,7 +259,7 @@ class CanonicalizeOSSALifetime {
251259
/// The destroys of the value. These are not uses, but need to be recorded so
252260
/// that we know when the last use in a consuming block is (without having to
253261
/// repeatedly do use-def walks from destroys).
254-
SmallPtrSet<SILInstruction *, 8> destroys;
262+
SmallPtrSetVector<SILInstruction *, 8> destroys;
255263

256264
/// Information about consuming instructions discovered in this canonical OSSA
257265
/// lifetime.
@@ -289,15 +297,17 @@ class CanonicalizeOSSALifetime {
289297
}
290298

291299
CanonicalizeOSSALifetime(
292-
bool pruneDebugMode, NonLocalAccessBlockAnalysis *accessBlockAnalysis,
293-
DominanceInfo *domTree, InstructionDeleter &deleter,
300+
bool pruneDebugMode, bool maximizeLifetime,
301+
NonLocalAccessBlockAnalysis *accessBlockAnalysis, DominanceInfo *domTree,
302+
InstructionDeleter &deleter,
294303
std::function<void(Operand *)> moveOnlyCopyValueNotification = nullptr,
295304
std::function<void(Operand *)> moveOnlyFinalConsumingUse = nullptr)
296-
: pruneDebugMode(pruneDebugMode),
305+
: pruneDebugMode(pruneDebugMode), maximizeLifetime(maximizeLifetime),
297306
moveOnlyCopyValueNotification(moveOnlyCopyValueNotification),
298307
moveOnlyFinalConsumingUse(moveOnlyFinalConsumingUse),
299308
accessBlockAnalysis(accessBlockAnalysis), domTree(domTree),
300-
deleter(deleter) {}
309+
deleter(deleter),
310+
liveness(maximizeLifetime ? &discoveredBlocks : nullptr) {}
301311

302312
SILValue getCurrentDef() const { return liveness.getDef(); }
303313

@@ -307,6 +317,7 @@ class CanonicalizeOSSALifetime {
307317
// analysis, freeing its memory.
308318
accessBlocks = nullptr;
309319
consumes.clear();
320+
destroys.clear();
310321

311322
liveness.initializeDef(def);
312323
}
@@ -315,6 +326,7 @@ class CanonicalizeOSSALifetime {
315326
consumingBlocks.clear();
316327
debugValues.clear();
317328
liveness.clear();
329+
discoveredBlocks.clear();
318330
}
319331

320332
/// Top-Level API: rewrites copies and destroys within \p def's extended
@@ -333,7 +345,7 @@ class CanonicalizeOSSALifetime {
333345

334346
InstModCallbacks &getCallbacks() { return deleter.getCallbacks(); }
335347

336-
protected:
348+
private:
337349
void recordDebugValue(DebugValueInst *dvi) { debugValues.insert(dvi); }
338350

339351
void recordConsumingUse(Operand *use) {
@@ -345,9 +357,14 @@ class CanonicalizeOSSALifetime {
345357

346358
void extendLivenessThroughOverlappingAccess();
347359

348-
void findExtendedBoundary(PrunedLivenessBoundary &boundary);
360+
void findOriginalBoundary(PrunedLivenessBoundary &boundary);
361+
362+
void findExtendedBoundary(PrunedLivenessBoundary const &originalBoundary,
363+
PrunedLivenessBoundary &boundary);
364+
365+
void extendUnconsumedLiveness(PrunedLivenessBoundary const &boundary);
349366

350-
void insertDestroysOnBoundary(PrunedLivenessBoundary &boundary);
367+
void insertDestroysOnBoundary(PrunedLivenessBoundary const &boundary);
351368

352369
void rewriteCopies();
353370
};

lib/SILOptimizer/Mandatory/MoveOnlyAddressChecker.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,9 @@ struct MoveOnlyChecker {
746746
instToDelete->eraseFromParent();
747747
})),
748748
canonicalizer(
749-
false /*pruneDebugMode*/, accessBlockAnalysis, domTree, deleter,
749+
false /*pruneDebugMode*/,
750+
!fn->shouldOptimize() /*maximizeLifetime*/, accessBlockAnalysis,
751+
domTree, deleter,
750752
[&](Operand *use) { consumingUsesNeedingCopy.push_back(use); },
751753
[&](Operand *use) { finalConsumingUses.push_back(use); }) {}
752754

lib/SILOptimizer/Mandatory/MoveOnlyObjectChecker.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,9 @@ bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
401401
};
402402

403403
CanonicalizeOSSALifetime canonicalizer(
404-
false /*pruneDebugMode*/, accessBlockAnalysis, domTree, deleter,
405-
foundConsumingUseNeedingCopy, foundConsumingUseNotNeedingCopy);
404+
false /*pruneDebugMode*/, !fn->shouldOptimize() /*maximizeLifetime*/,
405+
accessBlockAnalysis, domTree, deleter, foundConsumingUseNeedingCopy,
406+
foundConsumingUseNotNeedingCopy);
406407
auto moveIntroducers = llvm::makeArrayRef(moveIntroducersToProcess.begin(),
407408
moveIntroducersToProcess.end());
408409
SmallPtrSet<MarkMustCheckInst *, 4> valuesWithDiagnostics;

lib/SILOptimizer/SILCombiner/SILCombine.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,10 @@ void SILCombiner::canonicalizeOSSALifetimes(SILInstruction *currentInst) {
350350
InstructionDeleter deleter(std::move(canonicalizeCallbacks));
351351

352352
DominanceInfo *domTree = DA->get(&Builder.getFunction());
353-
CanonicalizeOSSALifetime canonicalizer(false /*prune debug*/, NLABA, domTree,
354-
deleter);
353+
CanonicalizeOSSALifetime canonicalizer(
354+
false /*prune debug*/,
355+
!parentTransform->getFunction()->shouldOptimize() /*maximize lifetime*/,
356+
NLABA, domTree, deleter);
355357
CanonicalizeBorrowScope borrowCanonicalizer(deleter);
356358

357359
while (!defsToCanonicalize.empty()) {

lib/SILOptimizer/Transforms/CopyPropagation.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,9 @@ static bool sinkOwnedForward(SILInstruction *ownedForward,
373373
namespace {
374374

375375
class CopyPropagation : public SILFunctionTransform {
376-
/// True if debug_value instructions should be pruned.
376+
/// If true, debug_value instructions should be pruned.
377377
bool pruneDebug;
378-
/// True if all values should be canonicalized.
378+
/// If true, all values will be canonicalized.
379379
bool canonicalizeAll;
380380
/// If true, then borrow scopes will be canonicalized, allowing copies of
381381
/// guaranteed values to be optimized. Does *not* shrink the borrow scope.
@@ -437,8 +437,9 @@ void CopyPropagation::run() {
437437

438438
// canonicalizer performs all modifications through deleter's callbacks, so we
439439
// don't need to explicitly check for changes.
440-
CanonicalizeOSSALifetime canonicalizer(pruneDebug, accessBlockAnalysis,
441-
domTree, deleter);
440+
CanonicalizeOSSALifetime canonicalizer(
441+
pruneDebug, /*maximizeLifetime=*/!getFunction()->shouldOptimize(),
442+
accessBlockAnalysis, domTree, deleter);
442443

443444
// NOTE: We assume that the function is in reverse post order so visiting the
444445
// blocks and pushing begin_borrows as we see them and then popping them

0 commit comments

Comments
 (0)