Mercurial > octave-nkf
comparison 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 |
comparison
equal
deleted
inserted
replaced
20653:9cef0a1207e4 | 20654:b65888ec820e |
---|---|
23 // Author: Max Brister <max@2bass.com> | 23 // Author: Max Brister <max@2bass.com> |
24 | 24 |
25 #if !defined (octave_jit_typeinfo_h) | 25 #if !defined (octave_jit_typeinfo_h) |
26 #define octave_jit_typeinfo_h 1 | 26 #define octave_jit_typeinfo_h 1 |
27 | 27 |
28 #ifdef HAVE_LLVM | 28 #ifdef HAVE_JIT |
29 | 29 |
30 #include <map> | 30 #include <map> |
31 #include <vector> | 31 #include <vector> |
32 | 32 |
33 #include "Range.h" | 33 #include "Range.h" |
131 // eventually we may allow for multiple predecessors. | 131 // eventually we may allow for multiple predecessors. |
132 class | 132 class |
133 jit_type | 133 jit_type |
134 { | 134 { |
135 public: | 135 public: |
136 #ifdef HAVE_LLVM | |
136 typedef llvm::Value *(*convert_fn) (llvm::IRBuilderD&, llvm::Value *); | 137 typedef llvm::Value *(*convert_fn) (llvm::IRBuilderD&, llvm::Value *); |
137 | 138 #endif |
138 jit_type (const std::string& aname, jit_type *aparent, llvm::Type *allvm_type, | 139 |
139 bool askip_paren, int aid); | 140 jit_type (const std::string& aname, jit_type *aparent |
141 #ifdef HAVE_LLVM | |
142 , llvm::Type *allvm_type | |
143 #endif | |
144 #ifdef HAVE_GCCJIT | |
145 , gccjit::type agcc_type | |
146 #endif | |
147 , bool askip_paren, int aid); | |
140 | 148 |
141 // a user readable type name | 149 // a user readable type name |
142 const std::string& name (void) const { return mname; } | 150 const std::string& name (void) const { return mname; } |
143 | 151 |
144 // a unique id for the type | 152 // a unique id for the type |
145 int type_id (void) const { return mid; } | 153 int type_id (void) const { return mid; } |
146 | 154 |
147 // An abstract base type, may be null | 155 // An abstract base type, may be null |
148 jit_type *parent (void) const { return mparent; } | 156 jit_type *parent (void) const { return mparent; } |
149 | 157 |
158 #ifdef HAVE_LLVM | |
150 // convert to an llvm type | 159 // convert to an llvm type |
151 llvm::Type *to_llvm (void) const { return llvm_type; } | 160 llvm::Type *to_llvm (void) const { return llvm_type; } |
152 | 161 |
153 // how this type gets passed as a function argument | 162 // how this type gets passed as a function argument |
154 llvm::Type *to_llvm_arg (void) const; | 163 llvm::Type *to_llvm_arg (void) const; |
164 #endif | |
165 | |
166 #ifdef HAVE_GCCJIT | |
167 gccjit::type to_gccjit (void) const { return gccjit_type; } | |
168 #endif | |
155 | 169 |
156 size_t depth (void) const { return mdepth; } | 170 size_t depth (void) const { return mdepth; } |
157 | 171 |
158 bool skip_paren (void) const { return mskip_paren; } | 172 bool skip_paren (void) const { return mskip_paren; } |
159 | 173 |
177 { mpointer_arg[cc] = true; } | 191 { mpointer_arg[cc] = true; } |
178 | 192 |
179 // Convert into an equivalent form before calling. For example, complex is | 193 // Convert into an equivalent form before calling. For example, complex is |
180 // represented as two values llvm vector, but we need to pass it as a two | 194 // represented as two values llvm vector, but we need to pass it as a two |
181 // valued llvm structure to C functions. | 195 // valued llvm structure to C functions. |
196 #ifdef HAVE_LLVM | |
182 convert_fn pack (jit_convention::type cc) { return mpack[cc]; } | 197 convert_fn pack (jit_convention::type cc) { return mpack[cc]; } |
183 | 198 |
184 void set_pack (jit_convention::type cc, convert_fn fn) { mpack[cc] = fn; } | 199 void set_pack (jit_convention::type cc, convert_fn fn) { mpack[cc] = fn; } |
185 | 200 |
186 // The inverse operation of pack. | 201 // The inverse operation of pack. |
193 llvm::Type *packed_type (jit_convention::type cc) | 208 llvm::Type *packed_type (jit_convention::type cc) |
194 { return mpacked_type[cc]; } | 209 { return mpacked_type[cc]; } |
195 | 210 |
196 void set_packed_type (jit_convention::type cc, llvm::Type *ty) | 211 void set_packed_type (jit_convention::type cc, llvm::Type *ty) |
197 { mpacked_type[cc] = ty; } | 212 { mpacked_type[cc] = ty; } |
213 #endif | |
214 | |
198 private: | 215 private: |
199 std::string mname; | 216 std::string mname; |
200 jit_type *mparent; | 217 jit_type *mparent; |
218 #ifdef HAVE_LLVM | |
201 llvm::Type *llvm_type; | 219 llvm::Type *llvm_type; |
220 #endif | |
221 #ifdef HAVE_GCCJIT | |
222 gccjit::type gccjit_type; | |
223 #endif | |
202 int mid; | 224 int mid; |
203 size_t mdepth; | 225 size_t mdepth; |
204 bool mskip_paren; | 226 bool mskip_paren; |
205 | 227 |
206 bool msret[jit_convention::length]; | 228 bool msret[jit_convention::length]; |
207 bool mpointer_arg[jit_convention::length]; | 229 bool mpointer_arg[jit_convention::length]; |
208 | 230 |
231 #ifdef HAVE_LLVM | |
209 convert_fn mpack[jit_convention::length]; | 232 convert_fn mpack[jit_convention::length]; |
210 convert_fn munpack[jit_convention::length]; | 233 convert_fn munpack[jit_convention::length]; |
211 | 234 |
212 llvm::Type *mpacked_type[jit_convention::length]; | 235 llvm::Type *mpacked_type[jit_convention::length]; |
236 #endif | |
213 }; | 237 }; |
214 | |
215 // seperate print function to allow easy printing if type is null | 238 // seperate print function to allow easy printing if type is null |
216 std::ostream& jit_print (std::ostream& os, jit_type *atype); | 239 std::ostream& jit_print (std::ostream& os, jit_type *atype); |
217 | 240 |
218 class jit_value; | 241 class jit_value; |
219 | 242 |
225 friend std::ostream& operator << (std::ostream& os, const jit_function& fn); | 248 friend std::ostream& operator << (std::ostream& os, const jit_function& fn); |
226 public: | 249 public: |
227 // create a function in an invalid state | 250 // create a function in an invalid state |
228 jit_function (); | 251 jit_function (); |
229 | 252 |
230 jit_function (llvm::Module *amodule, jit_convention::type acall_conv, | 253 jit_function ( |
231 const llvm::Twine& aname, jit_type *aresult, | 254 #ifdef HAVE_LLVM |
255 llvm::Module *amodule, | |
256 #endif | |
257 #ifdef HAVE_GCCJIT | |
258 gccjit::context gccjit_ctxt, | |
259 #endif | |
260 jit_convention::type acall_conv, | |
261 std::string aname, | |
262 jit_type *aresult, | |
232 const std::vector<jit_type *>& aargs); | 263 const std::vector<jit_type *>& aargs); |
233 | 264 |
234 // Use an existing function, but change the argument types. The new argument | 265 // Use an existing function, but change the argument types. The new argument |
235 // types must behave the same for the current calling convention. | 266 // types must behave the same for the current calling convention. |
236 jit_function (const jit_function& fn, jit_type *aresult, | 267 jit_function (const jit_function& fn, jit_type *aresult, |
239 jit_function (const jit_function& fn); | 270 jit_function (const jit_function& fn); |
240 | 271 |
241 // erase the interal LLVM function (if it exists). Will become invalid. | 272 // erase the interal LLVM function (if it exists). Will become invalid. |
242 void erase (void); | 273 void erase (void); |
243 | 274 |
275 #ifdef HAVE_LLVM | |
244 template <typename T> | 276 template <typename T> |
245 void add_mapping (llvm::ExecutionEngine *engine, T fn) | 277 void add_mapping (llvm::ExecutionEngine *engine, T fn) |
246 { | 278 { |
247 do_add_mapping (engine, reinterpret_cast<void *> (fn)); | 279 do_add_mapping (engine, reinterpret_cast<void *> (fn)); |
248 } | 280 } |
249 | 281 |
250 bool valid (void) const { return llvm_function; } | 282 bool valid (void) const { return llvm_function; } |
283 #else | |
284 bool valid (void) const; | |
285 #endif | |
251 | 286 |
252 std::string name (void) const; | 287 std::string name (void) const; |
253 | 288 |
289 #ifdef HAVE_LLVM | |
254 llvm::BasicBlock *new_block (const std::string& aname = "body", | 290 llvm::BasicBlock *new_block (const std::string& aname = "body", |
255 llvm::BasicBlock *insert_before = 0); | 291 llvm::BasicBlock *insert_before = 0); |
256 | 292 |
257 llvm::Value *call (llvm::IRBuilderD& builder, | 293 llvm::Value *call (llvm::IRBuilderD& builder, |
258 const std::vector<jit_value *>& in_args) const; | 294 const std::vector<jit_value *>& in_args) const; |
287 | 323 |
288 void do_return (llvm::IRBuilderD& builder, llvm::Value *rval = 0, | 324 void do_return (llvm::IRBuilderD& builder, llvm::Value *rval = 0, |
289 bool verify = true); | 325 bool verify = true); |
290 | 326 |
291 llvm::Function *to_llvm (void) const { return llvm_function; } | 327 llvm::Function *to_llvm (void) const { return llvm_function; } |
328 #endif | |
329 | |
330 #ifdef HAVE_GCCJIT | |
331 gccjit::rvalue call (gccjit::context ctxt, | |
332 gccjit::block block, | |
333 const std::vector<jit_value *>& in_args) const; | |
334 gccjit::rvalue call (gccjit::context ctxt, | |
335 gccjit::block block, | |
336 std::vector<gccjit::rvalue>& in_args) const; | |
337 gccjit::lvalue argument (size_t idx) const; | |
338 #endif | |
292 | 339 |
293 // If true, then the return value is passed as a pointer in the first argument | 340 // If true, then the return value is passed as a pointer in the first argument |
294 bool sret (void) const { return mresult && mresult->sret (call_conv); } | 341 bool sret (void) const { return mresult && mresult->sret (call_conv); } |
295 | 342 |
296 bool can_error (void) const { return mcan_error; } | 343 bool can_error (void) const { return mcan_error; } |
305 return args[idx]; | 352 return args[idx]; |
306 } | 353 } |
307 | 354 |
308 const std::vector<jit_type *>& arguments (void) const { return args; } | 355 const std::vector<jit_type *>& arguments (void) const { return args; } |
309 private: | 356 private: |
357 #ifdef HAVE_LLVM | |
310 void do_add_mapping (llvm::ExecutionEngine *engine, void *fn); | 358 void do_add_mapping (llvm::ExecutionEngine *engine, void *fn); |
311 | 359 |
312 llvm::Module *module; | 360 llvm::Module *module; |
313 llvm::Function *llvm_function; | 361 llvm::Function *llvm_function; |
362 #endif | |
363 #ifdef HAVE_GCCJIT | |
364 public: | |
365 gccjit::function gccjit_function; | |
366 private: | |
367 #endif | |
314 jit_type *mresult; | 368 jit_type *mresult; |
315 std::vector<jit_type *> args; | 369 std::vector<jit_type *> args; |
316 jit_convention::type call_conv; | 370 jit_convention::type call_conv; |
317 bool mcan_error; | 371 bool mcan_error; |
318 }; | 372 }; |
387 | 441 |
388 class | 442 class |
389 jit_index_operation : public jit_operation | 443 jit_index_operation : public jit_operation |
390 { | 444 { |
391 public: | 445 public: |
392 jit_index_operation (void) : module (0), engine (0) { } | 446 jit_index_operation (void) {} //: module (0), engine (0) { } |
393 | 447 |
394 void initialize (llvm::Module *amodule, llvm::ExecutionEngine *aengine) | 448 #ifdef HAVE_LLVM |
449 void initialize (llvm::Module *amodule, llvm::ExecutionEngine *aengine | |
450 #ifdef HAVE_GCCJIT | |
451 , gccjit::context agccjit_ctxt | |
452 #endif | |
453 ) | |
454 | |
395 { | 455 { |
396 module = amodule; | 456 module = amodule; |
397 engine = aengine; | 457 engine = aengine; |
458 #ifdef HAVE_GCCJIT | |
459 gccjit_ctxt = agccjit_ctxt; | |
460 #endif | |
398 do_initialize (); | 461 do_initialize (); |
399 } | 462 } |
463 #endif | |
464 | |
400 protected: | 465 protected: |
401 virtual jit_function *generate (const signature_vec& types) const; | 466 virtual jit_function *generate (const signature_vec& types) const; |
402 | 467 |
403 virtual jit_function *generate_matrix (const signature_vec& types) const = 0; | 468 virtual jit_function *generate_matrix (const signature_vec& types) const = 0; |
404 | 469 |
405 virtual void do_initialize (void) = 0; | 470 virtual void do_initialize (void) = 0; |
406 | 471 |
407 // helper functions | 472 // helper functions |
408 // [start_idx, end_idx). | 473 // [start_idx, end_idx). |
474 #ifdef HAVE_LLVM | |
409 llvm::Value *create_arg_array (llvm::IRBuilderD& builder, | 475 llvm::Value *create_arg_array (llvm::IRBuilderD& builder, |
410 const jit_function &fn, size_t start_idx, | 476 const jit_function &fn, size_t start_idx, |
411 size_t end_idx) const; | 477 size_t end_idx) const; |
412 | 478 |
413 llvm::Module *module; | 479 llvm::Module *module; |
414 llvm::ExecutionEngine *engine; | 480 llvm::ExecutionEngine *engine; |
481 #endif | |
482 #ifdef HAVE_GCCJIT | |
483 gccjit::rvalue create_arg_array (const jit_function &fn, | |
484 gccjit::block block, | |
485 size_t start_idx, | |
486 size_t end_idx) const; | |
487 | |
488 gccjit::context gccjit_ctxt; | |
489 #endif | |
415 }; | 490 }; |
416 | 491 |
417 class | 492 class |
418 jit_paren_subsref : public jit_index_operation | 493 jit_paren_subsref : public jit_index_operation |
419 { | 494 { |
440 // jit_operations. | 515 // jit_operations. |
441 class | 516 class |
442 jit_typeinfo | 517 jit_typeinfo |
443 { | 518 { |
444 public: | 519 public: |
445 static void initialize (llvm::Module *m, llvm::ExecutionEngine *e); | 520 static void initialize ( |
521 #ifdef HAVE_LLVM | |
522 llvm::Module *m, llvm::ExecutionEngine *e | |
523 #endif | |
524 ); | |
446 | 525 |
447 static jit_type *join (jit_type *lhs, jit_type *rhs) | 526 static jit_type *join (jit_type *lhs, jit_type *rhs) |
448 { | 527 { |
449 return instance->do_join (lhs, rhs); | 528 return instance->do_join (lhs, rhs); |
450 } | 529 } |
452 static jit_type *get_any (void) { return instance->any; } | 531 static jit_type *get_any (void) { return instance->any; } |
453 | 532 |
454 static jit_type *get_matrix (void) { return instance->matrix; } | 533 static jit_type *get_matrix (void) { return instance->matrix; } |
455 | 534 |
456 static jit_type *get_scalar (void) { return instance->scalar; } | 535 static jit_type *get_scalar (void) { return instance->scalar; } |
457 | 536 #ifdef HAVE_LLVM |
458 static llvm::Type *get_scalar_llvm (void) | 537 static llvm::Type *get_scalar_llvm (void) |
459 { return instance->scalar->to_llvm (); } | 538 { return instance->scalar->to_llvm (); } |
539 #endif | |
540 #ifdef HAVE_GCCJIT | |
541 static gccjit::type get_scalar_gccjit (void) | |
542 { return instance->scalar->to_gccjit (); } | |
543 #endif | |
460 | 544 |
461 static jit_type *get_scalar_ptr (void) { return instance->scalar_ptr; } | 545 static jit_type *get_scalar_ptr (void) { return instance->scalar_ptr; } |
462 | 546 |
463 static jit_type *get_any_ptr (void) { return instance->any_ptr; } | 547 static jit_type *get_any_ptr (void) { return instance->any_ptr; } |
464 | 548 |
468 | 552 |
469 static jit_type *get_bool (void) { return instance->boolean; } | 553 static jit_type *get_bool (void) { return instance->boolean; } |
470 | 554 |
471 static jit_type *get_index (void) { return instance->index; } | 555 static jit_type *get_index (void) { return instance->index; } |
472 | 556 |
557 #ifdef HAVE_LLVM | |
473 static llvm::Type *get_index_llvm (void) | 558 static llvm::Type *get_index_llvm (void) |
474 { return instance->index->to_llvm (); } | 559 { return instance->index->to_llvm (); } |
560 #endif | |
475 | 561 |
476 static jit_type *get_complex (void) { return instance->complex; } | 562 static jit_type *get_complex (void) { return instance->complex; } |
477 | 563 |
478 // Get the jit_type of an octave_value | 564 // Get the jit_type of an octave_value |
479 static jit_type *type_of (const octave_value& ov) | 565 static jit_type *type_of (const octave_value& ov) |
561 static const jit_function& cast (jit_type *to, jit_type *from) | 647 static const jit_function& cast (jit_type *to, jit_type *from) |
562 { | 648 { |
563 return instance->do_cast (to, from); | 649 return instance->do_cast (to, from); |
564 } | 650 } |
565 | 651 |
652 #ifdef HAVE_LLVM | |
566 static llvm::Value *insert_error_check (llvm::IRBuilderD& bld) | 653 static llvm::Value *insert_error_check (llvm::IRBuilderD& bld) |
567 { | 654 { |
568 return instance->do_insert_error_check (bld); | 655 return instance->do_insert_error_check (bld); |
569 } | 656 } |
570 | 657 |
571 static llvm::Value *insert_interrupt_check (llvm::IRBuilderD& bld) | 658 static llvm::Value *insert_interrupt_check (llvm::IRBuilderD& bld) |
572 { | 659 { |
573 return instance->do_insert_interrupt_check (bld); | 660 return instance->do_insert_interrupt_check (bld); |
574 } | 661 } |
662 #endif | |
663 #ifdef HAVE_GCCJIT | |
664 static gccjit::rvalue insert_error_check (gccjit::function func) | |
665 { | |
666 return instance->do_insert_error_check (func); | |
667 } | |
668 | |
669 static gccjit::rvalue insert_interrupt_check (gccjit::function func) | |
670 { | |
671 return instance->do_insert_interrupt_check (func); | |
672 } | |
673 #endif | |
575 | 674 |
576 static const jit_operation& end (void) | 675 static const jit_operation& end (void) |
577 { | 676 { |
578 return instance->end_fn; | 677 return instance->end_fn; |
579 } | 678 } |
587 static const jit_operation& create_undef (void) | 686 static const jit_operation& create_undef (void) |
588 { | 687 { |
589 return instance->create_undef_fn; | 688 return instance->create_undef_fn; |
590 } | 689 } |
591 | 690 |
691 #ifdef HAVE_LLVM | |
592 static llvm::Value *create_complex (llvm::Value *real, llvm::Value *imag) | 692 static llvm::Value *create_complex (llvm::Value *real, llvm::Value *imag) |
593 { | 693 { |
594 return instance->complex_new (real, imag); | 694 return instance->complex_new (real, imag); |
595 } | 695 } |
696 #endif | |
697 | |
698 #ifdef HAVE_GCCJIT | |
699 static gccjit::context create_gccjit_child_context () | |
700 { | |
701 return instance->gccjit_ctxt.new_child_context (); | |
702 } | |
703 #endif | |
704 | |
705 | |
596 private: | 706 private: |
707 #ifdef HAVE_LLVM | |
597 jit_typeinfo (llvm::Module *m, llvm::ExecutionEngine *e); | 708 jit_typeinfo (llvm::Module *m, llvm::ExecutionEngine *e); |
709 #endif | |
598 | 710 |
599 // FIXME: Do these methods really need to be in jit_typeinfo? | 711 // FIXME: Do these methods really need to be in jit_typeinfo? |
600 jit_type *do_join (jit_type *lhs, jit_type *rhs) | 712 jit_type *do_join (jit_type *lhs, jit_type *rhs) |
601 { | 713 { |
602 // empty case | 714 // empty case |
666 } | 778 } |
667 | 779 |
668 const jit_function& do_end (jit_value *value, jit_value *index, | 780 const jit_function& do_end (jit_value *value, jit_value *index, |
669 jit_value *count); | 781 jit_value *count); |
670 | 782 |
671 jit_type *new_type (const std::string& name, jit_type *parent, | 783 jit_type *new_type (const std::string& name, jit_type *parent |
672 llvm::Type *llvm_type, bool skip_paren = false); | 784 #ifdef HAVE_LLVM |
673 | 785 , llvm::Type *llvm_type |
786 #endif | |
787 #ifdef HAVE_GCCJIT | |
788 , gccjit::type gccjit_type | |
789 #endif | |
790 , bool skip_paren = false); | |
674 | 791 |
675 void add_print (jit_type *ty, void *fptr); | 792 void add_print (jit_type *ty, void *fptr); |
676 | 793 |
677 void add_binary_op (jit_type *ty, int op, int llvm_op); | 794 void add_binary_op (jit_type *ty, int op |
678 | 795 , int llvm_op |
679 void add_binary_icmp (jit_type *ty, int op, int llvm_op); | 796 #ifdef HAVE_GCCJIT |
680 | 797 , enum gcc_jit_binary_op gccjit_op |
681 void add_binary_fcmp (jit_type *ty, int op, int llvm_op); | 798 #endif |
799 ); | |
800 | |
801 void add_binary_icmp (jit_type *ty, int op | |
802 , int llvm_op | |
803 #ifdef HAVE_GCCJIT | |
804 , enum gcc_jit_comparison gccjit_op | |
805 #endif | |
806 ); | |
807 | |
808 void add_binary_fcmp (jit_type *ty, int op | |
809 , int llvm_op | |
810 #ifdef HAVE_GCCJIT | |
811 , enum gcc_jit_comparison gccjit_op | |
812 #endif | |
813 ); | |
682 | 814 |
683 // create a function with an external calling convention | 815 // create a function with an external calling convention |
684 // forces the function pointer to be specified | 816 // forces the function pointer to be specified |
685 template <typename T> | 817 template <typename T> |
686 jit_function create_external (llvm::ExecutionEngine *ee, T fn, | 818 jit_function create_external ( |
687 const llvm::Twine& name, jit_type *ret, | 819 #ifdef HAVE_LLVM |
820 llvm::ExecutionEngine *ee, | |
821 #endif | |
822 T fn, | |
823 std::string name, jit_type *ret, | |
688 const std::vector<jit_type *>& args | 824 const std::vector<jit_type *>& args |
689 = std::vector<jit_type *> ()) | 825 = std::vector<jit_type *> ()) |
690 { | 826 { |
691 jit_function retval = create_function (jit_convention::external, name, ret, | 827 jit_function retval = create_function (jit_convention::external, name, ret, |
692 args); | 828 args); |
829 #ifdef HAVE_LLVM | |
693 retval.add_mapping (ee, fn); | 830 retval.add_mapping (ee, fn); |
831 #endif | |
694 return retval; | 832 return retval; |
695 } | 833 } |
696 | 834 |
835 #ifdef HAVE_LLVM | |
697 #define JIT_PARAM_ARGS llvm::ExecutionEngine *ee, T fn, \ | 836 #define JIT_PARAM_ARGS llvm::ExecutionEngine *ee, T fn, \ |
698 const llvm::Twine& name, jit_type *ret, | 837 std::string name, jit_type *ret, |
699 #define JIT_PARAMS ee, fn, name, ret, | 838 #define JIT_PARAMS ee, fn, name, ret, |
839 #else | |
840 #define JIT_PARAM_ARGS T fn, \ | |
841 std::string name, jit_type *ret, | |
842 #define JIT_PARAMS fn, name, ret, | |
843 #endif | |
700 #define CREATE_FUNCTION(N) JIT_EXPAND(template <typename T> jit_function, \ | 844 #define CREATE_FUNCTION(N) JIT_EXPAND(template <typename T> jit_function, \ |
701 create_external, \ | 845 create_external, \ |
702 jit_type *, /* empty */, N) | 846 jit_type *, /* empty */, N) |
703 | 847 |
704 CREATE_FUNCTION(1); | 848 CREATE_FUNCTION(1); |
710 #undef JIT_PARAMS | 854 #undef JIT_PARAMS |
711 #undef CREATE_FUNCTION | 855 #undef CREATE_FUNCTION |
712 | 856 |
713 // use create_external or create_internal directly | 857 // use create_external or create_internal directly |
714 jit_function create_function (jit_convention::type cc, | 858 jit_function create_function (jit_convention::type cc, |
715 const llvm::Twine& name, jit_type *ret, | 859 std::string name, jit_type *ret, |
716 const std::vector<jit_type *>& args | 860 const std::vector<jit_type *>& args |
717 = std::vector<jit_type *> ()); | 861 = std::vector<jit_type *> ()); |
718 | 862 |
719 // create an internal calling convention (a function defined in llvm) | 863 // create an internal calling convention (a function defined in llvm) |
720 jit_function create_internal (const llvm::Twine& name, jit_type *ret, | 864 jit_function create_internal (std::string name, jit_type *ret, |
721 const std::vector<jit_type *>& args | 865 const std::vector<jit_type *>& args |
722 = std::vector<jit_type *> ()) | 866 = std::vector<jit_type *> ()) |
723 { | 867 { |
724 return create_function (jit_convention::internal, name, ret, args); | 868 return create_function (jit_convention::internal, name, ret, args); |
725 } | 869 } |
726 | 870 |
727 #define JIT_PARAM_ARGS const llvm::Twine& name, jit_type *ret, | 871 #define JIT_PARAM_ARGS std::string name, jit_type *ret, |
728 #define JIT_PARAMS name, ret, | 872 #define JIT_PARAMS name, ret, |
729 #define CREATE_FUNCTION(N) JIT_EXPAND(jit_function, create_internal, \ | 873 #define CREATE_FUNCTION(N) JIT_EXPAND(jit_function, create_internal, \ |
730 jit_type *, /* empty */, N) | 874 jit_type *, /* empty */, N) |
731 | 875 |
732 CREATE_FUNCTION(1); | 876 CREATE_FUNCTION(1); |
738 #undef JIT_PARAMS | 882 #undef JIT_PARAMS |
739 #undef CREATE_FUNCTION | 883 #undef CREATE_FUNCTION |
740 | 884 |
741 jit_function create_identity (jit_type *type); | 885 jit_function create_identity (jit_type *type); |
742 | 886 |
887 #ifdef HAVE_LLVM | |
743 llvm::Value *do_insert_error_check (llvm::IRBuilderD& bld); | 888 llvm::Value *do_insert_error_check (llvm::IRBuilderD& bld); |
744 | 889 |
745 llvm::Value *do_insert_interrupt_check (llvm::IRBuilderD& bld); | 890 llvm::Value *do_insert_interrupt_check (llvm::IRBuilderD& bld); |
891 #endif | |
892 | |
893 #ifdef HAVE_GCCJIT | |
894 gccjit::rvalue do_insert_error_check (gccjit::function func); | |
895 | |
896 gccjit::rvalue do_insert_interrupt_check (gccjit::function func); | |
897 #endif | |
746 | 898 |
747 void add_builtin (const std::string& name); | 899 void add_builtin (const std::string& name); |
748 | 900 |
749 void register_intrinsic (const std::string& name, size_t id, | 901 void register_intrinsic (const std::string& name, size_t id, |
750 jit_type *result, jit_type *arg0) | 902 jit_type *result, jit_type *arg0) |
768 | 920 |
769 octave_builtin *find_builtin (const std::string& name); | 921 octave_builtin *find_builtin (const std::string& name); |
770 | 922 |
771 jit_function mirror_binary (const jit_function& fn); | 923 jit_function mirror_binary (const jit_function& fn); |
772 | 924 |
925 #ifdef HAVE_LLVM | |
773 llvm::Function *wrap_complex (llvm::Function *wrap); | 926 llvm::Function *wrap_complex (llvm::Function *wrap); |
774 | 927 |
775 static llvm::Value *pack_complex (llvm::IRBuilderD& bld, | 928 static llvm::Value *pack_complex (llvm::IRBuilderD& bld, |
776 llvm::Value *cplx); | 929 llvm::Value *cplx); |
777 | 930 |
785 llvm::Value *complex_imag (llvm::Value *cx); | 938 llvm::Value *complex_imag (llvm::Value *cx); |
786 | 939 |
787 llvm::Value *complex_imag (llvm::Value *cx, llvm::Value *imag); | 940 llvm::Value *complex_imag (llvm::Value *cx, llvm::Value *imag); |
788 | 941 |
789 llvm::Value *complex_new (llvm::Value *real, llvm::Value *imag); | 942 llvm::Value *complex_new (llvm::Value *real, llvm::Value *imag); |
943 #endif | |
944 | |
945 #ifdef HAVE_GCCJIT | |
946 gccjit::rvalue complex_real (gccjit::rvalue cx); | |
947 | |
948 gccjit::rvalue complex_real (gccjit::block block, | |
949 gccjit::lvalue cx, | |
950 gccjit::rvalue real); | |
951 | |
952 gccjit::rvalue complex_imag (gccjit::rvalue cx); | |
953 | |
954 gccjit::rvalue complex_imag (gccjit::block block, | |
955 gccjit::lvalue cx, | |
956 gccjit::rvalue imag); | |
957 | |
958 gccjit::rvalue complex_new (gccjit::block block, | |
959 gccjit::rvalue real, | |
960 gccjit::rvalue imag); | |
961 #endif | |
790 | 962 |
791 void create_int (size_t nbits); | 963 void create_int (size_t nbits); |
792 | 964 |
793 jit_type *intN (size_t nbits) const; | 965 jit_type *intN (size_t nbits) const; |
794 | 966 |
795 static jit_typeinfo *instance; | 967 static jit_typeinfo *instance; |
796 | 968 |
969 #ifdef HAVE_LLVM | |
797 llvm::Module *module; | 970 llvm::Module *module; |
798 llvm::ExecutionEngine *engine; | 971 llvm::ExecutionEngine *engine; |
972 #endif | |
799 int next_id; | 973 int next_id; |
800 | 974 |
975 #ifdef HAVE_LLVM | |
801 llvm::GlobalVariable *lerror_state; | 976 llvm::GlobalVariable *lerror_state; |
802 llvm::GlobalVariable *loctave_interrupt_state; | 977 llvm::GlobalVariable *loctave_interrupt_state; |
803 | 978 |
804 llvm::Type *sig_atomic_type; | 979 llvm::Type *sig_atomic_type; |
980 #endif | |
981 | |
982 #ifdef HAVE_GCCJIT | |
983 gccjit::rvalue error_state_gccjit; | |
984 gccjit::rvalue octave_interrupt_state_gccjit; | |
985 gccjit::type sig_atomic_type_gccjit; | |
986 #endif | |
805 | 987 |
806 std::vector<jit_type*> id_to_type; | 988 std::vector<jit_type*> id_to_type; |
807 jit_type *any; | 989 jit_type *any; |
808 jit_type *matrix; | 990 jit_type *matrix; |
991 #ifdef HAVE_GCCJIT | |
992 gccjit::field field_ref_count; | |
993 gccjit::field field_slice_data; | |
994 gccjit::field field_slice_len; | |
995 gccjit::field field_dimensions; | |
996 gccjit::field field_array; | |
997 #endif | |
809 jit_type *scalar; | 998 jit_type *scalar; |
810 jit_type *scalar_ptr; // a fake type for interfacing with C++ | 999 jit_type *scalar_ptr; // a fake type for interfacing with C++ |
811 jit_type *any_ptr; // a fake type for interfacing with C++ | 1000 jit_type *any_ptr; // a fake type for interfacing with C++ |
812 jit_type *range; | 1001 jit_type *range; |
1002 #ifdef HAVE_GCCJIT | |
1003 gccjit::field field_rng_base; | |
1004 gccjit::field field_rng_limit; | |
1005 gccjit::field field_rng_inc; | |
1006 gccjit::field field_rng_nelem; | |
1007 #endif | |
813 jit_type *string; | 1008 jit_type *string; |
814 jit_type *boolean; | 1009 jit_type *boolean; |
815 jit_type *index; | 1010 jit_type *index; |
816 jit_type *complex; | 1011 jit_type *complex; |
817 jit_type *unknown_function; | 1012 jit_type *unknown_function; |
818 std::map<size_t, jit_type *> ints; | 1013 std::map<size_t, jit_type *> ints; |
819 std::map<std::string, jit_type *> builtins; | 1014 std::map<std::string, jit_type *> builtins; |
820 | 1015 |
1016 #ifdef HAVE_LLVM | |
821 llvm::StructType *complex_ret; | 1017 llvm::StructType *complex_ret; |
1018 #endif | |
822 | 1019 |
823 std::vector<jit_operation> binary_ops; | 1020 std::vector<jit_operation> binary_ops; |
824 std::vector<jit_operation> unary_ops; | 1021 std::vector<jit_operation> unary_ops; |
825 jit_operation grab_fn; | 1022 jit_operation grab_fn; |
826 jit_operation release_fn; | 1023 jit_operation release_fn; |
843 std::vector<jit_operation> casts; | 1040 std::vector<jit_operation> casts; |
844 | 1041 |
845 // type id -> identity function | 1042 // type id -> identity function |
846 std::vector<jit_function> identities; | 1043 std::vector<jit_function> identities; |
847 | 1044 |
1045 #ifdef HAVE_LLVM | |
848 llvm::IRBuilderD& builder; | 1046 llvm::IRBuilderD& builder; |
1047 #endif | |
1048 | |
1049 #ifdef HAVE_GCCJIT | |
1050 gccjit::context gccjit_ctxt; | |
1051 #endif | |
849 }; | 1052 }; |
850 | 1053 |
851 #endif | 1054 #endif /* ifdef HAVE_JIT */ |
852 #endif | 1055 #endif |