Skip to content

Commit 7df13b3

Browse files
committed
[sil] Refactor VariableNameUtils for handling more kinds of writes to temporaries.
1 parent 2010579 commit 7df13b3

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

include/swift/SILOptimizer/Utils/VariableNameUtils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ class VariableNameInferrer {
104104
/// Finds the SILValue that either provides the direct debug information or
105105
/// that has a debug_value user that provides the name of the value.
106106
SILValue findDebugInfoProvidingValue(SILValue searchValue);
107+
108+
/// Given an initialized once allocation inst without a ValueDecl or a
109+
/// DebugVariable provided name, attempt to find a root value from its
110+
/// initialization.
111+
SILValue getRootValueForTemporaryAllocation(AllocationInst *allocInst);
107112
};
108113

109114
} // namespace swift

lib/SILOptimizer/Utils/VariableNameUtils.cpp

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,60 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/SILOptimizer/Utils/VariableNameUtils.h"
14+
#include "swift/SIL/AddressWalker.h"
1415
#include "swift/SIL/Test.h"
1516

1617
using 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+
1868
SILValue
1969
VariableNameInferrer::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

162207
void 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

Comments
 (0)