27 #define __STDC_LIMIT_MACROS
28 #define __STDC_CONSTANT_MACROS
30 #if defined (HAVE_CONFIG_H)
34 #if defined (HAVE_LLVM)
36 #if defined (HAVE_LLVM_IR_VERIFIER_H)
37 # include <llvm/IR/Verifier.h>
39 # include <llvm/Analysis/Verifier.h>
42 #include <llvm/ExecutionEngine/ExecutionEngine.h>
44 #if defined (HAVE_LLVM_IR_FUNCTION_H)
45 # include <llvm/IR/GlobalVariable.h>
46 # include <llvm/IR/LLVMContext.h>
47 # include <llvm/IR/Function.h>
48 # include <llvm/IR/Instructions.h>
49 # include <llvm/IR/Intrinsics.h>
51 # include <llvm/GlobalVariable.h>
52 # include <llvm/LLVMContext.h>
53 # include <llvm/Function.h>
54 # include <llvm/Instructions.h>
55 # include <llvm/Intrinsics.h>
58 #if defined (HAVE_LLVM_SUPPORT_IRBUILDER_H)
59 # include <llvm/Support/IRBuilder.h>
60 # elif defined(HAVE_LLVM_IR_IRBUILDER_H)
61 # include <llvm/IR/IRBuilder.h>
63 # include <llvm/IRBuilder.h>
66 #include <llvm/Support/raw_os_ostream.h>
86 return os << atype->
name ();
244 if (array->
numel () < index)
248 data[index - 1] = value;
273 return ret.
xelem (0);
287 temp.
xelem(0) = value;
288 mat->
m_array->assign (idx, temp);
314 std::swap (
final, start);
317 if (start >= 0 && final < mat->m_slice_len)
323 std::fill (data + start, data + start + nelem, value);
336 avalue.
xelem (0) = value;
337 array->
assign (idx, avalue);
352 else if (ndim > count)
354 if (idx == count - 1)
381 if (lhs.imag () == 0 && rhs.imag() == 0)
382 return Complex (lhs.real () * rhs.real (), 0);
406 if (lhs < 0.0 && !
xisint (rhs))
414 if (lhs.imag () == 0 && rhs.imag () == 0)
422 if (lhs.imag () == 0)
430 if (rhs.imag () == 0)
441 OCTAVE_NORETURN
static
445 error (
"incorrect type information given to the JIT compiler");
454 for (
size_t i = 0; i < nargin; ++i)
484 return r.all_elements_are_ints ();
509 llvm::Type *allvm_type,
bool askip_paren,
int aid)
510 : m_name (aname), m_parent (aparent), m_llvm_type (allvm_type), m_id (aid),
511 m_depth (aparent ? aparent->m_depth + 1 : 0), m_skip_paren (askip_paren)
562 : m_module (nullptr), m_llvm_function (nullptr), m_result (nullptr),
563 m_call_conv (jit_convention::
length), m_can_error (false)
568 const llvm::Twine& aname,
jit_type *aresult,
569 const std::vector<jit_type *>& aargs)
570 : m_module (amodule), m_result (aresult), m_args (aargs),
571 m_call_conv (acall_conv), m_can_error (false)
573 llvm::SmallVector<llvm::Type *, 15> llvm_args;
575 llvm::Type *rtype = llvm::Type::getVoidTy (
context);
581 llvm_args.push_back (rtype->getPointerTo ());
582 rtype = llvm::Type::getVoidTy (
context);
586 for (
auto iter =
m_args.cbegin (); iter !=
m_args.cend (); ++iter)
592 argty = argty->getPointerTo ();
594 llvm_args.push_back (argty);
597 llvm::FunctionType *ft = llvm::FunctionType::get (rtype, llvm_args,
false);
602 #if defined (FUNCTION_ADDATTRIBUTE_ARG_IS_ATTRIBUTES)
603 llvm::AttrBuilder attr_builder;
604 attr_builder.addAttribute (llvm::Attributes::StructRet);
605 llvm::Attributes attrs = llvm::Attributes::get(
context, attr_builder);
613 #if defined (FUNCTION_ADDFNATTR_ARG_IS_ATTRIBUTES)
621 const std::vector<jit_type *>& aargs)
622 : m_module (fn.m_module), m_llvm_function (fn.m_llvm_function),
623 m_result (aresult), m_args (aargs), m_call_conv (fn.m_call_conv),
624 m_can_error (fn.m_can_error)
628 : m_module (fn.m_module), m_llvm_function (fn.m_llvm_function),
629 m_result (fn.m_result), m_args (fn.m_args), m_call_conv (fn.m_call_conv),
630 m_can_error (fn.m_can_error)
651 llvm::BasicBlock *insert_before)
659 const std::vector<jit_value *>& in_args)
const
664 assert (in_args.size () ==
m_args.size ());
665 std::vector<llvm::Value *> llvm_args (
m_args.size ());
666 for (
size_t i = 0; i < in_args.size (); ++i)
667 llvm_args[i] = in_args[i]->
to_llvm ();
674 const std::vector<llvm::Value *>& in_args)
const
679 assert (in_args.size () ==
m_args.size ());
680 llvm::SmallVector<llvm::Value *, 10> llvm_args;
681 llvm_args.reserve (in_args.size () +
sret ());
683 llvm::BasicBlock *insert_block =
builder.GetInsertBlock ();
684 llvm::Function *parent = insert_block->getParent ();
688 llvm::BasicBlock& prelude = parent->getEntryBlock ();
691 llvm::AllocaInst *sret_mem =
nullptr;
695 llvm_args.push_back (sret_mem);
698 for (
size_t i = 0; i < in_args.size (); ++i)
700 llvm::Value *arg = in_args[i];
708 llvm::Value *alloca = pre_builder.CreateAlloca (ty);
709 builder.CreateStore (arg, alloca);
713 llvm_args.push_back (arg);
717 llvm::Value *ret = callinst;
721 #if defined (CALLINST_ADDATTRIBUTE_ARG_IS_ATTRIBUTES)
722 llvm::AttrBuilder attr_builder;
723 attr_builder.addAttribute(llvm::Attributes::StructRet);
724 llvm::Attributes attrs = llvm::Attributes::get(
context, attr_builder);
725 callinst->addAttribute (1, attrs);
727 callinst->addAttribute (1, llvm::Attribute::StructRet);
729 ret =
builder.CreateLoad (sret_mem);
745 assert (idx <
m_args.size ());
754 for (
size_t i = 0; i < idx; ++i, ++iter);
757 return builder.CreateLoad (&*iter);
792 llvm::Function *lfn = fn.
to_llvm ();
794 llvm::raw_os_ostream llvm_out (os);
795 lfn->print (llvm_out);
812 const std::vector<jit_type*>& args)
815 size_t nargs = args.size ();
823 bool must_resize =
false;
825 if (dv.length () != idx.
numel ())
827 dv.resize (idx.
numel ());
848 size_t nargs = types.size ();
850 static jit_function null_overload;
851 for (
size_t i = 0; i < nargs; ++i)
853 return null_overload;
865 const jit_function& ret = over(idx);
880 i < static_cast<octave_idx_type> (types.size ());
882 idx(i) = types[i]->type_id ();
884 if (types.size () == 0)
886 if (types.size () == 1)
903 return *
find->second;
905 return null_overload;
910 return ret ? *ret : null_overload;
926 if (l.size () <
r.size ())
928 else if (l.size () >
r.size ())
931 for (
size_t i = 0; i < l.size (); ++i)
933 if (l[i]->type_id () <
r[i]->type_id ())
935 else if (l[i]->type_id () >
r[i]->type_id ())
950 for (
size_t i = 1; i < types.size (); ++i)
954 return generate_matrix (types);
964 size_t end_idx)
const
966 size_t n = end_idx - start_idx;
968 llvm::ArrayType *array_t = llvm::ArrayType::get (scalar_t,
n);
969 llvm::Value *array = llvm::UndefValue::get (array_t);
970 for (
size_t i = start_idx; i < end_idx; ++i)
973 array =
builder.CreateInsertValue (array, idx, i - start_idx);
976 llvm::Value *array_mem =
builder.CreateAlloca (array_t);
977 builder.CreateStore (array, array_mem);
978 return builder.CreateBitCast (array_mem, scalar_t->getPointerTo ());
998 std::stringstream ss;
999 ss <<
"jit_paren_subsref_matrix_scalar" << (types.size () - 1);
1005 fn->mark_can_error ();
1006 llvm::BasicBlock *body = fn->new_block ();
1012 llvm::Value *mat = fn->argument (
builder, 0);
1021 std::vector<jit_type *> types (3);
1028 "octave_jit_paren_scalar",
1051 std::stringstream ss;
1052 ss <<
"jit_paren_subsasgn_matrix_scalar" << (types.size () - 2);
1058 fn->mark_can_error ();
1059 llvm::BasicBlock *body = fn->new_block ();
1066 llvm::Value *mat = fn->argument (
builder, 0);
1067 llvm::Value *value = fn->argument (
builder, types.size () - 1);
1077 std::vector<jit_type *> types (4);
1085 "octave_jit_paren_scalar",
1122 #define JIT_FN(fn) &fn, #fn
1125 : paren_subsref_fn (*this),
1126 paren_subsasgn_fn (*this),
1129 m_release_fn (
"release"),
1130 m_destroy_fn (
"destroy"),
1131 m_print_fn (
"print"),
1132 m_for_init_fn (
"for_init"),
1133 m_for_check_fn (
"for_check"),
1134 m_for_index_fn (
"for_index"),
1135 m_logically_true_fn (
"logically_true"),
1136 m_make_range_fn (
"make_range"),
1139 m_create_undef_fn (
"create_undef"),
1140 m_base_jit_module (new
jit_module (
"octaveJITBaseModule")),
1143 m_builder (*m_builder_ptr)
1154 m_any_t = llvm::StructType::create (
context,
"octave_base_value");
1177 llvm::Type::getIntNTy (
context, 8));
1179 llvm::Type::getIntNTy (
context, 16));
1181 llvm::Type::getIntNTy (
context, 32));
1183 llvm::Type::getIntNTy (
context, 64));
1197 std::vector<llvm::Type *> range_contents (4,
m_scalar_t);
1206 llvm::Type *refcount_t = llvm::Type::getIntNTy (
context,
sizeof(
int) * 8);
1207 llvm::Type *matrix_contents[5];
1208 matrix_contents[0] = refcount_t->getPointerTo ();
1209 matrix_contents[1] =
m_scalar_t->getPointerTo ();
1211 matrix_contents[3] =
m_index_t->getPointerTo ();
1213 m_matrix_t->setBody (llvm::makeArrayRef (matrix_contents, 5));
1224 llvm::StructType *cmplx_inner = llvm::StructType::create (cmplx_inner_cont);
1225 llvm::Type *contents[] = {cmplx_inner};
1243 if (
sizeof (
void *) == 4)
1257 sizeof(sig_atomic_t) * 8);
1275 llvm::Type *llvm_bo_type = binary_op_type->
to_llvm ();
1277 m_any, binary_op_type,
1297 const llvm::Twine& fn_name
1298 =
"octave_jit_binary_any_any_" + llvm::Twine (op);
1302 llvm::BasicBlock *block = fn.
new_block ();
1305 std::numeric_limits<octave_value::binary_op>::is_signed);
1306 llvm::Value *op_as_llvm = llvm::ConstantInt::get (llvm_bo_type, op_int);
1360 llvm::BasicBlock *body = fn.
new_block ();
1363 llvm::BasicBlock *warn_block = fn.
new_block (
"warn");
1364 llvm::BasicBlock *normal_block = fn.
new_block (
"normal");
1366 llvm::Value *zero = llvm::ConstantFP::get (
m_scalar_t, 0);
1367 llvm::Value *check =
m_builder.CreateFCmpUEQ (zero,
1369 m_builder.CreateCondBr (check, warn_block, normal_block);
1374 m_builder.SetInsertPoint (normal_block);
1401 llvm::Value *one = llvm::ConstantFP::get (
m_scalar_t, 1);
1412 llvm::Value *one = llvm::ConstantFP::get (
m_scalar_t, 1);
1423 llvm::Value *mone = llvm::ConstantFP::get (
m_scalar_t, -1);
1488 llvm::BasicBlock *complex_mul = fn.
new_block (
"complex_mul");
1489 llvm::BasicBlock *scalar_mul = fn.
new_block (
"scalar_mul");
1491 llvm::Value *fzero = llvm::ConstantFP::get (
m_scalar_t, 0);
1496 m_builder.CreateCondBr (cmp, scalar_mul, complex_mul);
1500 temp =
m_builder.CreateFMul (lhs, temp);
1580 llvm::Value *zero = llvm::ConstantInt::get (
m_index_t, 0);
1594 llvm::Value *ret =
m_builder.CreateICmpULT (idx, nelem);
1608 llvm::Value *base =
m_builder.CreateExtractValue (rng, 0);
1609 llvm::Value *inc =
m_builder.CreateExtractValue (rng, 2);
1611 llvm::Value *ret =
m_builder.CreateFMul (didx, inc);
1628 llvm::BasicBlock *error_block = fn.
new_block (
"error");
1629 llvm::BasicBlock *normal_block = fn.
new_block (
"normal");
1633 m_builder.CreateCondBr (check, error_block, normal_block);
1638 m_builder.SetInsertPoint (normal_block);
1640 llvm::Value *zero = llvm::ConstantFP::get (
m_scalar_t, 0);
1663 llvm::Value *nelem = compute_nelem.
call (
m_builder, base, limit, inc);
1665 llvm::Value *dzero = llvm::ConstantFP::get (
m_scalar_t, 0);
1666 llvm::Value *izero = llvm::ConstantInt::get (
m_index_t, 0);
1667 llvm::Value *rng = llvm::ConstantStruct::get (
m_range_t, dzero, dzero,
1668 dzero, izero,
nullptr);
1669 rng =
m_builder.CreateInsertValue (rng, base, 0);
1670 rng =
m_builder.CreateInsertValue (rng, limit, 1);
1671 rng =
m_builder.CreateInsertValue (rng, inc, 2);
1672 rng =
m_builder.CreateInsertValue (rng, nelem, 3);
1679 llvm::Type *int_t = jit_int->
to_llvm ();
1683 nullptr, jit_int, jit_int,
1692 llvm::Value *one_idx = llvm::ConstantInt::get (
m_index_t, 1);
1693 llvm::Value *one_int = llvm::ConstantInt::get (int_t, 1);
1695 llvm::Value *undef = llvm::UndefValue::get (
m_scalar_t);
1702 llvm::Value *cond0 =
m_builder.CreateFCmpUNE (idx, check_idx);
1703 llvm::Value *cond1 =
m_builder.CreateICmpSLT (int_idx, one_idx);
1704 llvm::Value *cond =
m_builder.CreateOr (cond0, cond1);
1706 llvm::BasicBlock *done = fn.
new_block (
"done");
1707 llvm::BasicBlock *conv_error = fn.
new_block (
"conv_error", done);
1708 llvm::BasicBlock *normal = fn.
new_block (
"normal", done);
1709 m_builder.CreateCondBr (cond, conv_error, normal);
1717 =
m_builder.CreateExtractValue (mat, llvm::ArrayRef<unsigned> (2));
1720 llvm::BasicBlock *bounds_error = fn.
new_block (
"bounds_error", done);
1721 llvm::BasicBlock *success = fn.
new_block (
"success", done);
1722 m_builder.CreateCondBr (cond, bounds_error, success);
1724 m_builder.SetInsertPoint (bounds_error);
1729 llvm::Value *data =
m_builder.CreateExtractValue (mat,
1730 llvm::ArrayRef<unsigned> (1));
1731 llvm::Value *gep =
m_builder.CreateInBoundsGEP (data, int_idx);
1732 llvm::Value *ret =
m_builder.CreateLoad (gep);
1737 llvm::PHINode *merge = llvm::PHINode::Create (
m_scalar_t, 3);
1739 merge->addIncoming (undef, conv_error);
1740 merge->addIncoming (undef, bounds_error);
1741 merge->addIncoming (ret, success);
1756 llvm::Value *one_idx = llvm::ConstantInt::get (
m_index_t, 1);
1757 llvm::Value *one_int = llvm::ConstantInt::get (int_t, 1);
1765 llvm::Value *cond0 =
m_builder.CreateFCmpUNE (idx, check_idx);
1766 llvm::Value *cond1 =
m_builder.CreateICmpSLT (int_idx, one_idx);
1767 llvm::Value *cond =
m_builder.CreateOr (cond0, cond1);
1769 llvm::BasicBlock *done = fn.
new_block (
"done");
1771 llvm::BasicBlock *conv_error = fn.
new_block (
"conv_error", done);
1772 llvm::BasicBlock *normal = fn.
new_block (
"normal", done);
1773 m_builder.CreateCondBr (cond, conv_error, normal);
1779 llvm::Value *
len =
m_builder.CreateExtractValue (mat, 2);
1782 llvm::Value *rcount =
m_builder.CreateExtractValue (mat, 0);
1784 cond1 =
m_builder.CreateICmpSGT (rcount, one_int);
1785 cond =
m_builder.CreateOr (cond0, cond1);
1787 llvm::BasicBlock *bounds_error = fn.
new_block (
"bounds_error", done);
1788 llvm::BasicBlock *success = fn.
new_block (
"success", done);
1789 m_builder.CreateCondBr (cond, bounds_error, success);
1792 m_builder.SetInsertPoint (bounds_error);
1793 llvm::Value *resize_result = resize_paren_subsasgn.
call (
m_builder, mat,
1799 =
m_builder.CreateExtractValue (mat, llvm::ArrayRef<unsigned> (1));
1800 llvm::Value *gep =
m_builder.CreateInBoundsGEP (data, int_idx);
1806 llvm::PHINode *merge = llvm::PHINode::Create (
m_matrix_t, 3);
1808 merge->addIncoming (mat, conv_error);
1809 merge->addIncoming (resize_result, bounds_error);
1810 merge->addIncoming (mat, success);
1826 llvm::Value *ret =
m_builder.CreateExtractValue (mat, 2);
1889 llvm::Value *zero = llvm::ConstantFP::get (
m_scalar_t, 0);
1949 std::vector<jit_type *> (2,
m_scalar));
1965 std::vector<jit_type *> args;
1993 const llvm::Twine&
name,
1995 const std::vector<jit_type *>& args)
const
2008 llvm::Type *llvm_type,
2012 assert ((
name ==
"any") || (
name ==
"any_ptr")
2013 || (
name ==
"scalar_ptr") || (parent !=
nullptr));
2028 std::map<size_t, jit_type *>::const_iterator iter =
m_ints.find (nbits);
2029 if (iter !=
m_ints.end ())
2030 return iter->second;
2039 if (ccount && ccount->
value () == 1)
2048 std::stringstream
name;
2049 name <<
"octave_jit_print_" << ty->
name ();
2061 std::stringstream fname;
2064 <<
'_' << ty->
name ();
2067 llvm::BasicBlock *block = fn.
new_block ();
2069 llvm::Instruction::BinaryOps temp
2070 =
static_cast<llvm::Instruction::BinaryOps
>(llvm_op);
2081 std::stringstream fname;
2084 <<
'_' << ty->
name ();
2087 llvm::BasicBlock *block = fn.
new_block ();
2089 llvm::CmpInst::Predicate temp
2090 =
static_cast<llvm::CmpInst::Predicate
>(llvm_op);
2100 std::stringstream fname;
2103 <<
'_' << ty->
name ();
2106 llvm::BasicBlock *block = fn.
new_block ();
2108 llvm::CmpInst::Predicate temp
2109 =
static_cast<llvm::CmpInst::Predicate
>(llvm_op);
2119 size_t id =
type->type_id ();
2125 std::stringstream
name;
2129 llvm::BasicBlock *body = fn.
new_block ();
2148 val->setVolatile (
true);
2149 return abuilder.CreateICmpSGT (val, abuilder.getInt32 (0));
2166 const std::vector<jit_type *>& args)
2169 size_t nargs = args.size ();
2170 std::vector<llvm::Type*> llvm_args (nargs);
2171 for (
size_t i = 0; i < nargs; ++i)
2172 llvm_args[i] = args[i]->to_llvm ();
2175 get_intrinsic_declaration (iid, llvm_args);
2177 std::stringstream fn_name;
2178 fn_name <<
"octave_jit_" <<
name;
2180 std::vector<jit_type *> args1 (nargs + 1);
2181 args1[0] = builtin_type;
2182 std::copy (args.begin (), args.end (), args1.begin () + 1);
2188 llvm::BasicBlock *body = fn.
new_block ();
2191 llvm::SmallVector<llvm::Value *, 5> fargs (nargs);
2192 for (
size_t i = 0; i < nargs; ++i)
2195 llvm::Value *ret =
m_builder.CreateCall (ifun, fargs);
2213 const std::vector<jit_type *>& args)
2219 std::vector<jit_type *> fn_args (args.size () + 1);
2221 std::copy (args.begin (), args.end (), fn_args.begin () + 1);
2224 llvm::BasicBlock *block = fn.
new_block ();
2226 llvm::ArrayType *array_t = llvm::ArrayType::get (
m_any_t, args.size ());
2227 llvm::Value *array = llvm::UndefValue::get (array_t);
2228 for (
size_t i = 0; i < args.size (); ++i)
2235 array =
m_builder.CreateInsertValue (array,
2239 llvm::Value *array_mem =
m_builder.CreateAlloca (array_t);
2240 m_builder.CreateStore (array, array_mem);
2244 llvm::Type *intTy = jintTy->
to_llvm ();
2245 size_t fcn_int =
reinterpret_cast<size_t> (builtin->
function ());
2246 llvm::Value *fcn = llvm::ConstantInt::get (intTy, fcn_int);
2247 llvm::Value *nargin = llvm::ConstantInt::get (intTy, args.size ());
2248 size_t result_int =
reinterpret_cast<size_t> (result);
2249 llvm::Value *res_llvm = llvm::ConstantInt::get (intTy, result_int);
2267 llvm::BasicBlock *body = ret.
new_block ();
2282 llvm::Value *
real = bld.CreateExtractValue (cplx, 0);
2283 llvm::Value *
imag = bld.CreateExtractValue (cplx, 1);
2286 unsigned int re_idx[] = {0, 0};
2287 unsigned int im_idx[] = {0, 1};
2288 ret = bld.CreateInsertValue (ret,
real, re_idx);
2289 return bld.CreateInsertValue (ret,
imag, im_idx);
2295 unsigned int re_idx[] = {0, 0};
2296 unsigned int im_idx[] = {0, 1};
2299 llvm::Value *
real = bld.CreateExtractValue (result, re_idx);
2300 llvm::Value *
imag = bld.CreateExtractValue (result, im_idx);
2301 llvm::Value *ret = llvm::UndefValue::get (
m_complex_t);
2303 ret = bld.CreateInsertValue (ret,
real, 0);
2304 return bld.CreateInsertValue (ret,
imag, 1);
2310 return m_builder.CreateExtractValue (cx, 0);
2322 return m_builder.CreateExtractValue (cx, 1);
2348 return builtin && builtin->
to_jit () ? builtin->
to_jit ()
2370 if (cv.imag () != 0)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
N Dimensional Array with copy-on-write semantics.
void resize1(octave_idx_type n, const T &rfv)
Size of the specified dimension.
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
void assign(const idx_vector &i, const Array< T > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
T & xelem(octave_idx_type n)
Size of the specified dimension.
octave_idx_type numel(void) const
Number of elements in the array.
T * jit_slice_data(void) const
Size of the specified dimension.
int jit_ref_count(void)
WARNING: Only call these functions from jit.
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
const T * fortran_vec(void) const
Size of the specified dimension.
octave_idx_type numel(void) const
Vector representing the dimensions (size) of an Array.
llvm::Value * call(llvm::IRBuilderD &builder, const arg_vec &in_args=arg_vec()) const
std::string name(void) const
jit_type * argument_type(size_t idx) const
bool can_error(void) const
jit_convention::type m_call_conv
jit_type * result(void) const
std::vector< jit_type * > m_args
llvm::BasicBlock * new_block(const std::string &aname="body", llvm::BasicBlock *insert_before=nullptr)
void mark_can_error(void)
const jit_module * m_module
llvm::Value * argument(llvm::IRBuilderD &builder, size_t idx) const
llvm::Function * m_llvm_function
llvm::Function * to_llvm(void) const
void do_return(llvm::IRBuilderD &builder, llvm::Value *rval=nullptr, bool verify=true)
virtual jit_function * generate(const signature_vec &types) const
const jit_typeinfo & m_typeinfo
llvm::Value * create_arg_array(llvm::IRBuilderD &builder, const jit_function &fn, size_t start_idx, size_t end_idx) const
llvm::Function * create_llvm_function(llvm::FunctionType *ftype, const llvm::Twine &name) const
void add_global_mapping(const llvm::GlobalValue *gv, ptr_type p) const
void finalizeObject(void)
llvm::GlobalVariable * create_global_variable(llvm::Type *type, bool is_constant, const llvm::Twine &name) const
virtual ~jit_operation(void)
const jit_function & do_generate(const signature_vec &types) const
std::vector< jit_type * > signature_vec
generated_map m_generated
virtual jit_function * generate(const signature_vec &types) const
std::vector< Array< jit_function > > m_overloads
Array< octave_idx_type > to_idx(const signature_vec &types) const
void add_overload(const jit_function &func)
const jit_function & overload(const signature_vec &types) const
~jit_paren_subsasgn(void)
jit_function * generate_matrix(const signature_vec &types) const
jit_paren_subsasgn(const jit_typeinfo &ti)
void init_paren_scalar(void)
jit_function * m_paren_scalar
jit_paren_subsref(const jit_typeinfo &ti)
jit_function * m_paren_scalar
void init_paren_scalar(void)
virtual jit_function * generate_matrix(const signature_vec &types) const
llvm::Type * to_llvm(void) const
convert_fn m_pack[jit_convention::length]
bool pointer_arg(jit_convention::type cc) const
convert_fn pack(jit_convention::type cc)
llvm::Type * packed_type(jit_convention::type cc)
bool m_sret[jit_convention::length]
void set_unpack(jit_convention::type cc, convert_fn fn)
llvm::Type * to_llvm_arg(void) const
jit_type(const std::string &aname, jit_type *aparent, llvm::Type *allvm_type, bool askip_paren, int aid)
jit_type * parent(void) const
void set_pack(jit_convention::type cc, convert_fn fn)
llvm::Value *(* convert_fn)(llvm::IRBuilderD &, llvm::Value *)
void mark_pointer_arg(jit_convention::type cc)
llvm::Type * m_packed_type[jit_convention::length]
void set_packed_type(jit_convention::type cc, llvm::Type *ty)
convert_fn unpack(jit_convention::type cc)
bool m_pointer_arg[jit_convention::length]
void mark_sret(jit_convention::type cc)
const std::string & name(void) const
convert_fn m_unpack[jit_convention::length]
jit_operation m_logically_true_fn
static llvm::Type * get_scalar_llvm(void)
std::map< std::string, jit_type * > m_builtins
llvm::Type * m_sig_atomic_type
static bool s_in_construction
llvm::StructType * m_complex_ret
static llvm::Value * pack_complex(llvm::IRBuilderD &bld, llvm::Value *cplx)
void add_binary_op(jit_type *ty, int op, int llvm_op)
void add_binary_icmp(jit_type *ty, int op, int llvm_op)
static jit_type * get_scalar(void)
jit_type * do_get_intN(size_t nbits) const
llvm::IRBuilderD * m_builder_ptr
jit_operation m_for_index_fn
void add_print(jit_type *ty, void *fptr)
llvm::Value * do_insert_error_check(llvm::IRBuilderD &bld)
jit_type * m_unknown_function
void add_binary_fcmp(jit_type *ty, int op, int llvm_op)
llvm::Value * complex_new(llvm::Value *real, llvm::Value *imag)
static jit_typeinfo & instance(void)
std::vector< jit_operation > m_unary_ops
jit_type * do_type_of(const octave_value &ov) const
jit_operation m_for_init_fn
void register_intrinsic(const std::string &name, size_t id, jit_type *result, jit_type *arg0)
const jit_function & do_end(jit_value *value, jit_value *index, jit_value *count)
jit_function create_internal(const llvm::Twine &name, jit_type *ret, const signature_vec &args=signature_vec()) const
jit_operation m_for_check_fn
static jit_type * get_matrix(void)
jit_operation m_release_fn
static jit_type * get_complex(void)
static llvm::Value * unpack_complex(llvm::IRBuilderD &bld, llvm::Value *result)
llvm::Value * do_insert_interrupt_check(llvm::IRBuilderD &bld)
llvm::GlobalVariable * m_loctave_interrupt_state
llvm::StructType * m_range_t
jit_function create_external(T fn, const llvm::Twine &name, jit_type *ret, const signature_vec &args=signature_vec()) const
llvm::Value * complex_imag(llvm::Value *cx)
const jit_operation & do_cast(jit_type *to)
llvm::Value * do_pack_complex(llvm::IRBuilderD &bld, llvm::Value *cplx) const
void register_generic(const std::string &name, jit_type *result, jit_type *arg0)
jit_module * m_base_jit_module
std::vector< jit_operation > m_casts
std::vector< jit_function > m_identities
jit_function mirror_binary(const jit_function &fn)
std::map< size_t, jit_type * > m_ints
llvm::IRBuilderD & m_builder
jit_paren_subsref paren_subsref_fn
llvm::GlobalVariable * m_lerror_state
jit_operation m_create_undef_fn
void add_builtin(const std::string &name)
jit_paren_subsasgn paren_subsasgn_fn
jit_operation m_destroy_fn
llvm::Value * complex_real(llvm::Value *cx)
jit_function create_identity(jit_type *type)
llvm::StructType * m_matrix_t
std::vector< jit_type * > m_id_to_type
jit_operation m_make_range_fn
jit_type * do_register_new_type(const std::string &name, jit_type *parent, llvm::Type *llvm_type, bool skip_paren=false)
std::vector< jit_operation > m_binary_ops
octave_builtin * find_builtin(const std::string &name)
jit_type * type(void) const
octave_value builtin_find(const std::string &name, const symbol_scope &search_scope=symbol_scope())
static llvm::LLVMContext llvm_context
virtual void print_with_name(std::ostream &output_buf, const std::string &name, bool print_padding=true)
virtual NDArray array_value(bool=false) const
virtual double double_value(bool=false) const
virtual Range range_value(void) const
virtual Complex complex_value(bool=false) const
octave::jit_type * to_jit(void) const
octave_value_list(* fcn)(const octave_value_list &, int)
void stash_jit(octave::jit_type &type)
octave_value & xelem(octave_idx_type i)
octave_idx_type length(void) const
bool is_function(void) const
static std::string binary_op_as_string(binary_op)
void print_with_name(std::ostream &os, const std::string &name) const
Complex complex_value(bool frc_str_conv=false) const
octave_base_value * internal_rep(void) const
bool is_double_type(void) const
static std::string unary_op_as_string(unary_op)
bool is_matrix_type(void) const
bool is_range(void) const
bool is_real_scalar(void) const
bool is_undefined(void) const
bool iscomplex(void) const
bool is_complex_scalar(void) const
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
ColumnVector real(const ComplexColumnVector &a)
ColumnVector imag(const ComplexColumnVector &a)
void error(const char *fmt,...)
#define panic_impossible()
static int convert(int x, int ibase, int obase)
F77_RET_T const F77_DBLE * x
IRBuilder< true, ConstantFolder, IRBuilderDefaultInserter< true > > IRBuilderD
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
octave_idx_type octave_jit_compute_nelem(double base, double limit, double inc)
void octave_jit_print_any(const char *name, octave_base_value *obv)
void octave_jit_gindex_range(int nd, int dim, octave_idx_type iext, octave_idx_type ext)
std::ostream & operator<<(std::ostream &os, const jit_block_list &blocks)
void err_invalid_index(const std::string &idx, octave_idx_type nd, octave_idx_type dim, const std::string &)
void octave_jit_err_nan_to_logical_conversion(void)
jit_type * jit_type_join(jit_type *lhs, jit_type *rhs)
jit_range octave_jit_cast_range_any(octave_base_value *obv)
Complex octave_jit_pow_complex_scalar(Complex lhs, double rhs)
void octave_jit_release_any(octave_base_value *obv)
jit_matrix octave_jit_cast_matrix_any(octave_base_value *obv)
Complex octave_jit_pow_complex_complex(Complex lhs, Complex rhs)
Complex octave_jit_pow_scalar_scalar(double lhs, double rhs)
octave_base_value * octave_jit_grab_any(octave_base_value *obv)
Complex octave_jit_complex_div(Complex lhs, Complex rhs)
static int xisint(double x)
static llvm::LLVMContext & context
octave_base_value * octave_jit_cast_any_matrix(jit_matrix *m)
jit_matrix octave_jit_paren_scalar_subsasgn(jit_matrix *mat, double *indices, octave_idx_type idx_count, double value)
std::ostream & jit_print(std::ostream &os, jit_value *avalue)
void err_nan_to_logical_conversion(void)
void err_index_out_of_range(int nd, int dim, octave_idx_type idx, octave_idx_type ext, const dim_vector &dv)
void octave_jit_print_matrix(jit_matrix *m)
octave_base_value * octave_jit_create_undef(void)
octave_base_value * octave_jit_cast_any_complex(Complex c)
static OCTAVE_NORETURN void err_bad_result(void)
double octave_jit_paren_scalar(jit_matrix *mat, double *indices, octave_idx_type idx_count)
octave_base_value * octave_jit_cast_any_scalar(double value)
double octave_jit_cast_scalar_any(octave_base_value *obv)
Complex octave_jit_cast_complex_any(octave_base_value *obv)
jit_array< NDArray, double > jit_matrix
void octave_jit_print_scalar(const char *name, double value)
octave_base_value * octave_jit_binary_any_any(octave_value::binary_op op, octave_base_value *lhs, octave_base_value *rhs)
jit_matrix octave_jit_paren_subsasgn_matrix_range(jit_matrix *mat, jit_range *index, double value)
symbol_table & __get_symbol_table__(const std::string &who)
Complex octave_jit_complex_mul(Complex lhs, Complex rhs)
double octave_jit_end_matrix(jit_matrix *mat, octave_idx_type idx, octave_idx_type count)
static llvm::IRBuilder builder(tree_jit::llvm_context)
jit_matrix octave_jit_grab_matrix(jit_matrix *m)
Complex octave_jit_pow_scalar_complex(double lhs, Complex rhs)
static void make_indices(double *indices, octave_idx_type idx_count, Array< idx_vector > &result)
void octave_jit_ginvalid_index(void)
octave_base_value * octave_jit_call(octave_builtin::fcn fn, size_t nargin, octave_base_value **argin, jit_type *result_type)
jit_matrix octave_jit_paren_subsasgn_impl(jit_matrix *mat, octave_idx_type index, double value)
octave_base_value * octave_jit_cast_any_range(jit_range *rng)
void octave_jit_release_matrix(jit_matrix *m)
std::complex< double > Complex
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
T::size_type numel(const T &str)
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
static bool scalar(const dim_vector &dims)
octave_value::octave_value(const Array< char > &chm, char type) return retval
OCTINTERP_API octave_value do_binary_op(octave::type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
sig_atomic_t octave_interrupt_state
octave_idx_type * m_dimensions
octave_idx_type m_slice_len
bool operator()(const signature_vec *lhs, const signature_vec *rhs) const
bool all_elements_are_ints(void) const