locate a function address based on its name. The returned function address is a 64 bit int that needs casting to the function pointer type.
// given a function, for example: int fib(int x){ if (x < 2) return x; return fib(x-1) + fib(x-2); }
// and assuming the function was jitt'ed and added to the module under the // symbol "fib"
#ifndef ROADRUNNER_JIT_H
#define ROADRUNNER_JIT_H
#define NOMINMAX
#include <rrSparse.h>
#include "LLVMException.h"
#include "rrSparse.h"
#include <unordered_map>
#ifdef _MSC_VER
#pragma warning(disable: 4146)
#pragma warning(disable: 4141)
#pragma warning(disable: 4267)
#pragma warning(disable: 4624)
#endif
#include <llvm/Analysis/TargetLibraryInfo.h>
#include "llvm/IR/IRBuilder.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/IR/Mangler.h"
#ifdef _MSC_VER
#pragma warning(default: 4146)
#pragma warning(default: 4141)
#pragma warning(default: 4267)
#pragma warning(default: 4624)
#endif
namespace rr {
class ExecutableModel;
}
namespace rrllvm {
class Random;
class ModelResources;
class SBMLModelObjectCache;
template<typename FunctionPtrType>
class CodeGenBase;
using FnPtr_d1 = double (*)(double x);
using FnPtr_i1 = int (*)(int x);
using FnPtr_d2 = double (*)(double x, double y);
using fabsFnTy = FnPtr_d1;
using acosFnTy = FnPtr_d1;
using asinFnTy = FnPtr_d1;
using atanFnTy = FnPtr_d1;
using ceilFnTy = FnPtr_d1;
using cosFnTy = FnPtr_d1;
using coshFnTy = FnPtr_d1;
using expFnTy = FnPtr_d1;
using floorFnTy = FnPtr_d1;
using logFnTy = FnPtr_d1;
using log10FnTy = FnPtr_d1;
using sinFnTy = FnPtr_d1;
using sinhFnTy = FnPtr_d1;
using tanFnTy = FnPtr_d1;
using tanhFnTy = FnPtr_d1;
using fmodFnTy = FnPtr_d2;
using powFnTy = FnPtr_d2;
using arccotFnTy = FnPtr_d1;
using rr_arccot_negzeroFnTy = FnPtr_d1;
using arccothFnTy = FnPtr_d1;
using arccscFnTy = FnPtr_d1;
using arccschFnTy = FnPtr_d1;
using arcsecFnTy = FnPtr_d1;
using arcsechFnTy = FnPtr_d1;
using cotFnTy = FnPtr_d1;
using cothFnTy = FnPtr_d1;
using cscFnTy = FnPtr_d1;
using cschFnTy = FnPtr_d1;
using secFnTy = FnPtr_d1;
using sechFnTy = FnPtr_d1;
using arccoshFnTy = FnPtr_d1;
using arcsinhFnTy = FnPtr_d1;
using arctanhFnTy = FnPtr_d1;
using rr_factorialdFnTy = FnPtr_d1;
using rr_factorialiFnTy = FnPtr_i1;
using rr_logdFnTy = FnPtr_d2;
using rr_rootdFnTy = FnPtr_d2;
using quotientFnTy = FnPtr_d2;
using rr_maxFnTy = FnPtr_d2;
using rr_minFnTy = FnPtr_d2;
using csr_matrix_set_nz_FnTy = rr::csr_matrix *(*)(int, int, double);
using csr_matrix_get_nz_FnTy = rr::csr_matrix *(*)(int, int);
using DistribFnTy_d1 = double (*)(Random *, double);
using DistribFnTy_d2 = double (*)(Random *, double, double);
using DistribFnTy_d3 = double (*)(Random *, double, double, double);
using DistribFnTy_d4 = double (*)(Random *, double, double, double, double);
using distrib_bernoulli_FnTy = DistribFnTy_d1;
using distrib_cauchy_one_FnTy = DistribFnTy_d1;
using distrib_chisquare_FnTy = DistribFnTy_d1;
using distrib_exponential_FnTy = DistribFnTy_d1;
using distrib_laplace_one_FnTy = DistribFnTy_d1;
using distrib_poisson_FnTy = DistribFnTy_d1;
using distrib_rayleigh_FnTy = DistribFnTy_d1;
using distrib_uniform_FnTy = DistribFnTy_d2;
using distrib_normal_FnTy = DistribFnTy_d2;
using distrib_binomial_FnTy = DistribFnTy_d2;
using distrib_cauchy_FnTy = DistribFnTy_d2;
using distrib_gamma_FnTy = DistribFnTy_d2;
using distrib_laplace_FnTy = DistribFnTy_d2;
using distrib_lognormal_FnTy = DistribFnTy_d2;
using distrib_chisquare_three_FnTy = DistribFnTy_d3;
using distrib_exponential_three_FnTy = DistribFnTy_d3;
using distrib_poisson_three_FnTy = DistribFnTy_d3;
using distrib_rayleigh_three_FnTy = DistribFnTy_d3;
using distrib_normal_four_FnTy = DistribFnTy_d4;
using distrib_binomial_four_FnTy = DistribFnTy_d4;
using distrib_cauchy_four_FnTy = DistribFnTy_d4;
using distrib_gamma_four_FnTy = DistribFnTy_d4;
using distrib_laplace_four_FnTy = DistribFnTy_d4;
using distrib_lognormal_four_FnTy = DistribFnTy_d4;
using rrOwningBinary = llvm::object::OwningBinary<llvm::object::ObjectFile>;
using FnMap = std::unordered_map<std::string, std::pair<llvm::FunctionType *, void *>>;
class Jit {
public:
explicit Jit(std::uint32_t options);
virtual ~Jit() =
default;
virtual std::uint64_t lookupFunctionAddress(const std::string &name) = 0;
virtual void addObjectFile(std::unique_ptr<llvm::object::ObjectFile> objectFile) = 0;
virtual void addObjectFile(std::unique_ptr<llvm::MemoryBuffer> obj) = 0;
virtual void addModule(std::unique_ptr<llvm::Module> M, std::unique_ptr<llvm::LLVMContext> ctx) = 0;
std::string getDefaultTargetTriple() const;
void setModuleIdentifier(const std::string &id);
virtual std::string mangleName(const std::string &unmangledName) const;
protected:
std::unique_ptr<llvm::LLVMContext> context;
std::unique_ptr<llvm::Module> module;
llvm::Module *moduleNonOwning = nullptr;
std::unique_ptr<llvm::IRBuilder<>> builder;
std::uint32_t options;
private:
void createCLibraryFunction(llvm::LibFunc funcId, llvm::FunctionType *funcType);
void createCLibraryFunctions();
};
}
#endif
virtual void mapLLVMGeneratedFunctionsToSymbols(ModelResources *modelResources, std::uint32_t options)
Map the Jit'd functions that collectively represent a roadrunner compiled sbml model to symbols in th...
Definition: Jit.cpp:101
llvm::SmallVector< char, 10 > moduleBuffer
The buffer used by compiledModuleBinaryStream.
Definition: Jit.h:344
virtual void addObjectFile(rrOwningBinary owningObject)=0
add an in-memory representation of an object file to the current jit module.
virtual llvm::LLVMContext * getContextNonOwning()
returns a non owning pointer to the llvm::LLVMContext instance
Definition: Jit.cpp:76
llvm::raw_svector_ostream & getCompiledModuleStream()
get the stream that stores a compiled module as binary.
virtual ~Jit()=default
Add support for libsbml distrib functions.
virtual std::string getModuleAsString(std::string sbmlMD5)=0
get a binary string representation of the current module.
virtual void mapFunctionsToJitSymbols()=0
adds functions that are declared and defined in C++ to the jit engine.
std::string getProcessTriple() const
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Jit.cpp:314
virtual llvm::Module * getModuleNonOwning()
returns a non owning pointer to the llvm::Module instance
Definition: Jit.cpp:72
FnMap externalFunctionSignatures() const
returns a mapping between function names and function signatures
Definition: Jit.cpp:337
std::unique_ptr< llvm::raw_svector_ostream > compiledModuleBinaryStream
MCJit compiles the generated LLVM IR to this binary stream which is then used both for adding to the ...
Definition: Jit.h:339
virtual const llvm::DataLayout & getDataLayout() const =0
get the DataLayout currently in use in the Jit
virtual std::string emitToString()
Write the Jit::module in its current state to string as LLVM IR.
Definition: Jit.cpp:207
virtual void transferObjectsToResources(std::shared_ptr< rrllvm::ModelResources > modelResources)
Moves objects over to ModelResources ptr
Definition: Jit.cpp:95
virtual std::unique_ptr< llvm::MemoryBuffer > getCompiledModelFromCache(const std::string &sbmlMD5)=0
lookup the sbml with the md5
Jit()
default constructor.
Definition: Jit.cpp:69
const llvm::Target * getDefaultTargetMachine() const
use llvm calls to work out which TargetMachine is currently being used.
Definition: Jit.cpp:323
virtual void addModule()=0
add the module and context which are member variables of the Jit instance to the current Jit engine.
virtual llvm::IRBuilder * getBuilderNonOwning()
returns a non owning pointer to the llvm::LLVMContext instance
Definition: Jit.cpp:91