22
22
#include " swift/Basic/Defer.h"
23
23
#include " swift/SIL/BasicBlockUtils.h"
24
24
#include " swift/SIL/OwnershipUtils.h"
25
+ #include " swift/SIL/PrunedLiveness.h"
25
26
#include " swift/SIL/SILModule.h"
26
27
#include " swift/SILOptimizer/Utils/InstOptUtils.h"
27
28
@@ -34,6 +35,31 @@ inline bool requiresOSSACleanup(SILValue v) {
34
35
&& v.getOwnershipKind () != OwnershipKind::Unowned;
35
36
}
36
37
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
+
37
63
// / Given a new phi that may use a guaranteed value, create nested borrow scopes
38
64
// / for its incoming operands and end_borrows that cover the phi's extended
39
65
// / borrow scope, which transitively includes any phis that use this phi.
@@ -47,6 +73,73 @@ inline bool requiresOSSACleanup(SILValue v) {
47
73
// / newly created phis do not yet have a borrow scope.
48
74
bool createBorrowScopeForPhiOperands (SILPhiArgument *newPhi);
49
75
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
+
50
143
// / A struct that contains context shared in between different operation +
51
144
// / "ownership fixup" utilities. Please do not put actual methods on this, it is
52
145
// / meant to be composed with.
0 commit comments