25 #define __STDC_LIMIT_MACROS
26 #define __STDC_CONSTANT_MACROS
28 #if defined (HAVE_CONFIG_H)
42 #if defined (HAVE_LLVM)
52 #include <llvm/Analysis/CallGraph.h>
53 #include <llvm/Analysis/Passes.h>
55 #if defined (HAVE_LLVM_IR_VERIFIER_H)
56 # include <llvm/IR/Verifier.h>
58 # include <llvm/Analysis/Verifier.h>
61 #include <llvm/Bitcode/ReaderWriter.h>
62 #include <llvm/ExecutionEngine/ExecutionEngine.h>
63 #include <llvm/ExecutionEngine/JIT.h>
65 #if defined (LEGACY_PASSMANAGER)
66 # include <llvm/IR/LegacyPassManager.h>
68 # include <llvm/PassManager.h>
71 #if defined (HAVE_LLVM_IR_FUNCTION_H)
72 # include <llvm/IR/LLVMContext.h>
73 # include <llvm/IR/Module.h>
75 # include <llvm/LLVMContext.h>
76 # include <llvm/Module.h>
79 #if defined (HAVE_LLVM_SUPPORT_IRBUILDER_H)
80 # include <llvm/Support/IRBuilder.h>
81 #elif defined(HAVE_LLVM_IR_IRBUILDER_H)
82 # include <llvm/IR/IRBuilder.h>
84 # include <llvm/IRBuilder.h>
87 #include <llvm/Support/raw_os_ostream.h>
88 #include <llvm/Support/TargetSelect.h>
90 #if defined (HAVE_LLVM_IR_DATALAYOUT_H)
91 # include <llvm/IR/DataLayout.h>
92 #elif defined(HAVE_LLVM_DATALAYOUT_H)
93 # include <llvm/DataLayout.h>
95 # include <llvm/Target/TargetData.h>
98 #include <llvm/Transforms/IPO.h>
99 #include <llvm/Transforms/Scalar.h>
103 static llvm::LLVMContext&
context = llvm::getGlobalContext ();
115 : converting_function (
false)
136 for (variable_map::iterator iter =
vmap.begin (); iter !=
vmap.end (); ++iter)
140 if (name.size () && name[0] !=
'#')
148 const std::vector<jit_type *>&
args)
149 : converting_function (true)
155 if (plist && plist->takes_varargs ())
164 for (
size_t i = 0;
i < args.size (); ++
i, ++piter)
166 if (piter == plist->end ())
176 bool all_breaking =
false;
186 retval =
visit (expr);
193 "anonymous functions");
196 return_value = retvar;
221 if (! return_value && rlist && rlist->
size () == 1)
229 for (variable_map::iterator iter =
vmap.begin (); iter !=
vmap.end (); ++iter)
231 if (iter->second != return_value)
270 vmap[short_name] = short_result;
338 increment =
visit (tinc);
343 base, limit, increment));
395 vmap[iter_name] = iterator;
426 bool all_breaking =
false;
468 block = interrupt_check;
557 std::vector<jit_block *> entry_blocks (lst.
size () + 1 - last_else);
558 entry_blocks[0] =
block;
563 for (
size_t i = 1; iter != lst.
end (); ++iter, ++
i)
574 entry_blocks[entry_blocks.size () - 1] = tail;
582 size_t num_incomming = 0;
584 for (
size_t i = 0; iter != lst.
end (); ++iter, ++
i)
604 entry_blocks[i + 1]);
621 current_breaks.splice (current_breaks.end (),
breaks);
622 current_continues.splice (current_continues.end (),
continues);
628 if (num_incomming || ! last_else)
785 bool do_bind_ans =
false;
791 do_bind_ans = (!
id->is_variable ());
844 assert (expr &&
"Switch value can not be null");
848 size_t case_blocks_num = lst->
size ();
850 if (! case_blocks_num)
854 size_t has_otherwise = 0;
859 std::vector<jit_block *> entry_blocks (case_blocks_num + 1 - has_otherwise);
863 entry_blocks[0] =
block;
864 for (
size_t i = 1;
i < case_blocks_num; ++
i)
872 entry_blocks[entry_blocks.size()-1] = tail;
880 size_t num_incomming = 0;
883 for (
size_t i = 0;
i < case_blocks_num; ++iter, ++
i)
927 current_breaks.splice (current_breaks.end (),
breaks);
928 current_continues.splice (current_continues.end (),
continues);
935 if (num_incomming || ! has_otherwise)
971 assert (expr &&
"While expression can not be null");
983 bool all_breaking =
false;
988 loop_body->
accept (*
this);
1007 block = interrupt_check;
1036 bool all_breaking =
false;
1041 loop_body->
accept (*
this);
1045 all_breaking =
true;
1051 if (! all_breaking ||
continues.size ())
1060 block = interrupt_check;
1070 assert (expr &&
"Do-Until expression can not be null");
1116 variable_map::const_iterator iter;
1117 iter =
vmap.find (vname);
1118 return iter !=
vmap.end () ? iter->second : 0;
1173 std::stringstream ss;
1174 ss << prefix << count;
1185 if (! (type.size () == 1 && type[0] ==
'('))
1189 if (args.size () != 1)
1191 "tree_index_expression");
1197 if (arg_list->
size () < 1)
1210 object =
visit (tree_object);
1212 size_t narg = arg_list->
size ();
1214 bool have_extra = extra_arg;
1215 std::vector<jit_value *> call_args (narg + 1 + have_extra);
1218 for (
size_t idx = 0; iter != arg_list->
end (); ++idx, ++iter)
1222 &std::vector<jit_magic_end::context>::pop_back);
1226 call_args[idx + 1] =
visit (*iter);
1230 call_args[call_args.size () - 1] = extra_arg;
1244 if (isa<tree_identifier> (exp))
1247 = dynamic_cast<tree_index_expression *> (exp))
1250 do_assign (idx->expression (), new_object,
true);
1261 bool print,
bool artificial)
1292 for (block_list::const_iterator iter = lst.begin (); iter != lst.end ();
1304 const std::list<jit_value *>& constants)
1312 iter != entry_block->
end (); ++iter)
1314 = dynamic_cast<jit_extract_argument *> (*iter))
1315 argument_vec.push_back (std::make_pair (extract->name (),
true));
1320 llvm::Type *arg_type = any->
to_llvm ();
1321 arg_type = arg_type->getPointerTo ();
1322 llvm::FunctionType *ft;
1323 ft = llvm::FunctionType::get (llvm::Type::getVoidTy (context), arg_type,
1325 function = llvm::Function::Create (ft, llvm::Function::ExternalLinkage,
1330 prelude = llvm::BasicBlock::Create (context,
"prelude",
function);
1333 llvm::Value *
arg =
function->arg_begin ();
1336 llvm::Value *loaded_arg =
builder.CreateConstInBoundsGEP1_32 (arg,
i);
1344 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)
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);
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))
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)
2059 llvm::InitializeNativeTarget ();
2060 module =
new llvm::Module (
"octave", context);
2069 #if defined (LEGACY_PASSMANAGER)
2078 #if defined (HAVE_LLVM_DATALAYOUT)
2083 pass_manager->add (llvm::createCFGSimplificationPass ());
2084 pass_manager->add (llvm::createBasicAliasAnalysisPass ());
2085 pass_manager->add (llvm::createPromoteMemoryToRegisterPass ());
2086 pass_manager->add (llvm::createInstructionCombiningPass ());
2089 pass_manager->add (llvm::createCFGSimplificationPass ());
2105 extra_vars[
"#for_bounds0"] = &bounds;
2108 if (! info || ! info->
match (extra_vars))
2110 if (tc < static_cast<size_t> (Vjit_startcnt))
2114 info =
new jit_info (*
this, cmd, bounds);
2118 return info->
execute (extra_vars);
2128 if (! info || ! info->
match ())
2146 if (! info || ! info->
match (args))
2153 return info->
execute (args, retval);
2172 return rng.
numel ();
2183 llvm::verifyModule (*
module);
2191 #if defined (RAW_FD_OSTREAM_ARG_IS_LLVM_SYS_FS)
2192 llvm::raw_fd_ostream
fout (
"test.bc", error,
2193 llvm::sys::fs::F_Binary);
2195 llvm::raw_fd_ostream
fout (
"test.bc", error,
2196 llvm::raw_fd_ostream::F_Binary);
2198 llvm::WriteBitcodeToFile (
module, fout);
2208 size_t nargs = ov_args.
length ();
2209 for (
size_t i = 0;
i < nargs; ++
i)
2226 std::cout <<
"-------------------- Compiling function ";
2227 std::cout <<
"--------------------\n";
2233 blocks.
print (std::cout,
"octave jit ir");
2245 std::cout <<
"-------------------- raw function ";
2246 std::cout <<
"--------------------\n";
2247 std::cout << *raw_fn.
to_llvm () << std::endl;
2248 llvm::verifyFunction (*raw_fn.
to_llvm ());
2255 any_t, wrapper_args);
2257 llvm::BasicBlock *wrapper_body = wrapper.
new_block ();
2258 builder.SetInsertPoint (wrapper_body);
2261 std::vector<llvm::Value *> raw_args (nargs);
2262 for (
size_t i = 0;
i < nargs; ++
i)
2265 arg =
builder.CreateConstInBoundsGEP1_32 (wrapper_arg,
i);
2266 arg =
builder.CreateLoad (arg);
2288 llvm::Function *llvm_function = wrapper.
to_llvm ();
2293 std::cout <<
"-------------------- optimized and wrapped ";
2294 std::cout <<
"--------------------\n";
2295 std::cout << *llvm_function << std::endl;
2296 llvm::verifyFunction (*llvm_function);
2299 llvm::ExecutionEngine* engine = tjit.
get_engine ();
2300 void *void_fn = engine->getPointerToFunction (llvm_function);
2310 std::cout <<
"jit fail: " << e.what () << std::endl;
2328 size_t nargs = ov_args.
length ();
2329 std::vector<octave_base_value *>
args (nargs);
2330 for (
size_t i = 0;
i < nargs; ++
i)
2352 size_t nargs = ov_args.
length ();
2356 for (
size_t i = 0;
i < nargs; ++
i)
2365 : engine (tjit.get_engine ()),
function (0), llvm_function (0)
2371 : engine (tjit.get_engine ()),
function (0), llvm_function (0)
2388 std::vector<octave_base_value *> real_arguments (
arguments.size ());
2396 real_arguments[
i] = obv;
2400 function (&real_arguments[0]);
2407 if (name.size () && name[0] !=
'#')
2422 for (
size_t i = 0;
i <
bounds.size (); ++
i)
2451 std::cout <<
"-------------------- Compiling tree --------------------\n";
2453 blocks.
print (std::cout,
"octave jit ir");
2459 infer.get_blocks (),
2469 std::cout <<
"jit fail: " << e.what () << std::endl;
2480 std::cout <<
"-------------------- llvm ir --------------------";
2489 std::cout <<
"-------------------- optimized llvm ir "
2490 <<
"--------------------\n";
2502 vmap::const_iterator iter = extra_vars.find (vname);
2523 #if defined (HAVE_LLVM)
2526 octave_unused_parameter (
args);
2527 octave_unused_parameter (
nargout);
2547 #if defined (HAVE_LLVM)
2550 octave_unused_parameter (
args);
2551 octave_unused_parameter (
nargout);
2570 #if defined (HAVE_LLVM)
2573 octave_unused_parameter (
args);
2574 octave_unused_parameter (
nargout);
2598 #if defined (HAVE_LLVM)
2602 octave_unused_parameter (
args);
2603 octave_unused_parameter (
nargout);
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
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup calculate Y_a and Y _d item Given calculate Y nd enumerate In either initial values for the given components are and initial guesses for the unknown components must also be provided as input Set this option to to solve the first or to solve the second(the default is 0, so you must provide a set of initial conditions that are consistent).If this option is set to a nonzero value
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)
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
void visit_complex_for_command(tree_complex_for_command &)
void visit_octave_user_function_header(octave_user_function &)
in that an updated permutation matrix is returned Note that if var
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)
identity matrix If supplied two scalar respectively For allows like xample val
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)
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 &)
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup so it is best to provide a consistent set and leave this option set to zero tem it may help to set this parameter to a nonzero value it is probably best to try leaving this option set to zero first
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)
std::list< tree_decl_elt * >::iterator iterator
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
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)
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
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
octave_idx_type numel(void) 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
void warn_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
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 &)
With real return the complex result
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)
octave::unwind_protect frame
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 &)
=val(i)}if ode{val(i)}occurs in table i
size_t successor_count(void) const
static const jit_operation & print_value(void)
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by nd tex zero divided by nd ifnottex and any operation involving another NaN value(5+NaN).Note that NaN always compares not equal to NaN(NaN!
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)
void accept(tree_walker &tw)
llvm::Value * argument_llvm(size_t i) const
ots The first example below creates an uninitialized object
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
OCTAVE_EXPORT octave_value_list it applies a binary function and expands as necessary singleton dimensions in either input argument function
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 &)
the second is matched to the second specifier and placed in the second column and so forth If there are more words than specifiers then the process is repeated until all words have been processed or the limit imposed by any(non-whitespace) text in the format that is not one of these specifiers is considered a literal.If there is a literal between two format specifiers then that same literal must appear in the input stream between the matching words.The following specifiers are valid
jit_value * top(void) const
llvm::BasicBlock * successor_llvm(size_t idx=0) const
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
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)