12
12
13
13
#define DEBUG_TYPE " sil-opt-remark-gen"
14
14
15
+ #include " swift/AST/SemanticAttrs.h"
15
16
#include " swift/SIL/MemAccessUtils.h"
16
17
#include " swift/SIL/OptimizationRemark.h"
18
+ #include " swift/SIL/Projection.h"
17
19
#include " swift/SIL/SILFunction.h"
18
20
#include " swift/SIL/SILInstruction.h"
19
21
#include " swift/SIL/SILModule.h"
20
22
#include " swift/SIL/SILVisitor.h"
21
23
#include " swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
22
24
#include " swift/SILOptimizer/PassManager/Passes.h"
23
25
#include " swift/SILOptimizer/PassManager/Transforms.h"
26
+ #include " llvm/Support/raw_ostream.h"
24
27
25
28
using namespace swift ;
26
29
@@ -42,14 +45,18 @@ struct ValueToDeclInferrer {
42
45
using Argument = OptRemark::Argument;
43
46
using ArgumentKeyKind = OptRemark::ArgumentKeyKind;
44
47
45
- bool infer (ArgumentKeyKind keyKind, StringRef msg, SILValue value,
48
+ bool infer (ArgumentKeyKind keyKind, SILValue value,
46
49
function_ref<bool (Argument)> funcPassedInferedArgs);
47
50
};
48
51
49
52
} // anonymous namespace
50
53
54
+ static void printNote (llvm::raw_string_ostream &stream, const ValueDecl *decl) {
55
+ stream << " of '" << decl->getBaseName () << " '" ;
56
+ }
57
+
51
58
bool ValueToDeclInferrer::infer (
52
- ArgumentKeyKind keyKind, StringRef msg, SILValue value,
59
+ ArgumentKeyKind keyKind, SILValue value,
53
60
function_ref<bool (Argument)> funcPassedInferedArgs) {
54
61
55
62
// This is a linear IR traversal using a 'falling while loop'. That means
@@ -60,15 +67,27 @@ bool ValueToDeclInferrer::infer(
60
67
while (true ) {
61
68
// First check for "identified values" like arguments and global_addr.
62
69
if (auto *arg = dyn_cast<SILArgument>(value))
63
- if (auto *decl = arg->getDecl ())
70
+ if (auto *decl = arg->getDecl ()) {
71
+ std::string msg;
72
+ {
73
+ llvm::raw_string_ostream stream (msg);
74
+ printNote (stream, decl);
75
+ }
64
76
return funcPassedInferedArgs (
65
- Argument ({keyKind, " InferredValue" }, msg, decl));
77
+ Argument ({keyKind, " InferredValue" }, std::move (msg), decl));
78
+ }
66
79
67
80
if (auto *ga = dyn_cast<GlobalAddrInst>(value))
68
- if (auto *decl = ga->getReferencedGlobal ()->getDecl ())
81
+ if (auto *decl = ga->getReferencedGlobal ()->getDecl ()) {
82
+ std::string msg;
83
+ {
84
+ llvm::raw_string_ostream stream (msg);
85
+ printNote (stream, decl);
86
+ }
69
87
if (!funcPassedInferedArgs (
70
- Argument ({keyKind, " InferredValue" }, msg, decl)))
88
+ Argument ({keyKind, " InferredValue" }, std::move ( msg) , decl)))
71
89
return false ;
90
+ }
72
91
73
92
// Then visit our users and see if we can find a debug_value that provides
74
93
// us with a decl we can use to construct an argument.
@@ -78,15 +97,23 @@ bool ValueToDeclInferrer::infer(
78
97
continue ;
79
98
80
99
if (auto *dvi = dyn_cast<DebugValueInst>(use->getUser ())) {
81
- if (auto *decl = dvi->getDecl ())
100
+ if (auto *decl = dvi->getDecl ()) {
101
+ std::string msg;
102
+ {
103
+ llvm::raw_string_ostream stream (msg);
104
+ printNote (stream, decl);
105
+ }
82
106
if (!funcPassedInferedArgs (
83
- Argument ({keyKind, " InferredValue" }, msg, decl)))
107
+ Argument ({keyKind, " InferredValue" }, std::move ( msg) , decl)))
84
108
return false ;
109
+ }
85
110
}
86
111
}
87
112
88
113
// At this point, we could not infer any argument. See if we can look
89
- // through loads, geps to construct a ProjectionPath.
114
+ // through loads.
115
+ //
116
+ // TODO: Add GEPs to construct a ProjectionPath.
90
117
91
118
// Finally, see if we can look through a load...
92
119
if (auto *li = dyn_cast<LoadInst>(value)) {
@@ -135,24 +162,19 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
135
162
using namespace OptRemark ;
136
163
SILValue root = rcfi.getRCIdentityRoot (sri->getOperand ());
137
164
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
- });
165
+ bool foundArgs = valueToDeclInferrer.infer (ArgumentKeyKind::Note, root,
166
+ [&](Argument arg) {
167
+ inferredArgs.push_back (arg);
168
+ return true ;
169
+ });
143
170
(void )foundArgs;
144
171
145
172
// Retains begin a lifetime scope so we infer scan forward.
146
- auto remark = RemarkMissed (" memory-management " , *sri,
173
+ auto remark = RemarkMissed (" memory" , *sri,
147
174
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
- }
175
+ << " retain" ;
176
+ for (auto arg : inferredArgs) {
177
+ remark << arg;
156
178
}
157
179
return remark;
158
180
});
@@ -165,22 +187,18 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
165
187
// Releases end a lifetime scope so we infer scan backward.
166
188
SILValue root = rcfi.getRCIdentityRoot (sri->getOperand ());
167
189
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
- });
190
+ bool foundArgs = valueToDeclInferrer.infer (ArgumentKeyKind::Note, root,
191
+ [&](Argument arg) {
192
+ inferredArgs.push_back (arg);
193
+ return true ;
194
+ });
173
195
(void )foundArgs;
174
- auto remark = RemarkMissed (" memory-management" , *sri,
196
+
197
+ auto remark = RemarkMissed (" memory" , *sri,
175
198
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
- }
199
+ << " release" ;
200
+ for (auto arg : inferredArgs) {
201
+ remark << arg;
184
202
}
185
203
return remark;
186
204
});
@@ -192,24 +210,19 @@ void OptRemarkGeneratorInstructionVisitor::visitRetainValueInst(
192
210
using namespace OptRemark ;
193
211
SILValue root = rcfi.getRCIdentityRoot (rvi->getOperand ());
194
212
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
- });
213
+ bool foundArgs = valueToDeclInferrer.infer (ArgumentKeyKind::Note, root,
214
+ [&](Argument arg) {
215
+ inferredArgs.push_back (arg);
216
+ return true ;
217
+ });
200
218
(void )foundArgs;
201
219
202
220
// Retains begin a lifetime scope, so we infer scan forwards.
203
- auto remark = RemarkMissed (" memory-management " , *rvi,
221
+ auto remark = RemarkMissed (" memory" , *rvi,
204
222
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
- }
223
+ << " retain" ;
224
+ for (auto arg : inferredArgs) {
225
+ remark << arg;
213
226
}
214
227
return remark;
215
228
});
@@ -221,26 +234,20 @@ void OptRemarkGeneratorInstructionVisitor::visitReleaseValueInst(
221
234
using namespace OptRemark ;
222
235
SILValue root = rcfi.getRCIdentityRoot (rvi->getOperand ());
223
236
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
- });
237
+ bool foundArgs = valueToDeclInferrer.infer (ArgumentKeyKind::Note, root,
238
+ [&](Argument arg) {
239
+ inferredArgs.push_back (arg);
240
+ return true ;
241
+ });
229
242
(void )foundArgs;
230
243
231
244
// Releases end a lifetime scope so we infer scan backward.
232
- auto remark = RemarkMissed (" memory-management " , *rvi,
245
+ auto remark = RemarkMissed (" memory" , *rvi,
233
246
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
- }
247
+ << " release" ;
248
+ for (auto arg : inferredArgs) {
249
+ remark << arg;
242
250
}
243
-
244
251
return remark;
245
252
});
246
253
}
@@ -261,7 +268,9 @@ class OptRemarkGenerator : public SILFunctionTransform {
261
268
262
269
return bool (langOpts.OptimizationRemarkMissedPattern ) ||
263
270
bool (langOpts.OptimizationRemarkPassedPattern ) ||
264
- fn->getModule ().getSILRemarkStreamer ();
271
+ fn->getModule ().getSILRemarkStreamer () ||
272
+ fn->hasSemanticsAttrThatStartsWith (
273
+ semantics::FORCE_EMIT_OPT_REMARK_PREFIX);
265
274
}
266
275
267
276
// / The entry point to the transformation.
0 commit comments