Mercurial > hg > octave-nkf
changeset 15182:a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
* jit-ir.cc (jit_factory, jit_block_list): New class.
(jit_block::maybe_split): Use jit_factory and jit_block_list instead of
jit_convert.
(jit_magic_end::context::context): Use jit_factory instead of jit_convert.
* jit-ir.h (jit_factory, jit_block_list): New class.
(jit_block::maybe_split): Use jit_block_list and jit_factory.
(jit_magic_end::context::context) Use jit_factory.
* pt-jit.cc (jit_convert): Use jit_factory and jit_block_list instead of
internal methods.
(jit_convert::append): Removed method.
(jit_convert::create_checked_impl): Merg in jit_convert::create_check.
(jit_convert::insert_before, jit_convert;:insert_after,
jit_convert::~jit_convert, jit_convert::append): Remove method.
(jit_convert_llvm::convert): Use jit_block_list.
* pt-jit.h (jit_convert::~jit_convert, jit_convert::append): Remove declaration.
(jit_convert::create, jit_convert::insert_before, jit_convert::insert_after,
jit_convert::track_value): Remove method.
(jit_convert_llvm::convert): Use jit_block_list.
author | Max Brister <max@2bass.com> |
---|---|
date | Wed, 15 Aug 2012 23:30:02 -0500 |
parents | ed2b911a2fb3 |
children | 8b9b3677a4d6 |
files | src/interp-core/jit-ir.cc src/interp-core/jit-ir.h src/interp-core/pt-jit.cc src/interp-core/pt-jit.h |
diffstat | 4 files changed, 266 insertions(+), 207 deletions(-) [+] |
line wrap: on
line diff
--- a/src/interp-core/jit-ir.cc +++ b/src/interp-core/jit-ir.cc @@ -36,7 +36,57 @@ #include <llvm/Instructions.h> #include "error.h" -#include "pt-jit.h" + +// -------------------- jit_factory -------------------- +jit_factory::~jit_factory (void) +{ + for (value_list::iterator iter = all_values.begin (); + iter != all_values.end (); ++iter) + delete *iter; +} + +void +jit_factory::track_value (jit_value *value) +{ + if (value->type ()) + mconstants.push_back (value); + all_values.push_back (value); +} + +// -------------------- jit_block_list -------------------- +void +jit_block_list::insert_after (iterator iter, jit_block *ablock) +{ + ++iter; + insert_before (iter, ablock); +} + +void +jit_block_list::insert_after (jit_block *loc, jit_block *ablock) +{ + insert_after (loc->location (), ablock); +} + +void +jit_block_list::insert_before (iterator iter, jit_block *ablock) +{ + iter = mlist.insert (iter, ablock); + ablock->stash_location (iter); +} + +void +jit_block_list::insert_before (jit_block *loc, jit_block *ablock) +{ + insert_before (loc->location (), ablock); +} + +void +jit_block_list::push_back (jit_block *b) +{ + mlist.push_back (b); + iterator iter = mlist.end (); + b->stash_location (--iter); +} // -------------------- jit_use -------------------- jit_block * @@ -396,19 +446,20 @@ } jit_block * -jit_block::maybe_split (jit_convert& convert, jit_block *asuccessor) +jit_block::maybe_split (jit_factory& factory, jit_block_list& blocks, + jit_block *asuccessor) { if (successor_count () > 1) { jit_terminator *term = terminator (); size_t idx = term->successor_index (asuccessor); - jit_block *split = convert.create<jit_block> ("phi_split", mvisit_count); + jit_block *split = factory.create<jit_block> ("phi_split", mvisit_count); // place after this to ensure define before use in the blocks list - convert.insert_after (this, split); + blocks.insert_after (this, split); term->stash_argument (idx, split); - jit_branch *br = split->append (convert.create<jit_branch> (asuccessor)); + jit_branch *br = split->append (factory.create<jit_branch> (asuccessor)); replace_in_phi (asuccessor, split); if (alive ()) @@ -596,10 +647,10 @@ } // -------------------- jit_magic_end -------------------- -jit_magic_end::context::context (jit_convert& convert, jit_value *avalue, +jit_magic_end::context::context (jit_factory& factory, jit_value *avalue, size_t aindex, size_t acount) - : value (avalue), index (convert.create<jit_const_index> (aindex)), - count (convert.create<jit_const_index> (acount)) + : value (avalue), index (factory.create<jit_const_index> (aindex)), + count (factory.create<jit_const_index> (acount)) {} jit_magic_end::jit_magic_end (const std::vector<context>& full_context)
--- a/src/interp-core/jit-ir.h +++ b/src/interp-core/jit-ir.h @@ -69,8 +69,6 @@ #undef JIT_METH -class jit_convert; - // ABCs which aren't included in JIT_VISIT_IR_ALL class jit_instruction; class jit_terminator; @@ -92,6 +90,89 @@ class jit_ir_walker; class jit_use; +// Creates and tracks memory for jit_value and subclasses. +// Memory managment is simple, all values that are created live as long as the +// factory. +class +jit_factory +{ + typedef std::list<jit_value *> value_list; +public: + ~jit_factory (void); + + const value_list& constants (void) const { return mconstants; } + + // this would be easier with variadic templates + template <typename T> + T *create (void) + { + T *ret = new T (); + track_value (ret); + return ret; + } + +#define DECL_ARG(n) const ARG ## n& arg ## n +#define JIT_CREATE(N) \ + template <typename T, OCT_MAKE_DECL_LIST (typename, ARG, N)> \ + T *create (OCT_MAKE_LIST (DECL_ARG, N)) \ + { \ + T *ret = new T (OCT_MAKE_ARG_LIST (arg, N)); \ + track_value (ret); \ + return ret; \ + } + + JIT_CREATE (1) + JIT_CREATE (2) + JIT_CREATE (3) + JIT_CREATE (4) + +#undef JIT_CREATE +private: + void track_value (jit_value *v); + + value_list all_values; + + value_list mconstants; +}; + +// A list of basic blocks (jit_block) which form some body of code. +// +// We do not directly inherit from std::list because we need to update the +// blocks stashed location in push_back and insert. +class +jit_block_list +{ +public: + typedef std::list<jit_block *>::iterator iterator; + typedef std::list<jit_block *>::const_iterator const_iterator; + + jit_block *back (void) const { return mlist.back (); } + + iterator begin (void) { return mlist.begin (); } + + const_iterator begin (void) const { return mlist.begin (); } + + iterator end (void) { return mlist.end (); } + + const_iterator end (void) const { return mlist.end (); } + + iterator erase (iterator iter) { return mlist.erase (iter); } + + jit_block *front (void) const { return mlist.front (); } + + void insert_after (iterator iter, jit_block *ablock); + + void insert_after (jit_block *loc, jit_block *ablock); + + void insert_before (iterator iter, jit_block *ablock); + + void insert_before (jit_block *loc, jit_block *ablock); + + void push_back (jit_block *b); +private: + std::list<jit_block *> mlist; +}; + class jit_value : public jit_internal_list<jit_value, jit_use> { @@ -633,12 +714,13 @@ return os; } - // ... - jit_block *maybe_split (jit_convert& convert, jit_block *asuccessor); + jit_block *maybe_split (jit_factory& factory, jit_block_list& blocks, + jit_block *asuccessor); - jit_block *maybe_split (jit_convert& convert, jit_block& asuccessor) + jit_block *maybe_split (jit_factory& factory, jit_block_list& blocks, + jit_block& asuccessor) { - return maybe_split (convert, &asuccessor); + return maybe_split (factory, blocks, &asuccessor); } // print dominator infomration @@ -1162,7 +1244,7 @@ context (void) : value (0), index (0), count (0) {} - context (jit_convert& convert, jit_value *avalue, size_t aindex, + context (jit_factory& factory, jit_value *avalue, size_t aindex, size_t acount); jit_value *value;
--- a/src/interp-core/pt-jit.cc +++ b/src/interp-core/pt-jit.cc @@ -64,9 +64,9 @@ { jit_instruction::reset_ids (); - entry_block = create<jit_block> ("body"); - final_block = create<jit_block> ("final"); - append (entry_block); + entry_block = factory.create<jit_block> ("body"); + final_block = factory.create<jit_block> ("final"); + blocks.push_back (entry_block); entry_block->mark_alive (); block = entry_block; @@ -80,21 +80,22 @@ assert (breaks.empty ()); assert (continues.empty ()); - block->append (create<jit_branch> (final_block)); - append (final_block); + block->append (factory.create<jit_branch> (final_block)); + blocks.push_back (final_block); for (vmap_t::iterator iter = vmap.begin (); iter != vmap.end (); ++iter) { jit_variable *var = iter->second; const std::string& name = var->name (); if (name.size () && name[0] != '#') - final_block->append (create<jit_store_argument> (var)); + final_block->append (factory.create<jit_store_argument> (var)); } construct_ssa (); // initialize the worklist to instructions derived from constants - for (std::list<jit_value *>::iterator iter = constants.begin (); + const std::list<jit_value *>& constants = factory.constants (); + for (std::list<jit_value *>::const_iterator iter = constants.begin (); iter != constants.end (); ++iter) append_users (*iter); @@ -151,13 +152,6 @@ #endif } -jit_convert::~jit_convert (void) -{ - for (std::list<jit_value *>::iterator iter = all_values.begin (); - iter != all_values.end (); ++iter) - delete *iter; -} - void jit_convert::visit_anon_fcn_handle (tree_anon_fcn_handle&) { @@ -181,40 +175,40 @@ bool is_and = boole->op_type () == tree_boolean_expression::bool_and; std::string short_name = next_shortcircut_result (); - jit_variable *short_result = create<jit_variable> (short_name); + jit_variable *short_result = factory.create<jit_variable> (short_name); vmap[short_name] = short_result; - jit_block *done = create<jit_block> (block->name ()); + jit_block *done = factory.create<jit_block> (block->name ()); tree_expression *lhs = be.lhs (); jit_value *lhsv = visit (lhs); lhsv = create_checked (&jit_typeinfo::logically_true, lhsv); - jit_block *short_early = create<jit_block> ("short_early"); - append (short_early); + jit_block *short_early = factory.create<jit_block> ("short_early"); + blocks.push_back (short_early); - jit_block *short_cont = create<jit_block> ("short_cont"); + jit_block *short_cont = factory.create<jit_block> ("short_cont"); if (is_and) - block->append (create<jit_cond_branch> (lhsv, short_cont, short_early)); + block->append (factory.create<jit_cond_branch> (lhsv, short_cont, short_early)); else - block->append (create<jit_cond_branch> (lhsv, short_early, short_cont)); + block->append (factory.create<jit_cond_branch> (lhsv, short_early, short_cont)); block = short_early; - jit_value *early_result = create<jit_const_bool> (! is_and); - block->append (create<jit_assign> (short_result, early_result)); - block->append (create<jit_branch> (done)); + jit_value *early_result = factory.create<jit_const_bool> (! is_and); + block->append (factory.create<jit_assign> (short_result, early_result)); + block->append (factory.create<jit_branch> (done)); - append (short_cont); + blocks.push_back (short_cont); block = short_cont; tree_expression *rhs = be.rhs (); jit_value *rhsv = visit (rhs); rhsv = create_checked (&jit_typeinfo::logically_true, rhsv); - block->append (create<jit_assign> (short_result, rhsv)); - block->append (create<jit_branch> (done)); + block->append (factory.create<jit_assign> (short_result, rhsv)); + block->append (factory.create<jit_branch> (done)); - append (done); + blocks.push_back (done); block = done; result = short_result; } @@ -250,9 +244,9 @@ if (tinc) increment = visit (tinc); else - increment = create<jit_const_scalar> (1); + increment = factory.create<jit_const_scalar> (1); - result = block->append (create<jit_call> (jit_typeinfo::make_range, base, + result = block->append (factory.create<jit_call> (jit_typeinfo::make_range, base, limit, increment)); } @@ -305,32 +299,34 @@ // we need a variable for our iterator, because it is used in multiple blocks std::string iter_name = next_iterator (); - jit_variable *iterator = create<jit_variable> (iter_name); - create<jit_variable> (iter_name); + jit_variable *iterator = factory.create<jit_variable> (iter_name); + factory.create<jit_variable> (iter_name); vmap[iter_name] = iterator; - jit_block *body = create<jit_block> ("for_body"); - append (body); + jit_block *body = factory.create<jit_block> ("for_body"); + blocks.push_back (body); - jit_block *tail = create<jit_block> ("for_tail"); + jit_block *tail = factory.create<jit_block> ("for_tail"); // do control expression, iter init, and condition check in prev_block (block) // if we are the top level for loop, the bounds is an input argument. jit_value *control = find_variable (next_for_bounds ()); if (! control) control = visit (cmd.control_expr ()); - jit_call *init_iter = create<jit_call> (jit_typeinfo::for_init, control); + jit_call *init_iter = factory.create<jit_call> (jit_typeinfo::for_init, + control); block->append (init_iter); - block->append (create<jit_assign> (iterator, init_iter)); + block->append (factory.create<jit_assign> (iterator, init_iter)); - jit_value *check = block->append (create<jit_call> (jit_typeinfo::for_check, - control, iterator)); - block->append (create<jit_cond_branch> (check, body, tail)); + jit_call *check = factory.create<jit_call> (jit_typeinfo::for_check, control, + iterator); + block->append (check); + block->append (factory.create<jit_cond_branch> (check, body, tail)); block = body; // compute the syntactical iterator - jit_call *idx_rhs = create<jit_call> (jit_typeinfo::for_index, control, - iterator); + jit_call *idx_rhs = factory.create<jit_call> (jit_typeinfo::for_index, + control, iterator); block->append (idx_rhs); do_assign (cmd.left_hand_side (), idx_rhs); @@ -343,31 +339,31 @@ // WTF are you doing user? Every branch was a continue, why did you have // a loop??? Users are silly people... finish_breaks (tail, breaks); - append (tail); + blocks.push_back (tail); block = tail; return; } // check our condition, continues jump to this block - jit_block *check_block = create<jit_block> ("for_check"); - append (check_block); + jit_block *check_block = factory.create<jit_block> ("for_check"); + blocks.push_back (check_block); if (! breaking) - block->append (create<jit_branch> (check_block)); + block->append (factory.create<jit_branch> (check_block)); finish_breaks (check_block, continues); block = check_block; const jit_operation& add_fn = jit_typeinfo::binary_op (octave_value::op_add); - jit_value *one = create<jit_const_index> (1); - jit_call *iter_inc = create<jit_call> (add_fn, iterator, one); + jit_value *one = factory.create<jit_const_index> (1); + jit_call *iter_inc = factory.create<jit_call> (add_fn, iterator, one); block->append (iter_inc); - block->append (create<jit_assign> (iterator, iter_inc)); - check = block->append (create<jit_call> (jit_typeinfo::for_check, control, + block->append (factory.create<jit_assign> (iterator, iter_inc)); + check = block->append (factory.create<jit_call> (jit_typeinfo::for_check, control, iterator)); - block->append (create<jit_cond_branch> (check, body, tail)); + block->append (factory.create<jit_cond_branch> (check, body, tail)); // breaks will go to our tail - append (tail); + blocks.push_back (tail); finish_breaks (tail, breaks); block = tail; } @@ -415,7 +411,7 @@ { if (!end_context.size ()) throw jit_fail_exception ("Illegal end"); - result = block->append (create<jit_magic_end> (end_context)); + result = block->append (factory.create<jit_magic_end> (end_context)); } else result = get_variable (ti.name ()); @@ -455,12 +451,12 @@ { tree_if_clause *tic = *iter; if (tic->is_else_clause ()) - entry_blocks[i] = create<jit_block> ("else"); + entry_blocks[i] = factory.create<jit_block> ("else"); else - entry_blocks[i] = create<jit_block> ("ifelse_cond"); + entry_blocks[i] = factory.create<jit_block> ("ifelse_cond"); } - jit_block *tail = create<jit_block> ("if_tail"); + jit_block *tail = factory.create<jit_block> ("if_tail"); if (! last_else) entry_blocks[entry_blocks.size () - 1] = tail; @@ -473,7 +469,7 @@ assert (block); if (i) // the first block is prev_block, so it has already been added - append (entry_blocks[i]); + blocks.push_back (entry_blocks[i]); if (! tic->is_else_clause ()) { @@ -481,11 +477,11 @@ jit_value *cond = visit (expr); jit_call *check = create_checked (&jit_typeinfo::logically_true, cond); - jit_block *body = create<jit_block> (i == 0 ? "if_body" - : "ifelse_body"); - append (body); + jit_block *body = factory.create<jit_block> (i == 0 ? "if_body" + : "ifelse_body"); + blocks.push_back (body); - jit_instruction *br = create<jit_cond_branch> (check, body, + jit_instruction *br = factory.create<jit_cond_branch> (check, body, entry_blocks[i + 1]); block->append (br); block = body; @@ -500,13 +496,13 @@ else { ++num_incomming; - block->append (create<jit_branch> (tail)); + block->append (factory.create<jit_branch> (tail)); } } if (num_incomming || ! last_else) { - append (tail); + blocks.push_back (tail); block = tail; } else @@ -551,17 +547,17 @@ if (v.is_real_scalar () && v.is_double_type ()) { double dv = v.double_value (); - result = create<jit_const_scalar> (dv); + result = factory.create<jit_const_scalar> (dv); } else if (v.is_range ()) { Range rv = v.range_value (); - result = create<jit_const_range> (rv); + result = factory.create<jit_const_range> (rv); } else if (v.is_complex_scalar ()) { Complex cv = v.complex_value (); - result = create<jit_const_complex> (cv); + result = factory.create<jit_const_complex> (cv); } else throw jit_fail_exception ("Unknown constant"); @@ -673,8 +669,8 @@ // FIXME: ugly hack, we need to come up with a way to pass // nargout to visit_identifier const jit_operation& fn = jit_typeinfo::print_value (); - jit_const_string *name = create<jit_const_string> (expr->name ()); - block->append (create<jit_call> (fn, name, expr_result)); + jit_const_string *name = factory.create<jit_const_string> (expr->name ()); + block->append (factory.create<jit_call> (fn, name, expr_result)); } } } @@ -736,9 +732,9 @@ breaks.clear (); continues.clear (); - jit_block *cond_check = create<jit_block> ("while_cond_check"); - block->append (create<jit_branch> (cond_check)); - append (cond_check); + jit_block *cond_check = factory.create<jit_block> ("while_cond_check"); + block->append (factory.create<jit_branch> (cond_check)); + blocks.push_back (cond_check); block = cond_check; tree_expression *expr = wc.condition (); @@ -746,11 +742,11 @@ 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 *body = factory.create<jit_block> ("while_body"); + blocks.push_back (body); - jit_block *tail = create<jit_block> ("while_tail"); - block->append (create<jit_cond_branch> (check, body, tail)); + jit_block *tail = factory.create<jit_block> ("while_tail"); + block->append (factory.create<jit_cond_branch> (check, body, tail)); block = body; tree_statement_list *loop_body = wc.body (); @@ -761,9 +757,9 @@ finish_breaks (cond_check, continues); if (! breaking) - block->append (create<jit_branch> (cond_check)); + block->append (factory.create<jit_branch> (cond_check)); - append (tail); + blocks.push_back (tail); block = tail; } @@ -773,25 +769,19 @@ throw jit_fail_exception (); } -void -jit_convert::append (jit_block *ablock) -{ - blocks.push_back (ablock); - ablock->stash_location (--blocks.end ()); -} - -void -jit_convert::insert_before (block_iterator iter, jit_block *ablock) +jit_call * +jit_convert::create_checked_impl (jit_call *ret) { - iter = blocks.insert (iter, ablock); - ablock->stash_location (iter); -} + block->append (ret); -void -jit_convert::insert_after (block_iterator iter, jit_block *ablock) -{ - ++iter; - insert_before (iter, ablock); + jit_block *normal = factory.create<jit_block> (block->name ()); + jit_error_check *check = factory.create<jit_error_check> (ret, normal, + final_block); + block->append (check); + blocks.push_back (normal); + block = normal; + + return ret; } jit_variable * @@ -817,9 +807,9 @@ jit_variable * jit_convert::create_variable (const std::string& vname, jit_type *type) { - jit_variable *var = create<jit_variable> (vname); + jit_variable *var = factory.create<jit_variable> (vname); jit_extract_argument *extract; - extract = create<jit_extract_argument> (type, var); + extract = factory.create<jit_extract_argument> (type, var); entry_block->prepend (extract); return vmap[vname] = var; } @@ -867,7 +857,9 @@ unwind_protect prot; prot.add_method (&end_context, &std::vector<jit_magic_end::context>::pop_back); - end_context.push_back (jit_magic_end::context (*this, object, idx, narg)); + + jit_magic_end::context ctx (factory, object, idx, narg); + end_context.push_back (ctx); call_args[idx + 1] = visit (*iter); } @@ -904,7 +896,7 @@ bool print, bool artificial) { jit_variable *var = get_variable (lhs); - jit_assign *assign = block->append (create<jit_assign> (var, rhs)); + jit_assign *assign = block->append (factory.create<jit_assign> (var, rhs)); if (artificial) assign->mark_artificial (); @@ -912,8 +904,8 @@ if (print) { const jit_operation& print_fn = jit_typeinfo::print_value (); - jit_const_string *name = create<jit_const_string> (lhs); - block->append (create<jit_call> (print_fn, name, var)); + jit_const_string *name = factory.create<jit_const_string> (lhs); + block->append (factory.create<jit_call> (print_fn, name, var)); } return var; @@ -976,7 +968,7 @@ jit_block *dblock = *diter; if (! added_phi.count (dblock)) { - jit_phi *phi = create<jit_phi> (iter->second, + jit_phi *phi = factory.create<jit_phi> (iter->second, dblock->use_count ()); dblock->prepend (phi); added_phi.insert (dblock); @@ -1072,7 +1064,8 @@ { jit_block *succ = term->successor (1); term->remove (); - jit_branch *abreak = b->append (create<jit_branch> (succ)); + jit_branch *abreak = factory.create<jit_branch> (succ); + b->append (abreak); abreak->infer (); } @@ -1130,8 +1123,8 @@ if (! arg->needs_release ()) continue; - jit_call *release = create<jit_call> (&jit_typeinfo::release, - arg); + jit_call *release + = factory.create<jit_call> (&jit_typeinfo::release, arg); release->infer (); ablock.insert_after (iter, release); ++iter; @@ -1145,13 +1138,14 @@ // FIXME: If we support try/catch or unwind_protect final_block may not be the // destination - jit_block *split = ablock.maybe_split (*this, final_block); + jit_block *split = ablock.maybe_split (factory, blocks, final_block); jit_terminator *term = split->terminator (); for (std::set<jit_value *>::const_iterator iter = temp.begin (); iter != temp.end (); ++iter) { jit_value *value = *iter; - jit_call *release = create<jit_call> (&jit_typeinfo::release, value); + jit_call *release + = factory.create<jit_call> (&jit_typeinfo::release, value); split->insert_before (term, release); release->infer (); } @@ -1178,9 +1172,10 @@ continue; jit_block *inc = phi->incomming (i); - jit_block *split = inc->maybe_split (*this, ablock); + jit_block *split = inc->maybe_split (factory, blocks, ablock); jit_terminator *term = split->terminator (); - jit_call *release = create<jit_call> (jit_typeinfo::release, arg); + jit_call *release + = factory.create<jit_call> (jit_typeinfo::release, arg); release->infer (); split->insert_before (term, release); } @@ -1216,10 +1211,10 @@ if (arg->type () != phi.type ()) { jit_block *pred = phi.incomming (i); - jit_block *split = pred->maybe_split (*this, pblock); + jit_block *split = pred->maybe_split (factory, blocks, pblock); jit_terminator *term = split->terminator (); - jit_instruction *cast = create<jit_call> (cast_fn, arg); - jit_assign *assign = create<jit_assign> (dest, cast); + jit_instruction *cast = factory.create<jit_call> (cast_fn, arg); + jit_assign *assign = factory.create<jit_assign> (dest, cast); split->insert_before (term, cast); split->insert_before (term, assign); @@ -1237,7 +1232,7 @@ ++iter) { jit_block *b = *iter; - b->append (create<jit_branch> (dest)); + b->append (factory.create<jit_branch> (dest)); } } @@ -1246,7 +1241,7 @@ jit_convert_llvm::convert (llvm::Module *module, const std::vector<std::pair<std::string, bool> >& args, - const std::list<jit_block *>& blocks, + const jit_block_list& blocks, const std::list<jit_value *>& constants) { jit_type *any = jit_typeinfo::get_any ();
--- a/src/interp-core/pt-jit.h +++ b/src/interp-core/pt-jit.h @@ -39,8 +39,6 @@ jit_convert (llvm::Module *module, tree &tee, jit_type *for_bounds = 0); - ~jit_convert (void); - llvm::Function *get_function (void) const { return function; } const std::vector<std::pair<std::string, bool> >& get_arguments(void) const @@ -134,37 +132,11 @@ void visit_do_until_command (tree_do_until_command&); - // this would be easier with variadic templates - template <typename T> - T *create (void) - { - T *ret = new T(); - track_value (ret); - return ret; - } - -#define DECL_ARG(n) const ARG ## n& arg ## n -#define JIT_CREATE(N) \ - template <typename T, OCT_MAKE_DECL_LIST (typename, ARG, N)> \ - T *create (OCT_MAKE_LIST (DECL_ARG, N)) \ - { \ - T *ret = new T (OCT_MAKE_ARG_LIST (arg, N)); \ - track_value (ret); \ - return ret; \ - } - - JIT_CREATE (1) - JIT_CREATE (2) - JIT_CREATE (3) - JIT_CREATE (4) - -#undef JIT_CREATE - #define JIT_CREATE_CHECKED(N) \ template <OCT_MAKE_DECL_LIST (typename, ARG, N)> \ jit_call *create_checked (OCT_MAKE_LIST (DECL_ARG, N)) \ { \ - jit_call *ret = create<jit_call> (OCT_MAKE_ARG_LIST (arg, N)); \ + jit_call *ret = factory.create<jit_call> (OCT_MAKE_ARG_LIST (arg, N)); \ return create_checked_impl (ret); \ } @@ -175,29 +147,12 @@ #undef JIT_CREATE_CHECKED #undef DECL_ARG - - typedef std::list<jit_block *> block_list; - typedef block_list::iterator block_iterator; - - void append (jit_block *ablock); - - void insert_before (block_iterator iter, jit_block *ablock); - - void insert_before (jit_block *loc, jit_block *ablock) - { - insert_before (loc->location (), ablock); - } - - void insert_after (block_iterator iter, jit_block *ablock); - - void insert_after (jit_block *loc, jit_block *ablock) - { - insert_after (loc->location (), ablock); - } private: std::vector<std::pair<std::string, bool> > arguments; type_bound_vector bounds; + jit_factory factory; + // used instead of return values from visit_* functions jit_value *result; @@ -209,14 +164,10 @@ llvm::Function *function; - std::list<jit_block *> blocks; + jit_block_list blocks; std::list<jit_instruction *> worklist; - std::list<jit_value *> constants; - - std::list<jit_value *> all_values; - std::vector<jit_magic_end::context> end_context; size_t iterator_count; @@ -226,23 +177,7 @@ typedef std::map<std::string, jit_variable *> vmap_t; vmap_t vmap; - jit_call *create_checked_impl (jit_call *ret) - { - block->append (ret); - create_check (ret); - return ret; - } - - jit_error_check *create_check (jit_call *call) - { - jit_block *normal = create<jit_block> (block->name ()); - jit_error_check *ret - = block->append (create<jit_error_check> (call, normal, final_block)); - append (normal); - block = normal; - - return ret; - } + jit_call *create_checked_impl (jit_call *ret); // get an existing vairable. If the variable does not exist, it will not be // created @@ -300,13 +235,6 @@ void append_users_term (jit_terminator *term); - void track_value (jit_value *value) - { - if (value->type ()) - constants.push_back (value); - all_values.push_back (value); - } - void construct_ssa (void); void do_construct_ssa (jit_block& block, size_t avisit_count); @@ -348,6 +276,8 @@ } bool breaking; // true if we are breaking OR continuing + + typedef std::list<jit_block *> block_list; block_list breaks; block_list continues; @@ -362,8 +292,9 @@ jit_convert_llvm (jit_convert& jc) : jthis (jc) {} llvm::Function *convert (llvm::Module *module, - const std::vector<std::pair<std::string, bool> >& args, - const std::list<jit_block *>& blocks, + const std::vector<std::pair<std::string, bool> >& + args, + const jit_block_list& blocks, const std::list<jit_value *>& constants); #define JIT_METH(clname) \