comparison libinterp/corefcn/pt-jit.cc @ 18583:3b7490456101 draft

Add switch statement support
author LYH <lyh.kernel@gmail.com>
date Fri, 21 Mar 2014 14:59:38 -0400
parents f3314c4b9266
children f00ef64486a2
comparison
equal deleted inserted replaced
18582:c31fe3239c8b 18583:3b7490456101
819 { 819 {
820 throw jit_fail_exception (); 820 throw jit_fail_exception ();
821 } 821 }
822 822
823 void 823 void
824 jit_convert::visit_switch_command (tree_switch_command&) 824 jit_convert::visit_switch_command (tree_switch_command& cmd)
825 { 825 {
826 throw jit_fail_exception (); 826 // create blocks
827 jit_block *head = factory.create<jit_block> ("switch_head");
828
829 tree_switch_case_list *lst = cmd.case_list ();
830 tree_switch_case *last = lst->back ();
831
832 size_t cond_blocks_num;
833 if (lst->size() && last->is_default_case ())
834 cond_blocks_num = lst->size () - 1;
835 else
836 cond_blocks_num = lst->size ();
837
838 std::vector<jit_block *> if_blocks (cond_blocks_num);
839 std::vector<jit_block *> body_blocks (cond_blocks_num);
840 std::vector<jit_block *> else_blocks (cond_blocks_num);
841
842 //tree_switch_case_list::iterator iter = lst->begin ();
843 for (size_t i = 0; i < cond_blocks_num; ++i)
844 {
845 if_blocks[i] = factory.create<jit_block> ("if_cond");
846 body_blocks[i] = factory.create<jit_block> ("if_body");
847 else_blocks[i] = factory.create<jit_block> ("else");
848 }
849
850 jit_block *tail = factory.create<jit_block> ("switch_tail");
851
852
853 // link & fullfil these blocks
854 block->append (factory.create<jit_branch> (head));
855
856 blocks.push_back (head);
857 block = head; // switch_head
858 tree_expression *expr = cmd.switch_value ();
859 assert (expr && "Switch value can not be null");
860 jit_value *value = visit (expr);
861 assert (value);
862
863 // each branch in the if statement will have different breaks/continues
864 block_list current_breaks = breaks;
865 block_list current_continues = continues;
866 breaks.clear ();
867 continues.clear ();
868
869 #if 0
870 size_t num_incomming = 0; // number of incomming blocks to our tail
871 #endif
872 tree_switch_case_list::iterator iter = lst->begin ();
873 for (size_t i = 0; i < cond_blocks_num; ++iter, ++i)
874 {
875 block->append (factory.create<jit_branch> (if_blocks[i]));
876
877 blocks.push_back (if_blocks[i]);
878 block = if_blocks[i]; // if_cond
879 tree_switch_case *twc = *iter;
880 tree_expression *expr = twc->case_label ();
881 jit_value *label = visit (expr);
882 assert(label);
883
884 const jit_operation& fn = jit_typeinfo::binary_op (octave_value::op_eq);
885 jit_value *cond = create_checked (fn, value, label);
886 assert(cond);
887 jit_call *check = create_checked (&jit_typeinfo::logically_true,
888 cond);
889 block->append (factory.create<jit_cond_branch> (check, body_blocks[i],
890 else_blocks[i]));
891
892 blocks.push_back (body_blocks[i]);
893 block = body_blocks[i]; // if_body
894 tree_statement_list *stmt_lst = twc->commands ();
895 assert(stmt_lst);
896 #if 0
897 try
898 {
899 #endif
900 stmt_lst->accept (*this);
901 #if 0
902 num_incomming++;
903 #endif
904 block->append (factory.create<jit_branch> (tail));
905 #if 0
906 }
907 catch(const jit_break_exception&)
908 {}
909 #endif
910
911 #if 0
912 // each branch in the if statement will have different breaks/continues
913 current_breaks.splice (current_breaks.end (), breaks);
914 current_continues.splice (current_continues.end (), continues);
915 #endif
916
917 blocks.push_back (else_blocks[i]);
918 block = else_blocks[i]; // else
919 }
920
921 if (lst->size() && last->is_default_case ())
922 {
923 tree_statement_list *stmt_lst = last->commands ();
924 assert(stmt_lst);
925 stmt_lst->accept (*this);
926
927 #if 0
928 // each branch in the if statement will have different breaks/continues
929 current_breaks.splice (current_breaks.end (), breaks);
930 current_continues.splice (current_continues.end (), continues);
931 #endif
932 }
933
934 #if 0
935 // each branch in the if statement will have different breaks/continues
936 breaks.splice (breaks.end (), current_breaks);
937 continues.splice (continues.end (), current_continues);
938 #endif
939
940 block->append (factory.create<jit_branch> (tail));
941 blocks.push_back (tail);
942 block = tail; // switch_tail
827 } 943 }
828 944
829 void 945 void
830 jit_convert::visit_try_catch_command (tree_try_catch_command&) 946 jit_convert::visit_try_catch_command (tree_try_catch_command&)
831 { 947 {