static void assign_arrayvar(jl_arrayvar_t &av, Value *ar) { builder.CreateStore(builder.CreateBitCast(emit_arrayptr(ar),T_pint8), av.dataptr); builder.CreateStore(emit_arraylen_prim(ar, av.ty), av.len); builder.CreateStore(emit_arraysize(ar,1), av.nr); }
static Value *emit_arraylen_prim(Value *t, jl_value_t *ty) { #ifdef STORE_ARRAY_LEN (void)ty; Value *lenbits = emit_nthptr(t, 2); return builder.CreatePtrToInt(lenbits, T_size); #else jl_value_t *p1 = jl_tparam1(ty); if (jl_is_long(p1)) { size_t nd = jl_unbox_long(p1); Value *l = ConstantInt::get(T_size, 1); for(size_t i=0; i < nd; i++) { l = builder.CreateMul(l, emit_arraysize(t, (int)(i+1))); } return l; } else { std::vector<Type *> fargt(0); fargt.push_back(jl_pvalue_llvmt); FunctionType *ft = FunctionType::get(T_size, fargt, false); Value *alen = jl_Module->getOrInsertFunction("jl_array_len_", ft); return builder.CreateCall(alen, t); } #endif }
static Value *emit_arraysize(Value *t, jl_value_t *ex, int dim, jl_codectx_t *ctx) { if (dim == 1) { jl_arrayvar_t *av = arrayvar_for(ex, ctx); if (av!=NULL) return builder.CreateLoad(av->nr); } return emit_arraysize(t, dim); }
static Value *emit_array_nd_index(Value *a, size_t nd, jl_value_t **args, size_t nidxs, jl_codectx_t *ctx) { Value *i = ConstantInt::get(T_size, 0); Value *stride = ConstantInt::get(T_size, 1); #if CHECK_BOUNDS==1 BasicBlock *failBB = BasicBlock::Create(getGlobalContext(), "oob"); BasicBlock *endBB = BasicBlock::Create(getGlobalContext(), "idxend"); #endif for(size_t k=0; k < nidxs; k++) { Value *ii = emit_unbox(T_size, T_psize, emit_unboxed(args[k], ctx)); ii = builder.CreateSub(ii, ConstantInt::get(T_size, 1)); i = builder.CreateAdd(i, builder.CreateMul(ii, stride)); if (k < nidxs-1) { Value *d = k >= nd ? ConstantInt::get(T_size, 1) : emit_arraysize(a, k+1); #if CHECK_BOUNDS==1 BasicBlock *okBB = BasicBlock::Create(getGlobalContext(), "ib"); // if !(i < d) goto error builder.CreateCondBr(builder.CreateICmpULT(ii, d), okBB, failBB); ctx->f->getBasicBlockList().push_back(okBB); builder.SetInsertPoint(okBB); #endif stride = builder.CreateMul(stride, d); } } #if CHECK_BOUNDS==1 Value *alen = emit_arraylen(a); // if !(i < alen) goto error builder.CreateCondBr(builder.CreateICmpULT(i, alen), endBB, failBB); ctx->f->getBasicBlockList().push_back(failBB); builder.SetInsertPoint(failBB); builder.CreateCall2(jlthrow_line_func, builder.CreateLoad(jlboundserr_var), ConstantInt::get(T_int32, ctx->lineno)); builder.CreateUnreachable(); ctx->f->getBasicBlockList().push_back(endBB); builder.SetInsertPoint(endBB); #endif return i; }
static Value *emit_arraysize(Value *t, int dim) { return emit_arraysize(t, ConstantInt::get(T_int32, dim)); }