[C++20] [Modules] Allow to compile a pcm with and without -fPIC

seperately

We can compile a module unit in 2 phase compilaton:

```
clang++ -std=c++20 a.cppm --precompile -o a.pcm
clang++ -std=c++20 a.pcm -c -o a.o
```

And it is a general requirement that we need to compile a translation
unit with and without -fPIC for static and shared libraries.

But for C++20 modules with 2 phase compilation, it may be waste of time
to compile them 2 times completely. It may be fine to generate one BMI
and compile it with and without -fPIC seperately.

e.g.,

```
clang++ -std=c++20 a.cppm --precompile -o a.pcm
clang++ -std=c++20 a.pcm -c -o a.o
clang++ -std=c++20 a.pcm -c -fPIC -o a-PIC.o
```

Then we can save the time to parse a.cppm repeatedly.
This commit is contained in:
Chuanqi Xu 2024-02-23 10:59:46 +08:00
parent 5ccf54640a
commit 2e5af56b05
8 changed files with 54 additions and 15 deletions

View File

@ -691,16 +691,19 @@ public:
/// lifetime is expected to extend past that of the returned ASTUnit.
///
/// \returns - The initialized ASTUnit or null if the AST failed to load.
static std::unique_ptr<ASTUnit> LoadFromASTFile(
const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
const FileSystemOptions &FileSystemOpts,
std::shared_ptr<HeaderSearchOptions> HSOpts, bool OnlyLocalDecls = false,
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
bool AllowASTWithCompilerErrors = false,
bool UserFilesAreVolatile = false,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
llvm::vfs::getRealFileSystem());
static std::unique_ptr<ASTUnit>
LoadFromASTFile(const std::string &Filename,
const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
const FileSystemOptions &FileSystemOpts,
std::shared_ptr<HeaderSearchOptions> HSOpts,
std::shared_ptr<LangOptions> LangOpts = nullptr,
bool OnlyLocalDecls = false,
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
bool AllowASTWithCompilerErrors = false,
bool UserFilesAreVolatile = false,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
llvm::vfs::getRealFileSystem());
private:
/// Helper function for \c LoadFromCompilerInvocation() and

View File

@ -311,6 +311,9 @@ public:
LangOptions &getLangOpts() { return Invocation->getLangOpts(); }
const LangOptions &getLangOpts() const { return Invocation->getLangOpts(); }
std::shared_ptr<LangOptions> getLangOptsPtr() const {
return Invocation->getLangOptsPtr();
}
PreprocessorOptions &getPreprocessorOpts() {
return Invocation->getPreprocessorOpts();

View File

@ -271,6 +271,7 @@ public:
std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
return PPOpts;
}
std::shared_ptr<LangOptions> getLangOptsPtr() { return LangOpts; }
/// @}
/// Create a compiler invocation from a list of input options.

View File

@ -540,7 +540,17 @@ public:
if (InitializedLanguage)
return false;
// FIXME: We did similar things in ReadHeaderSearchOptions too. But such
// style is not scaling. Probably we need to invite some mechanism to
// handle such patterns generally.
auto PICLevel = LangOpt.PICLevel;
auto PIE = LangOpt.PIE;
LangOpt = LangOpts;
LangOpt.PICLevel = PICLevel;
LangOpt.PIE = PIE;
InitializedLanguage = true;
updated();
@ -790,7 +800,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
const FileSystemOptions &FileSystemOpts,
std::shared_ptr<HeaderSearchOptions> HSOpts, bool OnlyLocalDecls,
std::shared_ptr<HeaderSearchOptions> HSOpts,
std::shared_ptr<LangOptions> LangOpts, bool OnlyLocalDecls,
CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors,
bool UserFilesAreVolatile, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
@ -804,7 +815,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
AST->LangOpts = std::make_shared<LangOptions>();
AST->LangOpts = LangOpts ? LangOpts : std::make_shared<LangOptions>();
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->Diagnostics = Diags;

View File

@ -689,7 +689,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
std::string(InputFile), CI.getPCHContainerReader(),
ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(),
CI.getHeaderSearchOptsPtr());
CI.getHeaderSearchOptsPtr(), CI.getLangOptsPtr());
if (!AST)
return false;

View File

@ -0,0 +1,21 @@
// REQUIRES: x86-registered-target
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: %clang_cc1 -std=c++20 %s -pic-level 2 -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++20 %s -pic-level 2 -fmodule-output=%t/m.pcm -emit-llvm -o - \
// RUN: | FileCheck %s
//
// RUN: %clang_cc1 -std=c++20 %s -emit-module-interface -o %t/m.pcm
// RUN: %clang_cc1 -std=c++20 %t/m.pcm -pic-level 2 -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++20 %t/m.pcm -emit-llvm -o - | FileCheck %s --check-prefix=NOPIC
export module m;
export int x;
export int func() {
return x;
}
// CHECK: ![[METADATA_NUM:[0-9]+]] = !{{{.*}}, !"PIC Level", i32 2}
// NOPIC-NOT: ![[METADATA_NUM:[0-9]+]] = !{{{.*}}, !"PIC Level", i32 2}

View File

@ -276,7 +276,7 @@ static bool printSourceSymbolsFromModule(StringRef modulePath,
CompilerInstance::createDiagnostics(new DiagnosticOptions());
std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
std::string(modulePath), *pchRdr, ASTUnit::LoadASTOnly, Diags,
FileSystemOpts, HSOpts,
FileSystemOpts, HSOpts, /*LangOpts=*/nullptr,
/*OnlyLocalDecls=*/true, CaptureDiagsKind::None,
/*AllowASTWithCompilerErrors=*/true,
/*UserFilesAreVolatile=*/false);

View File

@ -3890,7 +3890,7 @@ enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
ASTUnit::LoadEverything, Diags, FileSystemOpts, HSOpts,
CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All,
/*LangOpts=*/nullptr, CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All,
/*AllowASTWithCompilerErrors=*/true,
/*UserFilesAreVolatile=*/true);
*out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));