21
21
#include " swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
22
22
#include " swift/SILOptimizer/PassManager/Passes.h"
23
23
#include " swift/SILOptimizer/PassManager/Transforms.h"
24
+ #include " llvm/Support/raw_ostream.h"
24
25
25
26
using namespace swift ;
26
27
@@ -42,14 +43,18 @@ struct ValueToDeclInferrer {
42
43
using Argument = OptRemark::Argument;
43
44
using ArgumentKeyKind = OptRemark::ArgumentKeyKind;
44
45
45
- bool infer (ArgumentKeyKind keyKind, StringRef msg, SILValue value,
46
+ bool infer (ArgumentKeyKind keyKind, SILValue value,
46
47
function_ref<bool (Argument)> funcPassedInferedArgs);
47
48
};
48
49
49
50
} // anonymous namespace
50
51
52
+ static void printNote (llvm::raw_string_ostream &stream, const ValueDecl *decl) {
53
+ stream << " of '" << decl->getBaseName () << " '" ;
54
+ }
55
+
51
56
bool ValueToDeclInferrer::infer (
52
- ArgumentKeyKind keyKind, StringRef msg, SILValue value,
57
+ ArgumentKeyKind keyKind, SILValue value,
53
58
function_ref<bool (Argument)> funcPassedInferedArgs) {
54
59
55
60
// This is a linear IR traversal using a 'falling while loop'. That means
@@ -60,15 +65,27 @@ bool ValueToDeclInferrer::infer(
60
65
while (true ) {
61
66
// First check for "identified values" like arguments and global_addr.
62
67
if (auto *arg = dyn_cast<SILArgument>(value))
63
- if (auto *decl = arg->getDecl ())
68
+ if (auto *decl = arg->getDecl ()) {
69
+ std::string msg;
70
+ {
71
+ llvm::raw_string_ostream stream (msg);
72
+ printNote (stream, decl);
73
+ }
64
74
return funcPassedInferedArgs (
65
- Argument ({keyKind, " InferredValue" }, msg, decl));
75
+ Argument ({keyKind, " InferredValue" }, std::move (msg), decl));
76
+ }
66
77
67
78
if (auto *ga = dyn_cast<GlobalAddrInst>(value))
68
- if (auto *decl = ga->getReferencedGlobal ()->getDecl ())
79
+ if (auto *decl = ga->getReferencedGlobal ()->getDecl ()) {
80
+ std::string msg;
81
+ {
82
+ llvm::raw_string_ostream stream (msg);
83
+ printNote (stream, decl);
84
+ }
69
85
if (!funcPassedInferedArgs (
70
- Argument ({keyKind, " InferredValue" }, msg, decl)))
86
+ Argument ({keyKind, " InferredValue" }, std::move ( msg) , decl)))
71
87
return false ;
88
+ }
72
89
73
90
// Then visit our users and see if we can find a debug_value that provides
74
91
// us with a decl we can use to construct an argument.
@@ -78,15 +95,23 @@ bool ValueToDeclInferrer::infer(
78
95
continue ;
79
96
80
97
if (auto *dvi = dyn_cast<DebugValueInst>(use->getUser ())) {
81
- if (auto *decl = dvi->getDecl ())
98
+ if (auto *decl = dvi->getDecl ()) {
99
+ std::string msg;
100
+ {
101
+ llvm::raw_string_ostream stream (msg);
102
+ printNote (stream, decl);
103
+ }
82
104
if (!funcPassedInferedArgs (
83
- Argument ({keyKind, " InferredValue" }, msg, decl)))
105
+ Argument ({keyKind, " InferredValue" }, std::move ( msg) , decl)))
84
106
return false ;
107
+ }
85
108
}
86
109
}
87
110
88
111
// At this point, we could not infer any argument. See if we can look
89
- // through loads, geps to construct a ProjectionPath.
112
+ // through loads.
113
+ //
114
+ // TODO: Add GEPs to construct a ProjectionPath.
90
115
91
116
// Finally, see if we can look through a load...
92
117
if (auto *li = dyn_cast<LoadInst>(value)) {
@@ -135,24 +160,19 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
135
160
using namespace OptRemark ;
136
161
SILValue root = rcfi.getRCIdentityRoot (sri->getOperand ());
137
162
SmallVector<Argument, 8 > inferredArgs;
138
- bool foundArgs = valueToDeclInferrer.infer (
139
- ArgumentKeyKind::Note, " on value: " , root, [&](Argument arg) {
140
- inferredArgs.push_back (arg);
141
- return true ;
142
- });
163
+ bool foundArgs = valueToDeclInferrer.infer (ArgumentKeyKind::Note, root,
164
+ [&](Argument arg) {
165
+ inferredArgs.push_back (arg);
166
+ return true ;
167
+ });
143
168
(void )foundArgs;
144
169
145
170
// Retains begin a lifetime scope so we infer scan forward.
146
- auto remark = RemarkMissed (" memory-management " , *sri,
171
+ auto remark = RemarkMissed (" memory" , *sri,
147
172
SourceLocInferenceBehavior::ForwardScanOnly)
148
- << " Found retain:" ;
149
- if (inferredArgs.empty ()) {
150
- remark << Argument ({ArgumentKeyKind::ParentLocNote, " InferValueFailure" },
151
- " Unable to infer any values being retained." );
152
- } else {
153
- for (auto arg : inferredArgs) {
154
- remark << arg;
155
- }
173
+ << " retain" ;
174
+ for (auto arg : inferredArgs) {
175
+ remark << arg;
156
176
}
157
177
return remark;
158
178
});
@@ -165,22 +185,18 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
165
185
// Releases end a lifetime scope so we infer scan backward.
166
186
SILValue root = rcfi.getRCIdentityRoot (sri->getOperand ());
167
187
SmallVector<Argument, 8 > inferredArgs;
168
- bool foundArgs = valueToDeclInferrer.infer (
169
- ArgumentKeyKind::Note, " on value: " , root, [&](Argument arg) {
170
- inferredArgs.push_back (arg);
171
- return true ;
172
- });
188
+ bool foundArgs = valueToDeclInferrer.infer (ArgumentKeyKind::Note, root,
189
+ [&](Argument arg) {
190
+ inferredArgs.push_back (arg);
191
+ return true ;
192
+ });
173
193
(void )foundArgs;
174
- auto remark = RemarkMissed (" memory-management" , *sri,
194
+
195
+ auto remark = RemarkMissed (" memory" , *sri,
175
196
SourceLocInferenceBehavior::BackwardScanOnly)
176
- << " Found release:" ;
177
- if (inferredArgs.empty ()) {
178
- remark << Argument ({ArgumentKeyKind::ParentLocNote, " InferValueFailure" },
179
- " Unable to infer any values being released." );
180
- } else {
181
- for (auto arg : inferredArgs) {
182
- remark << arg;
183
- }
197
+ << " release" ;
198
+ for (auto arg : inferredArgs) {
199
+ remark << arg;
184
200
}
185
201
return remark;
186
202
});
@@ -192,24 +208,19 @@ void OptRemarkGeneratorInstructionVisitor::visitRetainValueInst(
192
208
using namespace OptRemark ;
193
209
SILValue root = rcfi.getRCIdentityRoot (rvi->getOperand ());
194
210
SmallVector<Argument, 8 > inferredArgs;
195
- bool foundArgs = valueToDeclInferrer.infer (
196
- ArgumentKeyKind::Note, " on value: " , root, [&](Argument arg) {
197
- inferredArgs.push_back (arg);
198
- return true ;
199
- });
211
+ bool foundArgs = valueToDeclInferrer.infer (ArgumentKeyKind::Note, root,
212
+ [&](Argument arg) {
213
+ inferredArgs.push_back (arg);
214
+ return true ;
215
+ });
200
216
(void )foundArgs;
201
217
202
218
// Retains begin a lifetime scope, so we infer scan forwards.
203
- auto remark = RemarkMissed (" memory-management " , *rvi,
219
+ auto remark = RemarkMissed (" memory" , *rvi,
204
220
SourceLocInferenceBehavior::ForwardScanOnly)
205
- << " Found retain:" ;
206
- if (inferredArgs.empty ()) {
207
- remark << Argument ({ArgumentKeyKind::ParentLocNote, " InferValueFailure" },
208
- " Unable to infer any values being retained." );
209
- } else {
210
- for (auto arg : inferredArgs) {
211
- remark << arg;
212
- }
221
+ << " retain" ;
222
+ for (auto arg : inferredArgs) {
223
+ remark << arg;
213
224
}
214
225
return remark;
215
226
});
@@ -221,26 +232,20 @@ void OptRemarkGeneratorInstructionVisitor::visitReleaseValueInst(
221
232
using namespace OptRemark ;
222
233
SILValue root = rcfi.getRCIdentityRoot (rvi->getOperand ());
223
234
SmallVector<Argument, 8 > inferredArgs;
224
- bool foundArgs = valueToDeclInferrer.infer (
225
- ArgumentKeyKind::Note, " on value: " , root, [&](Argument arg) {
226
- inferredArgs.push_back (arg);
227
- return true ;
228
- });
235
+ bool foundArgs = valueToDeclInferrer.infer (ArgumentKeyKind::Note, root,
236
+ [&](Argument arg) {
237
+ inferredArgs.push_back (arg);
238
+ return true ;
239
+ });
229
240
(void )foundArgs;
230
241
231
242
// Releases end a lifetime scope so we infer scan backward.
232
- auto remark = RemarkMissed (" memory-management " , *rvi,
243
+ auto remark = RemarkMissed (" memory" , *rvi,
233
244
SourceLocInferenceBehavior::BackwardScanOnly)
234
- << " Found release:" ;
235
- if (inferredArgs.empty ()) {
236
- remark << Argument ({ArgumentKeyKind::ParentLocNote, " InferValueFailure" },
237
- " Unable to infer any values being released." );
238
- } else {
239
- for (auto arg : inferredArgs) {
240
- remark << arg;
241
- }
245
+ << " release" ;
246
+ for (auto arg : inferredArgs) {
247
+ remark << arg;
242
248
}
243
-
244
249
return remark;
245
250
});
246
251
}
0 commit comments