Skip to content

Commit 1f85e80

Browse files
committed
[ModuleInterface] Tighten up cache key for generated .swiftmodule.
1 parent c4697c3 commit 1f85e80

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/SILOptimizer/PassManager/Passes.h"
2121
#include "swift/Serialization/SerializationOptions.h"
2222
#include "clang/Basic/Module.h"
23+
#include "llvm/ADT/Hashing.h"
2324
#include "llvm/Support/Debug.h"
2425
#include "llvm/Support/CommandLine.h"
2526
#include "llvm/Support/CrashRecoveryContext.h"
@@ -66,6 +67,38 @@ extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
6667
return false;
6768
}
6869

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+
69102
void
70103
ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPath(
71104
CompilerInvocation &SubInvocation,
@@ -84,13 +117,13 @@ ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPath(
84117
SubInvocation.setRuntimeResourcePath(SearchPathOpts.RuntimeResourcePath);
85118
SubInvocation.setTargetTriple(LangOpts.Target);
86119

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.
90123
OutPath = CacheDir;
91124
llvm::sys::path::append(OutPath, llvm::sys::path::stem(InPath));
92125
OutPath.append("-");
93-
OutPath.append(SubInvocation.getPCHHash());
126+
OutPath.append(getCacheHash(Ctx, SubInvocation, InPath));
94127
OutPath.append(".");
95128
auto Ext = file_types::getExtension(file_types::TY_SwiftModuleFile);
96129
OutPath.append(Ext);

0 commit comments

Comments
 (0)