@@ -51,6 +51,11 @@ findRootValueForNonTupleTempAllocation(AllocationInst *allocInst,
5151 }
5252 }
5353
54+ if (auto *sbi = dyn_cast<StoreBorrowInst>(&inst)) {
55+ if (sbi->getDest () == allocInst)
56+ return sbi->getSrc ();
57+ }
58+
5459 // If we do not identify the write... return SILValue(). We weren't able
5560 // to understand the write.
5661 break ;
@@ -128,6 +133,57 @@ static SILValue findRootValueForTupleTempAllocation(AllocationInst *allocInst,
128133
129134 if (auto *si = dyn_cast<StoreInst>(&inst)) {
130135 if (si->getOwnershipQualifier () != StoreOwnershipQualifier::Assign) {
136+ // Check if we are updating the entire tuple value.
137+ if (si->getDest () == allocInst) {
138+ // If we already found a root address (meaning we were processing
139+ // tuple_elt_addr), bail. We have some sort of unhandled mix of
140+ // copy_addr and store.
141+ if (foundRootAddress)
142+ return SILValue ();
143+
144+ // If we already found a destructure, return SILValue(). We are
145+ // initializing twice.
146+ if (foundDestructure)
147+ return SILValue ();
148+
149+ // We are looking for a pattern where we construct a tuple from
150+ // destructured parts.
151+ if (auto *ti = dyn_cast<TupleInst>(si->getSrc ())) {
152+ for (auto p : llvm::enumerate (ti->getOperandValues ())) {
153+ SILValue value = lookThroughOwnershipInsts (p.value ());
154+ if (auto *dti = dyn_cast_or_null<DestructureTupleInst>(
155+ value->getDefiningInstruction ())) {
156+ // We should always go through the same dti.
157+ if (foundDestructure && foundDestructure != dti)
158+ return SILValue ();
159+ if (!foundDestructure)
160+ foundDestructure = dti;
161+
162+ // If we have a mixmatch of indices, we cannot look through.
163+ if (p.index () != dti->getIndexOfResult (value))
164+ return SILValue ();
165+ if (tupleValues[p.index ()])
166+ return SILValue ();
167+ tupleValues[p.index ()] = value;
168+
169+ // If we have completely covered the tuple, break.
170+ --numEltsLeft;
171+ if (!numEltsLeft)
172+ break ;
173+ }
174+ }
175+
176+ // If we haven't completely covered the tuple, return SILValue(). We
177+ // should completely cover the tuple.
178+ if (numEltsLeft)
179+ return SILValue ();
180+
181+ // Otherwise, break since we are done.
182+ break ;
183+ }
184+ }
185+
186+ // If we store to a tuple_element_addr, update for a single value.
131187 if (auto *tei = dyn_cast<TupleElementAddrInst>(si->getDest ())) {
132188 if (tei->getOperand () == allocInst) {
133189 unsigned i = tei->getFieldIndex ();
@@ -183,7 +239,7 @@ static SILValue findRootValueForTupleTempAllocation(AllocationInst *allocInst,
183239
184240SILValue VariableNameInferrer::getRootValueForTemporaryAllocation (
185241 AllocationInst *allocInst) {
186- struct AddressWalker : public TransitiveAddressWalker <AddressWalker> {
242+ struct AddressWalker final : public TransitiveAddressWalker<AddressWalker> {
187243 AddressWalkerState &state;
188244
189245 AddressWalker (AddressWalkerState &state) : state(state) {}
@@ -194,6 +250,12 @@ SILValue VariableNameInferrer::getRootValueForTemporaryAllocation(
194250 return true ;
195251 }
196252
253+ TransitiveUseVisitation visitTransitiveUseAsEndPointUse (Operand *use) {
254+ if (auto *sbi = dyn_cast<StoreBorrowInst>(use->getUser ()))
255+ return TransitiveUseVisitation::OnlyUser;
256+ return TransitiveUseVisitation::OnlyUses;
257+ }
258+
197259 void onError (Operand *use) { state.foundError = true ; }
198260 };
199261
@@ -288,6 +350,13 @@ SILValue VariableNameInferrer::findDebugInfoProvidingValueHelper(
288350 return allocInst;
289351 }
290352
353+ // If we have a store_borrow, always look at the dest. We are going to see
354+ // if we can determine if dest is a temporary alloc_stack.
355+ if (auto *sbi = dyn_cast<StoreBorrowInst>(searchValue)) {
356+ searchValue = sbi->getDest ();
357+ continue ;
358+ }
359+
291360 if (auto *globalAddrInst = dyn_cast<GlobalAddrInst>(searchValue)) {
292361 variableNamePath.push_back (globalAddrInst);
293362 return globalAddrInst;
@@ -487,7 +556,9 @@ SILValue VariableNameInferrer::findDebugInfoProvidingValueHelper(
487556 isa<ConvertFunctionInst>(searchValue) ||
488557 isa<MarkUninitializedInst>(searchValue) ||
489558 isa<CopyableToMoveOnlyWrapperAddrInst>(searchValue) ||
490- isa<MoveOnlyWrapperToCopyableAddrInst>(searchValue)) {
559+ isa<MoveOnlyWrapperToCopyableAddrInst>(searchValue) ||
560+ isa<MoveOnlyWrapperToCopyableValueInst>(searchValue) ||
561+ isa<CopyableToMoveOnlyWrapperValueInst>(searchValue)) {
491562 searchValue = cast<SingleValueInstruction>(searchValue)->getOperand (0 );
492563 continue ;
493564 }
0 commit comments