Skip to content

Commit 8fe8d69

Browse files
committed
[clang][deps] Make clang-scan-deps write modules in raw format
We have no use for debug info for the scanner modules, and writing raw ast files speeds up scanning ~15% in some cases. Note that the compile commands produced by the scanner will still build the obj format (if requested), and the scanner can *read* obj format pcms, e.g. from a PCH. rdar://108807592 Differential Revision: https://reviews.llvm.org/D149693
1 parent 3b01fa2 commit 8fe8d69

File tree

10 files changed

+94
-15
lines changed

10 files changed

+94
-15
lines changed

clang-tools-extra/clangd/Compiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void disableUnsupportedOptions(CompilerInvocation &CI) {
7373
// Always default to raw container format as clangd doesn't registry any other
7474
// and clang dies when faced with unknown formats.
7575
CI.getHeaderSearchOpts().ModuleFormat =
76-
PCHContainerOperations().getRawReader().getFormat().str();
76+
PCHContainerOperations().getRawReader().getFormats().front().str();
7777

7878
CI.getFrontendOpts().Plugins.clear();
7979
CI.getFrontendOpts().AddPluginActions.clear();

clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter {
3232
/// A PCHContainerReader implementation that uses LLVM to
3333
/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
3434
class ObjectFilePCHContainerReader : public PCHContainerReader {
35-
StringRef getFormat() const override { return "obj"; }
35+
ArrayRef<StringRef> getFormats() const override;
3636

3737
/// Returns the serialized AST inside the PCH container Buffer.
3838
StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;

clang/include/clang/Serialization/PCHContainerOperations.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class PCHContainerReader {
5656
public:
5757
virtual ~PCHContainerReader() = 0;
5858
/// Equivalent to the format passed to -fmodule-format=
59-
virtual llvm::StringRef getFormat() const = 0;
59+
virtual llvm::ArrayRef<llvm::StringRef> getFormats() const = 0;
6060

6161
/// Returns the serialized AST inside the PCH container Buffer.
6262
virtual llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const = 0;
@@ -78,16 +78,17 @@ class RawPCHContainerWriter : public PCHContainerWriter {
7878

7979
/// Implements read operations for a raw pass-through PCH container.
8080
class RawPCHContainerReader : public PCHContainerReader {
81-
llvm::StringRef getFormat() const override { return "raw"; }
82-
81+
llvm::ArrayRef<llvm::StringRef> getFormats() const override;
8382
/// Simply returns the buffer contained in Buffer.
8483
llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
8584
};
8685

8786
/// A registry of PCHContainerWriter and -Reader objects for different formats.
8887
class PCHContainerOperations {
8988
llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers;
90-
llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers;
89+
llvm::StringMap<PCHContainerReader *> Readers;
90+
llvm::SmallVector<std::unique_ptr<PCHContainerReader>> OwnedReaders;
91+
9192
public:
9293
/// Automatically registers a RawPCHContainerWriter and
9394
/// RawPCHContainerReader.
@@ -96,13 +97,17 @@ class PCHContainerOperations {
9697
Writers[Writer->getFormat()] = std::move(Writer);
9798
}
9899
void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
99-
Readers[Reader->getFormat()] = std::move(Reader);
100+
assert(!Reader->getFormats().empty() &&
101+
"PCHContainerReader must handle >=1 format");
102+
for (llvm::StringRef Fmt : Reader->getFormats())
103+
Readers[Fmt] = Reader.get();
104+
OwnedReaders.push_back(std::move(Reader));
100105
}
101106
const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) {
102107
return Writers[Format].get();
103108
}
104109
const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) {
105-
return Readers[Format].get();
110+
return Readers[Format];
106111
}
107112
const PCHContainerReader &getRawReader() {
108113
return *getReaderOrNull("raw");

clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,11 @@ ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
349349
CI, MainFileName, OutputFileName, std::move(OS), Buffer);
350350
}
351351

352+
ArrayRef<StringRef> ObjectFilePCHContainerReader::getFormats() const {
353+
static StringRef Formats[] = {"obj", "raw"};
354+
return Formats;
355+
}
356+
352357
StringRef
353358
ObjectFilePCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const {
354359
StringRef PCH;

clang/lib/Frontend/ASTUnit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
811811
UserFilesAreVolatile);
812812
AST->ModuleCache = new InMemoryModuleCache;
813813
AST->HSOpts = std::make_shared<HeaderSearchOptions>();
814-
AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormat());
814+
AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());
815815
AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
816816
AST->getSourceManager(),
817817
AST->getDiagnostics(),

clang/lib/Serialization/PCHContainerOperations.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ std::unique_ptr<ASTConsumer> RawPCHContainerWriter::CreatePCHContainerGenerator(
5757
return std::make_unique<RawPCHContainerGenerator>(std::move(OS), Buffer);
5858
}
5959

60+
ArrayRef<llvm::StringRef> RawPCHContainerReader::getFormats() const {
61+
static StringRef Raw("raw");
62+
return ArrayRef(Raw);
63+
}
64+
6065
StringRef
6166
RawPCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const {
6267
return Buffer.getBuffer();

clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class DependencyScanningAction : public tooling::ToolAction {
181181
ScanInstance.getFrontendOpts().GenerateGlobalModuleIndex = false;
182182
ScanInstance.getFrontendOpts().UseGlobalModuleIndex = false;
183183
ScanInstance.getFrontendOpts().ModulesShareFileManager = false;
184+
ScanInstance.getHeaderSearchOpts().ModuleFormat = "raw";
184185

185186
ScanInstance.setFileManager(FileMgr);
186187
// Support for virtual file system overlays.
@@ -309,12 +310,11 @@ DependencyScanningWorker::DependencyScanningWorker(
309310
: Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()),
310311
EagerLoadModules(Service.shouldEagerLoadModules()) {
311312
PCHContainerOps = std::make_shared<PCHContainerOperations>();
313+
// We need to read object files from PCH built outside the scanner.
312314
PCHContainerOps->registerReader(
313315
std::make_unique<ObjectFilePCHContainerReader>());
314-
// We don't need to write object files, but the current PCH implementation
315-
// requires the writer to be registered as well.
316-
PCHContainerOps->registerWriter(
317-
std::make_unique<ObjectFilePCHContainerWriter>());
316+
// The scanner itself writes only raw ast files.
317+
PCHContainerOps->registerWriter(std::make_unique<RawPCHContainerWriter>());
318318

319319
switch (Service.getMode()) {
320320
case ScanningMode::DependencyDirectivesScan:
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Check that the scanner produces raw ast files, even when builds produce the
2+
// obj format, and that the scanner can read obj format from PCH and modules
3+
// imported by PCH.
4+
5+
// Unsupported on AIX because we don't support the requisite "__clangast"
6+
// section in XCOFF yet.
7+
// UNSUPPORTED: target={{.*}}-aix{{.*}}
8+
9+
// REQUIRES: shell
10+
11+
// RUN: rm -rf %t && mkdir %t
12+
// RUN: cp %S/Inputs/modules-pch/* %t
13+
14+
// Scan dependencies of the PCH:
15+
//
16+
// RUN: rm -f %t/cdb_pch.json
17+
// RUN: sed "s|DIR|%/t|g" %S/Inputs/modules-pch/cdb_pch.json > %t/cdb_pch.json
18+
// RUN: clang-scan-deps -compilation-database %t/cdb_pch.json -format experimental-full \
19+
// RUN: -module-files-dir %t/build > %t/result_pch.json
20+
21+
// Explicitly build the PCH:
22+
//
23+
// RUN: %deps-to-rsp %t/result_pch.json --module-name=ModCommon1 > %t/mod_common_1.cc1.rsp
24+
// RUN: %deps-to-rsp %t/result_pch.json --module-name=ModCommon2 > %t/mod_common_2.cc1.rsp
25+
// RUN: %deps-to-rsp %t/result_pch.json --module-name=ModPCH > %t/mod_pch.cc1.rsp
26+
// RUN: %deps-to-rsp %t/result_pch.json --tu-index=0 > %t/pch.rsp
27+
//
28+
// RUN: %clang @%t/mod_common_1.cc1.rsp
29+
// RUN: %clang @%t/mod_common_2.cc1.rsp
30+
// RUN: %clang @%t/mod_pch.cc1.rsp
31+
// RUN: %clang @%t/pch.rsp
32+
33+
// Scan dependencies of the TU:
34+
//
35+
// RUN: rm -f %t/cdb_tu.json
36+
// RUN: sed "s|DIR|%/t|g" %S/Inputs/modules-pch/cdb_tu.json > %t/cdb_tu.json
37+
// RUN: clang-scan-deps -compilation-database %t/cdb_tu.json -format experimental-full \
38+
// RUN: -module-files-dir %t/build > %t/result_tu.json
39+
40+
// Explicitly build the TU:
41+
//
42+
// RUN: %deps-to-rsp %t/result_tu.json --module-name=ModTU > %t/mod_tu.cc1.rsp
43+
// RUN: %deps-to-rsp %t/result_tu.json --tu-index=0 > %t/tu.rsp
44+
//
45+
// RUN: %clang @%t/mod_tu.cc1.rsp
46+
// RUN: %clang @%t/tu.rsp
47+
48+
// Check the module format for scanner modules:
49+
//
50+
// RUN: find %t/cache -name "*.pcm" -exec %clang_cc1 -module-file-info "{}" ";" | FileCheck %s -check-prefix=SCAN
51+
// SCAN: Module format: raw
52+
// SCAN: Module format: raw
53+
// SCAN: Module format: raw
54+
// SCAN: Module format: raw
55+
56+
// Check the module format for built modules:
57+
//
58+
// RUN: find %t/build -name "*.pcm" -exec %clang_cc1 -module-file-info "{}" ";" | FileCheck %s -check-prefix=BUILD
59+
// BUILD: Module format: obj
60+
// BUILD: Module format: obj
61+
// BUILD: Module format: obj
62+
// BUILD: Module format: obj
63+
64+
// FIXME: check pch format as well; -module-file-info does not work with a PCH

clang/tools/libclang/CIndex.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3964,7 +3964,7 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
39643964
TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
39653965
/*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
39663966
/*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
3967-
CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3967+
CXXIdx->getPCHContainerOperations()->getRawReader().getFormats().front(),
39683968
&ErrUnit));
39693969

39703970
// Early failures in LoadFromCommandLine may return with ErrUnit unset.

clang/tools/libclang/Indexing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ static CXErrorCode clang_indexSourceFile_Impl(
552552

553553
// Make sure to use the raw module format.
554554
CInvok->getHeaderSearchOpts().ModuleFormat = std::string(
555-
CXXIdx->getPCHContainerOperations()->getRawReader().getFormat());
555+
CXXIdx->getPCHContainerOperations()->getRawReader().getFormats().front());
556556

557557
auto Unit = ASTUnit::create(CInvok, Diags, CaptureDiagnostics,
558558
/*UserFilesAreVolatile=*/true);

0 commit comments

Comments
 (0)