Mercurial > hg > octave-nkf
changeset 18367:2a8243d8327a
jit compiler: Add support for the do_until statement
* libinterp/corefcn/pt-jit.cc (jit_convert::visit_do_until_command):
Compile do_until loop.
* libinterp/corefcn/pt-eval.cc (tree_evaluator::visit_do_until_command):
Use jit compiler if available.
* test/jit.tst: do until tests added
author | LYH <lyh.kernel@gmail.com> |
---|---|
date | Fri, 27 Dec 2013 13:01:39 +0100 |
parents | 7e425ca58e9c |
children | 421bed6994f0 |
files | libinterp/corefcn/pt-jit.cc libinterp/parse-tree/pt-eval.cc test/jit.tst |
diffstat | 3 files changed, 90 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/pt-jit.cc +++ b/libinterp/corefcn/pt-jit.cc @@ -903,9 +903,66 @@ } void -jit_convert::visit_do_until_command (tree_do_until_command&) +jit_convert::visit_do_until_command (tree_do_until_command& duc) { - throw jit_fail_exception (); + unwind_protect prot; + prot.protect_var (breaks); + prot.protect_var (continues); + breaks.clear (); + continues.clear (); + + jit_block *body = factory.create<jit_block> ("do_until_body"); + jit_block *cond_check = factory.create<jit_block> ("do_until_cond_check"); + jit_block *tail = factory.create<jit_block> ("do_until_tail"); + + block->append (factory.create<jit_branch> (body)); + blocks.push_back (body); + block = body; + + tree_statement_list *loop_body = duc.body (); + bool all_breaking = false; + if (loop_body) + { + try + { + loop_body->accept (*this); + } + catch (const jit_break_exception&) + { + all_breaking = true; + } + } + + finish_breaks (tail, breaks); + + if (! all_breaking || continues.size ()) + { + jit_block *interrupt_check + = factory.create<jit_block> ("interrupt_check"); + blocks.push_back (interrupt_check); + finish_breaks (interrupt_check, continues); + if (! all_breaking) + block->append (factory.create<jit_branch> (interrupt_check)); + + block = interrupt_check; + jit_error_check *ec + = factory.create<jit_error_check> (jit_error_check::var_interrupt, + cond_check, final_block); + block->append (ec); + + blocks.push_back (cond_check); + block = cond_check; + + tree_expression *expr = duc.condition (); + assert (expr && "Do-Until expression can not be null"); + jit_value *check = visit (expr); + check = create_checked (&jit_typeinfo::logically_true, check); + + block->append (factory.create<jit_cond_branch> (check, tail, body)); + } + + blocks.push_back (tail); + block = tail; } void
--- a/libinterp/parse-tree/pt-eval.cc +++ b/libinterp/parse-tree/pt-eval.cc @@ -1121,6 +1121,11 @@ if (error_state) return; +#if HAVE_LLVM + if (tree_jit::execute (cmd)) + return; +#endif + unwind_protect frame; frame.protect_var (in_loop_command);
--- a/test/jit.tst +++ b/test/jit.tst @@ -52,6 +52,32 @@ %!testif HAVE_LLVM %! jit_failure_count (0) +%! do +%! break; +%! until (0) +%! assert (jit_failure_count, 0); + +%!testif HAVE_LLVM +%! jit_failure_count (0) +%! do +%! if (1) +%! break; +%! end; +%! until (0) +%! assert (jit_failure_count, 0); + +%!testif HAVE_LLVM +%! jit_failure_count (0) +%! i=1; +%! do +%! continue; +%! i=i+1; +%! until (1) +%! assert (i, 1); +%! assert (jit_failure_count, 0); + +%!testif HAVE_LLVM +%! jit_failure_count (0) %! for i=1:1e6 %! if (i == 100) %! break;