Skip to content

Commit f6844aa

Browse files
Merge pull request #75507 from nate-chandler/revert/20240726/1
Revert "[LifetimeCompletion] Enable."
2 parents 7d65170 + a7c6538 commit f6844aa

File tree

6 files changed

+31
-318
lines changed

6 files changed

+31
-318
lines changed

include/swift/AST/SILOptions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ class SILOptions {
180180
/// If set to true, compile with the SIL Opaque Values enabled.
181181
bool EnableSILOpaqueValues = false;
182182

183-
/// Introduce linear OSSA lifetimes after SILGen
184-
bool OSSACompleteLifetimes = true;
183+
/// Require linear OSSA lifetimes after SILGen
184+
bool OSSACompleteLifetimes = false;
185185

186186
/// Verify linear OSSA lifetimes after SILGen
187187
bool OSSAVerifyComplete = false;

lib/DriverTool/sil_opt_main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,9 @@ struct SILOptOptions {
231231
EnableSILOpaqueValues = llvm::cl::opt<bool>("enable-sil-opaque-values",
232232
llvm::cl::desc("Compile the module with sil-opaque-values enabled."));
233233

234-
llvm::cl::opt<bool> EnableOSSACompleteLifetimes = llvm::cl::opt<bool>(
235-
"enable-ossa-complete-lifetimes", llvm::cl::init(true),
236-
llvm::cl::desc("Require linear OSSA lifetimes after SILGenCleanup."));
234+
llvm::cl::opt<bool>
235+
EnableOSSACompleteLifetimes = llvm::cl::opt<bool>("enable-ossa-complete-lifetimes",
236+
llvm::cl::desc("Require linear OSSA lifetimes after SILGenCleanup."));
237237
llvm::cl::opt<bool>
238238
EnableOSSAVerifyComplete = llvm::cl::opt<bool>("enable-ossa-verify-complete",
239239
llvm::cl::desc("Verify linear OSSA lifetimes after SILGenCleanup."));

lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,21 @@
1414

1515
#include "swift/Basic/Assertions.h"
1616
#include "swift/Basic/Defer.h"
17-
#include "swift/SIL/BasicBlockDatastructures.h"
1817
#include "swift/SIL/DebugUtils.h"
1918
#include "swift/SIL/InstructionUtils.h"
2019
#include "swift/SIL/PrunedLiveness.h"
2120
#include "swift/SIL/SILArgument.h"
2221
#include "swift/SIL/SILBuilder.h"
2322
#include "swift/SIL/SILInstruction.h"
2423
#include "swift/SIL/SILValue.h"
24+
#include "swift/SIL/BasicBlockDatastructures.h"
2525
#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
26-
#include "swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
2726
#include "swift/SILOptimizer/PassManager/Passes.h"
2827
#include "swift/SILOptimizer/PassManager/Transforms.h"
2928
#include "swift/SILOptimizer/Utils/BasicBlockOptUtils.h"
3029
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
31-
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
3230
#include "swift/SILOptimizer/Utils/OwnershipOptUtils.h"
31+
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
3332
#include "swift/SILOptimizer/Utils/SILSSAUpdater.h"
3433
#include "swift/SILOptimizer/Utils/StackNesting.h"
3534

@@ -446,6 +445,14 @@ static BuiltinInst *getEndAsyncLet(BuiltinInst *startAsyncLet) {
446445
/// a closure is used by \p closureUser.
447446
static void insertAfterClosureUser(SILInstruction *closureUser,
448447
function_ref<void(SILBuilder &)> insertFn) {
448+
// Don't insert any destroy or deallocation right before an unreachable.
449+
// It's not needed an will only add up to code size.
450+
auto insertAtNonUnreachable = [&](SILBuilder &builder) {
451+
if (isa<UnreachableInst>(builder.getInsertionPoint()))
452+
return;
453+
insertFn(builder);
454+
};
455+
449456
{
450457
SILInstruction *userForBorrow = closureUser;
451458
if (auto *m = dyn_cast<MoveOnlyWrapperToCopyableValueInst>(userForBorrow))
@@ -461,7 +468,7 @@ static void insertAfterClosureUser(SILInstruction *closureUser,
461468

462469
for (auto eb : endBorrows) {
463470
SILBuilderWithScope builder(std::next(eb->getIterator()));
464-
insertFn(builder);
471+
insertAtNonUnreachable(builder);
465472
}
466473
return;
467474
}
@@ -472,12 +479,12 @@ static void insertAfterClosureUser(SILInstruction *closureUser,
472479
if (!endAsyncLet)
473480
return;
474481
SILBuilderWithScope builder(std::next(endAsyncLet->getIterator()));
475-
insertFn(builder);
482+
insertAtNonUnreachable(builder);
476483
return;
477484
}
478485
FullApplySite fas = FullApplySite::isa(closureUser);
479486
assert(fas);
480-
fas.insertAfterApplication(insertFn);
487+
fas.insertAfterApplication(insertAtNonUnreachable);
481488
}
482489

483490
static SILValue skipConvert(SILValue v) {
@@ -993,7 +1000,6 @@ static SILValue tryRewriteToPartialApplyStack(
9931000

9941001
static bool tryExtendLifetimeToLastUse(
9951002
ConvertEscapeToNoEscapeInst *cvt, DominanceAnalysis *dominanceAnalysis,
996-
DeadEndBlocksAnalysis *deadEndBlocksAnalysis,
9971003
llvm::DenseMap<SILInstruction *, SILInstruction *> &memoized,
9981004
llvm::DenseSet<SILBasicBlock *> &unreachableBlocks,
9991005
InstructionDeleter &deleter, const bool &modifiedCFG) {
@@ -1042,22 +1048,10 @@ static bool tryExtendLifetimeToLastUse(
10421048
cvt->setLifetimeGuaranteed();
10431049
cvt->setOperand(closureCopy);
10441050

1045-
auto *function = cvt->getFunction();
1046-
// The CFG may have been modified during this run, which would have made
1047-
// dead-end blocks analysis invalid. Mark it invalid it now if that
1048-
// happened. If the CFG hasn't been modified, this is a noop thanks to
1049-
// DeadEndBlocksAnalysis::shouldInvalidate.
1050-
deadEndBlocksAnalysis->invalidate(function,
1051-
analysisInvalidationKind(modifiedCFG));
1052-
auto *deadEndBlocks = deadEndBlocksAnalysis->get(function);
1053-
1054-
insertAfterClosureUser(
1055-
singleUser, [closureCopy, deadEndBlocks](SILBuilder &builder) {
1056-
auto loc = RegularLocation(builder.getInsertionPointLoc());
1057-
auto isDeadEnd = IsDeadEnd_t(
1058-
deadEndBlocks->isDeadEnd(builder.getInsertionPoint()->getParent()));
1059-
builder.createDestroyValue(loc, closureCopy, DontPoisonRefs, isDeadEnd);
1060-
});
1051+
insertAfterClosureUser(singleUser, [closureCopy](SILBuilder &builder) {
1052+
auto loc = RegularLocation(builder.getInsertionPointLoc());
1053+
builder.createDestroyValue(loc, closureCopy);
1054+
});
10611055
/*
10621056
llvm::errs() << "after lifetime extension of\n";
10631057
escapingClosure->dump();
@@ -1446,7 +1440,6 @@ static void computeUnreachableBlocks(
14461440

14471441
static bool fixupClosureLifetimes(SILFunction &fn,
14481442
DominanceAnalysis *dominanceAnalysis,
1449-
DeadEndBlocksAnalysis *deadEndBlocksAnalysis,
14501443
bool &checkStackNesting, bool &modifiedCFG) {
14511444
bool changed = false;
14521445

@@ -1483,8 +1476,7 @@ static bool fixupClosureLifetimes(SILFunction &fn,
14831476
}
14841477
}
14851478

1486-
if (tryExtendLifetimeToLastUse(cvt, dominanceAnalysis,
1487-
deadEndBlocksAnalysis, memoizedQueries,
1479+
if (tryExtendLifetimeToLastUse(cvt, dominanceAnalysis, memoizedQueries,
14881480
unreachableBlocks, updater.getDeleter(),
14891481
/*const*/ modifiedCFG)) {
14901482
changed = true;
@@ -1524,11 +1516,9 @@ class ClosureLifetimeFixup : public SILFunctionTransform {
15241516
bool modifiedCFG = false;
15251517

15261518
auto *dominanceAnalysis = PM->getAnalysis<DominanceAnalysis>();
1527-
auto *deadEndBlocksAnalysis = getAnalysis<DeadEndBlocksAnalysis>();
15281519

15291520
if (fixupClosureLifetimes(*getFunction(), dominanceAnalysis,
1530-
deadEndBlocksAnalysis, checkStackNesting,
1531-
modifiedCFG)) {
1521+
checkStackNesting, modifiedCFG)) {
15321522
updateBorrowedFrom(getPassManager(), getFunction());
15331523
if (checkStackNesting){
15341524
modifiedCFG |=

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 7 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ void CanonicalizeOSSALifetime::findExtendedBoundary(
943943
/// record it as a final consume.
944944
static void
945945
insertDestroyBeforeInstruction(SILInstruction *nextInstruction,
946-
SILValue currentDef, IsDeadEnd_t isDeadEnd,
946+
SILValue currentDef,
947947
CanonicalOSSAConsumeInfo &consumes,
948948
SmallVectorImpl<DestroyValueInst *> &destroys,
949949
InstModCallbacks &callbacks) {
@@ -974,63 +974,13 @@ insertDestroyBeforeInstruction(SILInstruction *nextInstruction,
974974
SILBuilderWithScope builder(nextInstruction);
975975
auto loc =
976976
RegularLocation::getAutoGeneratedLocation(nextInstruction->getLoc());
977-
auto *dvi =
978-
builder.createDestroyValue(loc, currentDef, DontPoisonRefs, isDeadEnd);
977+
auto *dvi = builder.createDestroyValue(loc, currentDef);
979978
callbacks.createdNewInst(dvi);
980979
consumes.recordFinalConsume(dvi);
981980
++NumDestroysGenerated;
982981
destroys.push_back(dvi);
983982
}
984983

985-
/// Whether a destroy created at \p inst should be marked [dead_end].
986-
///
987-
/// It should be if
988-
/// (1) \p inst is itself in a dead-end region
989-
/// (2) all destroys after \p inst are [dead_end]
990-
static IsDeadEnd_t
991-
isDeadEndDestroy(SILInstruction *inst,
992-
SmallPtrSetVector<SILInstruction *, 8> const &destroys,
993-
BasicBlockSet &semanticDestroysBlocks,
994-
DeadEndBlocks *deadEnds) {
995-
auto *parent = inst->getParent();
996-
if (!deadEnds->isDeadEnd(parent)) {
997-
// Only destroys in dead-ends can be non-meaningful (aka "dead end").
998-
return IsntDeadEnd;
999-
}
1000-
if (semanticDestroysBlocks.contains(parent)) {
1001-
// `parent` has a semantic destroy somewhere. Is it after `inst`?
1002-
for (auto *i = inst; i; i = i->getNextInstruction()) {
1003-
if (!destroys.contains(i)) {
1004-
continue;
1005-
}
1006-
auto *dvi = cast<DestroyValueInst>(i);
1007-
if (!dvi->isDeadEnd()) {
1008-
// Some subsequent destroy within `parent` was meaningful, so one
1009-
// created at `inst` must be too.
1010-
return IsntDeadEnd;
1011-
}
1012-
}
1013-
}
1014-
// Walk the portion of the dead-end region after `parent` to check that all
1015-
// destroys are non-meaningful.
1016-
BasicBlockWorklist worklist(inst->getFunction());
1017-
for (auto *successor : parent->getSuccessorBlocks()) {
1018-
worklist.push(successor);
1019-
}
1020-
while (auto *block = worklist.pop()) {
1021-
assert(deadEnds->isDeadEnd(block));
1022-
if (semanticDestroysBlocks.contains(block)) {
1023-
// Some subsequent destroy was meaningful, so one created at `inst`
1024-
// must be too.
1025-
return IsntDeadEnd;
1026-
}
1027-
for (auto *successor : block->getSuccessorBlocks()) {
1028-
worklist.pushIfNotVisited(successor);
1029-
}
1030-
}
1031-
return IsDeadEnd;
1032-
}
1033-
1034984
/// Inserts destroys along the boundary where needed and records all final
1035985
/// consuming uses.
1036986
///
@@ -1042,18 +992,6 @@ isDeadEndDestroy(SILInstruction *inst,
1042992
void CanonicalizeOSSALifetime::insertDestroysOnBoundary(
1043993
PrunedLivenessBoundary const &boundary,
1044994
SmallVectorImpl<DestroyValueInst *> &newDestroys) {
1045-
BasicBlockSet semanticDestroyBlocks(getCurrentDef()->getFunction());
1046-
for (auto *destroy : destroys) {
1047-
if (!cast<DestroyValueInst>(destroy)->isDeadEnd()) {
1048-
semanticDestroyBlocks.insert(destroy->getParent());
1049-
}
1050-
}
1051-
auto isDeadEnd = [&semanticDestroyBlocks,
1052-
this](SILInstruction *inst) -> IsDeadEnd_t {
1053-
return isDeadEndDestroy(
1054-
inst, destroys, semanticDestroyBlocks,
1055-
deadEndBlocksAnalysis->get(getCurrentDef()->getFunction()));
1056-
};
1057995
BasicBlockSet seenMergePoints(getCurrentDef()->getFunction());
1058996
for (auto *instruction : boundary.lastUsers) {
1059997
if (destroys.contains(instruction)) {
@@ -1075,8 +1013,7 @@ void CanonicalizeOSSALifetime::insertDestroysOnBoundary(
10751013
}
10761014
auto *insertionPoint = &*successor->begin();
10771015
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(),
1078-
isDeadEnd(insertionPoint), consumes,
1079-
newDestroys, getCallbacks());
1016+
consumes, newDestroys, getCallbacks());
10801017
LLVM_DEBUG(llvm::dbgs() << " Destroy after terminator "
10811018
<< *instruction << " at beginning of ";
10821019
successor->printID(llvm::dbgs(), false);
@@ -1085,8 +1022,7 @@ void CanonicalizeOSSALifetime::insertDestroysOnBoundary(
10851022
continue;
10861023
}
10871024
auto *insertionPoint = instruction->getNextInstruction();
1088-
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(),
1089-
isDeadEnd(insertionPoint), consumes,
1025+
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(), consumes,
10901026
newDestroys, getCallbacks());
10911027
LLVM_DEBUG(llvm::dbgs()
10921028
<< " Destroy at last use " << insertionPoint << "\n");
@@ -1095,25 +1031,22 @@ void CanonicalizeOSSALifetime::insertDestroysOnBoundary(
10951031
}
10961032
for (auto *edgeDestination : boundary.boundaryEdges) {
10971033
auto *insertionPoint = &*edgeDestination->begin();
1098-
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(),
1099-
isDeadEnd(insertionPoint), consumes,
1034+
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(), consumes,
11001035
newDestroys, getCallbacks());
11011036
LLVM_DEBUG(llvm::dbgs() << " Destroy on edge " << edgeDestination << "\n");
11021037
}
11031038
for (auto *def : boundary.deadDefs) {
11041039
if (auto *arg = dyn_cast<SILArgument>(def)) {
11051040
auto *insertionPoint = &*arg->getParent()->begin();
1106-
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(),
1107-
isDeadEnd(insertionPoint), consumes,
1041+
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(), consumes,
11081042
newDestroys, getCallbacks());
11091043
LLVM_DEBUG(llvm::dbgs()
11101044
<< " Destroy after dead def arg " << arg << "\n");
11111045
} else {
11121046
auto *instruction = cast<SILInstruction>(def);
11131047
auto *insertionPoint = instruction->getNextInstruction();
11141048
assert(insertionPoint && "def instruction was a terminator?!");
1115-
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(),
1116-
isDeadEnd(insertionPoint), consumes,
1049+
insertDestroyBeforeInstruction(insertionPoint, getCurrentDef(), consumes,
11171050
newDestroys, getCallbacks());
11181051
LLVM_DEBUG(llvm::dbgs()
11191052
<< " Destroy after dead def inst " << instruction << "\n");

0 commit comments

Comments
 (0)