about summary refs log tree commit diff homepage
path: root/lib/Core/ExternalDispatcher.h
diff options
context:
space:
mode:
authorDan Liew <daniel.liew@imperial.ac.uk>2017-05-24 12:57:48 +0100
committerDan Liew <delcypher@gmail.com>2017-05-24 14:24:47 +0100
commit5dd3eee423c866aac6659dc2db44310737cf201d (patch)
tree900559852fc063cb5acf4d4ad594a41234858678 /lib/Core/ExternalDispatcher.h
parenta3e82239a74cdc43c44bd5200434cb48c7dd1edb (diff)
downloadklee-5dd3eee423c866aac6659dc2db44310737cf201d.tar.gz
Rearchitect ExternalDispatcher
Previous changes for LLVM 3.6 using the MCJIT were incredibly hacky.
Those changes required creating and destroying the ExternalDispatcher
for every call to an external function. This is really bad

* It's very poor design. The Executor should not need to know
  about the internal implementation details of the ExternalDispatcher.
* It's likely very inefficient to keep creating and destroying the
  external dispatcher.

The new code does several things.

* Moves all of the implementation details into a `ExternalDispatcherImpl`
  class so that implementation details are not exposed in
  `ExternalDispatcher.h`.
* When using the MCJIT a module is compiled for every (instruction, function)
  tuple. This is necessary because the MCJIT compiles whole modules at a
  time and once a module is compiled it cannot be modified and
  re-compiled. Doing this means we get to reuse already generated code
  for call sites which hopefully will reduce the overhead of repeatedly
  executing the same call site.

A consequence of this change is that now the dispatcher function name
needs to be unique across all modules. To do this we just append the
module name because we guarantee that the module name is unique by
construction.

The code has also been clang-formatted.
Diffstat (limited to 'lib/Core/ExternalDispatcher.h')
-rw-r--r--lib/Core/ExternalDispatcher.h53
1 files changed, 21 insertions, 32 deletions
diff --git a/lib/Core/ExternalDispatcher.h b/lib/Core/ExternalDispatcher.h
index d869eb6f..c64dc7d8 100644
--- a/lib/Core/ExternalDispatcher.h
+++ b/lib/Core/ExternalDispatcher.h
@@ -14,44 +14,33 @@
 
 #include <map>
 #include <memory>
-#include <string>
 #include <stdint.h>
+#include <string>
 
 namespace llvm {
-  class ExecutionEngine;
-  class Instruction;
-  class LLVMContext;
-  class Function;
-  class FunctionType;
-  class Module;
+class Instruction;
+class LLVMContext;
+class Function;
 }
 
 namespace klee {
-  class ExternalDispatcher {
-  private:
-    typedef std::map<const llvm::Instruction*,llvm::Function*> dispatchers_ty;
-    dispatchers_ty dispatchers;
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
-    std::unique_ptr<llvm::Module> dispatchModule_uniptr;
-#endif
-    llvm::Module *dispatchModule;
-    llvm::ExecutionEngine *executionEngine;
-    std::map<std::string, void*> preboundFunctions;
-    
-    llvm::Function *createDispatcher(llvm::Function *f, llvm::Instruction *i);
-    bool runProtectedCall(llvm::Function *f, uint64_t *args);
-    
-  public:
-    ExternalDispatcher(llvm::LLVMContext &ctx);
-    ~ExternalDispatcher();
-
-    /* Call the given function using the parameter passing convention of
-     * ci with arguments in args[1], args[2], ... and writing the result
-     * into args[0].
-     */
-    bool executeCall(llvm::Function *function, llvm::Instruction *i, uint64_t *args);
-    void *resolveSymbol(const std::string &name);
-  };  
+class ExternalDispatcherImpl;
+class ExternalDispatcher {
+private:
+  ExternalDispatcherImpl *impl;
+
+public:
+  ExternalDispatcher(llvm::LLVMContext &ctx);
+  ~ExternalDispatcher();
+
+  /* Call the given function using the parameter passing convention of
+   * ci with arguments in args[1], args[2], ... and writing the result
+   * into args[0].
+   */
+  bool executeCall(llvm::Function *function, llvm::Instruction *i,
+                   uint64_t *args);
+  void *resolveSymbol(const std::string &name);
+};
 }
 
 #endif