Skip to content

[stable/20221013] Cherry-pick CAS changes #7143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
42c0375
[clang][cas] Move some caching env variables from clang-cache to driver
benlangmuir Apr 17, 2023
c09f6d0
[llvm][cas] Fix llvm-cas --ingest symlink issues
benlangmuir Apr 19, 2023
85a7598
[clang][cas] Fix issue when we emit caching-related diagnostic after …
akyrtzi Apr 19, 2023
3e8689b
[clang][modules] Avoid re-exporting PCH imports on every later module…
benlangmuir Apr 12, 2023
81e936c
[llvm][cas] Add "plugin://" CAS identifier scheme
akyrtzi Apr 16, 2023
37f3217
[clang-cas-test] Support using the CAS plugin mechanism
akyrtzi Apr 21, 2023
24bcd67
[llvm-cas] Add `-fcas-plugin-path` and `-fcas-plugin-option` options …
akyrtzi Apr 21, 2023
d9b5876
[clang][cas] Remove CASOptions from module context hash
benlangmuir Apr 20, 2023
9d6cbc5
[clang][cas] Fix dependency directive lookup for prefix-mapped paths
benlangmuir Apr 24, 2023
a36aad5
[clang][cas] Prefix-map paths in <module-includes>
benlangmuir Apr 24, 2023
c0d24c6
[CAS/ActionCache] Add asynchronous versions for the `ActionCache` APIs
akyrtzi Apr 27, 2023
e91f6ca
[clang][cas] Move `CompileJobCache` into `Frontend` library
akyrtzi Apr 28, 2023
d67ff0e
[clang][deps] Teach dep directive scanner about #pragma clang system_…
benlangmuir May 3, 2023
6f5414e
[clang][cas] Add test for #pragma clang system_header
benlangmuir May 3, 2023
fa5af80
[clang][deps] Teach dep directive scanner about _Pragma
benlangmuir May 4, 2023
01b9325
[clang] Prevent creation of new submodules in ASTWriter
benlangmuir May 8, 2023
0ff521f
[CompileJobCacheResult] Return the correct strings for `CompileJobCac…
akyrtzi May 10, 2023
692d150
[clang][cas] Only handle CLANG_CACHE_TEST_DETERMINISTIC_OUTPUTS with …
benlangmuir May 10, 2023
77f8041
[clang][cas] Fix cache poison error with diagnostic options
benlangmuir May 12, 2023
d2658ca
[clang][objc] Fix test for protocol stub fixits
benlangmuir May 17, 2023
c0b1a05
[clang][objc] Fix non-deterministic stub fixit output for missing req…
benlangmuir May 17, 2023
f11b5e7
[ThinLTO] Make the cache key independent of the module identifier paths
akyrtzi May 22, 2023
7bacdf8
[clang/DiagnosticLexKinds] Mark `-Wreproducible-caching` as DefaultWa…
akyrtzi Jun 21, 2023
0e17e27
[clang/HeaderSearch] Make sure `loadSubdirectoryModuleMaps` doesn't c…
akyrtzi Jun 23, 2023
d0f6c8b
[clang][modules] Avoid serializing all diag mappings in non-determini…
benlangmuir Jun 28, 2023
1b5110b
[clang][deps] Make clang-scan-deps write modules in raw format
benlangmuir May 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void disableUnsupportedOptions(CompilerInvocation &CI) {
// Always default to raw container format as clangd doesn't registry any other
// and clang dies when faced with unknown formats.
CI.getHeaderSearchOpts().ModuleFormat =
PCHContainerOperations().getRawReader().getFormat().str();
PCHContainerOperations().getRawReader().getFormats().front().str();

CI.getFrontendOpts().Plugins.clear();
CI.getFrontendOpts().AddPluginActions.clear();
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/DiagnosticIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ class DiagnosticMapping {
Result.Severity = Bits & 0x7;
return Result;
}

bool operator==(DiagnosticMapping Other) const {
return serialize() == Other.serialize();
}
};

/// Used for handling and querying diagnostic IDs.
Expand Down Expand Up @@ -209,6 +213,9 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
/// default.
static bool isDefaultMappingAsError(unsigned DiagID);

/// Get the default mapping for this diagnostic.
static DiagnosticMapping getDefaultMapping(unsigned DiagID);

/// Determine whether the given built-in diagnostic ID is a Note.
static bool isBuiltinNote(unsigned DiagID);

Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/DiagnosticLexKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,8 @@ def warn_pp_date_time : Warning<

def warn_pp_encounter_nonreproducible: Warning<
"encountered non-reproducible token, caching will be skipped">,
InGroup<DiagGroup<"reproducible-caching">>, DefaultIgnore;
InGroup<DiagGroup<"reproducible-caching">>,
DefaultWarnNoWerror, ShowInSystemHeader, ShowInSystemMacro;
def err_pp_encounter_nonreproducible: Error<
"encountered non-reproducible token, caching failed">;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter {
/// A PCHContainerReader implementation that uses LLVM to
/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
class ObjectFilePCHContainerReader : public PCHContainerReader {
StringRef getFormat() const override { return "obj"; }
ArrayRef<StringRef> getFormats() const override;

/// Returns the serialized AST inside the PCH container Buffer.
StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -6650,6 +6650,11 @@ defm cache_disable_replay : BoolFOption<"cache-disable-replay",
PosFlag<SetTrue, [], "Disable replaying a cached compile job">,
NegFlag<SetFalse>>;

defm modules_skip_diagnostic_options : BoolFOption<"modules-skip-diagnostic-options",
HeaderSearchOpts<"ModulesSkipDiagnosticOptions">, DefaultFalse,
PosFlag<SetTrue, [], "Disable writing diagnostic options">,
NegFlag<SetFalse>>;

def fcompilation_caching_service_path : Separate<["-"], "fcompilation-caching-service-path">,
Group<f_Group>, MetaVarName<"<pathname>">,
HelpText<"Specify the socket path for connecting to a remote caching service">,
Expand Down
100 changes: 100 additions & 0 deletions clang/include/clang/Frontend/CompileJobCache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//===- CompileJobCache.h ----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_FRONTEND_COMPILEJOBCACHE_H
#define LLVM_CLANG_FRONTEND_COMPILEJOBCACHE_H

#include "clang/Frontend/CompileJobCacheResult.h"

namespace clang {

class CompilerInstance;
class DiagnosticsEngine;

// Manage caching and replay of compile jobs.
//
// The high-level model is:
//
// 1. Extract options from the CompilerInvocation:
// - that can be simulated and
// - that don't affect the compile job's result.
// 2. Canonicalize the options extracted in (1).
// 3. Compute the result of the compile job using the canonicalized
// CompilerInvocation, with hooks installed to redirect outputs and
// enable live-streaming of a running compile job to stdout or stderr.
// - Compute a cache key.
// - Check the cache, and run the compile job if there's a cache miss.
// - Store the result of the compile job in the cache.
// 4. Replay the compile job, using the options extracted in (1).
//
// An example (albeit not yet implemented) is handling options controlling
// output of diagnostics. The CompilerInvocation can be canonicalized to
// serialize the diagnostics to a virtual path (<output>.diag or something).
//
// - On a cache miss, the compile job runs, and the diagnostics are
// serialized and stored in the cache per the canonicalized options
// from (2).
// - Either way, the diagnostics are replayed according to the options
// extracted from (1) during (4).
//
// The above will produce the correct output for diagnostics, but the experience
// will be degraded in the common command-line case (emitting to stderr)
// because the diagnostics will not be streamed live. This can be improved:
//
// - Change (3) to accept a hook: a DiagnosticsConsumer that diagnostics
// are mirrored to (in addition to canonicalized options from (2)).
// - If diagnostics would be live-streamed, send in a diagnostics consumer
// that matches (1). Otherwise, send in an IgnoringDiagnosticsConsumer.
// - In step (4), only skip replaying the diagnostics if they were already
// handled.
class CompileJobCache {
public:
CompileJobCache();
~CompileJobCache();

using OutputKind = clang::cas::CompileJobCacheResult::OutputKind;

StringRef getPathForOutputKind(OutputKind Kind);

/// Canonicalize \p Clang.
///
/// \returns status if should exit immediately, otherwise None.
///
/// TODO: Refactor \a cc1_main() so that instead this canonicalizes the
/// CompilerInvocation before Clang gets access to command-line arguments, to
/// control what might leak.
std::optional<int> initialize(CompilerInstance &Clang);

/// Try looking up a cached result and replaying it.
///
/// \returns status if should exit immediately, otherwise None.
std::optional<int> tryReplayCachedResult(CompilerInstance &Clang);

/// Finish writing outputs from a computed result, after a cache miss.
///
/// \returns true if finished successfully.
bool finishComputedResult(CompilerInstance &Clang, bool Success);

class CachingOutputs;

private:
int reportCachingBackendError(DiagnosticsEngine &Diag, llvm::Error &&E);

bool CacheCompileJob = false;
bool DisableCachedCompileJobReplay = false;

std::shared_ptr<llvm::cas::ObjectStore> CAS;
std::shared_ptr<llvm::cas::ActionCache> Cache;
llvm::Optional<llvm::cas::CASID> ResultCacheKey;

std::unique_ptr<CachingOutputs> CacheBackend;
};

} // namespace clang

#endif // LLVM_CLANG_FRONTEND_COMPILEJOBCACHE_H
8 changes: 8 additions & 0 deletions clang/include/clang/Frontend/CompilerInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "llvm/CAS/CASOutputBackend.h"
#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/PrefixMapper.h"
#include "llvm/Support/VirtualOutputBackend.h"
#include <cassert>
#include <list>
Expand Down Expand Up @@ -94,6 +95,9 @@ class CompilerInstance : public ModuleLoader {
/// The \c ActionCache key for this compilation, if caching is enabled.
Optional<cas::CASID> CompileJobCacheKey;

/// The prefix mapper; empty by default.
llvm::PrefixMapper PrefixMapper;

/// The file manager.
IntrusiveRefCntPtr<FileManager> FileMgr;

Expand Down Expand Up @@ -362,6 +366,10 @@ class CompilerInstance : public ModuleLoader {
}
bool isSourceNonReproducible() const;

llvm::PrefixMapper &getPrefixMapper() { return PrefixMapper; }

void setPrefixMapper(llvm::PrefixMapper PM) { PrefixMapper = std::move(PM); }

/// }
/// @name Diagnostics Engine
/// {
Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ class FrontendOptions {
/// caching of compilation outputs. This is used for testing purposes.
unsigned DisableCachedCompileJobReplay : 1;

/// Keep the diagnostic client open for receiving diagnostics after the source
/// files have been processed.
unsigned MayEmitDiagnosticsAfterProcessingSourceFiles : 1;

/// Output (and read) PCM files regardless of compiler errors.
unsigned AllowPCMWithCompilerErrors : 1;

Expand Down Expand Up @@ -570,7 +574,9 @@ class FrontendOptions {
ASTDumpLookups(false), BuildingImplicitModule(false),
BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false),
IncludeTimestamps(true), UseTemporary(true), CacheCompileJob(false),
DisableCachedCompileJobReplay(false), AllowPCMWithCompilerErrors(false),
DisableCachedCompileJobReplay(false),
MayEmitDiagnosticsAfterProcessingSourceFiles(false),
AllowPCMWithCompilerErrors(false),
ModulesShareFileManager(true), TimeTraceGranularity(500) {}

/// getInputKindForExtension - Return the appropriate input kind for a file
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Lex/DependencyDirectivesScanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ enum DirectiveKind : uint8_t {
pp_pragma_push_macro,
pp_pragma_pop_macro,
pp_pragma_include_alias,
pp_pragma_system_header,
pp_include_next,
pp_if,
pp_ifdef,
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Lex/HeaderSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,9 +653,13 @@ class HeaderSearch {

/// Retrieve all the modules corresponding to the given file.
///
/// \param AllowCreation Whether to allow inference of a new submodule, or to
/// only return existing known modules.
///
/// \ref findModuleForHeader should typically be used instead of this.
ArrayRef<ModuleMap::KnownHeader>
findAllModulesForHeader(const FileEntry *File) const;
findAllModulesForHeader(const FileEntry *File,
bool AllowCreation = true) const;

/// Read the contents of the given module map file.
///
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Lex/HeaderSearchOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ class HeaderSearchOptions {

unsigned ModulesValidateDiagnosticOptions : 1;

/// Whether to entirely skip writing diagnostic options.
unsigned ModulesSkipDiagnosticOptions : 1;

unsigned ModulesHashContent : 1;

/// Whether we should include all things that could impact the module in the
Expand All @@ -234,7 +237,8 @@ class HeaderSearchOptions {
ModulesValidateOncePerBuildSession(false),
ModulesValidateSystemHeaders(false),
ValidateASTInputFilesContent(false), UseDebugInfo(false),
ModulesValidateDiagnosticOptions(true), ModulesHashContent(false),
ModulesValidateDiagnosticOptions(true),
ModulesSkipDiagnosticOptions(false), ModulesHashContent(false),
ModulesStrictContextHash(false) {}

/// AddPath - Add the \p Path path to the specified \p Group list.
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Lex/ModuleMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,9 +458,13 @@ class ModuleMap {
/// and does not consult the external source. (Those checks are the
/// responsibility of \ref HeaderSearch.)
///
/// \param AllowCreation Whether to allow inference of a new submodule, or to
/// only return existing known modules.
///
/// Typically, \ref findModuleForHeader should be used instead, as it picks
/// the preferred module for the header.
ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File);
ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File,
bool AllowCreation = true);

/// Like \ref findAllModulesForHeader, but do not attempt to infer module
/// ownership from umbrella headers if we've not already done so.
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Lex/Pragma.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ class PragmaNamespace : public PragmaHandler {
PragmaNamespace *getIfNamespace() override { return this; }
};

/// Destringize a \c _Pragma("") string according to C11 6.10.9.1:
/// "The string literal is destringized by deleting any encoding prefix,
/// deleting the leading and trailing double-quotes, replacing each escape
/// sequence \" by a double-quote, and replacing each escape sequence \\ by a
/// single backslash."
void prepare_PragmaString(SmallVectorImpl<char> &StrVal);

} // namespace clang

#endif // LLVM_CLANG_LEX_PRAGMA_H
10 changes: 8 additions & 2 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -961,8 +961,14 @@ class ASTReader

private:
/// A list of modules that were imported by precompiled headers or
/// any other non-module AST file.
SmallVector<ImportedSubmodule, 2> ImportedModules;
/// any other non-module AST file and have not yet been made visible. If a
/// module is made visible in the ASTReader, it will be transfered to
/// \c PendingImportedModulesSema.
SmallVector<ImportedSubmodule, 2> PendingImportedModules;

/// A list of modules that were imported by precompiled headers or
/// any other non-module AST file and have not yet been made visible for Sema.
SmallVector<ImportedSubmodule, 2> PendingImportedModulesSema;
//@}

/// The system include root to be used when loading the
Expand Down
17 changes: 11 additions & 6 deletions clang/include/clang/Serialization/PCHContainerOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class PCHContainerReader {
public:
virtual ~PCHContainerReader() = 0;
/// Equivalent to the format passed to -fmodule-format=
virtual llvm::StringRef getFormat() const = 0;
virtual llvm::ArrayRef<llvm::StringRef> getFormats() const = 0;

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

/// Implements read operations for a raw pass-through PCH container.
class RawPCHContainerReader : public PCHContainerReader {
llvm::StringRef getFormat() const override { return "raw"; }

llvm::ArrayRef<llvm::StringRef> getFormats() const override;
/// Simply returns the buffer contained in Buffer.
llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
};

/// A registry of PCHContainerWriter and -Reader objects for different formats.
class PCHContainerOperations {
llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers;
llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers;
llvm::StringMap<PCHContainerReader *> Readers;
llvm::SmallVector<std::unique_ptr<PCHContainerReader>> OwnedReaders;

public:
/// Automatically registers a RawPCHContainerWriter and
/// RawPCHContainerReader.
Expand All @@ -96,13 +97,17 @@ class PCHContainerOperations {
Writers[Writer->getFormat()] = std::move(Writer);
}
void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
Readers[Reader->getFormat()] = std::move(Reader);
assert(!Reader->getFormats().empty() &&
"PCHContainerReader must handle >=1 format");
for (llvm::StringRef Fmt : Reader->getFormats())
Readers[Fmt] = Reader.get();
OwnedReaders.push_back(std::move(Reader));
}
const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) {
return Writers[Format].get();
}
const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) {
return Readers[Format].get();
return Readers[Format];
}
const PCHContainerReader &getRawReader() {
return *getReaderOrNull("raw");
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Basic/Diagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,18 @@ void DiagnosticsEngine::ReportDelayed() {
Report(ID) << DelayedDiagArg1 << DelayedDiagArg2 << DelayedDiagArg3;
}

DiagnosticMapping &
DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
std::pair<iterator, bool> Result =
DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));

// Initialize the entry if we added it.
if (Result.second)
Result.first->second = DiagnosticIDs::getDefaultMapping(Diag);

return Result.first->second;
}

void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) {
assert(Files.empty() && "not first");
FirstDiagState = CurDiagState = State;
Expand Down
Loading