11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " swift/SILOptimizer/Utils/VariableNameUtils.h"
14
+ #include " swift/SIL/AddressWalker.h"
14
15
#include " swift/SIL/Test.h"
15
16
16
17
using namespace swift ;
17
18
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
+
18
68
SILValue
19
69
VariableNameInferrer::findDebugInfoProvidingValue (SILValue searchValue) {
20
70
if (!searchValue)
@@ -33,16 +83,11 @@ VariableNameInferrer::findDebugInfoProvidingValue(SILValue searchValue) {
33
83
};
34
84
35
85
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 ;
42
89
}
43
90
44
- // If we didn't find anything and did not have a decl, return SILValue()
45
- // so that we fail.
46
91
return SILValue ();
47
92
}
48
93
@@ -160,6 +205,9 @@ static StringRef getNameFromDecl(Decl *d) {
160
205
}
161
206
162
207
void VariableNameInferrer::drainVariableNamePath () {
208
+ if (variableNamePath.empty ())
209
+ return ;
210
+
163
211
// Walk backwards, constructing our string.
164
212
while (true ) {
165
213
auto next = variableNamePath.pop_back_val ();
0 commit comments