@@ -48,6 +48,7 @@ class TransitiveAddressWalker {
4848 // / Whether we could tell if this address use didn't escape, did have a
4949 // / pointer escape, or unknown if we failed to understand something.
5050 AddressUseKind result = AddressUseKind::NonEscaping;
51+ Operand *escapingUse = nullptr ;
5152
5253 unsigned didInvalidate = false ;
5354
@@ -83,6 +84,11 @@ class TransitiveAddressWalker {
8384 result = swift::meet (result, other);
8485 }
8586
87+ void recordEscape (Operand *op, AddressUseKind kind = AddressUseKind::PointerEscape) {
88+ meet (kind);
89+ escapingUse = op;
90+ }
91+
8692private:
8793 // / Shim that actually calls visitUse and changes early exit.
8894 void callVisitUse (Operand *use) {
@@ -92,12 +98,16 @@ class TransitiveAddressWalker {
9298 }
9399
94100public:
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; }
96106};
97107
98108template <typename Impl>
99109inline AddressUseKind
100- TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
110+ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) {
101111 assert (!didInvalidate);
102112
103113 // 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) && {
155165 case TermKind::CondBranchInst:
156166 // We could have an address phi. To be conservative, just treat this as
157167 // a point escape.
158- meet (AddressUseKind::PointerEscape );
168+ recordEscape (op );
159169 for (auto succBlockArgList : ti->getSuccessorBlockArgumentLists ()) {
160170 auto *succ = succBlockArgList[op->getOperandNumber ()];
161171 for (auto *use : succ->getUses ())
@@ -185,10 +195,13 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
185195 }
186196 }
187197
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);
192205 callVisitUse (op);
193206 continue ;
194207 }
@@ -297,7 +310,7 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
297310 // address. See AddressUtils.swift. Until that is implemented, this must
298311 // be considered a pointer escape.
299312 if (op->get () == mdi->getBase ()) {
300- meet ( AddressUseKind::PointerEscape );
313+ recordEscape (op, AddressUseKind::Dependent );
301314 callVisitUse (op);
302315 continue ;
303316 }
0 commit comments