@@ -41,6 +41,15 @@ static llvm::cl::opt<bool> ForceVisitImplicitAutogeneratedFunctions(
4141 " Emit opt remarks even on implicit and autogenerated functions" ),
4242 llvm::cl::init(false ));
4343
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+
4453// ===----------------------------------------------------------------------===//
4554// Value To Decl Inferrer
4655// ===----------------------------------------------------------------------===//
@@ -65,16 +74,13 @@ struct ValueToDeclInferrer {
6574 // / accessPath we computed for decl producing a segmented access path, e.x.:
6675 // / "of 'x.lhs.ivar'".
6776 void printNote (llvm::raw_string_ostream &stream, const ValueDecl *decl);
77+
78+ void printProjectionPath (llvm::raw_string_ostream &stream);
6879};
6980
7081} // anonymous namespace
7182
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) {
7884 for (auto &pair : accessPath) {
7985 auto baseType = pair.first ;
8086 auto &proj = pair.second ;
@@ -111,8 +117,14 @@ void ValueToDeclInferrer::printNote(llvm::raw_string_ostream &stream,
111117
112118 llvm_unreachable (" Covered switch is not covered?!" );
113119 }
120+ }
114121
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);
116128 stream << " '" ;
117129}
118130
@@ -145,6 +157,11 @@ static bool hasNonInlinedDebugScope(SILInstruction *i) {
145157bool ValueToDeclInferrer::infer (
146158 ArgumentKeyKind keyKind, SILValue value,
147159 SmallVectorImpl<Argument> &resultingInferredDecls) {
160+ // Clear the stored access path at end of scope.
161+ SWIFT_DEFER {
162+ accessPath.clear ();
163+ };
164+
148165 // This is a linear IR traversal using a 'falling while loop'. That means
149166 // every time through the loop we are trying to handle a case before we hit
150167 // the bottom of the while loop where we always return true (since we did not
@@ -234,15 +251,37 @@ bool ValueToDeclInferrer::infer(
234251 llvm::raw_string_ostream stream (msg);
235252 printNote (stream, decl);
236253 }
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);
239257 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+ }
240281 }
241282 }
242283 }
243284 }
244- if (foundDeclFromUse)
245- return true ;
246285
247286 // At this point, we could not infer any argument. See if we can look
248287 // through loads.
@@ -267,7 +306,7 @@ bool ValueToDeclInferrer::infer(
267306
268307 // If we reached this point, we finished falling through the loop and return
269308 // true.
270- return true ;
309+ return foundDeclFromUse ;
271310 }
272311}
273312
0 commit comments