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