mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/main' into rebranch
This commit is contained in:
@@ -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);
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user