2222#include " swift/Basic/Defer.h"
2323#include " swift/SIL/BasicBlockUtils.h"
2424#include " swift/SIL/OwnershipUtils.h"
25+ #include " swift/SIL/PrunedLiveness.h"
2526#include " swift/SIL/SILModule.h"
2627#include " swift/SILOptimizer/Utils/InstOptUtils.h"
2728
@@ -34,6 +35,31 @@ inline bool requiresOSSACleanup(SILValue v) {
3435 && v.getOwnershipKind () != OwnershipKind::Unowned;
3536}
3637
38+ // / Rewrite the lifetime of \p ownedValue to match \p lifetimeBoundary. This may
39+ // / insert copies at forwarding consumes, including phis.
40+ // /
41+ // / Precondition: lifetimeBoundary is dominated by ownedValue.
42+ // /
43+ // / Precondition: lifetimeBoundary is a superset of ownedValue's current
44+ // / lifetime (therefore, none of the safety checks done during
45+ // / CanonicalizeOSSALifetime are needed here).
46+ void extendOwnedLifetime (SILValue ownedValue,
47+ PrunedLivenessBoundary &lifetimeBoundary,
48+ InstructionDeleter &deleter);
49+
50+ // / Rewrite the local borrow scope introduced by \p beginBorrow to match \p
51+ // / guaranteedBoundary.
52+ // /
53+ // / Precondition: guaranteedBoundary is dominated by beginBorrow which has no
54+ // / reborrows.
55+ // /
56+ // / Precondition: guaranteedBoundary is a superset of beginBorrow's current
57+ // / scope (therefore, none of the safety checks done during
58+ // / CanonicalizeBorrowScope are needed here).
59+ void extendLocalBorrow (BeginBorrowInst *beginBorrow,
60+ PrunedLivenessBoundary &guaranteedBoundary,
61+ InstructionDeleter &deleter);
62+
3763// / Given a new phi that may use a guaranteed value, create nested borrow scopes
3864// / for its incoming operands and end_borrows that cover the phi's extended
3965// / borrow scope, which transitively includes any phis that use this phi.
@@ -47,6 +73,73 @@ inline bool requiresOSSACleanup(SILValue v) {
4773// / newly created phis do not yet have a borrow scope.
4874bool createBorrowScopeForPhiOperands (SILPhiArgument *newPhi);
4975
76+ // ===----------------------------------------------------------------------===//
77+ // GuaranteedOwnershipExtension
78+ // ===----------------------------------------------------------------------===//
79+
80+ // / Extend existing guaranteed ownership to cover new guaranteeed uses that are
81+ // / dominated by the borrow introducer.
82+ class GuaranteedOwnershipExtension {
83+ // --- context
84+ InstructionDeleter &deleter;
85+ DeadEndBlocks &deBlocks;
86+
87+ // --- analysis state
88+ PrunedLiveness guaranteedLiveness;
89+ PrunedLiveness ownedLifetime;
90+ SmallVector<SILBasicBlock *, 4 > ownedConsumeBlocks;
91+ BeginBorrowInst *beginBorrow = nullptr ;
92+
93+ public:
94+ GuaranteedOwnershipExtension (InstructionDeleter &deleter,
95+ DeadEndBlocks &deBlocks)
96+ : deleter(deleter), deBlocks(deBlocks) {}
97+
98+ void clear () {
99+ guaranteedLiveness.clear ();
100+ ownedLifetime.clear ();
101+ ownedConsumeBlocks.clear ();
102+ beginBorrow = nullptr ;
103+ }
104+
105+ // / Invalid indicates that the current guaranteed scope is insufficient, and
106+ // / it does not meet the precondition for scope extension.
107+ // /
108+ // / Valid indicates that the current guaranteed scope is sufficient with no
109+ // / transformation required.
110+ // /
111+ // / ExtendBorrow indicates that the local borrow scope can be extended without
112+ // / affecting the owned lifetime or introducing copies.
113+ // /
114+ // / ExtendLifetime indicates that the owned lifetime can be extended possibly
115+ // / requiring additional copies.
116+ enum Status { Invalid, Valid, ExtendBorrow, ExtendLifetime };
117+
118+ // / Can the OSSA ownership of the \p parentAddress cover all uses of the \p
119+ // / childAddress?
120+ // /
121+ // / Precondition: \p parentAddress dominates \p childAddress
122+ Status checkAddressOwnership (SILValue parentAddress, SILValue childAddress);
123+
124+ // / Can the OSSA scope of \p borrow cover all \p newUses?
125+ // /
126+ // / Precondition: \p borrow dominates \p newUses
127+ Status checkBorrowExtension (BorrowedValue borrow,
128+ ArrayRef<Operand *> newUses);
129+
130+ // / Can the OSSA scope of \p ownedValue cover all the guaranteed \p newUses?
131+ // /
132+ // / Precondition: \p ownedValue dominates \p newUses
133+ Status checkLifetimeExtension (SILValue ownedValue,
134+ ArrayRef<Operand *> newUses);
135+
136+ void transform (Status status);
137+ };
138+
139+ // ===----------------------------------------------------------------------===//
140+ // RAUW - Replace All Uses With...
141+ // ===----------------------------------------------------------------------===//
142+
50143// / A struct that contains context shared in between different operation +
51144// / "ownership fixup" utilities. Please do not put actual methods on this, it is
52145// / meant to be composed with.
0 commit comments