26 #define __STDC_LIMIT_MACROS
27 #define __STDC_CONSTANT_MACROS
37 #include <llvm/Analysis/Verifier.h>
38 #include <llvm/ExecutionEngine/ExecutionEngine.h>
40 #ifdef HAVE_LLVM_IR_FUNCTION_H
41 #include <llvm/IR/GlobalVariable.h>
42 #include <llvm/IR/LLVMContext.h>
43 #include <llvm/IR/Function.h>
44 #include <llvm/IR/Instructions.h>
45 #include <llvm/IR/Intrinsics.h>
47 #include <llvm/GlobalVariable.h>
48 #include <llvm/LLVMContext.h>
49 #include <llvm/Function.h>
50 #include <llvm/Instructions.h>
51 #include <llvm/Intrinsics.h>
54 #ifdef HAVE_LLVM_SUPPORT_IRBUILDER_H
55 #include <llvm/Support/IRBuilder.h>
56 #elif defined(HAVE_LLVM_IR_IRBUILDER_H)
57 #include <llvm/IR/IRBuilder.h>
59 #include <llvm/IRBuilder.h>
62 #include <llvm/Support/raw_os_ostream.h>
71 static llvm::LLVMContext&
context = llvm::getGlobalContext ();
79 return os << atype->
name ();
217 catch (
const octave_execution_exception&)
230 catch (
const octave_execution_exception&)
244 catch (
const octave_execution_exception&)
255 if (array->
nelem () < index)
259 data[index - 1] = value;
285 return ret.
xelem (0);
287 catch (
const octave_execution_exception&)
306 temp.
xelem(0) = value;
307 mat->
array->assign (idx, temp);
310 catch (
const octave_execution_exception&)
338 std::swap (
final, start);
341 if (start >= 0 && final < mat->slice_len)
347 std::fill (data + start, data + start + nelem, value);
360 avalue.
xelem (0) = value;
361 array->
assign (idx, avalue);
376 else if (ndim > count)
378 if (idx == count - 1)
405 if (lhs.imag () == 0 && rhs.imag() == 0)
406 return Complex (lhs.real () * rhs.real (), 0);
434 if (lhs < 0.0 && !
xisint (rhs))
442 if (lhs.imag () == 0 && rhs.imag () == 0)
450 if (lhs.imag () == 0)
458 if (rhs.imag () == 0)
466 std::cout << *m << std::endl;
472 error (
"incorrect type information given to the JIT compiler");
481 for (
size_t i = 0; i < nargin; ++i)
519 return os <<
"Range[" << rng.
base <<
", " << rng.
limit <<
", " << rng.
inc
520 <<
", " << rng.
nelem <<
"]";
535 llvm::Type *allvm_type,
bool askip_paren,
int aid) :
536 mname (aname),
mparent (aparent), llvm_type (allvm_type),
mid (aid),
537 mdepth (aparent ? aparent->mdepth + 1 : 0), mskip_paren (askip_paren)
556 call_conv (jit_convention::
length),
562 const llvm::Twine& aname,
jit_type *aresult,
563 const std::vector<jit_type *>& aargs)
564 : module (amodule), mresult (aresult), args (aargs), call_conv (acall_conv),
567 llvm::SmallVector<llvm::Type *, 15> llvm_args;
569 llvm::Type *rtype = llvm::Type::getVoidTy (
context);
575 llvm_args.push_back (rtype->getPointerTo ());
576 rtype = llvm::Type::getVoidTy (
context);
580 for (std::vector<jit_type *>::const_iterator iter =
args.begin ();
581 iter !=
args.end (); ++iter)
587 argty = argty->getPointerTo ();
589 llvm_args.push_back (argty);
594 llvm::FunctionType *ft = llvm::FunctionType::get (rtype, llvm_args,
false);
595 llvm_function = llvm::Function::Create (ft, llvm::Function::ExternalLinkage,
600 #ifdef FUNCTION_ADDATTRIBUTE_ARG_IS_ATTRIBUTES
601 llvm::AttrBuilder attr_builder;
602 attr_builder.addAttribute (llvm::Attributes::StructRet);
603 llvm::Attributes attrs = llvm::Attributes::get(
context, attr_builder);
611 #ifdef FUNCTION_ADDFNATTR_ARG_IS_ATTRIBUTES
619 const std::vector<jit_type *>& aargs)
620 : module (fn.module), llvm_function (fn.llvm_function), mresult (aresult),
621 args (aargs), call_conv (fn.call_conv), mcan_error (fn.mcan_error)
626 : module (fn.module), llvm_function (fn.llvm_function), mresult (fn.mresult),
627 args (fn.args), call_conv (fn.call_conv), mcan_error (fn.mcan_error)
648 llvm::BasicBlock *insert_before)
656 const std::vector<jit_value *>& in_args)
const
661 assert (in_args.size () ==
args.size ());
662 std::vector<llvm::Value *> llvm_args (
args.size ());
663 for (
size_t i = 0; i < in_args.size (); ++i)
664 llvm_args[i] = in_args[i]->
to_llvm ();
666 return call (builder, llvm_args);
671 const std::vector<llvm::Value *>& in_args)
const
676 assert (in_args.size () ==
args.size ());
677 llvm::SmallVector<llvm::Value *, 10> llvm_args;
678 llvm_args.reserve (in_args.size () +
sret ());
680 llvm::BasicBlock *insert_block = builder.GetInsertBlock ();
681 llvm::Function *
parent = insert_block->getParent ();
685 llvm::BasicBlock& prelude = parent->getEntryBlock ();
686 llvm::IRBuilder<> pre_builder (&prelude, prelude.begin ());
688 llvm::AllocaInst *sret_mem = 0;
692 llvm_args.push_back (sret_mem);
695 for (
size_t i = 0; i < in_args.size (); ++i)
697 llvm::Value *
arg = in_args[i];
705 llvm::Value *alloca = pre_builder.CreateAlloca (ty);
706 builder.CreateStore (arg, alloca);
710 llvm_args.push_back (arg);
713 llvm::CallInst *callinst = builder.CreateCall (
llvm_function, llvm_args);
714 llvm::Value *ret = callinst;
718 #ifdef CALLINST_ADDATTRIBUTE_ARG_IS_ATTRIBUTES
719 llvm::AttrBuilder attr_builder;
720 attr_builder.addAttribute(llvm::Attributes::StructRet);
721 llvm::Attributes attrs = llvm::Attributes::get(
context, attr_builder);
722 callinst->addAttribute (1, attrs);
724 callinst->addAttribute (1, llvm::Attribute::StructRet);
726 ret = builder.CreateLoad (sret_mem);
733 ret = unpack (builder, ret);
742 assert (idx <
args.size ());
747 llvm::Function::arg_iterator iter =
llvm_function->arg_begin ();
751 for (
size_t i = 0; i < idx; ++i, ++iter);
754 return builder.CreateLoad (iter);
769 rval =
convert (builder, rval);
774 builder.CreateRetVoid ();
777 builder.CreateRet (rval);
780 builder.CreateRetVoid ();
796 llvm::Function *lfn = fn.
to_llvm ();
797 os <<
"jit_function: cc=" << fn.
call_conv;
798 llvm::raw_os_ostream llvm_out (os);
799 lfn->print (llvm_out);
807 for (generated_map::iterator iter =
generated.begin ();
817 const std::vector<jit_type*>& args)
825 bool must_resize =
false;
827 if (dv.length () != idx.numel ())
829 dv.resize (idx.numel ());
850 for (
size_t i =0; i < types.size (); ++i)
852 return null_overload;
878 for (
octave_idx_type i = 0; i < static_cast<octave_idx_type> (types.size ());
880 idx(i) = types[i]->type_id ();
882 if (types.size () == 0)
884 if (types.size () == 1)
897 generated_map::const_iterator
find =
generated.find (&types);
901 return *find->second;
903 return null_overload;
908 return ret ? *ret : null_overload;
924 if (l.size () < r.size ())
926 else if (l.size () > r.size ())
929 for (
size_t i = 0; i < l.size (); ++i)
931 if (l[i]->type_id () < r[i]->type_id ())
933 else if (l[i]->type_id () > r[i]->type_id ())
948 for (
size_t i = 1; i < types.size (); ++i)
949 if (types[i] != scalar)
961 size_t end_idx)
const
963 size_t n = end_idx - start_idx;
965 llvm::ArrayType *array_t = llvm::ArrayType::get (scalar_t, n);
966 llvm::Value *array = llvm::UndefValue::get (array_t);
967 for (
size_t i = start_idx; i < end_idx; ++i)
969 llvm::Value *idx = fn.
argument (builder, i);
970 array = builder.CreateInsertValue (array, idx, i - start_idx);
973 llvm::Value *array_mem = builder.CreateAlloca (array_t);
974 builder.CreateStore (array, array_mem);
975 return builder.CreateBitCast (array_mem, scalar_t->getPointerTo ());
982 std::stringstream ss;
983 ss <<
"jit_paren_subsref_matrix_scalar" << (types.size () - 1);
987 ss.str (),
scalar, types);
989 llvm::BasicBlock *body = fn->
new_block ();
990 llvm::IRBuilder<>
builder (body);
994 llvm::Value *nelem = llvm::ConstantInt::get (index->to_llvm (),
996 llvm::Value *mat = fn->
argument (builder, 0);
1005 std::vector<jit_type *> types (3);
1012 "octave_jit_paren_scalar", scalar, types);
1021 std::stringstream ss;
1022 ss <<
"jit_paren_subsasgn_matrix_scalar" << (types.size () - 2);
1026 ss.str (), matrix, types);
1028 llvm::BasicBlock *body = fn->
new_block ();
1029 llvm::IRBuilder<>
builder (body);
1031 llvm::Value *array =
create_arg_array (builder, *fn, 1, types.size () - 1);
1033 llvm::Value *nelem = llvm::ConstantInt::get (index->to_llvm (),
1036 llvm::Value *mat = fn->
argument (builder, 0);
1037 llvm::Value *value = fn->
argument (builder, types.size () - 1);
1050 std::vector<jit_type *> types (4);
1057 "octave_jit_paren_scalar", matrix, types);
1070 #define JIT_FN(fn) engine, &fn, #fn
1073 : module (m), engine (e),
next_id (0),
1079 llvm::Type *any_t = llvm::StructType::create (
context,
"octave_base_value");
1080 any_t = any_t->getPointerTo ();
1082 llvm::Type *scalar_t = llvm::Type::getDoubleTy (
context);
1083 llvm::Type *bool_t = llvm::Type::getInt1Ty (
context);
1084 llvm::Type *string_t = llvm::Type::getInt8Ty (
context);
1085 string_t = string_t->getPointerTo ();
1086 llvm::Type *index_t = llvm::Type::getIntNTy (
context,
1089 llvm::StructType *range_t = llvm::StructType::create (
context,
"range");
1090 std::vector<llvm::Type *> range_contents (4, scalar_t);
1091 range_contents[3] = index_t;
1092 range_t->setBody (range_contents);
1094 llvm::Type *refcount_t = llvm::Type::getIntNTy (
context,
sizeof(
int) * 8);
1096 llvm::StructType *matrix_t = llvm::StructType::create (
context,
"matrix");
1097 llvm::Type *matrix_contents[5];
1098 matrix_contents[0] = refcount_t->getPointerTo ();
1099 matrix_contents[1] = scalar_t->getPointerTo ();
1100 matrix_contents[2] = index_t;
1101 matrix_contents[3] = index_t->getPointerTo ();
1102 matrix_contents[4] = string_t;
1103 matrix_t->setBody (llvm::makeArrayRef (matrix_contents, 5));
1105 llvm::Type *complex_t = llvm::ArrayType::get (scalar_t, 2);
1109 llvm::Type *cmplx_inner_cont[] = {scalar_t, scalar_t};
1110 llvm::StructType *cmplx_inner = llvm::StructType::create (cmplx_inner_cont);
1114 llvm::Type *contents[] = {cmplx_inner};
1151 if (
sizeof (
void *) == 4)
1159 llvm::GlobalValue::ExternalLinkage,
1168 llvm::GlobalValue::ExternalLinkage, 0,
1169 "octave_interrupt_state");
1183 llvm::Type *llvm_bo_type = binary_op_type->
to_llvm ();
1192 binary_ops[i].stash_name (
"binary" + op_name);
1200 unary_ops[i].stash_name (
"unary" + op_name);
1203 for (
int op = 0; op < octave_value::num_binary_ops; ++op)
1205 llvm::Twine fn_name (
"octave_jit_binary_any_any_");
1206 fn_name = fn_name + llvm::Twine (op);
1210 llvm::BasicBlock *block = fn.
new_block ();
1211 builder.SetInsertPoint (block);
1213 std::numeric_limits<octave_value::binary_op>::is_signed);
1214 llvm::Value *op_as_llvm = llvm::ConstantInt::get (llvm_bo_type, op_int);
1215 llvm::Value *ret = any_binary.
call (
builder, op_as_llvm,
1270 llvm::BasicBlock *body = fn.
new_block ();
1271 builder.SetInsertPoint (body);
1273 llvm::BasicBlock *warn_block = fn.
new_block (
"warn");
1274 llvm::BasicBlock *normal_block = fn.
new_block (
"normal");
1276 llvm::Value *zero = llvm::ConstantFP::get (scalar_t, 0);
1278 builder.CreateCondBr (check, warn_block, normal_block);
1280 builder.SetInsertPoint (warn_block);
1282 builder.CreateBr (normal_block);
1284 builder.SetInsertPoint (normal_block);
1309 builder.SetInsertPoint (body);
1311 llvm::Value *one = llvm::ConstantFP::get (scalar_t, 1);
1313 val =
builder.CreateFAdd (val, one);
1320 builder.SetInsertPoint (body);
1322 llvm::Value *one = llvm::ConstantFP::get (scalar_t, 1);
1324 val =
builder.CreateFSub (val, one);
1331 builder.SetInsertPoint (body);
1333 llvm::Value *mone = llvm::ConstantFP::get (scalar_t, -1);
1335 val =
builder.CreateFMul (val, mone);
1348 builder.SetInsertPoint (body);
1363 builder.SetInsertPoint (body);
1395 builder.SetInsertPoint (body);
1397 llvm::BasicBlock *complex_mul = fn.
new_block (
"complex_mul");
1398 llvm::BasicBlock *scalar_mul = fn.
new_block (
"scalar_mul");
1400 llvm::Value *fzero = llvm::ConstantFP::get (scalar_t, 0);
1405 builder.CreateCondBr (cmp, scalar_mul, complex_mul);
1407 builder.SetInsertPoint (scalar_mul);
1409 temp =
builder.CreateFMul (lhs, temp);
1413 builder.SetInsertPoint (complex_mul);
1429 builder.SetInsertPoint (body);
1444 builder.SetInsertPoint (body);
1456 builder.SetInsertPoint (body);
1492 builder.SetInsertPoint (body);
1494 llvm::Value *zero = llvm::ConstantInt::get (index_t, 0);
1504 builder.SetInsertPoint (body);
1509 llvm::Value *ret =
builder.CreateICmpULT (idx, nelem);
1519 builder.SetInsertPoint (body);
1522 llvm::Value *didx =
builder.CreateSIToFP (idx, scalar_t);
1524 llvm::Value *base =
builder.CreateExtractValue (rng, 0);
1525 llvm::Value *inc =
builder.CreateExtractValue (rng, 2);
1527 llvm::Value *ret =
builder.CreateFMul (didx, inc);
1528 ret =
builder.CreateFAdd (base, ret);
1544 builder.SetInsertPoint (body);
1546 llvm::BasicBlock *error_block = fn.
new_block (
"error");
1547 llvm::BasicBlock *normal_block = fn.
new_block (
"normal");
1551 builder.CreateCondBr (check, error_block, normal_block);
1553 builder.SetInsertPoint (error_block);
1555 builder.CreateBr (normal_block);
1556 builder.SetInsertPoint (normal_block);
1558 llvm::Value *zero = llvm::ConstantFP::get (scalar_t, 0);
1578 builder.SetInsertPoint (body);
1583 llvm::Value *nelem = compute_nelem.
call (
builder, base, limit, inc);
1585 llvm::Value *dzero = llvm::ConstantFP::get (scalar_t, 0);
1586 llvm::Value *izero = llvm::ConstantInt::get (index_t, 0);
1587 llvm::Value *rng = llvm::ConstantStruct::get (range_t, dzero, dzero, dzero,
1589 rng =
builder.CreateInsertValue (rng, base, 0);
1590 rng =
builder.CreateInsertValue (rng, limit, 1);
1591 rng =
builder.CreateInsertValue (rng, inc, 2);
1592 rng =
builder.CreateInsertValue (rng, nelem, 3);
1599 llvm::Type *int_t = jit_int->
to_llvm ();
1603 0, jit_int, jit_int,
index,
1610 builder.SetInsertPoint (body);
1612 llvm::Value *one = llvm::ConstantInt::get (index_t, 1);
1614 if (index_t == int_t)
1617 ione = llvm::ConstantInt::get (int_t, 1);
1619 llvm::Value *undef = llvm::UndefValue::get (scalar_t);
1624 llvm::Value *int_idx =
builder.CreateFPToSI (idx, index_t);
1625 llvm::Value *check_idx =
builder.CreateSIToFP (int_idx, scalar_t);
1626 llvm::Value *cond0 =
builder.CreateFCmpUNE (idx, check_idx);
1627 llvm::Value *cond1 =
builder.CreateICmpSLT (int_idx, one);
1628 llvm::Value *cond =
builder.CreateOr (cond0, cond1);
1630 llvm::BasicBlock *done = fn.
new_block (
"done");
1631 llvm::BasicBlock *conv_error = fn.
new_block (
"conv_error", done);
1632 llvm::BasicBlock *normal = fn.
new_block (
"normal", done);
1633 builder.CreateCondBr (cond, conv_error, normal);
1635 builder.SetInsertPoint (conv_error);
1639 builder.SetInsertPoint (normal);
1641 =
builder.CreateExtractValue (mat, llvm::ArrayRef<unsigned> (2));
1642 cond =
builder.CreateICmpSGT (int_idx, len);
1645 llvm::BasicBlock *bounds_error = fn.
new_block (
"bounds_error", done);
1646 llvm::BasicBlock *success = fn.
new_block (
"success", done);
1647 builder.CreateCondBr (cond, bounds_error, success);
1649 builder.SetInsertPoint (bounds_error);
1650 gindex_range.
call (
builder, ione, ione, int_idx, len);
1653 builder.SetInsertPoint (success);
1654 llvm::Value *data =
builder.CreateExtractValue (mat,
1655 llvm::ArrayRef<unsigned> (1));
1656 llvm::Value *gep =
builder.CreateInBoundsGEP (data, int_idx);
1657 llvm::Value *ret =
builder.CreateLoad (gep);
1660 builder.SetInsertPoint (done);
1662 llvm::PHINode *merge = llvm::PHINode::Create (scalar_t, 3);
1664 merge->addIncoming (undef, conv_error);
1665 merge->addIncoming (undef, bounds_error);
1666 merge->addIncoming (ret, success);
1682 builder.SetInsertPoint (body);
1684 llvm::Value *one = llvm::ConstantInt::get (index_t, 1);
1690 llvm::Value *int_idx =
builder.CreateFPToSI (idx, index_t);
1691 llvm::Value *check_idx =
builder.CreateSIToFP (int_idx, scalar_t);
1692 llvm::Value *cond0 =
builder.CreateFCmpUNE (idx, check_idx);
1693 llvm::Value *cond1 =
builder.CreateICmpSLT (int_idx, one);
1694 llvm::Value *cond =
builder.CreateOr (cond0, cond1);
1696 llvm::BasicBlock *done = fn.
new_block (
"done");
1698 llvm::BasicBlock *conv_error = fn.
new_block (
"conv_error", done);
1699 llvm::BasicBlock *normal = fn.
new_block (
"normal", done);
1700 builder.CreateCondBr (cond, conv_error, normal);
1701 builder.SetInsertPoint (conv_error);
1705 builder.SetInsertPoint (normal);
1706 llvm::Value *len =
builder.CreateExtractValue (mat, 2);
1707 cond0 =
builder.CreateICmpSGT (int_idx, len);
1709 llvm::Value *rcount =
builder.CreateExtractValue (mat, 0);
1710 rcount =
builder.CreateLoad (rcount);
1711 cond1 =
builder.CreateICmpSGT (rcount, one);
1712 cond =
builder.CreateOr (cond0, cond1);
1714 llvm::BasicBlock *bounds_error = fn.
new_block (
"bounds_error", done);
1715 llvm::BasicBlock *success = fn.
new_block (
"success", done);
1716 builder.CreateCondBr (cond, bounds_error, success);
1719 builder.SetInsertPoint (bounds_error);
1720 llvm::Value *resize_result = resize_paren_subsasgn.
call (
builder, mat,
1724 builder.SetInsertPoint (success);
1726 =
builder.CreateExtractValue (mat, llvm::ArrayRef<unsigned> (1));
1727 llvm::Value *gep =
builder.CreateInBoundsGEP (data, int_idx);
1728 builder.CreateStore (value, gep);
1731 builder.SetInsertPoint (done);
1733 llvm::PHINode *merge = llvm::PHINode::Create (matrix_t, 3);
1735 merge->addIncoming (mat, conv_error);
1736 merge->addIncoming (resize_result, bounds_error);
1737 merge->addIncoming (mat, success);
1750 builder.SetInsertPoint (body);
1753 llvm::Value *ret =
builder.CreateExtractValue (mat, 2);
1772 casts[range->type_id ()].stash_name (
"(range)");
1788 casts[range->type_id ()].add_overload (fn);
1809 builder.SetInsertPoint (body);
1811 llvm::Value *zero = llvm::ConstantFP::get (scalar_t, 0);
1819 builder.SetInsertPoint (body);
1883 std::vector<jit_type *> args;
1886 for (std::map<std::string, jit_type *>::iterator iter =
builtins.begin ();
1906 if (ccount && ccount->
value () == 1)
1914 llvm::Type *llvm_type,
bool skip_paren)
1924 std::stringstream name;
1925 name <<
"octave_jit_print_" << ty->
name ();
1935 std::stringstream fname;
1938 <<
"_" << ty->
name ();
1941 llvm::BasicBlock *block = fn.
new_block ();
1942 builder.SetInsertPoint (block);
1943 llvm::Instruction::BinaryOps temp
1944 =
static_cast<llvm::Instruction::BinaryOps
>(llvm_op);
1955 std::stringstream fname;
1958 <<
"_" << ty->
name ();
1961 llvm::BasicBlock *block = fn.
new_block ();
1962 builder.SetInsertPoint (block);
1963 llvm::CmpInst::Predicate temp
1964 =
static_cast<llvm::CmpInst::Predicate
>(llvm_op);
1974 std::stringstream fname;
1977 <<
"_" << ty->
name ();
1980 llvm::BasicBlock *block = fn.
new_block ();
1981 builder.SetInsertPoint (block);
1982 llvm::CmpInst::Predicate temp
1983 =
static_cast<llvm::CmpInst::Predicate
>(llvm_op);
1993 const std::vector<jit_type *>& args)
2008 std::stringstream name;
2009 name <<
"id_" << type->
name ();
2012 llvm::BasicBlock *body = fn.
new_block ();
2013 builder.SetInsertPoint (body);
2031 val->setVolatile (
true);
2032 return abuilder.CreateICmpSGT (val, abuilder.getInt32 (0));
2049 const std::vector<jit_type *>& args)
2052 size_t nargs = args.size ();
2053 llvm::SmallVector<llvm::Type *, 5> llvm_args (nargs);
2054 for (
size_t i = 0; i < nargs; ++i)
2055 llvm_args[i] = args[i]->
to_llvm ();
2057 llvm::Intrinsic::ID
id =
static_cast<llvm::Intrinsic::ID
> (iid);
2058 llvm::Function *ifun = llvm::Intrinsic::getDeclaration (
module,
id,
2060 std::stringstream fn_name;
2061 fn_name <<
"octave_jit_" << name;
2063 std::vector<jit_type *> args1 (nargs + 1);
2064 args1[0] = builtin_type;
2065 std::copy (args.begin (), args.end (), args1.begin () + 1);
2071 llvm::BasicBlock *body = fn.
new_block ();
2072 builder.SetInsertPoint (body);
2074 llvm::SmallVector<llvm::Value *, 5> fargs (nargs);
2075 for (
size_t i = 0; i < nargs; ++i)
2076 fargs[i] = fn.argument (
builder, i + 1);
2078 llvm::Value *ret =
builder.CreateCall (ifun, fargs);
2094 const std::vector<jit_type *>& args)
2100 std::vector<jit_type *> fn_args (args.size () + 1);
2102 std::copy (args.begin (), args.end (), fn_args.begin () + 1);
2104 fn.mark_can_error ();
2105 llvm::BasicBlock *block = fn.new_block ();
2106 builder.SetInsertPoint (block);
2108 llvm::ArrayType *array_t = llvm::ArrayType::get (any_t, args.size ());
2109 llvm::Value *array = llvm::UndefValue::get (array_t);
2110 for (
size_t i = 0; i < args.size (); ++i)
2112 llvm::Value *
arg = fn.argument (
builder, i + 1);
2120 llvm::Value *array_mem =
builder.CreateAlloca (array_t);
2121 builder.CreateStore (array, array_mem);
2122 array =
builder.CreateBitCast (array_mem, any_t->getPointerTo ());
2125 llvm::Type *intTy = jintTy->
to_llvm ();
2126 size_t fcn_int =
reinterpret_cast<size_t> (builtin->
function ());
2127 llvm::Value *fcn = llvm::ConstantInt::get (intTy, fcn_int);
2128 llvm::Value *nargin = llvm::ConstantInt::get (intTy, args.size ());
2129 size_t result_int =
reinterpret_cast<size_t> (result);
2130 llvm::Value *res_llvm = llvm::ConstantInt::get (intTy, result_int);
2147 llvm::BasicBlock *body = ret.
new_block ();
2148 builder.SetInsertPoint (body);
2163 llvm::Value *
real = bld.CreateExtractValue (cplx, 0);
2164 llvm::Value *
imag = bld.CreateExtractValue (cplx, 1);
2165 llvm::Value *ret = llvm::UndefValue::get (complex_ret);
2167 unsigned int re_idx[] = {0, 0};
2168 unsigned int im_idx[] = {0, 1};
2169 ret = bld.CreateInsertValue (ret, real, re_idx);
2170 return bld.CreateInsertValue (ret, imag, im_idx);
2176 unsigned int re_idx[] = {0, 0};
2177 unsigned int im_idx[] = {0, 1};
2180 llvm::Value *
real = bld.CreateExtractValue (result, re_idx);
2181 llvm::Value *
imag = bld.CreateExtractValue (result, im_idx);
2182 llvm::Value *ret = llvm::UndefValue::get (complex_t);
2184 ret = bld.CreateInsertValue (ret, real, 0);
2185 return bld.CreateInsertValue (ret, imag, 1);
2191 return builder.CreateExtractValue (cx, 0);
2197 return builder.CreateInsertValue (cx, real, 0);
2203 return builder.CreateExtractValue (cx, 1);
2209 return builder.CreateInsertValue (cx, imag, 1);
2223 std::stringstream tname;
2224 tname <<
"int" << nbits;
2232 std::map<size_t, jit_type *>::const_iterator iter =
ints.find (nbits);
2233 if (iter !=
ints.end ())
2234 return iter->second;
2248 return builtin && builtin->
to_jit () ? builtin->
to_jit ()
2270 if (cv.imag () != 0)