From 1eb063f1957b2e287ad0c7435debc72af58bb6f1 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sat, 10 Jul 2021 14:29:16 +0200 Subject: [PATCH] Pass LLVMContext through ABI --- src/abi_aarch64.cpp | 56 ++++++++++++++++++++++----------------------- src/abi_arm.cpp | 50 ++++++++++++++++++++-------------------- src/abi_llvm.cpp | 6 ++--- src/abi_ppc64le.cpp | 11 +++++---- src/abi_win32.cpp | 8 +++---- src/abi_win64.cpp | 8 +++---- src/abi_x86.cpp | 6 ++--- src/abi_x86_64.cpp | 24 +++++++++---------- src/ccall.cpp | 18 +++++++-------- 9 files changed, 93 insertions(+), 94 deletions(-) diff --git a/src/abi_aarch64.cpp b/src/abi_aarch64.cpp index 3a0a5c25dc859..3e6b995f07b1e 100644 --- a/src/abi_aarch64.cpp +++ b/src/abi_aarch64.cpp @@ -13,7 +13,7 @@ struct ABI_AArch64Layout : AbiLayout { -Type *get_llvm_vectype(jl_datatype_t *dt) const +Type *get_llvm_vectype(jl_datatype_t *dt, LLVMContext &ctx) const { // Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt) // `!dt->name->mutabl && dt->pointerfree && !dt->haspadding && dt->nfields > 0` @@ -23,18 +23,16 @@ Type *get_llvm_vectype(jl_datatype_t *dt) const assert(nfields > 0); if (nfields < 2) return nullptr; - static Type *T_vec64 = FixedVectorType::get(T_int32, 2); - static Type *T_vec128 = FixedVectorType::get(T_int32, 4); Type *lltype; // Short vector should be either 8 bytes or 16 bytes. // Note that there are only two distinct fundamental types for // short vectors so we normalize them to <2 x i32> and <4 x i32> switch (jl_datatype_size(dt)) { case 8: - lltype = T_vec64; + lltype = FixedVectorType::get(Type::getInt32Ty(ctx), 2); break; case 16: - lltype = T_vec128; + lltype = FixedVectorType::get(Type::getInt32Ty(ctx), 4); break; default: return nullptr; @@ -59,7 +57,7 @@ Type *get_llvm_vectype(jl_datatype_t *dt) const } #define jl_is_floattype(v) jl_subtype(v,(jl_value_t*)jl_floatingpoint_type) -Type *get_llvm_fptype(jl_datatype_t *dt) const +Type *get_llvm_fptype(jl_datatype_t *dt, LLVMContext &ctx) const { // Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt) // `!dt->name->mutabl && dt->pointerfree && !dt->haspadding && dt->nfields == 0` @@ -67,16 +65,16 @@ Type *get_llvm_fptype(jl_datatype_t *dt) const // Check size first since it's cheaper. switch (jl_datatype_size(dt)) { case 2: - lltype = T_float16; + lltype = Type::getHalfTy(ctx); break; case 4: - lltype = T_float32; + lltype = Type::getFloatTy(ctx); break; case 8: - lltype = T_float64; + lltype = Type::getDoubleTy(ctx); break; case 16: - lltype = T_float128; + lltype = Type::getFP128Ty(ctx); break; default: return nullptr; @@ -85,12 +83,12 @@ Type *get_llvm_fptype(jl_datatype_t *dt) const lltype : nullptr); } -Type *get_llvm_fp_or_vectype(jl_datatype_t *dt) const +Type *get_llvm_fp_or_vectype(jl_datatype_t *dt, LLVMContext &ctx) const { // Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt) if (dt->name->mutabl || dt->layout->npointers || dt->layout->haspadding) return nullptr; - return dt->layout->nfields ? get_llvm_vectype(dt) : get_llvm_fptype(dt); + return dt->layout->nfields ? get_llvm_vectype(dt, ctx) : get_llvm_fptype(dt, ctx); } struct ElementType { @@ -105,7 +103,7 @@ struct ElementType { // Data Types of the members that compose the type are the same. // Note that it is the fundamental types that are important and not the member // types. -bool isHFAorHVA(jl_datatype_t *dt, size_t dsz, size_t &nele, ElementType &ele) const +bool isHFAorHVA(jl_datatype_t *dt, size_t dsz, size_t &nele, ElementType &ele, LLVMContext &ctx) const { // Assume: // dt is a pointerfree type, (all members are isbits) @@ -133,7 +131,7 @@ bool isHFAorHVA(jl_datatype_t *dt, size_t dsz, size_t &nele, ElementType &ele) c dt = (jl_datatype_t*)jl_field_type(dt, i); continue; } - if (Type *vectype = get_llvm_vectype(dt)) { + if (Type *vectype = get_llvm_vectype(dt, ctx)) { if ((ele.sz && dsz != ele.sz) || (ele.type && ele.type != vectype)) return false; ele.type = vectype; @@ -149,7 +147,7 @@ bool isHFAorHVA(jl_datatype_t *dt, size_t dsz, size_t &nele, ElementType &ele) c jl_datatype_t *fieldtype = (jl_datatype_t*)jl_field_type(dt, i); // Check element count. // This needs to be done after the zero size member check - if (nele > 3 || !isHFAorHVA(fieldtype, fieldsz, nele, ele)) { + if (nele > 3 || !isHFAorHVA(fieldtype, fieldsz, nele, ele, ctx)) { return false; } } @@ -158,7 +156,7 @@ bool isHFAorHVA(jl_datatype_t *dt, size_t dsz, size_t &nele, ElementType &ele) c // For bitstypes if (ele.sz && dsz != ele.sz) return false; - Type *new_type = get_llvm_fptype(dt); + Type *new_type = get_llvm_fptype(dt, ctx); if (new_type && (!ele.type || ele.type == new_type)) { ele.type = new_type; ele.sz = dsz; @@ -168,7 +166,7 @@ bool isHFAorHVA(jl_datatype_t *dt, size_t dsz, size_t &nele, ElementType &ele) c return false; } -Type *isHFAorHVA(jl_datatype_t *dt, size_t &nele) const +Type *isHFAorHVA(jl_datatype_t *dt, size_t &nele, LLVMContext &ctx) const { // Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt) @@ -184,18 +182,18 @@ Type *isHFAorHVA(jl_datatype_t *dt, size_t &nele) const return NULL; nele = 0; ElementType eltype; - if (isHFAorHVA(dt, dsz, nele, eltype)) + if (isHFAorHVA(dt, dsz, nele, eltype, ctx)) return eltype.type; return NULL; } -bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override +bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override { // B.2 // If the argument type is an HFA or an HVA, then the argument is used // unmodified. size_t size; - if (isHFAorHVA(dt, size)) + if (isHFAorHVA(dt, size, ctx)) return false; // B.3 // If the argument type is a Composite Type that is larger than 16 bytes, @@ -222,7 +220,7 @@ bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override // // All the out parameters should be default to `false`. Type *classify_arg(jl_datatype_t *dt, bool *fpreg, bool *onstack, - size_t *rewrite_len) const + size_t *rewrite_len, LLVMContext &ctx) const { // Based on section 5.4 C of the Procedure Call Standard // C.1 @@ -231,7 +229,7 @@ Type *classify_arg(jl_datatype_t *dt, bool *fpreg, bool *onstack, // the argument is allocated to the least significant bits of register // v[NSRN]. The NSRN is incremented by one. The argument has now been // allocated. - if (get_llvm_fp_or_vectype(dt)) { + if (get_llvm_fp_or_vectype(dt, ctx)) { *fpreg = true; return NULL; } @@ -243,7 +241,7 @@ Type *classify_arg(jl_datatype_t *dt, bool *fpreg, bool *onstack, // Floating-point Registers (with one register per member of the HFA // or HVA). The NSRN is incremented by the number of registers used. // The argument has now been allocated. - if (Type *eltype = isHFAorHVA(dt, *rewrite_len)) { + if (Type *eltype = isHFAorHVA(dt, *rewrite_len, ctx)) { assert(*rewrite_len > 0 && *rewrite_len <= 4); // HFA and HVA have <= 4 members *fpreg = true; @@ -322,7 +320,7 @@ Type *classify_arg(jl_datatype_t *dt, bool *fpreg, bool *onstack, assert(jl_datatype_size(dt) <= 16); // Should be pass by reference otherwise *rewrite_len = (jl_datatype_size(dt) + 7) >> 3; // Rewrite to [n x Int64] where n is the **size in dword** - return jl_datatype_size(dt) ? T_int64 : NULL; + return jl_datatype_size(dt) ? Type::getInt64Ty(ctx) : NULL; // C.11 // The NGRN is set to 8. @@ -346,7 +344,7 @@ Type *classify_arg(jl_datatype_t *dt, bool *fpreg, bool *onstack, // } -bool use_sret(jl_datatype_t *dt) override +bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override { // Section 5.5 // If the type, T, of the result of a function is such that @@ -360,18 +358,18 @@ bool use_sret(jl_datatype_t *dt) override bool fpreg = false; bool onstack = false; size_t rewrite_len = 0; - classify_arg(dt, &fpreg, &onstack, &rewrite_len); + classify_arg(dt, &fpreg, &onstack, &rewrite_len, ctx); return onstack; } -Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override +Type *preferred_llvm_type(jl_datatype_t *dt, bool isret, LLVMContext &ctx) const override { - if (Type *fptype = get_llvm_fp_or_vectype(dt)) + if (Type *fptype = get_llvm_fp_or_vectype(dt, ctx)) return fptype; bool fpreg = false; bool onstack = false; size_t rewrite_len = 0; - if (Type *rewrite_ty = classify_arg(dt, &fpreg, &onstack, &rewrite_len)) + if (Type *rewrite_ty = classify_arg(dt, &fpreg, &onstack, &rewrite_len, ctx)) return ArrayType::get(rewrite_ty, rewrite_len); return NULL; } diff --git a/src/abi_arm.cpp b/src/abi_arm.cpp index b0ae29a623abb..032943abd45f0 100644 --- a/src/abi_arm.cpp +++ b/src/abi_arm.cpp @@ -23,14 +23,14 @@ struct ABI_ARMLayout : AbiLayout { -bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override +bool needPassByRef(jl_datatype_t *dt, AttrBuilder &abi, LLVMContext &ctx) override { return false; } #define jl_is_floattype(v) jl_subtype(v,(jl_value_t*)jl_floatingpoint_type) -Type *get_llvm_fptype(jl_datatype_t *dt) const +Type *get_llvm_fptype(jl_datatype_t *dt, LLVMContext &ctx) const { // Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt) if (dt->name->mutabl || jl_datatype_nfields(dt) != 0) @@ -39,13 +39,13 @@ Type *get_llvm_fptype(jl_datatype_t *dt) const // Check size first since it's cheaper. switch (jl_datatype_size(dt)) { case 2: - lltype = T_float16; + lltype = Type::getHalfTy(ctx); break; case 4: - lltype = T_float32; + lltype = Type::getFloatTy(ctx); break; case 8: - lltype = T_float64; + lltype = Type::getDoubleTy(ctx); break; default: return NULL; @@ -58,10 +58,10 @@ Type *get_llvm_fptype(jl_datatype_t *dt) const // fundamental type. // // Returns the corresponding LLVM type. -Type *isLegalHAType(jl_datatype_t *dt) const +Type *isLegalHAType(jl_datatype_t *dt, LLVMContext &ctx) const { // single- or double-precision floating-point type - if (Type *fp = get_llvm_fptype(dt)) + if (Type *fp = get_llvm_fptype(dt, ctx)) return fp; // NOT SUPPORTED: 64- or 128-bit containerized vectors @@ -74,7 +74,7 @@ Type *isLegalHAType(jl_datatype_t *dt) const // // Legality of the HA is determined by a nonzero return value. // In case of a non-legal HA, the value of 'base' is undefined. -size_t isLegalHA(jl_datatype_t *dt, Type *&base) const +size_t isLegalHA(jl_datatype_t *dt, Type *&base, LLVMContext &ctx) const { // Homogeneous aggregates are only used for VFP registers, // so use that definition of legality (section 6.1.2.1) @@ -92,10 +92,10 @@ size_t isLegalHA(jl_datatype_t *dt, Type *&base) const for (size_t i = 0; i < parent_members; ++i) { jl_datatype_t *fdt = (jl_datatype_t*)jl_field_type(dt,i); - Type *T = isLegalHAType(fdt); + Type *T = isLegalHAType(fdt, ctx); if (T) total_members++; - else if (size_t field_members = isLegalHA(fdt, T)) + else if (size_t field_members = isLegalHA(fdt, T, ctx)) // recursive application (expanding nested composite types) total_members += field_members; else @@ -120,7 +120,7 @@ size_t isLegalHA(jl_datatype_t *dt, Type *&base) const // Determine if an argument can be passed through a coprocessor register. // // All the out parameters should be default to `false`. -void classify_cprc(jl_datatype_t *dt, bool *vfp) const +void classify_cprc(jl_datatype_t *dt, bool *vfp, LLVMContext &ctx) const { // Based on section 6.1 of the Procedure Call Standard @@ -128,7 +128,7 @@ void classify_cprc(jl_datatype_t *dt, bool *vfp) const // - A half-precision floating-point type. // - A single-precision floating-point type. // - A double-precision floating-point type. - if (get_llvm_fptype(dt)) { + if (get_llvm_fptype(dt, ctx)) { *vfp = true; return; } @@ -137,14 +137,14 @@ void classify_cprc(jl_datatype_t *dt, bool *vfp) const // - A Homogeneous Aggregate Type *base = NULL; - if (isLegalHA(dt, base)) { + if (isLegalHA(dt, base, ctx)) { *vfp = true; return; } } -void classify_return_arg(jl_datatype_t *dt, bool *reg, - bool *onstack, bool *need_rewrite) const +void classify_return_arg(jl_datatype_t *dt, bool *reg, bool *onstack, + bool *need_rewrite, LLVMContext &ctx) const { // Based on section 5.4 of the Procedure Call Standard @@ -152,7 +152,7 @@ void classify_return_arg(jl_datatype_t *dt, bool *reg, // Any result whose type would satisfy the conditions for a VFP CPRC is // returned in the appropriate number of consecutive VFP registers // starting with the lowest numbered register (s0, d0, q0). - classify_cprc(dt, reg); + classify_cprc(dt, reg, ctx); if (*reg) return; @@ -196,12 +196,12 @@ void classify_return_arg(jl_datatype_t *dt, bool *reg, *onstack = true; } -bool use_sret(jl_datatype_t *dt) override +bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override { bool reg = false; bool onstack = false; bool need_rewrite = false; - classify_return_arg(dt, ®, &onstack, &need_rewrite); + classify_return_arg(dt, ®, &onstack, &need_rewrite, ctx); return onstack; } @@ -218,7 +218,7 @@ bool use_sret(jl_datatype_t *dt) override // // All the out parameters should be default to `false`. void classify_arg(jl_datatype_t *dt, bool *reg, - bool *onstack, bool *need_rewrite) const + bool *onstack, bool *need_rewrite, LLVMContext &ctx) const { // Based on section 5.5 of the Procedure Call Standard @@ -226,7 +226,7 @@ void classify_arg(jl_datatype_t *dt, bool *reg, // If the argument is a CPRC and there are sufficient unallocated // co-processor registers of the appropriate class, the argument is // allocated to co-processor registers. - classify_cprc(dt, reg); + classify_cprc(dt, reg, ctx); if (*reg) return; @@ -239,18 +239,18 @@ void classify_arg(jl_datatype_t *dt, bool *reg, *need_rewrite = true; } -Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override +Type *preferred_llvm_type(jl_datatype_t *dt, bool isret, LLVMContext &ctx) const override { - if (Type *fptype = get_llvm_fptype(dt)) + if (Type *fptype = get_llvm_fptype(dt, ctx)) return fptype; bool reg = false; bool onstack = false; bool need_rewrite = false; if (isret) - classify_return_arg(dt, ®, &onstack, &need_rewrite); + classify_return_arg(dt, ®, &onstack, &need_rewrite, ctx); else - classify_arg(dt, ®, &onstack, &need_rewrite); + classify_arg(dt, ®, &onstack, &need_rewrite, ctx); if (!need_rewrite) return NULL; @@ -276,7 +276,7 @@ Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override if (align > 8) align = 8; - Type *T = Type::getIntNTy(jl_LLVMContext, align*8); + Type *T = Type::getIntNTy(ctx, align*8); return ArrayType::get(T, (jl_datatype_size(dt) + align - 1) / align); } diff --git a/src/abi_llvm.cpp b/src/abi_llvm.cpp index 1ab30da1b2f75..f21edeadee03a 100644 --- a/src/abi_llvm.cpp +++ b/src/abi_llvm.cpp @@ -40,17 +40,17 @@ struct ABI_LLVMLayout : AbiLayout { -bool use_sret(jl_datatype_t *ty) override +bool use_sret(jl_datatype_t *ty, LLVMContext &ctx) override { return false; } -bool needPassByRef(jl_datatype_t *ty, AttrBuilder &ab) override +bool needPassByRef(jl_datatype_t *ty, AttrBuilder &ab, LLVMContext &ctx) override { return false; } -Type *preferred_llvm_type(jl_datatype_t *ty, bool isret) const override +Type *preferred_llvm_type(jl_datatype_t *ty, bool isret, LLVMContext &ctx) const override { return NULL; } diff --git a/src/abi_ppc64le.cpp b/src/abi_ppc64le.cpp index 1564b79ce2332..da1d8484a0823 100644 --- a/src/abi_ppc64le.cpp +++ b/src/abi_ppc64le.cpp @@ -92,7 +92,7 @@ unsigned isHFA(jl_datatype_t *ty, jl_datatype_t **ty0, bool *hva) const return n; } -bool use_sret(jl_datatype_t *dt) override +bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override { jl_datatype_t *ty0 = NULL; bool hva = false; @@ -101,7 +101,7 @@ bool use_sret(jl_datatype_t *dt) override return false; } -bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override +bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override { jl_datatype_t *ty0 = NULL; bool hva = false; @@ -112,7 +112,7 @@ bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override return false; } -Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override +Type *preferred_llvm_type(jl_datatype_t *dt, bool isret, LLVMContext &ctx) const override { // Arguments are either scalar or passed by value size_t size = jl_datatype_size(dt); @@ -142,14 +142,15 @@ Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override // the bitsize of the integer gives the desired alignment if (size > 8) { if (jl_datatype_align(dt) <= 8) { + Type *T_int64 = Type::getInt64Ty(ctx); return ArrayType::get(T_int64, (size + 7) / 8); } else { - Type *T_int128 = Type::getIntNTy(jl_LLVMContext, 128); + Type *T_int128 = Type::getIntNTy(ctx, 128); return ArrayType::get(T_int128, (size + 15) / 16); } } - return Type::getIntNTy(jl_LLVMContext, size * 8); + return Type::getIntNTy(ctx, size * 8); } }; diff --git a/src/abi_win32.cpp b/src/abi_win32.cpp index af16a0310b124..a25fcaec9b82a 100644 --- a/src/abi_win32.cpp +++ b/src/abi_win32.cpp @@ -39,7 +39,7 @@ struct ABI_Win32Layout : AbiLayout { -bool use_sret(jl_datatype_t *dt) override +bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override { // Use sret if the size of the argument is not one of 1, 2, 4, 8 bytes // This covers the special case of ComplexF32 @@ -49,7 +49,7 @@ bool use_sret(jl_datatype_t *dt) override return true; } -bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override +bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override { // Use pass by reference for all structs if (dt->layout->nfields > 0) { @@ -59,13 +59,13 @@ bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override return false; } -Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override +Type *preferred_llvm_type(jl_datatype_t *dt, bool isret, LLVMContext &ctx) const override { // Arguments are either scalar or passed by value // rewrite integer sized (non-sret) struct to the corresponding integer if (!dt->layout->nfields) return NULL; - return Type::getIntNTy(jl_LLVMContext, jl_datatype_nbits(dt)); + return Type::getIntNTy(ctx, jl_datatype_nbits(dt)); } }; diff --git a/src/abi_win64.cpp b/src/abi_win64.cpp index 16e46a9703f6a..6f6d407cfc10d 100644 --- a/src/abi_win64.cpp +++ b/src/abi_win64.cpp @@ -47,7 +47,7 @@ struct ABI_Win64Layout : AbiLayout { int nargs; ABI_Win64Layout() : nargs(0) { } -bool use_sret(jl_datatype_t *dt) override +bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override { size_t size = jl_datatype_size(dt); if (win64_reg_size(size) || is_native_simd_type(dt)) @@ -56,7 +56,7 @@ bool use_sret(jl_datatype_t *dt) override return true; } -bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override +bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override { nargs++; size_t size = jl_datatype_size(dt); @@ -67,11 +67,11 @@ bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override return true; } -Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override +Type *preferred_llvm_type(jl_datatype_t *dt, bool isret, LLVMContext &ctx) const override { size_t size = jl_datatype_size(dt); if (size > 0 && win64_reg_size(size) && !jl_is_primitivetype(dt)) - return Type::getIntNTy(jl_LLVMContext, jl_datatype_nbits(dt)); + return Type::getIntNTy(ctx, jl_datatype_nbits(dt)); return NULL; } diff --git a/src/abi_x86.cpp b/src/abi_x86.cpp index 7a65de028e083..c68e657695f3c 100644 --- a/src/abi_x86.cpp +++ b/src/abi_x86.cpp @@ -57,7 +57,7 @@ inline bool is_complex128(jl_datatype_t *dt) const return is_complex_type(dt) && jl_tparam0(dt) == (jl_value_t*)jl_float64_type; } -bool use_sret(jl_datatype_t *dt) override +bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override { size_t size = jl_datatype_size(dt); if (size == 0) @@ -67,7 +67,7 @@ bool use_sret(jl_datatype_t *dt) override return true; } -bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override +bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override { size_t size = jl_datatype_size(dt); if (is_complex64(dt) || is_complex128(dt) || (jl_is_primitivetype(dt) && size <= 8)) @@ -76,7 +76,7 @@ bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override return true; } -Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override +Type *preferred_llvm_type(jl_datatype_t *dt, bool isret, LLVMContext &ctx) const override { if (!isret) return NULL; diff --git a/src/abi_x86_64.cpp b/src/abi_x86_64.cpp index ac28af3011ecd..898e98dfcc262 100644 --- a/src/abi_x86_64.cpp +++ b/src/abi_x86_64.cpp @@ -168,7 +168,7 @@ Classification classify(jl_datatype_t *dt) const return cl; } -bool use_sret(jl_datatype_t *dt) override +bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override { int sret = classify(dt).isMemory; if (sret) { @@ -178,7 +178,7 @@ bool use_sret(jl_datatype_t *dt) override return sret; } -bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override +bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override { Classification cl = classify(dt); if (cl.isMemory) { @@ -210,7 +210,7 @@ bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab) override // Called on behalf of ccall to determine preferred LLVM representation // for an argument or return value. -Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override +Type *preferred_llvm_type(jl_datatype_t *dt, bool isret, LLVMContext &ctx) const override { (void) isret; // no need to rewrite these types (they are returned as pointers anyways) @@ -230,15 +230,15 @@ Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override switch (cl.classes[0]) { case Integer: if (size >= 8) - types[0] = T_int64; + types[0] = Type::getInt64Ty(ctx); else - types[0] = Type::getIntNTy(jl_LLVMContext, nbits); + types[0] = Type::getIntNTy(ctx, nbits); break; case Sse: if (size <= 4) - types[0] = T_float32; + types[0] = Type::getFloatTy(ctx); else - types[0] = T_float64; + types[0] = Type::getDoubleTy(ctx); break; default: assert(0 && "Unexpected cl.classes[0]"); @@ -248,14 +248,14 @@ Type *preferred_llvm_type(jl_datatype_t *dt, bool isret) const override return types[0]; case Integer: assert(size > 8); - types[1] = Type::getIntNTy(jl_LLVMContext, (nbits-64)); - return StructType::get(jl_LLVMContext,ArrayRef(&types[0],2)); + types[1] = Type::getIntNTy(ctx, (nbits-64)); + return StructType::get(ctx,ArrayRef(&types[0],2)); case Sse: if (size <= 12) - types[1] = T_float32; + types[1] = Type::getFloatTy(ctx); else - types[1] = T_float64; - return StructType::get(jl_LLVMContext,ArrayRef(&types[0],2)); + types[1] = Type::getDoubleTy(ctx); + return StructType::get(ctx,ArrayRef(&types[0],2)); default: assert(0 && "Unexpected cl.classes[0]"); } diff --git a/src/ccall.cpp b/src/ccall.cpp index c7853ccc2a8d8..b9a6ddc6151a7 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -290,9 +290,9 @@ static Value *emit_plt( class AbiLayout { public: virtual ~AbiLayout() {} - virtual bool use_sret(jl_datatype_t *ty) = 0; - virtual bool needPassByRef(jl_datatype_t *ty, AttrBuilder&) = 0; - virtual Type *preferred_llvm_type(jl_datatype_t *ty, bool isret) const = 0; + virtual bool use_sret(jl_datatype_t *ty, LLVMContext &ctx) = 0; + virtual bool needPassByRef(jl_datatype_t *ty, AttrBuilder&, LLVMContext &ctx) = 0; + virtual Type *preferred_llvm_type(jl_datatype_t *ty, bool isret, LLVMContext &ctx) const = 0; }; // Determine if object of bitstype ty maps to a native x86 SIMD type (__m128, __m256, or __m512) in C @@ -1008,14 +1008,14 @@ std::string generate_func_sig(const char *fname) if (type_is_ghost(lrt)) { prt = lrt = T_void; - abi->use_sret(jl_nothing_type); + abi->use_sret(jl_nothing_type, jl_LLVMContext); } else { if (!jl_is_datatype(rt) || ((jl_datatype_t*)rt)->layout == NULL || jl_is_layout_opaque(((jl_datatype_t*)rt)->layout) || jl_is_cpointer_type(rt) || retboxed) { prt = lrt; // passed as pointer - abi->use_sret(jl_voidpointer_type); + abi->use_sret(jl_voidpointer_type, jl_LLVMContext); } - else if (abi->use_sret((jl_datatype_t*)rt)) { + else if (abi->use_sret((jl_datatype_t*)rt, jl_LLVMContext)) { AttrBuilder retattrs = AttrBuilder(); #if !defined(_OS_WINDOWS_) // llvm used to use the old mingw ABI, skipping this marking works around that difference #if JL_LLVM_VERSION < 120000 @@ -1031,7 +1031,7 @@ std::string generate_func_sig(const char *fname) prt = lrt; } else { - prt = abi->preferred_llvm_type((jl_datatype_t*)rt, true); + prt = abi->preferred_llvm_type((jl_datatype_t*)rt, true, jl_LLVMContext); if (prt == NULL) prt = lrt; } @@ -1077,7 +1077,7 @@ std::string generate_func_sig(const char *fname) } // Whether or not LLVM wants us to emit a pointer to the data - bool byRef = abi->needPassByRef((jl_datatype_t*)tti, ab); + bool byRef = abi->needPassByRef((jl_datatype_t*)tti, ab, jl_LLVMContext); if (jl_is_cpointer_type(tti)) { pat = t; @@ -1086,7 +1086,7 @@ std::string generate_func_sig(const char *fname) pat = PointerType::get(t, AddressSpace::Derived); } else { - pat = abi->preferred_llvm_type((jl_datatype_t*)tti, false); + pat = abi->preferred_llvm_type((jl_datatype_t*)tti, false, jl_LLVMContext); if (pat == NULL) pat = t; }