comparison src/pt-jit.cc @ 14925:8697e3e9d77a

Properly cleanup the low level IR
author Max Brister <max@2bass.com>
date Tue, 29 May 2012 12:07:26 -0500
parents d4d9a64db6aa
children 39d52aa37a08
comparison
equal deleted inserted replaced
14924:d4d9a64db6aa 14925:8697e3e9d77a
614 { 614 {
615 return muser->parent (); 615 return muser->parent ();
616 } 616 }
617 617
618 // -------------------- jit_value -------------------- 618 // -------------------- jit_value --------------------
619 jit_value::~jit_value (void)
620 {
621 while (use_head)
622 {
623 jit_instruction *user = use_head->user ();
624 size_t idx = use_head->index ();
625 user->stash_argument (idx, 0);
626 }
627 }
628
619 #define JIT_METH(clname) \ 629 #define JIT_METH(clname) \
620 void \ 630 void \
621 jit_ ## clname::accept (jit_ir_walker& walker) \ 631 jit_ ## clname::accept (jit_ir_walker& walker) \
622 { \ 632 { \
623 walker.visit (*this); \ 633 walker.visit (*this); \
731 jit_terminator *term = terminator (); 741 jit_terminator *term = terminator ();
732 return term ? term->sucessor_count () : 0; 742 return term ? term->sucessor_count () : 0;
733 } 743 }
734 744
735 jit_phi * 745 jit_phi *
736 jit_block::search_phi (const std::string& tag_name, jit_value *adefault) 746 jit_block::search_phi (const std::string& tag_name)
737 { 747 {
738 jit_phi *ret; 748 jit_phi *ret = 0;
739 for (iterator iter = begin (); iter != end () 749 for (iterator iter = begin (); iter != end ()
740 && (ret = dynamic_cast<jit_phi *> (*iter)); ++iter) 750 && (ret = dynamic_cast<jit_phi *> (*iter)); ++iter)
741 if (ret->tag () == tag_name) 751 if (ret->tag () == tag_name)
742 return ret; 752 return ret;
743 753
744 ret = new jit_phi (pred_count (), adefault); 754 return 0;
745 ret->stash_tag (tag_name);
746 prepend (ret);
747 return ret;
748 } 755 }
749 756
750 llvm::BasicBlock * 757 llvm::BasicBlock *
751 jit_block::to_llvm (void) const 758 jit_block::to_llvm (void) const
752 { 759 {
786 // -------------------- jit_convert -------------------- 793 // -------------------- jit_convert --------------------
787 jit_convert::jit_convert (llvm::Module *module, tree &tee) 794 jit_convert::jit_convert (llvm::Module *module, tree &tee)
788 { 795 {
789 jit_instruction::reset_ids (); 796 jit_instruction::reset_ids ();
790 797
791 jit_block *entry_block = new jit_block ("body"); 798 jit_block *entry_block = create<jit_block> ("body");
792 block = entry_block; 799 block = entry_block;
793 blocks.push_back (block); 800 blocks.push_back (block);
794 801
795 toplevel_map tlevel (block); 802 toplevel_map tlevel (*this, block);
796 variables = &tlevel; 803 variables = &tlevel;
797 final_block = new jit_block ("final"); 804 final_block = create<jit_block> ("final");
798 visit (tee); 805 visit (tee);
799 806
800 blocks.push_back (final_block); 807 blocks.push_back (final_block);
801 block->append (new jit_break (final_block)); 808 block->append (create<jit_break> (final_block));
802 809
803 for (variable_map::iterator iter = variables->begin (); 810 for (variable_map::iterator iter = variables->begin ();
804 iter != variables->end (); ++iter) 811 iter != variables->end (); ++iter)
805 final_block->append (new jit_store_argument (iter->first, iter->second)); 812 final_block->append (create<jit_store_argument> (iter->first, iter->second));
806 813
807 // FIXME: Maybe we should remove dead code here? 814 // FIXME: Maybe we should remove dead code here?
808 815
809 // initialize the worklist to instructions derived from constants 816 // initialize the worklist to instructions derived from constants
810 for (std::list<jit_value *>::iterator iter = constants.begin (); 817 for (std::list<jit_value *>::iterator iter = constants.begin ();
866 std::cout << std::endl; 873 std::cout << std::endl;
867 llvm::verifyFunction (*function); 874 llvm::verifyFunction (*function);
868 } 875 }
869 } 876 }
870 877
878 jit_convert::~jit_convert (void)
879 {
880 for (std::list<jit_value *>::iterator iter = all_values.begin ();
881 iter != all_values.end (); ++iter)
882 delete *iter;
883 }
884
871 void 885 void
872 jit_convert::visit_anon_fcn_handle (tree_anon_fcn_handle&) 886 jit_convert::visit_anon_fcn_handle (tree_anon_fcn_handle&)
873 { 887 {
874 fail (); 888 fail ();
875 } 889 }
892 906
893 tree_expression *rhs = be.rhs (); 907 tree_expression *rhs = be.rhs ();
894 jit_value *rhsv = visit (rhs); 908 jit_value *rhsv = visit (rhs);
895 909
896 const jit_function& fn = jit_typeinfo::binary_op (be.op_type ()); 910 const jit_function& fn = jit_typeinfo::binary_op (be.op_type ());
897 result = block->append (new jit_call (fn, lhsv, rhsv)); 911 result = block->append (create<jit_call> (fn, lhsv, rhsv));
898 } 912 }
899 913
900 void 914 void
901 jit_convert::visit_break_command (tree_break_command&) 915 jit_convert::visit_break_command (tree_break_command&)
902 { 916 {
975 tree_identifier *lhs = dynamic_cast<tree_identifier *>(cmd.left_hand_side ()); 989 tree_identifier *lhs = dynamic_cast<tree_identifier *>(cmd.left_hand_side ());
976 if (! lhs) 990 if (! lhs)
977 fail (); 991 fail ();
978 std::string lhs_name = lhs->name (); 992 std::string lhs_name = lhs->name ();
979 993
980 jit_block *body = new jit_block ("for_body"); 994 jit_block *body = create<jit_block> ("for_body");
981 blocks.push_back (body); 995 blocks.push_back (body);
982 996
983 jit_block *tail = new jit_block ("for_tail"); 997 jit_block *tail = create<jit_block> ("for_tail");
984 unwind_protect prot_tail;
985 prot_tail.add_delete (tail); // incase we fail before adding tail to blocks
986 998
987 // do control expression, iter init, and condition check in prev_block (block) 999 // do control expression, iter init, and condition check in prev_block (block)
988 jit_value *control = visit (cmd.control_expr ()); 1000 jit_value *control = visit (cmd.control_expr ());
989 jit_call *init_iter = new jit_call (jit_typeinfo::for_init, control); 1001 jit_call *init_iter = create<jit_call> (jit_typeinfo::for_init, control);
990 init_iter->stash_tag ("#iter"); 1002 init_iter->stash_tag ("#iter");
991 block->append (init_iter); 1003 block->append (init_iter);
992 jit_value *check = block->append (new jit_call (jit_typeinfo::for_check, 1004 jit_value *check = block->append (create<jit_call> (jit_typeinfo::for_check,
993 control, init_iter)); 1005 control, init_iter));
994 block->append (new jit_cond_break (check, body, tail)); 1006 block->append (create<jit_cond_break> (check, body, tail));
995 1007
996 // we need to do iter phi manually, for_map handles the rest 1008 // we need to do iter phi manually, for_map handles the rest
997 jit_phi *iter_phi = new jit_phi (2); 1009 jit_phi *iter_phi = create<jit_phi> (2);
998 iter_phi->stash_tag ("#iter"); 1010 iter_phi->stash_tag ("#iter");
999 iter_phi->stash_argument (0, init_iter); 1011 iter_phi->stash_argument (0, init_iter);
1000 body->append (iter_phi); 1012 body->append (iter_phi);
1001 1013
1002 variable_map *merge_vars = variables; 1014 variable_map *merge_vars = variables;
1003 for_map body_vars (variables, body); 1015 for_map body_vars (variables, body);
1004 variables = &body_vars; 1016 variables = &body_vars;
1005 block = body; 1017 block = body;
1006 1018
1007 // first thing we do in the for loop is bind our index from our itertor 1019 // first thing we do in the for loop is bind our index from our itertor
1008 jit_call *idx_rhs = new jit_call (jit_typeinfo::for_index, control, iter_phi); 1020 jit_call *idx_rhs = create<jit_call> (jit_typeinfo::for_index, control, iter_phi);
1009 block->append (idx_rhs); 1021 block->append (idx_rhs);
1010 idx_rhs->stash_tag (lhs_name); 1022 idx_rhs->stash_tag (lhs_name);
1011 do_assign (lhs_name, idx_rhs, false); 1023 do_assign (lhs_name, idx_rhs, false);
1012 1024
1013 tree_statement_list *pt_body = cmd.body (); 1025 tree_statement_list *pt_body = cmd.body ();
1014 pt_body->accept (*this); 1026 pt_body->accept (*this);
1015 1027
1016 // increment iterator, check conditional, and repeat 1028 // increment iterator, check conditional, and repeat
1017 const jit_function& add_fn = jit_typeinfo::binary_op (octave_value::op_add); 1029 const jit_function& add_fn = jit_typeinfo::binary_op (octave_value::op_add);
1018 jit_call *iter_inc = new jit_call (add_fn, iter_phi, 1030 jit_call *iter_inc = create<jit_call> (add_fn, iter_phi,
1019 get_const<jit_const_index> (1)); 1031 create<jit_const_index> (1));
1020 iter_inc->stash_tag ("#iter"); 1032 iter_inc->stash_tag ("#iter");
1021 block->append (iter_inc); 1033 block->append (iter_inc);
1022 check = block->append (new jit_call (jit_typeinfo::for_check, control, 1034 check = block->append (create<jit_call> (jit_typeinfo::for_check, control,
1023 iter_inc)); 1035 iter_inc));
1024 block->append (new jit_cond_break (check, body, tail)); 1036 block->append (create<jit_cond_break> (check, body, tail));
1025 iter_phi->stash_argument (1, iter_inc); 1037 iter_phi->stash_argument (1, iter_inc);
1026 body_vars.finish_phi (*variables); 1038 body_vars.finish_phi (*variables);
1027 merge (tail, *merge_vars, block, body_vars); 1039 merge (tail, *merge_vars, block, body_vars);
1028 1040
1029 blocks.push_back (tail); 1041 blocks.push_back (tail);
1030 prot_tail.discard ();
1031 block = tail; 1042 block = tail;
1032 variables = merge_vars; 1043 variables = merge_vars;
1033 1044
1034 iter_phi = new jit_phi (2); 1045 iter_phi = create<jit_phi> (2);
1035 iter_phi->stash_tag ("#iter"); 1046 iter_phi->stash_tag ("#iter");
1036 iter_phi->stash_argument (0, init_iter); 1047 iter_phi->stash_argument (0, init_iter);
1037 iter_phi->stash_argument (1, iter_inc); 1048 iter_phi->stash_argument (1, iter_inc);
1038 block->append (iter_phi); 1049 block->append (iter_phi);
1039 block->append (new jit_call (jit_typeinfo::release, iter_phi)); 1050 block->append (create<jit_call> (jit_typeinfo::release, iter_phi));
1040 } 1051 }
1041 1052
1042 void 1053 void
1043 jit_convert::visit_complex_for_command (tree_complex_for_command&) 1054 jit_convert::visit_complex_for_command (tree_complex_for_command&)
1044 { 1055 {
1078 void 1089 void
1079 jit_convert::visit_identifier (tree_identifier& ti) 1090 jit_convert::visit_identifier (tree_identifier& ti)
1080 { 1091 {
1081 const jit_function& fn = jit_typeinfo::grab (); 1092 const jit_function& fn = jit_typeinfo::grab ();
1082 jit_value *var = variables->get (ti.name ()); 1093 jit_value *var = variables->get (ti.name ());
1083 result = block->append (new jit_call (fn, var)); 1094 result = block->append (create<jit_call> (fn, var));
1084 } 1095 }
1085 1096
1086 void 1097 void
1087 jit_convert::visit_if_clause (tree_if_clause&) 1098 jit_convert::visit_if_clause (tree_if_clause&)
1088 { 1099 {
1147 ++iter; 1158 ++iter;
1148 for (size_t i = 1; iter != lst.end (); ++iter, ++i) 1159 for (size_t i = 1; iter != lst.end (); ++iter, ++i)
1149 { 1160 {
1150 tree_if_clause *tic = *iter; 1161 tree_if_clause *tic = *iter;
1151 if (tic->is_else_clause ()) 1162 if (tic->is_else_clause ())
1152 entry_blocks[i] = new jit_block ("else"); 1163 entry_blocks[i] = create<jit_block> ("else");
1153 else 1164 else
1154 entry_blocks[i] = new jit_block ("ifelse_cond"); 1165 entry_blocks[i] = create<jit_block> ("ifelse_cond");
1155 cleanup_blocks.push_back (entry_blocks[i]); 1166 }
1156 } 1167
1157 1168 jit_block *tail = create<jit_block> ("if_tail");
1158 jit_block *tail = new jit_block ("if_tail");
1159 if (! last_else) 1169 if (! last_else)
1160 entry_blocks[entry_blocks.size () - 1] = tail; 1170 entry_blocks[entry_blocks.size () - 1] = tail;
1161 1171
1162 // actually fill out the contents of our blocks. We store the variable maps 1172 // actually fill out the contents of our blocks. We store the variable maps
1163 // at the end of each branch, this allows us to merge them in the tail 1173 // at the end of each branch, this allows us to merge them in the tail
1176 if (! tic->is_else_clause ()) 1186 if (! tic->is_else_clause ())
1177 { 1187 {
1178 tree_expression *expr = tic->condition (); 1188 tree_expression *expr = tic->condition ();
1179 jit_value *cond = visit (expr); 1189 jit_value *cond = visit (expr);
1180 1190
1181 jit_block *body = new jit_block (i == 0 ? "if_body" : "ifelse_body"); 1191 jit_block *body = create<jit_block> (i == 0 ? "if_body" : "ifelse_body");
1182 blocks.push_back (body); 1192 blocks.push_back (body);
1183 1193
1184 jit_instruction *br = new jit_cond_break (cond, body, 1194 jit_instruction *br = create<jit_cond_break> (cond, body,
1185 entry_blocks[i + 1]); 1195 entry_blocks[i + 1]);
1186 block->append (br); 1196 block->append (br);
1187 block = body; 1197 block = body;
1188 1198
1189 variables = new compound_map (variables); 1199 variables = new compound_map (variables);
1190 branch_variables[i] = variables; 1200 branch_variables[i] = variables;
1194 assert (stmt_lst); // jwe: Can this be null? 1204 assert (stmt_lst); // jwe: Can this be null?
1195 stmt_lst->accept (*this); 1205 stmt_lst->accept (*this);
1196 1206
1197 branch_variables[i] = variables; 1207 branch_variables[i] = variables;
1198 branch_blocks[i] = block; 1208 branch_blocks[i] = block;
1199 block->append (new jit_break (tail)); 1209 block->append (create<jit_break> (tail));
1200 } 1210 }
1201 1211
1202 blocks.push_back (tail); 1212 blocks.push_back (tail);
1203 1213
1204 // We create phi nodes in the tail to merge blocks 1214 // We create phi nodes in the tail to merge blocks
1247 { 1257 {
1248 octave_value v = tc.rvalue1 (); 1258 octave_value v = tc.rvalue1 ();
1249 if (v.is_real_scalar () && v.is_double_type ()) 1259 if (v.is_real_scalar () && v.is_double_type ())
1250 { 1260 {
1251 double dv = v.double_value (); 1261 double dv = v.double_value ();
1252 result = get_const<jit_const_scalar> (dv); 1262 result = create<jit_const_scalar> (dv);
1253 } 1263 }
1254 else if (v.is_range ()) 1264 else if (v.is_range ())
1255 { 1265 {
1256 Range rv = v.range_value (); 1266 Range rv = v.range_value ();
1257 result = get_const<jit_const_range> (rv); 1267 result = create<jit_const_range> (rv);
1258 } 1268 }
1259 else 1269 else
1260 fail (); 1270 fail ();
1261 } 1271 }
1262 1272
1345 else if (expr->is_identifier () && expr->print_result ()) 1355 else if (expr->is_identifier () && expr->print_result ())
1346 { 1356 {
1347 // FIXME: ugly hack, we need to come up with a way to pass 1357 // FIXME: ugly hack, we need to come up with a way to pass
1348 // nargout to visit_identifier 1358 // nargout to visit_identifier
1349 const jit_function& fn = jit_typeinfo::print_value (); 1359 const jit_function& fn = jit_typeinfo::print_value ();
1350 jit_const_string *name = get_const<jit_const_string> (expr->name ()); 1360 jit_const_string *name = create<jit_const_string> (expr->name ());
1351 block->append (new jit_call (fn, name, expr_result)); 1361 block->append (create<jit_call> (fn, name, expr_result));
1352 } 1362 }
1353 } 1363 }
1354 } 1364 }
1355 1365
1356 void 1366 void
1411 void 1421 void
1412 jit_convert::do_assign (const std::string& lhs, jit_value *rhs, bool print) 1422 jit_convert::do_assign (const std::string& lhs, jit_value *rhs, bool print)
1413 { 1423 {
1414 const jit_function& release = jit_typeinfo::release (); 1424 const jit_function& release = jit_typeinfo::release ();
1415 jit_value *current = variables->get (lhs); 1425 jit_value *current = variables->get (lhs);
1416 block->append (new jit_call (release, current)); 1426 block->append (create<jit_call> (release, current));
1417 variables->set (lhs, rhs); 1427 variables->set (lhs, rhs);
1418 1428
1419 if (print) 1429 if (print)
1420 { 1430 {
1421 const jit_function& print_fn = jit_typeinfo::print_value (); 1431 const jit_function& print_fn = jit_typeinfo::print_value ();
1422 jit_const_string *name = get_const<jit_const_string> (lhs); 1432 jit_const_string *name = create<jit_const_string> (lhs);
1423 block->append (new jit_call (print_fn, name, rhs)); 1433 block->append (create<jit_call> (print_fn, name, rhs));
1424 } 1434 }
1425 } 1435 }
1426 1436
1427 jit_value * 1437 jit_value *
1428 jit_convert::visit (tree& tee) 1438 jit_convert::visit (tree& tee)
1438 void 1448 void
1439 jit_convert::merge (jit_block *merge_block, variable_map& merge_vars, 1449 jit_convert::merge (jit_block *merge_block, variable_map& merge_vars,
1440 jit_block *incomming_block, 1450 jit_block *incomming_block,
1441 const variable_map& incomming_vars) 1451 const variable_map& incomming_vars)
1442 { 1452 {
1453 size_t pred_count = merge_block->pred_count ();
1443 size_t merge_idx = merge_block->pred_index (incomming_block); 1454 size_t merge_idx = merge_block->pred_index (incomming_block);
1444 for (variable_map::const_iterator iter = incomming_vars.begin (); 1455 for (variable_map::const_iterator iter = incomming_vars.begin ();
1445 iter != incomming_vars.end (); ++iter) 1456 iter != incomming_vars.end (); ++iter)
1446 { 1457 {
1447 const std::string& vname = iter->first; 1458 const std::string& vname = iter->first;
1451 if (merge_val != inc_val) 1462 if (merge_val != inc_val)
1452 { 1463 {
1453 jit_phi *phi = dynamic_cast<jit_phi *> (merge_val); 1464 jit_phi *phi = dynamic_cast<jit_phi *> (merge_val);
1454 if (! (phi && phi->parent () == merge_block)) 1465 if (! (phi && phi->parent () == merge_block))
1455 { 1466 {
1456 phi = merge_block->search_phi (vname, merge_val); 1467 phi = merge_block->search_phi (vname);
1468 if (! phi)
1469 {
1470 phi = create<jit_phi> (pred_count, merge_val);
1471 merge_block->prepend (phi);
1472 }
1473
1457 merge_vars.set (vname, phi); 1474 merge_vars.set (vname, phi);
1458 } 1475 }
1459 1476
1460 phi->stash_argument (merge_idx, inc_val); 1477 phi->stash_argument (merge_idx, inc_val);
1461 } 1478 }
1469 assert (pval == 0); // we have no parent 1486 assert (pval == 0); // we have no parent
1470 1487
1471 jit_block *entry = block (); 1488 jit_block *entry = block ();
1472 octave_value val = symbol_table::find (name); 1489 octave_value val = symbol_table::find (name);
1473 jit_type *type = jit_typeinfo::type_of (val); 1490 jit_type *type = jit_typeinfo::type_of (val);
1474 jit_instruction *ret = new jit_extract_argument (type, name); 1491 jit_instruction *ret = convert.create<jit_extract_argument> (type, name);
1475 return vars[name] = entry->prepend (ret); 1492 return vars[name] = entry->prepend (ret);
1476 } 1493 }
1477 1494
1478 // -------------------- jit_convert::convert_llvm -------------------- 1495 // -------------------- jit_convert::convert_llvm --------------------
1479 llvm::Function * 1496 llvm::Function *