23#define DEBUG_TYPE "cache-pruning"
26#include <system_error>
39 return std::tie(Time,
Other.Size, Path) <
65 return std::chrono::seconds(Num);
67 return std::chrono::minutes(Num);
69 return std::chrono::hours(Num);
72 "' must end with one of 's', 'm' or 'h'",
80 std::pair<StringRef, StringRef>
P = {
"", PolicyStr};
81 while (!
P.second.empty()) {
82 P =
P.second.split(
':');
85 std::tie(
Key,
Value) =
P.first.split(
'=');
86 if (
Key ==
"prune_interval") {
89 return DurationOrErr.takeError();
91 }
else if (
Key ==
"prune_after") {
94 return DurationOrErr.takeError();
96 }
else if (
Key ==
"cache_size") {
97 if (
Value.back() !=
'%')
107 "' must be between 0 and 100",
110 }
else if (
Key ==
"cache_size_bytes") {
112 switch (tolower(
Value.back())) {
122 Mult = 1024 * 1024 * 1024;
131 }
else if (
Key ==
"cache_size_files") {
147 const std::vector<std::unique_ptr<MemoryBuffer>> &Files) {
148 using namespace std::chrono;
175 const auto CurrentTime = system_clock::now();
187 if (Policy.
Interval != seconds(0)) {
191 auto TimeStampAge = CurrentTime - TimeStampModTime;
192 if (TimeStampAge <= *Policy.
Interval) {
194 << duration_cast<seconds>(TimeStampAge).
count()
195 <<
"s old), do not prune.\n");
207 std::set<FileInfo> FileInfos;
216 File != FileEnd && !EC; File.increment(EC)) {
229 LLVM_DEBUG(
dbgs() <<
"Ignore " << File->path() <<
" (can't stat)\n");
234 const auto FileAccessTime = StatusOrErr->getLastAccessedTime();
235 auto FileAge = CurrentTime - FileAccessTime;
238 << duration_cast<seconds>(FileAge).count()
245 TotalSize += StatusOrErr->getSize();
246 FileInfos.insert({FileAccessTime, StatusOrErr->getSize(), File->path()});
249 auto FileInfo = FileInfos.begin();
250 size_t NumFiles = FileInfos.size();
252 auto RemoveCacheFile = [&]() {
256 TotalSize -= FileInfo->Size;
259 << FileInfo->Size <<
"), new occupancy is " << TotalSize
267 const size_t ActualNums = Files.size();
270 <<
"ThinLTO cache pruning happens since the number of created files ("
271 << ActualNums <<
") exceeds the maximum number of files ("
273 <<
"); consider adjusting --thinlto-cache-policy\n";
283 if (!SpaceInfoOrErr) {
284 auto EC = SpaceInfoOrErr.getError();
286 "cannot get available disk space for '%s': '%s'",
287 Path.str().c_str(), EC.message().c_str());
290 auto AvailableSpace = TotalSize + SpaceInfo.
free;
296 auto TotalSizeTarget = std::min<uint64_t>(
300 LLVM_DEBUG(
dbgs() <<
"Occupancy: " << ((100 * TotalSize) / AvailableSpace)
305 size_t ActualSizes = 0;
306 for (
const auto &File : Files)
308 ActualSizes += File->getBufferSize();
310 if (ActualSizes > TotalSizeTarget)
312 <<
"ThinLTO cache pruning happens since the total size of the cache "
313 "files consumed by the current link job ("
314 << ActualSizes <<
" bytes) exceeds maximum cache size ("
316 <<
" bytes); consider adjusting --thinlto-cache-policy\n";
319 while (TotalSize > TotalSizeTarget && FileInfo != FileInfos.end())
static Expected< std::chrono::seconds > parseDuration(StringRef Duration)
static void writeTimestampFile(StringRef TimestampFile)
Write a new timestamp file with the given path.
Represents either an error or a value T.
Tagged union holding either a T or a Error.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
Get the contents as an std::string.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
LLVM Value Representation.
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
A raw_ostream that writes to a file descriptor.
LLVM_ABI TimePoint getLastModificationTime() const
The file modification time as reported from the underlying file system.
directory_iterator - Iterates through the entries in path.
Represents the result of a call to sys::fs::status().
LLVM_ABI ErrorOr< space_info > disk_space(const Twine &Path)
Get disk space usage information.
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
LLVM_ABI std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
LLVM_ABI bool is_directory(const basic_file_status &status)
Does status represent a directory?
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
LLVM_ABI Expected< CachePruningPolicy > parseCachePruningPolicy(StringRef PolicyStr)
Parse the given string as a cache pruning policy.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
@ no_such_file_or_directory
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
LLVM_ABI Expected< bool > pruneCache(StringRef Path, CachePruningPolicy Policy, const std::vector< std::unique_ptr< MemoryBuffer > > &Files={})
Perform pruning using the supplied policy, returns true if pruning occurred, i.e.
Policy for the pruneCache() function.
uint64_t MaxSizeFiles
The maximum number of files in the cache directory.
std::optional< std::chrono::seconds > Interval
The pruning interval.
std::chrono::seconds Expiration
The expiration for a file.
uint64_t MaxSizeBytes
The maximum size for the cache directory in bytes.
unsigned MaxSizePercentageOfAvailableSpace
The maximum size for the cache directory, in terms of percentage of the available space on the disk.
space_info - Self explanatory.