Skip to content

Commit b3735f6

Browse files
author
git apple-llvm automerger
committed
Merge commit '5a4109d44085' from swift/release/6.0 into stable/20230725
2 parents aacdb41 + 5a4109d commit b3735f6

File tree

6 files changed

+157
-6
lines changed

6 files changed

+157
-6
lines changed

clang/include/clang/Frontend/CompileJobCache.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ class CompileJobCache {
9292
class CachingOutputs;
9393

9494
private:
95+
/// \returns true if the output from the compilation is not supported for
96+
/// caching.
97+
Expected<bool>
98+
maybeIngestNonVirtualOutputFromFileSystem(CompilerInstance &Clang);
9599
int reportCachingBackendError(DiagnosticsEngine &Diag, llvm::Error &&E);
96100

97101
bool CacheCompileJob = false;

clang/lib/Frontend/CompileJobCache.cpp

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class CompileJobCache::CachingOutputs {
5151

5252
void stopDiagnosticsCapture();
5353

54+
/// This is for an output file that was written directly on the file system.
55+
/// It's a workaround until all compilation consumers adopt
56+
/// \c llvm::vfs::OutputBackend.
57+
virtual Error addNonVirtualOutputFile(StringRef FilePath) = 0;
58+
5459
/// Finish writing outputs from a computed result, after a cache miss.
5560
/// If SkipCache is true, it should not insert the ResultCacheKey into
5661
/// Cache for future uses.
@@ -105,6 +110,8 @@ class ObjectStoreCachingOutputs : public CompileJobCache::CachingOutputs {
105110

106111
bool prepareOutputCollection() override;
107112

113+
Error addNonVirtualOutputFile(StringRef FilePath) override;
114+
108115
Error finishComputedResult(const llvm::cas::CASID &ResultCacheKey,
109116
bool SkipCache) override;
110117

@@ -143,6 +150,11 @@ class CollectingOutputBackend : public llvm::vfs::ProxyOutputBackend {
143150
KindMaps.push_back({Saver.save(Kind), Saver.save(Path)});
144151
}
145152

153+
void addOutput(StringRef Path) {
154+
StringRef Name = tryRemapPath(Path);
155+
OutputNames.push_back(Name.str());
156+
}
157+
146158
private:
147159
llvm::BumpPtrAllocator Alloc;
148160
llvm::StringSaver Saver{Alloc};
@@ -166,8 +178,7 @@ class CollectingOutputBackend : public llvm::vfs::ProxyOutputBackend {
166178
Expected<std::unique_ptr<llvm::vfs::OutputFileImpl>>
167179
createFileImpl(StringRef Path,
168180
std::optional<llvm::vfs::OutputConfig> Config) override {
169-
StringRef Name = tryRemapPath(Path);
170-
OutputNames.push_back(Name.str());
181+
addOutput(Path);
171182
return ProxyOutputBackend::createFileImpl(Path, std::move(Config));
172183
}
173184

@@ -198,6 +209,8 @@ class RemoteCachingOutputs : public CompileJobCache::CachingOutputs {
198209

199210
bool prepareOutputCollection() override;
200211

212+
Error addNonVirtualOutputFile(StringRef FilePath) override;
213+
201214
Error finishComputedResult(const llvm::cas::CASID &ResultCacheKey,
202215
bool SkipCache) override;
203216

@@ -514,9 +527,18 @@ bool CompileJobCache::finishComputedResult(CompilerInstance &Clang,
514527

515528
DiagnosticsEngine &Diags = Clang.getDiagnostics();
516529

530+
bool UnsupportedOutput;
531+
if (Error E = maybeIngestNonVirtualOutputFromFileSystem(Clang).moveInto(
532+
UnsupportedOutput)) {
533+
reportCachingBackendError(Diags, std::move(E));
534+
return false;
535+
}
536+
517537
// Check if we encounter any source that would generate non-reproducible
518538
// outputs.
519-
bool SkipCache = Clang.hasPreprocessor() && Clang.isSourceNonReproducible();
539+
bool SkipCache =
540+
(Clang.hasPreprocessor() && Clang.isSourceNonReproducible()) ||
541+
UnsupportedOutput;
520542
if (SkipCache) {
521543
switch (Clang.getPreprocessorOpts().CachingDiagOption) {
522544
case CachingDiagKind::None:
@@ -538,6 +560,31 @@ bool CompileJobCache::finishComputedResult(CompilerInstance &Clang,
538560
return true;
539561
}
540562

563+
Expected<bool> CompileJobCache::maybeIngestNonVirtualOutputFromFileSystem(
564+
CompilerInstance &Clang) {
565+
// FIXME: All consumers should adopt \c llvm::vfs::OutputBackend and this
566+
// function should go away.
567+
568+
const auto &FrontendOpts = Clang.getFrontendOpts();
569+
if (FrontendOpts.ProgramAction == frontend::RunAnalysis) {
570+
StringRef OutputPath = FrontendOpts.OutputFile;
571+
if (OutputPath.empty())
572+
return false;
573+
if (llvm::sys::fs::is_directory(OutputPath)) {
574+
// FIXME: A directory is produced for the 'html' output of the analyzer,
575+
// support it for caching purposes.
576+
Clang.getDiagnostics().Report(diag::warn_clang_cache_disabled_caching)
577+
<< "analyzer output is not supported";
578+
return true;
579+
}
580+
if (Error E = CacheBackend->addNonVirtualOutputFile(OutputPath))
581+
return std::move(E);
582+
return false;
583+
}
584+
585+
return false;
586+
}
587+
541588
Expected<std::optional<int>> CompileJobCache::replayCachedResult(
542589
std::shared_ptr<CompilerInvocation> Invok, StringRef WorkingDir,
543590
const llvm::cas::CASID &CacheKey, cas::CompileJobCacheResult &CachedResult,
@@ -633,6 +680,20 @@ Expected<llvm::cas::ObjectRef> ObjectStoreCachingOutputs::writeOutputs(
633680
return CachedResultBuilder.build(*CAS);
634681
}
635682

683+
Error ObjectStoreCachingOutputs::addNonVirtualOutputFile(StringRef FilePath) {
684+
auto F = llvm::sys::fs::openNativeFileForRead(FilePath);
685+
if (!F)
686+
return F.takeError();
687+
auto CloseOnExit =
688+
llvm::make_scope_exit([&F]() { llvm::sys::fs::closeFile(*F); });
689+
690+
std::optional<llvm::cas::ObjectRef> ObjRef;
691+
if (Error E = CAS->storeFromOpenFile(*F).moveInto(ObjRef))
692+
return E;
693+
CASOutputs->addObject(FilePath, *ObjRef);
694+
return Error::success();
695+
}
696+
636697
Error ObjectStoreCachingOutputs::finishComputedResult(
637698
const llvm::cas::CASID &ResultCacheKey, bool SkipCache) {
638699
Expected<llvm::cas::ObjectRef> Result = writeOutputs(ResultCacheKey);
@@ -1017,6 +1078,11 @@ RemoteCachingOutputs::saveOutputs(const llvm::cas::CASID &ResultCacheKey) {
10171078
return std::move(CompResult);
10181079
}
10191080

1081+
Error RemoteCachingOutputs::addNonVirtualOutputFile(StringRef FilePath) {
1082+
CollectingOutputs->addOutput(FilePath);
1083+
return Error::success();
1084+
}
1085+
10201086
Error RemoteCachingOutputs::finishComputedResult(
10211087
const llvm::cas::CASID &ResultCacheKey, bool SkipCache) {
10221088
if (SkipCache)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// REQUIRES: remote-cache-service
2+
3+
// Need a short path for the unix domain socket (and unique for this test file).
4+
// RUN: rm -f %{remote-cache-dir}/%basename_t
5+
// RUN: rm -rf %t && mkdir -p %t
6+
7+
// RUN: %clang_cc1 -cc1 -triple x86_64-apple-macosx12 -analyze -analyzer-checker=deadcode -analyzer-output plist %s -o %t/regular.plist 2>&1 \
8+
// RUN: | FileCheck %s --check-prefix=CHECK-DIAG
9+
// RUN: FileCheck %s --input-file=%t/regular.plist --check-prefix=CHECK-PLIST
10+
11+
// CHECK-DIAG: Value stored to 'v' during its initialization is never read
12+
// CHECK-PLIST: Value stored to &apos;v&apos; during its initialization is never read
13+
14+
// RUN: llvm-remote-cache-test -socket-path=%{remote-cache-dir}/%basename_t -cache-path=%t/cache -- env LLVM_CACHE_CAS_PATH=%t/cas %clang-cache \
15+
// RUN: %clang -target x86_64-apple-macosx12 --analyze --analyzer-output plist %s -o %t/cached.plist
16+
// RUN: rm %t/cached.plist
17+
// RUN: llvm-remote-cache-test -socket-path=%{remote-cache-dir}/%basename_t -cache-path=%t/cache -- env LLVM_CACHE_CAS_PATH=%t/cas %clang-cache \
18+
// RUN: %clang -target x86_64-apple-macosx12 --analyze --analyzer-output plist %s -o %t/cached.plist -Rcompile-job-cache \
19+
// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-HIT
20+
21+
// CHECK-HIT: remark: compile job cache hit
22+
// CHECK-HIT: Value stored to 'v' during its initialization is never read
23+
24+
// RUN: diff -u %t/regular.plist %t/cached.plist
25+
26+
// Check cache is skipped for analyzer html output.
27+
// RUN: llvm-remote-cache-test -socket-path=%{remote-cache-dir}/%basename_t -cache-path=%t/cache -- env LLVM_CACHE_CAS_PATH=%t/cas %clang-cache \
28+
// RUN: %clang -target x86_64-apple-macosx12 --analyze --analyzer-output html %s -o %t/analysis -Rcompile-job-cache -Wclang-cache \
29+
// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-HTML
30+
// RUN: llvm-remote-cache-test -socket-path=%{remote-cache-dir}/%basename_t -cache-path=%t/cache -- env LLVM_CACHE_CAS_PATH=%t/cas %clang-cache \
31+
// RUN: %clang -target x86_64-apple-macosx12 --analyze --analyzer-output html %s -o %t/analysis -Rcompile-job-cache -Wclang-cache \
32+
// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-HTML
33+
34+
// CHECK-HTML: remark: compile job cache miss
35+
// CHECK-HTML: remark: compile job cache skipped
36+
// FIXME: `analyse` action passes `-w` for `-cc1` args and the "caching disabled" warning doesn't show up.
37+
38+
void foo(int *p) {
39+
int v = p[0];
40+
}

clang/test/CAS/analyze-action.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: rm -rf %t && mkdir -p %t
2+
3+
// RUN: %clang_cc1 -cc1 -triple x86_64-apple-macosx12 -analyze -analyzer-checker=deadcode -analyzer-output plist %s -o %t/regular.plist 2>&1 \
4+
// RUN: | FileCheck %s --check-prefix=CHECK-DIAG
5+
// RUN: FileCheck %s --input-file=%t/regular.plist --check-prefix=CHECK-PLIST
6+
7+
// CHECK-DIAG: Value stored to 'v' during its initialization is never read
8+
// CHECK-PLIST: Value stored to &apos;v&apos; during its initialization is never read
9+
10+
// RUN: %clang -cc1depscan -fdepscan=inline -fdepscan-include-tree -o %t/t.rsp -cc1-args \
11+
// RUN: -cc1 -triple x86_64-apple-macosx12 -fcas-path %t/cas -analyze -analyzer-checker=deadcode -analyzer-output plist %s -o %t/cached.plist
12+
// RUN: %clang @%t/t.rsp
13+
14+
// RUN: rm %t/cached.plist
15+
// RUN: %clang @%t/t.rsp -Rcompile-job-cache 2>&1 \
16+
// RUN: | FileCheck %s --check-prefix=CHECK-HIT
17+
18+
// CHECK-HIT: remark: compile job cache hit
19+
// CHECK-HIT: Value stored to 'v' during its initialization is never read
20+
21+
// RUN: diff -u %t/regular.plist %t/cached.plist
22+
23+
// Check cache is skipped for analyzer html output.
24+
// RUN: %clang -cc1depscan -fdepscan=inline -fdepscan-include-tree -o %t/t2.rsp -cc1-args \
25+
// RUN: -cc1 -triple x86_64-apple-macosx12 -fcas-path %t/cas -analyze -analyzer-checker=deadcode -analyzer-output html %s -o %t/analysis
26+
// RUN: %clang @%t/t2.rsp -Rcompile-job-cache 2>&1 \
27+
// RUN: | FileCheck %s --check-prefix=CHECK-HTML
28+
// RUN: %clang @%t/t2.rsp -Rcompile-job-cache 2>&1 \
29+
// RUN: | FileCheck %s --check-prefix=CHECK-HTML
30+
31+
// CHECK-HTML: remark: compile job cache miss
32+
// CHECK-HTML: warning: caching disabled because analyzer output is not supported
33+
// CHECK-HTML: remark: compile job cache skipped
34+
35+
void foo(int *p) {
36+
int v = p[0];
37+
}

llvm/include/llvm/CAS/CASOutputBackend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class CASOutputBackend : public vfs::OutputBackend {
3333
SmallVector<OutputFile> takeOutputs() { return std::move(Outputs); }
3434

3535
/// Add a CAS object to the path in the output backend.
36-
Error addObject(StringRef Path, const CASID &Object);
36+
void addObject(StringRef Path, ObjectRef Object);
3737

3838
private:
3939
Expected<std::unique_ptr<vfs::OutputFileImpl>>

llvm/lib/CAS/CASOutputBackend.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,12 @@ CASOutputBackend::createFileImpl(StringRef ResolvedPath,
6060
if (Error E =
6161
CAS.storeFromString(std::nullopt, Bytes).moveInto(BytesRef))
6262
return E;
63-
// FIXME: Should there be a lock taken before modifying Outputs?
64-
Outputs.push_back({std::string(Path), *BytesRef});
63+
addObject(Path, *BytesRef);
6564
return Error::success();
6665
});
6766
}
67+
68+
void CASOutputBackend::addObject(StringRef Path, ObjectRef Object) {
69+
// FIXME: Should there be a lock taken before modifying Outputs?
70+
Outputs.push_back({std::string(Path), Object});
71+
}

0 commit comments

Comments
 (0)