From 96703befd6205890105bcdb0e05e64161d5e7132 Mon Sep 17 00:00:00 2001 From: Ben Dunbobbin Date: Tue, 19 Dec 2017 14:42:38 +0000 Subject: [PATCH] [Support][CachePruning] Disable cache pruning regression fix borked by: rL284966 (see: https://reviews.llvm.org/D25730). Previously, Interval was unsigned (see: CachePruning.h), replacing the type with std::chrono::seconds (which is signed) causes a regression in behaviour because the c-api intends negative values to translate to large positive intervals to *effectively* disable the pruning (see comments on: setCachePruningInterval()). Differential Revision: https://reviews.llvm.org/D41231 llvm-svn: 321077 --- .../llvm/LTO/legacy/ThinLTOCodeGenerator.h | 6 ++++- lib/Support/CachePruning.cpp | 6 +++-- test/ThinLTO/X86/cache.ll | 22 ++++++++++++++++--- tools/llvm-lto/llvm-lto.cpp | 4 ++++ 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h index 14f0c48266f..2c842ecf96a 100644 --- a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -151,8 +151,12 @@ public: /// Cache policy: interval (seconds) between two prune of the cache. Set to a /// negative value (default) to disable pruning. A value of 0 will be ignored. void setCachePruningInterval(int Interval) { + static_assert(std::is_same::value, + "ensure same types to avoid risk of overflow"); if (Interval) - CacheOptions.Policy.Interval = std::chrono::seconds(Interval); + CacheOptions.Policy.Interval = Interval > 0 ? std::chrono::seconds(Interval) + : std::chrono::seconds::max(); } /// Cache policy: expiration (in seconds) for an entry. diff --git a/lib/Support/CachePruning.cpp b/lib/Support/CachePruning.cpp index 3e97c991f50..e1ad8024096 100644 --- a/lib/Support/CachePruning.cpp +++ b/lib/Support/CachePruning.cpp @@ -155,7 +155,8 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) { SmallString<128> TimestampFile(Path); sys::path::append(TimestampFile, "llvmcache.timestamp"); sys::fs::file_status FileStatus; - const auto CurrentTime = system_clock::now(); + const auto CurrentTime = + time_point_cast(system_clock::now()); if (auto EC = sys::fs::status(TimestampFile, FileStatus)) { if (EC == errc::no_such_file_or_directory) { // If the timestamp file wasn't there, create one now. @@ -168,7 +169,8 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) { if (Policy.Interval != seconds(0)) { // Check whether the time stamp is older than our pruning interval. // If not, do nothing. - const auto TimeStampModTime = FileStatus.getLastModificationTime(); + const auto TimeStampModTime = time_point_cast( + FileStatus.getLastModificationTime()); auto TimeStampAge = CurrentTime - TimeStampModTime; if (TimeStampAge <= Policy.Interval) { DEBUG(dbgs() << "Timestamp file too recent (" diff --git a/test/ThinLTO/X86/cache.ll b/test/ThinLTO/X86/cache.ll index ea5c2f98d87..75466442d78 100644 --- a/test/ThinLTO/X86/cache.ll +++ b/test/ThinLTO/X86/cache.ll @@ -5,7 +5,7 @@ ; Verify that enabling caching is ignoring module without hash ; RUN: rm -Rf %t.cache && mkdir %t.cache -; RUN: llvm-lto -thinlto-action=run -exported-symbol=globalfunc %t2.bc %t.bc -thinlto-cache-dir %t.cache +; RUN: llvm-lto -thinlto-action=run -exported-symbol=globalfunc %t2.bc %t.bc -thinlto-cache-dir %t.cache ; RUN: ls %t.cache/llvmcache.timestamp ; RUN: ls %t.cache | count 1 @@ -27,7 +27,7 @@ ; files matching the pattern "llvmcache-*". ; RUN: rm -Rf %t.cache && mkdir %t.cache ; RUN: touch -t 197001011200 %t.cache/llvmcache-foo %t.cache/foo -; RUN: llvm-lto -thinlto-action=run -exported-symbol=globalfunc %t2.bc %t.bc -thinlto-cache-dir %t.cache +; RUN: llvm-lto -thinlto-action=run -exported-symbol=globalfunc %t2.bc %t.bc -thinlto-cache-dir %t.cache ; RUN: ls %t.cache | count 4 ; RUN: ls %t.cache/llvmcache.timestamp ; RUN: ls %t.cache/foo @@ -36,13 +36,29 @@ ; Verify that enabling caching is working with llvm-lto2 ; RUN: rm -Rf %t.cache -; RUN: llvm-lto2 run -o %t.o %t2.bc %t.bc -cache-dir %t.cache \ +; RUN: llvm-lto2 run -o %t.o %t2.bc %t.bc -cache-dir %t.cache \ ; RUN: -r=%t2.bc,_main,plx \ ; RUN: -r=%t2.bc,_globalfunc,lx \ ; RUN: -r=%t.bc,_globalfunc,plx ; RUN: ls %t.cache | count 2 ; RUN: ls %t.cache/llvmcache-* | count 2 +; Verify that caches with a timestamp older than the pruning interval +; will be pruned +; RUN: rm -Rf %t.cache && mkdir %t.cache +; RUN: touch -t 197001011200 %t.cache/llvmcache-foo +; RUN: touch -t 197001011200 %t.cache/llvmcache.timestamp +; RUN: llvm-lto -thinlto-action=run -exported-symbol=globalfunc %t2.bc %t.bc -thinlto-cache-dir %t.cache +; RUN: not ls %t.cache/llvmcache-foo + +; Verify that specifying a negative number for the pruning interval +; effectively disables the pruning +; RUN: rm -Rf %t.cache && mkdir %t.cache +; RUN: touch -t 197001011200 %t.cache/llvmcache-foo +; RUN: touch -t 197001011200 %t.cache/llvmcache.timestamp +; RUN: llvm-lto -thinlto-action=run -exported-symbol=globalfunc %t2.bc %t.bc -thinlto-cache-dir %t.cache --thinlto-cache-pruning-interval -1 +; RUN: ls %t.cache/llvmcache-foo + target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.11.0" diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index 20c6813968b..7d71a3e8dfe 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -156,6 +156,9 @@ static cl::opt ThinLTOModuleId( static cl::opt ThinLTOCacheDir("thinlto-cache-dir", cl::desc("Enable ThinLTO caching.")); +static cl::opt + ThinLTOCachePruningInterval("thinlto-cache-pruning-interval", cl::desc("Set ThinLTO cache pruning interval.")); + static cl::opt ThinLTOSaveTempsPrefix( "thinlto-save-temps", cl::desc("Save ThinLTO temp files using filenames created by adding " @@ -470,6 +473,7 @@ public: ThinGenerator.setCodePICModel(getRelocModel()); ThinGenerator.setTargetOptions(Options); ThinGenerator.setCacheDir(ThinLTOCacheDir); + ThinGenerator.setCachePruningInterval(ThinLTOCachePruningInterval); ThinGenerator.setFreestanding(EnableFreestanding); // Add all the exported symbols to the table of symbols to preserve.