diff --git a/src/abi_ppc64le.cpp b/src/abi_ppc64le.cpp index a6ae101040b4c..3c13d8b47aa4d 100644 --- a/src/abi_ppc64le.cpp +++ b/src/abi_ppc64le.cpp @@ -41,7 +41,7 @@ struct ABI_PPC64leLayout : AbiLayout { -// count the homogeneous floating agregate size (saturating at max count of 8) +// count the homogeneous floating aggregate size (saturating at max count of 8) unsigned isHFA(jl_datatype_t *ty, jl_datatype_t **ty0, bool *hva) const { size_t i, l = ty->layout->nfields; @@ -133,10 +133,7 @@ Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override else { jl_datatype_t *vecty = (jl_datatype_t*)jl_field_type(ty0, 0); assert(jl_is_datatype(vecty) && vecty->name == jl_vecelement_typename); - jl_value_t *elemty = jl_tparam0(vecty); - assert(jl_is_primitivetype(elemty)); - - Type *ety = julia_type_to_llvm(elemty); + Type *ety = bitstype_to_llvm(jl_tparam0(vecty)); Type *vty = VectorType::get(ety, jl_datatype_nfields(ty0)); return ArrayType::get(vty, hfa); } diff --git a/src/ccall.cpp b/src/ccall.cpp index 550f77bc153d8..45d5860e8ec9a 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -634,7 +634,7 @@ static Value *julia_to_address( return p; } - Type *slottype = julia_struct_to_llvm(jvinfo.typ, NULL, NULL); + Type *slottype = julia_struct_to_llvm(ctx, jvinfo.typ, NULL, NULL); // pass the address of an alloca'd thing, not a box // since those are immutable. Value *slot = emit_static_alloca(ctx, slottype); @@ -806,7 +806,7 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg else { rt = (jl_value_t*)jl_voidpointer_type; } - Type *lrt = julia_type_to_llvm(rt); + Type *lrt = julia_type_to_llvm(ctx, rt); interpret_symbol_arg(ctx, sym, args[1], "cglobal", false); @@ -1030,7 +1030,7 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar for (size_t i = 0; i < nargt; ++i) { jl_value_t *tti = jl_svecref(tt,i); bool toboxed; - Type *t = julia_type_to_llvm(tti, &toboxed); + Type *t = julia_type_to_llvm(ctx, tti, &toboxed); argtypes.push_back(t); if (4 + i > nargs) { jl_error("Missing arguments to llvmcall!"); @@ -1045,7 +1045,7 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar Function *f; bool retboxed; - Type *rettype = julia_type_to_llvm(rtt, &retboxed); + Type *rettype = julia_type_to_llvm(ctx, rtt, &retboxed); if (isString) { // Make sure to find a unique name std::string ir_name; @@ -1212,12 +1212,16 @@ class function_sig_t { jl_unionall_t *unionall_env; // UnionAll environment for `at` and `rt` size_t nargs; // number of actual arguments (can be different from the size of at when varargs) size_t isVa; + jl_codegen_params_t *ctx; - function_sig_t(Type *lrt, jl_value_t *rt, bool retboxed, jl_svec_t *at, jl_unionall_t *unionall_env, size_t nargs, size_t isVa, CallingConv::ID cc, bool llvmcall) + function_sig_t(Type *lrt, jl_value_t *rt, bool retboxed, + jl_svec_t *at, jl_unionall_t *unionall_env, size_t nargs, size_t isVa, + CallingConv::ID cc, bool llvmcall, + jl_codegen_params_t *ctx) : fargt_vasig(NULL), lrt(lrt), retboxed(retboxed), prt(NULL), sret(0), cc(cc), llvmcall(llvmcall), functype(NULL), at(at), rt(rt), unionall_env(unionall_env), - nargs(nargs), isVa(isVa) + nargs(nargs), isVa(isVa), ctx(ctx) { err_msg = generate_func_sig(); if (err_msg.empty()) @@ -1313,7 +1317,7 @@ std::string generate_func_sig() } } - t = julia_struct_to_llvm(tti, unionall_env, &isboxed); + t = _julia_struct_to_llvm(ctx, tti, unionall_env, &isboxed); if (isboxed) t = T_prjlvalue; if (t == NULL || t == T_void) { @@ -1415,6 +1419,7 @@ static std::pair convert_cconv(jl_sym_t *lhd) static const std::string verify_ccall_sig(size_t nccallargs, jl_value_t *&rt, jl_value_t *at, jl_unionall_t *unionall_env, jl_svec_t *sparam_vals, const char *funcName, + jl_codegen_params_t *ctx, size_t &nargt, bool &isVa, Type *&lrt, bool &retboxed, bool &static_rt) { assert(rt && !jl_is_abstract_ref_type(rt)); @@ -1426,7 +1431,7 @@ static const std::string verify_ccall_sig(size_t nccallargs, jl_value_t *&rt, jl rt = (jl_value_t*)jl_any_type; } - lrt = julia_struct_to_llvm(rt, unionall_env, &retboxed); + lrt = _julia_struct_to_llvm(ctx, rt, unionall_env, &retboxed); if (lrt == NULL) return "ccall: return type doesn't correspond to a C type"; else if (retboxed) @@ -1552,6 +1557,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) nccallargs, rt, at, unionall, ctx.spvals_ptr == NULL ? ctx.linfo->sparam_vals : NULL, ctx.funcName.c_str(), + &ctx.emission_context, /* outputs: */ nargt, isVa, lrt, retboxed, static_rt); if (!err.empty()) { @@ -1638,7 +1644,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) isboxed = false; } else { - largty = julia_struct_to_llvm(tti, unionall, &isboxed); + largty = julia_struct_to_llvm(ctx, tti, unionall, &isboxed); } if (isboxed) { ary = boxed(ctx, argv[0]); @@ -1808,7 +1814,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) } function_sig_t sig(lrt, rt, retboxed, (jl_svec_t*)at, unionall, nccallargs, - isVa, cc, llvmcall); + isVa, cc, llvmcall, &ctx.emission_context); jl_cgval_t retval = sig.emit_a_ccall( ctx, symarg, @@ -2055,7 +2061,7 @@ jl_cgval_t function_sig_t::emit_a_ccall( } } else { - Type *jlrt = julia_type_to_llvm(rt, &jlretboxed); // compute the real "julian" return type and compute whether it is boxed + Type *jlrt = julia_type_to_llvm(ctx, rt, &jlretboxed); // compute the real "julian" return type and compute whether it is boxed if (jlretboxed) { jlrt = T_prjlvalue; } diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 4b7b85bfa23ec..9b55474621782 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -157,39 +157,41 @@ static Value *stringConstPtr(IRBuilder<> &irbuilder, const std::string &txt) // --- Debug info --- -static DIType *julia_type_to_di(jl_value_t *jt, DIBuilder *dbuilder, bool isboxed = false) +static DIType *_julia_type_to_di(jl_codegen_params_t *ctx, jl_value_t *jt, DIBuilder *dbuilder, bool isboxed) { - if (isboxed || !jl_is_datatype(jt)) - return jl_pvalue_dillvmt; jl_datatype_t *jdt = (jl_datatype_t*)jt; - // always return the boxed representation for types with hidden content - if (jdt->ditype != NULL) - return (DIType*)jdt->ditype; + if (isboxed || !jl_is_datatype(jt) || !jdt->isconcretetype) + return jl_pvalue_dillvmt; + assert(jdt->uid && jdt->layout); + DIType* _ditype = NULL; + DIType* &ditype = (ctx ? ctx->ditypes[jdt] : _ditype); + if (ditype) + return ditype; + const char *tname = jl_symbol_name(jdt->name->name); if (jl_is_primitivetype(jt)) { uint64_t SizeInBits = jl_datatype_nbits(jdt); -#if JL_LLVM_VERSION >= 40000 - llvm::DIType *t = dbuilder->createBasicType( - jl_symbol_name(jdt->name->name), - SizeInBits, - llvm::dwarf::DW_ATE_unsigned); - jdt->ditype = t; - return t; -#else - llvm::DIType *t = dbuilder->createBasicType( - jl_symbol_name(jdt->name->name), - SizeInBits, + ditype = dbuilder->createBasicType(tname, SizeInBits, +#if JL_LLVM_VERSION < 40000 8 * jl_datatype_align(jdt), - llvm::dwarf::DW_ATE_unsigned); - jdt->ditype = t; - return t; #endif + llvm::dwarf::DW_ATE_unsigned); } - if (jl_is_structtype(jt) && jdt->uid && jdt->layout && !jl_is_layout_opaque(jdt->layout)) { + else if (jl_is_structtype(jt) && !jl_is_layout_opaque(jdt->layout)) { size_t ntypes = jl_datatype_nfields(jdt); - const char *tname = jl_symbol_name(jdt->name->name); + std::vector Elements(ntypes); + for (unsigned i = 0; i < ntypes; i++) { + jl_value_t *el = jl_svecref(jdt->types, i); + DIType *di; + if (jl_field_isptr(jdt, i)) + di = jl_pvalue_dillvmt; + else + di = _julia_type_to_di(ctx, el, dbuilder, false); + Elements[i] = di; + } + DINodeArray ElemArray = dbuilder->getOrCreateArray(Elements); std::stringstream unique_name; unique_name << jdt->uid; - llvm::DICompositeType *ct = dbuilder->createStructType( + ditype = dbuilder->createStructType( NULL, // Scope tname, // Name NULL, // File @@ -198,28 +200,22 @@ static DIType *julia_type_to_di(jl_value_t *jt, DIBuilder *dbuilder, bool isboxe 8 * jl_datatype_align(jdt), // AlignInBits DIFlagZero, // Flags NULL, // DerivedFrom - DINodeArray(), // Elements + ElemArray, // Elements dwarf::DW_LANG_Julia, // RuntimeLanguage nullptr, // VTableHolder unique_name.str() // UniqueIdentifier ); - jdt->ditype = ct; - std::vector Elements; - for (unsigned i = 0; i < ntypes; i++) { - jl_value_t *el = jl_svecref(jdt->types, i); - DIType *di; - if (jl_field_isptr(jdt, i)) - di = jl_pvalue_dillvmt; - else - di = julia_type_to_di(el, dbuilder, false); - Elements.push_back(di); - } - dbuilder->replaceArrays(ct, dbuilder->getOrCreateArray(ArrayRef(Elements))); - return ct; } - jdt->ditype = dbuilder->createTypedef(jl_pvalue_dillvmt, - jl_symbol_name(jdt->name->name), NULL, 0, NULL); - return (llvm::DIType*)jdt->ditype; + else { + // return a typealias for types with hidden content + ditype = dbuilder->createTypedef(jl_pvalue_dillvmt, tname, NULL, 0, NULL); + } + return ditype; +} + +static DIType *julia_type_to_di(jl_codectx_t &ctx, jl_value_t *jt, DIBuilder *dbuilder, bool isboxed) +{ + return _julia_type_to_di(&ctx.emission_context, jt, dbuilder, isboxed); } static Value *emit_pointer_from_objref(jl_codectx_t &ctx, Value *V) @@ -458,8 +454,6 @@ static Value *julia_binding_gv(jl_codectx_t &ctx, jl_binding_t *b) // --- mapping between julia and llvm types --- -static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua_env, bool *isboxed); - static unsigned convert_struct_offset(Type *lty, unsigned byte_offset) { const DataLayout &DL = @@ -483,8 +477,9 @@ static Value *emit_struct_gep(jl_codectx_t &ctx, Type *lty, Value *base, unsigne return ctx.builder.CreateConstInBoundsGEP2_32(lty, base, 0, idx); } -extern "C" { -JL_DLLEXPORT Type *julia_type_to_llvm(jl_value_t *jt, bool *isboxed) +static Type *_julia_struct_to_llvm(jl_codegen_params_t *ctx, jl_value_t *jt, jl_unionall_t *ua, bool *isboxed); + +static Type *_julia_type_to_llvm(jl_codegen_params_t *ctx, jl_value_t *jt, bool *isboxed) { // this function converts a Julia Type into the equivalent LLVM type if (isboxed) *isboxed = false; @@ -493,15 +488,26 @@ JL_DLLEXPORT Type *julia_type_to_llvm(jl_value_t *jt, bool *isboxed) if (jl_justbits(jt)) { if (jl_datatype_nbits(jt) == 0) return T_void; - Type *t = julia_struct_to_llvm(jt, NULL, isboxed); + Type *t = _julia_struct_to_llvm(ctx, jt, NULL, isboxed); assert(t != NULL); return t; } if (isboxed) *isboxed = true; return T_pjlvalue; } + +static Type *julia_type_to_llvm(jl_codectx_t &ctx, jl_value_t *jt, bool *isboxed) +{ + return _julia_type_to_llvm(&ctx.emission_context, jt, isboxed); +} + +extern "C" JL_DLLEXPORT +Type *jl_type_to_llvm(jl_value_t *jt, bool *isboxed) +{ + return _julia_type_to_llvm(NULL, jt, isboxed); } + // converts a julia bitstype into the equivalent LLVM bitstype static Type *bitstype_to_llvm(jl_value_t *bt) { @@ -525,7 +531,7 @@ static Type *bitstype_to_llvm(jl_value_t *bt) // fields depend on any of the parameters of the containing type) static bool julia_struct_has_layout(jl_datatype_t *dt, jl_unionall_t *ua) { - if (dt->layout || dt->struct_decl || jl_justbits((jl_value_t*)dt)) + if (dt->layout || jl_justbits((jl_value_t*)dt)) return true; if (ua) { size_t i, ntypes = jl_svec_len(dt->types); @@ -546,7 +552,7 @@ static unsigned jl_field_align(jl_datatype_t *dt, size_t i) return std::min(al, jl_datatype_align(dt)); } -static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isboxed) +static Type *_julia_struct_to_llvm(jl_codegen_params_t *ctx, jl_value_t *jt, jl_unionall_t *ua, bool *isboxed) { // this function converts a Julia Type into the equivalent LLVM struct // use this where C-compatible (unboxed) structs are desired @@ -558,12 +564,15 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox return bitstype_to_llvm(jt); bool isTuple = jl_is_tuple_type(jt); jl_datatype_t *jst = (jl_datatype_t*)jt; - if (jst->struct_decl != NULL) - return (Type*)jst->struct_decl; if (jl_is_structtype(jt) && !(jst->layout && jl_is_layout_opaque(jst->layout))) { size_t i, ntypes = jl_svec_len(jst->types); if (ntypes == 0 || (jst->layout && jl_datatype_nbits(jst) == 0)) return T_void; + Type* _struct_decl = NULL; + // TODO: we should probably make a temporary root for `jst` somewhere + Type* &struct_decl = (ctx ? ctx->llvmtypes[jst] : _struct_decl); + if (struct_decl) + return struct_decl; if (!julia_struct_has_layout(jst, ua)) return NULL; std::vector latypes(0); @@ -612,7 +621,7 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox continue; } else { - lty = julia_type_to_llvm(ty); + lty = _julia_type_to_llvm(ctx, ty, NULL); } if (lasttype != NULL && lasttype != lty) isarray = false; @@ -622,20 +631,19 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox latypes.push_back(lty); } } - Type *decl; if (allghost) { assert(jst->layout == NULL); // otherwise should have been caught above - decl = T_void; + struct_decl = T_void; } else if (jl_is_vecelement_type(jt)) { // VecElement type is unwrapped in LLVM - decl = latypes[0]; + struct_decl = latypes[0]; } - else if (isTuple && isarray && lasttype != T_int1 && !type_is_ghost(lasttype)) { + else if (isTuple && isarray && lasttype != T_int1 && !allghost) { if (isvector && jl_special_vector_alignment(ntypes, jlasttype) != 0) - decl = VectorType::get(lasttype, ntypes); + struct_decl = VectorType::get(lasttype, ntypes); else - decl = ArrayType::get(lasttype, ntypes); + struct_decl = ArrayType::get(lasttype, ntypes); } else { #if 0 // stress-test code that tries to assume julia-index == llvm-index @@ -645,12 +653,11 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox latypes.insert(latypes.begin(), NoopType); } #endif - decl = StructType::get(jl_LLVMContext, latypes); + struct_decl = StructType::get(jl_LLVMContext, latypes); } - jst->struct_decl = decl; - return decl; + return struct_decl; } - // TODO: enable this (with tests): + // TODO: enable this (with tests) to change ccall calling convention for Union: // if (jl_is_uniontype(ty)) { // // pick an Integer type size such that alignment will be correct // // and always end with an Int8 (selector byte) @@ -667,6 +674,11 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox return T_pjlvalue; } +static Type *julia_struct_to_llvm(jl_codectx_t &ctx, jl_value_t *jt, jl_unionall_t *ua, bool *isboxed) +{ + return _julia_struct_to_llvm(&ctx.emission_context, jt, ua, isboxed); +} + static bool is_datatype_all_pointers(jl_datatype_t *dt) { size_t i, l = jl_datatype_nfields(dt); @@ -1223,7 +1235,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j MDNode *tbaa, bool maybe_null_if_boxed = true, unsigned alignment = 0) { bool isboxed; - Type *elty = julia_type_to_llvm(jltype, &isboxed); + Type *elty = julia_type_to_llvm(ctx, jltype, &isboxed); if (type_is_ghost(elty)) return ghostValue(jltype); if (isboxed) @@ -1266,7 +1278,7 @@ static void typed_store(jl_codectx_t &ctx, unsigned alignment = 0) { bool isboxed; - Type *elty = julia_type_to_llvm(jltype, &isboxed); + Type *elty = julia_type_to_llvm(ctx, jltype, &isboxed); if (type_is_ghost(elty)) return; Value *r; @@ -1306,12 +1318,13 @@ static Value *julia_bool(jl_codectx_t &ctx, Value *cond) // --- accessing the representations of built-in data types --- -static Constant *julia_const_to_llvm(jl_value_t *e); +static Constant *julia_const_to_llvm(jl_codectx_t &ctx, jl_value_t *e); + static Value *data_pointer(jl_codectx_t &ctx, const jl_cgval_t &x) { Value *data = x.V; if (x.constant) { - Constant *val = julia_const_to_llvm(x.constant); + Constant *val = julia_const_to_llvm(ctx, x.constant); if (val) { data = get_pointer_to_constant(val, "", *jl_Module); } @@ -1427,7 +1440,7 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx, Value *ptr = decay_derived(data_pointer(ctx, strct)); if (!stt->mutabl) { // just compute the pointer and let user load it when necessary - Type *fty = julia_type_to_llvm(jt); + Type *fty = julia_type_to_llvm(ctx, jt); Value *addr = ctx.builder.CreateGEP(fty, emit_bitcast(ctx, ptr, PointerType::get(fty, 0)), idx); *ret = mark_julia_slot(addr, jt, NULL, strct.tbaa); ret->isimmutable = strct.isimmutable; @@ -1472,7 +1485,7 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx, static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &strct, unsigned idx, jl_datatype_t *jt) { jl_value_t *jfty = jl_field_type(jt, idx); - Type *elty = julia_type_to_llvm(jfty); + Type *elty = julia_type_to_llvm(ctx, jfty); if (jfty == jl_bottom_type) { raise_exception(ctx, literal_pointer_val(ctx, jl_undefref_exception)); return jl_cgval_t(); // unreachable @@ -1483,7 +1496,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st if (strct.ispointer()) { Value *staddr = decay_derived(data_pointer(ctx, strct)); bool isboxed; - Type *lt = julia_type_to_llvm((jl_value_t*)jt, &isboxed); + Type *lt = julia_type_to_llvm(ctx, (jl_value_t*)jt, &isboxed); size_t byte_offset = jl_field_offset(jt, idx); Value *addr; if (isboxed) { @@ -1610,7 +1623,7 @@ static void maybe_alloc_arrayvar(jl_codectx_t &ctx, int s) int ndims = jl_unbox_long(jl_tparam1(jt)); jl_value_t *jelt = jl_tparam0(jt); bool isboxed = !jl_array_store_unboxed(jelt); - Type *elt = julia_type_to_llvm(jelt); + Type *elt = julia_type_to_llvm(ctx, jelt); if (type_is_ghost(elt)) return; if (isboxed) @@ -2037,7 +2050,7 @@ static Value *_boxed_special(jl_codectx_t &ctx, const jl_cgval_t &vinfo, Type *t else if (jb == jl_ssavalue_type) { unsigned zero = 0; Value *v = as_value(ctx, t, vinfo); - assert(v->getType() == jl_ssavalue_type->struct_decl); + assert(v->getType() == ctx.emission_context.llvmtypes[jl_ssavalue_type]); v = ctx.builder.CreateExtractValue(v, makeArrayRef(&zero, 1)); box = call_with_unsigned(ctx, box_ssavalue_func, v); } @@ -2113,7 +2126,7 @@ static Value *box_union(jl_codectx_t &ctx, const jl_cgval_t &vinfo, const SmallB [&](unsigned idx, jl_datatype_t *jt) { if (idx < skip.size() && skip[idx]) return; - Type *t = julia_type_to_llvm((jl_value_t*)jt); + Type *t = julia_type_to_llvm(ctx, (jl_value_t*)jt); BasicBlock *tempBB = BasicBlock::Create(jl_LLVMContext, "box_union", ctx.f); ctx.builder.SetInsertPoint(tempBB); switchInst->addCase(ConstantInt::get(T_int8, idx), tempBB); @@ -2182,7 +2195,7 @@ static Value *boxed(jl_codectx_t &ctx, const jl_cgval_t &vinfo) else { assert(vinfo.V && "Missing data for unboxed value."); assert(jl_justbits(jt) && "This type shouldn't have been unboxed."); - Type *t = julia_type_to_llvm(jt); + Type *t = julia_type_to_llvm(ctx, jt); assert(!type_is_ghost(t)); // ghost values should have been handled by vinfo.constant above! box = _boxed_special(ctx, vinfo, t); if (!box) { @@ -2203,7 +2216,7 @@ static void emit_unionmove(jl_codectx_t &ctx, Value *dest, const jl_cgval_t &src ctx.builder.CreateStore(UndefValue::get(ai->getAllocatedType()), ai); if (jl_is_concrete_type(src.typ) || src.constant) { jl_value_t *typ = src.constant ? jl_typeof(src.constant) : src.typ; - Type *store_ty = julia_type_to_llvm(typ); + Type *store_ty = julia_type_to_llvm(ctx, typ); assert(skip || jl_justbits(typ)); if (jl_justbits(typ)) { if (!src.ispointer() || src.constant) { @@ -2364,7 +2377,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg size_t nf = jl_datatype_nfields(sty); if (nf > 0 || sty->mutabl) { if (jl_justbits(ty)) { - Type *lt = julia_type_to_llvm(ty); + Type *lt = julia_type_to_llvm(ctx, ty); unsigned na = nargs < nf ? nargs : nf; // whether we should perform the initialization with the struct as a IR value @@ -2389,7 +2402,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg emit_typecheck(ctx, fval_info, jtype, "new"); if (type_is_ghost(lt)) continue; - Type *fty = julia_type_to_llvm(jtype); + Type *fty = julia_type_to_llvm(ctx, jtype); if (type_is_ghost(fty)) continue; Value *dest = NULL; @@ -2485,7 +2498,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg if (jl_datatype_nbits(sty) == 0) return ghostValue(sty); bool isboxed; - Type *lt = julia_type_to_llvm(ty, &isboxed); + Type *lt = julia_type_to_llvm(ctx, ty, &isboxed); assert(!isboxed); return mark_julia_type(ctx, UndefValue::get(lt), false, ty); } diff --git a/src/codegen.cpp b/src/codegen.cpp index b3474c4e8353a..8ac1a994b286e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -247,9 +247,6 @@ static DISubroutineType *jl_di_func_null_sig; // constants static Constant *V_null; -extern "C" { -JL_DLLEXPORT Type *julia_type_to_llvm(jl_value_t *jt, bool *isboxed=NULL); -} static bool type_is_ghost(Type *ty) { return (ty == T_void || ty->isEmptyTy()); @@ -499,8 +496,6 @@ typedef struct { jl_value_t *ty; } jl_arrayvar_t; -static jl_returninfo_t get_specsig_function(Module *M, StringRef name, jl_value_t *sig, jl_value_t *jlrettype); - // information about the context of a piece of code: its enclosing // function and module, and visible local variables and labels. class jl_codectx_t { @@ -555,6 +550,8 @@ class jl_codectx_t { } }; +static Type *julia_type_to_llvm(jl_codectx_t &ctx, jl_value_t *jt, bool *isboxed = NULL); +static jl_returninfo_t get_specsig_function(jl_codectx_t &ctx, Module *M, StringRef name, jl_value_t *sig, jl_value_t *jlrettype); static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr); static Value *global_binding_pointer(jl_codectx_t &ctx, jl_module_t *m, jl_sym_t *s, jl_binding_t **pbnd, bool assign); @@ -623,9 +620,8 @@ static inline jl_cgval_t mark_julia_const(jl_value_t *jv) } else { typ = jl_typeof(jv); - if (type_is_ghost(julia_type_to_llvm(typ))) { + if (jl_is_datatype_singleton((jl_datatype_t*)typ)) return ghostValue(typ); - } } jl_cgval_t constant(NULL, NULL, true, typ, NULL); constant.constant = jv; @@ -656,7 +652,7 @@ static inline jl_cgval_t mark_julia_type(jl_codectx_t &ctx, Value *v, bool isbox return ghostValue(typ); } } - Type *T = julia_type_to_llvm(typ); + Type *T = julia_type_to_llvm(ctx, typ); if (type_is_ghost(T)) { return ghostValue(typ); } @@ -717,7 +713,7 @@ static inline jl_cgval_t update_julia_type(jl_codectx_t &ctx, const jl_cgval_t & if (!jl_is_concrete_type(typ)) return v; // not generally worth trying to change type info (which would require recomputing tindex) } - Type *T = julia_type_to_llvm(typ); + Type *T = julia_type_to_llvm(ctx, typ); if (type_is_ghost(T)) return ghostValue(typ); return jl_cgval_t(v, typ, NULL); @@ -983,7 +979,7 @@ static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_ return ghostValue(typ); // normalize TypeofBottom to Type{Union{}} if (v.typ == typ || v.typ == jl_bottom_type || jl_egal(v.typ, typ)) return v; // fast-path - Type *T = julia_type_to_llvm(typ); + Type *T = julia_type_to_llvm(ctx, typ); if (type_is_ghost(T)) return ghostValue(typ); Value *new_tindex = NULL; @@ -1637,7 +1633,7 @@ static Value *emit_bitsunion_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1, static Value *emit_bits_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgval_t &arg2) { bool isboxed; - Type *at = julia_type_to_llvm(arg1.typ, &isboxed); + Type *at = julia_type_to_llvm(ctx, arg1.typ, &isboxed); assert(jl_is_datatype(arg1.typ) && arg1.typ == arg2.typ && !isboxed); if (type_is_ghost(at)) @@ -1689,7 +1685,7 @@ static Value *emit_bits_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1, const Value *answer = ConstantInt::get(T_int1, 1); for (size_t i = 0, l = jl_svec_len(types); i < l; i++) { jl_value_t *fldty = jl_svecref(types, i); - if (type_is_ghost(julia_type_to_llvm(fldty))) + if (type_is_ghost(julia_type_to_llvm(ctx, fldty))) continue; unsigned byte_offset = jl_field_offset(sty, i); Value *subAns, *fld1, *fld2; @@ -2442,7 +2438,7 @@ static jl_cgval_t emit_call_specsig_object(jl_codectx_t &ctx, jl_method_instance { // emit specialized call site jl_value_t *jlretty = li->rettype; - jl_returninfo_t returninfo = get_specsig_function(jl_Module, specFunctionObject, li->specTypes, jlretty); + jl_returninfo_t returninfo = get_specsig_function(ctx, jl_Module, specFunctionObject, li->specTypes, jlretty); FunctionType *cft = returninfo.decl->getFunctionType(); *cc = returninfo.cc; @@ -2472,7 +2468,7 @@ static jl_cgval_t emit_call_specsig_object(jl_codectx_t &ctx, jl_method_instance for (size_t i = 0; i < nargs; i++) { jl_value_t *jt = jl_nth_slot_type(li->specTypes, i); bool isboxed; - Type *et = julia_type_to_llvm(jt, &isboxed); + Type *et = julia_type_to_llvm(ctx, jt, &isboxed); if (type_is_ghost(et)) continue; assert(idx < nfargs); @@ -3006,7 +3002,7 @@ static void emit_vi_assignment_unboxed(jl_codectx_t &ctx, jl_varinfo_t &vi, Valu Value *dest = vi.value.V; if (vi.pTIndex) ctx.builder.CreateStore(UndefValue::get(cast(vi.value.V)->getAllocatedType()), vi.value.V); - Type *store_ty = julia_type_to_llvm(rval_info.constant ? jl_typeof(rval_info.constant) : rval_info.typ); + Type *store_ty = julia_type_to_llvm(ctx, rval_info.constant ? jl_typeof(rval_info.constant) : rval_info.typ); Type *dest_ty = store_ty->getPointerTo(); if (dest_ty != dest->getType()) dest = emit_bitcast(ctx, dest, dest_ty); @@ -3100,7 +3096,7 @@ static void emit_assignment(jl_codectx_t &ctx, jl_value_t *l, jl_value_t *r) } else { bool isboxed; - Type *vtype = julia_type_to_llvm(slot.typ, &isboxed); + Type *vtype = julia_type_to_llvm(ctx, slot.typ, &isboxed); assert(!isboxed); dest = emit_static_alloca(ctx, vtype); emit_unbox(ctx, vtype, slot, slot.typ, dest); @@ -3605,7 +3601,7 @@ static void emit_cfunc_invalidate( for (size_t i = 0; i < nargs; i++) { jl_value_t *jt = jl_nth_slot_type(calltype, i); bool isboxed; - Type *et = julia_type_to_llvm(jt, &isboxed); + Type *et = julia_type_to_llvm(ctx, jt, &isboxed); if (type_is_ghost(et)) { assert(jl_is_datatype(jt) && ((jl_datatype_t*)jt)->instance); myargs[i] = mark_julia_const(((jl_datatype_t*)jt)->instance); @@ -3680,14 +3676,14 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t { // Generate a c-callable wrapper bool toboxed; - Type *crt = julia_struct_to_llvm(jlrettype, NULL, &toboxed); + Type *crt = _julia_struct_to_llvm(¶ms, jlrettype, NULL, &toboxed); if (crt == NULL) jl_error("cfunction: return type doesn't correspond to a C type"); else if (toboxed) crt = T_prjlvalue; size_t nargs = jl_nparams(argt); - function_sig_t sig(crt, jlrettype, toboxed, argt->parameters, NULL, nargs, false, CallingConv::C, false); + function_sig_t sig(crt, jlrettype, toboxed, argt->parameters, NULL, nargs, false, CallingConv::C, false, ¶ms); if (!sig.err_msg.empty()) jl_error(sig.err_msg.c_str()); if (sig.fargt.size() + sig.sret != sig.fargt_sig.size()) @@ -3807,7 +3803,7 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t } else { bool isboxed; - Type *T = julia_type_to_llvm(jargty, &isboxed); + Type *T = julia_type_to_llvm(ctx, jargty, &isboxed); assert(!isboxed); // a T* (of unknown origin) if (type_is_ghost(T)) { @@ -3822,7 +3818,7 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t } else { bool argboxed; - (void)julia_struct_to_llvm(jargty, NULL, &argboxed); + (void)julia_struct_to_llvm(ctx, jargty, NULL, &argboxed); if (argboxed) { // a jl_value_t*, even when represented as a struct inputarg = mark_julia_type(ctx, val, true, jargty); @@ -3839,7 +3835,7 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t val = llvm_type_rewrite(ctx, val, sig.fargt[i], issigned); } bool isboxed; - (void)julia_type_to_llvm(jargty, &isboxed); + (void)julia_type_to_llvm(ctx, jargty, &isboxed); if (isboxed) { // passed an unboxed T, but want something boxed Value *mem = emit_allocobj(ctx, jl_datatype_size(jargty), @@ -3870,7 +3866,7 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t else if (lam && !decls.specFunctionObject.empty()) { // emit a specsig call StringRef protoname = decls.specFunctionObject; - jl_returninfo_t returninfo = get_specsig_function(M, protoname, lam->specTypes, lam->rettype); + jl_returninfo_t returninfo = get_specsig_function(ctx, M, protoname, lam->specTypes, lam->rettype); FunctionType *cft = returninfo.decl->getFunctionType(); jlfunc_sret = (returninfo.cc == jl_returninfo_t::SRet); @@ -3890,7 +3886,7 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t Value *arg; jl_value_t *spect = jl_nth_slot_type(lam->specTypes, i); bool isboxed; - Type *T = julia_type_to_llvm(spect, &isboxed); + Type *T = julia_type_to_llvm(ctx, spect, &isboxed); if (isboxed) { arg = boxed(ctx, inputarg); } @@ -4180,7 +4176,7 @@ static Function *gen_jlcall_wrapper(jl_method_instance_t *lam, const jl_returnin for (size_t i = 0; i < jl_nparams(lam->specTypes) && idx < nfargs; ++i) { jl_value_t *ty = jl_nth_slot_type(lam->specTypes, i); bool isboxed; - Type *lty = julia_type_to_llvm(ty, &isboxed); + Type *lty = julia_type_to_llvm(ctx, ty, &isboxed); if (lty != NULL && type_is_ghost(lty)) continue; Value *theArg; @@ -4233,7 +4229,7 @@ static Function *gen_jlcall_wrapper(jl_method_instance_t *lam, const jl_returnin return w; } -static jl_returninfo_t get_specsig_function(Module *M, StringRef name, jl_value_t *sig, jl_value_t *jlrettype) +static jl_returninfo_t get_specsig_function(jl_codectx_t &ctx, Module *M, StringRef name, jl_value_t *sig, jl_value_t *jlrettype) { jl_returninfo_t props = {}; SmallVector fsig; @@ -4262,7 +4258,7 @@ static jl_returninfo_t get_specsig_function(Module *M, StringRef name, jl_value_ } else { bool retboxed; - rt = julia_type_to_llvm(jlrettype, &retboxed); + rt = julia_type_to_llvm(ctx, jlrettype, &retboxed); if (!retboxed) { if (rt != T_void && deserves_sret(jlrettype, rt)) { props.cc = jl_returninfo_t::SRet; @@ -4293,7 +4289,7 @@ static jl_returninfo_t get_specsig_function(Module *M, StringRef name, jl_value_ for (size_t i = 0; i < jl_nparams(sig); i++) { jl_value_t *jt = jl_tparam(sig, i); bool isboxed; - Type *ty = julia_type_to_llvm(jt, &isboxed); + Type *ty = julia_type_to_llvm(ctx, jt, &isboxed); if (type_is_ghost(ty)) continue; if (ty->isAggregateType()) { // aggregate types are passed by pointer @@ -4321,20 +4317,14 @@ static jl_returninfo_t get_specsig_function(Module *M, StringRef name, jl_value_ } static DISubroutineType * -get_specsig_di(jl_value_t *rt, jl_value_t *sig, DIFile *topfile, DIBuilder &dbuilder) +get_specsig_di(jl_codectx_t &ctx, jl_value_t *rt, jl_value_t *sig, DIBuilder &dbuilder) { - std::vector ditypes(0); - Type *ty = julia_type_to_llvm(rt); - if (type_is_ghost(ty)) - ditypes.push_back(nullptr); - else - ditypes.push_back(julia_type_to_di(rt, &dbuilder, false)); - for (size_t i = 0; i < jl_nparams(sig); i++) { + size_t nargs = jl_nparams(sig); // TODO: if this is a Varargs function, our debug info for the `...` var may be misleading + std::vector ditypes(nargs + 1); + ditypes[0] = julia_type_to_di(ctx, rt, &dbuilder, false); + for (size_t i = 0; i < nargs; i++) { jl_value_t *jt = jl_tparam(sig, i); - Type *ty = julia_type_to_llvm(jt); - if (type_is_ghost(ty)) - continue; - ditypes.push_back(julia_type_to_di(jt, &dbuilder, false)); + ditypes[i + 1] = julia_type_to_di(ctx, jt, &dbuilder, false); } return dbuilder.createSubroutineType(dbuilder.getOrCreateTypeArray(ditypes)); } @@ -4509,7 +4499,7 @@ static std::pair, jl_llvm_functions_t> std::stringstream specName; specName << "julia_" << unadorned_name << "_" << globalUnique; declarations.specFunctionObject = specName.str(); - returninfo = get_specsig_function(M, declarations.specFunctionObject, lam->specTypes, jlrettype); + returninfo = get_specsig_function(ctx, M, declarations.specFunctionObject, lam->specTypes, jlrettype); f = returninfo.decl; ctx.has_sret = (returninfo.cc == jl_returninfo_t::SRet || returninfo.cc == jl_returninfo_t::Union); gen_jlcall_wrapper(lam, returninfo, declarations.functionObject, M, ctx.emission_context); @@ -4586,7 +4576,7 @@ static std::pair, jl_llvm_functions_t> subrty = jl_di_func_sig; } else { - subrty = get_specsig_di(lam->rettype, lam->specTypes, topfile, dbuilder); + subrty = get_specsig_di(ctx, lam->rettype, lam->specTypes, dbuilder); } SP = dbuilder.createFunction(CU, dbgFuncName, // Name @@ -4617,7 +4607,7 @@ static std::pair, jl_llvm_functions_t> topfile, // File toplineno == -1 ? 0 : toplineno, // Line // Variable type - julia_type_to_di(varinfo.value.typ, &dbuilder, false), + julia_type_to_di(ctx, varinfo.value.typ, &dbuilder, false), AlwaysPreserve, // May be deleted if optimized out DIFlagZero); // Flags (TODO: Do we need any) } @@ -4628,7 +4618,7 @@ static std::pair, jl_llvm_functions_t> ctx.has_sret + nreq + 1, // Argument number (1-based) topfile, // File toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function) - julia_type_to_di(ctx.slots[ctx.vaSlot].value.typ, &dbuilder, false), + julia_type_to_di(ctx, ctx.slots[ctx.vaSlot].value.typ, &dbuilder, false), AlwaysPreserve, // May be deleted if optimized out DIFlagZero); // Flags (TODO: Do we need any) } @@ -4643,7 +4633,7 @@ static std::pair, jl_llvm_functions_t> jl_symbol_name(s), // Variable name topfile, // File toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function) - julia_type_to_di(varinfo.value.typ, &dbuilder, false), // Variable type + julia_type_to_di(ctx, varinfo.value.typ, &dbuilder, false), // Variable type AlwaysPreserve, // May be deleted if optimized out DIFlagZero // Flags (TODO: Do we need any) ); @@ -4747,7 +4737,7 @@ static std::pair, jl_llvm_functions_t> } else if (jl_justbits(jt)) { bool isboxed; - Type *vtype = julia_type_to_llvm(jt, &isboxed); + Type *vtype = julia_type_to_llvm(ctx, jt, &isboxed); assert(!isboxed); assert(!type_is_ghost(vtype) && "constants should already be handled"); // CreateAlloca is OK during prologue setup @@ -4826,7 +4816,7 @@ static std::pair, jl_llvm_functions_t> jl_sym_t *s = (jl_sym_t*)jl_array_ptr_ref(src->slotnames, i); jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i); bool isboxed; - Type *llvmArgType = julia_type_to_llvm(argType, &isboxed); + Type *llvmArgType = julia_type_to_llvm(ctx, argType, &isboxed); if (s == unused_sym) { if (specsig && !type_is_ghost(llvmArgType)) ++AI; @@ -4913,7 +4903,7 @@ static std::pair, jl_llvm_functions_t> for (size_t i = nreq; i < jl_nparams(lam->specTypes); ++i) { jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i); bool isboxed; - Type *llvmArgType = julia_type_to_llvm(argType, &isboxed); + Type *llvmArgType = julia_type_to_llvm(ctx, argType, &isboxed); vargs[i - nreq] = get_specsig_arg(argType, llvmArgType, isboxed); } jl_cgval_t tuple = emit_new_struct(ctx, vi.value.typ, nvargs, vargs); @@ -5257,7 +5247,7 @@ static std::pair, jl_llvm_functions_t> } } else { - Type *store_ty = julia_type_to_llvm(retvalinfo.typ); + Type *store_ty = julia_type_to_llvm(ctx, retvalinfo.typ); Type *dest_ty = store_ty->getPointerTo(); if (dest_ty != sret->getType()) sret = emit_bitcast(ctx, sret, dest_ty); @@ -5684,7 +5674,7 @@ static void init_julia_llvm_env(Module *m) // add needed base debugging definitions to our LLVM environment DIBuilder dbuilder(*m); - DIFile *julia_h = dbuilder.createFile("julia.h",""); + DIFile *julia_h = dbuilder.createFile("julia.h", ""); jl_value_dillvmt = dbuilder.createStructType(nullptr, "jl_value_t", julia_h, @@ -5704,14 +5694,14 @@ static void init_julia_llvm_env(Module *m) dbuilder.replaceArrays(jl_value_dillvmt, dbuilder.getOrCreateArray(Elts)); - jl_ppvalue_dillvmt = dbuilder.createPointerType(jl_pvalue_dillvmt,sizeof(jl_value_t**)*8, - __alignof__(jl_value_t**)*8); + jl_ppvalue_dillvmt = dbuilder.createPointerType(jl_pvalue_dillvmt, sizeof(jl_value_t**) * 8, + __alignof__(jl_value_t**) * 8); diargs.push_back(jl_pvalue_dillvmt); // Return Type (ret value) diargs.push_back(jl_pvalue_dillvmt); // First Argument (function) diargs.push_back(jl_ppvalue_dillvmt); // Second Argument (argv) // Third argument (length(argv)) - diargs.push_back(julia_type_to_di((jl_value_t*)jl_int32_type,&dbuilder,false)); + diargs.push_back(_julia_type_to_di(NULL, (jl_value_t*)jl_int32_type, &dbuilder, false)); jl_di_func_sig = dbuilder.createSubroutineType( dbuilder.getOrCreateTypeArray(diargs)); diff --git a/src/datatype.c b/src/datatype.c index 2b8b25cd18812..0c27db36818f7 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -464,8 +464,6 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype( t->mutabl = mutabl; t->ninitialized = ninitialized; t->instance = NULL; - t->struct_decl = NULL; - t->ditype = NULL; t->size = 0; if (tn == NULL) { diff --git a/src/dump.c b/src/dump.c index eee23f0f868a8..89d9e78669d75 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1195,9 +1195,7 @@ static jl_value_t *jl_deserialize_datatype(jl_serializer_state *s, int pos, jl_v assert(pos == backref_list.len - 1 && "nothing should have been deserialized since assigning pos"); backref_list.items[pos] = dt; dt->size = size; - dt->struct_decl = NULL; dt->instance = NULL; - dt->ditype = NULL; dt->abstract = flags & 1; dt->mutabl = (flags >> 1) & 1; int has_layout = (flags >> 2) & 1; diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index ecbf1fb53aa39..5cae20ce034a7 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -146,7 +146,7 @@ static Value *uint_cnvt(jl_codectx_t &ctx, Type *to, Value *x) return ctx.builder.CreateZExt(x, to); } -static Constant *julia_const_to_llvm(const void *ptr, jl_datatype_t *bt) +static Constant *julia_const_to_llvm(jl_codectx_t &ctx, const void *ptr, jl_datatype_t *bt) { // assumes `jl_justbits(bt)`. // `ptr` can point to a inline field, do not read the tag from it. @@ -158,7 +158,7 @@ static Constant *julia_const_to_llvm(const void *ptr, jl_datatype_t *bt) if (jl_is_vecelement_type((jl_value_t*)bt)) bt = (jl_datatype_t*)jl_tparam0(bt); - Type *lt = julia_struct_to_llvm((jl_value_t*)bt, NULL, NULL); + Type *lt = julia_struct_to_llvm(ctx, (jl_value_t*)bt, NULL, NULL); if (type_is_ghost(lt)) return UndefValue::get(lt); @@ -194,7 +194,7 @@ static Constant *julia_const_to_llvm(const void *ptr, jl_datatype_t *bt) size_t offs = jl_field_offset(bt, i); assert(!jl_field_isptr(bt, i)); jl_value_t *ft = jl_field_type(bt, i); - Type *lft = julia_type_to_llvm(ft); + Type *lft = julia_type_to_llvm(ctx, ft); if (type_is_ghost(lft)) continue; unsigned llvm_idx = isa(lt) ? convert_struct_offset(lt, offs) : i; @@ -249,7 +249,7 @@ static Constant *julia_const_to_llvm(const void *ptr, jl_datatype_t *bt) fields.push_back(ConstantInt::get(T_int8, sel)); } else { - Constant *val = julia_const_to_llvm(ov, (jl_datatype_t*)ft); + Constant *val = julia_const_to_llvm(ctx, ov, (jl_datatype_t*)ft); fields.push_back(val); } } @@ -262,7 +262,7 @@ static Constant *julia_const_to_llvm(const void *ptr, jl_datatype_t *bt) return ConstantArray::get(at, fields); } -static Constant *julia_const_to_llvm(jl_value_t *e) +static Constant *julia_const_to_llvm(jl_codectx_t &ctx, jl_value_t *e) { if (e == jl_true) return ConstantInt::get(T_int8, 1); @@ -271,7 +271,7 @@ static Constant *julia_const_to_llvm(jl_value_t *e) jl_value_t *bt = jl_typeof(e); if (!jl_justbits(bt)) return NULL; - return julia_const_to_llvm(e, (jl_datatype_t*)bt); + return julia_const_to_llvm(ctx, e, (jl_datatype_t*)bt); } static jl_cgval_t ghostValue(jl_value_t *ty); @@ -332,7 +332,7 @@ static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_va return UndefValue::get(to); // type mismatch error } - Constant *c = x.constant ? julia_const_to_llvm(x.constant) : NULL; + Constant *c = x.constant ? julia_const_to_llvm(ctx, x.constant) : NULL; if (!x.ispointer() || c) { // already unboxed, but sometimes need conversion Value *unboxed = emit_unboxed_coercion(ctx, to, c ? c : x.V); if (!dest) @@ -438,7 +438,7 @@ static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv) // Examine the second argument // bool isboxed; - Type *vxt = julia_type_to_llvm(v.typ, &isboxed); + Type *vxt = julia_type_to_llvm(ctx, v.typ, &isboxed); if (!jl_is_primitivetype(v.typ) || jl_datatype_size(v.typ) != nb) { Value *typ = emit_typeof_boxed(ctx, v); @@ -471,7 +471,7 @@ static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv) if (!v.ispointer()) vx = v.V; else if (v.constant) - vx = julia_const_to_llvm(v.constant); + vx = julia_const_to_llvm(ctx, v.constant); if (v.ispointer() && vx == NULL) { // try to load as original Type, to preserve llvm optimizations @@ -645,7 +645,7 @@ static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv) } else { bool isboxed; - Type *ptrty = julia_type_to_llvm(ety, &isboxed); + Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed); assert(!isboxed); Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ); return typed_load(ctx, thePtr, im1, ety, tbaa_data, true, align_nb); @@ -708,7 +708,7 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv) } else { bool isboxed; - Type *ptrty = julia_type_to_llvm(ety, &isboxed); + Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed); assert(!isboxed); thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ); typed_store(ctx, thePtr, im1, x, ety, tbaa_data, NULL, align_nb); @@ -840,7 +840,7 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar Value *ifelse_result; bool isboxed; - Type *llt1 = julia_type_to_llvm(t1, &isboxed); + Type *llt1 = julia_type_to_llvm(ctx, t1, &isboxed); if (t1 != t2) isboxed = true; if (!isboxed) { @@ -1026,7 +1026,7 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg *newtyp = tuptyp; Value *tupval; - tupval = UndefValue::get(julia_type_to_llvm((jl_value_t*)tuptyp)); + tupval = UndefValue::get(julia_type_to_llvm(ctx, (jl_value_t*)tuptyp)); tupval = ctx.builder.CreateInsertValue(tupval, val, ArrayRef(0)); tupval = ctx.builder.CreateInsertValue(tupval, obyte, ArrayRef(1)); return tupval; diff --git a/src/jitlayers.h b/src/jitlayers.h index 49cba6746a01f..fc058a098d1ab 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -65,7 +65,9 @@ typedef std::tuple, jl_llvm_functions_t, jl_value_t*, ui typedef struct { // outputs jl_codegen_call_targets_t workqueue; - std::map globals; + std::map globals; + std::map ditypes; + std::map llvmtypes; // inputs size_t world = 0; const jl_cgparams_t *params = &jl_default_cgparams; diff --git a/src/jltypes.c b/src/jltypes.c index 7bc2b86804245..01e2e32610d34 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -1239,8 +1239,6 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value ndt->abstract = dt->abstract; ndt->instance = NULL; ndt->uid = 0; - ndt->struct_decl = NULL; - ndt->ditype = NULL; ndt->size = 0; jl_precompute_memoized_dt(ndt); @@ -1669,7 +1667,7 @@ void jl_init_types(void) jl_datatype_type->name->wrapper = (jl_value_t*)jl_datatype_type; jl_datatype_type->super = (jl_datatype_t*)jl_type_type; jl_datatype_type->parameters = jl_emptysvec; - jl_datatype_type->name->names = jl_perm_symsvec(20, + jl_datatype_type->name->names = jl_perm_symsvec(18, "name", "super", "parameters", @@ -1687,26 +1685,22 @@ void jl_init_types(void) "isdispatchtuple", "isbitstype", "zeroinit", - "isinlinealloc", - "llvm::StructType", - "llvm::DIType"); - jl_datatype_type->types = jl_svec(20, - jl_typename_type, - jl_datatype_type, - jl_simplevector_type, - jl_simplevector_type, jl_simplevector_type, + "isinlinealloc"); + jl_datatype_type->types = jl_svec(18, + jl_typename_type, // name + jl_datatype_type, // super + jl_simplevector_type, // parameters + jl_simplevector_type, // types + jl_simplevector_type, // named-tuple jl_any_type, // instance + jl_any_type, jl_any_type, jl_any_type, jl_any_type, // properties jl_any_type, jl_any_type, jl_any_type, jl_any_type, - jl_any_type, jl_any_type, jl_any_type, jl_any_type, - jl_any_type, jl_any_type, jl_any_type, jl_any_type, - jl_any_type, jl_any_type); + jl_any_type, jl_any_type, jl_any_type, jl_any_type); jl_datatype_type->instance = NULL; jl_datatype_type->uid = jl_assign_type_uid(); - jl_datatype_type->struct_decl = NULL; - jl_datatype_type->ditype = NULL; jl_datatype_type->abstract = 0; - // NOTE: types should not really be mutable, but the instance and - // struct_decl fields are basically caches, which are mutated. + // NOTE: types are not actually mutable, but we want to ensure they are heap-allocated with stable addresses + // also, the `uid` field gets reset after loading a .ji precompile file jl_datatype_type->mutabl = 1; jl_datatype_type->ninitialized = 4; jl_precompute_memoized_dt(jl_datatype_type); @@ -1725,8 +1719,6 @@ void jl_init_types(void) jl_any_type, jl_any_type); jl_typename_type->uid = jl_assign_type_uid(); jl_typename_type->instance = NULL; - jl_typename_type->struct_decl = NULL; - jl_typename_type->ditype = NULL; jl_typename_type->abstract = 0; jl_typename_type->mutabl = 1; jl_typename_type->ninitialized = 2; @@ -1746,8 +1738,6 @@ void jl_init_types(void) jl_any_type/*any vector*/, jl_any_type/*long*/, jl_any_type/*int32*/); jl_methtable_type->uid = jl_assign_type_uid(); jl_methtable_type->instance = NULL; - jl_methtable_type->struct_decl = NULL; - jl_methtable_type->ditype = NULL; jl_methtable_type->abstract = 0; jl_methtable_type->mutabl = 1; jl_methtable_type->ninitialized = 4; @@ -1762,8 +1752,6 @@ void jl_init_types(void) jl_sym_type->types = jl_emptysvec; jl_sym_type->instance = NULL; jl_sym_type->uid = jl_assign_type_uid(); - jl_sym_type->struct_decl = NULL; - jl_sym_type->ditype = NULL; jl_sym_type->size = 0; jl_sym_type->abstract = 0; jl_sym_type->mutabl = 1; @@ -1779,8 +1767,6 @@ void jl_init_types(void) jl_simplevector_type->types = jl_emptysvec; jl_simplevector_type->uid = jl_assign_type_uid(); jl_simplevector_type->instance = NULL; - jl_simplevector_type->struct_decl = NULL; - jl_simplevector_type->ditype = NULL; jl_simplevector_type->abstract = 0; jl_simplevector_type->mutabl = 1; jl_simplevector_type->ninitialized = 0; @@ -2166,8 +2152,6 @@ void jl_init_types(void) jl_svecset(jl_datatype_type->types, 15, jl_bool_type); jl_svecset(jl_datatype_type->types, 16, jl_bool_type); jl_svecset(jl_datatype_type->types, 17, jl_bool_type); - jl_svecset(jl_datatype_type->types, 18, jl_voidpointer_type); - jl_svecset(jl_datatype_type->types, 19, jl_voidpointer_type); jl_svecset(jl_typename_type->types, 1, jl_module_type); jl_svecset(jl_typename_type->types, 6, jl_long_type); jl_svecset(jl_typename_type->types, 3, jl_type_type); diff --git a/src/julia.h b/src/julia.h index 4f82490f0fc0e..fe21710ae37d3 100644 --- a/src/julia.h +++ b/src/julia.h @@ -402,8 +402,6 @@ typedef struct _jl_datatype_t { uint8_t isbitstype; // relevant query for C-api and type-parameters uint8_t zeroinit; // if one or more fields requires zero-initialization uint8_t isinlinealloc; // if this is allocated inline - void *struct_decl; //llvm::Type* - void *ditype; // llvm::MDNode* to be used as llvm::DIType(ditype) } jl_datatype_t; typedef struct { diff --git a/src/staticdata.c b/src/staticdata.c index 080fd72ca30e6..6ea2ab398746e 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -683,8 +683,6 @@ static void jl_write_values(jl_serializer_state *s) else if (jl_is_datatype(v)) { jl_datatype_t *dt = (jl_datatype_t*)v; jl_datatype_t *newdt = (jl_datatype_t*)&s->s->buf[reloc_offset]; - newdt->struct_decl = NULL; - newdt->ditype = NULL; if (dt->layout != NULL) { size_t nf = dt->layout->nfields; size_t fieldsize = jl_fielddesc_size(dt->layout->fielddesc_type);