@@ -48,6 +48,7 @@ class TransitiveAddressWalker {
48
48
// / Whether we could tell if this address use didn't escape, did have a
49
49
// / pointer escape, or unknown if we failed to understand something.
50
50
AddressUseKind result = AddressUseKind::NonEscaping;
51
+ Operand *escapingUse = nullptr ;
51
52
52
53
unsigned didInvalidate = false ;
53
54
@@ -83,6 +84,11 @@ class TransitiveAddressWalker {
83
84
result = swift::meet (result, other);
84
85
}
85
86
87
+ void recordEscape (Operand *op, AddressUseKind kind = AddressUseKind::PointerEscape) {
88
+ meet (kind);
89
+ escapingUse = op;
90
+ }
91
+
86
92
private:
87
93
// / Shim that actually calls visitUse and changes early exit.
88
94
void callVisitUse (Operand *use) {
@@ -92,12 +98,16 @@ class TransitiveAddressWalker {
92
98
}
93
99
94
100
public:
95
- AddressUseKind walk (SILValue address) &&;
101
+ AddressUseKind walk (SILValue address);
102
+
103
+ // If the result of walk() is not NonEscaping, this returns a non-null
104
+ // operand that caused the escape or unknown use.
105
+ Operand *getEscapingUse () const { return escapingUse; }
96
106
};
97
107
98
108
template <typename Impl>
99
109
inline AddressUseKind
100
- TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
110
+ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) {
101
111
assert (!didInvalidate);
102
112
103
113
// When we exit, set the result to be invalidated so we can't use this again.
@@ -155,7 +165,7 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
155
165
case TermKind::CondBranchInst:
156
166
// We could have an address phi. To be conservative, just treat this as
157
167
// a point escape.
158
- meet (AddressUseKind::PointerEscape );
168
+ recordEscape (op );
159
169
for (auto succBlockArgList : ti->getSuccessorBlockArgumentLists ()) {
160
170
auto *succ = succBlockArgList[op->getOperandNumber ()];
161
171
for (auto *use : succ->getUses ())
@@ -185,10 +195,13 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
185
195
}
186
196
}
187
197
188
- // TODO: Partial apply should be NonEscaping, but then we need to consider
189
- // the apply to be a use point.
190
- if (isa<PartialApplyInst>(user) || isa<AddressToPointerInst>(user)) {
191
- meet (AddressUseKind::PointerEscape);
198
+ if (isa<PartialApplyInst>(user)) {
199
+ recordEscape (op, AddressUseKind::Dependent);
200
+ callVisitUse (op);
201
+ continue ;
202
+ }
203
+ if (isa<AddressToPointerInst>(user)) {
204
+ recordEscape (op);
192
205
callVisitUse (op);
193
206
continue ;
194
207
}
@@ -297,7 +310,7 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
297
310
// address. See AddressUtils.swift. Until that is implemented, this must
298
311
// be considered a pointer escape.
299
312
if (op->get () == mdi->getBase ()) {
300
- meet ( AddressUseKind::PointerEscape );
313
+ recordEscape (op, AddressUseKind::Dependent );
301
314
callVisitUse (op);
302
315
continue ;
303
316
}
0 commit comments