Mercurial > octave-nkf
comparison libinterp/corefcn/jit-ir.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 | 1f9ed81bd173 |
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_ir_h) | 25 #if !defined (octave_jit_ir_h) |
26 #define octave_jit_ir_h 1 | 26 #define octave_jit_ir_h 1 |
27 | 27 |
28 #ifdef HAVE_LLVM | 28 #ifdef HAVE_JIT |
29 | 29 |
30 #include <list> | 30 #include <list> |
31 #include <stack> | 31 #include <stack> |
32 #include <set> | 32 #include <set> |
33 | 33 |
186 | 186 |
187 class | 187 class |
188 jit_value : public jit_internal_list<jit_value, jit_use> | 188 jit_value : public jit_internal_list<jit_value, jit_use> |
189 { | 189 { |
190 public: | 190 public: |
191 jit_value (void) : llvm_value (0), ty (0), mlast_use (0), | 191 jit_value (void) : llvm_value (0), |
192 #ifdef HAVE_GCCJIT | |
193 m_gcc_lvalue (), m_gcc_rvalue (), | |
194 #endif | |
195 ty (0), mlast_use (0), | |
192 min_worklist (false) {} | 196 min_worklist (false) {} |
193 | 197 |
194 virtual ~jit_value (void); | 198 virtual ~jit_value (void); |
195 | 199 |
196 bool in_worklist (void) const | 200 bool in_worklist (void) const |
210 // replace all uses with | 214 // replace all uses with |
211 virtual void replace_with (jit_value *value); | 215 virtual void replace_with (jit_value *value); |
212 | 216 |
213 jit_type *type (void) const { return ty; } | 217 jit_type *type (void) const { return ty; } |
214 | 218 |
219 #if HAVE_LLVM | |
215 llvm::Type *type_llvm (void) const | 220 llvm::Type *type_llvm (void) const |
216 { | 221 { |
217 return ty ? ty->to_llvm () : 0; | 222 return ty ? ty->to_llvm () : 0; |
218 } | 223 } |
224 #endif | |
225 | |
226 #if HAVE_GCCJIT | |
227 gccjit::type type_gccjit (void) const | |
228 { | |
229 return ty ? ty->to_gccjit () : gccjit::type (); | |
230 } | |
231 #endif | |
219 | 232 |
220 const std::string& type_name (void) const | 233 const std::string& type_name (void) const |
221 { | 234 { |
222 return ty->name (); | 235 return ty->name (); |
223 } | 236 } |
245 virtual std::ostream& short_print (std::ostream& os) const | 258 virtual std::ostream& short_print (std::ostream& os) const |
246 { return print (os); } | 259 { return print (os); } |
247 | 260 |
248 virtual void accept (jit_ir_walker& walker) = 0; | 261 virtual void accept (jit_ir_walker& walker) = 0; |
249 | 262 |
263 #if HAVE_LLVM | |
250 bool has_llvm (void) const | 264 bool has_llvm (void) const |
251 { | 265 { |
252 return llvm_value; | 266 return llvm_value; |
253 } | 267 } |
254 | 268 |
260 | 274 |
261 void stash_llvm (llvm::Value *compiled) | 275 void stash_llvm (llvm::Value *compiled) |
262 { | 276 { |
263 llvm_value = compiled; | 277 llvm_value = compiled; |
264 } | 278 } |
279 #endif | |
280 | |
281 #if HAVE_GCCJIT | |
282 bool has_lvalue (void) const | |
283 { | |
284 return m_gcc_lvalue.get_inner_lvalue (); | |
285 } | |
286 bool has_rvalue (void) const | |
287 { | |
288 return m_gcc_rvalue.get_inner_rvalue (); | |
289 } | |
290 gccjit::lvalue as_lvalue (void) const | |
291 { | |
292 return m_gcc_lvalue; | |
293 } | |
294 gccjit::rvalue as_rvalue (void) const | |
295 { | |
296 return m_gcc_rvalue; | |
297 } | |
298 void stash_lvalue (gccjit::lvalue lvalue) | |
299 { | |
300 m_gcc_lvalue = lvalue; | |
301 } | |
302 void stash_rvalue (gccjit::rvalue rvalue) | |
303 { | |
304 m_gcc_rvalue = rvalue; | |
305 } | |
306 #endif | |
265 | 307 |
266 protected: | 308 protected: |
267 std::ostream& print_indent (std::ostream& os, size_t indent = 0) const | 309 std::ostream& print_indent (std::ostream& os, size_t indent = 0) const |
268 { | 310 { |
269 for (size_t i = 0; i < indent * 8; ++i) | 311 for (size_t i = 0; i < indent * 8; ++i) |
270 os << " "; | 312 os << " "; |
271 return os; | 313 return os; |
272 } | 314 } |
273 | 315 |
316 #if HAVE_LLVM | |
274 llvm::Value *llvm_value; | 317 llvm::Value *llvm_value; |
318 #endif | |
319 #if HAVE_GCCJIT | |
320 gccjit::lvalue m_gcc_lvalue; | |
321 gccjit::rvalue m_gcc_rvalue; | |
322 #endif | |
275 private: | 323 private: |
276 jit_type *ty; | 324 jit_type *ty; |
277 jit_instruction *mlast_use; | 325 jit_instruction *mlast_use; |
278 bool min_worklist; | 326 bool min_worklist; |
279 }; | 327 }; |
369 jit_value *argument (size_t i) const | 417 jit_value *argument (size_t i) const |
370 { | 418 { |
371 return marguments[i].value (); | 419 return marguments[i].value (); |
372 } | 420 } |
373 | 421 |
422 #if HAVE_LLVM | |
374 llvm::Value *argument_llvm (size_t i) const | 423 llvm::Value *argument_llvm (size_t i) const |
375 { | 424 { |
376 assert (argument (i)); | 425 assert (argument (i)); |
377 return argument (i)->to_llvm (); | 426 return argument (i)->to_llvm (); |
378 } | 427 } |
428 #endif | |
379 | 429 |
380 jit_type *argument_type (size_t i) const | 430 jit_type *argument_type (size_t i) const |
381 { | 431 { |
382 return argument (i)->type (); | 432 return argument (i)->type (); |
383 } | 433 } |
384 | 434 |
435 #if HAVE_LLVM | |
385 llvm::Type *argument_type_llvm (size_t i) const | 436 llvm::Type *argument_type_llvm (size_t i) const |
386 { | 437 { |
387 assert (argument (i)); | 438 assert (argument (i)); |
388 return argument_type (i)->to_llvm (); | 439 return argument_type (i)->to_llvm (); |
389 } | 440 } |
441 #endif | |
390 | 442 |
391 std::ostream& print_argument (std::ostream& os, size_t i) const | 443 std::ostream& print_argument (std::ostream& os, size_t i) const |
392 { | 444 { |
393 if (argument (i)) | 445 if (argument (i)) |
394 return argument (i)->short_print (os); | 446 return argument (i)->short_print (os); |
450 std::list<jit_instruction *>::iterator location (void) const | 502 std::list<jit_instruction *>::iterator location (void) const |
451 { | 503 { |
452 return mlocation; | 504 return mlocation; |
453 } | 505 } |
454 | 506 |
507 #if HAVE_LLVM | |
455 llvm::BasicBlock *parent_llvm (void) const; | 508 llvm::BasicBlock *parent_llvm (void) const; |
509 #endif | |
456 | 510 |
457 void stash_parent (jit_block *aparent, | 511 void stash_parent (jit_block *aparent, |
458 std::list<jit_instruction *>::iterator alocation) | 512 std::list<jit_instruction *>::iterator alocation) |
459 { | 513 { |
460 mparent = aparent; | 514 mparent = aparent; |
492 // for use as a dummy argument during conversion to LLVM | 546 // for use as a dummy argument during conversion to LLVM |
493 class | 547 class |
494 jit_argument : public jit_value | 548 jit_argument : public jit_value |
495 { | 549 { |
496 public: | 550 public: |
497 jit_argument (jit_type *atype, llvm::Value *avalue) | 551 jit_argument (jit_type *atype/*, llvm::Value *avalue*/) |
498 { | 552 { |
499 stash_type (atype); | 553 stash_type (atype); |
500 stash_llvm (avalue); | 554 //stash_llvm (avalue); |
501 } | 555 } |
502 | 556 |
503 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | 557 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const |
504 { | 558 { |
505 print_indent (os, indent); | 559 print_indent (os, indent); |
582 // merge another block into this block, leaving the merge block empty | 636 // merge another block into this block, leaving the merge block empty |
583 void merge (jit_block& merge); | 637 void merge (jit_block& merge); |
584 | 638 |
585 const std::string& name (void) const { return mname; } | 639 const std::string& name (void) const { return mname; } |
586 | 640 |
641 std::string name_and_id (void) const | |
642 { | |
643 std::ostringstream os; | |
644 short_print (os); | |
645 return os.str (); | |
646 } | |
647 | |
587 jit_instruction *prepend (jit_instruction *instr); | 648 jit_instruction *prepend (jit_instruction *instr); |
588 | 649 |
589 jit_instruction *prepend_after_phi (jit_instruction *instr); | 650 jit_instruction *prepend_after_phi (jit_instruction *instr); |
590 | 651 |
591 template <typename T> | 652 template <typename T> |
717 else | 778 else |
718 os << "!"; | 779 os << "!"; |
719 return os; | 780 return os; |
720 } | 781 } |
721 | 782 |
783 #if HAVE_LLVM | |
722 llvm::BasicBlock *to_llvm (void) const; | 784 llvm::BasicBlock *to_llvm (void) const; |
785 #endif | |
723 | 786 |
724 std::list<jit_block *>::iterator location (void) const | 787 std::list<jit_block *>::iterator location (void) const |
725 { return mlocation; } | 788 { return mlocation; } |
726 | 789 |
727 void stash_location (std::list<jit_block *>::iterator alocation) | 790 void stash_location (std::list<jit_block *>::iterator alocation) |
973 jit_block *incomming (size_t i) const | 1036 jit_block *incomming (size_t i) const |
974 { | 1037 { |
975 return mincomming[i].value (); | 1038 return mincomming[i].value (); |
976 } | 1039 } |
977 | 1040 |
1041 #if HAVE_LLVM | |
978 llvm::BasicBlock *incomming_llvm (size_t i) const | 1042 llvm::BasicBlock *incomming_llvm (size_t i) const |
979 { | 1043 { |
980 return incomming (i)->to_llvm (); | 1044 return incomming (i)->to_llvm (); |
981 } | 1045 } |
1046 #endif | |
982 | 1047 |
983 virtual void construct_ssa (void) { } | 1048 virtual void construct_ssa (void) { } |
984 | 1049 |
985 virtual bool infer (void); | 1050 virtual bool infer (void); |
986 | 1051 |
1007 } | 1072 } |
1008 | 1073 |
1009 return os; | 1074 return os; |
1010 } | 1075 } |
1011 | 1076 |
1077 #if HAVE_LLVM | |
1012 llvm::PHINode *to_llvm (void) const; | 1078 llvm::PHINode *to_llvm (void) const; |
1079 #endif | |
1013 | 1080 |
1014 JIT_VALUE_ACCEPT; | 1081 JIT_VALUE_ACCEPT; |
1015 private: | 1082 private: |
1016 std::vector<jit_phi_incomming> mincomming; | 1083 std::vector<jit_phi_incomming> mincomming; |
1017 }; | 1084 }; |
1035 jit_block *successor (size_t idx = 0) const | 1102 jit_block *successor (size_t idx = 0) const |
1036 { | 1103 { |
1037 return static_cast<jit_block *> (argument (idx)); | 1104 return static_cast<jit_block *> (argument (idx)); |
1038 } | 1105 } |
1039 | 1106 |
1107 #if HAVE_LLVM | |
1040 llvm::BasicBlock *successor_llvm (size_t idx = 0) const | 1108 llvm::BasicBlock *successor_llvm (size_t idx = 0) const |
1041 { | 1109 { |
1042 return successor (idx)->to_llvm (); | 1110 return successor (idx)->to_llvm (); |
1043 } | 1111 } |
1112 #endif | |
1044 | 1113 |
1045 size_t successor_index (const jit_block *asuccessor) const; | 1114 size_t successor_index (const jit_block *asuccessor) const; |
1046 | 1115 |
1047 std::ostream& print_successor (std::ostream& os, size_t idx = 0) const | 1116 std::ostream& print_successor (std::ostream& os, size_t idx = 0) const |
1048 { | 1117 { |
1066 | 1135 |
1067 size_t successor_count (void) const { return malive.size (); } | 1136 size_t successor_count (void) const { return malive.size (); } |
1068 | 1137 |
1069 virtual bool infer (void); | 1138 virtual bool infer (void); |
1070 | 1139 |
1140 #if HAVE_LLVM | |
1071 llvm::TerminatorInst *to_llvm (void) const; | 1141 llvm::TerminatorInst *to_llvm (void) const; |
1142 #endif | |
1072 protected: | 1143 protected: |
1073 virtual bool check_alive (size_t) const { return true; } | 1144 virtual bool check_alive (size_t) const { return true; } |
1074 private: | 1145 private: |
1075 std::vector<bool> malive; | 1146 std::vector<bool> malive; |
1076 }; | 1147 }; |
1104 std::ostream& print_cond (std::ostream& os) const | 1175 std::ostream& print_cond (std::ostream& os) const |
1105 { | 1176 { |
1106 return cond ()->short_print (os); | 1177 return cond ()->short_print (os); |
1107 } | 1178 } |
1108 | 1179 |
1180 #if HAVE_LLVM | |
1109 llvm::Value *cond_llvm (void) const | 1181 llvm::Value *cond_llvm (void) const |
1110 { | 1182 { |
1111 return cond ()->to_llvm (); | 1183 return cond ()->to_llvm (); |
1112 } | 1184 } |
1185 #endif | |
1113 | 1186 |
1114 virtual size_t successor_count (void) const { return 2; } | 1187 virtual size_t successor_count (void) const { return 2; } |
1115 | 1188 |
1116 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | 1189 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const |
1117 { | 1190 { |
1349 jit_type *result_type (void) const | 1422 jit_type *result_type (void) const |
1350 { | 1423 { |
1351 return result ()->type (); | 1424 return result ()->type (); |
1352 } | 1425 } |
1353 | 1426 |
1427 #if HAVE_LLVM | |
1354 llvm::Value *result_llvm (void) const | 1428 llvm::Value *result_llvm (void) const |
1355 { | 1429 { |
1356 return result ()->to_llvm (); | 1430 return result ()->to_llvm (); |
1357 } | 1431 } |
1432 #endif | |
1358 | 1433 |
1359 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | 1434 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const |
1360 { | 1435 { |
1361 jit_value *res = result (); | 1436 jit_value *res = result (); |
1362 print_indent (os, indent) << "store "; | 1437 print_indent (os, indent) << "store "; |
1429 walker.visit (*this); | 1504 walker.visit (*this); |
1430 } | 1505 } |
1431 | 1506 |
1432 #undef JIT_VALUE_ACCEPT | 1507 #undef JIT_VALUE_ACCEPT |
1433 | 1508 |
1434 #endif | 1509 #endif /* ifdef HAVE_JIT */ |
1435 #endif | 1510 #endif |