@@ -41,6 +41,15 @@ static llvm::cl::opt<bool> ForceVisitImplicitAutogeneratedFunctions(
41
41
" Emit opt remarks even on implicit and autogenerated functions" ),
42
42
llvm::cl::init(false ));
43
43
44
+ static llvm::cl::opt<bool > DecllessDebugValueUseSILDebugInfo (
45
+ " optremarkgen-declless-debugvalue-use-sildebugvar-info" , llvm::cl::Hidden,
46
+ llvm::cl::desc (
47
+ " If a debug_value does not have a decl, infer a value with a name from "
48
+ " that info that has a loc set to the loc of the debug_value "
49
+ " instruction itself. This is for testing purposes so it is easier to "
50
+ " write SIL test cases for this pass" ),
51
+ llvm::cl::init(false ));
52
+
44
53
// ===----------------------------------------------------------------------===//
45
54
// Value To Decl Inferrer
46
55
// ===----------------------------------------------------------------------===//
@@ -65,16 +74,13 @@ struct ValueToDeclInferrer {
65
74
// / accessPath we computed for decl producing a segmented access path, e.x.:
66
75
// / "of 'x.lhs.ivar'".
67
76
void printNote (llvm::raw_string_ostream &stream, const ValueDecl *decl);
77
+
78
+ void printProjectionPath (llvm::raw_string_ostream &stream);
68
79
};
69
80
70
81
} // anonymous namespace
71
82
72
- void ValueToDeclInferrer::printNote (llvm::raw_string_ostream &stream,
73
- const ValueDecl *decl) {
74
- assert (decl &&
75
- " We assume for now that this is always called with a non-null decl" );
76
- stream << " of '" << decl->getBaseName ();
77
-
83
+ void ValueToDeclInferrer::printProjectionPath (llvm::raw_string_ostream &stream) {
78
84
for (auto &pair : accessPath) {
79
85
auto baseType = pair.first ;
80
86
auto &proj = pair.second ;
@@ -111,8 +117,14 @@ void ValueToDeclInferrer::printNote(llvm::raw_string_ostream &stream,
111
117
112
118
llvm_unreachable (" Covered switch is not covered?!" );
113
119
}
120
+ }
114
121
115
- accessPath.clear ();
122
+ void ValueToDeclInferrer::printNote (llvm::raw_string_ostream &stream,
123
+ const ValueDecl *decl) {
124
+ assert (decl &&
125
+ " We assume for now that this is always called with a non-null decl" );
126
+ stream << " of '" << decl->getBaseName ();
127
+ printProjectionPath (stream);
116
128
stream << " '" ;
117
129
}
118
130
@@ -145,6 +157,11 @@ static bool hasNonInlinedDebugScope(SILInstruction *i) {
145
157
bool ValueToDeclInferrer::infer (
146
158
ArgumentKeyKind keyKind, SILValue value,
147
159
SmallVectorImpl<Argument> &resultingInferredDecls) {
160
+ // Clear the stored access path at end of scope.
161
+ SWIFT_DEFER {
162
+ accessPath.clear ();
163
+ };
164
+
148
165
// This is a linear IR traversal using a 'falling while loop'. That means
149
166
// every time through the loop we are trying to handle a case before we hit
150
167
// the bottom of the while loop where we always return true (since we did not
@@ -234,15 +251,37 @@ bool ValueToDeclInferrer::infer(
234
251
llvm::raw_string_ostream stream (msg);
235
252
printNote (stream, decl);
236
253
}
237
- resultingInferredDecls.push_back (
238
- Argument ({keyKind, " InferredValue" }, std::move (msg), decl));
254
+ resultingInferredDecls.emplace_back (
255
+ OptRemark::ArgumentKey{keyKind, " InferredValue" },
256
+ std::move (msg), decl);
239
257
foundDeclFromUse = true ;
258
+ } else {
259
+ // If we did not have a decl, see if we were asked for testing
260
+ // purposes to use SILDebugInfo to create a placeholder inferred
261
+ // value.
262
+ if (DecllessDebugValueUseSILDebugInfo) {
263
+ if (auto varInfo = dvi->getVarInfo ()) {
264
+ auto name = varInfo->Name ;
265
+ if (!name.empty ()) {
266
+ std::string msg;
267
+ {
268
+ llvm::raw_string_ostream stream (msg);
269
+ stream << " of '" << name;
270
+ printProjectionPath (stream);
271
+ stream << " '" ;
272
+ }
273
+ resultingInferredDecls.push_back (
274
+ Argument ({keyKind, " InferredValue" },
275
+ std::move (msg),
276
+ dvi->getLoc ()));
277
+ foundDeclFromUse = true ;
278
+ }
279
+ }
280
+ }
240
281
}
241
282
}
242
283
}
243
284
}
244
- if (foundDeclFromUse)
245
- return true ;
246
285
247
286
// At this point, we could not infer any argument. See if we can look
248
287
// through loads.
@@ -267,7 +306,7 @@ bool ValueToDeclInferrer::infer(
267
306
268
307
// If we reached this point, we finished falling through the loop and return
269
308
// true.
270
- return true ;
309
+ return foundDeclFromUse ;
271
310
}
272
311
}
273
312
0 commit comments