gallivm: add cache interface to mcjit
authorDave Airlie <airlied@redhat.com>
Wed, 13 May 2020 00:43:56 +0000 (10:43 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 10 Jun 2020 20:05:40 +0000 (06:05 +1000)
MCJIT uses an ObjectCache object to implement the cache,
this creates and instances of it and adds it to the MCJIT
instances, it stores the cached object for later use by
the outer layers.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5049>

src/gallium/auxiliary/gallivm/lp_bld_init.c
src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
src/gallium/auxiliary/gallivm/lp_bld_misc.h

index 43d020832875ff89202f48df098a9a3e74eb232a..6ebc9ebf25a358c71228593a9c6427c77a6f2273 100644 (file)
@@ -212,6 +212,7 @@ gallivm_free_ir(struct gallivm_state *gallivm)
    }
 
    if (gallivm->cache) {
+      lp_free_objcache(gallivm->cache->jit_obj_cache);
       free(gallivm->cache->data);
    }
    FREE(gallivm->module_name);
index 186965f32bb27e85c7e3a834368aa6f7f65270de..6f63ab50ded4e5a773d36add19ec605772d81aeb 100644 (file)
@@ -62,7 +62,7 @@
 #include <llvm/Support/CommandLine.h>
 #include <llvm/Support/Host.h>
 #include <llvm/Support/PrettyStackTrace.h>
-
+#include <llvm/ExecutionEngine/ObjectCache.h>
 #include <llvm/Support/TargetSelect.h>
 
 #if LLVM_VERSION_MAJOR < 11
@@ -289,6 +289,36 @@ class ShaderMemoryManager : public DelegatingJITMemoryManager {
       }
 };
 
+class LPObjectCache : public llvm::ObjectCache {
+private:
+   bool has_object;
+   struct lp_cached_code *cache_out;
+public:
+   LPObjectCache(struct lp_cached_code *cache) {
+      cache_out = cache;
+      has_object = false;
+   }
+
+   ~LPObjectCache() {
+   }
+   void notifyObjectCompiled(const llvm::Module *M, llvm::MemoryBufferRef Obj) {
+      const std::string ModuleID = M->getModuleIdentifier();
+      if (has_object)
+         fprintf(stderr, "CACHE ALREADY HAS MODULE OBJECT\n");
+      has_object = true;
+      cache_out->data_size = Obj.getBufferSize();
+      cache_out->data = malloc(cache_out->data_size);
+      memcpy(cache_out->data, Obj.getBufferStart(), cache_out->data_size);
+   }
+
+   virtual std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module *M) {
+      if (cache_out->data_size) {
+         return llvm::MemoryBuffer::getMemBuffer(llvm::StringRef((const char *)cache_out->data, cache_out->data_size));
+      }
+      return NULL;
+   }
+
+};
 
 /**
  * Same as LLVMCreateJITCompilerForModule, but:
@@ -502,6 +532,13 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
    ExecutionEngine *JIT;
 
    JIT = builder.create();
+
+   if (cache_out) {
+      LPObjectCache *objcache = new LPObjectCache(cache_out);
+      JIT->setObjectCache(objcache);
+      cache_out->jit_obj_cache = (void *)objcache;
+   }
+
 #if LLVM_USE_INTEL_JITEVENTS
    JITEventListener *JEL = JITEventListener::createIntelJITEventListener();
    JIT->RegisterJITEventListener(JEL);
@@ -541,6 +578,13 @@ lp_free_memory_manager(LLVMMCJITMemoryManagerRef memorymgr)
    delete reinterpret_cast<BaseMemoryManager*>(memorymgr);
 }
 
+extern "C" void
+lp_free_objcache(void *objcache_ptr)
+{
+   LPObjectCache *objcache = (LPObjectCache *)objcache_ptr;
+   delete objcache;
+}
+
 extern "C" LLVMValueRef
 lp_get_called_value(LLVMValueRef call)
 {
index f3be195554b88d08889f4b806d13c3fb44431bbd..f2a15f19e4707eaac35eed1b3ebf538658170581 100644 (file)
@@ -50,6 +50,7 @@ struct lp_cached_code {
    void *data;
    size_t data_size;
    bool dont_cache;
+   void *jit_obj_cache;
 };
 
 struct lp_generated_code;
@@ -88,6 +89,8 @@ lp_get_called_value(LLVMValueRef call);
 extern bool
 lp_is_function(LLVMValueRef v);
 
+void
+lp_free_objcache(void *objcache);
 #ifdef __cplusplus
 }
 #endif