comparison src/pt-jit.h @ 14935:5801e031a3b5

Place releases after last use and generalize dom visiting
author Max Brister <max@2bass.com>
date Mon, 04 Jun 2012 13:10:44 -0500
parents 1f914446157d
children 32deb562ae77
comparison
equal deleted inserted replaced
14934:4ec5f49cdfe4 14935:5801e031a3b5
161 // and code generation. 161 // and code generation.
162 class 162 class
163 jit_function 163 jit_function
164 { 164 {
165 public: 165 public:
166 struct overload 166 struct
167 overload
167 { 168 {
168 overload (void) : function (0), can_error (true), result (0) {} 169 overload (void) : function (0), can_error (true), result (0) {}
169 170
170 overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0) : 171 overload (llvm::Function *f, bool e, bool s, jit_type *r, jit_type *arg0) :
171 function (f), can_error (e), result (r), arguments (1) 172 function (f), can_error (e), side_effects (s), result (r), arguments (1)
172 { 173 {
173 arguments[0] = arg0; 174 arguments[0] = arg0;
174 } 175 }
175 176
176 overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0, 177 overload (llvm::Function *f, bool e, bool s, jit_type *r, jit_type *arg0,
177 jit_type *arg1) : function (f), can_error (e), result (r), 178 jit_type *arg1) : function (f), can_error (e), side_effects (s),
178 arguments (2) 179 result (r), arguments (2)
179 { 180 {
180 arguments[0] = arg0; 181 arguments[0] = arg0;
181 arguments[1] = arg1; 182 arguments[1] = arg1;
182 } 183 }
183 184
184 llvm::Function *function; 185 llvm::Function *function;
185 bool can_error; 186 bool can_error;
187 bool side_effects;
186 jit_type *result; 188 jit_type *result;
187 std::vector<jit_type*> arguments; 189 std::vector<jit_type*> arguments;
188 }; 190 };
189 191
190 void add_overload (const overload& func) 192 void add_overload (const overload& func)
191 { 193 {
192 add_overload (func, func.arguments); 194 add_overload (func, func.arguments);
193 } 195 }
194 196
195 void add_overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0) 197 void add_overload (llvm::Function *f, bool e, bool s, jit_type *r, jit_type *arg0)
196 { 198 {
197 overload ol (f, e, r, arg0); 199 overload ol (f, e, s, r, arg0);
198 add_overload (ol); 200 add_overload (ol);
199 } 201 }
200 202
201 void add_overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0, 203 void add_overload (llvm::Function *f, bool e, bool s, jit_type *r, jit_type *arg0,
202 jit_type *arg1) 204 jit_type *arg1)
203 { 205 {
204 overload ol (f, e, r, arg0, arg1); 206 overload ol (f, e, s, r, arg0, arg1);
205 add_overload (ol); 207 add_overload (ol);
206 } 208 }
207 209
208 void add_overload (const overload& func, 210 void add_overload (const overload& func,
209 const std::vector<jit_type*>& args); 211 const std::vector<jit_type*>& args);
289 static const jit_function& grab (void) { return instance->grab_fn; } 291 static const jit_function& grab (void) { return instance->grab_fn; }
290 292
291 static const jit_function& release (void) 293 static const jit_function& release (void)
292 { 294 {
293 return instance->release_fn; 295 return instance->release_fn;
296 }
297
298 static const jit_function::overload& get_release (jit_type *type)
299 {
300 return instance->release_fn.get_overload (type);
294 } 301 }
295 302
296 static const jit_function& print_value (void) 303 static const jit_function& print_value (void)
297 { 304 {
298 return instance->print_fn; 305 return instance->print_fn;
488 // The low level octave jit ir 495 // The low level octave jit ir
489 // this ir is close to llvm, but contains information for doing type inference. 496 // this ir is close to llvm, but contains information for doing type inference.
490 // We convert the octave parse tree to this IR directly. 497 // We convert the octave parse tree to this IR directly.
491 498
492 #define JIT_VISIT_IR_NOTEMPLATE \ 499 #define JIT_VISIT_IR_NOTEMPLATE \
493 JIT_METH(block); \ 500 JIT_METH(block) \
494 JIT_METH(break); \ 501 JIT_METH(break) \
495 JIT_METH(cond_break); \ 502 JIT_METH(cond_break) \
496 JIT_METH(call); \ 503 JIT_METH(call) \
497 JIT_METH(extract_argument); \ 504 JIT_METH(extract_argument) \
498 JIT_METH(store_argument); \ 505 JIT_METH(store_argument) \
499 JIT_METH(phi); \ 506 JIT_METH(phi) \
500 JIT_METH(variable) 507 JIT_METH(variable)
501 508
509 #define JIT_VISIT_IR_CONST \
510 JIT_METH(const_scalar) \
511 JIT_METH(const_index) \
512 JIT_METH(const_string) \
513 JIT_METH(const_range)
514
515 #define JIT_VISIT_IR_ABSTRACT \
516 JIT_METH(instruction) \
517 JIT_METH(terminator)
518
502 #define JIT_VISIT_IR_CLASSES \ 519 #define JIT_VISIT_IR_CLASSES \
503 JIT_VISIT_IR_NOTEMPLATE; \ 520 JIT_VISIT_IR_NOTEMPLATE \
504 JIT_VISIT_IR_CONST 521 JIT_VISIT_IR_CONST
505 522
523 #define JIT_VISIT_IR_ALL \
524 JIT_VISIT_IR_CLASSES \
525 JIT_VISIT_IR_ABSTRACT
526
527 // forward declare all ir classes
528 #define JIT_METH(cname) \
529 class jit_ ## cname;
530
531 JIT_VISIT_IR_ABSTRACT
532 JIT_VISIT_IR_NOTEMPLATE
533
534 #undef JIT_METH
535
536 // constants are typedefs from jit_const
537 template <typename T, jit_type *(*EXTRACT_T)(void), typename PASS_T = T,
538 bool QUOTE=false>
539 class jit_const;
540
541 typedef jit_const<double, jit_typeinfo::get_scalar> jit_const_scalar;
542 typedef jit_const<octave_idx_type, jit_typeinfo::get_index> jit_const_index;
543
544 typedef jit_const<std::string, jit_typeinfo::get_string, const std::string&, true>
545 jit_const_string;
546 typedef jit_const<jit_range, jit_typeinfo::get_range, const jit_range&>
547 jit_const_range;
506 548
507 class jit_ir_walker; 549 class jit_ir_walker;
508 class jit_use; 550 class jit_use;
509 551
510 class 552 class
564 606
565 void stash_llvm (llvm::Value *compiled) 607 void stash_llvm (llvm::Value *compiled)
566 { 608 {
567 llvm_value = compiled; 609 llvm_value = compiled;
568 } 610 }
611
612 #define JIT_METH(cname) \
613 virtual bool is_ ## cname (void) const \
614 { return false; } \
615 \
616 virtual jit_ ## cname *to_ ## cname (void) \
617 { return 0; } \
618 \
619 virtual const jit_ ## cname *to_ ## cname (void) const \
620 { return 0; }
621
622 JIT_VISIT_IR_NOTEMPLATE
623 JIT_VISIT_IR_ABSTRACT
624
625 #undef JIT_METH
626
569 protected: 627 protected:
570 std::ostream& print_indent (std::ostream& os, size_t indent) const 628 std::ostream& print_indent (std::ostream& os, size_t indent) const
571 { 629 {
572 for (size_t i = 0; i < indent * 8; ++i) 630 for (size_t i = 0; i < indent * 8; ++i)
573 os << " "; 631 os << " ";
581 size_t myuse_count; 639 size_t myuse_count;
582 }; 640 };
583 641
584 std::ostream& operator<< (std::ostream& os, const jit_value& value); 642 std::ostream& operator<< (std::ostream& os, const jit_value& value);
585 643
586 class jit_instruction; 644 #define JIT_GEN_CASTS(cname) \
587 class jit_block; 645 virtual bool is_ ## cname (void) const \
646 { return true; } \
647 \
648 virtual jit_ ## cname *to_ ## cname (void) \
649 { return this; } \
650 \
651 virtual const jit_ ## cname *to_ ## cname (void) const \
652 { return this; }
588 653
589 class 654 class
590 jit_use 655 jit_use
591 { 656 {
592 public: 657 public:
612 size_t index (void) const { return mindex; } 677 size_t index (void) const { return mindex; }
613 678
614 jit_instruction *user (void) const { return muser; } 679 jit_instruction *user (void) const { return muser; }
615 680
616 jit_block *user_parent (void) const; 681 jit_block *user_parent (void) const;
682
683 std::list<jit_block *> user_parent_location (void) const;
617 684
618 void stash_value (jit_value *avalue, jit_instruction *auser = 0, 685 void stash_value (jit_value *avalue, jit_instruction *auser = 0,
619 size_t aindex = -1) 686 size_t aindex = -1)
620 { 687 {
621 remove (); 688 remove ();
666 jit_use *mprev; 733 jit_use *mprev;
667 jit_instruction *muser; 734 jit_instruction *muser;
668 size_t mindex; 735 size_t mindex;
669 }; 736 };
670 737
671 class jit_variable;
672
673 class 738 class
674 jit_instruction : public jit_value 739 jit_instruction : public jit_value
675 { 740 {
676 public: 741 public:
677 // FIXME: this code could be so much pretier with varadic templates... 742 // FIXME: this code could be so much pretier with varadic templates...
735 llvm::Type *argument_type_llvm (size_t i) const 800 llvm::Type *argument_type_llvm (size_t i) const
736 { 801 {
737 assert (argument (i)); 802 assert (argument (i));
738 return argument_type (i)->to_llvm (); 803 return argument_type (i)->to_llvm ();
739 } 804 }
805
806 // generate functions of form argument_type where type is any subclass of
807 // jit_value
808 #define JIT_METH(cname) \
809 jit_ ## cname *argument_ ## cname (size_t i) const \
810 { \
811 jit_value *arg = argument (i); \
812 return arg ? arg->to_ ## cname () : 0; \
813 }
814
815 JIT_VISIT_IR_ABSTRACT
816 JIT_VISIT_IR_NOTEMPLATE
817
818 #undef JIT_METH
740 819
741 std::ostream& print_argument (std::ostream& os, size_t i) const 820 std::ostream& print_argument (std::ostream& os, size_t i) const
742 { 821 {
743 if (argument (i)) 822 if (argument (i))
744 return argument (i)->short_print (os); 823 return argument (i)->short_print (os);
768 847
769 // argument types which have been infered already 848 // argument types which have been infered already
770 const std::vector<jit_type *>& argument_types (void) const 849 const std::vector<jit_type *>& argument_types (void) const
771 { return already_infered; } 850 { return already_infered; }
772 851
852 virtual bool dead (void) const { return false; }
853
854 virtual bool almost_dead (void) const { return false; }
855
773 virtual bool infer (void) { return false; } 856 virtual bool infer (void) { return false; }
774 857
858 void remove (void);
859
775 void push_variable (void); 860 void push_variable (void);
776 861
777 void pop_variable (void); 862 void pop_variable (void);
778 863
779 virtual std::ostream& short_print (std::ostream& os) const; 864 virtual std::ostream& short_print (std::ostream& os) const;
780 865
781 jit_block *parent (void) const { return mparent; } 866 jit_block *parent (void) const { return mparent; }
782 867
868 std::list<jit_instruction *>::iterator location (void) const
869 {
870 return mlocation;
871 }
872
783 llvm::BasicBlock *parent_llvm (void) const; 873 llvm::BasicBlock *parent_llvm (void) const;
784 874
785 void stash_parent (jit_block *aparent) 875 void stash_parent (jit_block *aparent,
786 { 876 std::list<jit_instruction *>::iterator alocation)
787 assert (! mparent); 877 {
788 mparent = aparent; 878 mparent = aparent;
879 mlocation = alocation;
789 } 880 }
790 881
791 jit_variable *tag (void) const; 882 jit_variable *tag (void) const;
792 883
793 void stash_tag (jit_variable *atag); 884 void stash_tag (jit_variable *atag);
885
886 JIT_GEN_CASTS (instruction)
794 protected: 887 protected:
795 std::vector<jit_type *> already_infered; 888 std::vector<jit_type *> already_infered;
796 private: 889 private:
797 static size_t next_id (bool reset = false) 890 static size_t next_id (bool reset = false)
798 { 891 {
807 900
808 jit_use mtag; 901 jit_use mtag;
809 902
810 size_t id; 903 size_t id;
811 jit_block *mparent; 904 jit_block *mparent;
905 std::list<jit_instruction *>::iterator mlocation;
812 }; 906 };
813 907
814 // defnie accept methods for subclasses 908 // defnie accept methods for subclasses
815 #define JIT_VALUE_ACCEPT(clname) \ 909 #define JIT_VALUE_ACCEPT(clname) \
816 virtual void accept (jit_ir_walker& walker); 910 virtual void accept (jit_ir_walker& walker);
817 911
818 template <typename T, jit_type *(*EXTRACT_T)(void), typename PASS_T = T, 912 template <typename T, jit_type *(*EXTRACT_T)(void), typename PASS_T,
819 bool QUOTE=false> 913 bool QUOTE>
820 class 914 class
821 jit_const : public jit_instruction 915 jit_const : public jit_instruction
822 { 916 {
823 public: 917 public:
824 typedef PASS_T pass_t; 918 typedef PASS_T pass_t;
845 JIT_VALUE_ACCEPT (jit_const); 939 JIT_VALUE_ACCEPT (jit_const);
846 private: 940 private:
847 T mvalue; 941 T mvalue;
848 }; 942 };
849 943
850 typedef jit_const<double, jit_typeinfo::get_scalar> jit_const_scalar;
851 typedef jit_const<octave_idx_type, jit_typeinfo::get_index> jit_const_index;
852
853 typedef jit_const<std::string, jit_typeinfo::get_string, const std::string&, true>
854 jit_const_string;
855 typedef jit_const<jit_range, jit_typeinfo::get_range, const jit_range&>
856 jit_const_range;
857
858 #define JIT_VISIT_IR_CONST \
859 JIT_METH(const_scalar); \
860 JIT_METH(const_index); \
861 JIT_METH(const_string); \
862 JIT_METH(const_range)
863
864 class jit_terminator;
865 class jit_phi;
866 class jit_convert;
867
868 class 944 class
869 jit_block : public jit_value 945 jit_block : public jit_value
870 { 946 {
871 public: 947 public:
872 typedef std::list<jit_instruction *> instruction_list; 948 typedef std::list<jit_instruction *> instruction_list;
882 958
883 const std::string& name (void) const { return mname; } 959 const std::string& name (void) const { return mname; }
884 960
885 jit_instruction *prepend (jit_instruction *instr); 961 jit_instruction *prepend (jit_instruction *instr);
886 962
963 jit_instruction *prepend_after_phi (jit_instruction *instr);
964
887 jit_instruction *append (jit_instruction *instr); 965 jit_instruction *append (jit_instruction *instr);
888 966
889 jit_instruction *insert_before (iterator loc, jit_instruction *instr); 967 jit_instruction *insert_before (iterator loc, jit_instruction *instr);
890 968
891 jit_instruction *insert_after (iterator loc, jit_instruction *instr); 969 jit_instruction *insert_after (iterator loc, jit_instruction *instr);
892 970
893 void remove (jit_block::iterator iter) 971 void remove (jit_block::iterator iter)
894 { 972 {
973 jit_instruction *instr = *iter;
895 instructions.erase (iter); 974 instructions.erase (iter);
975 instr->stash_parent (0, instructions.end ());
896 } 976 }
897 977
898 jit_terminator *terminator (void) const; 978 jit_terminator *terminator (void) const;
899 979
900 jit_block *pred (size_t idx) const; 980 jit_block *pred (size_t idx) const;
999 void create_dom_tree (void) 1079 void create_dom_tree (void)
1000 { 1080 {
1001 create_dom_tree (mvisit_count); 1081 create_dom_tree (mvisit_count);
1002 } 1082 }
1003 1083
1004 void construct_ssa (jit_convert& convert) 1084 // visit blocks in the order of the dominator tree
1005 { 1085 // inorder - Run on the root first, then children
1006 do_construct_ssa (convert, mvisit_count); 1086 // postorder - Run on children first, then the root
1007 } 1087 template <typename func_type0, typename func_type1>
1088 void visit_dom (func_type0 inorder, func_type1 postorder)
1089 {
1090 do_visit_dom (mvisit_count, inorder, postorder);
1091 }
1092
1093 // call pop_varaible on all instructions
1094 void pop_all (void);
1008 1095
1009 virtual std::ostream& print (std::ostream& os, size_t indent) const 1096 virtual std::ostream& print (std::ostream& os, size_t indent) const
1010 { 1097 {
1011 print_indent (os, indent) << mname << ": %pred = "; 1098 print_indent (os, indent) << mname << ": %pred = ";
1012 for (size_t i = 0; i < pred_count (); ++i) 1099 for (size_t i = 0; i < pred_count (); ++i)
1034 } 1121 }
1035 1122
1036 llvm::BasicBlock *to_llvm (void) const; 1123 llvm::BasicBlock *to_llvm (void) const;
1037 1124
1038 JIT_VALUE_ACCEPT (block) 1125 JIT_VALUE_ACCEPT (block)
1126 JIT_GEN_CASTS (block)
1039 private: 1127 private:
1040 void compute_df (size_t visit_count); 1128 void compute_df (size_t visit_count);
1041 1129
1042 bool update_idom (size_t visit_count); 1130 bool update_idom (size_t visit_count);
1043 1131
1044 void finish_phi (jit_block *pred);
1045
1046 void do_construct_ssa (jit_convert& convert, size_t visit_count);
1047
1048 void create_dom_tree (size_t visit_count); 1132 void create_dom_tree (size_t visit_count);
1049 1133
1050 jit_block *idom_intersect (jit_block *b); 1134 jit_block *idom_intersect (jit_block *b);
1135
1136 template <typename func_type0, typename func_type1>
1137 void do_visit_dom (size_t visit_count, func_type0 inorder, func_type1 postorder);
1051 1138
1052 static const size_t NO_ID = static_cast<size_t> (-1); 1139 static const size_t NO_ID = static_cast<size_t> (-1);
1053 size_t mvisit_count; 1140 size_t mvisit_count;
1054 size_t mid; 1141 size_t mid;
1055 jit_block *idom; 1142 jit_block *idom;
1058 std::string mname; 1145 std::string mname;
1059 instruction_list instructions; 1146 instruction_list instructions;
1060 mutable std::vector<llvm::BasicBlock *> mpred_llvm; 1147 mutable std::vector<llvm::BasicBlock *> mpred_llvm;
1061 }; 1148 };
1062 1149
1150 // allow regular function pointers as well as pointers to members
1151 template <typename func_type>
1152 class jit_block_callback
1153 {
1154 public:
1155 jit_block_callback (func_type afunction) : function (afunction) {}
1156
1157 void operator() (jit_block& block)
1158 {
1159 function (block);
1160 }
1161 private:
1162 func_type function;
1163 };
1164
1165 template <>
1166 class jit_block_callback<void (jit_block::*)(void)>
1167 {
1168 public:
1169 typedef void (jit_block::*func_type)(void);
1170
1171 jit_block_callback (func_type afunction) : function (afunction) {}
1172
1173 void operator() (jit_block& ablock)
1174 {
1175 (ablock.*function) ();
1176 }
1177 private:
1178 func_type function;
1179 };
1180
1181 template <typename func_type0, typename func_type1>
1182 void
1183 jit_block::do_visit_dom (size_t visit_count, func_type0 inorder, func_type1 postorder)
1184 {
1185 if (mvisit_count > visit_count)
1186 return;
1187 mvisit_count = visit_count + 1;
1188
1189 jit_block_callback<func_type0> inorder_cb (inorder);
1190 inorder_cb (*this);
1191
1192 for (size_t i = 0; i < dom_succ.size (); ++i)
1193 dom_succ[i]->do_visit_dom (visit_count, inorder, postorder);
1194
1195 jit_block_callback<func_type1> postorder_cb (postorder);
1196 postorder_cb (*this);
1197 }
1063 1198
1064 1199
1065 // A non-ssa variable 1200 // A non-ssa variable
1066 class 1201 class
1067 jit_variable : public jit_value 1202 jit_variable : public jit_value
1068 { 1203 {
1069 public: 1204 public:
1070 jit_variable (const std::string& aname) : mname (aname) {} 1205 jit_variable (const std::string& aname) : mname (aname), mlast_use (0) {}
1071 1206
1072 const std::string &name (void) const { return mname; } 1207 const std::string &name (void) const { return mname; }
1073 1208
1074 // manipulate the value_stack, for use during SSA construction. The top of the 1209 // manipulate the value_stack, for use during SSA construction. The top of the
1075 // value stack represents the current value for this variable 1210 // value stack represents the current value for this variable
1081 jit_value *top (void) const 1216 jit_value *top (void) const
1082 { 1217 {
1083 return value_stack.top (); 1218 return value_stack.top ();
1084 } 1219 }
1085 1220
1086 void push (jit_value *v) 1221 void push (jit_instruction *v)
1087 { 1222 {
1088 value_stack.push (v); 1223 value_stack.push (v);
1224 mlast_use = v;
1089 } 1225 }
1090 1226
1091 void pop (void) 1227 void pop (void)
1092 { 1228 {
1093 value_stack.pop (); 1229 value_stack.pop ();
1230 }
1231
1232 jit_instruction *last_use (void) const
1233 {
1234 return mlast_use;
1235 }
1236
1237 void stash_last_use (jit_instruction *instr)
1238 {
1239 mlast_use = instr;
1094 } 1240 }
1095 1241
1096 // blocks in which we are used 1242 // blocks in which we are used
1097 void use_blocks (jit_block::df_set& result) 1243 void use_blocks (jit_block::df_set& result)
1098 { 1244 {
1108 { 1254 {
1109 return print_indent (os, indent) << mname; 1255 return print_indent (os, indent) << mname;
1110 } 1256 }
1111 1257
1112 JIT_VALUE_ACCEPT (variable) 1258 JIT_VALUE_ACCEPT (variable)
1259 JIT_GEN_CASTS (variable)
1113 private: 1260 private:
1114 std::string mname; 1261 std::string mname;
1115 std::stack<jit_value *> value_stack; 1262 std::stack<jit_value *> value_stack;
1263 jit_instruction *mlast_use;
1116 }; 1264 };
1117 1265
1118 class 1266 class
1119 jit_phi : public jit_instruction 1267 jit_phi : public jit_instruction
1120 { 1268 {
1121 public: 1269 public:
1122 jit_phi (jit_variable *avariable, size_t npred) 1270 jit_phi (jit_variable *avariable, size_t npred)
1123 : jit_instruction (npred) 1271 : jit_instruction (npred)
1124 { 1272 {
1125 stash_tag (avariable); 1273 stash_tag (avariable);
1274 }
1275
1276 virtual bool dead (void) const
1277 {
1278 return use_count () == 0;
1279 }
1280
1281 virtual bool almost_dead (void) const
1282 {
1283 return use_count () <= 1;
1126 } 1284 }
1127 1285
1128 virtual bool infer (void) 1286 virtual bool infer (void)
1129 { 1287 {
1130 jit_type *infered = 0; 1288 jit_type *infered = 0;
1165 1323
1166 return os; 1324 return os;
1167 } 1325 }
1168 1326
1169 JIT_VALUE_ACCEPT (phi); 1327 JIT_VALUE_ACCEPT (phi);
1328 JIT_GEN_CASTS (phi)
1170 }; 1329 };
1171 1330
1172 class 1331 class
1173 jit_terminator : public jit_instruction 1332 jit_terminator : public jit_instruction
1174 { 1333 {
1195 { 1354 {
1196 return sucessor (idx)->short_print (os); 1355 return sucessor (idx)->short_print (os);
1197 } 1356 }
1198 1357
1199 virtual size_t sucessor_count (void) const = 0; 1358 virtual size_t sucessor_count (void) const = 0;
1359
1360 JIT_GEN_CASTS (terminator)
1200 }; 1361 };
1201 1362
1202 class 1363 class
1203 jit_break : public jit_terminator 1364 jit_break : public jit_terminator
1204 { 1365 {
1218 print_indent (os, indent) << "break: "; 1379 print_indent (os, indent) << "break: ";
1219 return print_sucessor (os); 1380 return print_sucessor (os);
1220 } 1381 }
1221 1382
1222 JIT_VALUE_ACCEPT (break) 1383 JIT_VALUE_ACCEPT (break)
1384 JIT_GEN_CASTS (break)
1223 }; 1385 };
1224 1386
1225 class 1387 class
1226 jit_cond_break : public jit_terminator 1388 jit_cond_break : public jit_terminator
1227 { 1389 {
1256 print_sucessor (os, 0) << ", "; 1418 print_sucessor (os, 0) << ", ";
1257 return print_sucessor (os, 1); 1419 return print_sucessor (os, 1);
1258 } 1420 }
1259 1421
1260 JIT_VALUE_ACCEPT (cond_break) 1422 JIT_VALUE_ACCEPT (cond_break)
1423 JIT_GEN_CASTS (cond_break)
1261 }; 1424 };
1262 1425
1263 class 1426 class
1264 jit_call : public jit_instruction 1427 jit_call : public jit_instruction
1265 { 1428 {
1277 jit_call (const jit_function& (*afunction) (void), 1440 jit_call (const jit_function& (*afunction) (void),
1278 jit_value *arg0, jit_value *arg1) : jit_instruction (arg0, arg1), 1441 jit_value *arg0, jit_value *arg1) : jit_instruction (arg0, arg1),
1279 mfunction (afunction ()) {} 1442 mfunction (afunction ()) {}
1280 1443
1281 const jit_function& function (void) const { return mfunction; } 1444 const jit_function& function (void) const { return mfunction; }
1445
1446 bool has_side_effects (void) const
1447 {
1448 return overload ().side_effects;
1449 }
1282 1450
1283 const jit_function::overload& overload (void) const 1451 const jit_function::overload& overload (void) const
1284 { 1452 {
1285 return mfunction.get_overload (argument_types ()); 1453 return mfunction.get_overload (argument_types ());
1286 } 1454 }
1300 os << ", "; 1468 os << ", ";
1301 } 1469 }
1302 return os << ")"; 1470 return os << ")";
1303 } 1471 }
1304 1472
1473 virtual bool dead (void) const;
1474
1475 virtual bool almost_dead (void) const;
1476
1305 virtual bool infer (void); 1477 virtual bool infer (void);
1306 1478
1307 JIT_VALUE_ACCEPT (call) 1479 JIT_VALUE_ACCEPT (call)
1480 JIT_GEN_CASTS (call)
1308 private: 1481 private:
1309 const jit_function& mfunction; 1482 const jit_function& mfunction;
1310 }; 1483 };
1311 1484
1312 class 1485 class
1337 short_print (os); 1510 short_print (os);
1338 return os; 1511 return os;
1339 } 1512 }
1340 1513
1341 JIT_VALUE_ACCEPT (extract_argument) 1514 JIT_VALUE_ACCEPT (extract_argument)
1515 JIT_GEN_CASTS (extract_argument)
1342 }; 1516 };
1343 1517
1344 class 1518 class
1345 jit_store_argument : public jit_instruction 1519 jit_store_argument : public jit_instruction
1346 { 1520 {
1383 short_print (os) << " = "; 1557 short_print (os) << " = ";
1384 return res->short_print (os); 1558 return res->short_print (os);
1385 } 1559 }
1386 1560
1387 JIT_VALUE_ACCEPT (store_argument) 1561 JIT_VALUE_ACCEPT (store_argument)
1562 JIT_GEN_CASTS (store_argument)
1388 }; 1563 };
1389 1564
1390 class 1565 class
1391 jit_ir_walker 1566 jit_ir_walker
1392 { 1567 {
1393 public: 1568 public:
1394 virtual ~jit_ir_walker () {} 1569 virtual ~jit_ir_walker () {}
1395 1570
1396 #define JIT_METH(clname) \ 1571 #define JIT_METH(clname) \
1397 virtual void visit (jit_ ## clname&) = 0 1572 virtual void visit (jit_ ## clname&) = 0;
1398 1573
1399 JIT_VISIT_IR_CLASSES; 1574 JIT_VISIT_IR_CLASSES;
1400 1575
1401 #undef JIT_METH 1576 #undef JIT_METH
1402 }; 1577 };
1546 T *ret = new T(arg0, arg1, arg2); 1721 T *ret = new T(arg0, arg1, arg2);
1547 track_value (ret); 1722 track_value (ret);
1548 return ret; 1723 return ret;
1549 } 1724 }
1550 private: 1725 private:
1726 typedef std::list<jit_block *> block_list;
1727 typedef block_list::iterator block_iterator;
1728
1551 std::vector<std::pair<std::string, bool> > arguments; 1729 std::vector<std::pair<std::string, bool> > arguments;
1552 type_bound_vector bounds; 1730 type_bound_vector bounds;
1553 1731
1554 // used instead of return values from visit_* functions 1732 // used instead of return values from visit_* functions
1555 jit_instruction *result; 1733 jit_instruction *result;
1594 constants.push_back (value); 1772 constants.push_back (value);
1595 all_values.push_back (value); 1773 all_values.push_back (value);
1596 } 1774 }
1597 1775
1598 void construct_ssa (jit_block *final_block); 1776 void construct_ssa (jit_block *final_block);
1777
1778 static void do_construct_ssa (jit_block& block);
1779
1780 void place_releases (void);
1599 1781
1600 void print_blocks (const std::string& header) 1782 void print_blocks (const std::string& header)
1601 { 1783 {
1602 std::cout << "-------------------- " << header << " --------------------\n"; 1784 std::cout << "-------------------- " << header << " --------------------\n";
1603 for (std::list<jit_block *>::iterator iter = blocks.begin (); 1785 for (std::list<jit_block *>::iterator iter = blocks.begin ();
1619 (*iter)->print_dom (std::cout); 1801 (*iter)->print_dom (std::cout);
1620 } 1802 }
1621 std::cout << std::endl; 1803 std::cout << std::endl;
1622 } 1804 }
1623 1805
1624 typedef std::list<jit_block *> break_list;
1625
1626 bool breaking; // true if we are breaking OR continuing 1806 bool breaking; // true if we are breaking OR continuing
1627 break_list breaks; 1807 block_list breaks;
1628 break_list continues; 1808 block_list continues;
1629 1809
1630 void finish_breaks (jit_block *dest, const break_list& lst); 1810 void finish_breaks (jit_block *dest, const block_list& lst);
1811
1812 struct release_placer
1813 {
1814 release_placer (jit_convert& aconvert) : convert (aconvert) {}
1815
1816 jit_convert& convert;
1817
1818 void operator() (jit_block& block);
1819 };
1631 1820
1632 // this case is much simpler, just convert from the jit ir to llvm 1821 // this case is much simpler, just convert from the jit ir to llvm
1633 class 1822 class
1634 convert_llvm : public jit_ir_walker 1823 convert_llvm : public jit_ir_walker
1635 { 1824 {
1646 #undef JIT_METH 1835 #undef JIT_METH
1647 private: 1836 private:
1648 // name -> llvm argument 1837 // name -> llvm argument
1649 std::map<std::string, llvm::Value *> arguments; 1838 std::map<std::string, llvm::Value *> arguments;
1650 1839
1840 void finish_phi (jit_instruction *phi);
1651 1841
1652 void visit (jit_value *jvalue) 1842 void visit (jit_value *jvalue)
1653 { 1843 {
1654 return visit (*jvalue); 1844 return visit (*jvalue);
1655 } 1845 }