25 #define __STDC_LIMIT_MACROS 26 #define __STDC_CONSTANT_MACROS 28 #if defined (HAVE_CONFIG_H) 50 #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 #if defined (HAVE_LLVM_ANALYSIS_BASICALIASANALYSIS_H) 63 # include <llvm/Analysis/BasicAliasAnalysis.h> 68 #include <llvm/Bitcode/ReaderWriter.h> 69 #include <llvm/ExecutionEngine/ExecutionEngine.h> 73 #include <llvm/ExecutionEngine/MCJIT.h> 74 #include "llvm/ExecutionEngine/SectionMemoryManager.h" 76 #if defined (LEGACY_PASSMANAGER) 77 # include <llvm/IR/LegacyPassManager.h> 79 # include <llvm/PassManager.h> 82 #if defined (HAVE_LLVM_IR_FUNCTION_H) 83 # include <llvm/IR/LLVMContext.h> 84 # include <llvm/IR/Module.h> 85 # include <llvm/IR/Intrinsics.h> 87 # include <llvm/LLVMContext.h> 88 # include <llvm/Module.h> 89 # include <llvm/Intrinsics.h> 92 #if defined (HAVE_LLVM_SUPPORT_IRBUILDER_H) 93 # include <llvm/Support/IRBuilder.h> 94 #elif defined(HAVE_LLVM_IR_IRBUILDER_H) 95 # include <llvm/IR/IRBuilder.h> 97 # include <llvm/IRBuilder.h> 100 #include <llvm/Support/raw_os_ostream.h> 101 #include <llvm/Support/TargetSelect.h> 103 #if defined (HAVE_LLVM_IR_DATALAYOUT_H) 104 # include <llvm/IR/DataLayout.h> 105 #elif defined(HAVE_LLVM_DATALAYOUT_H) 106 # include <llvm/DataLayout.h> 108 # include <llvm/Target/TargetData.h> 111 #include <llvm/Transforms/IPO.h> 112 #include <llvm/Transforms/Scalar.h> 126 static llvm::LLVMContext&
context = llvm::getGlobalContext ();
138 : m_converting_function (
false)
159 for (variable_map::iterator iter =
m_vmap.begin (); iter !=
m_vmap.end ();
172 const std::vector<jit_type *>& args)
173 : m_converting_function (true)
179 if (plist && plist->takes_varargs ())
188 for (
size_t i = 0;
i < args.size (); ++
i, ++piter)
190 if (piter == plist->end ())
200 bool all_breaking =
false;
201 if (
fcn.is_special_expr ())
217 "anonymous functions");
220 return_value = retvar;
245 if (! return_value && rlist && rlist->
size () == 1)
253 for (variable_map::iterator iter =
m_vmap.begin ();
257 if (iter->second != return_value)
304 m_vmap[short_name] = short_result;
360 increment =
visit (tinc);
365 base, limit, increment));
411 m_vmap[iter_name] = iterator;
443 bool all_breaking =
false;
574 std::vector<jit_block *> entry_blocks (lst.
size () + 1 - last_else);
580 for (
size_t i = 1; iter != lst.
end (); ++iter, ++
i)
591 entry_blocks[entry_blocks.size () - 1] =
tail;
599 size_t num_incoming = 0;
601 for (
size_t i = 0; iter != lst.
end (); ++iter, ++
i)
622 entry_blocks[
i + 1]);
639 current_breaks.splice (current_breaks.end (),
m_breaks);
640 current_continues.splice (current_continues.end (),
m_continues);
646 if (num_incoming || ! last_else)
804 bool do_bind_ans =
false;
864 assert (expr &&
"Switch value can not be null");
868 size_t case_blocks_num = lst->
size ();
870 if (! case_blocks_num)
874 size_t has_otherwise = 0;
879 std::vector<jit_block *> entry_blocks (case_blocks_num+1 - has_otherwise);
884 for (
size_t i = 1;
i < case_blocks_num; ++
i)
892 entry_blocks[entry_blocks.size()-1] =
tail;
900 size_t num_incoming = 0;
903 for (
size_t i = 0;
i < case_blocks_num; ++iter, ++
i)
948 current_breaks.splice (current_breaks.end (),
m_breaks);
949 current_continues.splice (current_continues.end (),
m_continues);
956 if (num_incoming || ! has_otherwise)
992 assert (expr &&
"While expression can not be null");
1004 bool all_breaking =
false;
1009 loop_body->
accept (*
this);
1013 all_breaking =
true;
1057 bool all_breaking =
false;
1062 loop_body->
accept (*
this);
1066 all_breaking =
true;
1091 assert (expr &&
"Do-Until expression can not be null");
1138 variable_map::const_iterator iter;
1139 iter =
m_vmap.find (vname);
1140 return iter !=
m_vmap.end () ? iter->second :
nullptr;
1161 if (
val.is_undefined ())
1197 std::stringstream ss;
1198 ss << prefix << count;
1209 if (! (
type.size () == 1 &&
type[0] ==
'('))
1212 std::list<tree_argument_list *> args = exp.
arg_lists ();
1213 if (args.size () != 1)
1215 "tree_index_expression");
1221 if (arg_list->
size () < 1)
1234 object =
visit (tree_object);
1236 size_t narg = arg_list->
size ();
1238 bool have_extra = extra_arg;
1239 std::vector<jit_value *> call_args (narg + 1 + have_extra);
1242 for (
size_t idx = 0; iter != arg_list->
end (); ++idx, ++iter)
1246 &std::vector<jit_magic_end::context>::pop_back);
1250 call_args[idx + 1] =
visit (*iter);
1254 call_args[call_args.size () - 1] = extra_arg;
1269 if (isa<tree_identifier> (exp))
1272 = dynamic_cast<tree_index_expression *> (exp))
1275 do_assign (idx->expression (), new_object,
true);
1286 bool print,
bool artificial)
1318 for (block_list::const_iterator iter = lst.begin (); iter != lst.end ();
1330 const std::list<jit_value *>& constants,
1339 iter != m_entry_block->
end ();
1342 = dynamic_cast<jit_extract_argument *> (*iter))
1343 m_argument_vec.push_back (std::make_pair (extract->name (),
true));
1348 llvm::Type *arg_type =
any->to_llvm ();
1349 llvm::FunctionType *ft;
1350 ft = llvm::FunctionType::get (llvm::Type::getVoidTy (
context),
1351 arg_type->getPointerTo (),
false);
1368 llvm::Value *loaded_arg =
builder.CreateConstInBoundsGEP1_32 (arg_type,
arg,
i);
1387 const std::list<jit_value *>& constants,
1389 const std::vector<jit_type *>& args)
1411 for (
size_t i = 0;
i < args.size () && piter != pend; ++
i, ++piter)
1432 const std::list<jit_value *>& constants)
1434 std::list<jit_block *>::const_iterator biter;
1435 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1438 llvm::BasicBlock *m_block = llvm::BasicBlock::Create (
context,
1448 for (std::list<jit_value *>::const_iterator iter = constants.begin ();
1449 iter != constants.end (); ++iter)
1450 if (! isa<jit_instruction> (*iter))
1454 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1458 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1462 piter != m_block.
end () && isa<jit_phi> (*piter); ++piter)
1473 llvm::PHINode *llvm_phi = phi->
to_llvm ();
1484 cs.stash_llvm (
builder.CreateGlobalStringPtr (
cs.value ()));
1496 cs.stash_llvm (llvm::ConstantFP::get (
cs.type_llvm (),
cs.value ()));
1504 llvm::Value *
real = llvm::ConstantFP::get (scalar_t,
value.real ());
1505 llvm::Value *
imag = llvm::ConstantFP::get (scalar_t,
value.imag ());
1511 ci.stash_llvm (llvm::ConstantInt::get (ci.type_llvm (), ci.value ()));
1517 llvm::StructType *stype = llvm::cast<llvm::StructType>(
cr.type_llvm ());
1520 const jit_range& rng =
cr.value ();
1522 llvm::Constant *constants[4];
1523 constants[0] = llvm::ConstantFP::get (scalar_t, rng.m_base);
1524 constants[1] = llvm::ConstantFP::get (scalar_t, rng.m_limit);
1525 constants[2] = llvm::ConstantFP::get (scalar_t, rng.m_inc);
1526 constants[3] = llvm::ConstantInt::get (idx, rng.m_nelem);
1528 llvm::Value *as_llvm;
1529 as_llvm = llvm::ConstantStruct::get (stype,
1530 llvm::makeArrayRef (constants, 4));
1531 cr.stash_llvm (as_llvm);
1537 llvm::BasicBlock *m_block =
b.to_llvm ();
1538 builder.SetInsertPoint (m_block);
1546 b.stash_llvm (
builder.CreateBr (
b.successor_llvm ()));
1564 std::vector<jit_value *> args (call.
arguments ().size ());
1565 for (
size_t i = 0;
i < args.size (); ++
i)
1619 llvm::PHINode *node = llvm::PHINode::Create (phi.
type_llvm (),
1663 if (isa<jit_assign_base> (overwrite))
1689 : m_blocks (ablocks), m_factory (afactory), m_vmap (avmap) { }
1698 for (std::list<jit_value *>::const_iterator iter = constants.begin ();
1699 iter != constants.end (); ++iter)
1711 next->stash_in_worklist (
false);
1745 iter != succ->
end () && isa<jit_phi> (*iter); ++iter)
1764 for (variable_map::const_iterator iter =
m_vmap.begin ();
1769 std::list<jit_block *> ssa_worklist;
1770 iter->second->use_blocks (visited);
1771 ssa_worklist.insert (ssa_worklist.begin (), visited.begin (),
1774 while (ssa_worklist.size ())
1777 ssa_worklist.pop_front ();
1780 diter !=
b->df_end (); ++diter)
1783 if (! added_phi.count (dblock))
1788 added_phi.insert (dblock);
1791 if (! visited.count (dblock))
1793 ssa_worklist.push_back (dblock);
1794 visited.insert (dblock);
1806 if (ablock.
visited (avisit_count))
1811 iter != ablock.
end ();
1825 iter != finish->
end () && isa<jit_phi> (*iter);)
1831 if (
var->has_top ())
1838 assert (
var->name ().size () &&
var->name ()[0] ==
'#');
1853 std::set<jit_value *> temporaries;
1887 iter !=
b->end () && isa<jit_phi> (*iter);)
1891 iter =
b->remove (iter);
1931 while (iter != ablock.
end () && isa<jit_phi> (*iter))
1937 if (phi->
use_count () == 1 && isa<jit_assign> (use->
user ()))
1944 if (!
arg->needs_release ())
1967 iter != ablock.
end ();
1977 if (fu_block && fu_block != &ablock && instr->
needs_release ())
1978 temp.insert (instr);
1981 if (isa<jit_call> (instr))
1987 if (!
arg->needs_release ())
2000 if (! temp.size () || ! isa<jit_error_check> (ablock.
terminator ()))
2008 for (std::set<jit_value *>::const_iterator iter = temp.begin ();
2009 iter != temp.end ();
2029 iter != ablock.
end () && isa<jit_phi> (*iter); ++iter)
2043 if (
arg->type () != phi.
type ())
2088 bool abort_on_failure)
2091 void *pfn = llvm::RTDyldMemoryManager::getPointerToNamedFunction (
name,
2097 if ((pfn ==
nullptr) && abort_on_failure)
2098 llvm::report_fatal_error (
"Program used external function '" +
name +
2099 "' which could not be resolved!");
2106 uint64_t addr = llvm::SectionMemoryManager::getSymbolAddress (
name);
2112 llvm::report_fatal_error (
"Program used extern function '" +
name +
2113 "' which could not be resolved!");
2128 : target_machine (nullptr)
2155 llvm::ExecutionEngine *
e = llvm::EngineBuilder (std::move (module_owner))
2157 .setMCJITMemoryManager(llvm::make_unique<jit_memory_manager> ())
2166 std::cerr <<
"Failed to create JIT engine" << std::endl;
2167 std::cerr <<
err << std::endl;
2188 std::list<jit_module*>::const_iterator it;
2192 uint64_t addr = (*it)->getFunctionAddress (
name);
2195 return reinterpret_cast<void*
> (addr);
2204 std::list<jit_module*>::const_iterator it;
2208 uint64_t addr = (*it)->getFunctionAddress (
name);
2223 llvm::InitializeNativeTarget ();
2224 llvm::InitializeNativeTargetAsmPrinter ();
2225 llvm::InitializeNativeTargetAsmParser ();
2268 extra_vars[
"#for_bounds0"] = &bounds;
2272 if (! info || ! info->
match (extra_vars))
2284 return info->
execute (extra_vars);
2294 if (! info || ! info->
match ())
2313 if (! info || ! info->
match (args))
2317 fcn.stash_info (info);
2342 return rng.
numel ();
2353 : m_module (nullptr), m_engine (nullptr)
2369 engine_owner.release ();
2384 const llvm::Twine &
name)
const 2389 return llvm::Function::Create (ftype, llvm::Function::ExternalLinkage,
2397 std::vector<llvm::Type*> types)
const 2399 return llvm::Intrinsic::getDeclaration
2400 (
m_module, static_cast<llvm::Intrinsic::ID> (
id), types);
2404 llvm::GlobalVariable*
2406 const llvm::Twine&
name)
const 2408 return new llvm::GlobalVariable (*
m_module,
type, is_constant,
2409 llvm::GlobalValue::ExternalLinkage,
2438 module_pass_manager->add (llvm::createAlwaysInlinerPass ());
2456 pass_manager->add (llvm::createCFGSimplificationPass ());
2458 #if defined (HAVE_LLVM_ANALYSIS_BASICALIASANALYSIS_H) 2459 pass_manager->add (llvm::createBasicAAWrapperPass ());
2461 pass_manager->add (llvm::createBasicAliasAnalysisPass ());
2464 pass_manager->add (llvm::createPromoteMemoryToRegisterPass ());
2465 pass_manager->add (llvm::createInstructionCombiningPass ());
2466 pass_manager->add (llvm::createReassociatePass ());
2467 pass_manager->add (llvm::createGVNPass ());
2468 pass_manager->add (llvm::createCFGSimplificationPass ());
2469 pass_manager->doInitialization ();
2471 module_pass_manager->run (*
m_module);
2472 pass_manager->run (*fn);
2474 delete module_pass_manager;
2475 delete pass_manager;
2481 llvm::raw_fd_ostream fout (
"test.bc", ec, llvm::sys::fs::F_None);
2490 llvm::WriteBitcodeToFile (
m_module, fout);
2504 : m_llvm_function_name (
""),
2505 m_function (nullptr),
2506 m_argument_types (ov_args.
length ())
2508 size_t nargs = ov_args.
length ();
2509 for (
size_t i = 0;
i < nargs; ++
i)
2526 std::cout <<
"-------------------- Compiling function ";
2527 std::cout <<
"--------------------\n";
2533 blocks.
print (std::cout,
"octave jit ir");
2544 std::cout <<
"-------------------- raw function ";
2545 std::cout <<
"--------------------\n";
2546 std::cout << *raw_fn.
to_llvm () << std::endl;
2547 llvm::verifyFunction (*raw_fn.
to_llvm ());
2556 llvm::BasicBlock *wrapper_body = wrapper.
new_block ();
2557 builder.SetInsertPoint (wrapper_body);
2560 std::vector<llvm::Value *> raw_args (nargs);
2561 for (
size_t i = 0;
i < nargs; ++
i)
2593 llvm::Function *llvm_function = wrapper.
to_llvm ();
2598 std::cout <<
"-------------------- optimized and wrapped ";
2599 std::cout <<
"--------------------\n";
2600 std::cout << *llvm_function << std::endl;
2601 llvm::verifyFunction (*llvm_function);
2610 llvm_function->eraseFromParent ();
2611 llvm_function =
nullptr;
2626 std::cout <<
"jit fail: " <<
e.what () << std::endl;
2645 size_t nargs = ov_args.
length ();
2646 std::vector<octave_base_value *> args (nargs);
2647 for (
size_t i = 0;
i < nargs; ++
i)
2669 size_t nargs = ov_args.
length ();
2673 for (
size_t i = 0;
i < nargs; ++
i)
2683 : m_llvm_function_name (
tree_jit::generate_unique_function_name ()),
2684 m_function (nullptr)
2690 : m_llvm_function_name (
tree_jit::generate_unique_function_name ()),
2691 m_function (nullptr)
2698 : m_llvm_function_name (
tree_jit::generate_unique_forloop_name ()),
2699 m_function (nullptr)
2710 std::vector<octave_base_value *> real_arguments (
m_arguments.size ());
2720 real_arguments[
i] = obv;
2733 if (
name.size () &&
name[0] !=
'#')
2765 llvm::Function * llvm_function =
nullptr;
2779 std::cout <<
"-------------------- Compiling tree --------------------\n";
2781 blocks.
print (std::cout,
"octave jit ir");
2787 llvm_function = to_llvm.
convert_loop (*
this, infer.get_blocks (),
2800 std::cout <<
"jit fail: " <<
e.what () << std::endl;
2811 std::cout <<
"-------------------- llvm ir --------------------";
2812 std::cout << *llvm_function << std::endl;
2813 llvm::verifyFunction (*llvm_function);
2820 std::cout <<
"-------------------- optimized llvm ir " 2821 <<
"--------------------\n";
2822 std::cout << *llvm_function << std::endl;
2831 llvm_function->eraseFromParent ();
2832 llvm_function =
nullptr;
2845 vmap::const_iterator iter = extra_vars.find (vname);
2847 if (iter == extra_vars.end ())
2851 return scope.
varval (vname);
2854 return *iter->second;
2874 #if defined (HAVE_LLVM) 2877 octave_unused_parameter (args);
2878 octave_unused_parameter (
nargout);
2898 #if defined (HAVE_LLVM) 2901 octave_unused_parameter (args);
2902 octave_unused_parameter (
nargout);
2921 #if defined (HAVE_LLVM) 2924 octave_unused_parameter (args);
2925 octave_unused_parameter (
nargout);
2949 #if defined (HAVE_LLVM) 2953 octave_unused_parameter (args);
2954 octave_unused_parameter (
nargout);
size_t m_for_bounds_count
jit_value * do_assign(tree_expression *exp, jit_value *rhs, bool artificial=false)
llvm::BasicBlock * successor_llvm(size_t idx=0) const
tree_expression * right_hand_side(void)
static const jit_operation & destroy(void)
virtual std::string name(void) const
virtual bool needs_release(void) const
jit_block * dom_successor(size_t idx) const
static const jit_operation & for_init(void)
virtual octave::symbol_scope scope(void)
#define SET_INTERNAL_VARIABLE_WITH_LIMITS(NM, MINVAL, MAXVAL)
void create_dom_tree(void)
jit_instruction * prepend(jit_instruction *instr)
instruction_list::iterator iterator
octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
symbol_record find_symbol(const std::string &name, symbol_scope &sid)
std::unique_ptr< llvm::Module > ModuleOwner
void visit_decl_command(tree_decl_command &)
virtual void construct_ssa(void)
llvm::Type * to_llvm(void) const
octave_value::unary_op op_type(void) const
void stash_argument(size_t i, jit_value *arg)
octave_base_value * internal_rep(void) const
bool is_global(void) const
void visit_multi_assignment(tree_multi_assignment &)
llvm::Function * m_function
jit_function_info(octave_user_function &fcn, const octave_value_list &ov_args)
Range range_value(void) const
llvm::Function * to_llvm(void) const
void visit_anon_fcn_handle(tree_anon_fcn_handle &)
void compute_idom(jit_block &entry_block)
NODE_T * first_use(void) const
llvm::BasicBlock * new_block(const std::string &aname="body", llvm::BasicBlock *insert_before=nullptr)
octave_value::binary_op op_type(void) const
void assign(const std::string &name, const octave_value &value, bool force_add)
jit_value * src(void) const
void visit_no_op_command(tree_no_op_command &)
static llvm::Type * get_index_llvm(void)
const std::string & name(void) const
bool is_default_case(void)
std::string m_llvm_function_name
void finalizeObject(void)
void visit_switch_case_list(tree_switch_case_list &)
void visit_simple_for_command(tree_simple_for_command &)
jit_value * result(void) const
bool artificial(void) const
static const jit_operation & paren_subsasgn(void)
octave_value find(const vmap &extra_vars, const std::string &vname) const
uint64_t do_getSymbolAddress(const std::string &name) const
bool alive(const jit_block *asuccessor) const
std::list< jit_module * > jm_list
tree_expression * base(void)
jit_block * first_use_block(void)
void visit_octave_user_script(octave_user_script &)
static const jit_operation & cast(jit_type *result)
void visit_constant(tree_constant &)
std::string next_name(const char *prefix, size_t &count, bool inc)
identity matrix If supplied two scalar respectively For allows like xample val
llvm::Value * argument_llvm(size_t i) const
std::map< std::string, const octave_value * > vmap
df_set::const_iterator df_iterator
llvm::Function * create_llvm_function(llvm::FunctionType *ftype, const llvm::Twine &name) const
void push_back(jit_block *b)
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by zero($0/0$)
jit_block * parent(void) const
const value_list & constants(void) const
static const jit_operation & binary_op(int op)
std::string tail(const std::string &path)
jit_terminator * terminator(void) const
static jit_type * get_any_ptr(void)
void visit_if_command_list(tree_if_command_list &)
static llvm::Value * insert_interrupt_check(llvm::IRBuilderD &bld)
virtual void accept(tree_walker &tw)=0
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void release_dead_phi(jit_block &ablock)
static int next_function_number
jit_const< jit_range, jit_typeinfo::get_range, const jit_range & > jit_const_range
void visit_statement(tree_statement &)
void accept(tree_walker &tw)
#define SET_INTERNAL_VARIABLE(NM)
jit_module(const std::string &module_name=tree_jit::generate_unique_module_name())
static llvm::Type * get_scalar_llvm(void)
static const jit_operation & for_index(void)
std::vector< jit_magic_end::context > m_end_context
void do_return(llvm::IRBuilderD &builder, llvm::Value *rval=nullptr, bool verify=true)
iterator erase(iterator iter)
T * create(const Args &... args)
virtual void push_variable(void)
size_t argument_count(void) const
void visit_octave_user_function_trailer(octave_user_function &)
static binary_op assign_op_to_binary_op(assign_op)
static void unregister_jit_module(jit_module *jm)
llvm::BasicBlock * m_prelude
tree_statement_list * body(void)
void do_register_jit_module(jit_module *jm)
void * do_getPointerToNamedFunction(const std::string &Name) const
std::list< tree_decl_elt * >::iterator iterator
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_instruction * back(void)
static llvm::LLVMContext & context
llvm::Function * convert_loop(const jit_module &module, const jit_block_list &blocks, const std::list< jit_value *> &constants, const std::string &llvm_function_name)
static const jit_operation & print_value(void)
jit_value * overwrite(void) const
std::string str_print_code(void)
bool execute(const vmap &extra_vars=vmap()) const
symbol_scope __get_current_scope__(const std::string &who)
Complex complex_value(bool frc_str_conv=false) const
jit_block & final_block(void)
bool m_converting_function
static llvm::Value * create_complex(llvm::Value *real, llvm::Value *imag)
static llvm::IRBuilder builder(llvm::getGlobalContext())
jited_function m_function
void finish_phi(jit_phi *phi)
void place_releases(void)
llvm::Value * argument(llvm::IRBuilderD &builder, size_t idx) const
tree_statement_list * commands(void)
bool takes_varargs(void) const
jited_function m_function
void visit_boolean_expression(tree_boolean_expression &)
bool match(const vmap &extra_vars=vmap()) const
jit_block * successor(size_t i) const
jit_variable * create_variable(const std::string &vname, jit_type *type, bool isarg=true)
uint64_t getFunctionAddress(const std::string &name) const
void(* jited_function)(octave_base_value **)
static jit::ModuleOwner open_new_module(const std::string &module_name=generate_unique_module_name())
void visit_index_expression(tree_index_expression &)
void visit_decl_elt(tree_decl_elt &)
void visit_binary_expression(tree_binary_expression &)
llvm::PassManager PassManager
const type_bound_vector & get_bounds(void) const
const variable_map & get_variable_map(void) const
void visit_try_catch_command(tree_try_catch_command &)
void do_add_global_mapping(const llvm::GlobalValue *gv, void *p) const
llvm::FunctionPassManager FunctionPassManager
std::string name(void) const
NODE_T * next(void) const
jit_const< double, jit_typeinfo::get_scalar > jit_const_scalar
static jit_type * get_range(void)
std::string next_shortcircut_result(bool inc=true)
static void * getPointerToNamedFunction(const std::string &name)
jit_const< octave_idx_type, jit_typeinfo::get_index > jit_const_index
void stash_llvm(llvm::Value *compiled)
void visit_colon_expression(tree_colon_expression &)
void visit_funcall(tree_funcall &)
bool visited(size_t avisit_count)
tree_statement_list * commands(void)
bool is_persistent(void) const
jit_variable * get_variable(const std::string &vname)
virtual void replace_with(jit_value *m_value)
void append_users(jit_value *v)
variable check_variable(void) const
std::string next_iterator(bool inc=true)
jit_convert::variable_map variable_map
void do_construct_ssa(jit_block &block, size_t avisit_count)
void visit_statement_list(tree_statement_list &)
octave_base_value *(* jited_function)(octave_base_value **)
void stash_in_worklist(bool ain_worklist)
std::unique_ptr< llvm::ExecutionEngine > EngineOwner
llvm::ExecutionEngine * m_engine
symbol_table & __get_symbol_table__(const std::string &who)
nd deftypefn *std::string name
static const jit_operation & release(void)
static const jit_operation & paren_subsref(void)
static tree_jit & instance(void)
void push_worklist(jit_instruction *instr)
jit_block * back(void) const
tree_expression * expression(void)
void append_users_term(jit_terminator *term)
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)
static jit_type * type_of(const octave_value &ov)
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit first
std::set< jit_block * > df_set
static const jit_operation & grab(void)
jit::ModuleOwner do_open_new_module(const std::string &module_name) const
std::vector< std::pair< std::string, bool > > m_argument_vec
size_t successor_count(void) const
create a structure array and initialize its values The dimensions of each cell array of values must match Singleton cells and non cell values are repeated so that they fill the entire array If the cells are create an empty structure array with the specified field names If the argument is an object
jit_call * create_checked(const Args &... args)
bool in_worklist(void) const
size_t use_count(void) const
std::list< jit_block * > block_list
symbol_record::context_id current_context(void) const
jit_type * result_type(void) const
jit_value * argument(size_t i) const
static void register_jit_module(jit_module *jm)
bool do_execute(tree_simple_for_command &cmd, const octave_value &bounds)
void mark_artificial(void)
jit_const_index * m_index
jit_variable * dest(void) const
bool have_breakpoints(void)
llvm::Type * type_llvm(void) const
std::list< tree_argument_list * > arg_lists(void)
static const jit_operation & logically_true(void)
jit_block & entry_block(void)
jit_factory & get_factory(void)
context resolve_context(void) const
void convert(const jit_block_list &blocks, const std::list< jit_value *> &constants)
void visit_identifier(tree_identifier &)
std::string type_tags(void)
jit_block * successor(size_t idx=0) const
tree_expression * control_expr(void)
void visit_octave_user_function_header(octave_user_function &)
jit_type * type(void) const
tree_expression * left_hand_side(void)
virtual uint64_t getSymbolAddress(const std::string &name)
void warn_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
void accept(tree_walker &tw)
std::string next_for_bounds(bool inc=true)
octave_idx_type numel(void) const
static const jit_operation & for_check(void)
void visit_function_def(tree_function_def &)
jit_convert(tree &tee, jit_type *for_bounds=nullptr)
jit_function convert_function(const jit_module &module, const jit_block_list &blocks, const std::list< jit_value *> &constants, octave_user_function &fcn, const std::vector< jit_type *> &args)
void visit_parameter_list(tree_parameter_list &)
#define panic_impossible()
llvm::Value * call(llvm::IRBuilderD &builder, const arg_vec &in_args=arg_vec()) const
std::vector< std::pair< std::string, bool > > m_arguments
void visit_octave_user_function_trailer(octave_user_function &)
std::list< jit_block * >::iterator iterator
void visit_return_command(tree_return_command &)
const jit_function & overload(void) const
void visit_switch_case(tree_switch_case &)
void stash_info(jit_info *jinfo)
static jit_type * get_scalar(void)
jit_block_list & get_blocks(void)
std::string release(void)
static void reset_ids(void)
tree_expression * increment(void)
static const jit_function & get_release(jit_type *type)
jit_variable * find_variable(const std::string &vname) const
void compile(tree &tee, jit_type *for_bounds=0)
tree_command * command(void)
const std::vector< std::pair< std::string, bool > > & get_arguments(void) const
llvm::GlobalVariable * create_global_variable(llvm::Type *type, bool is_constant, const llvm::Twine &name) const
jit_infer(jit_factory &afactory, jit_block_list &ablocks, const variable_map &avmap)
bool execute(const octave_value_list &ov_args, octave_value_list &retval) const
llvm::Value * cond_llvm(void) const
octave_value varval(const std::string &name) const
void visit_cell(tree_cell &)
With real return the complex result
size_t dom_successor_count(void) const
void visit_if_clause(tree_if_clause &)
jit_instruction * insert_after(iterator loc, jit_instruction *instr)
virtual bool is_identifier(void) const
jit_block * front(void) const
tree_expression * switch_value(void)
std::string m_llvm_function_name
void visit_fcn_handle(tree_fcn_handle &)
void add_incoming(jit_block *from, jit_value *value)
void visit_prefix_expression(tree_prefix_expression &)
jit_type * result(void) const
octave::unwind_protect frame
std::list< jit_instruction * > m_worklist
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
charNDArray max(char d, const charNDArray &m)
static int next_forloop_number
static jit_type * get_any(void)
tree_statement_list * body(void)
llvm::Value * to_llvm(void) const
static const jit_operation & unary_op(int op)
tree_expression * rhs(void)
static llvm::Value * insert_error_check(llvm::IRBuilderD &bld)
symbol_scope __require_current_scope__(const std::string &who)
void visit_octave_user_function_header(octave_user_function &)
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
jit_instruction * insert_before(iterator loc, jit_instruction *instr)
static int next_module_number
void operator=(const jit_memory_manager &)=delete
bool is_else_clause(void)
bp_table & __get_bp_table__(const std::string &who)
const jit_function & overload() const
size_t successor_count(void) const
void initialize(const symbol_scope &s)
tree_expression * left_hand_side(void)
llvm::PHINode * to_llvm(void) const
jit_block * incoming(size_t i) const
const std::vector< jit_use > & arguments(void) const
const std::string & name(void) const
static jit::EngineOwner create_new_engine(jit::ModuleOwner module_owner)
void visit_switch_command(tree_switch_command &)
void visit_simple_assignment(tree_simple_assignment &)
jit_block * m_entry_block
static const jit_operation & make_range(void)
void visit_if_command(tree_if_command &)
jit_block * m_final_block
type_bound_vector m_bounds
void visit_argument_list(tree_argument_list &)
llvm::Function * get_intrinsic_declaration(size_t id, std::vector< llvm::Type *> types) const
jit_info * get_info(void) const
jit_const< Complex, jit_typeinfo::get_complex > jit_const_complex
double double_value(bool frc_str_conv=false) const
octave_idx_type length(void) const
std::pair< jit_type *, std::string > type_bound
void visit_continue_command(tree_continue_command &)
jit_block * maybe_split(jit_factory &factory, jit_block_list &blocks, jit_block *asuccessor)
void optimize(llvm::Function *fn) const
jit_block_list & m_blocks
jit_value * visit(tree *tee)
static jit_type * get_complex(void)
void add_method(T *obj, void(T::*method)(void))
tree_expression * lhs(void)
tree_expression * case_label(void)
std::string name(void) const
ColumnVector imag(const ComplexColumnVector &a)
const jit_function & overload(void) const
void visit_while_command(tree_while_command &)
void visit_matrix(tree_matrix &)
OCTAVE_EXPORT octave_value_list error nd deftypefn *const octave_scalar_map err
void visit_return_list(tree_return_list &)
virtual ~jit_memory_manager()
void visit_octave_user_function(octave_user_function &)
jit_instruction * user(void) const
std::complex< double > Complex
void do_unregister_jit_module(jit_module *jm)
octave_value varval(context_id context) const
std::vector< jit_type * > m_argument_types
bool is_range(void) const
void visit_decl_init_list(tree_decl_init_list &)
tree_expression * operand(void)
size_t use_count(void) const
std::ostream & print(std::ostream &os, const std::string &header) const
ColumnVector real(const ComplexColumnVector &a)
void accept(tree_walker &tw)
jit_const_index * m_count
jit_value * result(void) const
llvm::TargetMachine * target_machine
type_bound_vector m_bounds
std::string name(void) const
void visit_break_command(tree_break_command &)
tree_expression * condition(void)
virtual bool is_assignment_expression(void) const
void finish_breaks(jit_block *dest, const block_list &lst)
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
nd group nd example For each display the value
bool m_converting_function
void visit_complex_for_command(tree_complex_for_command &)
virtual void * getPointerToNamedFunction(const std::string &name, bool abort_on_failure)
void visit_unwind_protect_command(tree_unwind_protect_command &)
void visit_do_until_command(tree_do_until_command &)
void visit_postfix_expression(tree_postfix_expression &)
static uint64_t getSymbolAddress(const std::string &name)
void visit_statement_list(tree_statement_list &)
std::map< std::string, llvm::Value * > m_arguments
tree_switch_case_list * case_list(void)
void stash_info(jit_info *jinfo)
virtual void visit(jit_block &)
static const jit_operation & create_undef(void)
llvm::BasicBlock * incoming_llvm(size_t i) const
jit_info * get_info(void) const
octave_value::assign_op op_type(void) const
bool match(const octave_value_list &ov_args) const
static const size_t NO_ID
tree_if_command_list * cmd_list(void)
jit_instruction * resolve(tree_index_expression &exp, jit_value *extra_arg=nullptr, bool lhs=false)
tree_expression * condition(void)
const variable_map & m_vmap
bool print_result(void) const
jit_call * create_checked_impl(jit_call *ret)
bool has_magic_end(void) const
tree_expression * limit(void)
tree_expression * expression(void)
void release_temp(jit_block &ablock, std::set< jit_value *> &temp)
size_t trip_count(const octave_value &bounds) const