Merge remote-tracking branch 'origin/main' into rebranch

This commit is contained in:
swift-ci
2024-05-01 18:15:54 -07:00
11 changed files with 253 additions and 79 deletions

View File

@@ -50,22 +50,54 @@ public:
OSSALifetimeCompletion(SILFunction *function, const DominanceInfo *domInfo)
: domInfo(domInfo), completedValues(function) {}
// The kind of boundary at which to complete the lifetime.
//
// Liveness: "As early as possible." Consume the value after the last
// non-consuming uses.
// Availability: "As late as possible." Consume the value in the last blocks
// beyond the non-consuming uses in which the value has been
// consumed on no incoming paths.
struct Boundary {
enum Value : uint8_t {
Liveness,
Availability,
};
Value value;
Boundary(Value value) : value(value){};
operator Value() const { return value; }
static std::optional<Boundary> getForcingLiveness(bool force) {
if (!force)
return {};
return {Liveness};
}
bool isLiveness() { return value == Liveness; }
bool isAvailable() { return !isLiveness(); }
};
/// Insert a lifetime-ending instruction on every path to complete the OSSA
/// lifetime of \p value. Lifetime completion is only relevant for owned
/// lifetime of \p value along \p boundary.
///
/// If \p boundary is not specified, the following boundary will be used:
/// \p value is lexical -> Boundary::Availability
/// \p value is non-lexical -> Boundary::Liveness
///
/// Lifetime completion is only relevant for owned
/// values or borrow introducers.
/// For lexical values lifetime is completed at unreachable instructions.
/// For non-lexical values lifetime is completed at the lifetime boundary.
/// When \p forceBoundaryCompletion is true, the client is able to guarantee
/// that lifetime completion of lexical values at the lifetime boundary is
/// sufficient.
/// Currently \p forceBoundaryCompletion is used by mem2reg and temprvalueopt
/// to complete lexical enum values on trivial paths.
///
/// Currently \p boundary == {Boundary::Availability} is used by Mem2Reg and
/// TempRValueOpt and PredicatbleMemOpt to complete lexical enum values on
/// trivial paths.
///
/// Returns true if any new instructions were created to complete the
/// lifetime.
///
/// TODO: We also need to complete scoped addresses (e.g. store_borrow)!
LifetimeCompletion
completeOSSALifetime(SILValue value, bool forceBoundaryCompletion = false) {
completeOSSALifetime(SILValue value,
std::optional<Boundary> maybeBoundary = std::nullopt) {
if (value->getOwnershipKind() == OwnershipKind::None)
return LifetimeCompletion::NoLifetime;
@@ -80,7 +112,10 @@ public:
if (!completedValues.insert(value))
return LifetimeCompletion::AlreadyComplete;
return analyzeAndUpdateLifetime(value, forceBoundaryCompletion)
Boundary boundary = maybeBoundary.value_or(
value->isLexical() ? Boundary::Availability : Boundary::Liveness);
return analyzeAndUpdateLifetime(value, boundary)
? LifetimeCompletion::WasCompleted
: LifetimeCompletion::AlreadyComplete;
}
@@ -90,7 +125,7 @@ public:
llvm::function_ref<void(SILInstruction *)> visit);
protected:
bool analyzeAndUpdateLifetime(SILValue value, bool forceBoundaryCompletion);
bool analyzeAndUpdateLifetime(SILValue value, Boundary boundary);
};
//===----------------------------------------------------------------------===//