# HG changeset patch # User Max Brister # Date 1343323076 18000 # Node ID 75d1bc2fd6d2d70131282c8d822be21a1df4d58b # Parent e47b4e8c2714b33ecabe66346c7472bbf47fe83e Compile top level while loops in JIT. * src/pt-eval.cc (tree_evaluator::visit_while_command): Try compile while loops. * src/pt-jit.cc (jit_convert::jit_convert): Add first terminator to worklist. (tree_jit::execute): New overload. * src/pt-jit.h (tree_jit::execute): New overload. * src/pt-loop.cc (tree_while_command::~tree_while_command): Delete compiled. (tree_simple_for_command::~tree_simple_for_command): Only delete compiled if JIT is enabled. * src/pt-loop.h (tree_while_command::get_info, tree_while_command::stash_info): New function. diff --git a/src/pt-eval.cc b/src/pt-eval.cc --- a/src/pt-eval.cc +++ b/src/pt-eval.cc @@ -1034,6 +1034,11 @@ if (error_state) return; +#if HAVE_LLVM + if (jiter.execute (cmd)) + return; +#endif + unwind_protect frame; frame.protect_var (in_loop_command); diff --git a/src/pt-jit.cc b/src/pt-jit.cc --- a/src/pt-jit.cc +++ b/src/pt-jit.cc @@ -92,6 +92,10 @@ iter != constants.end (); ++iter) append_users (*iter); + // the entry block terminator may be a regular branch statement + if (entry_block->terminator ()) + push_worklist (entry_block->terminator ()); + // FIXME: Describe algorithm here while (worklist.size ()) { @@ -1475,6 +1479,23 @@ } bool +tree_jit::execute (tree_while_command& cmd) +{ + if (! initialize ()) + return false; + + jit_info *info = cmd.get_info (); + if (! info || ! info->match ()) + { + delete info; + info = new jit_info (*this, cmd); + cmd.stash_info (info); + } + + return info->execute (); +} + +bool tree_jit::initialize (void) { if (engine) @@ -1708,4 +1729,12 @@ %! test_set = gen_test (10000); %! assert (all (vectorized (test_set, 3) == loopy (test_set, 3))); +%!test +%! niter = 1001; +%! i = 0; +%! while (i < niter) +%! i = i + 1; +%! endwhile +%! assert (i == niter); + */ diff --git a/src/pt-jit.h b/src/pt-jit.h --- a/src/pt-jit.h +++ b/src/pt-jit.h @@ -406,6 +406,8 @@ bool execute (tree_simple_for_command& cmd); + bool execute (tree_while_command& cmd); + llvm::ExecutionEngine *get_engine (void) const { return engine; } llvm::Module *get_module (void) const { return module; } diff --git a/src/pt-loop.cc b/src/pt-loop.cc --- a/src/pt-loop.cc +++ b/src/pt-loop.cc @@ -50,6 +50,9 @@ delete list; delete lead_comm; delete trail_comm; +#ifdef HAVE_LLVM + delete compiled; +#endif } tree_command * @@ -98,7 +101,9 @@ delete list; delete lead_comm; delete trail_comm; +#ifdef HAVE_LLVM delete compiled; +#endif } tree_command * diff --git a/src/pt-loop.h b/src/pt-loop.h --- a/src/pt-loop.h +++ b/src/pt-loop.h @@ -47,21 +47,33 @@ tree_while_command (int l = -1, int c = -1) : tree_command (l, c), expr (0), list (0), lead_comm (0), - trail_comm (0) { } + trail_comm (0) +#ifdef HAVE_LLVM + , compiled (0) +#endif + { } tree_while_command (tree_expression *e, octave_comment_list *lc = 0, octave_comment_list *tc = 0, int l = -1, int c = -1) : tree_command (l, c), expr (e), list (0), lead_comm (lc), - trail_comm (tc) { } + trail_comm (tc) +#ifdef HAVE_LLVM + , compiled (0) +#endif + { } tree_while_command (tree_expression *e, tree_statement_list *lst, octave_comment_list *lc = 0, octave_comment_list *tc = 0, int l = -1, int c = -1) : tree_command (l, c), expr (e), list (lst), lead_comm (lc), - trail_comm (tc) { } + trail_comm (tc) +#ifdef HAVE_LLVM + , compiled (0) +#endif + { } ~tree_while_command (void); @@ -78,6 +90,19 @@ void accept (tree_walker& tw); +#ifdef HAVE_LLVM + // some functions use by tree_jit + jit_info *get_info (void) const + { + return compiled; + } + + void stash_info (jit_info *jinfo) + { + compiled = jinfo; + } +#endif + protected: // Expression to test. @@ -94,6 +119,11 @@ private: +#ifdef HAVE_LLVM + // compiled version of the loop + jit_info *compiled; +#endif + // No copying! tree_while_command (const tree_while_command&); @@ -148,7 +178,11 @@ tree_simple_for_command (int l = -1, int c = -1) : tree_command (l, c), parallel (false), lhs (0), expr (0), - maxproc (0), list (0), lead_comm (0), trail_comm (0), compiled (0) { } + maxproc (0), list (0), lead_comm (0), trail_comm (0) +#ifdef HAVE_LLVM + , compiled (0) +#endif + { } tree_simple_for_command (bool parallel_arg, tree_expression *le, tree_expression *re, @@ -159,7 +193,11 @@ int l = -1, int c = -1) : tree_command (l, c), parallel (parallel_arg), lhs (le), expr (re), maxproc (maxproc_arg), list (lst), - lead_comm (lc), trail_comm (tc), compiled (0) { } + lead_comm (lc), trail_comm (tc) +#ifdef HAVE_LLVM + , compiled (0) +#endif + { } ~tree_simple_for_command (void); @@ -182,6 +220,7 @@ void accept (tree_walker& tw); +#ifdef HAVE_LLVM // some functions use by tree_jit jit_info *get_info (void) const { @@ -192,6 +231,7 @@ { compiled = jinfo; } +#endif private: // TRUE means operate in parallel (subject to the value of the