Skip to content

Commit 729748d

Browse files
committed
[Modules] Fix rebuilding an updated module for each of its consumers.
Marking a module for a rebuild when its signature differs from the expected one causes redundant module rebuilds for incremental builds. When a module is updated, its signature changes. But its consumers still have the old signature and loading them will result in signature mismatches. It will correctly cause the rebuilds for the consumers but we don't need to rebuild the common module for each of them as it is already up to date. In practice this bug causes longer build times. We are doing more work than required and only a single process can build a module, so parallel builds degrade to a single-process mode where extra processes are just waiting on a file lock. Fix by not marking a module dependency for a rebuild on signature mismatch. We'll check if it is up to date when we load it. rdar://problem/50212358 Reviewers: dexonsmith, bruno, rsmith Reviewed By: dexonsmith, bruno Subscribers: jkorous, ributzka, cfe-commits, aprantl Differential Revision: https://reviews.llvm.org/D66907 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370274 91177308-0d34-0410-b5e6-96231b3b80d8 (cherry picked from commit 39c70ef6ac1d2d280abedca1b64c57dcff22b796) apple-llvm-split-commit: 9fbdf1d6c0269c9bbadba34f92db5d2b6a5fca26 apple-llvm-split-dir: clang/
1 parent 0fe0887 commit 729748d

File tree

6 files changed

+45
-6
lines changed

6 files changed

+45
-6
lines changed

clang/lib/Serialization/ModuleManager.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,8 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
207207
// Read the signature eagerly now so that we can check it. Avoid calling
208208
// ReadSignature unless there's something to check though.
209209
if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data),
210-
ExpectedSignature, ErrorStr)) {
211-
// Try to remove the buffer. If it can't be removed, then it was already
212-
// validated by this process.
213-
if (!getModuleCache().tryToDropPCM(NewModule->FileName))
214-
FileMgr.invalidateCache(NewModule->File);
210+
ExpectedSignature, ErrorStr))
215211
return OutOfDate;
216-
}
217212

218213
// We're keeping this module. Store it everywhere.
219214
Module = Modules[Entry] = NewModule.get();
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// A
2+
#include "Common.h"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// B
2+
#include "Common.h"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Common
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module A { header "A.h" }
2+
module B { header "B.h" }
3+
module Common { header "Common.h" }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// REQUIRES: shell
2+
// RUN: rm -rf %t
3+
// RUN: mkdir -p %t/implicit-invalidate-common
4+
// RUN: cp -r %S/Inputs/implicit-invalidate-common %t/
5+
// RUN: echo '#include "A.h"' > %t/A.c
6+
// RUN: echo '#include "B.h"' > %t/B.c
7+
8+
// Build with an empty module cache. Module 'Common' should be built only once.
9+
//
10+
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/Cache \
11+
// RUN: -fsyntax-only -I %t/implicit-invalidate-common -Rmodule-build \
12+
// RUN: %t/A.c 2> %t/initial_build.txt
13+
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/Cache \
14+
// RUN: -fsyntax-only -I %t/implicit-invalidate-common -Rmodule-build \
15+
// RUN: %t/B.c 2>> %t/initial_build.txt
16+
// RUN: FileCheck %s --implicit-check-not "remark:" --input-file %t/initial_build.txt
17+
18+
// Update module 'Common' and build with the populated module cache. Module
19+
// 'Common' still should be built only once. Note that we are using the same
20+
// flags for A.c and B.c to avoid building Common.pcm at different paths.
21+
//
22+
// RUN: echo ' // ' >> %t/implicit-invalidate-common/Common.h
23+
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/Cache \
24+
// RUN: -fsyntax-only -I %t/implicit-invalidate-common -Rmodule-build \
25+
// RUN: %t/A.c 2> %t/incremental_build.txt
26+
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/Cache \
27+
// RUN: -fsyntax-only -I %t/implicit-invalidate-common -Rmodule-build \
28+
// RUN: %t/B.c 2>> %t/incremental_build.txt
29+
// RUN: FileCheck %s --implicit-check-not "remark:" --input-file %t/incremental_build.txt
30+
31+
// CHECK: remark: building module 'A'
32+
// CHECK: remark: building module 'Common'
33+
// CHECK: remark: finished building module 'Common'
34+
// CHECK: remark: finished building module 'A'
35+
// CHECK: remark: building module 'B'
36+
// CHECK: remark: finished building module 'B'

0 commit comments

Comments
 (0)