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