CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
llvm_model_library_4_0.hpp
1#ifndef CPPAD_CG_LLVM_MODEL_LIBRARY_4_0_INCLUDED
2#define CPPAD_CG_LLVM_MODEL_LIBRARY_4_0_INCLUDED
3/* --------------------------------------------------------------------------
4 * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5 * Copyright (C) 2017 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
19namespace CppAD {
20namespace cg {
21
22template<class Base> class LlvmModel;
23
29template<class Base>
31protected:
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::legacy::FunctionPassManager> _fpm;
36public:
37
38 LlvmModelLibrary4_0(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::legacy::FunctionPassManager(_module));
59
61
62 _fpm->doInitialization();
63
67 this->validate();
68 }
69
71 LlvmModelLibrary4_0& operator=(const LlvmModelLibrary4_0&) = delete;
72
73 inline virtual ~LlvmModelLibrary4_0() {
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