Skip to content

Commit 9291c25

Browse files
Merge pull request #68660 from cachemeifyoucan/eng/PR-cache-replay-api
[SwiftScan] Add SwiftScan APIs to replay the cache output rdar://117947645
2 parents 67c67a0 + 034c15c commit 9291c25

19 files changed

+1518
-304
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 162 additions & 7 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

@@ -441,6 +441,23 @@ typedef struct swiftscan_cas_options_s *swiftscan_cas_options_t;
441441
/// ActionCache.
442442
typedef struct swiftscan_cas_s *swiftscan_cas_t;
443443

444+
/// Opaque container for a cached compilation.
445+
typedef struct swiftscan_cached_compilation_s *swiftscan_cached_compilation_t;
446+
447+
/// Opaque container for a cached compilation output.
448+
typedef struct swiftscan_cached_output_s *swiftscan_cached_output_t;
449+
450+
/// Opaque type for a cache replay instance.
451+
typedef struct swiftscan_cache_replay_instance_s
452+
*swiftscan_cache_replay_instance_t;
453+
454+
/// Opaque container for a cached compilation replay result.
455+
typedef struct swiftscan_cache_replay_result_s *swiftscan_cache_replay_result_t;
456+
457+
/// Opaque type for a cancellation token for async cache operations.
458+
typedef struct swiftscan_cache_cancellation_token_s
459+
*swiftscan_cache_cancellation_token_t;
460+
444461
/// Create a \c CASOptions for creating CAS inside scanner specified.
445462
SWIFTSCAN_PUBLIC swiftscan_cas_options_t swiftscan_cas_options_create(void);
446463

@@ -462,26 +479,26 @@ swiftscan_cas_options_set_plugin_path(swiftscan_cas_options_t options,
462479
/// If error happens, the error message is returned via `error` parameter, and
463480
/// caller needs to free the error message via `swiftscan_string_dispose`.
464481
SWIFTSCAN_PUBLIC bool
465-
swiftscan_cas_options_set_option(swiftscan_cas_options_t options,
466-
const char *name, const char *value,
467-
swiftscan_string_ref_t *error);
482+
swiftscan_cas_options_set_plugin_option(swiftscan_cas_options_t options,
483+
const char *name, const char *value,
484+
swiftscan_string_ref_t *error);
468485

469486
/// Create a \c cas instance from plugin. Return NULL if error.
470487
/// If error happens, the error message is returned via `error` parameter, and
471488
/// caller needs to free the error message via `swiftscan_string_dispose`.
472489
SWIFTSCAN_PUBLIC swiftscan_cas_t swiftscan_cas_create_from_options(
473490
swiftscan_cas_options_t options, swiftscan_string_ref_t *error);
474491

475-
/// Dispose the \c cas instance.
476-
SWIFTSCAN_PUBLIC void swiftscan_cas_dispose(swiftscan_cas_t cas);
477-
478492
/// Store content into CAS. Return \c CASID as string. Return NULL on error.
479493
/// If error happens, the error message is returned via `error` parameter, and
480494
/// caller needs to free the error message via `swiftscan_string_dispose`.
481495
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
482496
swiftscan_cas_store(swiftscan_cas_t cas, uint8_t *data, unsigned size,
483497
swiftscan_string_ref_t *error);
484498

499+
/// Dispose the \c cas instance.
500+
SWIFTSCAN_PUBLIC void swiftscan_cas_dispose(swiftscan_cas_t cas);
501+
485502
/// Compute \c CacheKey for the outputs of a primary input file from a compiler
486503
/// invocation with command-line \c argc and \c argv. When primary input file
487504
/// is not available for compilation, e.g., using WMO, primary file is the first
@@ -492,6 +509,144 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t
492509
swiftscan_cache_compute_key(swiftscan_cas_t cas, int argc, const char **argv,
493510
const char *input, swiftscan_string_ref_t *error);
494511

512+
/// Query the result of the compilation using the output cache key. \c globally
513+
/// suggests if the lookup should check remote cache if such operation exists.
514+
/// Returns the cached compilation of the result if found, or nullptr if output
515+
/// is not found or an error occurs. When an error occurs, the error message is
516+
/// returned via \c error parameter and its caller needs to free the message
517+
/// using `swiftscan_string_dispose`. The returned cached compilation needs to
518+
/// be freed via `swiftscan_cached_compilation_dispose`.
519+
SWIFTSCAN_PUBLIC swiftscan_cached_compilation_t
520+
swiftscan_cache_query(swiftscan_cas_t cas, const char *key, bool globally,
521+
swiftscan_string_ref_t *error);
522+
523+
/// Async version of `swiftscan_cache_query` where result is returned via
524+
/// callback. Both cache_result enum and cached compilation will be provided to
525+
/// callback. \c ctx is an opaque value that passed to the callback and \c
526+
/// swiftscan_cache_cancellation_token_t will return an token that can be used
527+
/// to cancel the async operation. The token needs to be freed by caller using
528+
/// `swiftscan_cache_cancellation_token_dispose`. If no token is needed, nullptr
529+
/// can be passed and no token will be returned.
530+
SWIFTSCAN_PUBLIC void swiftscan_cache_query_async(
531+
swiftscan_cas_t cas, const char *key, bool globally, void *ctx,
532+
void (*callback)(void *ctx, swiftscan_cached_compilation_t,
533+
swiftscan_string_ref_t error),
534+
swiftscan_cache_cancellation_token_t *);
535+
536+
/// Query the number of outputs from a cached compilation.
537+
SWIFTSCAN_PUBLIC unsigned swiftscan_cached_compilation_get_num_outputs(
538+
swiftscan_cached_compilation_t);
539+
540+
/// Get the cached output for the given index in the cached compilation.
541+
SWIFTSCAN_PUBLIC swiftscan_cached_output_t
542+
swiftscan_cached_compilation_get_output(swiftscan_cached_compilation_t,
543+
unsigned idx);
544+
545+
/// Check if the requested cached compilation is uncacheable. That means the
546+
/// compiler decides to skip caching its output even the compilation is
547+
/// successful.
548+
SWIFTSCAN_PUBLIC bool
549+
swiftscan_cached_compilation_is_uncacheable(swiftscan_cached_compilation_t);
550+
551+
/// Make the cache compilation available globally. \c callback will be called
552+
/// on completion.
553+
/// \c swiftscan_cache_cancellation_token_t will return an token that can be
554+
/// used to cancel the async operation. The token needs to be freed by caller
555+
/// using `swiftscan_cache_cancellation_token_dispose`. If no token is needed,
556+
/// nullptr can be passed and no token will be returned.
557+
SWIFTSCAN_PUBLIC void swiftscan_cached_compilation_make_global_async(
558+
swiftscan_cached_compilation_t, void *ctx,
559+
void (*callback)(void *ctx, swiftscan_string_ref_t error),
560+
swiftscan_cache_cancellation_token_t *);
561+
562+
/// Dispose a cached compilation.
563+
SWIFTSCAN_PUBLIC
564+
void swiftscan_cached_compilation_dispose(swiftscan_cached_compilation_t);
565+
566+
/// Download and materialize the cached output if needed from a remote CAS.
567+
/// Return true if load is successful, else false if not found or error. If
568+
/// error, the error message is returned via \c error parameter and its caller
569+
/// needs to free the message using `swiftscan_string_dispose`.
570+
SWIFTSCAN_PUBLIC bool
571+
swiftscan_cached_output_load(swiftscan_cached_output_t,
572+
swiftscan_string_ref_t *error);
573+
574+
/// Async version of `swiftscan_cached_output_load` where result is
575+
/// returned via callback. \c ctx is an opaque value that passed to the callback
576+
/// and \c swiftscan_cache_cancellation_token_t will return an token that can be
577+
/// used to cancel the async operation. The token needs to be freed by caller
578+
/// using `swiftscan_cache_cancellation_token_dispose`. If no token is needed,
579+
/// nullptr can be passed and no token will be returned.
580+
SWIFTSCAN_PUBLIC void swiftscan_cached_output_load_async(
581+
swiftscan_cached_output_t, void *ctx,
582+
void (*callback)(void *ctx, bool success, swiftscan_string_ref_t error),
583+
swiftscan_cache_cancellation_token_t *);
584+
585+
/// Check if cached output is materialized locally and can be accessed
586+
/// without downloading.
587+
SWIFTSCAN_PUBLIC bool
588+
swiftscan_cached_output_is_materialized(swiftscan_cached_output_t);
589+
590+
/// Return the casid for the cached output as \c swiftscan_string_ref_t and the
591+
/// returned string needs to be freed using `swiftscan_string_dispose`. CASID
592+
/// can be requested before loading/materializing.
593+
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
594+
swiftscan_cached_output_get_casid(swiftscan_cached_output_t);
595+
596+
/// Get the output name for cached compilation. The
597+
/// returned name needs to be freed by `swiftscan_string_dispose`.
598+
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
599+
swiftscan_cached_output_get_name(swiftscan_cached_output_t);
600+
601+
/// Dispose a cached output.
602+
SWIFTSCAN_PUBLIC
603+
void swiftscan_cached_output_dispose(swiftscan_cached_output_t);
604+
605+
/// Cancel the async cache action that is associated with token.
606+
SWIFTSCAN_PUBLIC void
607+
swiftscan_cache_action_cancel(swiftscan_cache_cancellation_token_t);
608+
609+
/// Dispose the cancellation token.
610+
SWIFTSCAN_PUBLIC void swiftscan_cache_cancellation_token_dispose(
611+
swiftscan_cache_cancellation_token_t);
612+
613+
/// Create a swift cached compilation replay instance with its command-line
614+
/// invocation. Return nullptr when errors occurs and the error message is
615+
/// returned via \c error parameter and its caller needs to free the message
616+
/// using `swiftscan_string_dispose`.
617+
SWIFTSCAN_PUBLIC swiftscan_cache_replay_instance_t
618+
swiftscan_cache_replay_instance_create(int argc, const char **argv,
619+
swiftscan_string_ref_t *error);
620+
621+
/// Dispose swift cached compilation replay instance.
622+
SWIFTSCAN_PUBLIC void
623+
swiftscan_cache_replay_instance_dispose(swiftscan_cache_replay_instance_t);
624+
625+
/// Replay the cached compilation using cached compliation replay instance.
626+
/// Returns replay result or nullptr if output not found or error occurs. If
627+
/// error, the error message is returned via \c error parameter and its caller
628+
/// needs to free the message using `swiftscan_string_dispose`.
629+
SWIFTSCAN_PUBLIC swiftscan_cache_replay_result_t
630+
swiftscan_cache_replay_compilation(swiftscan_cache_replay_instance_t,
631+
swiftscan_cached_compilation_t,
632+
swiftscan_string_ref_t *error);
633+
634+
/// Get stdout from cached replay result. The returning swiftscan_string_ref_t
635+
/// is owned by replay result and should not be disposed.
636+
SWIFTSCAN_PUBLIC
637+
swiftscan_string_ref_t
638+
swiftscan_cache_replay_result_get_stdout(swiftscan_cache_replay_result_t);
639+
640+
/// Get stderr from cached replay result. The returning swiftscan_string_ref_t
641+
/// is owned by replay result and should not be disposed.
642+
SWIFTSCAN_PUBLIC
643+
swiftscan_string_ref_t
644+
swiftscan_cache_replay_result_get_stderr(swiftscan_cache_replay_result_t);
645+
646+
/// Dispose a cached replay result.
647+
SWIFTSCAN_PUBLIC
648+
void swiftscan_cache_replay_result_dispose(swiftscan_cache_replay_result_t);
649+
495650
//===----------------------------------------------------------------------===//
496651

497652
SWIFTSCAN_END_DECLS

include/swift/Frontend/CachingUtils.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,19 @@ std::vector<std::string> remapPathsFromCommandLine(
6363
namespace cas {
6464
class CachedResultLoader {
6565
public:
66-
CachedResultLoader(llvm::cas::ObjectStore &CAS, llvm::cas::ActionCache &Cache,
67-
llvm::cas::ObjectRef CacheKey)
68-
: CAS(CAS), Cache(Cache), CacheKey(CacheKey) {}
66+
CachedResultLoader(llvm::cas::ObjectStore &CAS,
67+
llvm::cas::ObjectRef OutputRef)
68+
: CAS(CAS), OutputRef(OutputRef) {}
6969

7070
using CallbackTy =
7171
llvm::function_ref<llvm::Error(file_types::ID, llvm::cas::ObjectRef)>;
72-
// Replay the cached result, return false if a cache miss happened.
73-
llvm::Expected<bool> replay(CallbackTy Callback);
72+
73+
/// Replay the cached result.
74+
llvm::Error replay(CallbackTy Callback);
7475

7576
private:
7677
llvm::cas::ObjectStore &CAS;
77-
llvm::cas::ActionCache &Cache;
78-
llvm::cas::ObjectRef CacheKey;
78+
llvm::cas::ObjectRef OutputRef;
7979
};
8080
} // end namespace cas
8181
} // end namespace swift

include/swift/Frontend/FrontendInputsAndOutputs.h

Lines changed: 2 additions & 0 deletions
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;

0 commit comments

Comments
 (0)