CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
llvm_model_library_3_6.hpp
1 #ifndef CPPAD_CG_LLVM_MODEL_LIBRARY_3_6_INCLUDED
2 #define CPPAD_CG_LLVM_MODEL_LIBRARY_3_6_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2015 Ciengis
6  * Copyright (C) 2018 Joao Leal
7  *
8  * CppADCodeGen is distributed under multiple licenses:
9  *
10  * - Eclipse Public License Version 1.0 (EPL1), and
11  * - GNU General Public License Version 3 (GPL3).
12  *
13  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
14  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
15  * ----------------------------------------------------------------------------
16  * Author: Joao Leal
17  */
18 
19 namespace CppAD {
20 namespace cg {
21 
22 template<class Base> class LlvmModel;
23 
29 template<class Base>
30 class LlvmModelLibrary3_6 : public LlvmModelLibrary<Base> {
31 protected:
32  llvm::Module* _module; // owned by _executionEngine
33  std::shared_ptr<llvm::LLVMContext> _context;
34  std::unique_ptr<llvm::ExecutionEngine> _executionEngine;
35  std::unique_ptr<llvm::FunctionPassManager> _fpm;
36 public:
37 
38  LlvmModelLibrary3_6(std::unique_ptr<llvm::Module> module,
39  std::shared_ptr<llvm::LLVMContext> context) :
40  _module(module.get()),
41  _context(context) {
42  using namespace llvm;
43 
44  // Create the JIT. This takes ownership of the module.
45  std::string errStr;
46  _executionEngine.reset(EngineBuilder(std::move(module))
47  .setErrorStr(&errStr)
48  .setEngineKind(EngineKind::JIT)
49 #ifndef NDEBUG
50  .setVerifyModules(true)
51 #endif
52  // .setMCJITMemoryManager(llvm::make_unique<llvm::SectionMemoryManager>())
53  .create());
54  if (!_executionEngine.get()) {
55  throw CGException("Could not create ExecutionEngine: ", errStr);
56  }
57 
58  _fpm.reset(new llvm::FunctionPassManager(_module));
59 
61 
62  _fpm->doInitialization();
63 
67  this->validate();
68  }
69 
71  LlvmModelLibrary3_6& operator=(const LlvmModelLibrary3_6&) = delete;
72 
73  inline virtual ~LlvmModelLibrary3_6() {
74  this->cleanUp();
75  }
76 
80  virtual void preparePassManager() {
81  llvm::PassManagerBuilder builder;
82  builder.OptLevel = 2;
83  builder.populateFunctionPassManager(*_fpm);
84  //_fpm.add(new DataLayoutPass());
85  }
86 
87  void* loadFunction(const std::string& functionName, bool required = true) override {
88  llvm::Function* func = _module->getFunction(functionName);
89  if (func == nullptr) {
90  if (required)
91  throw CGException("Unable to find function '", functionName, "' in LLVM module");
92  return nullptr;
93  }
94 
95 #ifndef NDEBUG
96  // Validate the generated code, checking for consistency.
97  llvm::raw_os_ostream os(std::cerr);
98  bool failed = llvm::verifyFunction(*func, &os);
99  if (failed)
100  throw CGException("Function '", functionName, "' verification failed");
101 #endif
102 
103  // Optimize the function.
104  _fpm->run(*func);
105 
106  // JIT the function, returning a function pointer.
107  uint64_t fPtr = _executionEngine->getFunctionAddress(functionName);
108  if (fPtr == 0 && required) {
109  throw CGException("Unable to find function '", functionName, "' in LLVM module");
110  }
111  return (void*) fPtr;
112  }
113 
114  friend class LlvmModel<Base>;
115 
116 };
117 
118 } // END cg namespace
119 } // END CppAD namespace
120 
121 #endif
void * loadFunction(const std::string &functionName, bool required=true) override
LlvmModelLibrary3_6(std::unique_ptr< llvm::Module > module, std::shared_ptr< llvm::LLVMContext > context)