# HG changeset patch # User Max Brister # Date 1342046062 18000 # Node ID dfaa8da46364508b207d614e3ddae07d4a815ed3 # Parent 822d52bee9731b1162b6dd806837f9c9fbf1ac86 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. diff -r 822d52bee973 -r dfaa8da46364 src/pt-jit.cc --- 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 ("while_cond_check"); + block->append (create (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 ("while_body"); + append (body); + + jit_block *tail = create ("while_tail"); + block->append (create (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 (cond_check)); + + append (tail); + block = tail; } void diff -r 822d52bee973 -r dfaa8da46364 src/pt-jit.h --- 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;