From ce65bfa22872a8ac11b5b26de8a70a703089ffb0 Mon Sep 17 00:00:00 2001 From: Shubham Sandeep Rastogi Date: Fri, 16 Aug 2024 17:36:12 -0700 Subject: [PATCH] Swift MCCAS object files are 0 bytes on cache miss When clang caching and MCCAS are enabled, on a cache miss, the object file is not written to in MachOCASWriter, instead the replay code is rerun and the object file is serialized and written out. However, in swift, the replay code isn't run on a cache miss at all, and it expects the object writer to write to the object file. This patch makes it so that on a cache miss, the MachOCASWriter always writes to the raw_ostream buffer for the object file and doesn't serialize the object file in the replay code. --- clang/lib/Frontend/CompileJobCache.cpp | 7 ++----- clang/test/CAS/cas-backend.c | 4 ++-- clang/test/CAS/casid-output-test.cpp | 25 +++++++++++++++++++++++++ llvm/lib/MC/MachOCASWriter.cpp | 17 ++--------------- 4 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 clang/test/CAS/casid-output-test.cpp diff --git a/clang/lib/Frontend/CompileJobCache.cpp b/clang/lib/Frontend/CompileJobCache.cpp index 44e509080f69d..018e3a085969c 100644 --- a/clang/lib/Frontend/CompileJobCache.cpp +++ b/clang/lib/Frontend/CompileJobCache.cpp @@ -724,7 +724,7 @@ Error ObjectStoreCachingOutputs::finishComputedResult( std::optional ObjectStoreCachingOutputs::replayCachedResult( const llvm::cas::CASID &ResultCacheKey, llvm::cas::ObjectRef ResultID, bool JustComputedResult) { - if (JustComputedResult && !ComputedJobNeedsReplay) + if (JustComputedResult && !WriteOutputAsCASID) return std::nullopt; // FIXME: Stop calling report_fatal_error(). @@ -745,10 +745,7 @@ std::optional ObjectStoreCachingOutputs::replayCachedResult( Expected> ObjectStoreCachingOutputs::replayCachedResult( const llvm::cas::CASID &ResultCacheKey, clang::cas::CompileJobCacheResult &Result, bool JustComputedResult) { - // FIXME: The correct fix for MCCAS replay is that you have an official CASID - // file output going all the way down into ObjectWriter, we can remove this - // callback and special case. - if (JustComputedResult && !ComputedJobNeedsReplay) + if (JustComputedResult && !WriteOutputAsCASID) return std::nullopt; llvm::cas::ObjectStore &CAS = Result.getCAS(); diff --git a/clang/test/CAS/cas-backend.c b/clang/test/CAS/cas-backend.c index 725ea3f50ae71..662c45b0f7212 100644 --- a/clang/test/CAS/cas-backend.c +++ b/clang/test/CAS/cas-backend.c @@ -1,7 +1,7 @@ // RUN: rm -rf %t && mkdir -p %t // RUN: llvm-cas --cas %t/cas --ingest %s > %t/casid // -// RUN: %clang -cc1 -triple x86_64-apple-macos11 -fcas-backend \ +// RUN: %clang -cc1 -fcas-emit-casid-file -triple x86_64-apple-macos11 -fcas-backend \ // RUN: -fcas-path %t/cas -fcas-fs @%t/casid -fcache-compile-job \ // RUN: -Rcompile-job-cache %s -emit-obj -o %t/output.o \ // RUN: -debug-info-kind=standalone -dwarf-version=4 -debugger-tuning=lldb \ @@ -11,7 +11,7 @@ // RUN: ls %t/output.o && rm %t/output.o // RUN: ls %t/deps.d && mv %t/deps.d %t/deps.d.orig // -// RUN: CLANG_CAS_BACKEND_SAVE_CASID_FILE=1 %clang -cc1 \ +// RUN: %clang -cc1 -fcas-emit-casid-file\ // RUN: -triple x86_64-apple-macos11 -fcas-backend \ // RUN: -fcas-path %t/cas -fcas-fs @%t/casid -fcache-compile-job \ // RUN: -Rcompile-job-cache %s -emit-obj -o %t/output.o \ diff --git a/clang/test/CAS/casid-output-test.cpp b/clang/test/CAS/casid-output-test.cpp new file mode 100644 index 0000000000000..2e4f98761b64b --- /dev/null +++ b/clang/test/CAS/casid-output-test.cpp @@ -0,0 +1,25 @@ +// RUN: rm -rf %t && mkdir -p %t + +// Check if -fcasid-output works on a cache miss with file based caching +// RUN: env LLVM_CACHE_CAS_PATH=%t/cas CLANG_CACHE_DISABLE_MCCAS=1 %clang-cache %clang -target x86_64-apple-macos11 -Xclang -fcasid-output -g -c %s -o %t/test.o +// RUN: cat %t/test.o | FileCheck %s +// RUN: rm -rf %t/test.o +// Check if -fcasid-output works on a cache hit with file based caching +// RUN: env LLVM_CACHE_CAS_PATH=%t/cas CLANG_CACHE_DISABLE_MCCAS=1 %clang-cache %clang -target x86_64-apple-macos11 -Xclang -fcasid-output -g -c %s -o %t/test.o +// RUN: cat %t/test.o | FileCheck %s +// RUN: rm -rf %t/test.o +// RUN: rm -rf %t/cas + +// Check if -fcasid-output works on a cache miss with MCCAS +// RUN: env LLVM_CACHE_CAS_PATH=%t/cas %clang-cache %clang -target x86_64-apple-macos11 -Xclang -fcasid-output -g -c %s -o %t/test.o +// RUN: cat %t/test.o | FileCheck %s +// RUN: rm -rf %t/test.o + +// Check if -fcasid-output works on a cache hit with MCCAS +// RUN: env LLVM_CACHE_CAS_PATH=%t/cas %clang-cache %clang -target x86_64-apple-macos11 -Xclang -fcasid-output -g -c %s -o %t/test.o +// RUN: cat %t/test.o | FileCheck %s + +// CHECK: llvmcas://{{[a-f0-9]+}} + + +void foo() {} diff --git a/llvm/lib/MC/MachOCASWriter.cpp b/llvm/lib/MC/MachOCASWriter.cpp index 2235b1976e687..be16b6c662cb9 100644 --- a/llvm/lib/MC/MachOCASWriter.cpp +++ b/llvm/lib/MC/MachOCASWriter.cpp @@ -78,6 +78,7 @@ uint64_t MachOCASWriter::writeObject(MCAssembler &Asm, inconvertibleErrorCode(), "CASBackend output round-trip verification error"); + OS << ObjectBuffer; return Error::success(); }; @@ -87,11 +88,6 @@ uint64_t MachOCASWriter::writeObject(MCAssembler &Asm, // If there is a callback, then just hand off the result through callback. if (ResultCallBack) { cantFail((*ResultCallBack)(CASObj.getID())); - if (Mode == CASBackendMode::Verify) { - if (auto E = VerifyObject()) - report_fatal_error(std::move(E)); - } - return 0; } switch (Mode) { @@ -105,17 +101,8 @@ uint64_t MachOCASWriter::writeObject(MCAssembler &Asm, break; } case CASBackendMode::Verify: { - SmallString<512> ObjectBuffer; - raw_svector_ostream ObjectOS(ObjectBuffer); - auto E = SerializeObjectFile(CASObj, CAS, ObjectOS); - if (E) + if (auto E = VerifyObject()) report_fatal_error(std::move(E)); - - if (!ObjectBuffer.equals(InternalBuffer)) - report_fatal_error("CASBackend output round-trip verification error"); - - OS << ObjectBuffer; - break; } }