changeset 14989:dfaa8da46364

Support while loops in JIT * src/pt-jit.cc (jit_block::update_idom): Change call to idom_intersect. (jit_block::idom_intersect): Take first block explicity and check for null blocks. (jit_convert::visit_simple_for_command): Clear continues. (jit_convert::visit_while_command): Implement. * src/pt-jit.h (jit_block::idom_intersect): Change declaration.
author Max Brister <max@2bass.com>
date Wed, 11 Jul 2012 17:34:22 -0500
parents 822d52bee973
children 149d1e2224f0
files src/pt-jit.cc src/pt-jit.h
diffstat 2 files changed, 46 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/pt-jit.cc	Wed Jul 11 14:42:56 2012 -0500
+++ b/src/pt-jit.cc	Wed Jul 11 17:34:22 2012 -0500
@@ -2042,7 +2042,7 @@
       jit_block *pred = use->user_parent ();
       jit_block *pidom = pred->idom;
       if (pidom)
-        new_idom = pidom->idom_intersect (new_idom);
+        new_idom = idom_intersect (pidom, new_idom);
     }
 
   if (idom != new_idom)
@@ -2109,21 +2109,18 @@
 }
 
 jit_block *
-jit_block::idom_intersect (jit_block *b)
+jit_block::idom_intersect (jit_block *i, jit_block *j)
 {
-  jit_block *i = this;
-  jit_block *j = b;
-
-  while (i != j)
+  while (i && j && i != j)
     {
-      while (i->id () > j->id ())
+      while (i && i->id () > j->id ())
         i = i->idom;
 
-      while (j->id () > i->id ())
+      while (i && j && j->id () > i->id ())
         j = j->idom;
     }
 
-  return i;
+  return i ? i : j;
 }
 
 // -------------------- jit_phi_incomming --------------------
@@ -2509,6 +2506,7 @@
   prot.protect_var (continues);
   prot.protect_var (breaking);
   breaks.clear ();
+  continues.clear ();
 
   // we need a variable for our iterator, because it is used in multiple blocks
   std::stringstream ss;
@@ -2902,9 +2900,45 @@
 }
 
 void
-jit_convert::visit_while_command (tree_while_command&)
+jit_convert::visit_while_command (tree_while_command& wc)
 {
-  fail ();
+  assert (! breaking);
+  unwind_protect prot;
+  prot.protect_var (breaks);
+  prot.protect_var (continues);
+  prot.protect_var (breaking);
+  breaks.clear ();
+  continues.clear ();
+
+  jit_block *cond_check = create<jit_block> ("while_cond_check");
+  block->append (create<jit_branch> (cond_check));
+  append (cond_check);
+  block = cond_check;
+
+  tree_expression *expr = wc.condition ();
+  assert (expr && "While expression can not be null");
+  jit_value *check = visit (expr);
+  check = create_checked (&jit_typeinfo::logically_true, check);
+
+  jit_block *body = create<jit_block> ("while_body");
+  append (body);
+
+  jit_block *tail = create<jit_block> ("while_tail");
+  block->append (create<jit_cond_branch> (check, body, tail));
+  block = body;
+
+  tree_statement_list *loop_body = wc.body ();
+  if (loop_body)
+    loop_body->accept (*this);
+
+  finish_breaks (tail, breaks);
+  finish_breaks (cond_check, continues);
+
+  if (! breaking)
+    block->append (create<jit_branch> (cond_check));
+
+  append (tail);
+  block = tail;
 }
 
 void
--- a/src/pt-jit.h	Wed Jul 11 14:42:56 2012 -0500
+++ b/src/pt-jit.h	Wed Jul 11 17:34:22 2012 -0500
@@ -1373,7 +1373,7 @@
 
   void create_dom_tree (size_t avisit_count);
 
-  jit_block *idom_intersect (jit_block *b);
+  static jit_block *idom_intersect (jit_block *i, jit_block *j);
 
   size_t mvisit_count;
   size_t mid;