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