Skip to content

Commit 30cfa3d

Browse files
[Caching] Re-associate diagnostics cache key with InputFile
Change how cached diagnostics are stored inside the CAS. It used to be stored as a standalone entry for a frontend invocation in the cache and now it is switched to be associated with input files, stored together with other outputs like object files, etc. This enables cleaner Cache Replay APIs and future cached diagnostics that can be splitted up by file contribution.
1 parent 22592d2 commit 30cfa3d

8 files changed

+83
-61
lines changed

Diff for: include/swift/Frontend/FrontendInputsAndOutputs.h

+2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ class FrontendInputsAndOutputs {
157157
/// instead of just answering "batch" if there is more than one primary.
158158
std::string getStatsFileMangledInputName() const;
159159

160+
const InputFile &getFirstOutputProducingInput() const;
161+
160162
bool isInputPrimary(StringRef file) const;
161163

162164
unsigned numberOfPrimaryInputsEndingWith(StringRef extension) const;

Diff for: lib/DriverTool/swift_cache_tool_main.cpp

+23-21
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ enum class SwiftCacheToolAction {
5050

5151
struct OutputEntry {
5252
std::string InputPath;
53-
std::string OutputPath;
54-
std::string OutputKind;
5553
std::string CacheKey;
54+
std::vector<std::pair<std::string, std::string>> Outputs;
5655
};
5756

5857
enum ID {
@@ -285,44 +284,41 @@ int SwiftCacheToolInvocation::printOutputKeys() {
285284

286285
std::vector<OutputEntry> OutputKeys;
287286
bool hasError = false;
288-
auto addOutputKey = [&](StringRef InputPath, file_types::ID OutputKind,
289-
StringRef OutputPath) {
287+
auto addFromInputFile = [&](const InputFile &Input) {
288+
auto InputPath = Input.getFileName();
290289
auto OutputKey =
291290
createCompileJobCacheKeyForOutput(CAS, *BaseKey, InputPath);
292291
if (!OutputKey) {
293-
llvm::errs() << "cannot create cache key for " << OutputPath << ": "
292+
llvm::errs() << "cannot create cache key for " << InputPath << ": "
294293
<< toString(OutputKey.takeError()) << "\n";
295294
hasError = true;
296295
}
297296
OutputKeys.emplace_back(
298-
OutputEntry{InputPath.str(), OutputPath.str(),
299-
file_types::getTypeName(OutputKind).str(),
300-
CAS.getID(*OutputKey).toString()});
301-
};
302-
auto addFromInputFile = [&](const InputFile &Input) {
303-
auto InputPath = Input.getFileName();
297+
OutputEntry{InputPath, CAS.getID(*OutputKey).toString(), {}});
298+
auto &Outputs = OutputKeys.back().Outputs;
304299
if (!Input.outputFilename().empty())
305-
addOutputKey(InputPath,
306-
Invocation.getFrontendOptions()
307-
.InputsAndOutputs.getPrincipalOutputType(),
308-
Input.outputFilename());
300+
Outputs.emplace_back(file_types::getTypeName(
301+
Invocation.getFrontendOptions()
302+
.InputsAndOutputs.getPrincipalOutputType()),
303+
Input.outputFilename());
309304
Input.getPrimarySpecificPaths()
310305
.SupplementaryOutputs.forEachSetOutputAndType(
311306
[&](const std::string &File, file_types::ID ID) {
312307
// Dont print serialized diagnostics.
313308
if (file_types::isProducedFromDiagnostics(ID))
314309
return;
315-
316-
addOutputKey(InputPath, ID, File);
310+
Outputs.emplace_back(file_types::getTypeName(ID), File);
317311
});
318312
};
319313
llvm::for_each(
320314
Invocation.getFrontendOptions().InputsAndOutputs.getAllInputs(),
321315
addFromInputFile);
322316

323317
// Add diagnostics file.
324-
addOutputKey("<cached-diagnostics>", file_types::ID::TY_CachedDiagnostics,
325-
"<cached-diagnostics>");
318+
if (!OutputKeys.empty())
319+
OutputKeys.front().Outputs.emplace_back(
320+
file_types::getTypeName(file_types::ID::TY_CachedDiagnostics),
321+
"<cached-diagnostics>");
326322

327323
if (hasError)
328324
return 1;
@@ -331,10 +327,16 @@ int SwiftCacheToolInvocation::printOutputKeys() {
331327
Out.array([&] {
332328
for (const auto &E : OutputKeys) {
333329
Out.object([&] {
334-
Out.attribute("OutputPath", E.OutputPath);
335-
Out.attribute("OutputKind", E.OutputKind);
336330
Out.attribute("Input", E.InputPath);
337331
Out.attribute("CacheKey", E.CacheKey);
332+
Out.attributeArray("Outputs", [&] {
333+
for (const auto &OutEntry : E.Outputs) {
334+
Out.object([&] {
335+
Out.attribute("Kind", OutEntry.first);
336+
Out.attribute("Path", OutEntry.second);
337+
});
338+
}
339+
});
338340
});
339341
}
340342
});

Diff for: lib/Frontend/CASOutputBackends.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ void SwiftCASOutputBackend::Implementation::initBackend(
157157
});
158158
};
159159
llvm::for_each(InputsAndOutputs.getAllInputs(), addInput);
160+
161+
// FIXME: Cached diagnostics is associated with the first output producing
162+
// input file.
163+
OutputToInputMap.insert({"<cached-diagnostics>",
164+
{InputsAndOutputs.getFirstOutputProducingInput(),
165+
file_types::TY_CachedDiagnostics}});
160166
}
161167

162168
Error SwiftCASOutputBackend::Implementation::storeImpl(

Diff for: lib/Frontend/CachedDiagnostics.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -772,10 +772,14 @@ CachingDiagnosticsProcessor::CachingDiagnosticsProcessor(
772772
}
773773

774774
StringRef Content = Compression.empty() ? Output : toStringRef(Compression);
775-
// Store CachedDiagnostics in the CAS/Cache. There is no real associated
776-
// inputs.
775+
// Store CachedDiagnostics in the CAS/Cache.
776+
// FIXME: Currently associated with first output producing input file.
777777
auto Err = Instance.getCASOutputBackend().storeCachedDiagnostics(
778-
"<cached-diagnostics>", Content);
778+
Instance.getInvocation()
779+
.getFrontendOptions()
780+
.InputsAndOutputs.getFirstOutputProducingInput()
781+
.getFileName(),
782+
Content);
779783

780784
if (Err) {
781785
Instance.getDiags().diagnose(SourceLoc(), diag::error_cas,

Diff for: lib/Frontend/CachingUtils.cpp

+3-7
Original file line numberDiff line numberDiff line change
@@ -209,19 +209,15 @@ bool replayCachedCompilerOutputs(
209209
Outputs.try_emplace(ID, File);
210210
});
211211

212-
// Nothing to replay.
213-
if (Outputs.empty())
214-
return;
212+
// Add cached diagnostic entry for lookup. Output path doesn't matter here.
213+
Outputs.try_emplace(file_types::ID::TY_CachedDiagnostics,
214+
"<cached-diagnostics>");
215215

216216
return replayOutputsForInputFile(InputPath, Outputs);
217217
};
218218

219219
llvm::for_each(InputsAndOutputs.getAllInputs(), replayOutputFromInput);
220220

221-
replayOutputsForInputFile(
222-
"<cached-diagnostics>",
223-
{{file_types::ID::TY_CachedDiagnostics, "<cached-diagnostics>"}});
224-
225221
if (!CanReplayAllOutput)
226222
return false;
227223

Diff for: lib/Frontend/FrontendInputsAndOutputs.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,15 @@ std::string FrontendInputsAndOutputs::getStatsFileMangledInputName() const {
150150
return isWholeModule() ? "all" : firstPrimaryInput().getFileName();
151151
}
152152

153+
const InputFile &
154+
FrontendInputsAndOutputs::getFirstOutputProducingInput() const {
155+
// Get the first input file that produces the output file. That is currently
156+
// used to compute with input should the cached diagnostics be associated
157+
// with. The first output producing input file is the first input if using
158+
// whole module, or first primary input if not using whole module.
159+
return isWholeModule() ? firstInput() : firstPrimaryInput();
160+
}
161+
153162
bool FrontendInputsAndOutputs::isInputPrimary(StringRef file) const {
154163
return primaryInputNamed(file) != nullptr;
155164
}

Diff for: test/CAS/Inputs/ExtractOutputKey.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010

1111

1212
with open(input_json, 'r') as file:
13-
outputs = json.load(file)
14-
for output in outputs:
15-
if output['OutputPath'] != output_path:
16-
continue
17-
print(output['CacheKey'])
13+
entries = json.load(file)
14+
for entry in entries:
15+
for output in entry["Outputs"]:
16+
if output['Path'] != output_path:
17+
continue
18+
print(entry['CacheKey'])

Diff for: test/CAS/cache_key_compute.swift

+27-25
Original file line numberDiff line numberDiff line change
@@ -50,32 +50,34 @@
5050
// RUN: %target-swift-frontend -cache-compile-job %s -emit-module -c -emit-dependencies \
5151
// RUN: -emit-tbd -emit-tbd-path %t/test.tbd -o %t/test.o -allow-unstable-cache-key-for-testing | %FileCheck %s --check-prefix=CHECK --check-prefix=PLUGIN
5252

53-
// CHECK: test.o
54-
// CHECK-NEXT: "OutputKind": "object"
55-
// CHECK-NEXT: "Input"
53+
// CHECK: "Input": "{{.*}}{{/|\\}}cache_key_compute.swift"
5654
// CHECK-NEXT: "CacheKey"
5755
// PLUGIN-SAME: myfirst-llvmcas://
5856

59-
// CHECK: test.swiftmodule
60-
// CHECK-NEXT: "OutputKind": "swiftmodule"
61-
// CHECK-NEXT: "Input"
62-
// CHECK-NEXT: "CacheKey"
63-
// PLUGIN-SAME: myfirst-llvmcas://
64-
65-
// CHECK: test.d
66-
// CHECK-NEXT: "OutputKind": "dependencies"
67-
// CHECK-NEXT: "Input"
68-
// CHECK-NEXT: "CacheKey"
69-
// PLUGIN-SAME: myfirst-llvmcas://
57+
// CHECK-NEXT: "Outputs": [
58+
// CHECK-NEXT: {
59+
// CHECK-NEXT: "Kind": "object",
60+
// CHECK-NEXT: "Path":
61+
// CHECK-SAME: test.o
62+
// CHECK-NEXT: },
63+
// CHECK-NEXT: {
64+
// CHECK-NEXT: "Kind": "swiftmodule",
65+
// CHECK-NEXT: "Path":
66+
// CHECK-SAME: test.swiftmodule
67+
// CHECK-NEXT: },
68+
// CHECK-NEXT: {
69+
// CHECK-NEXT: "Kind": "dependencies",
70+
// CHECK-NEXT: "Path":
71+
// CHECK-SAME: test.d
72+
// CHECK-NEXT: },
73+
// CHECK-NEXT: {
74+
// CHECK-NEXT: "Kind": "tbd",
75+
// CHECK-NEXT: "Path":
76+
// CHECK-SAME: test.tbd
77+
// CHECK-NEXT: },
78+
// CHECK-NEXT: {
79+
// CHECK-NEXT: "Kind": "cached-diagnostics",
80+
// CHECK-NEXT: "Path": "<cached-diagnostics>"
81+
// CHECK-NEXT: }
82+
// CHECK-NEXT: ]
7083

71-
// CHECK: test.tbd
72-
// CHECK-NEXT: "OutputKind": "tbd"
73-
// CHECK-NEXT: "Input"
74-
// CHECK-NEXT: "CacheKey"
75-
// PLUGIN-SAME: myfirst-llvmcas://
76-
77-
// CHECK: <cached-diagnostics>
78-
// CHECK-NEXT: "OutputKind": "cached-diagnostics"
79-
// CHECK-NEXT: "Input": "<cached-diagnostics>"
80-
// CHECK-NEXT: "CacheKey"
81-
// PLUGIN-SAME: myfirst-llvmcas://

0 commit comments

Comments
 (0)