changeset 15023:75d1bc2fd6d2

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.
author Max Brister <max@2bass.com>
date Thu, 26 Jul 2012 12:17:56 -0500
parents e47b4e8c2714
children f23e60748072
files src/pt-eval.cc src/pt-jit.cc src/pt-jit.h src/pt-loop.cc src/pt-loop.h
diffstat 5 files changed, 86 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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);
+
 */
--- 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; }
--- 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 *
--- 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