25 #define __STDC_LIMIT_MACROS
26 #define __STDC_CONSTANT_MACROS
51 #include <llvm/Analysis/CallGraph.h>
52 #include <llvm/Analysis/Passes.h>
54 #ifdef HAVE_LLVM_IR_VERIFIER_H
55 #include <llvm/IR/Verifier.h>
57 #include <llvm/Analysis/Verifier.h>
60 #include <llvm/Bitcode/ReaderWriter.h>
61 #include <llvm/ExecutionEngine/ExecutionEngine.h>
62 #include <llvm/ExecutionEngine/JIT.h>
64 #ifdef LEGACY_PASSMANAGER
65 #include <llvm/IR/LegacyPassManager.h>
67 #include <llvm/PassManager.h>
70 #ifdef HAVE_LLVM_IR_FUNCTION_H
71 #include <llvm/IR/LLVMContext.h>
72 #include <llvm/IR/Module.h>
74 #include <llvm/LLVMContext.h>
75 #include <llvm/Module.h>
78 #ifdef HAVE_LLVM_SUPPORT_IRBUILDER_H
79 #include <llvm/Support/IRBuilder.h>
80 #elif defined(HAVE_LLVM_IR_IRBUILDER_H)
81 #include <llvm/IR/IRBuilder.h>
83 #include <llvm/IRBuilder.h>
86 #include <llvm/Support/raw_os_ostream.h>
87 #include <llvm/Support/TargetSelect.h>
89 #ifdef HAVE_LLVM_IR_DATALAYOUT_H
90 #include <llvm/IR/DataLayout.h>
91 #elif defined(HAVE_LLVM_DATALAYOUT_H)
92 #include <llvm/DataLayout.h>
94 #include <llvm/Target/TargetData.h>
97 #include <llvm/Transforms/IPO.h>
98 #include <llvm/Transforms/Scalar.h>
102 static llvm::LLVMContext&
context = llvm::getGlobalContext ();
112 : converting_function (false)
133 for (variable_map::iterator iter =
vmap.begin (); iter !=
vmap.end (); ++iter)
136 const std::string& name = var->
name ();
137 if (name.size () && name[0] !=
'#')
145 const std::vector<jit_type *>& args)
146 : converting_function (true)
152 if (plist && plist->takes_varargs ())
161 for (
size_t i = 0; i < args.size (); ++i, ++piter)
163 if (piter == plist->end ())
167 std::string name = elt->
name ();
173 bool all_breaking =
false;
183 retval =
visit (expr);
190 "anonymous functions");
193 return_value = retvar;
218 if (! return_value && rlist && rlist->
size () == 1)
226 for (variable_map::iterator iter =
vmap.begin (); iter !=
vmap.end (); ++iter)
228 if (iter->second != return_value)
267 vmap[short_name] = short_result;
335 increment =
visit (tinc);
340 base, limit, increment));
392 vmap[iter_name] = iterator;
423 bool all_breaking =
false;
465 block = interrupt_check;
554 std::vector<jit_block *> entry_blocks (lst.
size () + 1 - last_else);
555 entry_blocks[0] =
block;
560 for (
size_t i = 1; iter != lst.
end (); ++iter, ++i)
571 entry_blocks[entry_blocks.size () - 1] = tail;
580 size_t num_incomming = 0;
582 for (
size_t i = 0; iter != lst.
end (); ++iter, ++i)
585 block = entry_blocks[i];
602 entry_blocks[i + 1]);
619 current_breaks.splice (current_breaks.end (),
breaks);
620 current_continues.splice (current_continues.end (),
continues);
626 if (num_incomming || ! last_else)
783 bool do_bind_ans =
false;
789 do_bind_ans = (!
id->is_variable ());
842 assert (expr &&
"Switch value can not be null");
846 size_t case_blocks_num = lst->
size ();
848 if (! case_blocks_num)
852 size_t has_otherwise = 0;
857 std::vector<jit_block *> entry_blocks (case_blocks_num + 1 - has_otherwise);
861 entry_blocks[0] =
block;
862 for (
size_t i = 1; i < case_blocks_num; ++i)
870 entry_blocks[entry_blocks.size()-1] = tail;
878 size_t num_incomming = 0;
881 for (
size_t i = 0; i < case_blocks_num; ++iter, ++i)
884 block = entry_blocks[i];
925 current_breaks.splice (current_breaks.end (),
breaks);
926 current_continues.splice (current_continues.end (),
continues);
933 if (num_incomming || ! has_otherwise)
969 assert (expr &&
"While expression can not be null");
981 bool all_breaking =
false;
986 loop_body->
accept (*
this);
1005 block = interrupt_check;
1034 bool all_breaking =
false;
1039 loop_body->
accept (*
this);
1043 all_breaking =
true;
1049 if (! all_breaking ||
continues.size ())
1058 block = interrupt_check;
1068 assert (expr &&
"Do-Until expression can not be null");
1114 variable_map::const_iterator iter;
1115 iter =
vmap.find (vname);
1116 return iter !=
vmap.end () ? iter->second : 0;
1165 return vmap[vname] = var;
1171 std::stringstream ss;
1172 ss << prefix << count;
1183 if (! (type.size () == 1 && type[0] ==
'('))
1186 std::list<tree_argument_list *> args = exp.
arg_lists ();
1187 if (args.size () != 1)
1189 "tree_index_expression");
1195 if (arg_list->
size () < 1)
1208 object =
visit (tree_object);
1210 size_t narg = arg_list->
size ();
1212 bool have_extra = extra_arg;
1213 std::vector<jit_value *> call_args (narg + 1 + have_extra);
1214 call_args[0] = object;
1216 for (
size_t idx = 0; iter != arg_list->
end (); ++idx, ++iter)
1220 &std::vector<jit_magic_end::context>::pop_back);
1224 call_args[idx + 1] =
visit (*iter);
1228 call_args[call_args.size () - 1] = extra_arg;
1242 if (isa<tree_identifier> (exp))
1245 = dynamic_cast<tree_index_expression *> (exp))
1248 do_assign (idx->expression (), new_object,
true);
1259 bool print,
bool artificial)
1290 for (block_list::const_iterator iter = lst.begin (); iter != lst.end ();
1302 const std::list<jit_value *>& constants)
1310 iter != entry_block->
end (); ++iter)
1312 = dynamic_cast<jit_extract_argument *> (*iter))
1313 argument_vec.push_back (std::make_pair (extract->name (),
true));
1319 llvm::Type *arg_type = any->
to_llvm ();
1320 arg_type = arg_type->getPointerTo ();
1321 llvm::FunctionType *ft;
1322 ft = llvm::FunctionType::get (llvm::Type::getVoidTy (context), arg_type,
1324 function = llvm::Function::Create (ft, llvm::Function::ExternalLinkage,
1329 prelude = llvm::BasicBlock::Create (context,
"prelude",
function);
1332 llvm::Value *
arg =
function->arg_begin ();
1335 llvm::Value *loaded_arg =
builder.CreateConstInBoundsGEP1_32 (arg, i);
1343 function->eraseFromParent ();
1354 const std::list<jit_value *>& constants,
1356 const std::vector<jit_type *>& args)
1378 for (
size_t i = 0; i < args.size () && piter != pend; ++i, ++piter)
1381 std::string arg_name = elt->
name ();
1390 function->eraseFromParent ();
1399 const std::list<jit_value *>& constants)
1401 std::list<jit_block *>::const_iterator biter;
1402 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1405 llvm::BasicBlock *block = llvm::BasicBlock::Create (context,
1415 for (std::list<jit_value *>::const_iterator iter = constants.begin ();
1416 iter != constants.end (); ++iter)
1417 if (! isa<jit_instruction> (*iter))
1421 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1425 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1429 piter != block.
end () && isa<jit_phi> (*piter); ++piter)
1440 llvm::PHINode *llvm_phi = phi->
to_llvm ();
1471 llvm::Value *
real = llvm::ConstantFP::get (scalar_t, value.real ());
1472 llvm::Value *
imag = llvm::ConstantFP::get (scalar_t, value.imag ());
1484 llvm::StructType *stype = llvm::cast<llvm::StructType>(cr.
type_llvm ());
1489 llvm::Constant *constants[4];
1490 constants[0] = llvm::ConstantFP::get (scalar_t, rng.
base);
1491 constants[1] = llvm::ConstantFP::get (scalar_t, rng.
limit);
1492 constants[2] = llvm::ConstantFP::get (scalar_t, rng.
inc);
1493 constants[3] = llvm::ConstantInt::get (idx, rng.
nelem);
1495 llvm::Value *as_llvm;
1496 as_llvm = llvm::ConstantStruct::get (stype,
1497 llvm::makeArrayRef (constants, 4));
1504 llvm::BasicBlock *block = b.
to_llvm ();
1505 builder.SetInsertPoint (block);
1531 std::vector<jit_value *> args (call.
arguments ().size ());
1532 for (
size_t i = 0; i < args.size (); ++i)
1549 arg =
builder.CreateLoad (arg);
1586 llvm::PHINode *node = llvm::PHINode::Create (phi.
type_llvm (),
1630 if (isa<jit_assign_base> (overwrite))
1655 : blocks (ablocks), factory (afactory), vmap (avmap) { }
1664 for (std::list<jit_value *>::const_iterator iter = constants.begin ();
1665 iter != constants.end (); ++iter)
1682 if (
jit_terminator *term = dynamic_cast<jit_terminator *> (next))
1707 if (term->
alive (i))
1711 iter != succ->
end () && isa<jit_phi> (*iter); ++iter)
1730 for (variable_map::const_iterator iter =
vmap.begin (); iter !=
vmap.end ();
1734 std::list<jit_block *> ssa_worklist;
1735 iter->second->use_blocks (visited);
1736 ssa_worklist.insert (ssa_worklist.begin (), visited.begin (),
1739 while (ssa_worklist.size ())
1742 ssa_worklist.pop_front ();
1745 diter != b->
df_end (); ++diter)
1748 if (! added_phi.count (dblock))
1753 added_phi.insert (dblock);
1756 if (! visited.count (dblock))
1758 ssa_worklist.push_back (dblock);
1759 visited.insert (dblock);
1771 if (ablock.
visited (avisit_count))
1789 iter != finish->
end () && isa<jit_phi> (*iter);)
1801 assert (var->
name ().size () && var->
name ()[0] ==
'#');
1816 std::set<jit_value *> temporaries;
1849 iter != b->
end () && isa<jit_phi> (*iter);)
1893 while (iter != ablock.
end () && isa<jit_phi> (*iter))
1899 if (phi->
use_count () == 1 && isa<jit_assign> (use->
user ()))
1937 if (fu_block && fu_block != &ablock && instr->
needs_release ())
1938 temp.insert (instr);
1941 if (isa<jit_call> (instr))
1960 if (! temp.size () || ! isa<jit_error_check> (ablock.
terminator ()))
1967 for (std::set<jit_value *>::const_iterator iter = temp.begin ();
1968 iter != temp.end (); ++iter)
1986 iter != ablock.
end () && isa<jit_phi> (*iter); ++iter)
2060 llvm::InitializeNativeTarget ();
2061 module =
new llvm::Module (
"octave", context);
2070 #ifdef LEGACY_PASSMANAGER
2079 #ifdef HAVE_LLVM_DATALAYOUT
2084 pass_manager->add (llvm::createCFGSimplificationPass ());
2085 pass_manager->add (llvm::createBasicAliasAnalysisPass ());
2086 pass_manager->add (llvm::createPromoteMemoryToRegisterPass ());
2087 pass_manager->add (llvm::createInstructionCombiningPass ());
2090 pass_manager->add (llvm::createCFGSimplificationPass ());
2106 extra_vars[
"#for_bounds0"] = &bounds;
2109 if (! info || ! info->
match (extra_vars))
2111 if (tc < static_cast<size_t> (Vjit_startcnt))
2115 info =
new jit_info (*
this, cmd, bounds);
2119 return info->
execute (extra_vars);
2129 if (! info || ! info->
match ())
2147 if (! info || ! info->
match (args))
2154 return info->
execute (args, retval);
2173 return rng.
nelem ();
2185 llvm::verifyModule (*
module);
2193 #ifdef RAW_FD_OSTREAM_ARG_IS_LLVM_SYS_FS
2194 llvm::raw_fd_ostream
fout (
"test.bc", error,
2195 llvm::sys::fs::F_Binary);
2197 llvm::raw_fd_ostream
fout (
"test.bc", error,
2198 llvm::raw_fd_ostream::F_Binary);
2200 llvm::WriteBitcodeToFile (
module, fout);
2208 : argument_types (ov_args.
length ()), function (0)
2210 size_t nargs = ov_args.
length ();
2211 for (
size_t i = 0; i < nargs; ++i)
2228 std::cout <<
"-------------------- Compiling function ";
2229 std::cout <<
"--------------------\n";
2235 blocks.
print (std::cout,
"octave jit ir");
2247 std::cout <<
"-------------------- raw function ";
2248 std::cout <<
"--------------------\n";
2249 std::cout << *raw_fn.
to_llvm () << std::endl;
2250 llvm::verifyFunction (*raw_fn.
to_llvm ());
2253 std::string wrapper_name = fcn.
name () +
"_wrapper";
2257 any_t, wrapper_args);
2259 llvm::BasicBlock *wrapper_body = wrapper.
new_block ();
2260 builder.SetInsertPoint (wrapper_body);
2263 std::vector<llvm::Value *> raw_args (nargs);
2264 for (
size_t i = 0; i < nargs; ++i)
2267 arg =
builder.CreateConstInBoundsGEP1_32 (wrapper_arg, i);
2268 arg =
builder.CreateLoad (arg);
2275 llvm::Value *result = raw_fn.
call (
builder, raw_args);
2284 llvm::Value *zero =
builder.getInt32 (0);
2290 llvm::Function *llvm_function = wrapper.
to_llvm ();
2295 std::cout <<
"-------------------- optimized and wrapped ";
2296 std::cout <<
"--------------------\n";
2297 std::cout << *llvm_function << std::endl;
2298 llvm::verifyFunction (*llvm_function);
2301 llvm::ExecutionEngine* engine = tjit.
get_engine ();
2302 void *void_fn = engine->getPointerToFunction (llvm_function);
2312 std::cout <<
"jit fail: " << e.what () << std::endl;
2330 size_t nargs = ov_args.
length ();
2331 std::vector<octave_base_value *> args (nargs);
2332 for (
size_t i = 0; i < nargs; ++i)
2354 size_t nargs = ov_args.
length ();
2358 for (
size_t i = 0; i < nargs; ++i)
2367 : engine (tjit.get_engine ()), function (0), llvm_function (0)
2373 : engine (tjit.get_engine ()), function (0), llvm_function (0)
2390 std::vector<octave_base_value *> real_arguments (
arguments.size ());
2391 for (
size_t i = 0; i <
arguments.size (); ++i)
2398 real_arguments[i] = obv;
2402 function (&real_arguments[0]);
2404 for (
size_t i = 0; i <
arguments.size (); ++i)
2406 const std::string& name =
arguments[i].first;
2409 if (name.size () && name[0] !=
'#')
2424 for (
size_t i = 0; i <
bounds.size (); ++i)
2426 const std::string& arg_name =
bounds[i].second;
2431 if (type !=
bounds[i].first)
2453 std::cout <<
"-------------------- Compiling tree --------------------\n";
2455 blocks.
print (std::cout,
"octave jit ir");
2461 infer.get_blocks (),
2471 std::cout <<
"jit fail: " << e.what () << std::endl;
2482 std::cout <<
"-------------------- llvm ir --------------------";
2491 std::cout <<
"-------------------- optimized llvm ir "
2492 <<
"--------------------\n";
2504 vmap::const_iterator iter = extra_vars.find (vname);
2511 #if defined (HAVE_LLVM)
2512 #define UNUSED_WITHOUT_LLVM(x) x
2514 #define UNUSED_WITHOUT_LLVM(x) x GCC_ATTR_UNUSED
2520 @deftypefn {Built-in Function} {@var{val} =} jit_failcnt ()\n\
2521 @deftypefnx {Built-in Function} {@var{old_val} =} jit_failcnt (@var{new_val})\n\
2522 @deftypefnx {Built-in Function} {} jit_failcnt (@var{new_val}, \"local\")\n\
2523 Query or set the internal variable that counts the number of JIT fail\n\
2524 exceptions for Octave's JIT compiler.\n\
2526 When called from inside a function with the @qcode{\"local\"} option, the\n\
2527 variable is changed locally for the function and any subroutines it calls.\n\
2528 The original variable value is restored when exiting the function.\n\
2529 @seealso{jit_enable, jit_startcnt, debug_jit}\n\
2532 #if defined (HAVE_LLVM)
2535 warning (
"jit_failcnt: JIT compiling not available in this version of Octave");
2543 @deftypefn {Built-in Function} {@var{val} =} debug_jit ()\n\
2544 @deftypefnx {Built-in Function} {@var{old_val} =} debug_jit (@var{new_val})\n\
2545 @deftypefnx {Built-in Function} {} debug_jit (@var{new_val}, \"local\")\n\
2546 Query or set the internal variable that determines whether\n\
2547 debugging/tracing is enabled for Octave's JIT compiler.\n\
2549 When called from inside a function with the @qcode{\"local\"} option, the\n\
2550 variable is changed locally for the function and any subroutines it calls.\n\
2551 The original variable value is restored when exiting the function.\n\
2552 @seealso{jit_enable, jit_startcnt}\n\
2555 #if defined (HAVE_LLVM)
2558 warning (
"debug_jit: JIT compiling not available in this version of Octave");
2566 @deftypefn {Built-in Function} {@var{val} =} jit_enable ()\n\
2567 @deftypefnx {Built-in Function} {@var{old_val} =} jit_enable (@var{new_val})\n\
2568 @deftypefnx {Built-in Function} {} jit_enable (@var{new_val}, \"local\")\n\
2569 Query or set the internal variable that enables Octave's JIT compiler.\n\
2571 When called from inside a function with the @qcode{\"local\"} option, the\n\
2572 variable is changed locally for the function and any subroutines it calls.\n\
2573 The original variable value is restored when exiting the function.\n\
2574 @seealso{jit_startcnt, debug_jit}\n\
2577 #if defined (HAVE_LLVM)
2580 warning (
"jit_enable: JIT compiling not available in this version of Octave");
2588 @deftypefn {Built-in Function} {@var{val} =} jit_startcnt ()\n\
2589 @deftypefnx {Built-in Function} {@var{old_val} =} jit_startcnt (@var{new_val})\n\
2590 @deftypefnx {Built-in Function} {} jit_startcnt (@var{new_val}, \"local\")\n\
2591 Query or set the internal variable that determines whether JIT compilation\n\
2592 will take place for a specific loop.\n\
2594 Because compilation is a costly operation it does not make sense to employ\n\
2595 JIT when the loop count is low. By default only loops with greater than\n\
2596 1000 iterations will be accelerated.\n\
2598 When called from inside a function with the @qcode{\"local\"} option, the\n\
2599 variable is changed locally for the function and any subroutines it calls.\n\
2600 The original variable value is restored when exiting the function.\n\
2601 @seealso{jit_enable, jit_failcnt, debug_jit}\n\
2604 #if defined (HAVE_LLVM)
2608 warning (
"jit_enable: JIT compiling not available in this version of Octave");
virtual void visit(jit_block &)
jit_type * result(void) const
void do_return(llvm::IRBuilderD &builder, llvm::Value *rval=0, bool verify=true)
octave_base_value *(* jited_function)(octave_base_value **)
tree_expression * operand(void)
void visit_colon_expression(tree_colon_expression &)
const type_bound_vector & get_bounds(void) const
octave_value::assign_op op_type(void) const
jit_instruction * insert_after(iterator loc, jit_instruction *instr)
static llvm::Value * insert_interrupt_check(llvm::IRBuilderD &bld)
static const jit_operation & paren_subsasgn(void)
instruction_list::iterator iterator
#define SET_INTERNAL_VARIABLE_WITH_LIMITS(NM, MINVAL, MAXVAL)
jit_instruction * insert_before(iterator loc, jit_instruction *instr)
const std::vector< std::pair< std::string, bool > > & get_arguments(void) const
void stash_llvm(llvm::Value *compiled)
bool is_range(void) const
std::string next_shortcircut_result(bool inc=true)
std::map< std::string, llvm::Value * > arguments
jit_variable * dest(void) const
jit_value * result(void) const
virtual void replace_with(jit_value *value)
void release_dead_phi(jit_block &ablock)
jit_block * incomming(size_t i) const
void visit_if_command(tree_if_command &)
jit_type * result_type(void) const
octave_value rvalue1(int=1)
df_iterator df_end(void) const
octave_value::unary_op op_type(void) const
void visit_simple_for_command(tree_simple_for_command &)
static jit_type * get_any_ptr(void)
void stash_info(jit_info *jinfo)
size_t use_count(void) const
void visit_simple_assignment(tree_simple_assignment &)
void visit_matrix(tree_matrix &)
jit_terminator * terminator(void) const
const std::string & name(void) const
tree_expression * left_hand_side(void)
df_iterator df_begin(void) const
void push_worklist(jit_instruction *instr)
jit_call * create_checked_impl(jit_call *ret)
tree_expression * switch_value(void)
tree_parameter_list * parameter_list(void)
void visit_if_clause(tree_if_clause &)
llvm::Type * to_llvm(void) const
void place_releases(void)
void visit_complex_for_command(tree_complex_for_command &)
void visit_octave_user_function_header(octave_user_function &)
std::vector< jit_type * > argument_types
void visit_fcn_handle(tree_fcn_handle &)
static void initialize(llvm::Module *m, llvm::ExecutionEngine *e)
jit_function_info(tree_jit &tjit, octave_user_function &fcn, const octave_value_list &ov_args)
void visit_return_list(tree_return_list &)
jit_info(tree_jit &tjit, tree &tee)
const jit_function & overload() const
octave_idx_type length(void) const
jit_block * parent(void) const
llvm::Function * convert_loop(llvm::Module *module, const jit_block_list &blocks, const std::list< jit_value * > &constants)
void accept(tree_walker &tw)
octave_idx_type nelem(void) const
static bool have_breakpoints(void)
llvm::Value * to_llvm(void) const
jit_instruction * prepend(jit_instruction *instr)
llvm::Type * type_llvm(void) const
void visit_statement_list(tree_statement_list &)
jit_function convert_function(llvm::Module *module, const jit_block_list &blocks, const std::list< jit_value * > &constants, octave_user_function &fcn, const std::vector< jit_type * > &args)
void release_temp(jit_block &ablock, std::set< jit_value * > &temp)
void visit_constant(tree_constant &)
jit_instruction * resolve(tree_index_expression &exp, jit_value *extra_arg=0, bool lhs=false)
llvm::PassManager * module_pass_manager
bool is_default_case(void)
static bool execute(tree_simple_for_command &cmd, const octave_value &bounds)
tree_command * command(void)
void visit_if_command_list(tree_if_command_list &)
llvm::BasicBlock * prelude
static const jit_operation & for_init(void)
#define DEFUN(name, args_name, nargout_name, doc)
size_t trip_count(const octave_value &bounds) const
void error(const char *fmt,...)
symbol_table::scope_id scope(void)
static const jit_operation & release(void)
std::string name(void) const
#define SET_INTERNAL_VARIABLE(NM)
bool is_special_expr(void) const
octave_value varval(context_id context=xdefault_context) const
jit_type * type(void) const
tree_switch_case_list * case_list(void)
llvm::Module * get_module(void) const
jit_block * first_use_block(void)
static binary_op assign_op_to_binary_op(assign_op)
std::vector< jit_magic_end::context > end_context
std::vector< std::pair< std::string, bool > > arguments
jit_block * dom_successor(size_t idx) const
void stash_info(jit_function_info *info)
iterator erase(iterator iter)
void visit_argument_list(tree_argument_list &)
bool execute(const octave_value_list &ov_args, octave_value_list &retval) const
tree_statement_list * commands(void)
void add_incomming(jit_block *from, jit_value *value)
bool do_execute(tree_simple_for_command &cmd, const octave_value &bounds)
void visit_global_command(tree_global_command &)
void visit_postfix_expression(tree_postfix_expression &)
static const jit_operation & for_check(void)
static const jit_operation & paren_subsref(void)
tree_expression * expression(void)
tree_expression * case_label(void)
void visit_anon_fcn_handle(tree_anon_fcn_handle &)
static llvm::IRBuilder builder(llvm::getGlobalContext())
void stash_info(jit_info *jinfo)
bool visited(size_t avisit_count)
void visit_parameter_list(tree_parameter_list &)
static llvm::Type * get_scalar_llvm(void)
void add_method(T *obj, void(T::*method)(void))
std::map< std::string, const octave_value * > vmap
void create_dom_tree(void)
jit_block_list & get_blocks(void)
static octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
std::string next_for_bounds(bool inc=true)
std::string type_tags(void)
jit_value * overwrite(void) const
static tree_jit & instance(void)
static octave_value varval(const std::string &name, scope_id scope=xcurrent_scope, context_id context=xdefault_context)
void convert(const jit_block_list &blocks, const std::list< jit_value * > &constants)
void visit_prefix_expression(tree_prefix_expression &)
void visit_switch_case(tree_switch_case &)
virtual bool needs_release(void) const
void do_construct_ssa(jit_block &block, size_t avisit_count)
const jit_function & overload(void) const
jit_info * get_info(void) const
static jit_type * get_range(void)
void visit_cell(tree_cell &)
void visit_statement(tree_statement &)
void push_back(jit_block *b)
jit_value * src(void) const
void visit_octave_user_function_trailer(octave_user_function &)
llvm::Value * call(llvm::IRBuilderD &builder, const std::vector< jit_value * > &in_args) const
tree_expression * increment(void)
void visit_index_expression(tree_index_expression &)
static const size_t NO_ID
tree_if_command_list * cmd_list(void)
std::list< jit_instruction * > worklist
bool execute(const vmap &extra_vars=vmap()) const
static llvm::LLVMContext & context
static symbol_record find_symbol(const std::string &name, scope_id scope=xcurrent_scope)
tree_statement_list * body(void)
bool has_magic_end(void) const
std::list< tree_decl_elt * >::iterator iterator
static const jit_operation & cast(jit_type *result)
void visit_octave_user_script(octave_user_script &)
static jit_type * get_complex(void)
void finish_breaks(jit_block *dest, const block_list &lst)
iterator remove(iterator iter)
bool alive(const jit_block *asuccessor) const
bool print_result(void) const
jit_block * back(void) const
tree_expression * right_hand_side(void)
std::list< tree_argument_list * > arg_lists(void)
tree_expression * condition(void)
void visit_persistent_command(tree_persistent_command &)
bool is_persistent(void) const
jit_block & entry_block(void)
void visit_identifier(tree_identifier &)
const jit_function & overload(void) const
static const jit_operation & make_range(void)
symbol_table::scope_id scope
tree_expression * control_expr(void)
variable check_variable(void) const
bool is_global(void) const
jit_infer(jit_factory &afactory, jit_block_list &ablocks, const variable_map &avmap)
virtual void construct_ssa(void)
tree_parameter_list * return_list(void)
void accept(tree_walker &tw)
std::list< jit_block * > block_list
std::string name(void) const
Range range_value(void) const
void append_users(jit_value *v)
jit_convert::variable_map variable_map
void visit_do_until_command(tree_do_until_command &)
jit_block * front(void) const
jit_block * successor(size_t idx=0) const
bool match(const octave_value_list &ov_args) const
void visit_octave_user_function_header(octave_user_function &)
bool in_worklist(void) const
llvm::ExecutionEngine * engine
void append_users_term(jit_terminator *term)
std::vector< std::pair< std::string, bool > > argument_vec
bool artificial(void) const
static const jit_operation & binary_op(int op)
context resolve_context(void) const
tree_expression * limit(void)
void visit_unwind_protect_command(tree_unwind_protect_command &)
std::ostream & print(std::ostream &os, const std::string &header) const
#define panic_impossible()
static jit_type * get_scalar(void)
jit_convert(tree &tee, jit_type *for_bounds=0)
void visit_funcall(tree_funcall &)
tree_expression * lhs(void)
tree_expression * left_hand_side(void)
jit_value * visit(tree *tee)
jit_value * argument(size_t i) const
static void assign(const std::string &name, const octave_value &value=octave_value(), scope_id scope=xcurrent_scope, context_id context=xdefault_context, bool force_add=false)
static const jit_operation & create_undef(void)
llvm::Value * cond_llvm(void) const
llvm::PHINode * to_llvm(void) const
static llvm::Value * insert_error_check(llvm::IRBuilderD &bld)
void visit_switch_case_list(tree_switch_case_list &)
jit_function_info * get_info(void)
size_t argument_count(void) const
tree_statement_list * commands(void)
octave_value::binary_op op_type(void) const
void visit_return_command(tree_return_command &)
tree_expression * special_expr(void)
void stash_argument(size_t i, jit_value *arg)
jit_value * do_assign(tree_expression *exp, jit_value *rhs, bool artificial=false)
void visit_switch_command(tree_switch_command &)
void finish_phi(jit_phi *phi)
jit_factory & get_factory(void)
void stash_in_worklist(bool ain_worklist)
llvm::BasicBlock * to_llvm(void) const
df_set::const_iterator df_iterator
bool takes_varargs(void) const
void visit_multi_assignment(tree_multi_assignment &)
static llvm::Type * get_index_llvm(void)
std::string next_iterator(bool inc=true)
void warning(const char *fmt,...)
virtual std::string name(void) const
std::string str_print_code(void)
static octave_idx_type fout(const octave_idx_type &lsize, const double &alpha, const double &beta, const double &, const double &p)
charNDArray max(char d, const charNDArray &m)
size_t use_count(void) const
static const jit_operation & unary_op(int op)
void compile(tree_jit &tjit, tree &tee, jit_type *for_bounds=0)
void visit_octave_user_function_trailer(octave_user_function &)
static const jit_function & get_release(jit_type *type)
llvm::BasicBlock * incomming_llvm(size_t i) const
jit_info * get_info(void) const
std::pair< jit_type *, std::string > type_bound
const variable_map & vmap
void visit_no_op_command(tree_no_op_command &)
tree_expression * rhs(void)
NODE_T * first_use(void) const
bool is_else_clause(void)
std::set< jit_block * > df_set
jit_value * result(void) const
void visit_decl_elt(tree_decl_elt &)
size_t successor_count(void) const
static const jit_operation & print_value(void)
tree_expression * expression(void)
void visit_break_command(tree_break_command &)
void compute_idom(jit_block &entry_block)
Complex complex_value(bool frc_str_conv=false) const
const value_list & constants(void) const
bool match(const vmap &extra_vars=vmap()) const
void optimize(llvm::Function *fn)
#define UNUSED_WITHOUT_LLVM(x)
void accept(tree_walker &tw)
llvm::Value * argument_llvm(size_t i) const
void visit_continue_command(tree_continue_command &)
bool is_undefined(void) const
std::list< jit_block * >::iterator iterator
static void reset_ids(void)
llvm::BasicBlock * new_block(const std::string &aname="body", llvm::BasicBlock *insert_before=0)
void visit_binary_expression(tree_binary_expression &)
void visit_decl_init_list(tree_decl_init_list &)
void visit_octave_user_function(octave_user_function &)
virtual bool is_assignment_expression(void) const
jit_block * successor(size_t i) const
llvm::ExecutionEngine * engine
llvm::FunctionPassManager * pass_manager
static const jit_operation & grab(void)
ColumnVector imag(const ComplexColumnVector &a)
const std::string & name(void) const
jit_block & final_block(void)
std::string next_name(const char *prefix, size_t &count, bool inc)
llvm::ExecutionEngine * get_engine(void) const
jit_block * maybe_split(jit_factory &factory, jit_block_list &blocks, jit_block *asuccessor)
const std::string & name(void) const
static jit_type * get_any(void)
llvm::Value * argument(llvm::IRBuilderD &builder, size_t idx) const
tree_expression * base(void)
tree_statement_list * body(void)
jit_instruction * back(void)
void visit_while_command(tree_while_command &)
std::complex< double > Complex
void(* jited_function)(octave_base_value **)
void initialize(symbol_table::scope_id s)
llvm::Function * llvm_function
static jit_type * type_of(const octave_value &ov)
octave_base_value * internal_rep(void) const
ColumnVector real(const ComplexColumnVector &a)
double double_value(bool frc_str_conv=false) const
virtual void push_variable(void)
static llvm::Value * create_complex(llvm::Value *real, llvm::Value *imag)
llvm::Function * to_llvm(void) const
NODE_T * next(void) const
tree_statement_list * body(void)
jit_instruction * user(void) const
void visit_function_def(tree_function_def &)
jit_value * top(void) const
llvm::BasicBlock * successor_llvm(size_t idx=0) const
void visit_statement_list(tree_statement_list &)
octave_value find(const vmap &extra_vars, const std::string &vname) const
virtual void accept(tree_walker &tw)=0
size_t successor_count(void) const
const variable_map & get_variable_map(void) const
void visit_try_catch_command(tree_try_catch_command &)
static const jit_operation & for_index(void)
virtual bool is_identifier(void) const
jit_variable * find_variable(const std::string &vname) const
size_t dom_successor_count(void) const
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
jit_variable * get_variable(const std::string &vname)
static const jit_operation & logically_true(void)
void mark_artificial(void)
static scope_id current_scope(void)
jit_call * create_checked(const ARG0 &arg0)
const std::vector< jit_use > & arguments(void) const
tree_expression * condition(void)
static const jit_operation & destroy(void)
jit_variable * create_variable(const std::string &vname, jit_type *type, bool isarg=true)