GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
jit-typeinfo.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2012-2017 Max Brister
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 // Author: Max Brister <max@2bass.com>
24 
25 #if ! defined (octave_jit_typeinfo_h)
26 #define octave_jit_typeinfo_h 1
27 
28 #include "octave-config.h"
29 
30 #if defined (HAVE_LLVM)
31 
32 #include <map>
33 #include <vector>
34 
35 #include "Range.h"
36 #include "jit-util.h"
37 
38 // Defines the type system used by jit and a singleton class, jit_typeinfo, to
39 // manage the types.
40 //
41 // FIXME:
42 // Operations are defined and implemented in jit_typeinfo. Eventually they
43 // should be moved elsewhere. (just like with octave_typeinfo)
44 
45 // jit_range is compatible with the llvm range structure
46 struct
48 {
49  jit_range (const Range& from) : base (from.base ()), limit (from.limit ()),
50  inc (from.inc ()), nelem (from.numel ())
51  { }
52 
53  operator Range () const
54  {
55  return Range (base, limit, inc);
56  }
57 
58  bool all_elements_are_ints () const;
59 
60  double base;
61  double limit;
62  double inc;
64 };
65 
66 std::ostream& operator << (std::ostream& os, const jit_range& rng);
67 
68 // jit_array is compatible with the llvm array/matrix structures
69 template <typename T, typename U>
70 struct
72 {
73  jit_array () : array (0) { }
74 
75  jit_array (T& from) : array (new T (from))
76  {
77  update ();
78  }
79 
80  void update (void)
81  {
82  ref_count = array->jit_ref_count ();
83  slice_data = array->jit_slice_data () - 1;
84  slice_len = array->numel ();
85  dimensions = array->jit_dimensions ();
86  }
87 
88  void update (T *aarray)
89  {
90  array = aarray;
91  update ();
92  }
93 
94  operator T () const
95  {
96  return *array;
97  }
98 
99  int *ref_count;
100 
104 
105  T *array;
106 };
107 
109 
110 std::ostream& operator << (std::ostream& os, const jit_matrix& mat);
111 
112 // calling convention
113 namespace jit_convention
114 {
115  enum
116  type
117  {
118  // internal to jit
119  internal,
120 
121  // an external C call
123 
125  };
126 }
127 
128 // Used to keep track of estimated (infered) types during JIT. This is a
129 // hierarchical type system which includes both concrete and abstract types.
130 //
131 // The types form a lattice. Currently we only allow for one parent type, but
132 // eventually we may allow for multiple predecessors.
133 class
134 jit_type
135 {
136 public:
137  typedef llvm::Value *(*convert_fn) (llvm::IRBuilderD&, llvm::Value *);
138 
139  jit_type (const std::string& aname, jit_type *aparent, llvm::Type *allvm_type,
140  bool askip_paren, int aid);
141 
142  // a user readable type name
143  const std::string& name (void) const { return mname; }
144 
145  // a unique id for the type
146  int type_id (void) const { return mid; }
147 
148  // An abstract base type, may be null
149  jit_type *parent (void) const { return mparent; }
150 
151  // convert to an llvm type
152  llvm::Type *to_llvm (void) const { return llvm_type; }
153 
154  // how this type gets passed as a function argument
155  llvm::Type *to_llvm_arg (void) const;
156 
157  size_t depth (void) const { return mdepth; }
158 
159  bool skip_paren (void) const { return mskip_paren; }
160 
161  // -------------------- Calling Convention information --------------------
162 
163  // A function declared like: mytype foo (int arg0, int arg1);
164  // Will be converted to: void foo (mytype *retval, int arg0, int arg1)
165  // if mytype is sret. The caller is responsible for allocating space for
166  // retval. (on the stack)
167  bool sret (jit_convention::type cc) const { return msret[cc]; }
168 
170  { msret[cc] = true; }
171 
172  // A function like: void foo (mytype arg0)
173  // Will be converted to: void foo (mytype *arg0)
174  // Basically just pass by reference.
175  bool pointer_arg (jit_convention::type cc) const { return mpointer_arg[cc]; }
176 
178  { mpointer_arg[cc] = true; }
179 
180  // Convert into an equivalent form before calling. For example, complex is
181  // represented as two values llvm vector, but we need to pass it as a two
182  // valued llvm structure to C functions.
183  convert_fn pack (jit_convention::type cc) { return mpack[cc]; }
184 
185  void set_pack (jit_convention::type cc, convert_fn fn) { mpack[cc] = fn; }
186 
187  // The inverse operation of pack.
188  convert_fn unpack (jit_convention::type cc) { return munpack[cc]; }
189 
190  void set_unpack (jit_convention::type cc, convert_fn fn)
191  { munpack[cc] = fn; }
192 
193  // The resulting type after pack is called.
195  { return mpacked_type[cc]; }
196 
197  void set_packed_type (jit_convention::type cc, llvm::Type *ty)
198  { mpacked_type[cc] = ty; }
199 private:
202  llvm::Type *llvm_type;
203  int mid;
204  size_t mdepth;
206 
208  bool mpointer_arg[jit_convention::length];
209 
210  convert_fn mpack[jit_convention::length];
211  convert_fn munpack[jit_convention::length];
212 
213  llvm::Type *mpacked_type[jit_convention::length];
214 };
215 
216 // seperate print function to allow easy printing if type is null
217 std::ostream& jit_print (std::ostream& os, jit_type *atype);
218 
219 class jit_value;
220 
221 // An abstraction for calling llvm functions with jit_values. Deals with
222 // calling convention details.
223 class
225 {
226  friend std::ostream& operator << (std::ostream& os, const jit_function& fn);
227 public:
228  // create a function in an invalid state
229  jit_function ();
230 
231  jit_function (llvm::Module *amodule, jit_convention::type acall_conv,
232  const llvm::Twine& aname, jit_type *aresult,
233  const std::vector<jit_type *>& aargs);
234 
235  // Use an existing function, but change the argument types. The new argument
236  // types must behave the same for the current calling convention.
237  jit_function (const jit_function& fn, jit_type *aresult,
238  const std::vector<jit_type *>& aargs);
239 
240  jit_function (const jit_function& fn);
241 
242  // erase the interal LLVM function (if it exists). Will become invalid.
243  void erase (void);
244 
245  template <typename T>
246  void add_mapping (llvm::ExecutionEngine *engine, T fn)
247  {
248  do_add_mapping (engine, reinterpret_cast<void *> (fn));
249  }
250 
251  bool valid (void) const { return llvm_function; }
252 
253  std::string name (void) const;
254 
255  llvm::BasicBlock *new_block (const std::string& aname = "body",
256  llvm::BasicBlock *insert_before = 0);
257 
258  llvm::Value *call (llvm::IRBuilderD& builder,
259  const std::vector<jit_value *>& in_args) const;
260 
261  llvm::Value *call (llvm::IRBuilderD& builder,
262  const std::vector<llvm::Value *>& in_args
263  = std::vector<llvm::Value *> ()) const;
264 
265 #define JIT_PARAM_ARGS llvm::IRBuilderD& builder,
266 #define JIT_PARAMS builder,
267 #define JIT_CALL(N) JIT_EXPAND (llvm::Value *, call, llvm::Value *, const, N)
268 
270  JIT_CALL (2)
272  JIT_CALL (4)
275 #undef JIT_CALL
276 
277 #define JIT_CALL(N) JIT_EXPAND (llvm::Value *, call, jit_value *, const, N)
278 
279  JIT_CALL (1);
280  JIT_CALL (2);
281  JIT_CALL (3);
282 
283 #undef JIT_CALL
284 #undef JIT_PARAMS
285 #undef JIT_PARAM_ARGS
287  llvm::Value *argument (llvm::IRBuilderD& builder, size_t idx) const;
288 
289  void do_return (llvm::IRBuilderD& builder, llvm::Value *rval = 0,
290  bool verify = true);
292  llvm::Function *to_llvm (void) const { return llvm_function; }
294  // If true, then the return value is passed as a pointer in the first argument
295  bool sret (void) const { return mresult && mresult->sret (call_conv); }
296 
297  bool can_error (void) const { return mcan_error; }
298 
299  void mark_can_error (void) { mcan_error = true; }
300 
301  jit_type *result (void) const { return mresult; }
302 
303  jit_type *argument_type (size_t idx) const
304  {
305  assert (idx < args.size ());
306  return args[idx];
307  }
309  const std::vector<jit_type *>& arguments (void) const { return args; }
310 private:
311  void do_add_mapping (llvm::ExecutionEngine *engine, void *fn);
313  llvm::Module *module;
314  llvm::Function *llvm_function;
315  jit_type *mresult;
316  std::vector<jit_type *> args;
317  jit_convention::type call_conv;
318  bool mcan_error;
319 };
320 
321 std::ostream& operator << (std::ostream& os, const jit_function& fn);
322 
323 // Keeps track of information about how to implement operations (+, -, *, ect)
324 // and their resulting types.
325 class
327 {
328 public:
329  // type signature vector
330  typedef std::vector<jit_type *> signature_vec;
331 
332  virtual ~jit_operation (void);
333 
334  void add_overload (const jit_function& func)
335  {
336  add_overload (func, func.arguments ());
337  }
339  void add_overload (const jit_function& func,
340  const signature_vec& args);
341 
342  const jit_function& overload (const signature_vec& types) const;
343 
344  jit_type *result (const signature_vec& types) const
345  {
346  const jit_function& temp = overload (types);
347  return temp.result ();
348  }
349 
350 #define JIT_PARAMS
351 #define JIT_PARAM_ARGS
352 #define JIT_OVERLOAD(N) \
353  JIT_EXPAND (const jit_function&, overload, jit_type *, const, N) \
354  JIT_EXPAND (jit_type *, result, jit_type *, const, N)
355 
356  JIT_OVERLOAD (1);
358  JIT_OVERLOAD (3);
360 #undef JIT_PARAMS
361 #undef JIT_PARAM_ARGS
362 
363  const std::string& name (void) const { return mname; }
364 
365  void stash_name (const std::string& aname) { mname = aname; }
366 protected:
367  virtual jit_function *generate (const signature_vec& types) const;
368 private:
369  Array<octave_idx_type> to_idx (const signature_vec& types) const;
370 
371  const jit_function& do_generate (const signature_vec& types) const;
372 
374  {
375  bool operator () (const signature_vec *lhs, const signature_vec *rhs) const;
376  };
378  typedef std::map<const signature_vec *, jit_function *, signature_cmp>
380 
381  mutable generated_map generated;
383  std::vector<Array<jit_function> > overloads;
384 
385  std::string mname;
386 };
387 
388 class
390 {
391 public:
392  jit_index_operation (void) : module (0), engine (0) { }
393 
394  void initialize (llvm::Module *amodule, llvm::ExecutionEngine *aengine)
395  {
396  module = amodule;
397  engine = aengine;
398  do_initialize ();
399  }
400 protected:
401  virtual jit_function *generate (const signature_vec& types) const;
402 
403  virtual jit_function *generate_matrix (const signature_vec& types) const = 0;
404 
405  virtual void do_initialize (void) = 0;
406 
407  // helper functions
408  // [start_idx, end_idx).
409  llvm::Value *create_arg_array (llvm::IRBuilderD& builder,
410  const jit_function &fn, size_t start_idx,
411  size_t end_idx) const;
412 
413  llvm::Module *module;
414  llvm::ExecutionEngine *engine;
415 };
416 
417 class
419 {
420 protected:
421  virtual jit_function *generate_matrix (const signature_vec& types) const;
423  virtual void do_initialize (void);
424 private:
425  jit_function paren_scalar;
426 };
427 
428 class
430 {
431 protected:
432  jit_function *generate_matrix (const signature_vec& types) const;
433 
434  virtual void do_initialize (void);
435 private:
436  jit_function paren_scalar;
437 };
438 
439 // A singleton class which handles the construction of jit_types and
440 // jit_operations.
441 class
443 {
444 public:
445  static void initialize (llvm::Module *m, llvm::ExecutionEngine *e);
447  static jit_type *join (jit_type *lhs, jit_type *rhs)
448  {
449  return instance->do_join (lhs, rhs);
450  }
451 
452  static jit_type *get_any (void) { return instance->any; }
453 
454  static jit_type *get_matrix (void) { return instance->matrix; }
456  static jit_type *get_scalar (void) { return instance->scalar; }
458  static llvm::Type *get_scalar_llvm (void)
459  { return instance->scalar->to_llvm (); }
460 
461  static jit_type *get_scalar_ptr (void) { return instance->scalar_ptr; }
462 
463  static jit_type *get_any_ptr (void) { return instance->any_ptr; }
464 
465  static jit_type *get_range (void) { return instance->range; }
466 
467  static jit_type *get_string (void) { return instance->string; }
468 
469  static jit_type *get_bool (void) { return instance->boolean; }
471  static jit_type *get_index (void) { return instance->index; }
472 
473  static llvm::Type *get_index_llvm (void)
474  { return instance->index->to_llvm (); }
475 
476  static jit_type *get_complex (void) { return instance->complex; }
477 
478  // Get the jit_type of an octave_value
479  static jit_type *type_of (const octave_value& ov)
480  {
481  return instance->do_type_of (ov);
482  }
484  static const jit_operation& binary_op (int op)
485  {
486  return instance->do_binary_op (op);
487  }
489  static const jit_operation& unary_op (int op)
490  {
491  return instance->do_unary_op (op);
492  }
493 
494  static const jit_operation& grab (void) { return instance->grab_fn; }
496  static const jit_function& get_grab (jit_type *type)
497  {
498  return instance->grab_fn.overload (type);
499  }
501  static const jit_operation& release (void)
502  {
503  return instance->release_fn;
504  }
506  static const jit_function& get_release (jit_type *type)
507  {
508  return instance->release_fn.overload (type);
509  }
511  static const jit_operation& destroy (void)
512  {
513  return instance->destroy_fn;
514  }
516  static const jit_operation& print_value (void)
517  {
518  return instance->print_fn;
519  }
521  static const jit_operation& for_init (void)
522  {
523  return instance->for_init_fn;
524  }
526  static const jit_operation& for_check (void)
527  {
528  return instance->for_check_fn;
529  }
531  static const jit_operation& for_index (void)
532  {
533  return instance->for_index_fn;
534  }
536  static const jit_operation& make_range (void)
537  {
538  return instance->make_range_fn;
539  }
541  static const jit_operation& paren_subsref (void)
542  {
543  return instance->paren_subsref_fn;
544  }
546  static const jit_operation& paren_subsasgn (void)
547  {
548  return instance->paren_subsasgn_fn;
549  }
551  static const jit_operation& logically_true (void)
552  {
553  return instance->logically_true_fn;
554  }
556  static const jit_operation& cast (jit_type *result)
557  {
558  return instance->do_cast (result);
559  }
561  static const jit_function& cast (jit_type *to, jit_type *from)
562  {
563  return instance->do_cast (to, from);
564  }
566  static llvm::Value *insert_error_check (llvm::IRBuilderD& bld)
567  {
568  return instance->do_insert_error_check (bld);
569  }
571  static llvm::Value *insert_interrupt_check (llvm::IRBuilderD& bld)
572  {
573  return instance->do_insert_interrupt_check (bld);
574  }
576  static const jit_operation& end (void)
577  {
578  return instance->end_fn;
579  }
580 
581  static const jit_function& end (jit_value *value, jit_value *index,
582  jit_value *count)
583  {
584  return instance->do_end (value, index, count);
585  }
587  static const jit_operation& create_undef (void)
588  {
589  return instance->create_undef_fn;
590  }
591 
592  static llvm::Value *create_complex (llvm::Value *real, llvm::Value *imag)
593  {
594  return instance->complex_new (real, imag);
595  }
596 private:
597  jit_typeinfo (llvm::Module *m, llvm::ExecutionEngine *e);
598 
599  // FIXME: Do these methods really need to be in jit_typeinfo?
600  jit_type *do_join (jit_type *lhs, jit_type *rhs)
601  {
602  // empty case
603  if (! lhs)
604  return rhs;
605 
606  if (! rhs)
607  return lhs;
608 
609  // check for a shared parent
610  while (lhs != rhs)
611  {
612  if (lhs->depth () > rhs->depth ())
613  lhs = lhs->parent ();
614  else if (lhs->depth () < rhs->depth ())
615  rhs = rhs->parent ();
616  else
617  {
618  // we MUST have depth > 0 as any is the base type of everything
619  do
620  {
621  lhs = lhs->parent ();
622  rhs = rhs->parent ();
623  }
624  while (lhs != rhs);
625  }
626  }
627 
628  return lhs;
629  }
630 
631  jit_type *do_difference (jit_type *lhs, jit_type *)
632  {
633  // FIXME: Maybe we can do something smarter?
634  return lhs;
635  }
636 
637  jit_type *do_type_of (const octave_value &ov) const;
638 
639  const jit_operation& do_binary_op (int op) const
640  {
641  assert (static_cast<size_t>(op) < binary_ops.size ());
642  return binary_ops[op];
643  }
644 
645  const jit_operation& do_unary_op (int op) const
646  {
647  assert (static_cast<size_t> (op) < unary_ops.size ());
648  return unary_ops[op];
649  }
650 
651  const jit_operation& do_cast (jit_type *to)
652  {
653  static jit_operation null_function;
654  if (! to)
655  return null_function;
656 
657  size_t id = to->type_id ();
658  if (id >= casts.size ())
659  return null_function;
660  return casts[id];
661  }
662 
663  const jit_function& do_cast (jit_type *to, jit_type *from)
664  {
665  return do_cast (to).overload (from);
666  }
667 
668  const jit_function& do_end (jit_value *value, jit_value *index,
669  jit_value *count);
670 
671  jit_type *new_type (const std::string& name, jit_type *parent,
672  llvm::Type *llvm_type, bool skip_paren = false);
673 
674  void add_print (jit_type *ty, void *fptr);
675 
676  void add_binary_op (jit_type *ty, int op, int llvm_op);
677 
678  void add_binary_icmp (jit_type *ty, int op, int llvm_op);
680  void add_binary_fcmp (jit_type *ty, int op, int llvm_op);
681 
682  // create a function with an external calling convention
683  // forces the function pointer to be specified
684  template <typename T>
685  jit_function create_external (llvm::ExecutionEngine *ee, T fn,
686  const llvm::Twine& name, jit_type *ret,
687  const std::vector<jit_type *>& args
688  = std::vector<jit_type *> ())
689  {
690  jit_function retval = create_function (jit_convention::external, name, ret,
691  args);
692  retval.add_mapping (ee, fn);
693  return retval;
694  }
695 
696 #define JIT_PARAM_ARGS llvm::ExecutionEngine *ee, T fn, \
697  const llvm::Twine& name, jit_type *ret,
698 #define JIT_PARAMS ee, fn, name, ret,
699 #define CREATE_FUNCTION(N) JIT_EXPAND(template <typename T> jit_function, \
700  create_external, \
701  jit_type *, /* empty */, N)
702 
703  CREATE_FUNCTION(1);
704  CREATE_FUNCTION(2);
705  CREATE_FUNCTION(3);
706  CREATE_FUNCTION(4);
707 
708 #undef JIT_PARAM_ARGS
709 #undef JIT_PARAMS
710 #undef CREATE_FUNCTION
711 
712  // use create_external or create_internal directly
713  jit_function create_function (jit_convention::type cc,
714  const llvm::Twine& name, jit_type *ret,
715  const std::vector<jit_type *>& args
716  = std::vector<jit_type *> ());
717 
718  // create an internal calling convention (a function defined in llvm)
719  jit_function create_internal (const llvm::Twine& name, jit_type *ret,
720  const std::vector<jit_type *>& args
721  = std::vector<jit_type *> ())
722  {
723  return create_function (jit_convention::internal, name, ret, args);
724  }
726 #define JIT_PARAM_ARGS const llvm::Twine& name, jit_type *ret,
727 #define JIT_PARAMS name, ret,
728 #define CREATE_FUNCTION(N) JIT_EXPAND(jit_function, create_internal, \
729  jit_type *, /* empty */, N)
730 
731  CREATE_FUNCTION(1);
732  CREATE_FUNCTION(2);
733  CREATE_FUNCTION(3);
734  CREATE_FUNCTION(4);
735 
736 #undef JIT_PARAM_ARGS
737 #undef JIT_PARAMS
738 #undef CREATE_FUNCTION
739 
740  jit_function create_identity (jit_type *type);
741 
742  llvm::Value *do_insert_error_check (llvm::IRBuilderD& bld);
743 
744  llvm::Value *do_insert_interrupt_check (llvm::IRBuilderD& bld);
745 
746  void add_builtin (const std::string& name);
747 
748  void register_intrinsic (const std::string& name, size_t id,
749  jit_type *result, jit_type *arg0)
750  {
751  std::vector<jit_type *> args (1, arg0);
752  register_intrinsic (name, id, result, args);
753  }
754 
755  void register_intrinsic (const std::string& name, size_t id, jit_type *result,
756  const std::vector<jit_type *>& args);
757 
758  void register_generic (const std::string& name, jit_type *result,
759  jit_type *arg0)
760  {
761  std::vector<jit_type *> args (1, arg0);
762  register_generic (name, result, args);
763  }
764 
765  void register_generic (const std::string& name, jit_type *result,
766  const std::vector<jit_type *>& args);
767 
768  octave_builtin *find_builtin (const std::string& name);
769 
770  jit_function mirror_binary (const jit_function& fn);
771 
772  llvm::Function *wrap_complex (llvm::Function *wrap);
773 
774  static llvm::Value *pack_complex (llvm::IRBuilderD& bld,
775  llvm::Value *cplx);
776 
777  static llvm::Value *unpack_complex (llvm::IRBuilderD& bld,
778  llvm::Value *result);
779 
780  llvm::Value *complex_real (llvm::Value *cx);
781 
782  llvm::Value *complex_real (llvm::Value *cx, llvm::Value *real);
783 
784  llvm::Value *complex_imag (llvm::Value *cx);
785 
786  llvm::Value *complex_imag (llvm::Value *cx, llvm::Value *imag);
787 
788  llvm::Value *complex_new (llvm::Value *real, llvm::Value *imag);
789 
790  void create_int (size_t nbits);
792  jit_type *intN (size_t nbits) const;
793 
794  static jit_typeinfo *instance;
796  llvm::Module *module;
797  llvm::ExecutionEngine *engine;
798  int next_id;
800  llvm::GlobalVariable *lerror_state;
801  llvm::GlobalVariable *loctave_interrupt_state;
803  llvm::Type *sig_atomic_type;
805  std::vector<jit_type*> id_to_type;
809  jit_type *scalar_ptr; // a fake type for interfacing with C++
810  jit_type *any_ptr; // a fake type for interfacing with C++
813  jit_type *boolean;
814  jit_type *index;
815  jit_type *complex;
816  jit_type *unknown_function;
817  std::map<size_t, jit_type *> ints;
818  std::map<std::string, jit_type *> builtins;
820  llvm::StructType *complex_ret;
822  std::vector<jit_operation> binary_ops;
823  std::vector<jit_operation> unary_ops;
824  jit_operation grab_fn;
825  jit_operation release_fn;
826  jit_operation destroy_fn;
827  jit_operation print_fn;
828  jit_operation for_init_fn;
829  jit_operation for_check_fn;
830  jit_operation for_index_fn;
831  jit_operation logically_true_fn;
832  jit_operation make_range_fn;
833  jit_paren_subsref paren_subsref_fn;
834  jit_paren_subsasgn paren_subsasgn_fn;
835  jit_operation end1_fn;
837  jit_operation create_undef_fn;
838 
839  jit_function any_call;
840 
841  // type id -> cast function TO that type
842  std::vector<jit_operation> casts;
843 
844  // type id -> identity function
845  std::vector<jit_function> identities;
846 
848 };
849 
850 #endif
851 #endif
uint32_t id
Definition: graphics.cc:11587
jit_type * result(void) const
Definition: jit-typeinfo.h:295
octave_idx_type slice_len
Definition: jit-typeinfo.h:102
#define CREATE_FUNCTION(N)
Definition: jit-typeinfo.h:722
bool valid(void) const
Definition: jit-typeinfo.h:251
const std::string & name(void) const
Definition: jit-typeinfo.h:143
void update(T *aarray)
Definition: jit-typeinfo.h:88
nd group nd example oindent but is performed more efficiently If only and it is a scalar
Definition: data.cc:5342
llvm::Type * to_llvm(void) const
Definition: jit-typeinfo.h:152
bool sret(jit_convention::type cc) const
Definition: jit-typeinfo.h:167
jit_array(T &from)
Definition: jit-typeinfo.h:75
llvm::Value * to_llvm(void) const
Definition: jit-ir.h:257
octave_value do_unary_op(octave_value::unary_op op, const octave_value &v)
Definition: ov.cc:2645
llvm::Type * llvm_type
Definition: jit-typeinfo.h:202
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the then the first element defines the pivoting tolerance for the unsymmetric the values defined such that for full matrix
Definition: lu.cc:138
jit_range(const Range &from)
Definition: jit-typeinfo.h:49
Definition: Range.h:33
size_t mdepth
Definition: jit-typeinfo.h:204
std::string mname
Definition: jit-typeinfo.h:200
void set_packed_type(jit_convention::type cc, llvm::Type *ty)
Definition: jit-typeinfo.h:197
void mark_sret(jit_convention::type cc)
Definition: jit-typeinfo.h:169
std::vector< jit_type * > signature_vec
Definition: jit-typeinfo.h:324
octave_idx_type nelem
Definition: jit-typeinfo.h:63
#define JIT_CALL(N)
Definition: jit-typeinfo.h:271
convert_fn pack(jit_convention::type cc)
Definition: jit-typeinfo.h:183
static llvm::IRBuilder builder(llvm::getGlobalContext())
jit_type * parent(void) const
Definition: jit-typeinfo.h:149
i e
Definition: data.cc:2724
double base
Definition: jit-typeinfo.h:60
void mark_pointer_arg(jit_convention::type cc)
Definition: jit-typeinfo.h:177
jit_type * mparent
Definition: jit-typeinfo.h:201
JNIEnv void * args
Definition: ov-java.cc:67
void add_mapping(llvm::ExecutionEngine *engine, T fn)
Definition: jit-typeinfo.h:246
OCTAVE_EXPORT octave_value_list any number nd example oindent prints the prompt xample Pick a any number!nd example oindent and waits for the user to enter a value The string entered by the user is evaluated as an so it may be a literal a variable name
Definition: input.cc:871
bool pointer_arg(jit_convention::type cc) const
Definition: jit-typeinfo.h:175
std::map< const signature_vec *, jit_function *, signature_cmp > generated_map
Definition: jit-typeinfo.h:373
U * slice_data
Definition: jit-typeinfo.h:101
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
then the function must return scalars which will be concatenated into the return array(s).If code
Definition: cellfun.cc:398
returns the type of the matrix and caches it for future use Called with more than one argument
Definition: matrix_type.cc:120
octave_value retval
Definition: data.cc:6294
idx type
Definition: ov.cc:3129
octave_idx_type * dimensions
Definition: jit-typeinfo.h:103
may be zero for pure relative error test tem the relative tolerance must be greater than or equal to
Definition: Quad-opts.cc:233
With real return the complex result
Definition: data.cc:3375
void update(void)
Definition: jit-typeinfo.h:80
#define JIT_OVERLOAD(N)
Definition: jit-typeinfo.h:346
convert_fn unpack(jit_convention::type cc)
Definition: jit-typeinfo.h:188
int * ref_count
Definition: jit-typeinfo.h:99
T::size_type numel(const T &str)
Definition: oct-string.cc:61
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by nd tex zero divided by nd ifnottex and any operation involving another NaN value(5+NaN).Note that NaN always compares not equal to NaN(NaN!
double inc
Definition: jit-typeinfo.h:62
bool mskip_paren
Definition: jit-typeinfo.h:205
void set_pack(jit_convention::type cc, convert_fn fn)
Definition: jit-typeinfo.h:185
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:142
int type_id(void) const
Definition: jit-typeinfo.h:146
double limit
Definition: jit-typeinfo.h:61
std::ostream & jit_print(std::ostream &os, jit_type *atype)
Definition: jit-typeinfo.cc:80
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
Definition: lo-specfun.cc:1724
bool skip_paren(void) const
Definition: jit-typeinfo.h:159
std::ostream & operator<<(std::ostream &os, const jit_range &rng)
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:136
size_t depth(void) const
Definition: jit-typeinfo.h:157
static void initialize(void)
Definition: mkoctfile.cc:123
the second is matched to the second specifier and placed in the second column and so forth If there are more words than specifiers then the process is repeated until all words have been processed or the limit imposed by any(non-whitespace) text in the format that is not one of these specifiers is considered a literal.If there is a literal between two format specifiers then that same literal must appear in the input stream between the matching words.The following specifiers are valid
Definition: file-io.cc:1491
jit_array< NDArray, double > jit_matrix
Definition: jit-typeinfo.h:108
llvm::Type * packed_type(jit_convention::type cc)
Definition: jit-typeinfo.h:194
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
void set_unpack(jit_convention::type cc, convert_fn fn)
Definition: jit-typeinfo.h:190
With real arguments
Definition: data.cc:3375
OCTAVE_EXPORT octave_value_list or cell arrays Arguments are concatenated vertically The returned values are padded with blanks as needed to make each row of the string array have the same length Empty input strings are significant and will concatenated in the output For numerical each element is converted to the corresponding ASCII character A range error results if an input is outside the ASCII range(0-255).For cell arrays
const std::vector< jit_type * > & arguments(void) const
Definition: jit-typeinfo.h:303
octave_value do_binary_op(octave_value::binary_op op, const octave_value &v1, const octave_value &v2)
Definition: ov.cc:2214