1111// ===----------------------------------------------------------------------===//
1212
1313#include " swift/SILOptimizer/Utils/VariableNameUtils.h"
14+ #include " swift/SIL/AddressWalker.h"
1415#include " swift/SIL/Test.h"
1516
1617using namespace swift ;
1718
19+ SILValue VariableNameInferrer::getRootValueForTemporaryAllocation (
20+ AllocationInst *allocInst) {
21+ struct AddressWalkerState {
22+ bool foundError = false ;
23+ InstructionSet writes;
24+ AddressWalkerState (SILFunction *fn) : writes(fn) {}
25+ };
26+
27+ struct AddressWalker : public TransitiveAddressWalker <AddressWalker> {
28+ AddressWalkerState &state;
29+
30+ AddressWalker (AddressWalkerState &state) : state(state) {}
31+
32+ bool visitUse (Operand *use) {
33+ if (use->getUser ()->mayWriteToMemory ())
34+ state.writes .insert (use->getUser ());
35+ return true ;
36+ }
37+
38+ void onError (Operand *use) { state.foundError = true ; }
39+ };
40+
41+ AddressWalkerState state (allocInst->getFunction ());
42+ AddressWalker walker (state);
43+ if (std::move (walker).walk (allocInst) == AddressUseKind::Unknown ||
44+ state.foundError )
45+ return SILValue ();
46+
47+ // Walk from our allocation to one of our writes. Then make sure that the
48+ // write writes to our entire value.
49+ for (auto &inst : allocInst->getParent ()->getRangeStartingAtInst (allocInst)) {
50+ if (!state.writes .contains (&inst))
51+ continue ;
52+
53+ if (auto *copyAddr = dyn_cast<CopyAddrInst>(&inst)) {
54+ if (copyAddr->getDest () == allocInst &&
55+ copyAddr->isInitializationOfDest ()) {
56+ return copyAddr->getSrc ();
57+ }
58+ }
59+
60+ // If we do not identify the write... return SILValue(). We weren't able to
61+ // understand the write.
62+ return SILValue ();
63+ }
64+
65+ return SILValue ();
66+ }
67+
1868SILValue
1969VariableNameInferrer::findDebugInfoProvidingValue (SILValue searchValue) {
2070 if (!searchValue)
@@ -33,16 +83,11 @@ VariableNameInferrer::findDebugInfoProvidingValue(SILValue searchValue) {
3383 };
3484
3585 if (!allocInstHasInfo (allocInst)) {
36- if (auto copy = allocInst->getSingleUserOfType <CopyAddrInst>()) {
37- if (copy->getDest () == allocInst && !copy->isTakeOfSrc () &&
38- copy->isInitializationOfDest ()) {
39- searchValue = copy->getSrc ();
40- continue ;
41- }
86+ if (auto value = getRootValueForTemporaryAllocation (allocInst)) {
87+ searchValue = value;
88+ continue ;
4289 }
4390
44- // If we didn't find anything and did not have a decl, return SILValue()
45- // so that we fail.
4691 return SILValue ();
4792 }
4893
@@ -160,6 +205,9 @@ static StringRef getNameFromDecl(Decl *d) {
160205}
161206
162207void VariableNameInferrer::drainVariableNamePath () {
208+ if (variableNamePath.empty ())
209+ return ;
210+
163211 // Walk backwards, constructing our string.
164212 while (true ) {
165213 auto next = variableNamePath.pop_back_val ();
0 commit comments