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