Skip to content

Commit c3595ad

Browse files
authored
Merge pull request swiftlang#33115 from gottesmm/pr-3b1ab9c8196e6decb2b6b49cbf4f5b44435ed2c9
[opt-remark] Move Argument::inferArgumentFromValue into OptRemarkGenerator.
2 parents c042638 + 2f3670f commit c3595ad

File tree

3 files changed

+85
-53
lines changed

3 files changed

+85
-53
lines changed

include/swift/SIL/OptimizationRemark.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -119,19 +119,6 @@ struct Argument {
119119
: Argument(ArgumentKey(ArgumentKeyKind::Default, key), msg, decl) {}
120120
Argument(ArgumentKey key, StringRef msg, const ValueDecl *decl)
121121
: key(key), val(msg), loc(decl->getLoc()) {}
122-
123-
/// Given a value, call \p funcPassedInferredArgs for each associated
124-
/// ValueDecl that is associated with \p value. All created Arguments are
125-
/// passed the same StringRef. To stop iteration, return false in \p
126-
/// funcPassedInferedArgs.
127-
///
128-
/// NOTE: the function may be called multiple times if the optimizer joined
129-
/// two live ranges and thus when iterating over value's users we see multiple
130-
/// debug_value operations.
131-
static bool
132-
inferArgumentsForValue(ArgumentKeyKind keyKind, StringRef message,
133-
SILValue value,
134-
function_ref<bool(Argument)> funcPassedInferedArgs);
135122
};
136123

137124
/// Shorthand to insert named-value pairs.

lib/SIL/Utils/OptimizationRemark.cpp

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -77,42 +77,6 @@ Argument::Argument(StringRef key, CanType ty)
7777
ty.print(stream);
7878
}
7979

80-
bool Argument::inferArgumentsForValue(
81-
ArgumentKeyKind keyKind, StringRef msg, SILValue value,
82-
function_ref<bool(Argument)> funcPassedInferedArgs) {
83-
84-
while (true) {
85-
// If we have an argument, just use that.
86-
if (auto *arg = dyn_cast<SILArgument>(value))
87-
if (auto *decl = arg->getDecl())
88-
return funcPassedInferedArgs(
89-
Argument({keyKind, "InferredValue"}, msg, decl));
90-
91-
// Otherwise, look for debug_values.
92-
for (auto *use : getDebugUses(value))
93-
if (auto *dvi = dyn_cast<DebugValueInst>(use->getUser()))
94-
if (auto *decl = dvi->getDecl())
95-
if (!funcPassedInferedArgs(
96-
Argument({keyKind, "InferredValue"}, msg, decl)))
97-
return false;
98-
99-
// If we have a load, look through it and continue. We may have a global or
100-
// a function argument.
101-
if (auto *li = dyn_cast<LoadInst>(value)) {
102-
value = stripAccessMarkers(li->getOperand());
103-
continue;
104-
}
105-
106-
if (auto *ga = dyn_cast<GlobalAddrInst>(value))
107-
if (auto *decl = ga->getReferencedGlobal()->getDecl())
108-
if (!funcPassedInferedArgs(
109-
Argument({keyKind, "InferredValue"}, msg, decl)))
110-
return false;
111-
112-
return true;
113-
}
114-
}
115-
11680
template <typename DerivedT>
11781
std::string Remark<DerivedT>::getMsg() const {
11882
std::string str;

lib/SILOptimizer/Transforms/OptRemarkGenerator.cpp

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#define DEBUG_TYPE "sil-opt-remark-gen"
1414

15+
#include "swift/SIL/MemAccessUtils.h"
1516
#include "swift/SIL/OptimizationRemark.h"
1617
#include "swift/SIL/SILFunction.h"
1718
#include "swift/SIL/SILInstruction.h"
@@ -23,6 +24,82 @@
2324

2425
using namespace swift;
2526

27+
//===----------------------------------------------------------------------===//
28+
// Utility
29+
//===----------------------------------------------------------------------===//
30+
31+
namespace {
32+
33+
/// Given a value, call \p funcPassedInferredArgs for each associated
34+
/// ValueDecl that is associated with \p value. All created Arguments are
35+
/// passed the same StringRef. To stop iteration, return false in \p
36+
/// funcPassedInferedArgs.
37+
///
38+
/// NOTE: the function may be called multiple times if the optimizer joined
39+
/// two live ranges and thus when iterating over value's users we see multiple
40+
/// debug_value operations.
41+
struct ValueToDeclInferrer {
42+
using Argument = OptRemark::Argument;
43+
using ArgumentKeyKind = OptRemark::ArgumentKeyKind;
44+
45+
bool infer(ArgumentKeyKind keyKind, StringRef msg, SILValue value,
46+
function_ref<bool(Argument)> funcPassedInferedArgs);
47+
};
48+
49+
} // anonymous namespace
50+
51+
bool ValueToDeclInferrer::infer(
52+
ArgumentKeyKind keyKind, StringRef msg, SILValue value,
53+
function_ref<bool(Argument)> funcPassedInferedArgs) {
54+
55+
// This is a linear IR traversal using a 'falling while loop'. That means
56+
// every time through the loop we are trying to handle a case before we hit
57+
// the bottom of the while loop where we always return true (since we did not
58+
// hit a could not compute case). Reassign value and continue to go to the
59+
// next step.
60+
while (true) {
61+
// First check for "identified values" like arguments and global_addr.
62+
if (auto *arg = dyn_cast<SILArgument>(value))
63+
if (auto *decl = arg->getDecl())
64+
return funcPassedInferedArgs(
65+
Argument({keyKind, "InferredValue"}, msg, decl));
66+
67+
if (auto *ga = dyn_cast<GlobalAddrInst>(value))
68+
if (auto *decl = ga->getReferencedGlobal()->getDecl())
69+
if (!funcPassedInferedArgs(
70+
Argument({keyKind, "InferredValue"}, msg, decl)))
71+
return false;
72+
73+
// Then visit our users and see if we can find a debug_value that provides
74+
// us with a decl we can use to construct an argument.
75+
for (auto *use : value->getUses()) {
76+
// Skip type dependent uses.
77+
if (use->isTypeDependent())
78+
continue;
79+
80+
if (auto *dvi = dyn_cast<DebugValueInst>(use->getUser())) {
81+
if (auto *decl = dvi->getDecl())
82+
if (!funcPassedInferedArgs(
83+
Argument({keyKind, "InferredValue"}, msg, decl)))
84+
return false;
85+
}
86+
}
87+
88+
// At this point, we could not infer any argument. See if we can look
89+
// through loads, geps to construct a ProjectionPath.
90+
91+
// Finally, see if we can look through a load...
92+
if (auto *li = dyn_cast<LoadInst>(value)) {
93+
value = stripAccessMarkers(li->getOperand());
94+
continue;
95+
}
96+
97+
// If we reached this point, we finished falling through the loop and return
98+
// true.
99+
return true;
100+
}
101+
}
102+
26103
//===----------------------------------------------------------------------===//
27104
// Opt Remark Generator Visitor
28105
//===----------------------------------------------------------------------===//
@@ -35,6 +112,10 @@ struct OptRemarkGeneratorInstructionVisitor
35112
RCIdentityFunctionInfo &rcfi;
36113
OptRemark::Emitter ORE;
37114

115+
/// A class that we use to infer the decl that is associated with a
116+
/// miscellaneous SIL value. This is just a heuristic that is to taste.
117+
ValueToDeclInferrer valueToDeclInferrer;
118+
38119
OptRemarkGeneratorInstructionVisitor(SILFunction &fn,
39120
RCIdentityFunctionInfo &rcfi)
40121
: mod(fn.getModule()), rcfi(rcfi), ORE(DEBUG_TYPE, fn) {}
@@ -54,7 +135,7 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
54135
using namespace OptRemark;
55136
SILValue root = rcfi.getRCIdentityRoot(sri->getOperand());
56137
SmallVector<Argument, 8> inferredArgs;
57-
bool foundArgs = Argument::inferArgumentsForValue(
138+
bool foundArgs = valueToDeclInferrer.infer(
58139
ArgumentKeyKind::Note, "on value:", root, [&](Argument arg) {
59140
inferredArgs.push_back(arg);
60141
return true;
@@ -84,7 +165,7 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
84165
// Releases end a lifetime scope so we infer scan backward.
85166
SILValue root = rcfi.getRCIdentityRoot(sri->getOperand());
86167
SmallVector<Argument, 8> inferredArgs;
87-
bool foundArgs = Argument::inferArgumentsForValue(
168+
bool foundArgs = valueToDeclInferrer.infer(
88169
ArgumentKeyKind::Note, "on value:", root, [&](Argument arg) {
89170
inferredArgs.push_back(arg);
90171
return true;
@@ -111,7 +192,7 @@ void OptRemarkGeneratorInstructionVisitor::visitRetainValueInst(
111192
using namespace OptRemark;
112193
SILValue root = rcfi.getRCIdentityRoot(rvi->getOperand());
113194
SmallVector<Argument, 8> inferredArgs;
114-
bool foundArgs = Argument::inferArgumentsForValue(
195+
bool foundArgs = valueToDeclInferrer.infer(
115196
ArgumentKeyKind::Note, "on value:", root, [&](Argument arg) {
116197
inferredArgs.push_back(arg);
117198
return true;
@@ -140,7 +221,7 @@ void OptRemarkGeneratorInstructionVisitor::visitReleaseValueInst(
140221
using namespace OptRemark;
141222
SILValue root = rcfi.getRCIdentityRoot(rvi->getOperand());
142223
SmallVector<Argument, 8> inferredArgs;
143-
bool foundArgs = Argument::inferArgumentsForValue(
224+
bool foundArgs = valueToDeclInferrer.infer(
144225
ArgumentKeyKind::Note, "on value:", root, [&](Argument arg) {
145226
inferredArgs.push_back(arg);
146227
return true;

0 commit comments

Comments
 (0)