26 #define __STDC_LIMIT_MACROS 27 #define __STDC_CONSTANT_MACROS 29 #if defined (HAVE_CONFIG_H) 33 #if defined (HAVE_LLVM) 35 #if defined (HAVE_LLVM_IR_VERIFIER_H) 36 # include <llvm/IR/Verifier.h> 38 # include <llvm/Analysis/Verifier.h> 41 #include <llvm/ExecutionEngine/ExecutionEngine.h> 43 #if defined (HAVE_LLVM_IR_FUNCTION_H) 44 # include <llvm/IR/GlobalVariable.h> 45 # include <llvm/IR/LLVMContext.h> 46 # include <llvm/IR/Function.h> 47 # include <llvm/IR/Instructions.h> 48 # include <llvm/IR/Intrinsics.h> 50 # include <llvm/GlobalVariable.h> 51 # include <llvm/LLVMContext.h> 52 # include <llvm/Function.h> 53 # include <llvm/Instructions.h> 54 # include <llvm/Intrinsics.h> 57 #if defined (HAVE_LLVM_SUPPORT_IRBUILDER_H) 58 # include <llvm/Support/IRBuilder.h> 59 # elif defined(HAVE_LLVM_IR_IRBUILDER_H) 60 # include <llvm/IR/IRBuilder.h> 62 # include <llvm/IRBuilder.h> 65 #include <llvm/Support/raw_os_ostream.h> 79 static llvm::LLVMContext&
context = llvm::getGlobalContext ();
85 return os << atype->
name ();
243 if (
array->numel () < index)
244 array->resize1 (index);
246 double *data =
array->fortran_vec ();
247 data[index - 1] =
value;
272 return ret.
xelem (0);
287 mat->
m_array->assign (idx, temp);
301 if (*
array->jit_ref_count () == 1
316 if (
start >= 0 && final < mat->m_slice_len)
320 double *data =
array->jit_slice_data ();
336 array->assign (idx, avalue);
351 else if (ndim > count)
353 if (idx == count - 1)
380 if (lhs.imag () == 0 && rhs.imag() == 0)
381 return Complex (lhs.real () * rhs.real (), 0);
409 if (lhs < 0.0 && !
xisint (rhs))
417 if (lhs.imag () == 0 && rhs.imag () == 0)
425 if (lhs.imag () == 0)
433 if (rhs.imag () == 0)
441 std::cout << *m << std::endl;
444 OCTAVE_NORETURN
static 448 error (
"incorrect type information given to the JIT compiler");
512 llvm::Type *allvm_type,
bool askip_paren,
int aid)
513 : m_name (aname), m_parent (aparent), m_llvm_type (allvm_type), m_id (aid),
514 m_depth (aparent ? aparent->m_depth + 1 : 0), m_skip_paren (askip_paren)
565 : m_module (nullptr), m_llvm_function (nullptr), m_result (nullptr),
566 m_call_conv (jit_convention::
length), m_can_error (
false)
571 const llvm::Twine& aname,
jit_type *aresult,
572 const std::vector<jit_type *>& aargs)
573 : m_module (amodule), m_result (aresult), m_args (aargs),
574 m_call_conv (acall_conv), m_can_error (
false)
576 llvm::SmallVector<llvm::Type *, 15> llvm_args;
578 llvm::Type *rtype = llvm::Type::getVoidTy (
context);
584 llvm_args.push_back (rtype->getPointerTo ());
585 rtype = llvm::Type::getVoidTy (
context);
589 for (std::vector<jit_type *>::const_iterator iter =
m_args.begin ();
590 iter !=
m_args.end (); ++iter)
596 argty = argty->getPointerTo ();
598 llvm_args.push_back (argty);
601 llvm::FunctionType *ft = llvm::FunctionType::get (rtype, llvm_args,
false);
606 #if defined (FUNCTION_ADDATTRIBUTE_ARG_IS_ATTRIBUTES) 607 llvm::AttrBuilder attr_builder;
608 attr_builder.addAttribute (llvm::Attributes::StructRet);
609 llvm::Attributes attrs = llvm::Attributes::get(
context, attr_builder);
617 #if defined (FUNCTION_ADDFNATTR_ARG_IS_ATTRIBUTES) 625 const std::vector<jit_type *>& aargs)
626 : m_module (fn.m_module), m_llvm_function (fn.m_llvm_function),
627 m_result (aresult), m_args (aargs), m_call_conv (fn.m_call_conv),
628 m_can_error (fn.m_can_error)
632 : m_module (fn.m_module), m_llvm_function (fn.m_llvm_function),
633 m_result (fn.m_result), m_args (fn.m_args), m_call_conv (fn.m_call_conv),
634 m_can_error (fn.m_can_error)
655 llvm::BasicBlock *insert_before)
663 const std::vector<jit_value *>& in_args)
const 668 assert (in_args.size () ==
m_args.size ());
669 std::vector<llvm::Value *> llvm_args (
m_args.size ());
670 for (
size_t i = 0;
i < in_args.size (); ++
i)
678 const std::vector<llvm::Value *>& in_args)
const 683 assert (in_args.size () ==
m_args.size ());
684 llvm::SmallVector<llvm::Value *, 10> llvm_args;
685 llvm_args.reserve (in_args.size () +
sret ());
687 llvm::BasicBlock *insert_block =
builder.GetInsertBlock ();
688 llvm::Function *parent = insert_block->getParent ();
692 llvm::BasicBlock& prelude = parent->getEntryBlock ();
695 llvm::AllocaInst *sret_mem =
nullptr;
699 llvm_args.push_back (sret_mem);
702 for (
size_t i = 0;
i < in_args.size (); ++
i)
704 llvm::Value *
arg = in_args[
i];
712 llvm::Value *alloca = pre_builder.CreateAlloca (ty);
717 llvm_args.push_back (
arg);
721 llvm::Value *ret = callinst;
725 #if defined (CALLINST_ADDATTRIBUTE_ARG_IS_ATTRIBUTES) 726 llvm::AttrBuilder attr_builder;
727 attr_builder.addAttribute(llvm::Attributes::StructRet);
728 llvm::Attributes attrs = llvm::Attributes::get(
context, attr_builder);
729 callinst->addAttribute (1, attrs);
731 callinst->addAttribute (1, llvm::Attribute::StructRet);
733 ret =
builder.CreateLoad (sret_mem);
749 assert (idx <
m_args.size ());
758 for (
size_t i = 0;
i < idx; ++
i, ++iter);
761 return builder.CreateLoad (&*iter);
776 rval = convert (
builder, rval);
796 llvm::Function *lfn = fn.
to_llvm ();
798 llvm::raw_os_ostream llvm_out (
os);
799 lfn->print (llvm_out);
807 for (generated_map::iterator iter =
m_generated.begin ();
817 const std::vector<jit_type*>& args)
820 size_t nargs = args.size ();
828 bool must_resize =
false;
853 size_t nargs = types.size ();
855 static jit_function null_overload;
856 for (
size_t i = 0;
i < nargs; ++
i)
858 return null_overload;
870 const jit_function& ret = over(idx);
885 i < static_cast<octave_idx_type> (types.size ());
887 idx(
i) = types[
i]->type_id ();
889 if (types.size () == 0)
891 if (types.size () == 1)
908 return *
find->second;
910 return null_overload;
915 return ret ? *ret : null_overload;
931 if (l.size () < r.size ())
933 else if (l.size () > r.size ())
936 for (
size_t i = 0;
i < l.size (); ++
i)
938 if (l[
i]->type_id () < r[
i]->type_id ())
940 else if (l[
i]->type_id () > r[
i]->type_id ())
955 for (
size_t i = 1;
i < types.size (); ++
i)
959 return generate_matrix (types);
969 size_t end_idx)
const 971 size_t n = end_idx - start_idx;
973 llvm::ArrayType *array_t = llvm::ArrayType::get (scalar_t, n);
974 llvm::Value *
array = llvm::UndefValue::get (array_t);
975 for (
size_t i = start_idx;
i < end_idx; ++
i)
981 llvm::Value *array_mem =
builder.CreateAlloca (array_t);
983 return builder.CreateBitCast (array_mem, scalar_t->getPointerTo ());
1003 std::stringstream ss;
1004 ss <<
"jit_paren_subsref_matrix_scalar" << (types.size () - 1);
1010 fn->mark_can_error ();
1011 llvm::BasicBlock *body = fn->new_block ();
1017 llvm::Value *mat = fn->argument (
builder, 0);
1026 std::vector<jit_type *> types (3);
1033 "octave_jit_paren_scalar",
1056 std::stringstream ss;
1057 ss <<
"jit_paren_subsasgn_matrix_scalar" << (types.size () - 2);
1063 fn->mark_can_error ();
1064 llvm::BasicBlock *body = fn->new_block ();
1071 llvm::Value *mat = fn->argument (
builder, 0);
1072 llvm::Value *
value = fn->argument (
builder, types.size () - 1);
1082 std::vector<jit_type *> types (4);
1090 "octave_jit_paren_scalar",
1127 #define JIT_FN(fn) &fn, #fn 1130 : paren_subsref_fn (*
this),
1131 paren_subsasgn_fn (*
this),
1134 m_release_fn (
"release"),
1135 m_destroy_fn (
"destroy"),
1136 m_print_fn (
"print"),
1137 m_for_init_fn (
"for_init"),
1138 m_for_check_fn (
"for_check"),
1139 m_for_index_fn (
"for_index"),
1140 m_logically_true_fn (
"logically_true"),
1141 m_make_range_fn (
"make_range"),
1144 m_create_undef_fn (
"create_undef"),
1145 m_base_jit_module (new
jit_module (
"octaveJITBaseModule")),
1148 m_builder (*m_builder_ptr)
1159 m_any_t = llvm::StructType::create (
context,
"octave_base_value");
1182 llvm::Type::getIntNTy (
context, 8));
1184 llvm::Type::getIntNTy (
context, 16));
1186 llvm::Type::getIntNTy (
context, 32));
1188 llvm::Type::getIntNTy (
context, 64));
1202 std::vector<llvm::Type *> range_contents (4,
m_scalar_t);
1211 llvm::Type *refcount_t = llvm::Type::getIntNTy (
context,
sizeof(
int) * 8);
1212 llvm::Type *matrix_contents[5];
1213 matrix_contents[0] = refcount_t->getPointerTo ();
1214 matrix_contents[1] =
m_scalar_t->getPointerTo ();
1216 matrix_contents[3] =
m_index_t->getPointerTo ();
1218 m_matrix_t->setBody (llvm::makeArrayRef (matrix_contents, 5));
1229 llvm::StructType *cmplx_inner = llvm::StructType::create (cmplx_inner_cont);
1230 llvm::Type *contents[] = {cmplx_inner};
1248 if (
sizeof (
void *) == 4)
1262 sizeof(sig_atomic_t) * 8);
1280 llvm::Type *llvm_bo_type = binary_op_type->
to_llvm ();
1282 m_any, binary_op_type,
1302 const llvm::Twine &fn_name =
1303 "octave_jit_binary_any_any_" + llvm::Twine (op);
1307 llvm::BasicBlock *block = fn.
new_block ();
1310 std::numeric_limits<octave_value::binary_op>::is_signed);
1311 llvm::Value *op_as_llvm = llvm::ConstantInt::get (llvm_bo_type, op_int);
1369 llvm::BasicBlock *body = fn.
new_block ();
1372 llvm::BasicBlock *warn_block = fn.
new_block (
"warn");
1373 llvm::BasicBlock *normal_block = fn.
new_block (
"normal");
1378 m_builder.CreateCondBr (check, warn_block, normal_block);
1384 m_builder.SetInsertPoint (normal_block);
1411 llvm::Value *one = llvm::ConstantFP::get (
m_scalar_t, 1);
1422 llvm::Value *one = llvm::ConstantFP::get (
m_scalar_t, 1);
1433 llvm::Value *mone = llvm::ConstantFP::get (
m_scalar_t, -1);
1498 llvm::BasicBlock *complex_mul = fn.
new_block (
"complex_mul");
1499 llvm::BasicBlock *scalar_mul = fn.
new_block (
"scalar_mul");
1501 llvm::Value *fzero = llvm::ConstantFP::get (
m_scalar_t, 0);
1506 m_builder.CreateCondBr (cmp, scalar_mul, complex_mul);
1510 temp =
m_builder.CreateFMul (lhs, temp);
1604 llvm::Value *ret =
m_builder.CreateICmpULT (idx, nelem);
1618 llvm::Value *base =
m_builder.CreateExtractValue (rng, 0);
1619 llvm::Value *inc =
m_builder.CreateExtractValue (rng, 2);
1621 llvm::Value *ret =
m_builder.CreateFMul (didx, inc);
1638 llvm::BasicBlock *error_block = fn.
new_block (
"error");
1639 llvm::BasicBlock *normal_block = fn.
new_block (
"normal");
1643 m_builder.CreateCondBr (check, error_block, normal_block);
1648 m_builder.SetInsertPoint (normal_block);
1673 llvm::Value *nelem = compute_nelem.
call (
m_builder, base, limit, inc);
1675 llvm::Value *dzero = llvm::ConstantFP::get (
m_scalar_t, 0);
1676 llvm::Value *izero = llvm::ConstantInt::get (
m_index_t, 0);
1677 llvm::Value *rng = llvm::ConstantStruct::get (
m_range_t, dzero, dzero,
1678 dzero, izero, NULL);
1679 rng =
m_builder.CreateInsertValue (rng, base, 0);
1680 rng =
m_builder.CreateInsertValue (rng, limit, 1);
1681 rng =
m_builder.CreateInsertValue (rng, inc, 2);
1682 rng =
m_builder.CreateInsertValue (rng, nelem, 3);
1689 llvm::Type *int_t = jit_int->
to_llvm ();
1693 nullptr, jit_int, jit_int,
1702 llvm::Value *one_idx = llvm::ConstantInt::get (
m_index_t, 1);
1703 llvm::Value *one_int = llvm::ConstantInt::get (int_t, 1);
1705 llvm::Value *undef = llvm::UndefValue::get (
m_scalar_t);
1712 llvm::Value *cond0 =
m_builder.CreateFCmpUNE (idx, check_idx);
1713 llvm::Value *cond1 =
m_builder.CreateICmpSLT (int_idx, one_idx);
1714 llvm::Value *cond =
m_builder.CreateOr (cond0, cond1);
1717 llvm::BasicBlock *conv_error = fn.
new_block (
"conv_error",
done);
1719 m_builder.CreateCondBr (cond, conv_error, normal);
1727 =
m_builder.CreateExtractValue (mat, llvm::ArrayRef<unsigned> (2));
1728 cond =
m_builder.CreateICmpSGT (int_idx, len);
1730 llvm::BasicBlock *bounds_error = fn.
new_block (
"bounds_error",
done);
1732 m_builder.CreateCondBr (cond, bounds_error, success);
1734 m_builder.SetInsertPoint (bounds_error);
1735 gindex_range.
call (
m_builder, one_int, one_int, int_idx, len);
1739 llvm::Value *data =
m_builder.CreateExtractValue (mat,
1740 llvm::ArrayRef<unsigned> (1));
1741 llvm::Value *gep =
m_builder.CreateInBoundsGEP (data, int_idx);
1742 llvm::Value *ret =
m_builder.CreateLoad (gep);
1747 llvm::PHINode *merge = llvm::PHINode::Create (
m_scalar_t, 3);
1749 merge->addIncoming (undef, conv_error);
1750 merge->addIncoming (undef, bounds_error);
1751 merge->addIncoming (ret, success);
1766 llvm::Value *one_idx = llvm::ConstantInt::get (
m_index_t, 1);
1767 llvm::Value *one_int = llvm::ConstantInt::get (int_t, 1);
1775 llvm::Value *cond0 =
m_builder.CreateFCmpUNE (idx, check_idx);
1776 llvm::Value *cond1 =
m_builder.CreateICmpSLT (int_idx, one_idx);
1777 llvm::Value *cond =
m_builder.CreateOr (cond0, cond1);
1781 llvm::BasicBlock *conv_error = fn.
new_block (
"conv_error",
done);
1783 m_builder.CreateCondBr (cond, conv_error, normal);
1789 llvm::Value *len =
m_builder.CreateExtractValue (mat, 2);
1790 cond0 =
m_builder.CreateICmpSGT (int_idx, len);
1792 llvm::Value *rcount =
m_builder.CreateExtractValue (mat, 0);
1794 cond1 =
m_builder.CreateICmpSGT (rcount, one_int);
1795 cond =
m_builder.CreateOr (cond0, cond1);
1797 llvm::BasicBlock *bounds_error = fn.
new_block (
"bounds_error",
done);
1799 m_builder.CreateCondBr (cond, bounds_error, success);
1802 m_builder.SetInsertPoint (bounds_error);
1803 llvm::Value *resize_result = resize_paren_subsasgn.
call (
m_builder, mat,
1809 =
m_builder.CreateExtractValue (mat, llvm::ArrayRef<unsigned> (1));
1810 llvm::Value *gep =
m_builder.CreateInBoundsGEP (data, int_idx);
1816 llvm::PHINode *merge = llvm::PHINode::Create (
m_matrix_t, 3);
1818 merge->addIncoming (mat, conv_error);
1819 merge->addIncoming (resize_result, bounds_error);
1820 merge->addIncoming (mat, success);
1836 llvm::Value *ret =
m_builder.CreateExtractValue (mat, 2);
1959 std::vector<jit_type *> (2,
m_scalar));
1975 std::vector<jit_type *> args;
1978 for (std::map<std::string, jit_type *>::iterator iter =
m_builtins.begin ();
2003 const llvm::Twine&
name,
2005 const std::vector<jit_type *>& args)
const 2018 llvm::Type *llvm_type,
2022 assert ((
name ==
"any") || (
name ==
"any_ptr") ||
2023 (
name ==
"scalar_ptr") || (parent !=
nullptr));
2038 std::map<size_t, jit_type *>::const_iterator iter =
m_ints.find (nbits);
2039 if (iter !=
m_ints.end ())
2040 return iter->second;
2049 if (ccount && ccount->
value () == 1)
2058 std::stringstream
name;
2059 name <<
"octave_jit_print_" << ty->
name ();
2071 std::stringstream
fname;
2074 <<
'_' << ty->
name ();
2077 llvm::BasicBlock *block = fn.
new_block ();
2079 llvm::Instruction::BinaryOps temp
2080 =
static_cast<llvm::Instruction::BinaryOps
>(llvm_op);
2091 std::stringstream
fname;
2094 <<
'_' << ty->
name ();
2097 llvm::BasicBlock *block = fn.
new_block ();
2099 llvm::CmpInst::Predicate temp
2100 =
static_cast<llvm::CmpInst::Predicate
>(llvm_op);
2110 std::stringstream
fname;
2113 <<
'_' << ty->
name ();
2116 llvm::BasicBlock *block = fn.
new_block ();
2118 llvm::CmpInst::Predicate temp
2119 =
static_cast<llvm::CmpInst::Predicate
>(llvm_op);
2129 size_t id =
type->type_id ();
2135 std::stringstream
name;
2139 llvm::BasicBlock *body = fn.
new_block ();
2158 val->setVolatile (
true);
2159 return abuilder.CreateICmpSGT (
val, abuilder.getInt32 (0));
2176 const std::vector<jit_type *>& args)
2179 size_t nargs = args.size ();
2180 std::vector<llvm::Type*> llvm_args (nargs);
2181 for (
size_t i = 0;
i < nargs; ++
i)
2182 llvm_args[
i] = args[
i]->to_llvm ();
2185 get_intrinsic_declaration (iid, llvm_args);
2187 std::stringstream fn_name;
2188 fn_name <<
"octave_jit_" <<
name;
2190 std::vector<jit_type *> args1 (nargs + 1);
2191 args1[0] = builtin_type;
2192 std::copy (args.begin (), args.end (), args1.begin () + 1);
2198 llvm::BasicBlock *body = fn.
new_block ();
2201 llvm::SmallVector<llvm::Value *, 5> fargs (nargs);
2202 for (
size_t i = 0;
i < nargs; ++
i)
2205 llvm::Value *ret =
m_builder.CreateCall (ifun, fargs);
2223 const std::vector<jit_type *>& args)
2229 std::vector<jit_type *> fn_args (args.size () + 1);
2231 std::copy (args.begin (), args.end (), fn_args.begin () + 1);
2233 fn.mark_can_error ();
2234 llvm::BasicBlock *block = fn.new_block ();
2236 llvm::ArrayType *array_t = llvm::ArrayType::get (
m_any_t, args.size ());
2237 llvm::Value *
array = llvm::UndefValue::get (array_t);
2238 for (
size_t i = 0;
i < args.size (); ++
i)
2249 llvm::Value *array_mem =
m_builder.CreateAlloca (array_t);
2254 llvm::Type *intTy = jintTy->
to_llvm ();
2255 size_t fcn_int =
reinterpret_cast<size_t> (builtin->
function ());
2256 llvm::Value *
fcn = llvm::ConstantInt::get (intTy, fcn_int);
2257 llvm::Value *
nargin = llvm::ConstantInt::get (intTy, args.size ());
2258 size_t result_int =
reinterpret_cast<size_t> (
result);
2259 llvm::Value *res_llvm = llvm::ConstantInt::get (intTy, result_int);
2277 llvm::BasicBlock *body = ret.
new_block ();
2292 llvm::Value *
real = bld.CreateExtractValue (cplx, 0);
2293 llvm::Value *
imag = bld.CreateExtractValue (cplx, 1);
2296 unsigned int re_idx[] = {0, 0};
2297 unsigned int im_idx[] = {0, 1};
2298 ret = bld.CreateInsertValue (ret,
real, re_idx);
2299 return bld.CreateInsertValue (ret,
imag, im_idx);
2305 unsigned int re_idx[] = {0, 0};
2306 unsigned int im_idx[] = {0, 1};
2309 llvm::Value *
real = bld.CreateExtractValue (
result, re_idx);
2310 llvm::Value *
imag = bld.CreateExtractValue (
result, im_idx);
2311 llvm::Value *ret = llvm::UndefValue::get (
m_complex_t);
2313 ret = bld.CreateInsertValue (ret,
real, 0);
2314 return bld.CreateInsertValue (ret,
imag, 1);
2320 return m_builder.CreateExtractValue (cx, 0);
2332 return m_builder.CreateExtractValue (cx, 1);
2358 return builtin && builtin->
to_jit () ? builtin->
to_jit ()
2380 if (cv.imag () != 0)
jit_matrix octave_jit_paren_scalar_subsasgn(jit_matrix *mat, double *indices, octave_idx_type idx_count, double value)
octave_base_value * octave_jit_call(octave_builtin::fcn fn, size_t nargin, octave_base_value **argin, jit_type *result_type)
void add_binary_op(jit_type *ty, int op, int llvm_op)
jit_operation m_release_fn
jit_function mirror_binary(const jit_function &fn)
static jit_typeinfo & instance(void)
bool all_elements_are_ints(void) const
octave::jit_type * to_jit(void) const
llvm::Type * to_llvm(void) const
bool operator()(const signature_vec *lhs, const signature_vec *rhs) const
octave_base_value * internal_rep(void) const
llvm::Function * to_llvm(void) const
llvm::BasicBlock * new_block(const std::string &aname="body", llvm::BasicBlock *insert_before=nullptr)
Complex octave_jit_pow_complex_complex(Complex lhs, Complex rhs)
void octave_jit_ginvalid_index(void)
void init_paren_scalar(void)
jit_operation m_destroy_fn
jit_function create_identity(jit_type *type)
void finalizeObject(void)
jit_function * m_paren_scalar
std::vector< jit_type * > m_args
void octave_jit_print_any(const char *name, octave_base_value *obv)
llvm::StructType * m_range_t
nd group nd example oindent but is performed more efficiently If only and it is a scalar
Complex octave_jit_complex_div(Complex lhs, Complex rhs)
void print_with_name(std::ostream &os, const std::string &name) const
llvm::Value * complex_real(llvm::Value *cx)
static std::string binary_op_as_string(binary_op)
const jit_function & do_end(jit_value *value, jit_value *index, jit_value *count)
jit_convention::type m_call_conv
identity matrix If supplied two scalar respectively For allows like xample val
Complex octave_jit_pow_scalar_scalar(double lhs, double rhs)
bool all_elements_are_ints(void) const
std::map< size_t, jit_type * > m_ints
virtual jit_function * generate_matrix(const signature_vec &types) const
void octave_jit_err_nan_to_logical_conversion(void)
void octave_jit_release_matrix(jit_matrix *m)
llvm::Function * create_llvm_function(llvm::FunctionType *ftype, const llvm::Twine &name) const
jit_array< NDArray, double > jit_matrix
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by zero($0/0$)
const jit_function & do_generate(const signature_vec &types) const
generated_map m_generated
jit_matrix octave_jit_paren_subsasgn_impl(jit_matrix *mat, octave_idx_type index, double value)
jit_type * jit_type_join(jit_type *lhs, jit_type *rhs)
static jit_type * get_matrix(void)
void resize(int n, int fill_value=0)
jit_function * m_paren_scalar
octave_base_value * octave_jit_cast_any_range(jit_range *rng)
octave_value_list(* fcn)(const octave_value_list &, int)
void err_index_out_of_range(int nd, int dim, octave_idx_type idx, octave_idx_type ext)
bool is_complex_scalar(void) const
void err_invalid_index(const std::string &idx, octave_idx_type nd, octave_idx_type dim, const std::string &)
void error(const char *fmt,...)
void stash_jit(octave::jit_type &type)
llvm::Value * do_insert_error_check(llvm::IRBuilderD &bld)
static llvm::Type * get_scalar_llvm(void)
void do_return(llvm::IRBuilderD &builder, llvm::Value *rval=nullptr, bool verify=true)
jit_paren_subsasgn(const jit_typeinfo &ti)
octave_base_value * octave_jit_grab_any(octave_base_value *obv)
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
jit_type * do_type_of(const octave_value &ov) const
octave_base_value * octave_jit_cast_any_complex(Complex c)
static llvm::LLVMContext & context
jit_type * argument_type(size_t idx) const
llvm::Type * m_packed_type[jit_convention::length]
llvm::Value * do_insert_interrupt_check(llvm::IRBuilderD &bld)
Complex complex_value(bool frc_str_conv=false) const
static llvm::IRBuilder builder(llvm::getGlobalContext())
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
llvm::Value * argument(llvm::IRBuilderD &builder, size_t idx) const
llvm::Type * m_sig_atomic_type
void mark_can_error(void)
virtual ~jit_operation(void)
void err_nan_to_logical_conversion(void)
Complex octave_jit_complex_mul(Complex lhs, Complex rhs)
std::ostream & jit_print(std::ostream &os, jit_value *avalue)
Array< octave_idx_type > to_idx(const signature_vec &types) const
void set_unpack(jit_convention::type cc, convert_fn fn)
jit_type * m_unknown_function
void octave_jit_gindex_range(int nd, int dim, octave_idx_type iext, octave_idx_type ext)
void register_generic(const std::string &name, jit_type *result, jit_type *arg0)
octave_base_value * octave_jit_binary_any_any(octave_value::binary_op op, octave_base_value *lhs, octave_base_value *rhs)
void octave_jit_release_any(octave_base_value *obv)
virtual Range range_value(void) const
octave_base_value * octave_jit_cast_any_scalar(double value)
llvm::IRBuilderD & m_builder
llvm::Value * create_arg_array(llvm::IRBuilderD &builder, const jit_function &fn, size_t start_idx, size_t end_idx) const
jit_matrix octave_jit_grab_matrix(jit_matrix *m)
const jit_operation & do_cast(jit_type *to)
virtual jit_function * generate(const signature_vec &types) const
then the function must return scalars which will be concatenated into the return array(s). If code
bool m_pointer_arg[jit_convention::length]
llvm::Type * packed_type(jit_convention::type cc)
std::map< std::string, jit_type * > m_builtins
void register_intrinsic(const std::string &name, size_t id, jit_type *result, jit_type *arg0)
jit_type(const std::string &aname, jit_type *aparent, llvm::Type *allvm_type, bool askip_paren, int aid)
octave_idx_type octave_jit_compute_nelem(double base, double limit, double inc)
jit_operation m_logically_true_fn
symbol_table & __get_symbol_table__(const std::string &who)
double octave_jit_end_matrix(jit_matrix *mat, octave_idx_type idx, octave_idx_type count)
nd deftypefn *std::string name
std::ostream & operator<<(std::ostream &os, const jit_block_list &blocks)
double octave_jit_paren_scalar(jit_matrix *mat, double *indicies, octave_idx_type idx_count)
convert_fn unpack(jit_convention::type cc)
octave_idx_type m_slice_len
jit_type * parent(void) const
void add_binary_icmp(jit_type *ty, int op, int llvm_op)
llvm::Value * complex_imag(llvm::Value *cx)
void add_overload(const jit_function &func)
jit_operation m_for_index_fn
virtual NDArray array_value(bool=false) const
llvm::StructType * m_complex_ret
Complex octave_jit_pow_complex_scalar(Complex lhs, double rhs)
jit_operation m_for_check_fn
octave_base_value * octave_jit_create_undef(void)
OCTINTERP_API octave_value do_binary_op(octave::type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)
~jit_paren_subsasgn(void)
octave_builtin * find_builtin(const std::string &name)
convert_fn pack(jit_convention::type cc)
convert_fn m_pack[jit_convention::length]
llvm::Value * do_pack_complex(llvm::IRBuilderD &bld, llvm::Value *cplx) const
jit_type * type(void) const
convert_fn m_unpack[jit_convention::length]
octave_idx_type numel(void) const
void resize(const dim_vector &dv, const T &rfv)
Resizing (with fill).
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
llvm::Value *(* convert_fn)(llvm::IRBuilderD &, llvm::Value *)
std::vector< jit_operation > m_casts
#define panic_impossible()
static llvm::Value * unpack_complex(llvm::IRBuilderD &bld, llvm::Value *result)
llvm::Value * call(llvm::IRBuilderD &builder, const arg_vec &in_args=arg_vec()) const
virtual Complex complex_value(bool=false) const
std::vector< jit_operation > m_unary_ops
void add_global_mapping(const llvm::GlobalValue *gv, ptr_type p) const
sig_atomic_t octave_interrupt_state
returns the type of the matrix and caches it for future use Called with more than one the function will not attempt to guess the type if it is still unknown This is useful for debugging purposes The possible matrix types depend on whether the matrix is full or and can be one of the following able sis tem and mark type as unknown tem as the structure of the matrix explicitly gives this(Sparse matrices only) tem code
jit_module * m_base_jit_module
Complex octave_jit_pow_scalar_complex(double lhs, Complex rhs)
void set_pack(jit_convention::type cc, convert_fn fn)
void warn_divide_by_zero(void)
void set_packed_type(jit_convention::type cc, llvm::Type *ty)
static jit_type * get_scalar(void)
bool is_function(void) const
jit_paren_subsasgn paren_subsasgn_fn
std::string name(void) const
octave_value find(const std::string &name, const octave_value_list &args=octave_value_list(), bool skip_variables=false, bool local_funcs=true)
void octave_jit_print_scalar(const char *name, double value)
llvm::GlobalVariable * create_global_variable(llvm::Type *type, bool is_constant, const llvm::Twine &name) const
std::vector< jit_type * > m_id_to_type
With real return the complex result
std::vector< jit_type * > signature_vec
jit_paren_subsref(const jit_typeinfo &ti)
llvm::Function * m_llvm_function
llvm::IRBuilderD * m_builder_ptr
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
T & xelem(octave_idx_type n)
llvm::Value * complex_new(llvm::Value *real, llvm::Value *imag)
jit_type * result(void) const
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
N Dimensional Array with copy-on-write semantics.
static OCTAVE_NORETURN void err_bad_result(void)
charNDArray max(char d, const charNDArray &m)
virtual jit_function * generate(const signature_vec &types) const
jit_operation m_make_range_fn
jit_matrix octave_jit_paren_subsasgn_matrix_range(jit_matrix *mat, jit_range *index, double value)
T::size_type numel(const T &str)
jit_paren_subsref paren_subsref_fn
bool is_undefined(void) const
jit_operation m_create_undef_fn
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
void octave_jit_print_matrix(jit_matrix *m)
bool pointer_arg(jit_convention::type cc) const
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
jit_type * do_register_new_type(const std::string &name, jit_type *parent, llvm::Type *llvm_type, bool skip_paren=false)
const jit_function & overload(const signature_vec &types) const
void init_paren_scalar(void)
Complex octave_jit_cast_complex_any(octave_base_value *obv)
void mark_sret(jit_convention::type cc)
jit_function create_internal(const llvm::Twine &name, jit_type *ret, const signature_vec &args=signature_vec()) const
octave_idx_type length(void) const
void add_builtin(const std::string &name)
bool can_error(void) const
jit_matrix octave_jit_cast_matrix_any(octave_base_value *obv)
std::vector< jit_function > m_identities
static jit_type * get_complex(void)
llvm::StructType * m_matrix_t
octave_idx_type * m_dimensions
jit_function create_external(T fn, const llvm::Twine &name, jit_type *ret, const signature_vec &args=signature_vec()) const
octave_base_value * octave_jit_cast_any_matrix(jit_matrix *m)
bool iscomplex(void) const
static bool s_in_construction
ColumnVector imag(const ComplexColumnVector &a)
double octave_jit_cast_scalar_any(octave_base_value *obv)
bool is_double_type(void) const
static void make_indices(double *indices, octave_idx_type idx_count, Array< idx_vector > &result)
llvm::GlobalVariable * m_lerror_state
std::complex< double > Complex
static llvm::Value * pack_complex(llvm::IRBuilderD &bld, llvm::Value *cplx)
bool is_range(void) const
static std::string unary_op_as_string(unary_op)
ColumnVector real(const ComplexColumnVector &a)
static int xisint(double x)
Vector representing the dimensions (size) of an Array.
jit_range octave_jit_cast_range_any(octave_base_value *obv)
jit_function * generate_matrix(const signature_vec &types) const
void add_print(jit_type *ty, void *fptr)
octave_value & xelem(octave_idx_type i)
jit_operation m_for_init_fn
bool m_sret[jit_convention::length]
std::vector< Array< jit_function > > m_overloads
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 is_real_scalar(void) const
virtual void print_with_name(std::ostream &output_buf, const std::string &name, bool print_padding=true)
IRBuilder< true, ConstantFolder, IRBuilderDefaultInserter< true > > IRBuilderD
int length(void) const
Number of dimensions.
void mark_pointer_arg(jit_convention::type cc)
bool is_matrix_type(void) const
const std::string & name(void) const
llvm::GlobalVariable * m_loctave_interrupt_state
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE * x
jit_type * do_get_intN(size_t nbits) const
const jit_typeinfo & m_typeinfo
charNDArray min(char d, const charNDArray &m)
const jit_module * m_module
virtual double double_value(bool=false) const
void add_binary_fcmp(jit_type *ty, int op, int llvm_op)
std::vector< jit_operation > m_binary_ops
llvm::Type * to_llvm_arg(void) const