CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
llvm_model_library_3_2.hpp
1 #ifndef CPPAD_CG_LLVM_MODEL_LIBRARY_3_2_INCLUDED
2 #define CPPAD_CG_LLVM_MODEL_LIBRARY_3_2_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2013 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_2 : public LlvmModelLibrary<Base> {
31 protected:
32  llvm::Module* _module;
33  std::unique_ptr<llvm::LLVMContext> _context;
34  std::unique_ptr<llvm::ExecutionEngine> _executionEngine;
35  std::unique_ptr<llvm::FunctionPassManager> _fpm;
36 public:
37 
38  LlvmModelLibrary3_2(llvm::Module* module,
39  llvm::LLVMContext* context) :
40  _module(module),
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(_module)
47  .setErrorStr(&errStr)
48  .setEngineKind(EngineKind::JIT)
49  .create());
50  if (!_executionEngine.get()) {
51  throw CGException("Could not create ExecutionEngine: ", errStr);
52  }
53 
54  _fpm.reset(new llvm::FunctionPassManager(_module));
55 
57 
58  _fpm->doInitialization();
59 
63  this->validate();
64  }
65 
67  LlvmModelLibrary3_2& operator=(const LlvmModelLibrary3_2&) = delete;
68 
69  inline virtual ~LlvmModelLibrary3_2() {
70  this->cleanUp();
71  }
72 
76  virtual void preparePassManager() {
77  llvm::PassManagerBuilder builder;
78  builder.OptLevel = 2;
79  builder.populateFunctionPassManager(*_fpm);
80 
81  /*
82  // Set up the optimizer pipeline. Start with registering info about how the
83  // target lays out data structures.
84  _fpm->add(new DataLayout(*_executionEngine->getDataLayout()));
85  // Provide basic AliasAnalysis support for GVN.
86  _fpm->add(createBasicAliasAnalysisPass());
87  // Do simple "peephole" optimizations and bit-twiddling optzns.
88  _fpm->add(createInstructionCombiningPass());
89  // Re-associate expressions.
90  _fpm->add(createReassociatePass());
91  // Eliminate Common SubExpressions.
92  _fpm->add(createGVNPass());
93  _fpm->add(llvm::createDeadStoreEliminationPass()); // Delete dead stores
94  // Simplify the control flow graph (deleting unreachable blocks, etc).
95  _fpm->add(createCFGSimplificationPass());
96  */
97  }
98 
99  void* loadFunction(const std::string& functionName, bool required = true) override {
100  llvm::Function* func = _module->getFunction(functionName);
101  if (func == nullptr) {
102  if (required)
103  throw CGException("Unable to find function '", functionName, "' in LLVM module");
104  return nullptr;
105  }
106 
107 #ifndef NDEBUG
108  // Validate the generated code, checking for consistency.
109  llvm::verifyFunction(*func);
110 #endif
111  // Optimize the function.
112  _fpm->run(*func);
113 
114  // JIT the function, returning a function pointer.
115  void *fPtr = _executionEngine->getPointerToFunction(func);
116  return fPtr;
117  }
118 
119  friend class LlvmModel<Base>;
120 
121 };
122 
123 } // END cg namespace
124 } // END CppAD namespace
125 
126 #endif
LlvmModelLibrary3_2(llvm::Module *module, llvm::LLVMContext *context)
void * loadFunction(const std::string &functionName, bool required=true) override