@@ -386,48 +386,42 @@ std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
386
386
std::move (OutputBuffer), /* RequiresNullTerminator=*/ false );
387
387
}
388
388
389
+ struct NullModuleCacheEntry : ModuleCacheEntry {
390
+ std::string getEntryPath () override { return " <null>" ; }
391
+ ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer () override {
392
+ return std::error_code ();
393
+ }
394
+ void write (const MemoryBuffer &OutputBuffer) override {}
395
+ };
396
+
389
397
class FileModuleCacheEntry : public ModuleCacheEntry {
390
398
public:
399
+ static std::unique_ptr<ModuleCacheEntry> create (StringRef CachePath,
400
+ std::string Key) {
401
+ if (CachePath.empty ())
402
+ return std::make_unique<NullModuleCacheEntry>();
403
+ return std::make_unique<FileModuleCacheEntry>(CachePath, std::move (Key));
404
+ }
405
+
391
406
// Create a cache entry. This compute a unique hash for the Module considering
392
407
// the current list of export/import, and offer an interface to query to
393
408
// access the content in the cache.
394
- FileModuleCacheEntry (
395
- StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,
396
- const FunctionImporter::ImportMapTy &ImportList,
397
- const FunctionImporter::ExportSetTy &ExportList,
398
- const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
399
- const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
400
- bool Freestanding, const TargetMachineBuilder &TMBuilder) {
401
- if (CachePath.empty ())
402
- return ;
403
-
404
- std::optional<std::string> Key =
405
- computeCacheKey (Index, ModuleID, ImportList, ExportList, ResolvedODR,
406
- DefinedGVSummaries, OptLevel, Freestanding, TMBuilder);
407
-
408
- if (!Key)
409
- return ;
410
-
409
+ FileModuleCacheEntry (StringRef CachePath, std::string Key) {
410
+ assert (!CachePath.empty ());
411
411
// This choice of file name allows the cache to be pruned (see pruneCache()
412
412
// in include/llvm/Support/CachePruning.h).
413
- sys::path::append (EntryPath, CachePath, " llvmcache-" + * Key);
413
+ sys::path::append (EntryPath, CachePath, " llvmcache-" + Key);
414
414
}
415
415
416
416
std::string getEntryPath () final { return EntryPath.str ().str (); }
417
417
418
418
// Try loading the buffer for this cache entry.
419
419
ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer () final {
420
- if (EntryPath.empty ())
421
- return std::error_code ();
422
-
423
420
return MemoryBuffer::getFile (EntryPath);
424
421
}
425
422
426
423
// Cache the Produced object file
427
424
void write (const MemoryBuffer &OutputBuffer) final {
428
- if (EntryPath.empty ())
429
- return ;
430
-
431
425
if (auto Err = llvm::writeToOutput (
432
426
EntryPath, [&OutputBuffer](llvm::raw_ostream &OS) -> llvm::Error {
433
427
OS << OutputBuffer.getBuffer ();
@@ -442,30 +436,24 @@ class FileModuleCacheEntry : public ModuleCacheEntry {
442
436
StringRef OutputPath) final {
443
437
// Clear output file if exists for hard-linking.
444
438
sys::fs::remove (OutputPath);
445
- // Cache is enabled, hard-link the entry (or copy if hard-link fails).
446
- std::string CacheEntryPath = getEntryPath ();
447
- if (!CacheEntryPath.empty ()) {
448
- auto Err = sys::fs::create_hard_link (CacheEntryPath, OutputPath);
449
- if (!Err)
450
- return Error::success ();
451
- // Hard linking failed, try to copy.
452
- Err = sys::fs::copy_file (CacheEntryPath, OutputPath);
453
- if (!Err)
454
- return Error::success ();
455
- // Copy failed (could be because the CacheEntry was removed from the cache
456
- // in the meantime by another process), fall back and try to write down
457
- // the buffer to the output.
458
- errs () << " remark: can't link or copy from cached entry '"
459
- << CacheEntryPath << " ' to '" << OutputPath << " '\n " ;
460
- }
439
+ // Hard-link the entry (or copy if hard-link fails).
440
+ auto Err = sys::fs::create_hard_link (EntryPath, OutputPath);
441
+ if (!Err)
442
+ return Error::success ();
443
+ // Hard linking failed, try to copy.
444
+ Err = sys::fs::copy_file (EntryPath, OutputPath);
445
+ if (!Err)
446
+ return Error::success ();
447
+ // Copy failed (could be because the CacheEntry was removed from the cache
448
+ // in the meantime by another process), fall back and try to write down
449
+ // the buffer to the output.
450
+ errs () << " remark: can't link or copy from cached entry '" << EntryPath
451
+ << " ' to '" << OutputPath << " '\n " ;
461
452
// Fallback to default.
462
453
return ModuleCacheEntry::writeObject (OutputBuffer, OutputPath);
463
454
}
464
455
465
456
std::optional<std::unique_ptr<MemoryBuffer>> getMappedBuffer () final {
466
- if (getEntryPath ().empty ())
467
- return std::nullopt;
468
-
469
457
auto ReloadedBufferOrErr = tryLoadingBuffer ();
470
458
if (auto EC = ReloadedBufferOrErr.getError ()) {
471
459
// On error, keep the preexisting buffer and print a diagnostic.
@@ -498,54 +486,34 @@ static void handleCASError(
498
486
consumeError (std::move (E));
499
487
}
500
488
489
+ static cas::CASID createCASProxyOrAbort (cas::ObjectStore &CAS, StringRef Key) {
490
+ // Create the key by inserting cache key (SHA1) into CAS to create an ID for
491
+ // the correct context.
492
+ // TODO: We can have an alternative hashing function that doesn't need to
493
+ // store the key into CAS to get the CacheKey.
494
+ auto CASKey = CAS.createProxy (std::nullopt, Key);
495
+ if (!CASKey)
496
+ report_fatal_error (CASKey.takeError ());
497
+ return CASKey->getID ();
498
+ }
499
+
501
500
class CASModuleCacheEntry : public ModuleCacheEntry {
502
501
public:
503
502
// Create a cache entry. This compute a unique hash for the Module considering
504
503
// the current list of export/import, and offer an interface to query to
505
504
// access the content in the cache.
506
505
CASModuleCacheEntry (
507
- cas::ObjectStore &CAS, cas::ActionCache &Cache,
508
- const ModuleSummaryIndex &Index, StringRef ModuleID,
509
- const FunctionImporter::ImportMapTy &ImportList,
510
- const FunctionImporter::ExportSetTy &ExportList,
511
- const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
512
- const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
513
- bool Freestanding, const TargetMachineBuilder &TMBuilder,
506
+ cas::ObjectStore &CAS, cas::ActionCache &Cache, std::string Key,
514
507
std::function<void (llvm::function_ref<void (raw_ostream &OS)>)> Logger)
515
- : CAS(CAS), Cache(Cache), Logger(std::move(Logger)) {
516
- std::optional<std::string> Key =
517
- computeCacheKey (Index, ModuleID, ImportList, ExportList, ResolvedODR,
518
- DefinedGVSummaries, OptLevel, Freestanding, TMBuilder);
519
-
520
- if (!Key)
521
- return ;
522
-
523
- // Create the key by inserting cache key (SHA1) into CAS to create a ID for
524
- // the correct context.
525
- // TODO: We can have an alternative hashing function that doesn't
526
- // need to store the key into CAS to get the CacheKey.
527
- auto CASKey = CAS.createProxy (std::nullopt, *Key);
528
- if (!CASKey) {
529
- handleCASError (CASKey.takeError (), this ->Logger );
530
- // return as if the key doesn't exist, which will be treated as miss.
531
- return ;
532
- }
533
-
534
- ID = CASKey->getID ();
535
- }
508
+ : CAS(CAS), Cache(Cache), ID(createCASProxyOrAbort(CAS, Key)),
509
+ Logger (std::move(Logger)) {}
536
510
537
511
std::string getEntryPath () final {
538
- if (!ID)
539
- return " " ;
540
-
541
- return ID->toString ();
512
+ return ID.toString ();
542
513
}
543
514
544
515
// Try loading the buffer for this cache entry.
545
516
ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer () final {
546
- if (!ID)
547
- return std::error_code ();
548
-
549
517
std::optional<cas::CASID> MaybeKeyID;
550
518
{
551
519
ScopedDurationTimer ScopedTime ([&](double Seconds) {
@@ -557,7 +525,7 @@ class CASModuleCacheEntry : public ModuleCacheEntry {
557
525
}
558
526
});
559
527
560
- if (Error E = Cache.get (* ID, /* Globally=*/ true ).moveInto (MaybeKeyID)) {
528
+ if (Error E = Cache.get (ID, /* Globally=*/ true ).moveInto (MaybeKeyID)) {
561
529
handleCASError (std::move (E), Logger);
562
530
// If handleCASError didn't abort, treat as miss.
563
531
return std::error_code ();
@@ -586,11 +554,8 @@ class CASModuleCacheEntry : public ModuleCacheEntry {
586
554
return MaybeObject->getMemoryBuffer (" " , /* NullTerminated=*/ true );
587
555
}
588
556
589
- // Cache the Produced object file
557
+ // Cache the computed object file.
590
558
void write (const MemoryBuffer &OutputBuffer) final {
591
- if (!ID)
592
- return ;
593
-
594
559
std::optional<cas::ObjectProxy> Proxy;
595
560
{
596
561
ScopedDurationTimer ScopedTime ([&](double Seconds) {
@@ -616,14 +581,14 @@ class CASModuleCacheEntry : public ModuleCacheEntry {
616
581
}
617
582
});
618
583
619
- if (auto Err = Cache.put (* ID, Proxy->getID (), /* Globally=*/ true ))
584
+ if (auto Err = Cache.put (ID, Proxy->getID (), /* Globally=*/ true ))
620
585
handleCASError (std::move (Err), Logger);
621
586
}
622
587
623
588
private:
624
589
cas::ObjectStore &CAS;
625
590
cas::ActionCache &Cache;
626
- std::optional< cas::CASID> ID;
591
+ cas::CASID ID;
627
592
std::function<void (llvm::function_ref<void (raw_ostream &OS)>)> Logger;
628
593
};
629
594
@@ -633,33 +598,16 @@ class RemoteModuleCacheEntry : public ModuleCacheEntry {
633
598
// the current list of export/import, and offer an interface to query to
634
599
// access the content in the cache.
635
600
RemoteModuleCacheEntry (
636
- cas::remote::ClientServices &Service, const ModuleSummaryIndex &Index,
637
- StringRef ModuleID, StringRef OutputPath,
638
- const FunctionImporter::ImportMapTy &ImportList,
639
- const FunctionImporter::ExportSetTy &ExportList,
640
- const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
641
- const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
642
- bool Freestanding, const TargetMachineBuilder &TMBuilder,
601
+ cas::remote::ClientServices &Service, StringRef OutputPath,
602
+ std::string Key,
643
603
std::function<void (llvm::function_ref<void (raw_ostream &OS)>)> Logger)
644
- : Service(Service), OutputPath(OutputPath.str()),
645
- Logger (std::move(Logger)) {
646
- std::optional<std::string> Key =
647
- computeCacheKey (Index, ModuleID, ImportList, ExportList, ResolvedODR,
648
- DefinedGVSummaries, OptLevel, Freestanding, TMBuilder);
649
-
650
- if (!Key)
651
- return ;
652
-
653
- ID = *Key;
654
- }
604
+ : Service(Service), ID(std::move(Key)), OutputPath(OutputPath.str()),
605
+ Logger (std::move(Logger)) {}
655
606
656
607
std::string getEntryPath () final { return ID; }
657
608
658
609
// Try loading the buffer for this cache entry.
659
610
ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer () final {
660
- if (ID.empty ())
661
- return std::error_code ();
662
-
663
611
// Lookup the output value from KVDB.
664
612
std::optional<cas::remote::KeyValueDBClient::ValueTy> GetResponse;
665
613
{
@@ -718,9 +666,6 @@ class RemoteModuleCacheEntry : public ModuleCacheEntry {
718
666
719
667
// Cache the Produced object file
720
668
void write (const MemoryBuffer &OutputBuffer) final {
721
- if (ID.empty ())
722
- return ;
723
-
724
669
if (!ProducedOutput)
725
670
cantFail (ModuleCacheEntry::writeObject (OutputBuffer, OutputPath));
726
671
@@ -1001,21 +946,23 @@ std::unique_ptr<ModuleCacheEntry> ThinLTOCodeGenerator::createModuleCacheEntry(
1001
946
const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
1002
947
bool Freestanding, const TargetMachineBuilder &TMBuilder,
1003
948
std::function<void (llvm::function_ref<void (raw_ostream &OS)>)> Logger) {
949
+ std::optional<std::string> Key = ModuleCacheEntry::computeCacheKey (
950
+ Index, ModuleID, ImportList, ExportList, ResolvedODR, DefinedGVSummaries,
951
+ OptLevel, Freestanding, TMBuilder);
952
+
953
+ if (!Key)
954
+ return std::make_unique<NullModuleCacheEntry>();
955
+
1004
956
switch (CacheOptions.Type ) {
1005
957
case CachingOptions::CacheType::CacheDirectory:
1006
- return std::make_unique<FileModuleCacheEntry>(
1007
- CacheOptions.Path , Index, ModuleID, ImportList, ExportList, ResolvedODR,
1008
- DefinedGVSummaries, OptLevel, Freestanding, TMBuilder);
958
+ return FileModuleCacheEntry::create (CacheOptions.Path , std::move (*Key));
1009
959
case CachingOptions::CacheType::CAS:
1010
960
return std::make_unique<CASModuleCacheEntry>(
1011
- *CacheOptions.CAS , *CacheOptions.Cache , Index, ModuleID, ImportList,
1012
- ExportList, ResolvedODR, DefinedGVSummaries, OptLevel, Freestanding,
1013
- TMBuilder, std::move (Logger));
961
+ *CacheOptions.CAS , *CacheOptions.Cache , std::move (*Key),
962
+ std::move (Logger));
1014
963
case CachingOptions::CacheType::RemoteService:
1015
964
return std::make_unique<RemoteModuleCacheEntry>(
1016
- *CacheOptions.Service , Index, ModuleID, OutputPath, ImportList,
1017
- ExportList, ResolvedODR, DefinedGVSummaries, OptLevel, Freestanding,
1018
- TMBuilder, std::move (Logger));
965
+ *CacheOptions.Service , OutputPath, std::move (*Key), std::move (Logger));
1019
966
}
1020
967
}
1021
968
@@ -1714,7 +1661,7 @@ void ThinLTOCodeGenerator::run() {
1714
1661
OS << " Update cached result for " << ModuleIdentifier << " \n " ;
1715
1662
});
1716
1663
1717
- // Commit to the cache (if enabled)
1664
+ // Commit to the cache.
1718
1665
CacheEntry->write (*OutputBuffer);
1719
1666
1720
1667
if (UseBufferAPI) {
0 commit comments