Mercurial > octave-nkf
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 * |