20
20
#include " swift/SILOptimizer/PassManager/Passes.h"
21
21
#include " swift/Serialization/SerializationOptions.h"
22
22
#include " clang/Basic/Module.h"
23
+ #include " llvm/ADT/Hashing.h"
23
24
#include " llvm/Support/Debug.h"
24
25
#include " llvm/Support/CommandLine.h"
25
26
#include " llvm/Support/CrashRecoveryContext.h"
@@ -66,6 +67,38 @@ extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
66
67
return false ;
67
68
}
68
69
70
+ // / Construct a cache key for the .swiftmodule being generated. There is a
71
+ // / balance to be struck here between things that go in the cache key and
72
+ // / things that go in the "up to date" check of the cache entry. We want to
73
+ // / avoid fighting over a single cache entry too much when (say) running
74
+ // / different compiler versions on the same machine or different inputs
75
+ // / that happen to have the same short module name, so we will disambiguate
76
+ // / those in the key. But we want to invalidate and rebuild a cache entry
77
+ // / -- rather than making a new one and potentially filling up the cache
78
+ // / with dead entries -- when other factors change, such as the contents of
79
+ // / the .swiftinterface input or its dependencies.
80
+ std::string getCacheHash (ASTContext &Ctx,
81
+ CompilerInvocation &SubInvocation,
82
+ StringRef InPath) {
83
+ // Start with the compiler version (which will be either tag names or revs).
84
+ std::string vers = swift::version::getSwiftFullVersion (
85
+ Ctx.LangOpts .EffectiveLanguageVersion );
86
+ llvm::hash_code H = llvm::hash_value (vers);
87
+
88
+ // Simplest representation of input "identity" (not content) is just a
89
+ // pathname, and probably all we can get from the VFS in this regard anyways.
90
+ H = llvm::hash_combine (H, InPath);
91
+
92
+ // ClangImporterOpts does include the target CPU, which is redundant: we
93
+ // already have separate .swiftinterface files per target due to expanding
94
+ // preprocessing directives, but further specializing the cache key to that
95
+ // target is harmless and will not make any extra cache entries, so allow it.
96
+ H = llvm::hash_combine (
97
+ H, SubInvocation.getClangImporterOptions ().getPCHHashComponents ());
98
+
99
+ return llvm::APInt (64 , H).toString (36 , /* Signed=*/ false );
100
+ }
101
+
69
102
void
70
103
ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPath (
71
104
CompilerInvocation &SubInvocation,
@@ -84,13 +117,13 @@ ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPath(
84
117
SubInvocation.setRuntimeResourcePath (SearchPathOpts.RuntimeResourcePath );
85
118
SubInvocation.setTargetTriple (LangOpts.Target );
86
119
87
- // Calculate an output filename based on the SubInvocation hash, and
88
- // wire up the SubInvocation's InputsAndOutputs to contain both
89
- // input and output filenames.
120
+ // Calculate an output filename that includes a hash of relevant key data , and
121
+ // wire up the SubInvocation's InputsAndOutputs to contain both input and
122
+ // output filenames.
90
123
OutPath = CacheDir;
91
124
llvm::sys::path::append (OutPath, llvm::sys::path::stem (InPath));
92
125
OutPath.append (" -" );
93
- OutPath.append (SubInvocation. getPCHHash ( ));
126
+ OutPath.append (getCacheHash (Ctx, SubInvocation, InPath ));
94
127
OutPath.append (" ." );
95
128
auto Ext = file_types::getExtension (file_types::TY_SwiftModuleFile);
96
129
OutPath.append (Ext);
0 commit comments