Mercurial > octave-nkf
diff libinterp/corefcn/jit-typeinfo.h @ 20654:b65888ec820e draft default tip gccjit
dmalcom gcc jit import
author | Stefan Mahr <dac922@gmx.de> |
---|---|
date | Fri, 27 Feb 2015 16:59:36 +0100 |
parents | d35201e5ce5d |
children |
line wrap: on
line diff
--- a/libinterp/corefcn/jit-typeinfo.h Tue Oct 13 11:40:05 2015 +0100 +++ b/libinterp/corefcn/jit-typeinfo.h Fri Feb 27 16:59:36 2015 +0100 @@ -25,7 +25,7 @@ #if !defined (octave_jit_typeinfo_h) #define octave_jit_typeinfo_h 1 -#ifdef HAVE_LLVM +#ifdef HAVE_JIT #include <map> #include <vector> @@ -133,10 +133,18 @@ jit_type { public: +#ifdef HAVE_LLVM typedef llvm::Value *(*convert_fn) (llvm::IRBuilderD&, llvm::Value *); +#endif - jit_type (const std::string& aname, jit_type *aparent, llvm::Type *allvm_type, - bool askip_paren, int aid); + jit_type (const std::string& aname, jit_type *aparent +#ifdef HAVE_LLVM + , llvm::Type *allvm_type +#endif +#ifdef HAVE_GCCJIT + , gccjit::type agcc_type +#endif + , bool askip_paren, int aid); // a user readable type name const std::string& name (void) const { return mname; } @@ -147,11 +155,17 @@ // An abstract base type, may be null jit_type *parent (void) const { return mparent; } +#ifdef HAVE_LLVM // convert to an llvm type llvm::Type *to_llvm (void) const { return llvm_type; } // how this type gets passed as a function argument llvm::Type *to_llvm_arg (void) const; +#endif + +#ifdef HAVE_GCCJIT + gccjit::type to_gccjit (void) const { return gccjit_type; } +#endif size_t depth (void) const { return mdepth; } @@ -179,6 +193,7 @@ // Convert into an equivalent form before calling. For example, complex is // represented as two values llvm vector, but we need to pass it as a two // valued llvm structure to C functions. +#ifdef HAVE_LLVM convert_fn pack (jit_convention::type cc) { return mpack[cc]; } void set_pack (jit_convention::type cc, convert_fn fn) { mpack[cc] = fn; } @@ -195,10 +210,17 @@ void set_packed_type (jit_convention::type cc, llvm::Type *ty) { mpacked_type[cc] = ty; } +#endif + private: std::string mname; jit_type *mparent; +#ifdef HAVE_LLVM llvm::Type *llvm_type; +#endif +#ifdef HAVE_GCCJIT + gccjit::type gccjit_type; +#endif int mid; size_t mdepth; bool mskip_paren; @@ -206,12 +228,13 @@ bool msret[jit_convention::length]; bool mpointer_arg[jit_convention::length]; +#ifdef HAVE_LLVM convert_fn mpack[jit_convention::length]; convert_fn munpack[jit_convention::length]; llvm::Type *mpacked_type[jit_convention::length]; +#endif }; - // seperate print function to allow easy printing if type is null std::ostream& jit_print (std::ostream& os, jit_type *atype); @@ -227,8 +250,16 @@ // create a function in an invalid state jit_function (); - jit_function (llvm::Module *amodule, jit_convention::type acall_conv, - const llvm::Twine& aname, jit_type *aresult, + jit_function ( +#ifdef HAVE_LLVM + llvm::Module *amodule, +#endif +#ifdef HAVE_GCCJIT + gccjit::context gccjit_ctxt, +#endif + jit_convention::type acall_conv, + std::string aname, + jit_type *aresult, const std::vector<jit_type *>& aargs); // Use an existing function, but change the argument types. The new argument @@ -241,6 +272,7 @@ // erase the interal LLVM function (if it exists). Will become invalid. void erase (void); +#ifdef HAVE_LLVM template <typename T> void add_mapping (llvm::ExecutionEngine *engine, T fn) { @@ -248,9 +280,13 @@ } bool valid (void) const { return llvm_function; } +#else + bool valid (void) const; +#endif std::string name (void) const; +#ifdef HAVE_LLVM llvm::BasicBlock *new_block (const std::string& aname = "body", llvm::BasicBlock *insert_before = 0); @@ -289,6 +325,17 @@ bool verify = true); llvm::Function *to_llvm (void) const { return llvm_function; } +#endif + +#ifdef HAVE_GCCJIT + gccjit::rvalue call (gccjit::context ctxt, + gccjit::block block, + const std::vector<jit_value *>& in_args) const; + gccjit::rvalue call (gccjit::context ctxt, + gccjit::block block, + std::vector<gccjit::rvalue>& in_args) const; + gccjit::lvalue argument (size_t idx) const; +#endif // If true, then the return value is passed as a pointer in the first argument bool sret (void) const { return mresult && mresult->sret (call_conv); } @@ -307,10 +354,17 @@ const std::vector<jit_type *>& arguments (void) const { return args; } private: +#ifdef HAVE_LLVM void do_add_mapping (llvm::ExecutionEngine *engine, void *fn); llvm::Module *module; llvm::Function *llvm_function; +#endif +#ifdef HAVE_GCCJIT +public: + gccjit::function gccjit_function; +private: +#endif jit_type *mresult; std::vector<jit_type *> args; jit_convention::type call_conv; @@ -389,14 +443,25 @@ jit_index_operation : public jit_operation { public: - jit_index_operation (void) : module (0), engine (0) { } + jit_index_operation (void) {} //: module (0), engine (0) { } - void initialize (llvm::Module *amodule, llvm::ExecutionEngine *aengine) +#ifdef HAVE_LLVM + void initialize (llvm::Module *amodule, llvm::ExecutionEngine *aengine +#ifdef HAVE_GCCJIT + , gccjit::context agccjit_ctxt +#endif + ) + { module = amodule; engine = aengine; +#ifdef HAVE_GCCJIT + gccjit_ctxt = agccjit_ctxt; +#endif do_initialize (); } +#endif + protected: virtual jit_function *generate (const signature_vec& types) const; @@ -406,12 +471,22 @@ // helper functions // [start_idx, end_idx). +#ifdef HAVE_LLVM llvm::Value *create_arg_array (llvm::IRBuilderD& builder, const jit_function &fn, size_t start_idx, size_t end_idx) const; llvm::Module *module; llvm::ExecutionEngine *engine; +#endif +#ifdef HAVE_GCCJIT + gccjit::rvalue create_arg_array (const jit_function &fn, + gccjit::block block, + size_t start_idx, + size_t end_idx) const; + + gccjit::context gccjit_ctxt; +#endif }; class @@ -442,7 +517,11 @@ jit_typeinfo { public: - static void initialize (llvm::Module *m, llvm::ExecutionEngine *e); + static void initialize ( +#ifdef HAVE_LLVM + llvm::Module *m, llvm::ExecutionEngine *e +#endif + ); static jit_type *join (jit_type *lhs, jit_type *rhs) { @@ -454,9 +533,14 @@ static jit_type *get_matrix (void) { return instance->matrix; } static jit_type *get_scalar (void) { return instance->scalar; } - +#ifdef HAVE_LLVM static llvm::Type *get_scalar_llvm (void) { return instance->scalar->to_llvm (); } +#endif +#ifdef HAVE_GCCJIT + static gccjit::type get_scalar_gccjit (void) + { return instance->scalar->to_gccjit (); } +#endif static jit_type *get_scalar_ptr (void) { return instance->scalar_ptr; } @@ -470,8 +554,10 @@ static jit_type *get_index (void) { return instance->index; } +#ifdef HAVE_LLVM static llvm::Type *get_index_llvm (void) { return instance->index->to_llvm (); } +#endif static jit_type *get_complex (void) { return instance->complex; } @@ -563,6 +649,7 @@ return instance->do_cast (to, from); } +#ifdef HAVE_LLVM static llvm::Value *insert_error_check (llvm::IRBuilderD& bld) { return instance->do_insert_error_check (bld); @@ -572,6 +659,18 @@ { return instance->do_insert_interrupt_check (bld); } +#endif +#ifdef HAVE_GCCJIT + static gccjit::rvalue insert_error_check (gccjit::function func) + { + return instance->do_insert_error_check (func); + } + + static gccjit::rvalue insert_interrupt_check (gccjit::function func) + { + return instance->do_insert_interrupt_check (func); + } +#endif static const jit_operation& end (void) { @@ -589,12 +688,25 @@ return instance->create_undef_fn; } +#ifdef HAVE_LLVM static llvm::Value *create_complex (llvm::Value *real, llvm::Value *imag) { return instance->complex_new (real, imag); } +#endif + +#ifdef HAVE_GCCJIT + static gccjit::context create_gccjit_child_context () + { + return instance->gccjit_ctxt.new_child_context (); + } +#endif + + private: +#ifdef HAVE_LLVM jit_typeinfo (llvm::Module *m, llvm::ExecutionEngine *e); +#endif // FIXME: Do these methods really need to be in jit_typeinfo? jit_type *do_join (jit_type *lhs, jit_type *rhs) @@ -668,35 +780,67 @@ const jit_function& do_end (jit_value *value, jit_value *index, jit_value *count); - jit_type *new_type (const std::string& name, jit_type *parent, - llvm::Type *llvm_type, bool skip_paren = false); - + jit_type *new_type (const std::string& name, jit_type *parent +#ifdef HAVE_LLVM + , llvm::Type *llvm_type +#endif +#ifdef HAVE_GCCJIT + , gccjit::type gccjit_type +#endif + , bool skip_paren = false); void add_print (jit_type *ty, void *fptr); - void add_binary_op (jit_type *ty, int op, int llvm_op); + void add_binary_op (jit_type *ty, int op + , int llvm_op +#ifdef HAVE_GCCJIT + , enum gcc_jit_binary_op gccjit_op +#endif + ); - void add_binary_icmp (jit_type *ty, int op, int llvm_op); + void add_binary_icmp (jit_type *ty, int op + , int llvm_op +#ifdef HAVE_GCCJIT + , enum gcc_jit_comparison gccjit_op +#endif + ); - void add_binary_fcmp (jit_type *ty, int op, int llvm_op); + void add_binary_fcmp (jit_type *ty, int op + , int llvm_op +#ifdef HAVE_GCCJIT + , enum gcc_jit_comparison gccjit_op +#endif + ); // create a function with an external calling convention // forces the function pointer to be specified template <typename T> - jit_function create_external (llvm::ExecutionEngine *ee, T fn, - const llvm::Twine& name, jit_type *ret, + jit_function create_external ( +#ifdef HAVE_LLVM + llvm::ExecutionEngine *ee, +#endif + T fn, + std::string name, jit_type *ret, const std::vector<jit_type *>& args = std::vector<jit_type *> ()) { jit_function retval = create_function (jit_convention::external, name, ret, args); +#ifdef HAVE_LLVM retval.add_mapping (ee, fn); +#endif return retval; } +#ifdef HAVE_LLVM #define JIT_PARAM_ARGS llvm::ExecutionEngine *ee, T fn, \ - const llvm::Twine& name, jit_type *ret, + std::string name, jit_type *ret, #define JIT_PARAMS ee, fn, name, ret, +#else +#define JIT_PARAM_ARGS T fn, \ + std::string name, jit_type *ret, +#define JIT_PARAMS fn, name, ret, +#endif #define CREATE_FUNCTION(N) JIT_EXPAND(template <typename T> jit_function, \ create_external, \ jit_type *, /* empty */, N) @@ -712,19 +856,19 @@ // use create_external or create_internal directly jit_function create_function (jit_convention::type cc, - const llvm::Twine& name, jit_type *ret, + std::string name, jit_type *ret, const std::vector<jit_type *>& args = std::vector<jit_type *> ()); // create an internal calling convention (a function defined in llvm) - jit_function create_internal (const llvm::Twine& name, jit_type *ret, + jit_function create_internal (std::string name, jit_type *ret, const std::vector<jit_type *>& args = std::vector<jit_type *> ()) { return create_function (jit_convention::internal, name, ret, args); } -#define JIT_PARAM_ARGS const llvm::Twine& name, jit_type *ret, +#define JIT_PARAM_ARGS std::string name, jit_type *ret, #define JIT_PARAMS name, ret, #define CREATE_FUNCTION(N) JIT_EXPAND(jit_function, create_internal, \ jit_type *, /* empty */, N) @@ -740,9 +884,17 @@ jit_function create_identity (jit_type *type); +#ifdef HAVE_LLVM llvm::Value *do_insert_error_check (llvm::IRBuilderD& bld); llvm::Value *do_insert_interrupt_check (llvm::IRBuilderD& bld); +#endif + +#ifdef HAVE_GCCJIT + gccjit::rvalue do_insert_error_check (gccjit::function func); + + gccjit::rvalue do_insert_interrupt_check (gccjit::function func); +#endif void add_builtin (const std::string& name); @@ -770,6 +922,7 @@ jit_function mirror_binary (const jit_function& fn); +#ifdef HAVE_LLVM llvm::Function *wrap_complex (llvm::Function *wrap); static llvm::Value *pack_complex (llvm::IRBuilderD& bld, @@ -787,6 +940,25 @@ llvm::Value *complex_imag (llvm::Value *cx, llvm::Value *imag); llvm::Value *complex_new (llvm::Value *real, llvm::Value *imag); +#endif + +#ifdef HAVE_GCCJIT + gccjit::rvalue complex_real (gccjit::rvalue cx); + + gccjit::rvalue complex_real (gccjit::block block, + gccjit::lvalue cx, + gccjit::rvalue real); + + gccjit::rvalue complex_imag (gccjit::rvalue cx); + + gccjit::rvalue complex_imag (gccjit::block block, + gccjit::lvalue cx, + gccjit::rvalue imag); + + gccjit::rvalue complex_new (gccjit::block block, + gccjit::rvalue real, + gccjit::rvalue imag); +#endif void create_int (size_t nbits); @@ -794,22 +966,45 @@ static jit_typeinfo *instance; +#ifdef HAVE_LLVM llvm::Module *module; llvm::ExecutionEngine *engine; +#endif int next_id; +#ifdef HAVE_LLVM llvm::GlobalVariable *lerror_state; llvm::GlobalVariable *loctave_interrupt_state; llvm::Type *sig_atomic_type; +#endif + +#ifdef HAVE_GCCJIT + gccjit::rvalue error_state_gccjit; + gccjit::rvalue octave_interrupt_state_gccjit; + gccjit::type sig_atomic_type_gccjit; +#endif std::vector<jit_type*> id_to_type; jit_type *any; jit_type *matrix; +#ifdef HAVE_GCCJIT + gccjit::field field_ref_count; + gccjit::field field_slice_data; + gccjit::field field_slice_len; + gccjit::field field_dimensions; + gccjit::field field_array; +#endif jit_type *scalar; jit_type *scalar_ptr; // a fake type for interfacing with C++ jit_type *any_ptr; // a fake type for interfacing with C++ jit_type *range; +#ifdef HAVE_GCCJIT + gccjit::field field_rng_base; + gccjit::field field_rng_limit; + gccjit::field field_rng_inc; + gccjit::field field_rng_nelem; +#endif jit_type *string; jit_type *boolean; jit_type *index; @@ -818,7 +1013,9 @@ std::map<size_t, jit_type *> ints; std::map<std::string, jit_type *> builtins; +#ifdef HAVE_LLVM llvm::StructType *complex_ret; +#endif std::vector<jit_operation> binary_ops; std::vector<jit_operation> unary_ops; @@ -845,8 +1042,14 @@ // type id -> identity function std::vector<jit_function> identities; +#ifdef HAVE_LLVM llvm::IRBuilderD& builder; +#endif + +#ifdef HAVE_GCCJIT + gccjit::context gccjit_ctxt; +#endif }; +#endif /* ifdef HAVE_JIT */ #endif -#endif