Skip to content

Commit f61dd7b

Browse files
committed
[NFC] Hash LLVM options more robustly
Replaces getLLVMCodeGenOptionsHash(), which combined a bunch of individual bits into a string, with writeLLVMCodeGenOptionsTo(), which writes each one separately into a raw_ostream. This is intended to be make the hashing more future-proof. The current design needs to know exactly how many bits each of the values needs; if any of the values grew and you forgot to update this function, its bits would interfere with those of an earlier value in the hash. This new design is expected to be slightly slower, but more robust to future change in the compiler.
1 parent 7c043b8 commit f61dd7b

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
// FIXME: This include is just for llvm::SanitizerCoverageOptions. We should
2727
// split the header upstream so we don't include so much.
2828
#include "llvm/Transforms/Instrumentation.h"
29+
#include "llvm/Support/raw_ostream.h"
2930
#include "llvm/Support/VersionTuple.h"
3031
#include <string>
3132
#include <vector>
@@ -253,15 +254,18 @@ class IRGenOptions {
253254
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
254255
TypeInfoFilter(TypeInfoDumpFilter::All) {}
255256

256-
// Get a hash of all options which influence the llvm compilation but are not
257-
// reflected in the llvm module itself.
258-
unsigned getLLVMCodeGenOptionsHash() {
259-
unsigned Hash = (unsigned)OptMode;
260-
Hash = (Hash << 1) | DisableLLVMOptzns;
261-
Hash = (Hash << 1) | DisableSwiftSpecificLLVMOptzns;
262-
Hash = (Hash << 1) | GenerateProfile;
263-
Hash = (Hash << 1) | Sanitizers.contains(SanitizerKind::Fuzzer);
264-
return Hash;
257+
/// Appends to \p os an arbitrary string representing all options which
258+
/// influence the llvm compilation but are not reflected in the llvm module
259+
/// itself.
260+
void writeLLVMCodeGenOptionsTo(llvm::raw_ostream &os) {
261+
// We put a letter between each value simply to keep them from running into
262+
// one another. There might be a vague correspondence between meaning and
263+
// letter, but don't sweat it.
264+
os << 'O' << (unsigned)OptMode
265+
<< 'd' << DisableLLVMOptzns
266+
<< 'D' << DisableSwiftSpecificLLVMOptzns
267+
<< 'p' << GenerateProfile
268+
<< 's' << Sanitizers.contains(SanitizerKind::Fuzzer);
265269
}
266270

267271
/// Should LLVM IR value names be emitted and preserved?

lib/IRGen/IRGen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ static void getHashOfModule(MD5::MD5Result &Result, IRGenOptions &Opts,
349349

350350
// Add all options which influence the llvm compilation but are not yet
351351
// reflected in the llvm module itself.
352-
HashStream << Opts.getLLVMCodeGenOptionsHash();
352+
Opts.writeLLVMCodeGenOptionsTo(HashStream);
353353

354354
HashStream.final(Result);
355355
}
@@ -614,7 +614,7 @@ bool swift::performLLVM(IRGenOptions &Opts, DiagnosticEngine *Diags,
614614
);
615615
// Note for future debuggers: If you see this error, either you changed
616616
// LLVM and need to clean your build folder to rebuild everything with it,
617-
// or IRGenOptions::getLLVMCodeGenOptionsHash() doesn't account for a flag
617+
// or IRGenOptions::writeLLVMCodeGenOptionsTo() doesn't account for a flag
618618
// that changed LLVM's output between this compile and the previous one.
619619

620620
case FileDifference::SameContents:

0 commit comments

Comments
 (0)