[libcxx-commits] [libcxx] 4afa9c1 - [libc++] Persistently cache memoized operations during Lit configuration

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 18 07:44:44 PST 2022


Author: Louis Dionne
Date: 2022-01-18T10:44:23-05:00
New Revision: 4afa9c17262cbca3f85352c8d3f352639f83e0b3

URL: https://github.com/llvm/llvm-project/commit/4afa9c17262cbca3f85352c8d3f352639f83e0b3
DIFF: https://github.com/llvm/llvm-project/commit/4afa9c17262cbca3f85352c8d3f352639f83e0b3.diff

LOG: [libc++] Persistently cache memoized operations during Lit configuration

When invoking Lit repeatedly, we perform all the configuration checks
over and over again, which takes a lot of time. This patch allows caching
the result of configuration checks persistently across Lit invocations to
speed this up.

In theory, this should still be functionally correct since the cache
key should contain everything that determines the output of the
configuration check. However, in cases where e.g. the compiler has
changed but is at the same path as previously, the Lit configuration
checks will be cached even though technically the cache should have
been invalidated.

Differential Revision: https://reviews.llvm.org/D117361

Added: 
    

Modified: 
    libcxx/utils/libcxx/test/dsl.py

Removed: 
    


################################################################################
diff  --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py
index 52f4d309c2b01..c50a7508cab30 100644
--- a/libcxx/utils/libcxx/test/dsl.py
+++ b/libcxx/utils/libcxx/test/dsl.py
@@ -37,13 +37,34 @@ def _memoizeExpensiveOperation(extractCacheKey):
   We pickle the cache key to make sure we store an immutable representation
   of it. If we stored an object and the object was referenced elsewhere, it
   could be changed from under our feet, which would break the cache.
+
+  We also store the cache for a given function persistently across invocations
+  of Lit. This dramatically speeds up the configuration of the test suite when
+  invoking Lit repeatedly, which is important for developer workflow. However,
+  with the current implementation that does not synchronize updates to the
+  persistent cache, this also means that one should not call a memoized
+  operation from multiple threads. This should normally not be a problem
+  since Lit configuration is single-threaded.
   """
   def decorator(function):
-    cache = {}
-    def f(*args, **kwargs):
-      cacheKey = pickle.dumps(extractCacheKey(*args, **kwargs))
+    def f(config, *args, **kwargs):
+      cacheRoot = os.path.join(config.test_exec_root, '__config_cache__')
+      persistentCache = os.path.join(cacheRoot, function.__name__)
+      if not os.path.exists(cacheRoot):
+        os.makedirs(cacheRoot)
+
+      cache = {}
+      # Load a cache from a previous Lit invocation if there is one.
+      if os.path.exists(persistentCache):
+        with open(persistentCache, 'rb') as cacheFile:
+          cache = pickle.load(cacheFile)
+
+      cacheKey = pickle.dumps(extractCacheKey(config, *args, **kwargs))
       if cacheKey not in cache:
-        cache[cacheKey] = function(*args, **kwargs)
+        cache[cacheKey] = function(config, *args, **kwargs)
+        # Update the persistent cache so it knows about the new key
+        with open(persistentCache, 'wb') as cacheFile:
+          pickle.dump(cache, cacheFile)
       return cache[cacheKey]
     return f
   return decorator


        


More information about the libcxx-commits mailing list