|
28 | 28 | #include "swift/SIL/Projection.h" |
29 | 29 | #include "swift/SIL/SILFunction.h" |
30 | 30 | #include "swift/SIL/SILInstruction.h" |
| 31 | +#include "swift/SIL/PatternMatch.h" |
31 | 32 | #include "swift/SIL/SILModule.h" |
32 | 33 | #include "swift/SIL/SILVisitor.h" |
33 | 34 | #include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" |
|
37 | 38 | #include "llvm/Support/raw_ostream.h" |
38 | 39 |
|
39 | 40 | using namespace swift; |
| 41 | +using namespace swift::PatternMatch; |
40 | 42 |
|
41 | 43 | static llvm::cl::opt<bool> ForceVisitImplicitAutogeneratedFunctions( |
42 | 44 | "optremarkgen-visit-implicit-autogen-funcs", llvm::cl::Hidden, |
@@ -374,6 +376,30 @@ bool ValueToDeclInferrer::infer( |
374 | 376 | } |
375 | 377 | } |
376 | 378 |
|
| 379 | + // A pattern that we see around empty array storage is: |
| 380 | + // |
| 381 | + // %0 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage |
| 382 | + // %1 = address_to_pointer %0 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer |
| 383 | + // %2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to $__EmptyArrayStorage |
| 384 | + // |
| 385 | + // Recognize this case. |
| 386 | + { |
| 387 | + GlobalAddrInst *gai; |
| 388 | + if (match(value, m_RawPointerToRefInst( |
| 389 | + m_AddressToPointerInst(m_GlobalAddrInst(gai))))) { |
| 390 | + if (auto *decl = gai->getReferencedGlobal()->getDecl()) { |
| 391 | + std::string msg; |
| 392 | + { |
| 393 | + llvm::raw_string_ostream stream(msg); |
| 394 | + printNote(stream, decl); |
| 395 | + } |
| 396 | + resultingInferredDecls.push_back( |
| 397 | + Argument({keyKind, "InferredValue"}, std::move(msg), decl)); |
| 398 | + return true; |
| 399 | + } |
| 400 | + } |
| 401 | + } |
| 402 | + |
377 | 403 | // We prefer decls not from uses since these are inherently noisier. Still, |
378 | 404 | // it is better than nothing. |
379 | 405 | bool foundDeclFromUse = false; |
|
0 commit comments