Skip to content

Commit f509a29

Browse files
Merge pull request #66575 from cachemeifyoucan/eng/PR-caching-tune-up
Various cleanups to allow better swift caching.
2 parents 282a9a7 + b8e2f37 commit f509a29

File tree

14 files changed

+147
-77
lines changed

14 files changed

+147
-77
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,11 @@ class ClangImporter final : public ClangModuleLoader {
409409
/// Reads the original source file name from PCH.
410410
std::string getOriginalSourceFile(StringRef PCHFilename);
411411

412+
/// Add clang dependency file names.
413+
///
414+
/// \param files The list of file to append dependencies to.
415+
void addClangInvovcationDependencies(std::vector<std::string> &files);
416+
412417
/// Makes a temporary replica of the ClangImporter's CompilerInstance, reads a
413418
/// module map into the replica and emits a PCM file for one of the modules it
414419
/// declares. Delegates to clang for everything except construction of the

include/swift/ConstExtract/ConstExtract.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ gatherConstValuesForModule(const std::unordered_set<std::string> &Protocols,
5555
/// Serialize a collection of \c ConstValueInfos to JSON at the
5656
/// provided output stream.
5757
bool writeAsJSONToFile(const std::vector<ConstValueTypeInfo> &ConstValueInfos,
58-
llvm::raw_fd_ostream &OS);
58+
llvm::raw_ostream &OS);
5959
} // namespace swift
6060

6161
#endif

lib/AST/ModuleDependencies.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,11 @@ void SwiftDependencyScanningService::setupCachingDependencyScanningService(
446446
}
447447
}
448448

449+
// Fetch some dependency files from clang importer.
450+
auto clangImporter = static_cast<ClangImporter *>(
451+
Instance.getASTContext().getClangModuleLoader());
452+
clangImporter->addClangInvovcationDependencies(CommonDependencyFiles);
453+
449454
auto CachingFS =
450455
llvm::cas::createCachingOnDiskFileSystem(Instance.getObjectStore());
451456
if (!CachingFS) {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,27 @@ std::string ClangImporter::getOriginalSourceFile(StringRef PCHFilename) {
939939
Impl.Instance->getPCHContainerReader(), Impl.Instance->getDiagnostics());
940940
}
941941

942+
void ClangImporter::addClangInvovcationDependencies(
943+
std::vector<std::string> &files) {
944+
auto addFiles = [&files](const auto &F) {
945+
files.insert(files.end(), F.begin(), F.end());
946+
};
947+
auto &invocation = *Impl.Invocation;
948+
// FIXME: Add file dependencies that are not accounted. The long term solution
949+
// is to do a dependency scanning for clang importer and use that directly.
950+
SmallVector<std::string, 4> HeaderMapFileNames;
951+
Impl.Instance->getPreprocessor().getHeaderSearchInfo().getHeaderMapFileNames(
952+
HeaderMapFileNames);
953+
addFiles(HeaderMapFileNames);
954+
addFiles(invocation.getHeaderSearchOpts().VFSOverlayFiles);
955+
// FIXME: Should not depend on working directory. Build system/swift driver
956+
// should not pass working directory here but if that option is passed,
957+
// repect that and add that into CASFS.
958+
auto CWD = invocation.getFileSystemOpts().WorkingDir;
959+
if (!CWD.empty())
960+
files.push_back(CWD);
961+
}
962+
942963
Optional<std::string>
943964
ClangImporter::getPCHFilename(const ClangImporterOptions &ImporterOptions,
944965
StringRef SwiftPCHHash, bool &isExplicit) {

lib/ConstExtract/ConstExtract.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ void writeAttrInformation(llvm::json::OStream &JSON,
804804
}
805805

806806
bool writeAsJSONToFile(const std::vector<ConstValueTypeInfo> &ConstValueInfos,
807-
llvm::raw_fd_ostream &OS) {
807+
llvm::raw_ostream &OS) {
808808
llvm::json::OStream JSON(OS, 2);
809809
JSON.array([&] {
810810
for (const auto &TypeInfo : ConstValueInfos) {

lib/Frontend/ArgsToFrontendOutputsConverter.cpp

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -587,24 +587,9 @@ createFromTypeToPathMap(const TypeToPathMap *map) {
587587
if (!map)
588588
return paths;
589589
const std::pair<file_types::ID, std::string &> typesAndStrings[] = {
590-
{file_types::TY_ClangHeader, paths.ClangHeaderOutputPath},
591-
{file_types::TY_SwiftModuleFile, paths.ModuleOutputPath},
592-
{file_types::TY_SwiftModuleDocFile, paths.ModuleDocOutputPath},
593-
{file_types::TY_SwiftSourceInfoFile, paths.ModuleSourceInfoOutputPath},
594-
{file_types::TY_Dependencies, paths.DependenciesFilePath},
595-
{file_types::TY_SwiftDeps, paths.ReferenceDependenciesFilePath},
596-
{file_types::TY_SerializedDiagnostics, paths.SerializedDiagnosticsPath},
597-
{file_types::TY_ModuleTrace, paths.LoadedModuleTracePath},
598-
{file_types::TY_TBD, paths.TBDPath},
599-
{file_types::TY_SwiftModuleInterfaceFile,
600-
paths.ModuleInterfaceOutputPath},
601-
{file_types::TY_SwiftModuleSummaryFile, paths.ModuleSummaryOutputPath},
602-
{file_types::TY_PrivateSwiftModuleInterfaceFile,
603-
paths.PrivateModuleInterfaceOutputPath},
604-
{file_types::TY_YAMLOptRecord, paths.YAMLOptRecordPath},
605-
{file_types::TY_BitstreamOptRecord, paths.BitstreamOptRecordPath},
606-
{file_types::TY_SwiftABIDescriptor, paths.ABIDescriptorOutputPath},
607-
{file_types::TY_ConstValues, paths.ConstValuesOutputPath}
590+
#define OUTPUT(NAME, TYPE) {file_types::TYPE, paths.NAME},
591+
#include "swift/Basic/SupplementaryOutputPaths.def"
592+
#undef OUTPUT
608593
};
609594
for (const std::pair<file_types::ID, std::string &> &typeAndString :
610595
typesAndStrings) {

lib/Frontend/CachedDiagnostics.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,33 @@ struct DiagnosticSerializer {
108108
ReplayFunc Fn = nullptr);
109109
llvm::Error serializeEmittedDiagnostics(llvm::raw_ostream &os);
110110

111-
static llvm::Error emitDiagnosticsFromCached(llvm::StringRef Buffer,
112-
SourceManager &SrcMgr,
113-
DiagnosticEngine &Diags) {
111+
static llvm::Error
112+
emitDiagnosticsFromCached(llvm::StringRef Buffer, SourceManager &SrcMgr,
113+
DiagnosticEngine &Diags,
114+
const FrontendInputsAndOutputs &InAndOut) {
114115
// Create a new DiagnosticSerializer since this cannot be shared with a
115116
// serialization instance.
116117
DiagnosticSerializer DS(SrcMgr.getFileSystem());
118+
DS.addInputsToSourceMgr(InAndOut);
117119
return DS.doEmitFromCached(Buffer, Diags);
118120
}
119121

120122
SourceManager &getSourceMgr() { return SrcMgr; }
121123

124+
void addInputsToSourceMgr(const FrontendInputsAndOutputs &InAndOut) {
125+
// Extract all the input file names so they can be added to the source
126+
// manager when replaying the diagnostics. All input files are needed even
127+
// they don't contain diagnostics because FileSpecificDiagConsumer need
128+
// has references to input files to find subconsumer.
129+
auto addInputToSourceMgr = [&](const InputFile &Input) {
130+
if (Input.getFileName() != "-")
131+
SrcMgr.getExternalSourceBufferID(Input.getFileName());
132+
return false;
133+
};
134+
InAndOut.forEachInputProducingSupplementaryOutput(addInputToSourceMgr);
135+
InAndOut.forEachNonPrimaryInput(addInputToSourceMgr);
136+
}
137+
122138
private:
123139
// Serialization helper
124140
unsigned getFileIDFromBufferID(SourceManager &SM, unsigned Idx);
@@ -632,7 +648,7 @@ class CachingDiagnosticsProcessor::Implementation
632648

633649
llvm::Error replayCachedDiagnostics(llvm::StringRef Buffer) {
634650
return DiagnosticSerializer::emitDiagnosticsFromCached(
635-
Buffer, getDiagnosticSourceMgr(), Diags);
651+
Buffer, getDiagnosticSourceMgr(), Diags, InAndOut);
636652
}
637653

638654
void handleDiagnostic(SourceManager &SM,
@@ -683,18 +699,7 @@ class CachingDiagnosticsProcessor::Implementation
683699
if (!Serializer) {
684700
Serializer.reset(
685701
new DiagnosticSerializer(InstanceSourceMgr.getFileSystem()));
686-
auto &SM = Serializer->getSourceMgr();
687-
// Extract all the input file names so they can be added to the source
688-
// manager when replaying the diagnostics. All input files are needed even
689-
// they don't contain diagnostics because FileSpecificDiagConsumer need
690-
// has references to input files to find subconsumer.
691-
auto addInputToSourceMgr = [&](const InputFile &Input) {
692-
if (Input.getFileName() != "-")
693-
SM.getExternalSourceBufferID(Input.getFileName());
694-
return false;
695-
};
696-
InAndOut.forEachInputProducingSupplementaryOutput(addInputToSourceMgr);
697-
InAndOut.forEachNonPrimaryInput(addInputToSourceMgr);
702+
Serializer->addInputsToSourceMgr(InAndOut);
698703
}
699704

700705
return *Serializer;

lib/Frontend/CompileJobCacheKey.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "llvm/ADT/STLExtras.h"
2121
#include "llvm/CAS/HierarchicalTreeBuilder.h"
2222
#include "llvm/CAS/ObjectStore.h"
23+
#include "llvm/Support/Error.h"
24+
#include "llvm/Support/MemoryBuffer.h"
2325

2426
using namespace swift;
2527

@@ -30,29 +32,45 @@ llvm::Expected<llvm::cas::ObjectRef> swift::createCompileJobBaseCacheKey(
3032

3133
// TODO: Improve this list.
3234
static const std::vector<std::string> removeArgAndNext = {
33-
"-o", "-supplementary-output-file-map", "-serialize-diagnostics-path",
34-
"-num-threads", "-cas-path"};
35+
"-o",
36+
"-output-filelist",
37+
"-supplementary-output-file-map",
38+
"-index-unit-output-path",
39+
"-index-unit-output-path-filelist",
40+
"-serialize-diagnostics-path",
41+
"-num-threads",
42+
"-cas-path"};
3543

3644
// Don't count the `-frontend` in the first location since only frontend
3745
// invocation can have a cache key.
3846
if (Args.size() > 1 && StringRef(Args.front()) == "-frontend")
3947
Args = Args.drop_front();
4048

41-
bool SkipNext = false;
42-
for (StringRef Arg : Args) {
43-
if (SkipNext) {
44-
SkipNext = false;
45-
continue;
46-
}
49+
for (unsigned I = 0, IE =Args.size(); I < IE; ++I) {
50+
StringRef Arg = Args[I];
4751
if (llvm::is_contained(removeArgAndNext, Arg)) {
48-
SkipNext = true;
52+
++I;
4953
continue;
5054
}
5155
// FIXME: Use a heuristic to remove all the flags that affect output paths.
5256
// Those should not affect compile cache key.
5357
if (Arg.startswith("-emit-")) {
5458
if (Arg.endswith("-path"))
55-
SkipNext = true;
59+
++I;
60+
continue;
61+
}
62+
// Handle -file-list option. Need to drop the option but adds the file
63+
// content instead.
64+
// FIXME: will be nice if the same list of files gets the same key no matter
65+
// going through command-line or filelist.
66+
if (Arg == "-filelist" || Arg == "-primary-filelist") {
67+
auto FileList = llvm::MemoryBuffer::getFile(Args[++I]);
68+
if (!FileList)
69+
return llvm::errorCodeToError(FileList.getError());
70+
CommandLine.append(Arg);
71+
CommandLine.push_back(0);
72+
CommandLine.append((*FileList)->getBuffer());
73+
CommandLine.push_back(0);
5674
continue;
5775
}
5876
CommandLine.append(Arg);

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,11 @@ bool ExplicitModuleInterfaceBuilder::collectDepsForSerialization(
145145
continue;
146146

147147
auto Status = fs.status(DepName);
148-
if (!Status)
148+
if (!Status) {
149+
Instance.getDiags().diagnose(SourceLoc(), diag::cannot_open_file, DepName,
150+
Status.getError().message());
149151
return true;
152+
}
150153

151154
/// Lazily load the dependency buffer if we need it. If we're not
152155
/// dealing with a hash-based dependencies, and if the dependency is
@@ -155,11 +158,14 @@ bool ExplicitModuleInterfaceBuilder::collectDepsForSerialization(
155158
auto getDepBuf = [&]() -> llvm::MemoryBuffer * {
156159
if (DepBuf)
157160
return DepBuf.get();
158-
if (auto Buf = fs.getBufferForFile(DepName, /*FileSize=*/-1,
159-
/*RequiresNullTerminator=*/false)) {
161+
auto Buf = fs.getBufferForFile(DepName, /*FileSize=*/-1,
162+
/*RequiresNullTerminator=*/false);
163+
if (Buf) {
160164
DepBuf = std::move(Buf.get());
161165
return DepBuf.get();
162166
}
167+
Instance.getDiags().diagnose(SourceLoc(), diag::cannot_open_file, DepName,
168+
Buf.getError().message());
163169
return nullptr;
164170
};
165171

@@ -287,11 +293,11 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
287293
SerializationOpts.ABIDescriptorPath = ABIDescriptorPath.str();
288294
SmallVector<FileDependency, 16> Deps;
289295
bool SerializeHashes = FEOpts.SerializeModuleInterfaceDependencyHashes;
290-
if (collectDepsForSerialization(Deps, InterfacePath, SerializeHashes)) {
291-
return std::make_error_code(std::errc::not_supported);
292-
}
293-
if (ShouldSerializeDeps)
296+
if (ShouldSerializeDeps) {
297+
if (collectDepsForSerialization(Deps, InterfacePath, SerializeHashes))
298+
return std::make_error_code(std::errc::not_supported);
294299
SerializationOpts.Dependencies = Deps;
300+
}
295301
SerializationOpts.IsOSSA = SILOpts.EnableOSSAModules;
296302

297303
SILMod->setSerializeSILAction([&]() {

lib/FrontendTool/FrontendTool.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -726,10 +726,12 @@ static bool emitConstValuesForWholeModuleIfNeeded(
726726
return true;
727727
auto ConstValues = gatherConstValuesForModule(Protocols,
728728
Instance.getMainModule());
729-
std::error_code EC;
730-
llvm::raw_fd_ostream OS(ConstValuesFilePath, EC, llvm::sys::fs::OF_None);
731-
writeAsJSONToFile(ConstValues, OS);
732-
return false;
729+
730+
return withOutputPath(Instance.getDiags(), Instance.getOutputBackend(),
731+
ConstValuesFilePath, [&](llvm::raw_ostream &OS) {
732+
writeAsJSONToFile(ConstValues, OS);
733+
return false;
734+
});
733735
}
734736

735737
static void emitConstValuesForAllPrimaryInputsIfNeeded(
@@ -755,9 +757,11 @@ static void emitConstValuesForAllPrimaryInputsIfNeeded(
755757
continue;
756758

757759
auto ConstValues = gatherConstValuesForPrimary(Protocols, SF);
758-
std::error_code EC;
759-
llvm::raw_fd_ostream OS(ConstValuesFilePath, EC, llvm::sys::fs::OF_None);
760-
writeAsJSONToFile(ConstValues, OS);
760+
withOutputPath(Instance.getDiags(), Instance.getOutputBackend(),
761+
ConstValuesFilePath, [&](llvm::raw_ostream &OS) {
762+
writeAsJSONToFile(ConstValues, OS);
763+
return false;
764+
});
761765
}
762766
}
763767

@@ -772,9 +776,12 @@ static bool writeModuleSemanticInfoIfNeeded(CompilerInstance &Instance) {
772776
auto ModuleSemanticPath = frontendOpts.InputsAndOutputs
773777
.getPrimarySpecificPathsForAtMostOnePrimary().SupplementaryOutputs
774778
.ModuleSemanticInfoOutputPath;
775-
llvm::raw_fd_ostream OS(ModuleSemanticPath, EC, llvm::sys::fs::OF_None);
776-
OS << "{}\n";
777-
return false;
779+
780+
return withOutputPath(Instance.getDiags(), Instance.getOutputBackend(),
781+
ModuleSemanticPath, [&](llvm::raw_ostream &OS) {
782+
OS << "{}\n";
783+
return false;
784+
});
778785
}
779786

780787
static bool writeTBDIfNeeded(CompilerInstance &Instance) {
@@ -799,7 +806,8 @@ static bool writeTBDIfNeeded(CompilerInstance &Instance) {
799806

800807
const std::string &TBDPath = Invocation.getTBDPathForWholeModule();
801808

802-
return writeTBD(Instance.getMainModule(), TBDPath, tbdOpts);
809+
return writeTBD(Instance.getMainModule(), TBDPath,
810+
Instance.getOutputBackend(), tbdOpts);
803811
}
804812

805813
static bool performCompileStepsPostSILGen(CompilerInstance &Instance,

lib/FrontendTool/TBD.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "swift/AST/Decl.h"
1616
#include "swift/AST/DiagnosticEngine.h"
1717
#include "swift/AST/DiagnosticsFrontend.h"
18+
#include "swift/AST/FileSystem.h"
1819
#include "swift/AST/FileUnit.h"
1920
#include "swift/AST/Module.h"
2021
#include "swift/AST/TBDGenRequests.h"
@@ -29,6 +30,7 @@
2930
#include "llvm/IR/Mangler.h"
3031
#include "llvm/IR/ValueSymbolTable.h"
3132
#include "llvm/Support/FileSystem.h"
33+
#include "llvm/Support/VirtualOutputBackend.h"
3234
#include <vector>
3335

3436
using namespace swift;
@@ -42,18 +44,13 @@ static std::vector<StringRef> sortSymbols(llvm::StringSet<> &symbols) {
4244
}
4345

4446
bool swift::writeTBD(ModuleDecl *M, StringRef OutputFilename,
47+
llvm::vfs::OutputBackend &Backend,
4548
const TBDGenOptions &Opts) {
46-
std::error_code EC;
47-
llvm::raw_fd_ostream OS(OutputFilename, EC, llvm::sys::fs::OF_None);
48-
if (EC) {
49-
M->getASTContext().Diags.diagnose(SourceLoc(), diag::error_opening_output,
50-
OutputFilename, EC.message());
51-
return true;
52-
}
53-
54-
writeTBDFile(M, OS, Opts);
55-
56-
return false;
49+
return withOutputPath(M->getDiags(), Backend, OutputFilename,
50+
[&](raw_ostream &OS) -> bool {
51+
writeTBDFile(M, OS, Opts);
52+
return false;
53+
});
5754
}
5855

5956
static bool validateSymbols(DiagnosticEngine &diags,

lib/FrontendTool/TBD.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
namespace llvm {
1919
class StringRef;
2020
class Module;
21+
namespace vfs {
22+
class OutputBackend;
23+
}
2124
}
2225
namespace swift {
2326
class ModuleDecl;
@@ -26,7 +29,7 @@ class FrontendOptions;
2629
struct TBDGenOptions;
2730

2831
bool writeTBD(ModuleDecl *M, StringRef OutputFilename,
29-
const TBDGenOptions &Opts);
32+
llvm::vfs::OutputBackend &Backend, const TBDGenOptions &Opts);
3033
bool validateTBD(ModuleDecl *M,
3134
const llvm::Module &IRModule,
3235
const TBDGenOptions &opts,

0 commit comments

Comments
 (0)