comparison src/pt-jit.cc @ 14928:39d52aa37a08

Use standard SSA construction algorithm, and support break/continue
author Max Brister <max@2bass.com>
date Fri, 01 Jun 2012 19:08:43 -0500
parents 8697e3e9d77a
children 1f914446157d
comparison
equal deleted inserted replaced
14927:3b40dbc14572 14928:39d52aa37a08
88 fail (const std::string& reason) 88 fail (const std::string& reason)
89 { 89 {
90 throw jit_fail_exception (reason); 90 throw jit_fail_exception (reason);
91 } 91 }
92 92
93 std::ostream& jit_print (std::ostream& os, jit_type *atype)
94 {
95 if (! atype)
96 return os << "null";
97 return os << atype->name ();
98 }
99
93 // function that jit code calls 100 // function that jit code calls
94 extern "C" void 101 extern "C" void
95 octave_jit_print_any (const char *name, octave_base_value *obv) 102 octave_jit_print_any (const char *name, octave_base_value *obv)
96 { 103 {
97 obv->print_with_name (octave_stdout, name, true); 104 obv->print_with_name (octave_stdout, name, true);
616 } 623 }
617 624
618 // -------------------- jit_value -------------------- 625 // -------------------- jit_value --------------------
619 jit_value::~jit_value (void) 626 jit_value::~jit_value (void)
620 { 627 {
628 replace_with (0);
629 }
630
631 void
632 jit_value::replace_with (jit_value *value)
633 {
621 while (use_head) 634 while (use_head)
622 { 635 {
623 jit_instruction *user = use_head->user (); 636 jit_instruction *user = use_head->user ();
624 size_t idx = use_head->index (); 637 size_t idx = use_head->index ();
625 user->stash_argument (idx, 0); 638 if (idx < user->argument_count ())
639 user->stash_argument (idx, value);
640 else
641 user->stash_tag (0);
626 } 642 }
627 } 643 }
628 644
629 #define JIT_METH(clname) \ 645 #define JIT_METH(clname) \
630 void \ 646 void \
634 } 650 }
635 651
636 JIT_VISIT_IR_NOTEMPLATE 652 JIT_VISIT_IR_NOTEMPLATE
637 #undef JIT_METH 653 #undef JIT_METH
638 654
655 std::ostream&
656 operator<< (std::ostream& os, const jit_value& value)
657 {
658 return value.short_print (os);
659 }
660
639 // -------------------- jit_instruction -------------------- 661 // -------------------- jit_instruction --------------------
662 void
663 jit_instruction::push_variable (void)
664 {
665 if (tag ())
666 tag ()->push (this);
667 }
668
669 void
670 jit_instruction::pop_variable (void)
671 {
672 if (tag ())
673 tag ()->pop ();
674 }
675
640 llvm::BasicBlock * 676 llvm::BasicBlock *
641 jit_instruction::parent_llvm (void) const 677 jit_instruction::parent_llvm (void) const
642 { 678 {
643 return mparent->to_llvm (); 679 return mparent->to_llvm ();
680 }
681
682 std::ostream&
683 jit_instruction::short_print (std::ostream& os) const
684 {
685 if (type ())
686 jit_print (os, type ()) << ": ";
687
688 if (tag ())
689 os << tag ()->name () << "." << id;
690 else
691 os << "#" << id;
692 return os;
693 }
694
695 jit_variable *
696 jit_instruction::tag (void) const
697 {
698 return reinterpret_cast<jit_variable *> (mtag.value ());
699 }
700
701 void
702 jit_instruction::stash_tag (jit_variable *atag)
703 {
704 mtag.stash_value (atag, this);
644 } 705 }
645 706
646 // -------------------- jit_block -------------------- 707 // -------------------- jit_block --------------------
647 jit_instruction * 708 jit_instruction *
648 jit_block::prepend (jit_instruction *instr) 709 jit_block::prepend (jit_instruction *instr)
654 715
655 jit_instruction * 716 jit_instruction *
656 jit_block::append (jit_instruction *instr) 717 jit_block::append (jit_instruction *instr)
657 { 718 {
658 instructions.push_back (instr); 719 instructions.push_back (instr);
720 instr->stash_parent (this);
721 return instr;
722 }
723
724 jit_instruction *
725 jit_block::insert_before (iterator loc, jit_instruction *instr)
726 {
727 instructions.insert (loc, instr);
728 instr->stash_parent (this);
729 return instr;
730 }
731
732 jit_instruction *
733 jit_block::insert_after (iterator loc, jit_instruction *instr)
734 {
735 ++loc;
736 instructions.insert (loc, instr);
659 instr->stash_parent (this); 737 instr->stash_parent (this);
660 return instr; 738 return instr;
661 } 739 }
662 740
663 jit_terminator * 741 jit_terminator *
685 use = use->next ()); 763 use = use->next ());
686 764
687 return use->user_parent (); 765 return use->user_parent ();
688 } 766 }
689 767
690 llvm::Value *
691 jit_block::pred_terminator_llvm (size_t idx) const
692 {
693 jit_terminator *term = pred_terminator (idx);
694 return term ? term->to_llvm () : 0;
695 }
696
697 size_t 768 size_t
698 jit_block::pred_index (jit_block *apred) const 769 jit_block::pred_index (jit_block *apred) const
699 { 770 {
700 for (size_t i = 0; i < pred_count (); ++i) 771 for (size_t i = 0; i < pred_count (); ++i)
701 if (pred (i) == apred) 772 if (pred (i) == apred)
716 llvm::BasicBlock *merge; 787 llvm::BasicBlock *merge;
717 merge = llvm::BasicBlock::Create (context, "phi_merge", inside, 788 merge = llvm::BasicBlock::Create (context, "phi_merge", inside,
718 to_llvm ()); 789 to_llvm ());
719 790
720 // fix the predecessor jump if it has been created 791 // fix the predecessor jump if it has been created
721 llvm::Value *term = pred_terminator_llvm (pred_idx); 792 jit_terminator *jterm = pred_terminator (pred_idx);
722 if (term) 793 if (jterm->has_llvm ())
723 { 794 {
795 llvm::Value *term = jterm->to_llvm ();
724 llvm::TerminatorInst *branch = llvm::cast<llvm::TerminatorInst> (term); 796 llvm::TerminatorInst *branch = llvm::cast<llvm::TerminatorInst> (term);
725 for (size_t i = 0; i < branch->getNumSuccessors (); ++i) 797 for (size_t i = 0; i < branch->getNumSuccessors (); ++i)
726 { 798 {
727 if (branch->getSuccessor (i) == to_llvm ()) 799 if (branch->getSuccessor (i) == to_llvm ())
728 branch->setSuccessor (i, merge); 800 branch->setSuccessor (i, merge);
733 temp.CreateBr (to_llvm ()); 805 temp.CreateBr (to_llvm ());
734 mpred_llvm[pred_idx] = merge; 806 mpred_llvm[pred_idx] = merge;
735 } 807 }
736 } 808 }
737 809
810 jit_block *
811 jit_block::succ (size_t i) const
812 {
813 jit_terminator *term = terminator ();
814 return term->sucessor (i);
815 }
816
738 size_t 817 size_t
739 jit_block::succ_count (void) const 818 jit_block::succ_count (void) const
740 { 819 {
741 jit_terminator *term = terminator (); 820 jit_terminator *term = terminator ();
742 return term ? term->sucessor_count () : 0; 821 return term ? term->sucessor_count () : 0;
743 } 822 }
744 823
745 jit_phi *
746 jit_block::search_phi (const std::string& tag_name)
747 {
748 jit_phi *ret = 0;
749 for (iterator iter = begin (); iter != end ()
750 && (ret = dynamic_cast<jit_phi *> (*iter)); ++iter)
751 if (ret->tag () == tag_name)
752 return ret;
753
754 return 0;
755 }
756
757 llvm::BasicBlock * 824 llvm::BasicBlock *
758 jit_block::to_llvm (void) const 825 jit_block::to_llvm (void) const
759 { 826 {
760 return llvm::cast<llvm::BasicBlock> (llvm_value); 827 return llvm::cast<llvm::BasicBlock> (llvm_value);
828 }
829
830 std::ostream&
831 jit_block::print_dom (std::ostream& os) const
832 {
833 short_print (os);
834 os << ":\n";
835 os << " mid: " << mid << std::endl;
836 os << " pred: ";
837 for (size_t i = 0; i < pred_count (); ++i)
838 os << *pred (i) << " ";
839 os << std::endl;
840
841 os << " succ: ";
842 for (size_t i = 0; i < succ_count (); ++i)
843 os << *succ (i) << " ";
844 os << std::endl;
845
846 os << " idom: ";
847 if (idom)
848 os << *idom;
849 else
850 os << "NULL";
851 os << std::endl;
852 os << " df: ";
853 for (df_iterator iter = df_begin (); iter != df_end (); ++iter)
854 os << **iter << " ";
855 os << std::endl;
856
857 os << " dom_succ: ";
858 for (size_t i = 0; i < dom_succ.size (); ++i)
859 os << *dom_succ[i] << " ";
860
861 return os << std::endl;
862 }
863
864 void
865 jit_block::compute_df (size_t visit_count)
866 {
867 if (mvisit_count > visit_count)
868 return;
869 ++mvisit_count;
870
871 if (pred_count () >= 2)
872 {
873 for (size_t i = 0; i < pred_count (); ++i)
874 {
875 jit_block *runner = pred (i);
876 while (runner != idom)
877 {
878 runner->mdf.insert (this);
879 runner = runner->idom;
880 }
881 }
882 }
883
884 for (size_t i = 0; i < succ_count (); ++i)
885 succ (i)->compute_df (visit_count);
886 }
887
888 bool
889 jit_block::update_idom (size_t visit_count)
890 {
891 if (mvisit_count > visit_count)
892 return false;
893 ++mvisit_count;
894
895 if (! pred_count ())
896 return false;
897
898 bool changed = false;
899 for (size_t i = 0; i < pred_count (); ++i)
900 changed = pred (i)->update_idom (visit_count) || changed;
901
902 jit_block *new_idom = pred (0);
903 for (size_t i = 1; i < pred_count (); ++i)
904 {
905 jit_block *pidom = pred (i)->idom;
906 if (! new_idom)
907 new_idom = pidom;
908 else if (pidom)
909 new_idom = pidom->idom_intersect (new_idom);
910 }
911
912 if (idom != new_idom)
913 {
914 idom = new_idom;
915 return true;
916 }
917
918 return changed;
919 }
920
921 void
922 jit_block::finish_phi (jit_block *apred)
923 {
924 size_t pred_idx = pred_index (apred);
925 for (iterator iter = begin (); iter != end ()
926 && dynamic_cast<jit_phi *> (*iter); ++iter)
927 {
928 jit_instruction *phi = *iter;
929 jit_variable *var = phi->tag ();
930 phi->stash_argument (pred_idx, var->top ());
931 }
932 }
933
934 void
935 jit_block::do_construct_ssa (jit_convert& convert, size_t visit_count)
936 {
937 if (mvisit_count > visit_count)
938 return;
939 ++mvisit_count;
940
941 for (iterator iter = begin (); iter != end (); ++iter)
942 {
943 jit_instruction *instr = *iter;
944 bool isphi = dynamic_cast<jit_phi *> (instr);
945
946 if (! isphi)
947 {
948 for (size_t i = 0; i < instr->argument_count (); ++i)
949 {
950 jit_variable *var;
951 var = dynamic_cast<jit_variable *> (instr->argument (i));
952 if (var)
953 instr->stash_argument (i, var->top ());
954 }
955
956 // FIXME: Remove need for jit_store_argument dynamic cast
957 jit_variable *tag = instr->tag ();
958 if (tag && tag->has_top ()
959 && ! dynamic_cast<jit_store_argument *> (instr))
960 {
961 jit_call *rel = convert.create<jit_call> (jit_typeinfo::release,
962 tag->top ());
963 insert_after (iter, rel);
964 ++iter;
965 }
966 }
967
968 instr->push_variable ();
969 }
970
971 for (size_t i = 0; i < succ_count (); ++i)
972 succ (i)->finish_phi (this);
973
974 for (size_t i = 0; i < dom_succ.size (); ++i)
975 dom_succ[i]->do_construct_ssa (convert, visit_count);
976
977 for (iterator iter = begin (); iter != end (); ++iter)
978 {
979 jit_instruction *instr = *iter;
980 instr->pop_variable ();
981 }
982 }
983
984 void
985 jit_block::create_dom_tree (size_t visit_count)
986 {
987 if (mvisit_count > visit_count)
988 return;
989 ++mvisit_count;
990
991 if (idom != this)
992 idom->dom_succ.push_back (this);
993
994 for (size_t i = 0; i < succ_count (); ++i)
995 succ (i)->create_dom_tree (visit_count);
996 }
997
998 jit_block *
999 jit_block::idom_intersect (jit_block *b)
1000 {
1001 jit_block *i = this;
1002 jit_block *j = b;
1003
1004 while (i != j)
1005 {
1006 while (i->id () > j->id ())
1007 i = i->idom;
1008
1009 while (j->id () > i->id ())
1010 j = j->idom;
1011 }
1012
1013 return i;
761 } 1014 }
762 1015
763 // -------------------- jit_call -------------------- 1016 // -------------------- jit_call --------------------
764 bool 1017 bool
765 jit_call::infer (void) 1018 jit_call::infer (void)
790 return false; 1043 return false;
791 } 1044 }
792 1045
793 // -------------------- jit_convert -------------------- 1046 // -------------------- jit_convert --------------------
794 jit_convert::jit_convert (llvm::Module *module, tree &tee) 1047 jit_convert::jit_convert (llvm::Module *module, tree &tee)
1048 : iterator_count (0), breaking (false)
795 { 1049 {
796 jit_instruction::reset_ids (); 1050 jit_instruction::reset_ids ();
797 1051
798 jit_block *entry_block = create<jit_block> ("body"); 1052 entry_block = create<jit_block> ("body");
1053 blocks.push_back (entry_block);
799 block = entry_block; 1054 block = entry_block;
800 blocks.push_back (block);
801
802 toplevel_map tlevel (*this, block);
803 variables = &tlevel;
804 final_block = create<jit_block> ("final");
805 visit (tee); 1055 visit (tee);
806 1056
807 blocks.push_back (final_block); 1057 // FIXME: Remove if we no longer only compile loops
808 block->append (create<jit_break> (final_block)); 1058 assert (! breaking);
809 1059 assert (breaks.empty ());
810 for (variable_map::iterator iter = variables->begin (); 1060 assert (continues.empty ());
811 iter != variables->end (); ++iter) 1061
812 final_block->append (create<jit_store_argument> (iter->first, iter->second)); 1062 jit_block *final_block = block;
813 1063 for (vmap_t::iterator iter = vmap.begin (); iter != vmap.end (); ++iter)
814 // FIXME: Maybe we should remove dead code here? 1064
1065 {
1066 jit_variable *var = iter->second;
1067 const std::string& name = var->name ();
1068 if (name.size () && name[0] != '#')
1069 final_block->append (create<jit_store_argument> (var));
1070 }
1071
1072 construct_ssa (final_block);
815 1073
816 // initialize the worklist to instructions derived from constants 1074 // initialize the worklist to instructions derived from constants
817 for (std::list<jit_value *>::iterator iter = constants.begin (); 1075 for (std::list<jit_value *>::iterator iter = constants.begin ();
818 iter != constants.end (); ++iter) 1076 iter != constants.end (); ++iter)
819 append_users (*iter); 1077 append_users (*iter);
820 1078
821 // also get anything from jit_extract_argument, as these have constant types 1079 if (debug_print)
822 for (jit_block::iterator iter = entry_block->begin (); 1080 print_blocks ("octave jit ir");
823 iter != entry_block->end (); ++iter)
824 {
825 jit_instruction *instr = *iter;
826 if (jit_extract_argument *extract = dynamic_cast<jit_extract_argument *>(instr))
827 {
828 if (! extract->type ())
829 // we depend on an unknown type
830 fail ("Unknown initial type: \"" + extract->tag () + "\"");
831 append_users (extract);
832 }
833 }
834 1081
835 // FIXME: Describe algorithm here 1082 // FIXME: Describe algorithm here
836 while (worklist.size ()) 1083 while (worklist.size ())
837 { 1084 {
838 jit_instruction *next = worklist.front (); 1085 jit_instruction *next = worklist.front ();
844 1091
845 if (debug_print) 1092 if (debug_print)
846 { 1093 {
847 std::cout << "-------------------- Compiling tree --------------------\n"; 1094 std::cout << "-------------------- Compiling tree --------------------\n";
848 std::cout << tee.str_print_code () << std::endl; 1095 std::cout << tee.str_print_code () << std::endl;
849 std::cout << "-------------------- octave jit ir --------------------\n"; 1096 print_blocks ("octave jit ir");
850 for (std::list<jit_block *>::iterator iter = blocks.begin ();
851 iter != blocks.end (); ++iter)
852 (*iter)->print (std::cout, 0);
853 std::cout << std::endl;
854 } 1097 }
855 1098
856 // for now just init arguments from entry, later we will have to do something 1099 // for now just init arguments from entry, later we will have to do something
857 // more interesting 1100 // more interesting
858 for (jit_block::iterator iter = entry_block->begin (); 1101 for (jit_block::iterator iter = entry_block->begin ();
859 iter != entry_block->end (); ++iter) 1102 iter != entry_block->end (); ++iter)
860 { 1103 {
861 if (jit_extract_argument *extract = dynamic_cast<jit_extract_argument *> (*iter)) 1104 if (jit_extract_argument *extract = dynamic_cast<jit_extract_argument *> (*iter))
862 arguments.push_back (std::make_pair (extract->tag (), true)); 1105 arguments.push_back (std::make_pair (extract->name (), true));
863 } 1106 }
864 1107
865 convert_llvm to_llvm; 1108 convert_llvm to_llvm;
866 function = to_llvm.convert (module, arguments, blocks, constants); 1109 function = to_llvm.convert (module, arguments, blocks);
867 1110
868 if (debug_print) 1111 if (debug_print)
869 { 1112 {
870 std::cout << "-------------------- llvm ir --------------------"; 1113 std::cout << "-------------------- llvm ir --------------------";
871 llvm::raw_os_ostream llvm_cout (std::cout); 1114 llvm::raw_os_ostream llvm_cout (std::cout);
912 } 1155 }
913 1156
914 void 1157 void
915 jit_convert::visit_break_command (tree_break_command&) 1158 jit_convert::visit_break_command (tree_break_command&)
916 { 1159 {
917 fail (); 1160 breaks.push_back (block);
1161 breaking = true;
918 } 1162 }
919 1163
920 void 1164 void
921 jit_convert::visit_colon_expression (tree_colon_expression&) 1165 jit_convert::visit_colon_expression (tree_colon_expression&)
922 { 1166 {
924 } 1168 }
925 1169
926 void 1170 void
927 jit_convert::visit_continue_command (tree_continue_command&) 1171 jit_convert::visit_continue_command (tree_continue_command&)
928 { 1172 {
929 fail (); 1173 continues.push_back (block);
1174 breaking = true;
930 } 1175 }
931 1176
932 void 1177 void
933 jit_convert::visit_global_command (tree_global_command&) 1178 jit_convert::visit_global_command (tree_global_command&)
934 { 1179 {
959 // how a for statement is compiled. Note we do an initial check 1204 // how a for statement is compiled. Note we do an initial check
960 // to see if the loop will run atleast once. This allows us to get 1205 // to see if the loop will run atleast once. This allows us to get
961 // better type inference bounds on variables defined and used only 1206 // better type inference bounds on variables defined and used only
962 // inside the for loop (e.g. the index variable) 1207 // inside the for loop (e.g. the index variable)
963 1208
964 // prev_block: % pred = ? 1209 // If we are a nested for loop we need to store the previous breaks
965 // #control.0 = % compute_control (note this will just be a temp) 1210 assert (! breaking);
966 // #iter.0 = call for_init (#control.0) % Let type of control decide iter 1211 unwind_protect prot;
967 // % initial value and type 1212 prot.protect_var (breaks);
968 // #temp.0 = call for_check (control.0, #iter.0) 1213 prot.protect_var (continues);
969 // cond_break #temp.0, for_body, for_tail 1214 prot.protect_var (breaking);
970 // for_body: % pred = for_init, for_cond 1215 breaks.clear ();
971 // idxvar.2 = phi | for_init -> idxvar.1
972 // | for_body -> idxvar.3
973 // #iter.1 = phi | for_init -> #iter.0
974 // | for_body -> #iter.2
975 // idxvar.3 = call for_index (#control.0, #iter.1)
976 // % do loop body
977 // #iter.2 = #iter.1 + 1 % release is implicit in iter reuse
978 // #check = call for_check (#control.0, iter.2)
979 // cond_break #check for_body, for_tail
980 // for_tail: % pred = prev_block, for_body
981 // #iter.3 = phi | prev_block -> #iter.0
982 // | for_body -> #iter.2
983 // idxvar.4 = phi | prev_block -> idxvar.0
984 // | for_body -> idxvar.3
985 // call release (#iter.3)
986 // % rest of code
987 1216
988 // FIXME: one of these days we will introduce proper lvalues... 1217 // FIXME: one of these days we will introduce proper lvalues...
989 tree_identifier *lhs = dynamic_cast<tree_identifier *>(cmd.left_hand_side ()); 1218 tree_identifier *lhs = dynamic_cast<tree_identifier *>(cmd.left_hand_side ());
990 if (! lhs) 1219 if (! lhs)
991 fail (); 1220 fail ();
992 std::string lhs_name = lhs->name (); 1221 std::string lhs_name = lhs->name ();
993 1222
1223 // we need a variable for our iterator, because it is used in multiple blocks
1224 std::stringstream ss;
1225 ss << "#iter" << iterator_count++;
1226 std::string iter_name = ss.str ();
1227 jit_variable *iterator = create<jit_variable> (iter_name);
1228 vmap[iter_name] = iterator;
1229
994 jit_block *body = create<jit_block> ("for_body"); 1230 jit_block *body = create<jit_block> ("for_body");
995 blocks.push_back (body); 1231 blocks.push_back (body);
996 1232
997 jit_block *tail = create<jit_block> ("for_tail"); 1233 jit_block *tail = create<jit_block> ("for_tail");
998 1234
999 // do control expression, iter init, and condition check in prev_block (block) 1235 // do control expression, iter init, and condition check in prev_block (block)
1000 jit_value *control = visit (cmd.control_expr ()); 1236 jit_value *control = visit (cmd.control_expr ());
1001 jit_call *init_iter = create<jit_call> (jit_typeinfo::for_init, control); 1237 jit_call *init_iter = create<jit_call> (jit_typeinfo::for_init, control);
1002 init_iter->stash_tag ("#iter"); 1238 init_iter->stash_tag (iterator);
1003 block->append (init_iter); 1239 block->append (init_iter);
1240
1004 jit_value *check = block->append (create<jit_call> (jit_typeinfo::for_check, 1241 jit_value *check = block->append (create<jit_call> (jit_typeinfo::for_check,
1005 control, init_iter)); 1242 control, iterator));
1006 block->append (create<jit_cond_break> (check, body, tail)); 1243 block->append (create<jit_cond_break> (check, body, tail));
1007
1008 // we need to do iter phi manually, for_map handles the rest
1009 jit_phi *iter_phi = create<jit_phi> (2);
1010 iter_phi->stash_tag ("#iter");
1011 iter_phi->stash_argument (0, init_iter);
1012 body->append (iter_phi);
1013
1014 variable_map *merge_vars = variables;
1015 for_map body_vars (variables, body);
1016 variables = &body_vars;
1017 block = body; 1244 block = body;
1018 1245
1019 // first thing we do in the for loop is bind our index from our itertor 1246 // compute the syntactical iterator
1020 jit_call *idx_rhs = create<jit_call> (jit_typeinfo::for_index, control, iter_phi); 1247 jit_call *idx_rhs = create<jit_call> (jit_typeinfo::for_index, control, iterator);
1021 block->append (idx_rhs); 1248 block->append (idx_rhs);
1022 idx_rhs->stash_tag (lhs_name);
1023 do_assign (lhs_name, idx_rhs, false); 1249 do_assign (lhs_name, idx_rhs, false);
1024 1250
1251 // do loop
1025 tree_statement_list *pt_body = cmd.body (); 1252 tree_statement_list *pt_body = cmd.body ();
1026 pt_body->accept (*this); 1253 pt_body->accept (*this);
1027 1254
1028 // increment iterator, check conditional, and repeat 1255 if (breaking && continues.empty ())
1256 {
1257 // WTF are you doing user? Every branch was a continue, why did you have
1258 // a loop??? Users are silly people...
1259 finish_breaks (tail, breaks);
1260 blocks.push_back (tail);
1261 block = tail;
1262 return;
1263 }
1264
1265 // check our condition, continues jump to this block
1266 jit_block *check_block = create<jit_block> ("for_check");
1267 blocks.push_back (check_block);
1268
1269 if (! breaking)
1270 block->append (create<jit_break> (check_block));
1271 finish_breaks (check_block, continues);
1272
1273 block = check_block;
1029 const jit_function& add_fn = jit_typeinfo::binary_op (octave_value::op_add); 1274 const jit_function& add_fn = jit_typeinfo::binary_op (octave_value::op_add);
1030 jit_call *iter_inc = create<jit_call> (add_fn, iter_phi, 1275 jit_instruction *one = create<jit_const_index> (1);
1031 create<jit_const_index> (1)); 1276 block->append (one);
1032 iter_inc->stash_tag ("#iter"); 1277
1278 jit_call *iter_inc = create<jit_call> (add_fn, iterator, one);
1279 iter_inc->stash_tag (iterator);
1033 block->append (iter_inc); 1280 block->append (iter_inc);
1034 check = block->append (create<jit_call> (jit_typeinfo::for_check, control, 1281 check = block->append (create<jit_call> (jit_typeinfo::for_check, control,
1035 iter_inc)); 1282 iterator));
1036 block->append (create<jit_cond_break> (check, body, tail)); 1283 block->append (create<jit_cond_break> (check, body, tail));
1037 iter_phi->stash_argument (1, iter_inc); 1284
1038 body_vars.finish_phi (*variables); 1285 // breaks will go to our tail
1039 merge (tail, *merge_vars, block, body_vars);
1040
1041 blocks.push_back (tail); 1286 blocks.push_back (tail);
1287 finish_breaks (tail, breaks);
1042 block = tail; 1288 block = tail;
1043 variables = merge_vars;
1044
1045 iter_phi = create<jit_phi> (2);
1046 iter_phi->stash_tag ("#iter");
1047 iter_phi->stash_argument (0, init_iter);
1048 iter_phi->stash_argument (1, iter_inc);
1049 block->append (iter_phi);
1050 block->append (create<jit_call> (jit_typeinfo::release, iter_phi));
1051 } 1289 }
1052 1290
1053 void 1291 void
1054 jit_convert::visit_complex_for_command (tree_complex_for_command&) 1292 jit_convert::visit_complex_for_command (tree_complex_for_command&)
1055 { 1293 {
1088 1326
1089 void 1327 void
1090 jit_convert::visit_identifier (tree_identifier& ti) 1328 jit_convert::visit_identifier (tree_identifier& ti)
1091 { 1329 {
1092 const jit_function& fn = jit_typeinfo::grab (); 1330 const jit_function& fn = jit_typeinfo::grab ();
1093 jit_value *var = variables->get (ti.name ()); 1331 jit_value *decl = get_variable (ti.name ());
1094 result = block->append (create<jit_call> (fn, var)); 1332 result = block->append (create<jit_call> (fn, decl));
1095 } 1333 }
1096 1334
1097 void 1335 void
1098 jit_convert::visit_if_clause (tree_if_clause&) 1336 jit_convert::visit_if_clause (tree_if_clause&)
1099 { 1337 {
1117 // elseif b == 1 1355 // elseif b == 1
1118 // c = c + 2; 1356 // c = c + 2;
1119 // else 1357 // else
1120 // c = c + 3; 1358 // c = c + 3;
1121 // endif 1359 // endif
1360
1361 // ********************
1362 // FIXME: Documentation no longer reflects current version
1363 // ********************
1122 1364
1123 // Generates: 1365 // Generates:
1124 // prev_block0: % pred - ? 1366 // prev_block0: % pred - ?
1125 // #temp.0 = call binary== (a.0, 1) 1367 // #temp.0 = call binary== (a.0, 1)
1126 // cond_break #temp.0, if_body1, ifelse_cond2 1368 // cond_break #temp.0, if_body1, ifelse_cond2
1147 1389
1148 // entry_blocks represents the block you need to enter in order to execute 1390 // entry_blocks represents the block you need to enter in order to execute
1149 // the condition check for the ith clause. For the else, it is simple the 1391 // the condition check for the ith clause. For the else, it is simple the
1150 // else body. If there is no else body, then it is padded with the tail 1392 // else body. If there is no else body, then it is padded with the tail
1151 std::vector<jit_block *> entry_blocks (lst.size () + 1 - last_else); 1393 std::vector<jit_block *> entry_blocks (lst.size () + 1 - last_else);
1152 std::vector<variable_map *> branch_variables (lst.size (), 0);
1153 std::vector<jit_block *> branch_blocks (lst.size (), 0); // final blocks 1394 std::vector<jit_block *> branch_blocks (lst.size (), 0); // final blocks
1154 entry_blocks[0] = block; 1395 entry_blocks[0] = block;
1155 1396
1156 // we need to construct blocks first, because they have jumps to eachother 1397 // we need to construct blocks first, because they have jumps to eachother
1157 tree_if_command_list::iterator iter = lst.begin (); 1398 tree_if_command_list::iterator iter = lst.begin ();
1167 1408
1168 jit_block *tail = create<jit_block> ("if_tail"); 1409 jit_block *tail = create<jit_block> ("if_tail");
1169 if (! last_else) 1410 if (! last_else)
1170 entry_blocks[entry_blocks.size () - 1] = tail; 1411 entry_blocks[entry_blocks.size () - 1] = tail;
1171 1412
1172 // actually fill out the contents of our blocks. We store the variable maps 1413 size_t num_incomming = 0; // number of incomming blocks to our tail
1173 // at the end of each branch, this allows us to merge them in the tail
1174 variable_map *prev_map = variables;
1175 iter = lst.begin (); 1414 iter = lst.begin ();
1176 for (size_t i = 0; iter != lst.end (); ++iter, ++i) 1415 for (size_t i = 0; iter != lst.end (); ++iter, ++i)
1177 { 1416 {
1178 tree_if_clause *tic = *iter; 1417 tree_if_clause *tic = *iter;
1179 block = entry_blocks[i]; 1418 block = entry_blocks[i];
1180 assert (block); 1419 assert (block);
1181 variables = prev_map;
1182 1420
1183 if (i) // the first block is prev_block, so it has already been added 1421 if (i) // the first block is prev_block, so it has already been added
1184 blocks.push_back (entry_blocks[i]); 1422 blocks.push_back (entry_blocks[i]);
1185 1423
1186 if (! tic->is_else_clause ()) 1424 if (! tic->is_else_clause ())
1193 1431
1194 jit_instruction *br = create<jit_cond_break> (cond, body, 1432 jit_instruction *br = create<jit_cond_break> (cond, body,
1195 entry_blocks[i + 1]); 1433 entry_blocks[i + 1]);
1196 block->append (br); 1434 block->append (br);
1197 block = body; 1435 block = body;
1198
1199 variables = new compound_map (variables);
1200 branch_variables[i] = variables;
1201 } 1436 }
1202 1437
1203 tree_statement_list *stmt_lst = tic->commands (); 1438 tree_statement_list *stmt_lst = tic->commands ();
1204 assert (stmt_lst); // jwe: Can this be null? 1439 assert (stmt_lst); // jwe: Can this be null?
1205 stmt_lst->accept (*this); 1440 stmt_lst->accept (*this);
1206 1441
1207 branch_variables[i] = variables; 1442 if (breaking)
1208 branch_blocks[i] = block; 1443 breaking = false;
1209 block->append (create<jit_break> (tail)); 1444 else
1210 } 1445 {
1211 1446 ++num_incomming;
1212 blocks.push_back (tail); 1447 block->append (create<jit_break> (tail));
1213 1448 }
1214 // We create phi nodes in the tail to merge blocks 1449 }
1215 for (size_t i = 0; i < branch_variables.size () - last_else; ++i) 1450
1216 { 1451 if (num_incomming || ! last_else)
1217 merge (tail, *prev_map, branch_blocks[i], *branch_variables[i]); 1452 {
1218 delete branch_variables[i]; 1453 blocks.push_back (tail);
1219 } 1454 block = tail;
1220 1455 }
1221 variables = prev_map; 1456 else
1222 block = tail; 1457 // every branch broke, so we don't have a tail
1458 breaking = true;
1223 } 1459 }
1224 1460
1225 void 1461 void
1226 jit_convert::visit_index_expression (tree_index_expression&) 1462 jit_convert::visit_index_expression (tree_index_expression&)
1227 { 1463 {
1265 { 1501 {
1266 Range rv = v.range_value (); 1502 Range rv = v.range_value ();
1267 result = create<jit_const_range> (rv); 1503 result = create<jit_const_range> (rv);
1268 } 1504 }
1269 else 1505 else
1270 fail (); 1506 fail ("Unknown constant");
1507
1508 block->append (result);
1271 } 1509 }
1272 1510
1273 void 1511 void
1274 jit_convert::visit_fcn_handle (tree_fcn_handle&) 1512 jit_convert::visit_fcn_handle (tree_fcn_handle&)
1275 { 1513 {
1309 void 1547 void
1310 jit_convert::visit_simple_assignment (tree_simple_assignment& tsa) 1548 jit_convert::visit_simple_assignment (tree_simple_assignment& tsa)
1311 { 1549 {
1312 // resolve rhs 1550 // resolve rhs
1313 tree_expression *rhs = tsa.right_hand_side (); 1551 tree_expression *rhs = tsa.right_hand_side ();
1314 jit_value *rhsv = visit (rhs); 1552 jit_instruction *rhsv = visit (rhs);
1315 1553
1316 // resolve lhs 1554 // resolve lhs
1317 tree_expression *lhs = tsa.left_hand_side (); 1555 tree_expression *lhs = tsa.left_hand_side ();
1318 if (! lhs->is_identifier ()) 1556 if (! lhs->is_identifier ())
1319 fail (); 1557 fail ();
1320 1558
1321 std::string lhs_name = lhs->name (); 1559 std::string lhs_name = lhs->name ();
1322 do_assign (lhs_name, rhsv, tsa.print_result ()); 1560 result = do_assign (lhs_name, rhsv, tsa.print_result ());
1323 result = rhsv;
1324
1325 if (jit_instruction *instr = dynamic_cast<jit_instruction *>(rhsv))
1326 instr->stash_tag (lhs_name);
1327 } 1561 }
1328 1562
1329 void 1563 void
1330 jit_convert::visit_statement (tree_statement& stmt) 1564 jit_convert::visit_statement (tree_statement& stmt)
1331 { 1565 {
1346 do_bind_ans = (! id->is_variable ()); 1580 do_bind_ans = (! id->is_variable ());
1347 } 1581 }
1348 else 1582 else
1349 do_bind_ans = (! expr->is_assignment_expression ()); 1583 do_bind_ans = (! expr->is_assignment_expression ());
1350 1584
1351 jit_value *expr_result = visit (expr); 1585 jit_instruction *expr_result = visit (expr);
1352 1586
1353 if (do_bind_ans) 1587 if (do_bind_ans)
1354 do_assign ("ans", expr_result, expr->print_result ()); 1588 do_assign ("ans", expr_result, expr->print_result ());
1355 else if (expr->is_identifier () && expr->print_result ()) 1589 else if (expr->is_identifier () && expr->print_result ())
1356 { 1590 {
1371 { 1605 {
1372 tree_statement *elt = *iter; 1606 tree_statement *elt = *iter;
1373 // jwe: Can this ever be null? 1607 // jwe: Can this ever be null?
1374 assert (elt); 1608 assert (elt);
1375 elt->accept (*this); 1609 elt->accept (*this);
1610
1611 if (breaking)
1612 break;
1376 } 1613 }
1377 } 1614 }
1378 1615
1379 void 1616 void
1380 jit_convert::visit_switch_case (tree_switch_case&) 1617 jit_convert::visit_switch_case (tree_switch_case&)
1416 jit_convert::visit_do_until_command (tree_do_until_command&) 1653 jit_convert::visit_do_until_command (tree_do_until_command&)
1417 { 1654 {
1418 fail (); 1655 fail ();
1419 } 1656 }
1420 1657
1421 void 1658 jit_variable *
1422 jit_convert::do_assign (const std::string& lhs, jit_value *rhs, bool print) 1659 jit_convert::get_variable (const std::string& vname)
1423 { 1660 {
1424 const jit_function& release = jit_typeinfo::release (); 1661 vmap_t::iterator iter;
1425 jit_value *current = variables->get (lhs); 1662 iter = vmap.find (vname);
1426 block->append (create<jit_call> (release, current)); 1663 if (iter != vmap.end ())
1427 variables->set (lhs, rhs); 1664 return iter->second;
1665
1666 jit_variable *var = create<jit_variable> (vname);
1667 octave_value val = symbol_table::find (vname);
1668 jit_type *type = jit_typeinfo::type_of (val);
1669 jit_extract_argument *extract;
1670 extract = create<jit_extract_argument> (type, var);
1671 entry_block->prepend (extract);
1672
1673 return vmap[vname] = var;
1674 }
1675
1676 jit_instruction *
1677 jit_convert::do_assign (const std::string& lhs, jit_instruction *rhs,
1678 bool print)
1679 {
1680 jit_variable *var = get_variable (lhs);
1681 rhs->stash_tag (var);
1428 1682
1429 if (print) 1683 if (print)
1430 { 1684 {
1431 const jit_function& print_fn = jit_typeinfo::print_value (); 1685 const jit_function& print_fn = jit_typeinfo::print_value ();
1432 jit_const_string *name = create<jit_const_string> (lhs); 1686 jit_const_string *name = create<jit_const_string> (lhs);
1433 block->append (create<jit_call> (print_fn, name, rhs)); 1687 block->append (create<jit_call> (print_fn, name, var));
1434 } 1688 }
1435 } 1689
1436 1690 return rhs;
1437 jit_value * 1691 }
1692
1693 jit_instruction *
1438 jit_convert::visit (tree& tee) 1694 jit_convert::visit (tree& tee)
1439 { 1695 {
1440 result = 0; 1696 result = 0;
1441 tee.accept (*this); 1697 tee.accept (*this);
1442 1698
1443 jit_value *ret = result; 1699 jit_instruction *ret = result;
1444 result = 0; 1700 result = 0;
1445 return ret; 1701 return ret;
1446 } 1702 }
1447 1703
1448 void 1704 void
1449 jit_convert::merge (jit_block *merge_block, variable_map& merge_vars, 1705 jit_convert::construct_ssa (jit_block *final_block)
1450 jit_block *incomming_block, 1706 {
1451 const variable_map& incomming_vars) 1707 final_block->label ();
1452 { 1708 entry_block->compute_idom (final_block);
1453 size_t pred_count = merge_block->pred_count (); 1709 entry_block->compute_df ();
1454 size_t merge_idx = merge_block->pred_index (incomming_block); 1710 entry_block->create_dom_tree ();
1455 for (variable_map::const_iterator iter = incomming_vars.begin (); 1711
1456 iter != incomming_vars.end (); ++iter) 1712 // insert phi nodes where needed
1457 { 1713 for (vmap_t::iterator iter = vmap.begin (); iter != vmap.end (); ++iter)
1458 const std::string& vname = iter->first; 1714 {
1459 jit_value *merge_val = merge_vars.get (vname); 1715 jit_block::df_set visited, added_phi;
1460 jit_value *inc_val = iter->second; 1716 std::list<jit_block *> ssa_worklist;
1461 1717 iter->second->use_blocks (visited);
1462 if (merge_val != inc_val) 1718 ssa_worklist.insert (ssa_worklist.begin (), visited.begin (), visited.end ());
1719
1720 while (ssa_worklist.size ())
1463 { 1721 {
1464 jit_phi *phi = dynamic_cast<jit_phi *> (merge_val); 1722 jit_block *b = ssa_worklist.front ();
1465 if (! (phi && phi->parent () == merge_block)) 1723 ssa_worklist.pop_front ();
1724
1725 for (jit_block::df_iterator diter = b->df_begin ();
1726 diter != b->df_end (); ++diter)
1466 { 1727 {
1467 phi = merge_block->search_phi (vname); 1728 jit_block *dblock = *diter;
1468 if (! phi) 1729 if (! added_phi.count (dblock))
1469 { 1730 {
1470 phi = create<jit_phi> (pred_count, merge_val); 1731 jit_phi *phi = create<jit_phi> (iter->second,
1471 merge_block->prepend (phi); 1732 dblock->pred_count ());
1733 dblock->prepend (phi);
1734 added_phi.insert (dblock);
1472 } 1735 }
1473 1736
1474 merge_vars.set (vname, phi); 1737 if (! visited.count (dblock))
1738 {
1739 ssa_worklist.push_back (dblock);
1740 visited.insert (dblock);
1741 }
1475 } 1742 }
1476
1477 phi->stash_argument (merge_idx, inc_val);
1478 } 1743 }
1479 } 1744 }
1480 } 1745
1481 1746 entry_block->construct_ssa (*this);
1482 // -------------------- jit_convert::toplevel_map -------------------- 1747 }
1483 jit_value * 1748
1484 jit_convert::toplevel_map::insert (const std::string& name, jit_value *pval) 1749 void
1485 { 1750 jit_convert::finish_breaks (jit_block *dest, const break_list& lst)
1486 assert (pval == 0); // we have no parent 1751 {
1487 1752 for (break_list::const_iterator iter = lst.begin (); iter != lst.end ();
1488 jit_block *entry = block (); 1753 ++iter)
1489 octave_value val = symbol_table::find (name); 1754 {
1490 jit_type *type = jit_typeinfo::type_of (val); 1755 jit_block *b = *iter;
1491 jit_instruction *ret = convert.create<jit_extract_argument> (type, name); 1756 b->append (create<jit_break> (dest));
1492 return vars[name] = entry->prepend (ret); 1757 }
1493 } 1758 }
1494 1759
1495 // -------------------- jit_convert::convert_llvm -------------------- 1760 // -------------------- jit_convert::convert_llvm --------------------
1496 llvm::Function * 1761 llvm::Function *
1497 jit_convert::convert_llvm::convert (llvm::Module *module, 1762 jit_convert::convert_llvm::convert (llvm::Module *module,
1498 const std::vector<std::pair< std::string, bool> >& args, 1763 const std::vector<std::pair< std::string, bool> >& args,
1499 const std::list<jit_block *>& blocks, 1764 const std::list<jit_block *>& blocks)
1500 const std::list<jit_value *>& constants)
1501 { 1765 {
1502 jit_type *any = jit_typeinfo::get_any (); 1766 jit_type *any = jit_typeinfo::get_any ();
1503 1767
1504 // argument is an array of octave_base_value*, or octave_base_value** 1768 // argument is an array of octave_base_value*, or octave_base_value**
1505 llvm::Type *arg_type = any->to_llvm (); // this is octave_base_value* 1769 llvm::Type *arg_type = any->to_llvm (); // this is octave_base_value*
1519 for (size_t i = 0; i < args.size (); ++i) 1783 for (size_t i = 0; i < args.size (); ++i)
1520 { 1784 {
1521 llvm::Value *loaded_arg = builder.CreateConstInBoundsGEP1_32 (arg, i); 1785 llvm::Value *loaded_arg = builder.CreateConstInBoundsGEP1_32 (arg, i);
1522 arguments[args[i].first] = loaded_arg; 1786 arguments[args[i].first] = loaded_arg;
1523 } 1787 }
1524
1525 // we need to generate llvm values for constants, as these don't appear in
1526 // a block
1527 for (std::list<jit_value *>::const_iterator iter = constants.begin ();
1528 iter != constants.end (); ++iter)
1529 visit (*iter);
1530 1788
1531 std::list<jit_block *>::const_iterator biter; 1789 std::list<jit_block *>::const_iterator biter;
1532 for (biter = blocks.begin (); biter != blocks.end (); ++biter) 1790 for (biter = blocks.begin (); biter != blocks.end (); ++biter)
1533 { 1791 {
1534 jit_block *jblock = *biter; 1792 jit_block *jblock = *biter;
1665 jit_convert::convert_llvm::visit (jit_call& call) 1923 jit_convert::convert_llvm::visit (jit_call& call)
1666 { 1924 {
1667 const jit_function::overload& ol = call.overload (); 1925 const jit_function::overload& ol = call.overload ();
1668 if (! ol.function) 1926 if (! ol.function)
1669 fail ("No overload for: " + call.print_string ()); 1927 fail ("No overload for: " + call.print_string ());
1670 1928
1671 std::vector<llvm::Value *> args (call.argument_count ()); 1929 std::vector<llvm::Value *> args (call.argument_count ());
1672 for (size_t i = 0; i < call.argument_count (); ++i) 1930 for (size_t i = 0; i < call.argument_count (); ++i)
1673 args[i] = call.argument_llvm (i); 1931 args[i] = call.argument_llvm (i);
1674 1932
1675 call.stash_llvm (builder.CreateCall (ol.function, args, call.tag ())); 1933 call.stash_llvm (builder.CreateCall (ol.function, args));
1676 } 1934 }
1677 1935
1678 void 1936 void
1679 jit_convert::convert_llvm::visit (jit_extract_argument& extract) 1937 jit_convert::convert_llvm::visit (jit_extract_argument& extract)
1680 { 1938 {
1681 const jit_function::overload& ol = extract.overload (); 1939 const jit_function::overload& ol = extract.overload ();
1682 if (! ol.function) 1940 if (! ol.function)
1683 fail (); 1941 fail ();
1684 1942
1685 llvm::Value *arg = arguments[extract.tag ()]; 1943 llvm::Value *arg = arguments[extract.name ()];
1686 assert (arg); 1944 assert (arg);
1687 arg = builder.CreateLoad (arg); 1945 arg = builder.CreateLoad (arg);
1688 extract.stash_llvm (builder.CreateCall (ol.function, arg, extract.tag ())); 1946 extract.stash_llvm (builder.CreateCall (ol.function, arg, extract.name ()));
1689 } 1947 }
1690 1948
1691 void 1949 void
1692 jit_convert::convert_llvm::visit (jit_store_argument& store) 1950 jit_convert::convert_llvm::visit (jit_store_argument& store)
1693 { 1951 {
1696 if (! ol.function) 1954 if (! ol.function)
1697 fail (); 1955 fail ();
1698 1956
1699 arg_value = builder.CreateCall (ol.function, arg_value); 1957 arg_value = builder.CreateCall (ol.function, arg_value);
1700 1958
1701 llvm::Value *arg = arguments[store.tag ()]; 1959 llvm::Value *arg = arguments[store.name ()];
1702 store.stash_llvm (builder.CreateStore (arg_value, arg)); 1960 store.stash_llvm (builder.CreateStore (arg_value, arg));
1703 } 1961 }
1704 1962
1705 void 1963 void
1706 jit_convert::convert_llvm::visit (jit_phi& phi) 1964 jit_convert::convert_llvm::visit (jit_phi& phi)
1707 { 1965 {
1708 // we might not have converted all incoming branches, so we don't 1966 // we might not have converted all incoming branches, so we don't
1709 // set incomming branches now 1967 // set incomming branches now
1710 llvm::PHINode *node = llvm::PHINode::Create (phi.type_llvm (), 1968 llvm::PHINode *node = llvm::PHINode::Create (phi.type_llvm (),
1711 phi.argument_count (), 1969 phi.argument_count ());
1712 phi.tag ());
1713 builder.Insert (node); 1970 builder.Insert (node);
1714 phi.stash_llvm (node); 1971 phi.stash_llvm (node);
1715 1972
1716 jit_block *parent = phi.parent (); 1973 jit_block *parent = phi.parent ();
1717 for (size_t i = 0; i < phi.argument_count (); ++i) 1974 for (size_t i = 0; i < phi.argument_count (); ++i)
1718 if (phi.argument_type (i) != phi.type ()) 1975 if (phi.argument_type (i) != phi.type ())
1719 parent->create_merge (function, i); 1976 parent->create_merge (function, i);
1977 }
1978
1979 void
1980 jit_convert::convert_llvm::visit (jit_variable&)
1981 {
1982 fail ("ERROR: SSA construction should remove all variables");
1720 } 1983 }
1721 1984
1722 // -------------------- tree_jit -------------------- 1985 // -------------------- tree_jit --------------------
1723 1986
1724 tree_jit::tree_jit (void) : module (0), engine (0) 1987 tree_jit::tree_jit (void) : module (0), engine (0)