@@ -51,6 +51,11 @@ findRootValueForNonTupleTempAllocation(AllocationInst *allocInst,
51
51
}
52
52
}
53
53
54
+ if (auto *sbi = dyn_cast<StoreBorrowInst>(&inst)) {
55
+ if (sbi->getDest () == allocInst)
56
+ return sbi->getSrc ();
57
+ }
58
+
54
59
// If we do not identify the write... return SILValue(). We weren't able
55
60
// to understand the write.
56
61
break ;
@@ -128,6 +133,57 @@ static SILValue findRootValueForTupleTempAllocation(AllocationInst *allocInst,
128
133
129
134
if (auto *si = dyn_cast<StoreInst>(&inst)) {
130
135
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.
131
187
if (auto *tei = dyn_cast<TupleElementAddrInst>(si->getDest ())) {
132
188
if (tei->getOperand () == allocInst) {
133
189
unsigned i = tei->getFieldIndex ();
@@ -183,7 +239,7 @@ static SILValue findRootValueForTupleTempAllocation(AllocationInst *allocInst,
183
239
184
240
SILValue VariableNameInferrer::getRootValueForTemporaryAllocation (
185
241
AllocationInst *allocInst) {
186
- struct AddressWalker : public TransitiveAddressWalker <AddressWalker> {
242
+ struct AddressWalker final : public TransitiveAddressWalker<AddressWalker> {
187
243
AddressWalkerState &state;
188
244
189
245
AddressWalker (AddressWalkerState &state) : state(state) {}
@@ -194,6 +250,12 @@ SILValue VariableNameInferrer::getRootValueForTemporaryAllocation(
194
250
return true ;
195
251
}
196
252
253
+ TransitiveUseVisitation visitTransitiveUseAsEndPointUse (Operand *use) {
254
+ if (auto *sbi = dyn_cast<StoreBorrowInst>(use->getUser ()))
255
+ return TransitiveUseVisitation::OnlyUser;
256
+ return TransitiveUseVisitation::OnlyUses;
257
+ }
258
+
197
259
void onError (Operand *use) { state.foundError = true ; }
198
260
};
199
261
@@ -288,6 +350,13 @@ SILValue VariableNameInferrer::findDebugInfoProvidingValueHelper(
288
350
return allocInst;
289
351
}
290
352
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
+
291
360
if (auto *globalAddrInst = dyn_cast<GlobalAddrInst>(searchValue)) {
292
361
variableNamePath.push_back (globalAddrInst);
293
362
return globalAddrInst;
@@ -487,7 +556,9 @@ SILValue VariableNameInferrer::findDebugInfoProvidingValueHelper(
487
556
isa<ConvertFunctionInst>(searchValue) ||
488
557
isa<MarkUninitializedInst>(searchValue) ||
489
558
isa<CopyableToMoveOnlyWrapperAddrInst>(searchValue) ||
490
- isa<MoveOnlyWrapperToCopyableAddrInst>(searchValue)) {
559
+ isa<MoveOnlyWrapperToCopyableAddrInst>(searchValue) ||
560
+ isa<MoveOnlyWrapperToCopyableValueInst>(searchValue) ||
561
+ isa<CopyableToMoveOnlyWrapperValueInst>(searchValue)) {
491
562
searchValue = cast<SingleValueInstruction>(searchValue)->getOperand (0 );
492
563
continue ;
493
564
}
0 commit comments