Skip to content

Commit 0d56a00

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 a69bcf8 commit 0d56a00

File tree

5 files changed

+437
-28
lines changed

5 files changed

+437
-28
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 118 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,47 @@ typedef struct swiftscan_cas_options_s *swiftscan_cas_options_t;
437437
/// ActionCache.
438438
typedef struct swiftscan_cas_s *swiftscan_cas_t;
439439

440+
/// Opaque container for a CASID.
441+
typedef struct swiftscan_cas_id_s *swiftscan_cas_id_t;
442+
443+
/// Opaque type for a cancellation token for async cache operations.
444+
typedef struct swiftscan_cache_cancellation_token_s
445+
*swiftscan_cache_cancellation_token_t;
446+
440447
/// Enum types for output types for cache key computation.
441-
/// TODO: complete the list.
448+
/// List should contain all the output file types, including supplemententary
449+
/// outputs, except diagnostics outputs, which are covered by cached diagnostic
450+
/// entry.
442451
typedef enum {
443452
SWIFTSCAN_OUTPUT_TYPE_OBJECT = 0,
444453
SWIFTSCAN_OUTPUT_TYPE_SWIFTMODULE = 1,
445454
SWIFTSCAN_OUTPUT_TYPE_SWIFTINTERFACE = 2,
446455
SWIFTSCAN_OUTPUT_TYPE_SWIFTPRIVATEINTERFACE = 3,
447456
SWIFTSCAN_OUTPUT_TYPE_CLANG_MODULE = 4,
448-
SWIFTSCAN_OUTPUT_TYPE_CLANG_PCH = 5
457+
SWIFTSCAN_OUTPUT_TYPE_CLANG_PCH = 5,
458+
SWIFTSCAN_OUTPUT_TYPE_CLANG_HEADER = 6,
459+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_SOURCE_INFO = 7,
460+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_MODULE_DOC = 8,
461+
SWIFTSCAN_OUTPUT_TYPE_DEPENDENCIES = 9,
462+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_DEPS = 10,
463+
SWIFTSCAN_OUTPUT_TYPE_MODULE_TRACE = 11,
464+
SWIFTSCAN_OUTPUT_TYPE_TBD = 12,
465+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_MODULE_SUMMARY = 13,
466+
SWIFTSCAN_OUTPUT_TYPE_SWIFT_ABI_DESCRIPTOR = 14,
467+
SWIFTSCAN_OUTPUT_TYPE_CONST_VALUE = 15,
468+
SWIFTSCAN_OUTPUT_TYPE_MODULE_SEMANTIC_INFO = 16,
469+
SWIFTSCAN_OUTPUT_TYPE_YAML_OPT_RECORD = 17,
470+
SWIFTSCAN_OUTPUT_TYPE_BITSTREAM_OPT_RECORD = 18,
471+
SWIFTSCAN_OUTPUT_TYPE_CACHED_DIAGNOSTICS = 19
449472
} swiftscan_output_kind_t;
450473

474+
/// Enum types for cache result lookup or replay.
475+
typedef enum {
476+
SWIFTSCAN_CACHE_RESULT_SUCCESS = 0,
477+
SWIFTSCAN_CACHE_RESULT_NOT_FOUND = 1,
478+
SWIFTSCAN_CACHE_RESULT_ERROR = 2,
479+
} swiftscan_cache_result_t;
480+
451481
/// Create a \c CASOptions for creating CAS inside scanner specified.
452482
SWIFTSCAN_PUBLIC swiftscan_cas_options_t swiftscan_cas_options_create(void);
453483

@@ -497,6 +527,91 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t swiftscan_compute_cache_key(
497527
swiftscan_cas_t cas, int argc, const char **argv, const char *input,
498528
swiftscan_output_kind_t kind, swiftscan_string_ref_t *error);
499529

530+
/// Query the result of the compilation using the output cache key. \c globally
531+
/// suggests if the lookup should check remote cache if such operation exists.
532+
/// Returns the CASID of the result if found, or nullptr if output is not found
533+
/// or an error occurs. When an error occurs, the error message is returned via
534+
/// \c error parameter and it caller needs to free the message using
535+
/// `swiftscan_string_dispose`. The returned CASID needs to be freed via
536+
/// `swiftscan_cas_id_dispose`.
537+
SWIFTSCAN_PUBLIC swiftscan_cas_id_t
538+
swiftscan_cache_query(swiftscan_cas_t cas, const char *key, bool globally,
539+
swiftscan_string_ref_t *error);
540+
541+
/// Async version of `swiftscan_cache_query` where result is returned via
542+
/// callback. Both cache_result enum and CASID will be provided to callback.
543+
/// \c ctx is an opaque value that passed to the callback and
544+
/// \c swiftscan_cache_cancellation_token_t will return an token that can be
545+
/// used to cancel the async operation. The token needs to be freed by caller
546+
/// using `swiftscan_cache_cancellation_token_dispose`.
547+
SWIFTSCAN_PUBLIC void swiftscan_cache_query_async(
548+
swiftscan_cas_t cas, const char *key, bool globally, void *ctx,
549+
void (*callback)(void *ctx, swiftscan_cache_result_t, swiftscan_cas_id_t,
550+
swiftscan_string_ref_t error),
551+
swiftscan_cache_cancellation_token_t *);
552+
553+
/// Dispose a CASID.
554+
SWIFTSCAN_PUBLIC void swiftscan_cas_id_dispose(swiftscan_cas_id_t);
555+
556+
/// Download and materialized the CASObject referenced by the CASID in the local
557+
/// CAS if needed from a remote CAS.
558+
/// If the return value is SWIFTSCAN_CACHE_RESULT_ERROR, the error message is
559+
/// returned via \c error parameter and it caller needs to free the message
560+
/// using `swiftscan_string_dispose`.
561+
SWIFTSCAN_PUBLIC swiftscan_cache_result_t swiftscan_cache_load_object(
562+
swiftscan_cas_t cas, swiftscan_cas_id_t, swiftscan_string_ref_t *error);
563+
564+
/// Async version of `swiftscan_cache_load_object` where result is returned via
565+
/// callback. \c ctx is an opaque value that passed to the callback and
566+
/// \c swiftscan_cache_cancellation_token_t will return an token that can be
567+
/// used to cancel the async operation. The token needs to be freed by caller
568+
/// using `swiftscan_cache_cancellation_token_dispose`.
569+
SWIFTSCAN_PUBLIC void swiftscan_cache_load_object_async(
570+
swiftscan_cas_t cas, swiftscan_cas_id_t, void *ctx,
571+
void (*callback)(void *ctx, swiftscan_cache_result_t,
572+
swiftscan_string_ref_t error),
573+
swiftscan_cache_cancellation_token_t *);
574+
575+
/// Make the cache compilation available globally. \c callback will be called
576+
/// on completion.
577+
/// \c swiftscan_cache_cancellation_token_t will return an token that can be
578+
/// used to cancel the async operation. The token needs to be freed by caller
579+
/// using `swiftscan_cache_cancellation_token_dispose`.
580+
SWIFTSCAN_PUBLIC void swiftscan_cache_make_global_async(
581+
swiftscan_cas_t cas, const char *key, void *ctx,
582+
void (*callback)(void *ctx, swiftscan_string_ref_t error),
583+
swiftscan_cache_cancellation_token_t *);
584+
585+
/// Cancel the async cache action that is associated with token.
586+
SWIFTSCAN_PUBLIC void
587+
swiftscan_cache_action_cancel(swiftscan_cache_cancellation_token_t);
588+
589+
/// Dispose the cancellation token.
590+
SWIFTSCAN_PUBLIC void swiftscan_cache_cancellation_token_dispose(
591+
swiftscan_cache_cancellation_token_t);
592+
593+
/// Replay the cached compilation using command-line.
594+
/// If the return value is SWIFTSCAN_CACHE_RESULT_ERROR, the error message is
595+
/// returned via \c error parameter and it caller needs to free the message
596+
/// using `swiftscan_string_dispose`.
597+
SWIFTSCAN_PUBLIC swiftscan_cache_result_t swiftscan_cache_replay_compilation(
598+
swiftscan_cas_t cas, int argc, const char **argv, void *reserved,
599+
swiftscan_string_ref_t *error);
600+
601+
/// Async replay the cached compilation. Callback function will be provided
602+
/// by the cache replay result, and its stdout, stderr, and any error message.
603+
/// \c ctx is an opaque value that passed to the callback and
604+
/// \c swiftscan_cache_cancellation_token_t will return an token that can be
605+
/// used to cancel the async operation. The token needs to be freed by caller
606+
/// using `swiftscan_cache_cancellation_token_dispose`.
607+
SWIFTSCAN_PUBLIC void swiftscan_cache_replay_compilation_async(
608+
swiftscan_cas_t cas, int argc, const char **argv, void *reserved, void *ctx,
609+
void (*callback)(void *ctx, swiftscan_cache_result_t,
610+
swiftscan_string_ref_t std_out,
611+
swiftscan_string_ref_t std_err,
612+
swiftscan_string_ref_t error),
613+
swiftscan_cache_cancellation_token_t *);
614+
500615
//===----------------------------------------------------------------------===//
501616

502617
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)