|
12 | 12 |
|
13 | 13 | import SIL
|
14 | 14 |
|
15 |
| -// Visit the introducers of a forwarded lifetime (Value -> LifetimeIntroducer). |
16 |
| -// |
17 |
| -// A lifetime introducer produces an initial OSSA lifetime which may be extended by forwarding instructions. The introducer is never itself the result of a ForwardingInstruction. Example: |
18 |
| -// |
19 |
| -// # lifetime introducer |
20 |
| -// %1 = apply -+ -+ |
21 |
| -// ... | OSSA lifetime | |
22 |
| -// # forwarding instruction | | |
23 |
| -// %2 = struct $S (%1) -+ -+ | forward-extended lifetime |
24 |
| -// | OSSA lifetime | |
25 |
| -// # non-forwarding consumer | | |
26 |
| -// destroy_value %2 -+ -+ |
27 |
| -// |
28 |
| -// The lifetime of a single owned value ends when it is forwarded, but certain lifetime properties are relevant for the entire forward-extended lifetime. For example, if an owned lifetime has a pointer-escaping use, then all values in the forward-extended lifetime are also considered pointer-escaping. Certain propeties, like lexical lifetimes, only exist on the forward introducer and apply to all forwarded values. |
29 |
| -// |
30 |
| -// Note: Although move_value conceptually forwards an owned value, it also summarizes lifetime attributes; therefore, it is not formally a ForwardingInstruction. |
31 |
| -// |
32 |
| -// The lifetime introducer of a guaranteed value is the borrow introducer: |
33 |
| -// |
34 |
| -// # lifetime introducer / borrow introducer |
35 |
| -// %1 = begin_borrow -+ |
36 |
| -// ... | OSSA lifetime == forwarded lifetime |
37 |
| -// # forwarding instruction | |
38 |
| -// %2 = struct $S (%1) | - forwarded uses are within the OSSA lifetime |
39 |
| -// | |
40 |
| -// end_borrow %1 -+ |
41 |
| -// |
42 |
| -// TODO: When a begin_borrow has no lifetime flags, it can be ignored as a lifetime introducer. In that case, an owned value may introduce guaranteed OSSA lifetimes. |
43 |
| -// |
44 |
| -// Forwarded lifetimes also extend through phis. In this case, however, there is no ForwardingInstruction. |
45 |
| -// |
46 |
| -// # lifetime introducer |
47 |
| -// %1 = apply -+ -+ |
48 |
| -// ... | OSSA lifetime | |
49 |
| -// # phi operand | | |
50 |
| -// br bbContinue(%1: $S) -+ | forward-extended lifetime |
51 |
| -// | |
52 |
| -// bbContinue(%phi : $S): -+ OSSA lifetime | |
53 |
| -// ... | | |
54 |
| -// destroy_value %phi -+ -+ |
55 |
| -// |
56 |
| -// TODO: when phi lifetime flags are implemented, phis will introduce a lifetime in the same way as move_value. |
57 |
| -// |
58 |
| -// This walker is used to query basic lifetime attributes on values, such as "escaping" or "lexical". It must be precise for correctness and is performance critical. |
| 15 | +/// Visit the introducers of a forwarded lifetime (Value -> LifetimeIntroducer). |
| 16 | +/// |
| 17 | +/// A lifetime introducer produces an initial OSSA lifetime which may |
| 18 | +/// be extended by forwarding instructions. The introducer is never |
| 19 | +/// itself the result of a ForwardingInstruction. Example: |
| 20 | +/// |
| 21 | +/// # lifetime introducer |
| 22 | +/// %1 = apply -+ -+ |
| 23 | +/// ... | OSSA lifetime | |
| 24 | +/// # forwarding instruction | | |
| 25 | +/// %2 = struct $S (%1) -+ -+ | forward-extended lifetime |
| 26 | +/// | OSSA lifetime | |
| 27 | +/// # non-forwarding consumer | | |
| 28 | +/// destroy_value %2 -+ -+ |
| 29 | +/// |
| 30 | +/// The lifetime of a single owned value ends when it is forwarded, |
| 31 | +/// but certain lifetime properties are relevant for the entire |
| 32 | +/// forward-extended lifetime. For example, if an owned lifetime has a |
| 33 | +/// pointer-escaping use, then all values in the forward-extended |
| 34 | +/// lifetime are also considered pointer-escaping. Certain properties, |
| 35 | +/// like lexical lifetimes, only exist on the forward introducer and |
| 36 | +/// apply to all forwarded values. |
| 37 | +/// |
| 38 | +/// Note: Although move_value conceptually forwards an owned value, it |
| 39 | +/// also summarizes lifetime attributes; therefore, it is not formally |
| 40 | +/// a ForwardingInstruction. |
| 41 | +/// |
| 42 | +/// The lifetime introducer of a guaranteed value is the borrow introducer: |
| 43 | +/// |
| 44 | +/// # lifetime introducer / borrow introducer |
| 45 | +/// %1 = begin_borrow -+ |
| 46 | +/// ... | OSSA lifetime == forwarded lifetime |
| 47 | +/// # forwarding instruction | |
| 48 | +/// %2 = struct $S (%1) | - forwarded uses are within the OSSA lifetime |
| 49 | +/// | |
| 50 | +/// end_borrow %1 -+ |
| 51 | +/// |
| 52 | +/// TODO: When a begin_borrow has no lifetime flags, it can be ignored |
| 53 | +/// as a lifetime introducer. In that case, an owned value may |
| 54 | +/// introduce guaranteed OSSA lifetimes. |
| 55 | +/// |
| 56 | +/// Forwarded lifetimes also extend through phis. In this case, |
| 57 | +/// however, there is no ForwardingInstruction. |
| 58 | +/// |
| 59 | +/// # lifetime introducer |
| 60 | +/// %1 = apply -+ -+ |
| 61 | +/// ... | OSSA lifetime | |
| 62 | +/// # phi operand | | |
| 63 | +/// br bbContinue(%1: $S) -+ | forward-extended lifetime |
| 64 | +/// | |
| 65 | +/// bbContinue(%phi : $S): -+ OSSA lifetime | |
| 66 | +/// ... | | |
| 67 | +/// destroy_value %phi -+ -+ |
| 68 | +/// |
| 69 | +/// TODO: when phi lifetime flags are implemented, phis will introduce |
| 70 | +/// a lifetime in the same way as move_value. |
| 71 | +/// |
| 72 | +/// This walker is used to query basic lifetime attributes on values, |
| 73 | +/// such as "escaping" or "lexical". It must be precise for |
| 74 | +/// correctness and is performance critical. |
59 | 75 | protocol ForwardingUseDefWalker {
|
60 | 76 | mutating func introducer(_ value: Value) -> WalkResult
|
61 | 77 |
|
62 |
| - // Minimally, check a ValueSet. This walker may traverse chains of aggregation and destructuring along with phis. |
| 78 | + // Minimally, check a ValueSet. This walker may traverse chains of |
| 79 | + // aggregation and destructuring along with phis. |
63 | 80 | mutating func needWalk(for value: Value) -> Bool
|
64 | 81 |
|
65 | 82 | mutating func walkUp(value: Value) -> WalkResult
|
@@ -100,7 +117,8 @@ extension ForwardingUseDefWalker {
|
100 | 117 | }
|
101 | 118 | }
|
102 | 119 |
|
103 |
| -// This conveniently gathers all forward introducers and deinitializes visitedValues before the caller has a chance to recurse. |
| 120 | +// This conveniently gathers all forward introducers and deinitializes |
| 121 | +// visitedValues before the caller has a chance to recurse. |
104 | 122 | func gatherLifetimeIntroducers(for value: Value, _ context: Context) -> [Value] {
|
105 | 123 | var gather = GatherLifetimeIntroducers(context)
|
106 | 124 | defer { gather.visitedValues.deinitialize() }
|
@@ -145,14 +163,16 @@ enum ForwardingUseResult: CustomStringConvertible {
|
145 | 163 | }
|
146 | 164 | }
|
147 | 165 |
|
148 |
| -// Visit all the uses in a forward-extended lifetime (LifetimeIntroducer -> Operand). |
| 166 | +/// Visit all the uses in a forward-extended lifetime (LifetimeIntroducer -> Operand). |
149 | 167 | protocol ForwardingDefUseWalker {
|
150 |
| - // Minimally, check a ValueSet. This walker may traverse chains of aggregation and destructuring by default. Implementations may handle phis. |
| 168 | + // Minimally, check a ValueSet. This walker may traverse chains of |
| 169 | + // aggregation and destructuring by default. Implementations may |
| 170 | + // handle phis. |
151 | 171 | mutating func needWalk(for value: Value) -> Bool
|
152 | 172 |
|
153 | 173 | mutating func leafUse(_ operand: Operand) -> WalkResult
|
154 | 174 |
|
155 |
| - // Report any initial or forwarded with no uses. Only relevant for |
| 175 | + // Report any initial or forwarded value with no uses. Only relevant for |
156 | 176 | // guaranteed values or incomplete OSSA. This could be a dead
|
157 | 177 | // instruction, a terminator in which the result is dead on one
|
158 | 178 | // path, or a dead phi.
|
@@ -219,9 +239,9 @@ extension ForwardingDefUseWalker {
|
219 | 239 | }
|
220 | 240 | }
|
221 | 241 |
|
222 |
| -// This conveniently allows a closure to be called for each leaf use of a forward-extended lifetime. It should be called on a forward introducer provided by ForwardingDefUseWalker.introducer() or gatherLifetimeIntroducers(). |
223 |
| -// |
224 |
| -// TODO: make the visitor non-escaping once Swift supports stored non-escaping closues. |
| 242 | +/// This conveniently allows a closure to be called for each leaf use of a forward-extended lifetime. It should be called on a forward introducer provided by ForwardingDefUseWalker.introducer() or gatherLifetimeIntroducers(). |
| 243 | +/// |
| 244 | +/// TODO: make the visitor non-escaping once Swift supports stored non-escaping closues. |
225 | 245 | func visitForwardedUses(introducer: Value, _ context: Context,
|
226 | 246 | visitor: @escaping (ForwardingUseResult) -> WalkResult)
|
227 | 247 | -> WalkResult {
|
|
0 commit comments