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