Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ir2obj cache pruning support. #1753

Merged
merged 2 commits into from
Sep 14, 2016

Conversation

JohanEngelen
Copy link
Member

@JohanEngelen JohanEngelen commented Sep 11, 2016

This implements ir2obj cache pruning in the compiler itself, and also through a stand-alone tool (they share the cache pruning D implementation).

Cache pruning scheme:

  1. Check the prune interval (-ir2obj-cache-prune-interval and ldc-prune-cache --interval) to see if pruning is already needed again. A timestamp file is written to the cache for this.
  2. First remove all "expired" files, i.e. files with an age older than a set limit (-ir2obj-cache-prune-expiration and ldc-prune-cache --expiry).
  3. Then, if the cache size is still too large, remove files (oldest first) until the size is below a set limit. The limit can be specified absolutely (--ir2obj-cache-prune-maxbytes and ldc-prune-cache --max-bytes) and/or relatively (--ir2obj-cache-prune-maxpercentage and ldc-prune-cache --max-percentage-of-avail).

Pruning is done after codegen, but before linking. So the prune parameters must be such that the object files needed for linking will survive (e.g. the cache size limit should be large enough).

Pruning is off by default, but specifying any pruning parameters on the commandline implies enabling it (--ir2obj-cache-prune).
The reasoning for having it off per default is that in projects using parallel compilation threads, you'd want the pruning to happen at the end of a build cycle (using the standalone tool). Otherwise, the first finishing compilation thread may start pruning stuff that you might cache-hit in another compile thread. Also, multi-threaded pruning is untested at best.

The pruning code uses the file's "last access time". But because this is not automatically updated upon symlinking or usage by the linker on some platforms (Windows 7, from what I read online), I added an extra "touch" upon a cache hit such that the last access time is refreshed at least during compilation.

Resolves #1747

#ifndef LDC_DRIVER_IR2OBJ_CACHE_PRUNING_H
#define LDC_DRIVER_IR2OBJ_CACHE_PRUNING_H

void DpruneCache(const char *cacheDirectoryPtr, size_t cacheDirectoryLen,
Copy link
Member

@dnadlinger dnadlinger Sep 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for nit-picking, but DpruneCache is not a great name ("D"?), especially since it is hardcoded to "ircache_…".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wip !
(it was to set it apart from the previous C++ implementation)

@JohanEngelen JohanEngelen force-pushed the prunecache_d branch 4 times, most recently from 1a29e8b to 1bc289a Compare September 13, 2016 08:22
@JohanEngelen JohanEngelen changed the title [wip] Add ir2obj cache pruning support. Add ir2obj cache pruning support. Sep 13, 2016
@JohanEngelen JohanEngelen reopened this Sep 13, 2016
@JohanEngelen
Copy link
Member Author

All green :)
Don't think I can make it better than this.

#define LDC_DRIVER_IR2OBJ_CACHE_PRUNING_H

#if __LP64__
using d_ulong = unsigned long;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <cstdint> and use uint64_t.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had tried it, and it doesn't work :(

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mac's compiler produces:
pruneCache(char const*, unsigned long, unsigned int, unsigned int, unsigned long long, unsigned int)
DMD and LDC produce:
pruneCache(char const*, unsigned long, unsigned int, unsigned int, unsigned long, unsigned int)

Even the table here https://dlang.org/spec/interfaceToC.html is ambiguous for ulong...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't notice this was actually an extern(C++) interface.

@dnadlinger
Copy link
Member

I suppose you'll move ldc-profdata over in a separate PR?

@JohanEngelen
Copy link
Member Author

I suppose you'll move ldc-profdata over in a separate PR?

Yep!

@JohanEngelen
Copy link
Member Author

(CircleCI was green. Currently broken because LLVM 4.0 API change)

@dnadlinger dnadlinger merged commit 1a70704 into ldc-developers:master Sep 14, 2016
@dnadlinger
Copy link
Member

We could think about backing out ldc-prune-cache and integrating it into ldc2 before the next release, now that the code is there anyway. Not sure which is the less confusing way.

@JohanEngelen JohanEngelen deleted the prunecache_d branch September 15, 2016 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants