Mercurial > octave-nkf
diff libinterp/corefcn/pt-jit.cc @ 20654:b65888ec820e draft default tip gccjit
dmalcom gcc jit import
author | Stefan Mahr <dac922@gmx.de> |
---|---|
date | Fri, 27 Feb 2015 16:59:36 +0100 |
parents | d35201e5ce5d |
children |
line wrap: on
line diff
--- a/libinterp/corefcn/pt-jit.cc Tue Oct 13 11:40:05 2015 +0100 +++ b/libinterp/corefcn/pt-jit.cc Fri Feb 27 16:59:36 2015 +0100 @@ -38,7 +38,7 @@ #include "symtab.h" #include "variables.h" -#ifdef HAVE_LLVM +#ifdef HAVE_JIT static bool Vdebug_jit = false; @@ -48,6 +48,7 @@ static int Vjit_failcnt = 0; +#ifdef HAVE_LLVM #include <llvm/Analysis/CallGraph.h> #include <llvm/Analysis/Passes.h> @@ -101,6 +102,8 @@ static llvm::LLVMContext& context = llvm::getGlobalContext (); +#endif /* ifdef HAVE_LLVM */ + // -------------------- jit_break_exception -------------------- // jit_break is thrown whenever a branch we are converting has only breaks or @@ -1295,7 +1298,565 @@ } } +// -------------------- jit_convert_gcc -------------------- +#ifdef HAVE_GCCJIT +jit_convert_gcc::jit_convert_gcc () + : m_blocks (NULL), + m_constants (NULL), + m_ctxt (jit_typeinfo::create_gccjit_child_context ()), + m_func (), + m_extracted_params (), + m_block_map (), + m_locals_for_insns (), + m_block_stack (), + m_log_visits (false) +{ + // FIXME: error-handling + + m_ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + 3); + + // Diagnostics, debugging etc: + if (1) + { + m_ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, + 1); + m_ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, + 0); + m_ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, + 1); + m_ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_SUMMARY, + 1); + m_ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + 0); + m_ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, + 1); + m_ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_SELFCHECK_GC, + 0); + m_ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, + 1); + } +} + +jit_convert_gcc::~jit_convert_gcc () +{ + m_ctxt.release (); +} + +gcc_jit_result * +jit_convert_gcc::convert_loop (const jit_block_list& blocks, + const std::list<jit_value *>& constants) +{ + converting_function = false; + + m_blocks = &blocks; + m_constants = &constants; + + jit_type *any = jit_typeinfo::get_any (); + // argument is an array of octave_base_value*, or octave_base_value** + gccjit::type arg_type = any->to_gccjit (); // this is octave_base_value* + arg_type = arg_type.get_pointer (); + + // for now just init arguments from entry, later we will have to do something + // more interesting + jit_block *entry_block = m_blocks->front (); + for (jit_block::iterator iter = entry_block->begin (); + iter != entry_block->end (); ++iter) + if (jit_extract_argument *extract + = dynamic_cast<jit_extract_argument *> (*iter)) + { + m_argument_index[extract->name ()] = m_argument_vec.size (); + m_argument_vec.push_back (std::make_pair (extract->name (), true)); + } + + /* We have a single param, confusingly named "params" (an array). */ + params = m_ctxt.new_param (arg_type, "params"); + + std::vector<gccjit::param> params_of_fn (1, params); + + m_func = m_ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, + m_ctxt.get_type (GCC_JIT_TYPE_VOID), + "loop", + params_of_fn, + 0); + + gccjit::block initial_block = m_func.new_block ("initial"); + + /* Create gccjit::blocks for each jit_block, and for each edge. + + We're converting from an SSA representation back to a non-SSA + representation, hence we need to convert phi nodes into regular + assignments. To do this, introduce a gccjit::block for each edge, to + handle the phis along each edges. Jumps to blocks in the JIT-IR + will become jumps to edge-handling gccjit::blocks in our CFG; each + such "edge" block will end with a jump to the "real" gccjit::block. */ + std::list<jit_block *>::const_iterator block_iter; + for (block_iter = m_blocks->begin (); + block_iter != m_blocks->end (); + ++block_iter) + { + jit_block *jblock = *block_iter; + + // Find predecessor blocks + for (jit_use *use = jblock->first_use (); use; use = use->next ()) + { + jit_block *pred = use->user_parent (); + + /* Create edge-handling gccjit::block. */ + m_blocks_for_edges[std::make_pair(pred, jblock)] = + m_func.new_block (std::string ("edge_from_") + + pred->name_and_id () + + std::string ("_to_") + + jblock->name_and_id ()); + } + + /* The "real" gccjit::block. */ + m_block_map[jblock] = + m_func.new_block (jblock->name_and_id ()); + } + + /* It's an SSA representation, so we have another pass here that + creates a local for every statement. */ + for (block_iter = m_blocks->begin (); + block_iter != m_blocks->end (); + ++block_iter) + for (jit_block::iterator insn_iter = (*block_iter)->begin (); + insn_iter != (*block_iter)->end (); + ++insn_iter) + { + jit_instruction *insn = *insn_iter; + + /* Some insns have NULL type e.g. conditional branches; it only + makes sense to create a local for those with actual types. */ + if (insn->type ()) + { + std::stringstream ss; + // FIXME: perhaps make these identifiers look less weird? + // that said, the short_print vfunc conveys more information + ss << "("; + insn->short_print (ss); + ss << ")"; + + m_locals_for_insns[insn] = + m_func.new_local (insn->type_gccjit (), + ss.str ().c_str ()); + + insn->stash_rvalue (m_locals_for_insns[insn]); + } + } + + // constants aren't in the IR, we visit those first + for (std::list<jit_value *>::const_iterator iter = m_constants->begin (); + iter != m_constants->end (); ++iter) + if (! isa<jit_instruction> (*iter)) + visit (*iter); + + /* Prelude: extract params from the "params" array. */ + if (m_with_comments) + initial_block.add_comment ("prelude"); + for (int i = 0; i < m_argument_vec.size (); ++i) + { + gccjit::lvalue extracted_param = + m_func.new_local (any->to_gccjit (), + "extracted_param_" + m_argument_vec[i].first); + m_extracted_params.push_back (extracted_param); + initial_block.add_assignment ( + extracted_param, + m_ctxt.new_array_access ( + params, + m_ctxt.new_rvalue (m_ctxt.get_type (GCC_JIT_TYPE_INT), + i))); + } + initial_block.end_with_jump (m_block_map[*m_blocks->begin ()]); + + // convert all instructions + for (block_iter = m_blocks->begin (); block_iter != m_blocks->end (); ++block_iter) + visit (**block_iter); + + m_ctxt.dump_to_file ("/tmp/loop-dump.c", true); + + m_func.dump_to_dot ("/tmp/loop.dot"); + + return m_ctxt.compile (); +} + +#if 0 +gccjit::lvalue +jit_convert_gcc::as_lvalue (jit_value *jval) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::as_lvalue (jit_value *jval): " << *jval << "\n"; + + if (!jval->has_lvalue ()) + { + gccjit::lvalue local = + m_func.new_local (/* FIXME: */ + m_ctxt.get_type (GCC_JIT_TYPE_INT), + jval->print_string ().c_str ()); + jval->stash_lvalue (local); + } + + return jval->as_lvalue (); +} +#endif + +gccjit::rvalue +jit_convert_gcc::as_rvalue (jit_value *jval) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::as_rvalue (jit_value *jval): " << *jval << "\n"; + //std::map<jit_value *, gcc_jit_rvalue *> m_rvalues; + + if (jit_instruction *insn = dynamic_cast<jit_instruction *> (jval)) + { + return m_locals_for_insns[insn]; + } + + // return gcc_jit_lvalue_as_rvalue (as_lvalue (jval)); + return jval->as_rvalue (); +} + +void +jit_convert_gcc::add_assignment_for_insn (jit_instruction &insn, + gccjit::rvalue val) +{ + //insn.stash_rvalue (val); + if (insn.type ()) + get_current_block ().add_assignment (m_locals_for_insns[&insn], + val); + //TODO: use location of insn +} + +gccjit::block +jit_convert_gcc::get_block_for_edge (jit_block *src, jit_block *dest) +{ + return m_blocks_for_edges[std::make_pair (src, dest)]; +} + +gccjit::block +jit_convert_gcc::get_current_block () +{ + assert (!m_block_stack.empty ()); + return m_block_stack.top (); +} + +void +jit_convert_gcc::push_block (gccjit::block block) +{ + m_block_stack.push (block); +} + +void +jit_convert_gcc::pop_block () +{ + m_block_stack.pop (); +} + + //std::vector<gccjit::block> m_current_block_stack; + + +void +jit_convert_gcc::visit (jit_const_string& cs) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_const_string& cs): " << cs << "\n"; + gccjit::rvalue rvalue = m_ctxt.new_rvalue (cs.value ()); + cs.stash_rvalue (rvalue); +} + +void +jit_convert_gcc::visit (jit_const_bool& cb) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_const_bool& cb): " << cb << "\n"; + gccjit::rvalue rvalue = m_ctxt.new_rvalue (cb.type_gccjit (), + cb.value ()); + cb.stash_rvalue (rvalue); +} + +void +jit_convert_gcc::visit (jit_const_scalar& cs) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_const_scalar& cs): " << cs << "\n"; + gccjit::rvalue rvalue = m_ctxt.new_rvalue (cs.type_gccjit (), + cs.value ()); + cs.stash_rvalue (rvalue); +} + +void +jit_convert_gcc::visit (jit_const_complex& cc) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_const_complex& cc): " << cc << "\n"; +#if 0 + gccjit::rvalue rvalue = m_ctxt.new_rvalue (cc.type_gccjit (), + cc.value ()); + cc.stash_rvalue (rvalue); +#else + throw jit_fail_exception ("TODO"); +#endif +} + +void jit_convert_gcc::visit (jit_const_index& ci) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_const_index& ci): " << ci << "\n"; + gccjit::rvalue rvalue = m_ctxt.new_rvalue (ci.type_gccjit (), + ci.value ()); + ci.stash_rvalue (rvalue); +} + +void +jit_convert_gcc::visit (jit_const_range& cr) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_const_range& cr): " << cr << "\n"; +#if 0 + gccjit::rvalue rvalue = m_ctxt.new_rvalue (cr.type_gccjit (), + cr.value ()); + cr.stash_rvalue (rvalue); +#else + throw jit_fail_exception ("TODO"); +#endif +} + +void +jit_convert_gcc::visit (jit_block& b) +{ + /* First, handle the phi nodes by populating the edge-handling blocks + with assignments that set up the phi nodes's lvalues based on the incoming + edge, then jumping to the "real" block for this block. */ + for (jit_block::iterator insn_iter = b.begin (); + insn_iter != b.end (); + ++insn_iter) + if (jit_phi *phi = dynamic_cast<jit_phi *> (*insn_iter)) + { + for (size_t i = 0; i < phi->argument_count (); ++i) + { + jit_block *pred = phi->incomming (i); + push_block (m_blocks_for_edges[std::make_pair(pred, &b)]); + if (m_with_comments) + { + std::ostringstream os; + os << "incoming edge " << i << " for: "; + phi->print (os); + get_current_block ().add_comment (os.str ()); + } + get_current_block ().add_assignment ( + m_locals_for_insns[phi], + m_locals_for_insns[static_cast <jit_instruction *> (phi->argument (i))]); + pop_block (); + } + } + + /* Terminate the blocks for edges leading to this block. */ + jit_use *use; + for (use = b.first_use (); use; use = use->next ()) + { + jit_block *pred = use->user_parent (); + gccjit::block block_for_edge = + m_blocks_for_edges[std::make_pair(pred, &b)]; + block_for_edge.end_with_jump (m_block_map[&b]); + } + + /* Now generate a block for all of the non-phi instructions. */ + push_block (m_block_map[&b]); + for (jit_block::iterator insn_iter = b.begin (); + insn_iter != b.end (); + ++insn_iter) + { + // We've handled phi nodes above; skip them: + if (dynamic_cast<jit_phi *> (*insn_iter)) + continue; + + if (m_with_comments) + get_current_block ().add_comment (std::string ("jit_instruction: ") + + (*insn_iter)->print_string ()); + visit (*insn_iter); + } + pop_block (); +} + +void +jit_convert_gcc::visit (jit_branch& b) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_branch& b): " << b << "\n"; + + jit_block *this_block = b.parent (); + jit_block *next = b.successor (); + + get_current_block ().end_with_jump (get_block_for_edge (this_block, next)); +} + +void +jit_convert_gcc::visit (jit_cond_branch& cb) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_cond_branch& cb): " << cb << "\n"; + + gccjit::rvalue boolval = as_rvalue (cb.cond ()); + + jit_block *this_block = cb.parent (); + get_current_block ().end_with_conditional ( + boolval, + get_block_for_edge (this_block, cb.successor (0)), + get_block_for_edge (this_block, cb.successor (1))); +} + +void +jit_convert_gcc::visit (jit_call& call) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_call& call): " << call << "\n"; + + const jit_function& ol = call.overload (); + + std::vector<jit_value *> args (call.arguments ().size ()); + for (size_t i = 0; i < args.size (); ++i) + args[i] = call.argument (i); + + gccjit::rvalue ret = ol.call (m_ctxt, get_current_block (), args); + add_assignment_for_insn (call, ret); +} + +void +jit_convert_gcc::visit (jit_extract_argument& extract) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_extract_argument& extract): " << extract << "\n"; + + const std::string& argname = extract.name (); + + // Get the stored (octave_base_value *) + gccjit::lvalue param = m_extracted_params[m_argument_index[argname]]; + + // Convert it to a more specialized type: + const jit_function& ol = extract.overload (); + std::vector<gccjit::rvalue> args (1, param); + gccjit::rvalue extracted = ol.call (m_ctxt, get_current_block (), args); + add_assignment_for_insn (extract, + extracted); +} + +void +jit_convert_gcc::visit (jit_store_argument& store) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_store_argument& store): " << store << "\n"; + + const jit_function& ol = store.overload (); + + std::vector<jit_value *> args (1); + args[0] = store.result (); + + gccjit::rvalue ret = ol.call (m_ctxt, get_current_block (), args); + int index = m_argument_index[store.name ()]; + get_current_block ().add_assignment ( + // "params[index] = ..." + m_ctxt.new_array_access ( + params, + m_ctxt.new_rvalue (m_ctxt.get_type (GCC_JIT_TYPE_INT), + index)), + // "... = ret;" + ret); +} + +void +jit_convert_gcc::visit (jit_return& ret) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_return& ret): " << ret << "\n"; + jit_value *res = ret.result (); + + if (converting_function) + throw jit_fail_exception ("TODO"); + else + { + if (res) + get_current_block ().end_with_return (res->as_rvalue ()); + else + get_current_block ().end_with_return (); + } +} + +void +jit_convert_gcc::visit (jit_phi& phi) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_phi& phi): " << phi << "\n"; + throw jit_fail_exception ("TODO"); +} + +void +jit_convert_gcc::visit (jit_variable& var) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_variable&): " << var << "\n"; + throw jit_fail_exception ("TODO"); +} + +void +jit_convert_gcc::visit (jit_error_check& check) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_error_check& check): " << check << "\n"; + + gccjit::rvalue cond; + + switch (check.check_variable ()) + { + case jit_error_check::var_error_state: + cond = jit_typeinfo::insert_error_check (m_func); + break; + case jit_error_check::var_interrupt: + cond = jit_typeinfo::insert_interrupt_check (m_func); + break; + default: + panic_impossible (); + } + + jit_block *this_block = check.parent (); + get_current_block ().end_with_conditional ( + cond, + get_block_for_edge (this_block, check.successor (0)), + get_block_for_edge (this_block, check.successor (1))); +} + +void +jit_convert_gcc::visit (jit_assign& assign) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_assign& assign): " << assign << "\n"; + + jit_value *jsrc = assign.src (); + + add_assignment_for_insn (assign, + as_rvalue (jsrc)); +} + +void +jit_convert_gcc::visit (jit_argument& arg) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_argument&): " << arg << "\n"; + throw jit_fail_exception ("TODO"); +} + +void +jit_convert_gcc::visit (jit_magic_end& me) +{ + if (m_log_visits) + std::cerr << "jit_convert_gcc::visit (jit_magic_end& me): " << me << "\n"; + throw jit_fail_exception ("TODO"); +} +#endif /* HAVE_GCCJIT */ + // -------------------- jit_convert_llvm -------------------- + +#ifdef HAVE_LLVM + llvm::Function * jit_convert_llvm::convert_loop (llvm::Module *module, const jit_block_list& blocks, @@ -1361,7 +1922,11 @@ jit_return *ret = dynamic_cast<jit_return *> (final_block->back ()); assert (ret); - creating = jit_function (module, jit_convention::internal, + creating = jit_function (module, +#ifdef HAVE_GCCJIT + gccjit::context (), // FIXME? +#endif + jit_convention::internal, "foobar", ret->result_type (), args); function = creating.to_llvm (); @@ -1649,6 +2214,8 @@ me.stash_llvm (ret); } +#endif /* ifdef HAVE_LLVM */ + // -------------------- jit_infer -------------------- jit_infer::jit_infer (jit_factory& afactory, jit_block_list& ablocks, const variable_map& avmap) @@ -2052,6 +2619,7 @@ bool tree_jit::initialize (void) { +#ifdef HAVE_LLVM if (engine) return true; @@ -2089,8 +2657,13 @@ pass_manager->add (llvm::createGVNPass ()); pass_manager->add (llvm::createCFGSimplificationPass ()); pass_manager->doInitialization (); - - jit_typeinfo::initialize (module, engine); +#endif /* ifdef HAVE_LLVM */ + + jit_typeinfo::initialize ( +#ifdef HAVE_LLVM + module, engine +#endif +); return true; } @@ -2177,7 +2750,7 @@ return 0; } - +#ifdef HAVE_LLVM void tree_jit::optimize (llvm::Function *fn) { @@ -2200,8 +2773,10 @@ llvm::WriteBitcodeToFile (module, fout); } } +#endif /* ifdef HAVE_LLVM */ // -------------------- jit_function_info -------------------- +#ifdef HAVE_JIT jit_function_info::jit_function_info (tree_jit& tjit, octave_user_function& fcn, const octave_value_list& ov_args) @@ -2217,6 +2792,21 @@ try { jit_convert conv (fcn, argument_types); + + if (Vdebug_jit) + { + jit_block_list& blocks = conv.get_blocks (); + blocks.label (); + std::cout << "-------------------- Compiling function "; + std::cout << "--------------------\n"; + + tree_print_code tpc (std::cout); + tpc.visit_octave_user_function_header (fcn); + tpc.visit_statement_list (*fcn.body ()); + tpc.visit_octave_user_function_trailer (fcn); + blocks.print (std::cout, "octave jit ir"); + } + jit_infer infer (conv.get_factory (), conv.get_blocks (), conv.get_variable_map ()); infer.infer (); @@ -2253,7 +2843,11 @@ std::string wrapper_name = fcn.name () + "_wrapper"; jit_type *any_t = jit_typeinfo::get_any (); std::vector<jit_type *> wrapper_args (1, jit_typeinfo::get_any_ptr ()); - wrapper = jit_function (module, jit_convention::internal, wrapper_name, + wrapper = jit_function (module, +#ifdef HAVE_GCCJIT + gccjit::context (), // FIXME +#endif + jit_convention::internal, wrapper_name, any_t, wrapper_args); llvm::BasicBlock *wrapper_body = wrapper.new_block (); @@ -2318,6 +2912,7 @@ raw_fn.erase (); } } +#endif /* ifdef HAVE_JIT */ bool jit_function_info::execute (const octave_value_list& ov_args, @@ -2363,14 +2958,21 @@ } // -------------------- jit_info -------------------- +#ifdef HAVE_LLVM jit_info::jit_info (tree_jit& tjit, tree& tee) : engine (tjit.get_engine ()), function (0), llvm_function (0) +#ifdef HAVE_GCCJIT + , gccjit_result (NULL) +#endif { compile (tjit, tee); } jit_info::jit_info (tree_jit& tjit, tree& tee, const octave_value& for_bounds) : engine (tjit.get_engine ()), function (0), llvm_function (0) +#ifdef HAVE_GCCJIT + , gccjit_result (NULL) +#endif { compile (tjit, tee, jit_typeinfo::type_of (for_bounds)); } @@ -2379,7 +2981,12 @@ { if (llvm_function) llvm_function->eraseFromParent (); +#ifdef HAVE_GCCJIT + if (gccjit_result) + gcc_jit_result_release (gccjit_result); +#endif } +#endif bool jit_info::execute (const vmap& extra_vars) const @@ -2435,12 +3042,23 @@ return true; } +#ifdef HAVE_LLVM void jit_info::compile (tree_jit& tjit, tree& tee, jit_type *for_bounds) { try { jit_convert conv (tee, for_bounds); + + if (Vdebug_jit) + { + jit_block_list& blocks = conv.get_blocks (); + blocks.label (); + std::cout << "-------------------- Compiling tree --------------------\n"; + std::cout << tee.str_print_code () << std::endl; + blocks.print (std::cout, "octave jit ir"); + } + jit_infer infer (conv.get_factory (), conv.get_blocks (), conv.get_variable_map ()); @@ -2456,6 +3074,13 @@ } jit_factory& factory = conv.get_factory (); + +#ifdef HAVE_GCCJIT + jit_convert_gcc to_gcc; + gccjit_result = to_gcc.convert_loop (infer.get_blocks (), + factory.constants ()); +#endif + jit_convert_llvm to_llvm; llvm_function = to_llvm.convert_loop (tjit.get_module (), infer.get_blocks (), @@ -2474,7 +3099,19 @@ Vjit_failcnt++; } - +#ifdef HAVE_GCCJIT + if (gccjit_result) + { + if (Vdebug_jit) + { + std::cout << "-------------------- gccjit --------------------"; + void *void_fn = gcc_jit_result_get_code (gccjit_result, "loop"); + function = reinterpret_cast<jited_function> (void_fn); + } + printf ("using gccjit function\n"); + } + else +#endif if (llvm_function) { if (Vdebug_jit) @@ -2497,6 +3134,7 @@ function = reinterpret_cast<jited_function> (void_fn); } } +#endif octave_value jit_info::find (const vmap& extra_vars, const std::string& vname) const @@ -2506,16 +3144,16 @@ : *iter->second; } -#endif - -#if defined (HAVE_LLVM) -#define UNUSED_WITHOUT_LLVM(x) x +#endif /* if HAVE_JIT */ + +#if defined (HAVE_JIT) +#define UNUSED_WITHOUT_JIT(x) x #else -#define UNUSED_WITHOUT_LLVM(x) x GCC_ATTR_UNUSED +#define UNUSED_WITHOUT_JIT(x) x GCC_ATTR_UNUSED #endif -DEFUN (jit_failcnt, UNUSED_WITHOUT_LLVM (args), - UNUSED_WITHOUT_LLVM (nargout), +DEFUN (jit_failcnt, UNUSED_WITHOUT_JIT (args), + UNUSED_WITHOUT_JIT (nargout), "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} jit_failcnt ()\n\ @deftypefnx {Built-in Function} {@var{old_val} =} jit_failcnt (@var{new_val})\n\ @@ -2529,7 +3167,7 @@ @seealso{jit_enable, jit_startcnt, debug_jit}\n\ @end deftypefn") { -#if defined (HAVE_LLVM) +#if defined (HAVE_JIT) return SET_INTERNAL_VARIABLE (jit_failcnt); #else warning ("jit_failcnt: JIT compiling not available in this version of Octave"); @@ -2537,8 +3175,8 @@ #endif } -DEFUN (debug_jit, UNUSED_WITHOUT_LLVM (args), - UNUSED_WITHOUT_LLVM (nargout), +DEFUN (debug_jit, UNUSED_WITHOUT_JIT (args), + UNUSED_WITHOUT_JIT (nargout), "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} debug_jit ()\n\ @deftypefnx {Built-in Function} {@var{old_val} =} debug_jit (@var{new_val})\n\ @@ -2552,7 +3190,7 @@ @seealso{jit_enable, jit_startcnt}\n\ @end deftypefn") { -#if defined (HAVE_LLVM) +#if defined (HAVE_JIT) return SET_INTERNAL_VARIABLE (debug_jit); #else warning ("debug_jit: JIT compiling not available in this version of Octave"); @@ -2560,8 +3198,8 @@ #endif } -DEFUN (jit_enable, UNUSED_WITHOUT_LLVM (args), - UNUSED_WITHOUT_LLVM (nargout), +DEFUN (jit_enable, UNUSED_WITHOUT_JIT (args), + UNUSED_WITHOUT_JIT (nargout), "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} jit_enable ()\n\ @deftypefnx {Built-in Function} {@var{old_val} =} jit_enable (@var{new_val})\n\ @@ -2574,7 +3212,7 @@ @seealso{jit_startcnt, debug_jit}\n\ @end deftypefn") { -#if defined (HAVE_LLVM) +#if defined (HAVE_JIT) return SET_INTERNAL_VARIABLE (jit_enable); #else warning ("jit_enable: JIT compiling not available in this version of Octave"); @@ -2582,8 +3220,8 @@ #endif } -DEFUN (jit_startcnt, UNUSED_WITHOUT_LLVM (args), - UNUSED_WITHOUT_LLVM (nargout), +DEFUN (jit_startcnt, UNUSED_WITHOUT_JIT (args), + UNUSED_WITHOUT_JIT (nargout), "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} jit_startcnt ()\n\ @deftypefnx {Built-in Function} {@var{old_val} =} jit_startcnt (@var{new_val})\n\ @@ -2601,7 +3239,7 @@ @seealso{jit_enable, jit_failcnt, debug_jit}\n\ @end deftypefn") { -#if defined (HAVE_LLVM) +#if defined (HAVE_JIT) return SET_INTERNAL_VARIABLE_WITH_LIMITS (jit_startcnt, 1, std::numeric_limits<int>::max ()); #else