Skip to content

Commit 68edb2c

Browse files
[SwiftScan] Add SwiftScan APIs to replay the cache output
Add new C APIs to libSwiftScan for cache querying and cache replays.
1 parent b741b01 commit 68edb2c

File tree

5 files changed

+316
-14
lines changed

5 files changed

+316
-14
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/// SWIFTSCAN_VERSION_MINOR should increase when there are API additions.
2626
/// SWIFTSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
2727
#define SWIFTSCAN_VERSION_MAJOR 0
28-
#define SWIFTSCAN_VERSION_MINOR 5
28+
#define SWIFTSCAN_VERSION_MINOR 6
2929

3030
SWIFTSCAN_BEGIN_DECLS
3131

@@ -437,17 +437,44 @@ typedef struct swiftscan_cas_options_s *swiftscan_cas_options_t;
437437
/// ActionCache.
438438
typedef struct swiftscan_cas_s *swiftscan_cas_t;
439439

440+
/// Opaque type for a cancellation token for async cache operations.
441+
typedef struct swiftscan_cache_cancellation_token_s
442+
*swiftscan_cache_cancellation_token_t;
443+
440444
/// Enum types for output types for cache key computation.
441-
/// TODO: complete the list.
445+
/// List should contain all the output file types, including supplemententary
446+
/// outputs, except diagnostics outputs, which are covered by cached diagnostic
447+
/// entry.
442448
typedef enum {
443449
SWIFTSCAN_OUTPUT_TYPE_OBJECT = 0,
444450
SWIFTSCAN_OUTPUT_TYPE_SWIFTMODULE = 1,
445451
SWIFTSCAN_OUTPUT_TYPE_SWIFTINTERFACE = 2,
446452
SWIFTSCAN_OUTPUT_TYPE_SWIFTPRIVATEINTERFACE = 3,
447453
SWIFTSCAN_OUTPUT_TYPE_CLANG_MODULE = 4,
448-
SWIFTSCAN_OUTPUT_TYPE_CLANG_PCH = 5
454+
SWIFTSCAN_OUTPUT_TYPE_CLANG_PCH = 5,
455+
SWIFTSCAN_OUTPUT_TYPE_CLANG_HEADER = 6,
456+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_SOURCE_INFO = 7,
457+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_MODULE_DOC = 8,
458+
SWIFTSCAN_OUTPUT_TYPE_DEPENDENCIES = 9,
459+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_DEPS = 10,
460+
SWIFTSCAN_OUTPUT_TYPE_MODULE_TRACE = 11,
461+
SWIFTSCAN_OUTPUT_TYPE_TBD = 12,
462+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_MODULE_SUMMARY = 13,
463+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_ABI_DESCRIPTOR = 14,
464+
SWIFTSCAN_OUTPUT_TYPE_CONST_VALUE = 15,
465+
SWIFTSCAN_OUTPUT_TYPE_MODULE_SEMANTIC_INFO = 16,
466+
SWIFTSCAN_OUTPUT_TYPE_YAML_OPT_RECORD = 17,
467+
SWIFTSCAN_OUTPUT_TYPE_BITSTREAM_OPT_RECORD = 18,
468+
SWIFTSCAN_OUTPUT_TYPE_CACHED_DIAGNOSTICS = 19
449469
} swiftscan_output_kind_t;
450470

471+
/// Enum types for cache result lookup or replay.
472+
typedef enum {
473+
SWIFTSCAN_CACHE_RESULT_SUCCESS = 0,
474+
SWIFTSCAN_CACHE_RESULT_NOT_FOUND = 1,
475+
SWIFTSCAN_CACHE_RESULT_ERROR = 2,
476+
} swiftscan_cache_result_t;
477+
451478
/// Create a \c CASOptions for creating CAS inside scanner specified.
452479
SWIFTSCAN_PUBLIC swiftscan_cas_options_t swiftscan_cas_options_create(void);
453480

@@ -497,6 +524,69 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t swiftscan_compute_cache_key(
497524
swiftscan_cas_t cas, int argc, const char **argv, const char *input,
498525
swiftscan_output_kind_t kind, swiftscan_string_ref_t *error);
499526

527+
/// Query the result of the compilation using the output cache key. \c globally
528+
/// suggests if the lookup should check remote cache if such operation exists.
529+
/// If remote cache is checked and result is found, the output is materialized
530+
/// locally so that later replay action should not require remote actions.
531+
/// If the return value is SWIFTSCAN_CACHE_RESULT_ERROR, the error message is
532+
/// returned via \c error parameter and it caller needs to free the message
533+
/// using `swiftscan_string_dispose`.
534+
SWIFTSCAN_PUBLIC swiftscan_cache_result_t
535+
swiftscan_cache_query(swiftscan_cas_t cas, const char *key, bool globally,
536+
swiftscan_string_ref_t *error);
537+
538+
/// Async version of `swiftscan_cache_query` where result is returned via
539+
/// callback. \c ctx is an opaque value that passed to the callback and
540+
/// \c swiftscan_cache_cancellation_token_t will return an token that can be
541+
/// used to cancel the async operation. The token needs to be freed by caller
542+
/// using `swiftscan_cache_cancellation_token_dispose`.
543+
SWIFTSCAN_PUBLIC void swiftscan_cache_query_async(
544+
swiftscan_cas_t cas, const char *key, bool globally, void *ctx,
545+
void (*callback)(void *ctx, swiftscan_cache_result_t,
546+
swiftscan_string_ref_t error),
547+
swiftscan_cache_cancellation_token_t *);
548+
549+
/// Make the cache compilation available globally. \c callback will be called
550+
/// on completion.
551+
/// \c swiftscan_cache_cancellation_token_t will return an token that can be
552+
/// used to cancel the async operation. The token needs to be freed by caller
553+
/// using `swiftscan_cache_cancellation_token_dispose`.
554+
SWIFTSCAN_PUBLIC void swiftscan_cache_make_global_async(
555+
swiftscan_cas_t cas, const char *key, void *ctx,
556+
void (*callback)(void *ctx, swiftscan_string_ref_t error),
557+
swiftscan_cache_cancellation_token_t *);
558+
559+
/// Cancel the async cache action that is associated with token.
560+
SWIFTSCAN_PUBLIC void
561+
swiftscan_cache_action_cancel(swiftscan_cache_cancellation_token_t);
562+
563+
/// Dispose the cancellation token.
564+
SWIFTSCAN_PUBLIC void swiftscan_cache_cancellation_token_dispose(
565+
swiftscan_cache_cancellation_token_t);
566+
567+
/// Replay the cached compilation using command-line.
568+
/// If the return value is SWIFTSCAN_CACHE_RESULT_ERROR, the error message is
569+
/// returned via \c error parameter and it caller needs to free the message
570+
/// using `swiftscan_string_dispose`.
571+
SWIFTSCAN_PUBLIC swiftscan_cache_result_t swiftscan_cache_replay_compilation(
572+
swiftscan_cas_t cas, int argc, const char **argv,
573+
swiftscan_string_ref_t *error);
574+
575+
576+
/// Async replay the cached compilation. Callback function will be provided
577+
/// by the cache replay result, and its stdout, stderr, and any error message.
578+
/// \c ctx is an opaque value that passed to the callback and
579+
/// \c swiftscan_cache_cancellation_token_t will return an token that can be
580+
/// used to cancel the async operation. The token needs to be freed by caller
581+
/// using `swiftscan_cache_cancellation_token_dispose`.
582+
SWIFTSCAN_PUBLIC void swiftscan_cache_replay_compilation_async(
583+
swiftscan_cas_t cas, int argc, const char **argv, void *ctx,
584+
void (*callback)(void *ctx, swiftscan_cache_result_t,
585+
swiftscan_string_ref_t std_out,
586+
swiftscan_string_ref_t std_err,
587+
swiftscan_string_ref_t error),
588+
swiftscan_cache_cancellation_token_t *);
589+
500590
//===----------------------------------------------------------------------===//
501591

502592
SWIFTSCAN_END_DECLS

include/swift/FrontendTool/FrontendTool.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SWIFT_FRONTENDTOOL_H
2020

2121
#include "swift/Basic/LLVM.h"
22+
#include "llvm/Support/raw_ostream.h"
2223

2324
namespace llvm {
2425
class Module;
@@ -76,7 +77,8 @@ StringRef escapeForMake(StringRef raw, llvm::SmallVectorImpl<char> &buffer);
7677
int performFrontend(ArrayRef<const char *> args,
7778
const char *argv0,
7879
void *mainAddr,
79-
FrontendObserver *observer = nullptr);
80+
FrontendObserver *observer = nullptr,
81+
llvm::raw_ostream &OS = llvm::errs());
8082

8183
bool performCompileStepsPostSema(CompilerInstance &Instance, int &ReturnValue,
8284
FrontendObserver *observer);

lib/FrontendTool/FrontendTool.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,9 +2077,9 @@ class PrettyStackTraceFrontend : public llvm::PrettyStackTraceEntry {
20772077
};
20782078
};
20792079

2080-
int swift::performFrontend(ArrayRef<const char *> Args,
2081-
const char *Argv0, void *MainAddr,
2082-
FrontendObserver *observer) {
2080+
int swift::performFrontend(ArrayRef<const char *> Args, const char *Argv0,
2081+
void *MainAddr, FrontendObserver *observer,
2082+
llvm::raw_ostream &OS) {
20832083
INITIALIZE_LLVM();
20842084
llvm::setBugReportMsg(SWIFT_CRASH_BUG_REPORT_MESSAGE "\n");
20852085
llvm::EnablePrettyStackTraceOnSigInfoForThisThread();
@@ -2261,7 +2261,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
22612261
PDC.setSuppressOutput(true);
22622262
}
22632263

2264-
auto emitParseableBeganMessage = [&Invocation, &Args]() {
2264+
auto emitParseableBeganMessage = [&Invocation, &Args, &OS]() {
22652265
const auto &IO = Invocation.getFrontendOptions().InputsAndOutputs;
22662266
const auto OSPid = getpid();
22672267
const auto ProcInfo = sys::TaskProcessInformation(OSPid);
@@ -2276,7 +2276,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
22762276
IO.forEachPrimaryInputWithIndex([&](const InputFile &Input,
22772277
unsigned idx) -> bool {
22782278
ArrayRef<InputFile> Inputs(Input);
2279-
emitBeganMessage(llvm::errs(),
2279+
emitBeganMessage(OS,
22802280
mapFrontendInvocationToAction(Invocation),
22812281
constructDetailedTaskDescription(Invocation,
22822282
Inputs,
@@ -2286,15 +2286,15 @@ int swift::performFrontend(ArrayRef<const char *> Args,
22862286
});
22872287
} else {
22882288
// If no primary inputs are present, we are in WMO.
2289-
emitBeganMessage(llvm::errs(),
2289+
emitBeganMessage(OS,
22902290
mapFrontendInvocationToAction(Invocation),
22912291
constructDetailedTaskDescription(Invocation, IO.getAllInputs(), Args),
22922292
OSPid, ProcInfo);
22932293
}
22942294
};
22952295

2296-
auto emitParseableFinishedMessage = [&Invocation, &FileSpecificDiagnostics](
2297-
int ExitStatus) {
2296+
auto emitParseableFinishedMessage = [&Invocation, &FileSpecificDiagnostics,
2297+
&OS](int ExitStatus) {
22982298
const auto &IO = Invocation.getFrontendOptions().InputsAndOutputs;
22992299
const auto OSPid = getpid();
23002300
const auto ProcInfo = sys::TaskProcessInformation(OSPid);
@@ -2318,7 +2318,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
23182318
std::copy(PrimaryDiags.begin(), PrimaryDiags.end(),
23192319
std::ostream_iterator<std::string>(JoinedDiags, Delim));
23202320

2321-
emitFinishedMessage(llvm::errs(),
2321+
emitFinishedMessage(OS,
23222322
mapFrontendInvocationToAction(Invocation),
23232323
JoinedDiags.str(), ExitStatus, Pid - idx, ProcInfo);
23242324
return false;
@@ -2335,7 +2335,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
23352335
std::ostringstream JoinedDiags;
23362336
std::copy(AllDiagnostics.begin(), AllDiagnostics.end(),
23372337
std::ostream_iterator<std::string>(JoinedDiags, Delim));
2338-
emitFinishedMessage(llvm::errs(),
2338+
emitFinishedMessage(OS,
23392339
mapFrontendInvocationToAction(Invocation),
23402340
JoinedDiags.str(), ExitStatus, OSPid, ProcInfo);
23412341
}

0 commit comments

Comments
 (0)