26 #define __STDC_LIMIT_MACROS
27 #define __STDC_CONSTANT_MACROS
29 #if defined (HAVE_CONFIG_H)
51 #if defined (HAVE_LLVM)
53 #include <llvm/Analysis/CallGraph.h>
54 #include <llvm/Analysis/Passes.h>
56 #if defined (HAVE_LLVM_IR_VERIFIER_H)
57 # include <llvm/IR/Verifier.h>
59 # include <llvm/Analysis/Verifier.h>
62 #if defined (HAVE_LLVM_ANALYSIS_BASICALIASANALYSIS_H)
64 # include <llvm/Analysis/BasicAliasAnalysis.h>
69 #if defined (HAVE_LLVM_BITCODE_READERWRITER_H)
71 # include <llvm/Bitcode/ReaderWriter.h>
74 # include <llvm/Bitcode/BitcodeReader.h>
75 # include <llvm/Bitcode/BitcodeWriter.h>
78 #include <llvm/ExecutionEngine/ExecutionEngine.h>
82 #include <llvm/ExecutionEngine/MCJIT.h>
83 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
85 #if defined (LEGACY_PASSMANAGER)
86 # include <llvm/IR/LegacyPassManager.h>
88 # include <llvm/PassManager.h>
91 #if defined (HAVE_LLVM_IR_FUNCTION_H)
92 # include <llvm/IR/LLVMContext.h>
93 # include <llvm/IR/Module.h>
94 # include <llvm/IR/Intrinsics.h>
96 # include <llvm/LLVMContext.h>
97 # include <llvm/Module.h>
98 # include <llvm/Intrinsics.h>
101 #if defined (HAVE_LLVM_SUPPORT_IRBUILDER_H)
102 # include <llvm/Support/IRBuilder.h>
103 #elif defined(HAVE_LLVM_IR_IRBUILDER_H)
104 # include <llvm/IR/IRBuilder.h>
106 # include <llvm/IRBuilder.h>
109 #include <llvm/Support/raw_os_ostream.h>
110 #include <llvm/Support/TargetSelect.h>
112 #if defined (HAVE_LLVM_IR_DATALAYOUT_H)
113 # include <llvm/IR/DataLayout.h>
114 #elif defined(HAVE_LLVM_DATALAYOUT_H)
115 # include <llvm/DataLayout.h>
117 # include <llvm/Target/TargetData.h>
120 #include <llvm/Transforms/IPO.h>
121 #include <llvm/Transforms/Scalar.h>
126 #if defined (HAVE_LLVM_TRANSFORMS_SCALAR_GVN_H)
127 # include <llvm/Transforms/Scalar/GVN.h>
142 #if defined (LEGACY_PASSMANAGER)
165 : m_converting_function (false)
186 for (
auto iter =
m_vmap.begin (); iter !=
m_vmap.end (); ++iter)
189 const std::string&
name = var->
name ();
198 const std::vector<jit_type *>& args)
199 : m_converting_function (true)
213 auto piter = plist->
begin ();
214 for (
size_t i = 0; i < args.size (); ++i, ++piter)
216 if (piter == plist->
end ())
226 bool all_breaking =
false;
243 "anonymous functions");
246 return_value = retvar;
271 if (! return_value && rlist && rlist->
size () == 1)
279 for (
auto iter =
m_vmap.begin ();
283 if (iter->second != return_value)
330 m_vmap[short_name] = short_result;
386 increment =
visit (tinc);
391 base, limit, increment));
437 m_vmap[iter_name] = iterator;
469 bool all_breaking =
false;
562 if (ti.has_magic_end ())
592 std::vector<jit_block *> entry_blocks (lst.
size () + 1 - last_else);
596 auto iter = lst.
begin ();
598 for (
size_t i = 1; iter != lst.
end (); ++iter, ++i)
609 entry_blocks[entry_blocks.size () - 1] =
tail;
617 size_t num_incoming = 0;
619 for (
size_t i = 0; iter != lst.
end (); ++iter, ++i)
640 entry_blocks[i + 1]);
657 current_breaks.splice (current_breaks.end (),
m_breaks);
658 current_continues.splice (current_continues.end (),
m_continues);
664 if (num_incoming || ! last_else)
810 bool do_bind_ans =
false;
816 do_bind_ans = (!
id->is_variable (
m_scope.current_context ()));
857 assert (expr &&
"Switch value can not be null");
861 size_t case_blocks_num = lst->
size ();
863 if (! case_blocks_num)
867 size_t has_otherwise = 0;
872 std::vector<jit_block *> entry_blocks (case_blocks_num+1 - has_otherwise);
877 for (
size_t i = 1; i < case_blocks_num; ++i)
885 entry_blocks[entry_blocks.size()-1] =
tail;
893 size_t num_incoming = 0;
895 auto iter = lst->
begin ();
896 for (
size_t i = 0; i < case_blocks_num; ++iter, ++i)
941 current_breaks.splice (current_breaks.end (),
m_breaks);
942 current_continues.splice (current_continues.end (),
m_continues);
949 if (num_incoming || ! has_otherwise)
985 assert (expr &&
"While expression can not be null");
997 bool all_breaking =
false;
1002 loop_body->
accept (*
this);
1006 all_breaking =
true;
1050 bool all_breaking =
false;
1055 loop_body->
accept (*
this);
1059 all_breaking =
true;
1084 assert (expr &&
"Do-Until expression can not be null");
1131 variable_map::const_iterator iter;
1132 iter =
m_vmap.find (vname);
1133 return iter !=
m_vmap.end () ? iter->second :
nullptr;
1146 if (record.is_persistent () || record.is_global ())
1184 return m_vmap[vname] = var;
1190 std::stringstream ss;
1191 ss << prefix << count;
1202 if (! (
type.size () == 1 &&
type[0] ==
'('))
1205 std::list<tree_argument_list *> args = exp.
arg_lists ();
1206 if (args.size () != 1)
1208 "tree_index_expression");
1214 if (arg_list->
size () < 1)
1227 object =
visit (tree_object);
1229 size_t narg = arg_list->
size ();
1230 auto iter = arg_list->
begin ();
1231 bool have_extra = extra_arg;
1232 std::vector<jit_value *> call_args (narg + 1 + have_extra);
1233 call_args[0] = object;
1235 for (
size_t idx = 0; iter != arg_list->
end (); ++idx, ++iter)
1239 &std::vector<jit_magic_end::context>::pop_back);
1243 call_args[idx + 1] =
visit (*iter);
1247 call_args[call_args.size () - 1] = extra_arg;
1262 if (isa<tree_identifier> (exp))
1268 do_assign (idx->expression (), new_object,
true);
1279 bool print,
bool artificial)
1311 for (
auto iter = lst.begin (); iter != lst.end (); ++iter)
1322 const std::list<jit_value *>& constants,
1323 const std::string& llvm_function_name)
1330 for (
auto iter = m_entry_block->
begin ();
1331 iter != m_entry_block->
end (); ++iter)
1334 m_argument_vec.push_back (std::make_pair (extract->name (),
true));
1339 llvm::Type *arg_type = any->
to_llvm ();
1340 llvm::FunctionType *ft;
1341 ft = llvm::FunctionType::get (llvm::Type::getVoidTy (
context),
1342 arg_type->getPointerTo (),
false);
1352 llvm::Value *arg = &*(
m_function->arg_begin ());
1356 #if defined (LLVM_IRBUILDER_CREATECONSTINBOUNDSGEP1_32_REQUIRES_TYPE)
1358 llvm::Value *loaded_arg =
builder.CreateConstInBoundsGEP1_32 (arg_type, arg, i);
1361 llvm::Value *loaded_arg =
builder.CreateConstInBoundsGEP1_32 (arg, i);
1380 const std::list<jit_value *>& constants,
1382 const std::vector<jit_type *>& args)
1402 auto piter = plist->
begin ();
1403 auto pend = plist->
end ();
1404 for (
size_t i = 0; i < args.size () && piter != pend; ++i, ++piter)
1407 std::string arg_name = elt->
name ();
1425 const std::list<jit_value *>& constants)
1427 std::list<jit_block *>::const_iterator biter;
1428 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1431 llvm::BasicBlock *m_block = llvm::BasicBlock::Create (
context,
1441 for (
auto iter = constants.begin (); iter != constants.end (); ++iter)
1442 if (! isa<jit_instruction> (*iter))
1446 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1450 for (biter = blocks.
begin (); biter != blocks.
end (); ++biter)
1453 for (
auto piter = m_block.
begin ();
1454 piter != m_block.
end () && isa<jit_phi> (*piter); ++piter)
1465 llvm::PHINode *llvm_phi = phi->
to_llvm ();
1488 cs.stash_llvm (llvm::ConstantFP::get (cs.type_llvm (), cs.value ()));
1496 llvm::Value *
real = llvm::ConstantFP::get (scalar_t, value.real ());
1497 llvm::Value *
imag = llvm::ConstantFP::get (scalar_t, value.imag ());
1503 ci.stash_llvm (llvm::ConstantInt::get (ci.type_llvm (), ci.value ()));
1509 llvm::StructType *stype = llvm::cast<llvm::StructType>(cr.type_llvm ());
1512 const jit_range& rng = cr.value ();
1514 llvm::Constant *constants[4];
1515 constants[0] = llvm::ConstantFP::get (scalar_t, rng.m_base);
1516 constants[1] = llvm::ConstantFP::get (scalar_t, rng.m_limit);
1517 constants[2] = llvm::ConstantFP::get (scalar_t, rng.m_inc);
1518 constants[3] = llvm::ConstantInt::get (idx, rng.m_nelem);
1520 llvm::Value *as_llvm;
1521 as_llvm = llvm::ConstantStruct::get (stype,
1522 llvm::makeArrayRef (constants, 4));
1523 cr.stash_llvm (as_llvm);
1529 llvm::BasicBlock *m_block = b.
to_llvm ();
1530 builder.SetInsertPoint (m_block);
1531 for (
auto iter = b.
begin (); iter != b.
end (); ++iter)
1556 std::vector<jit_value *> args (call.
arguments ().size ());
1557 for (
size_t i = 0; i < args.size (); ++i)
1574 arg =
builder.CreateLoad (arg);
1611 llvm::PHINode *node = llvm::PHINode::Create (phi.
type_llvm (),
1655 if (isa<jit_assign_base> (overwrite))
1681 : m_blocks (ablocks), m_factory (afactory), m_vmap (avmap) { }
1690 for (
auto iter = constants.begin (); iter != constants.end (); ++iter)
1702 next->stash_in_worklist (
false);
1732 if (term->
alive (i))
1735 for (
auto iter = succ->
begin ();
1736 iter != succ->
end () && isa<jit_phi> (*iter); ++iter)
1755 for (
auto iter =
m_vmap.cbegin (); iter !=
m_vmap.cend (); ++iter)
1758 std::list<jit_block *> ssa_worklist;
1759 iter->second->use_blocks (visited);
1760 ssa_worklist.insert (ssa_worklist.begin (), visited.begin (),
1763 while (ssa_worklist.size ())
1766 ssa_worklist.pop_front ();
1768 for (
auto diter = b->
df_begin (); diter != b->
df_end (); ++diter)
1771 if (! added_phi.count (dblock))
1776 added_phi.insert (dblock);
1779 if (! visited.count (dblock))
1781 ssa_worklist.push_back (dblock);
1782 visited.insert (dblock);
1794 if (ablock.
visited (avisit_count))
1798 for (
auto iter = ablock.
begin (); iter != ablock.
end (); ++iter)
1810 for (
auto iter = finish->
begin ();
1811 iter != finish->
end () && isa<jit_phi> (*iter);)
1824 assert (var->
name ().size () && var->
name ()[0] ==
'#');
1839 std::set<jit_value *> temporaries;
1870 for (
auto iter = b->
begin ();
1871 iter != b->
end () && isa<jit_phi> (*iter);)
1914 auto iter = ablock.
begin ();
1915 while (iter != ablock.
end () && isa<jit_phi> (*iter))
1921 if (phi->
use_count () == 1 && isa<jit_assign> (use->
user ()))
1950 for (
auto iter = ablock.
begin (); iter != ablock.
end (); ++iter)
1959 if (fu_block && fu_block != &ablock && instr->
needs_release ())
1960 temp.insert (instr);
1963 if (isa<jit_call> (instr))
1982 if (! temp.size () || ! isa<jit_error_check> (ablock.
terminator ()))
1990 for (
auto iter = temp.cbegin (); iter != temp.cend (); ++iter)
2006 for (
auto iter = ablock.
begin ();
2007 iter != ablock.
end () && isa<jit_phi> (*iter); ++iter)
2066 bool abort_on_failure)
2069 void *pfn = llvm::RTDyldMemoryManager::getPointerToNamedFunction (
name,
2075 if ((pfn ==
nullptr) && abort_on_failure)
2076 llvm::report_fatal_error (
"Program used external function '" +
name +
2077 "' which could not be resolved!");
2084 uint64_t addr = llvm::SectionMemoryManager::getSymbolAddress (
name);
2090 llvm::report_fatal_error (
"Program used extern function '" +
name +
2091 "' which could not be resolved!");
2108 : target_machine (nullptr)
2135 llvm::ExecutionEngine *e = llvm::EngineBuilder (std::move (module_owner))
2137 .setMCJITMemoryManager(llvm::make_unique<jit_memory_manager> ())
2145 error (
"failed to create JIT engine: %s", err.c_str ());
2165 std::list<jit_module*>::const_iterator it;
2169 uint64_t addr = (*it)->getFunctionAddress (
name);
2172 return reinterpret_cast<void*
> (addr);
2181 std::list<jit_module*>::const_iterator it;
2185 uint64_t addr = (*it)->getFunctionAddress (
name);
2200 llvm::InitializeNativeTarget ();
2201 llvm::InitializeNativeTargetAsmPrinter ();
2202 llvm::InitializeNativeTargetAsmParser ();
2245 extra_vars[
"#for_bounds0"] = &bounds;
2249 if (! info || ! info->
match (extra_vars))
2261 return info->
execute (extra_vars);
2271 if (! info || ! info->
match ())
2290 if (! info || ! info->
match (args))
2318 return rng.
numel ();
2329 : m_module (nullptr), m_engine (nullptr)
2345 engine_owner.release ();
2360 const llvm::Twine &
name)
const
2365 return llvm::Function::Create (ftype, llvm::Function::ExternalLinkage,
2373 std::vector<llvm::Type*> types)
const
2375 return llvm::Intrinsic::getDeclaration
2376 (
m_module,
static_cast<llvm::Intrinsic::ID
> (
id), types);
2380 llvm::GlobalVariable*
2382 const llvm::Twine&
name)
const
2384 return new llvm::GlobalVariable (*
m_module,
type, is_constant,
2385 llvm::GlobalValue::ExternalLinkage,
2393 m_engine->addGlobalMapping (gv, p);
2414 #if defined (LLVM_HAS_CREATEALWAYSINLINERPASS)
2417 module_pass_manager->add (llvm::createAlwaysInlinerPass ());
2436 pass_manager->add (llvm::createCFGSimplificationPass ());
2438 #if defined (HAVE_LLVM_ANALYSIS_BASICALIASANALYSIS_H)
2439 pass_manager->add (llvm::createBasicAAWrapperPass ());
2441 pass_manager->add (llvm::createBasicAliasAnalysisPass ());
2444 pass_manager->add (llvm::createPromoteMemoryToRegisterPass ());
2445 pass_manager->add (llvm::createInstructionCombiningPass ());
2446 pass_manager->add (llvm::createReassociatePass ());
2447 pass_manager->add (llvm::createGVNPass ());
2448 pass_manager->add (llvm::createCFGSimplificationPass ());
2449 pass_manager->doInitialization ();
2451 module_pass_manager->run (*
m_module);
2452 pass_manager->run (*fn);
2454 delete module_pass_manager;
2455 delete pass_manager;
2461 llvm::raw_fd_ostream fout (
"test.bc", ec, llvm::sys::fs::F_None);
2470 llvm::WriteBitcodeToFile (
m_module, fout);
2484 : m_llvm_function_name (
""),
2485 m_function (nullptr),
2486 m_argument_types (ov_args.
length ())
2488 size_t nargs = ov_args.
length ();
2489 for (
size_t i = 0; i < nargs; ++i)
2506 octave_stdout <<
"-------------------- Compiling function ";
2527 llvm::verifyFunction (*raw_fn.
to_llvm ());
2536 llvm::BasicBlock *wrapper_body = wrapper.
new_block ();
2537 builder.SetInsertPoint (wrapper_body);
2540 std::vector<llvm::Value *> raw_args (nargs);
2541 for (
size_t i = 0; i < nargs; ++i)
2550 arg =
builder.CreateLoad (arg);
2557 llvm::Value *result = raw_fn.
call (
builder, raw_args);
2567 llvm::Value *zero =
builder.getInt32 (0);
2573 llvm::Function *llvm_function = wrapper.
to_llvm ();
2578 octave_stdout <<
"-------------------- optimized and wrapped ";
2581 llvm::verifyFunction (*llvm_function);
2590 llvm_function->eraseFromParent ();
2591 llvm_function =
nullptr;
2625 size_t nargs = ov_args.
length ();
2626 std::vector<octave_base_value *> args (nargs);
2627 for (
size_t i = 0; i < nargs; ++i)
2649 size_t nargs = ov_args.
length ();
2653 for (
size_t i = 0; i < nargs; ++i)
2663 : m_llvm_function_name (
tree_jit::generate_unique_function_name ()),
2664 m_function (nullptr)
2670 : m_llvm_function_name (
tree_jit::generate_unique_function_name ()),
2671 m_function (nullptr)
2678 : m_llvm_function_name (
tree_jit::generate_unique_forloop_name ()),
2679 m_function (nullptr)
2690 std::vector<octave_base_value *> real_arguments (
m_arguments.size ());
2700 real_arguments[i] = obv;
2713 if (
name.size () &&
name[0] !=
'#')
2714 scope.assign (
m_arguments[i].first, real_arguments[i]);
2728 for (
size_t i = 0; i <
m_bounds.size (); ++i)
2730 const std::string& arg_name =
m_bounds[i].second;
2745 llvm::Function * llvm_function =
nullptr;
2759 octave_stdout <<
"-------------------- Compiling tree --------------------\n";
2791 octave_stdout <<
"-------------------- llvm ir --------------------";
2793 llvm::verifyFunction (*llvm_function);
2801 <<
"--------------------\n";
2811 llvm_function->eraseFromParent ();
2812 llvm_function =
nullptr;
2825 vmap::const_iterator iter = extra_vars.find (vname);
2827 if (iter == extra_vars.end ())
2831 return scope.varval (vname);
2834 return *iter->second;
2840 DEFUN (jit_failcnt, args, nargout,
2854 #if defined (HAVE_LLVM)
2857 octave_unused_parameter (args);
2858 octave_unused_parameter (nargout);
2864 DEFUN (debug_jit, args, nargout,
2878 #if defined (HAVE_LLVM)
2881 octave_unused_parameter (args);
2882 octave_unused_parameter (nargout);
2888 DEFUN (jit_enable, args, nargout,
2901 #if defined (HAVE_LLVM)
2904 octave_unused_parameter (args);
2905 octave_unused_parameter (nargout);
2911 DEFUN (jit_startcnt, args, nargout,
2929 #if defined (HAVE_LLVM)
2933 octave_unused_parameter (args);
2934 octave_unused_parameter (nargout);
charNDArray max(char d, const charNDArray &m)
octave_idx_type numel(void) const
void add_method(T *obj, void(T::*method)(Params...), Args &&... args)
bool have_breakpoints(void)
jit_variable * dest(void) const
jit_value * src(void) const
void mark_artificial(void)
jit_value * overwrite(void) const
bool artificial(void) const
iterator erase(iterator iter)
jit_block * front(void) const
void push_back(jit_block *b)
jit_block * back(void) const
std::list< jit_block * >::iterator iterator
std::ostream & print(std::ostream &os, const std::string &header) const
llvm::BasicBlock * to_llvm(void) const
void create_dom_tree(void)
static const size_t NO_ID
jit_instruction * back(void)
size_t dom_successor_count(void) const
iterator remove(iterator iter)
jit_instruction * insert_after(iterator loc, jit_instruction *instr)
size_t successor_count(void) const
jit_block * maybe_split(jit_factory &factory, jit_block_list &blocks, jit_block *asuccessor)
jit_block * successor(size_t i) const
bool visited(size_t avisit_count)
std::set< jit_block * > df_set
jit_instruction * prepend(jit_instruction *instr)
jit_terminator * terminator(void) const
df_iterator df_begin(void) const
void compute_idom(jit_block &entry_block)
const std::string & name(void) const
size_t use_count(void) const
jit_instruction * front(void)
jit_block * dom_successor(size_t idx) const
df_iterator df_end(void) const
jit_instruction * insert_before(iterator loc, jit_instruction *instr)
const jit_function & overload(void) const
llvm::Value * cond_llvm(void) const
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)
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)
llvm::Function * m_function
std::map< std::string, llvm::Value * > m_arguments
void finish_phi(jit_phi *phi)
void convert(const jit_block_list &blocks, const std::list< jit_value * > &constants)
const std::vector< std::pair< std::string, bool > > & get_arguments(void) const
llvm::BasicBlock * m_prelude
bool m_converting_function
std::vector< std::pair< std::string, bool > > m_argument_vec
virtual void visit(jit_block &)
void visit_boolean_expression(tree_boolean_expression &)
void visit_prefix_expression(tree_prefix_expression &)
void visit_octave_user_function_trailer(octave_user_function &)
void visit_simple_assignment(tree_simple_assignment &)
void visit_octave_user_function(octave_user_function &)
void visit_complex_for_command(tree_complex_for_command &)
std::string next_name(const char *prefix, size_t &count, bool inc)
bool m_converting_function
std::string next_for_bounds(bool inc=true)
void visit_octave_user_function_header(octave_user_function &)
void visit_statement_list(tree_statement_list &)
void visit_parameter_list(tree_parameter_list &)
void visit_multi_assignment(tree_multi_assignment &)
jit_factory & get_factory(void)
void visit_switch_command(tree_switch_command &)
void visit_no_op_command(tree_no_op_command &)
void visit_unwind_protect_command(tree_unwind_protect_command &)
jit_call * create_checked_impl(jit_call *ret)
jit_block_list & get_blocks(void)
void visit_break_command(tree_break_command &)
void visit_do_until_command(tree_do_until_command &)
void visit_switch_case(tree_switch_case &)
jit_instruction * resolve(tree_index_expression &exp, jit_value *extra_arg=nullptr, bool lhs=false)
void visit_octave_user_script(octave_user_script &)
jit_value * do_assign(tree_expression *exp, jit_value *rhs, bool artificial=false)
jit_block * m_entry_block
jit_block * m_final_block
void visit_matrix(tree_matrix &)
jit_variable * create_variable(const std::string &vname, jit_type *type, bool isarg=true)
void visit_argument_list(tree_argument_list &)
void visit_if_command_list(tree_if_command_list &)
void visit_binary_expression(tree_binary_expression &)
jit_value * visit(tree *tee)
const variable_map & get_variable_map(void) const
void visit_return_command(tree_return_command &)
void visit_decl_command(tree_decl_command &)
void visit_fcn_handle(tree_fcn_handle &)
void visit_if_clause(tree_if_clause &)
jit_variable * get_variable(const std::string &vname)
void visit_identifier(tree_identifier &)
void visit_statement(tree_statement &)
void visit_constant(tree_constant &)
jit_convert(tree &tee, jit_type *for_bounds=nullptr)
void finish_breaks(jit_block *dest, const block_list &lst)
std::string next_shortcircut_result(bool inc=true)
void visit_anon_fcn_handle(tree_anon_fcn_handle &)
std::pair< jit_type *, std::string > type_bound
std::vector< jit_magic_end::context > m_end_context
void visit_decl_init_list(tree_decl_init_list &)
size_t m_for_bounds_count
std::string next_iterator(bool inc=true)
void visit_switch_case_list(tree_switch_case_list &)
void visit_decl_elt(tree_decl_elt &)
void visit_continue_command(tree_continue_command &)
void visit_index_expression(tree_index_expression &)
void visit_cell(tree_cell &)
type_bound_vector m_bounds
std::list< jit_block * > block_list
void visit_while_command(tree_while_command &)
void initialize(const symbol_scope &s)
void visit_function_def(tree_function_def &)
jit_call * create_checked(const Args &... args)
void visit_colon_expression(tree_colon_expression &)
void visit_try_catch_command(tree_try_catch_command &)
void visit_postfix_expression(tree_postfix_expression &)
const type_bound_vector & get_bounds(void) const
void visit_simple_for_command(tree_simple_for_command &)
jit_variable * find_variable(const std::string &vname) const
variable check_variable(void) const
const value_list & constants(void) const
T * create(const Args &... args)
jit_function_info(octave_user_function &fcn, const octave_value_list &ov_args)
bool match(const octave_value_list &ov_args) const
jited_function m_function
std::string m_llvm_function_name
bool execute(const octave_value_list &ov_args, octave_value_list &retval) const
octave_base_value *(* jited_function)(octave_base_value **)
std::vector< jit_type * > m_argument_types
llvm::Value * call(llvm::IRBuilderD &builder, const arg_vec &in_args=arg_vec()) const
jit_type * result(void) const
llvm::BasicBlock * new_block(const std::string &aname="body", llvm::BasicBlock *insert_before=nullptr)
llvm::Value * argument(llvm::IRBuilderD &builder, size_t idx) const
llvm::Function * to_llvm(void) const
void do_return(llvm::IRBuilderD &builder, llvm::Value *rval=nullptr, bool verify=true)
std::list< jit_instruction * > m_worklist
void append_users(jit_value *v)
jit_block_list & get_blocks(void) const
void do_construct_ssa(jit_block &block, size_t avisit_count)
void push_worklist(jit_instruction *instr)
void release_dead_phi(jit_block &ablock)
jit_block_list & m_blocks
jit_infer(jit_factory &afactory, jit_block_list &ablocks, const variable_map &avmap)
void release_temp(jit_block &ablock, std::set< jit_value * > &temp)
void place_releases(void)
jit_convert::variable_map variable_map
jit_block & entry_block(void)
void append_users_term(jit_terminator *term)
const variable_map & m_vmap
jit_block & final_block(void)
octave_value find(const vmap &extra_vars, const std::string &vname) const
void compile(tree &tee, jit_type *for_bounds=0)
void(* jited_function)(octave_base_value **)
type_bound_vector m_bounds
bool execute(const vmap &extra_vars=vmap()) const
std::vector< std::pair< std::string, bool > > m_arguments
jited_function m_function
std::map< std::string, const octave_value * > vmap
bool match(const vmap &extra_vars=vmap()) const
std::string m_llvm_function_name
llvm::Value * argument_llvm(size_t i) const
const std::vector< jit_use > & arguments(void) const
virtual void push_variable(void)
void stash_argument(size_t i, jit_value *arg)
size_t argument_count(void) const
jit_block * parent(void) const
jit_value * argument(size_t i) const
static void reset_ids(void)
virtual void construct_ssa(void)
NODE_T * first_use(void) const
size_t use_count(void) const
NODE_T * next(void) const
jit_const_index * m_index
jit_const_index * m_count
const jit_function & overload() const
context resolve_context(void) const
void operator=(const jit_memory_manager &)=delete
virtual ~jit_memory_manager()
virtual void * getPointerToNamedFunction(const std::string &name, bool abort_on_failure)
virtual uint64_t getSymbolAddress(const std::string &name)
jit_memory_manager(const jit_memory_manager &)=delete
llvm::Function * create_llvm_function(llvm::FunctionType *ftype, const llvm::Twine &name) const
llvm::ExecutionEngine * m_engine
void do_add_global_mapping(const llvm::GlobalValue *gv, void *p) const
jit_module(const std::string &module_name=tree_jit::generate_unique_module_name())
void optimize(llvm::Function *fn) const
uint64_t getFunctionAddress(const std::string &name) const
void finalizeObject(void)
llvm::GlobalVariable * create_global_variable(llvm::Type *type, bool is_constant, const llvm::Twine &name) const
llvm::Function * get_intrinsic_declaration(size_t id, std::vector< llvm::Type * > types) const
llvm::BasicBlock * incoming_llvm(size_t i) const
void add_incoming(jit_block *from, jit_value *value)
llvm::PHINode * to_llvm(void) const
jit_block * incoming(size_t i) const
jit_value * result(void) const
jit_type * result_type(void) const
const jit_function & overload(void) const
const std::string & name(void) const
jit_value * result(void) const
llvm::BasicBlock * successor_llvm(size_t idx=0) const
bool alive(const jit_block *asuccessor) const
size_t successor_count(void) const
jit_block * successor(size_t idx=0) const
llvm::Type * to_llvm(void) const
static const jit_operation & paren_subsasgn(void)
static llvm::Value * insert_interrupt_check(llvm::IRBuilderD &bld)
static llvm::Type * get_scalar_llvm(void)
static llvm::Value * insert_error_check(llvm::IRBuilderD &bld)
static llvm::Value * create_complex(llvm::Value *real, llvm::Value *imag)
static jit_type * get_scalar(void)
static const jit_function & get_release(jit_type *type)
static const jit_operation & destroy(void)
static llvm::Type * get_index_llvm(void)
static const jit_operation & cast(jit_type *result)
static jit_type * get_any_ptr(void)
static jit_type * get_any(void)
static const jit_operation & logically_true(void)
static jit_type * get_complex(void)
static const jit_operation & for_check(void)
static jit_type * get_range(void)
static const jit_operation & unary_op(int op)
static const jit_operation & for_index(void)
static jit_type * type_of(const octave_value &ov)
static const jit_operation & release(void)
static const jit_operation & grab(void)
static const jit_operation & for_init(void)
static const jit_operation & paren_subsref(void)
static const jit_operation & binary_op(int op)
static const jit_operation & make_range(void)
static const jit_operation & create_undef(void)
static const jit_operation & print_value(void)
jit_instruction * user(void) const
void stash_llvm(llvm::Value *compiled)
virtual bool needs_release(void) const
virtual void replace_with(jit_value *m_value)
bool in_worklist(void) const
jit_type * type(void) const
jit_block * first_use_block(void)
void stash_in_worklist(bool ain_worklist)
llvm::Value * to_llvm(void) const
llvm::Type * type_llvm(void) const
const std::string & name(void) const
jit_value * top(void) const
symbol_record find_symbol(const std::string &name)
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope())
tree_expression * lhs(void)
octave_value::binary_op op_type(void) const
tree_expression * rhs(void)
tree_expression * increment(void)
tree_expression * limit(void)
tree_expression * base(void)
std::string name(void) const
virtual bool is_identifier(void) const
virtual std::string name(void) const
virtual bool is_assignment_expression(void) const
bool print_result(void) const
std::string name(void) const
tree_expression * condition(void)
bool is_else_clause(void)
tree_statement_list * commands(void)
std::string type_tags(void)
std::list< tree_argument_list * > arg_lists(void)
tree_expression * expression(void)
static tree_jit & instance(void)
static int next_module_number
void * do_getPointerToNamedFunction(const std::string &Name) const
uint64_t do_getSymbolAddress(const std::string &name) const
void do_register_jit_module(jit_module *jm)
static llvm::LLVMContext llvm_context
void do_unregister_jit_module(jit_module *jm)
static void * getPointerToNamedFunction(const std::string &name)
size_t trip_count(const octave_value &bounds) const
std::list< jit_module * > jm_list
static uint64_t getSymbolAddress(const std::string &name)
static jit::ModuleOwner open_new_module(const std::string &module_name=generate_unique_module_name())
static int next_function_number
static void unregister_jit_module(jit_module *jm)
static void register_jit_module(jit_module *jm)
static int next_forloop_number
llvm::TargetMachine * target_machine
static jit::EngineOwner create_new_engine(jit::ModuleOwner module_owner)
jit::ModuleOwner do_open_new_module(const std::string &module_name) const
bool do_execute(tree_simple_for_command &cmd, const octave_value &bounds)
bool takes_varargs(void) const
void visit_octave_user_function_trailer(octave_user_function &)
void visit_statement_list(tree_statement_list &)
void visit_octave_user_function_header(octave_user_function &)
tree_expression * right_hand_side(void)
octave_value::assign_op op_type(void) const
tree_expression * left_hand_side(void)
tree_expression * control_expr(void)
jit_info * get_info(void) const
void stash_info(jit_info *jinfo)
tree_expression * left_hand_side(void)
tree_statement_list * body(void)
void accept(tree_walker &tw)
tree_expression * expression(void)
tree_command * command(void)
tree_statement_list * commands(void)
tree_expression * case_label(void)
bool is_default_case(void)
tree_switch_case_list * case_list(void)
tree_expression * switch_value(void)
tree_expression * operand(void)
octave_value::unary_op op_type(void) const
tree_statement_list * body(void)
jit_info * get_info(void) const
void stash_info(jit_info *jinfo)
tree_expression * condition(void)
std::string str_print_code(void)
virtual void accept(tree_walker &tw)=0
std::string name(void) const
octave::tree_statement_list * body(void)
octave::symbol_scope scope(void)
octave::jit_function_info * get_info(void)
octave::tree_expression * special_expr(void)
bool is_special_expr(void) const
octave::tree_parameter_list * return_list(void)
octave::tree_parameter_list * parameter_list(void)
void stash_info(octave::jit_function_info *info)
octave_idx_type length(void) const
Complex complex_value(bool frc_str_conv=false) const
Range range_value(void) const
octave_base_value * internal_rep(void) const
bool is_range(void) const
static binary_op assign_op_to_binary_op(assign_op)
bool is_undefined(void) const
double double_value(bool frc_str_conv=false) const
ColumnVector real(const ComplexColumnVector &a)
ColumnVector imag(const ComplexColumnVector &a)
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error(const char *fmt,...)
#define panic_impossible()
void warn_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
std::string release(void)
std::unique_ptr< llvm::ExecutionEngine > EngineOwner
llvm::FunctionPassManager FunctionPassManager
std::unique_ptr< llvm::Module > ModuleOwner
llvm::PassManager PassManager
std::string tail(const std::string &path)
jit_const< double, jit_typeinfo::get_scalar > jit_const_scalar
jit_const< octave_idx_type, jit_typeinfo::get_index > jit_const_index
static llvm::LLVMContext & context
bp_table & __get_bp_table__(const std::string &who)
jit_const< Complex, jit_typeinfo::get_complex > jit_const_complex
symbol_scope __get_current_scope__(const std::string &who)
symbol_table & __get_symbol_table__(const std::string &who)
static llvm::IRBuilder builder(tree_jit::llvm_context)
symbol_scope __require_current_scope__(const std::string &who)
jit_const< jit_range, jit_typeinfo::get_range, const jit_range & > jit_const_range
std::complex< double > Complex
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value::octave_value(const Array< char > &chm, char type) return retval
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
#define SET_INTERNAL_VARIABLE_WITH_LIMITS(NM, MINVAL, MAXVAL)
#define SET_INTERNAL_VARIABLE(NM)