summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2019-10-14 23:02:03 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2019-10-14 23:02:03 +0000
commit779f672417bab6e2329d3135fc3d83a8bfd9f705 (patch)
treeb4a4685e0c602e1fa8eec1bc861d01138863ab4d /include
parentc1c73801616efa1eda1925ebf64a1a6bce7527e7 (diff)
downloadclang-779f672417bab6e2329d3135fc3d83a8bfd9f705.tar.gz
[Modules][PCH] Hash input files content
Summary: When files often get touched during builds, the mtime based validation leads to different problems in implicit modules builds, even when the content doesn't actually change: - Modules only: module invalidation due to out of date files. Usually causing rebuild traffic. - Modules + PCH: build failures because clang cannot rebuild a module if it comes from building a PCH. - PCH: build failures because clang cannot rebuild a PCH in case one of the input headers has different mtime. This patch proposes hashing the content of input files (headers and module maps), which is performed during serialization time. When looking at input files for validation, clang only computes the hash in case there's a mtime mismatch. I've tested a couple of different hash algorithms availble in LLVM in face of building modules+pch for `#import <Cocoa/Cocoa.h>`: - `hash_code`: performace diff within the noise, total module cache increased by 0.07%. - `SHA1`: 5% slowdown. Haven't done real size measurements, but it'd be BLOCK_ID+20 bytes per input file, instead of BLOCK_ID+8 bytes from `hash_code`. - `MD5`: 3% slowdown. Like above, but BLOCK_ID+16 bytes per input file. Given the numbers above, the patch uses `hash_code`. The patch also improves invalidation error msgs to point out which type of problem the user is facing: "mtime", "size" or "content". rdar://problem/29320105 Reviewers: dexonsmith, arphaman, rsmith, aprantl Subscribers: jkorous, cfe-commits, ributzka Tags: #clang Differential Revision: https://reviews.llvm.org/D67249 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374841 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td11
-rw-r--r--include/clang/Driver/Options.td22
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h7
-rw-r--r--include/clang/Serialization/ASTBitCodes.h5
-rw-r--r--include/clang/Serialization/ASTReader.h10
5 files changed, 49 insertions, 6 deletions
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 0461d2f429..757dbbeee3 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -18,13 +18,16 @@ def err_fe_pch_malformed : Error<
def err_fe_pch_malformed_block : Error<
"malformed block record in PCH file: '%0'">, DefaultFatal;
def err_fe_pch_file_modified : Error<
- "file '%0' has been modified since the precompiled header '%1' was built">,
+ "file '%0' has been modified since the precompiled header '%1' was built"
+ ": %select{size|mtime|content}2 changed">,
DefaultFatal;
def err_fe_module_file_modified : Error<
- "file '%0' has been modified since the module file '%1' was built">,
+ "file '%0' has been modified since the module file '%1' was built"
+ ": %select{size|mtime|content}2 changed">,
DefaultFatal;
def err_fe_ast_file_modified : Error<
- "file '%0' has been modified since the AST file '%1' was built">,
+ "file '%0' has been modified since the AST file '%1' was built"
+ ": %select{size|mtime|content}2 changed">,
DefaultFatal;
def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
@@ -399,6 +402,8 @@ def warn_module_uses_date_time : Warning<
def err_module_no_size_mtime_for_header : Error<
"cannot emit module %0: %select{size|mtime}1 must be explicitly specified "
"for missing header file \"%2\"">;
+def err_module_unable_to_hash_content : Error<
+ "failed to hash content for '%0' because memory buffer cannot be retrieved">;
} // let CategoryName
} // let Component
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 22676b6787..3ce6fcf29f 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -1368,6 +1368,28 @@ def fmodules_validate_system_headers : Flag<["-"], "fmodules-validate-system-hea
HelpText<"Validate the system headers that a module depends on when loading the module">;
def fno_modules_validate_system_headers : Flag<["-"], "fno-modules-validate-system-headers">,
Group<i_Group>, Flags<[DriverOption]>;
+
+def fvalidate_ast_input_files_content:
+ Flag <["-"], "fvalidate-ast-input-files-content">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Compute and store the hash of input files used to build an AST."
+ " Files with mismatching mtime's are considered valid"
+ " if both contents is identical">;
+def fmodules_validate_input_files_content:
+ Flag <["-"], "fmodules-validate-input-files-content">,
+ Group<f_Group>, Flags<[DriverOption]>,
+ HelpText<"Validate PCM input files based on content if mtime differs">;
+def fno_modules_validate_input_files_content:
+ Flag <["-"], "fno_modules-validate-input-files-content">,
+ Group<f_Group>, Flags<[DriverOption]>;
+def fpch_validate_input_files_content:
+ Flag <["-"], "fpch-validate-input-files-content">,
+ Group<f_Group>, Flags<[DriverOption]>,
+ HelpText<"Validate PCH input files based on content if mtime differs">;
+def fno_pch_validate_input_files_content:
+ Flag <["-"], "fno_pch-validate-input-files-content">,
+ Group<f_Group>, Flags<[DriverOption]>;
+
def fmodules : Flag <["-"], "fmodules">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
HelpText<"Enable the 'modules' language feature">;
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index ed128bce48..3c309744ba 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -195,6 +195,10 @@ public:
/// Whether to validate system input files when a module is loaded.
unsigned ModulesValidateSystemHeaders : 1;
+ // Whether the content of input files should be hashed and used to
+ // validate consistency.
+ unsigned ValidateASTInputFilesContent : 1;
+
/// Whether the module includes debug information (-gmodules).
unsigned UseDebugInfo : 1;
@@ -208,7 +212,8 @@ public:
UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
ModulesValidateOncePerBuildSession(false),
- ModulesValidateSystemHeaders(false), UseDebugInfo(false),
+ ModulesValidateSystemHeaders(false),
+ ValidateASTInputFilesContent(false), UseDebugInfo(false),
ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {}
/// AddPath - Add the \p Path path to the specified \p Group list.
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 94721f9fd3..eab1ec86db 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -382,7 +382,10 @@ namespace serialization {
/// inside the control block.
enum InputFileRecordTypes {
/// An input file.
- INPUT_FILE = 1
+ INPUT_FILE = 1,
+
+ /// The input file content hash
+ INPUT_FILE_HASH
};
/// Record types that occur within the AST block itself.
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 13d16539cc..7495c2b17a 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -930,6 +930,9 @@ private:
/// Whether validate system input files.
bool ValidateSystemInputs;
+ /// Whether validate headers and module maps using hash based on contents.
+ bool ValidateASTInputFilesContent;
+
/// Whether we are allowed to use the global module index.
bool UseGlobalIndex;
@@ -1203,6 +1206,7 @@ private:
struct InputFileInfo {
std::string Filename;
+ uint64_t ContentHash;
off_t StoredSize;
time_t StoredTime;
bool Overridden;
@@ -1437,6 +1441,8 @@ private:
void Error(StringRef Msg) const;
void Error(unsigned DiagID, StringRef Arg1 = StringRef(),
StringRef Arg2 = StringRef()) const;
+ void Error(unsigned DiagID, StringRef Arg1, StringRef Arg2,
+ unsigned Select) const;
void Error(llvm::Error &&Err) const;
public:
@@ -1485,7 +1491,9 @@ public:
StringRef isysroot = "", bool DisableValidation = false,
bool AllowASTWithCompilerErrors = false,
bool AllowConfigurationMismatch = false,
- bool ValidateSystemInputs = false, bool UseGlobalIndex = true,
+ bool ValidateSystemInputs = false,
+ bool ValidateASTInputFilesContent = false,
+ bool UseGlobalIndex = true,
std::unique_ptr<llvm::Timer> ReadTimer = {});
ASTReader(const ASTReader &) = delete;
ASTReader &operator=(const ASTReader &) = delete;