From 5888f803f52f2995d9f279a87bbc4855663e43d9 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 11 Oct 2022 10:06:56 -0400 Subject: [PATCH] [mono][llvm] Fix usage of implicit pointer types in a few more places, enable for LLVM 15+. --- src/mono/mono/mini/mini-llvm-cpp.cpp | 8 +++- src/mono/mono/mini/mini-llvm-cpp.h | 4 +- src/mono/mono/mini/mini-llvm.c | 61 ++++++++++++++++------------ 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/mono/mono/mini/mini-llvm-cpp.cpp b/src/mono/mono/mini/mini-llvm-cpp.cpp index 4ae67135dad982..cd8503aee38285 100644 --- a/src/mono/mono/mini/mini-llvm-cpp.cpp +++ b/src/mono/mono/mini/mini-llvm-cpp.cpp @@ -722,7 +722,7 @@ is_overloaded_intrins (IntrinsicId id) * Register an LLVM intrinsic identified by ID. */ LLVMValueRef -mono_llvm_register_intrinsic (LLVMModuleRef module, IntrinsicId id) +mono_llvm_register_intrinsic (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef *out_type) { if (is_overloaded_intrins (id)) return NULL; @@ -734,6 +734,8 @@ mono_llvm_register_intrinsic (LLVMModuleRef module, IntrinsicId id) outs () << id << "\n"; g_assert_not_reached (); } + auto type = Intrinsic::getType (*unwrap(LLVMGetGlobalContext ()), intrins_id); + *out_type = wrap (type); return wrap (f); } else { return NULL; @@ -746,7 +748,7 @@ mono_llvm_register_intrinsic (LLVMModuleRef module, IntrinsicId id) * Register an overloaded LLVM intrinsic identified by ID using the supplied types. */ LLVMValueRef -mono_llvm_register_overloaded_intrinsic (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef *types, int ntypes) +mono_llvm_register_overloaded_intrinsic (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef *types, int ntypes, LLVMTypeRef *out_type) { auto intrins_id = get_intrins_id (id); @@ -756,6 +758,8 @@ mono_llvm_register_overloaded_intrinsic (LLVMModuleRef module, IntrinsicId id, L for (int i = 0; i < ntypes; ++i) arr [i] = unwrap (types [i]); auto f = Intrinsic::getDeclaration (unwrap (module), intrins_id, { arr, (size_t)ntypes }); + auto type = Intrinsic::getType (*unwrap(LLVMGetGlobalContext ()), intrins_id, { arr, (size_t)ntypes }); + *out_type = wrap (type); return wrap (f); } diff --git a/src/mono/mono/mini/mini-llvm-cpp.h b/src/mono/mono/mini/mini-llvm-cpp.h index 3104d6b54a3824..9f40accf3043ac 100644 --- a/src/mono/mono/mini/mini-llvm-cpp.h +++ b/src/mono/mono/mini/mini-llvm-cpp.h @@ -214,10 +214,10 @@ int mono_llvm_check_cpu_features (const CpuFeatureAliasFlag *features, int length); LLVMValueRef -mono_llvm_register_intrinsic (LLVMModuleRef module, IntrinsicId id); +mono_llvm_register_intrinsic (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef *out_type); LLVMValueRef -mono_llvm_register_overloaded_intrinsic (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef *types, int ntypes); +mono_llvm_register_overloaded_intrinsic (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef *types, int ntypes, LLVMTypeRef *out_type); unsigned int mono_llvm_get_prim_size_bits (LLVMTypeRef type); diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 890e6cad878c66..1652d00c2f88e2 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -58,8 +58,8 @@ #define LLVMBuildLoad UseLLVMBuildLoad2Instead #define LLVMBuildCall UseLLVMBuildCall2Instead -#if LLVM_API_VERSION >= 1400 -//#define USE_OPAQUE_POINTERS 1 +#if LLVM_API_VERSION >= 1500 +#define USE_OPAQUE_POINTERS 1 #endif /* @@ -115,6 +115,7 @@ typedef struct { LLVMValueRef unbox_trampolines; LLVMValueRef gc_poll_cold_wrapper; LLVMValueRef info_var; + LLVMTypeRef info_var_type; LLVMTypeRef *info_var_eltypes; guint32 max_inited_idx, max_method_idx; gboolean has_jitted_code; @@ -169,6 +170,7 @@ typedef struct { MonoCompile *cfg; LLVMValueRef lmethod; + LLVMTypeRef lmethod_type; MonoLLVMModule *module; LLVMModuleRef lmodule; BBInfo *bblocks; @@ -338,6 +340,7 @@ enum { static MonoLLVMModule aot_module; static GHashTable *intrins_id_to_intrins; +static GHashTable *intrins_id_to_type; static LLVMTypeRef ptr_t; static LLVMTypeRef i1_t, i2_t, i4_t, i8_t, r4_t, r8_t; static LLVMTypeRef sse_i1_t, sse_i2_t, sse_i4_t, sse_i8_t, sse_r4_t, sse_r8_t; @@ -5575,7 +5578,9 @@ call_overloaded_intrins (EmitContext *ctx, int id, llvm_ovr_tag_t ovr_tag, LLVMV { int key = key_from_id_and_tag (id, ovr_tag); LLVMValueRef intrins = get_intrins (ctx, key); - int nargs = LLVMCountParamTypes (LLVMGetElementType (LLVMTypeOf (intrins))); + LLVMTypeRef type = g_hash_table_lookup (intrins_id_to_type, GINT_TO_POINTER (key)); + g_assert (type); + int nargs = LLVMCountParamTypes (type); for (int i = 0; i < nargs; ++i) { LLVMTypeRef t1 = LLVMTypeOf (args [i]); LLVMTypeRef t2 = LLVMTypeOf (LLVMGetParam (intrins, i)); @@ -5605,7 +5610,6 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) { MonoCompile *cfg = ctx->cfg; MonoMethodSignature *sig = ctx->sig; - LLVMValueRef method = ctx->lmethod; LLVMValueRef *values = ctx->values; Address **addresses = ctx->addresses; LLVMCallInfo *linfo = ctx->linfo; @@ -5907,7 +5911,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) case LLVMArgVtypeInReg: case LLVMArgVtypeAsScalar: case LLVMArgWasmVtypeAsScalar: { - LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method))); + LLVMTypeRef ret_type = LLVMGetReturnType (ctx->lmethod_type); LLVMValueRef retval = LLVMGetUndef (ret_type); gboolean src_in_reg = FALSE; gboolean is_simd = MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (sig->ret)); @@ -6004,7 +6008,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) } case LLVMArgAsIArgs: case LLVMArgFpStruct: { - LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method))); + LLVMTypeRef ret_type = LLVMGetReturnType (ctx->lmethod_type); LLVMValueRef retval, elem; gboolean is_simd = MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (sig->ret)); @@ -11926,6 +11930,7 @@ emit_method_inner (EmitContext *ctx) method = LLVMAddFunction (lmodule, ctx->method_name, method_type); ctx->lmethod = method; + ctx->lmethod_type = method_type; if (cfg->llvm_only && cfg->header->num_clauses && mono_opt_wasm_exceptions) { LLVMValueRef personality = get_mono_personality (ctx); @@ -12681,38 +12686,40 @@ add_func (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMType } static LLVMValueRef -add_intrins (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef *params, int nparams) +add_intrins (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef *params, int nparams, LLVMTypeRef *out_type) { - return mono_llvm_register_overloaded_intrinsic (module, id, params, nparams); + return mono_llvm_register_overloaded_intrinsic (module, id, params, nparams, out_type); } static LLVMValueRef -add_intrins1 (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef param1) +add_intrins1 (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef param1, LLVMTypeRef *out_type) { - return mono_llvm_register_overloaded_intrinsic (module, id, ¶m1, 1); + return mono_llvm_register_overloaded_intrinsic (module, id, ¶m1, 1, out_type); } static LLVMValueRef -add_intrins2 (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef param1, LLVMTypeRef param2) +add_intrins2 (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef param1, LLVMTypeRef param2, LLVMTypeRef *out_type) { LLVMTypeRef params [] = { param1, param2 }; - return mono_llvm_register_overloaded_intrinsic (module, id, params, 2); + return mono_llvm_register_overloaded_intrinsic (module, id, params, 2, out_type); } static LLVMValueRef -add_intrins3 (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef param1, LLVMTypeRef param2, LLVMTypeRef param3) +add_intrins3 (LLVMModuleRef module, IntrinsicId id, LLVMTypeRef param1, LLVMTypeRef param2, LLVMTypeRef param3, LLVMTypeRef *out_type) { LLVMTypeRef params [] = { param1, param2, param3 }; - return mono_llvm_register_overloaded_intrinsic (module, id, params, 3); + return mono_llvm_register_overloaded_intrinsic (module, id, params, 3, out_type); } static void add_intrinsic (LLVMModuleRef module, int id) { /* Register simple intrinsics */ - LLVMValueRef intrins = mono_llvm_register_intrinsic (module, (IntrinsicId)id); + LLVMTypeRef intrins_type = NULL; + LLVMValueRef intrins = mono_llvm_register_intrinsic (module, (IntrinsicId)id, &intrins_type); if (intrins) { g_hash_table_insert (intrins_id_to_intrins, GINT_TO_POINTER (id), intrins); + g_hash_table_insert (intrins_id_to_type, GINT_TO_POINTER (id), intrins_type); return; } @@ -12731,13 +12738,13 @@ add_intrinsic (LLVMModuleRef module, int id) * @llvm.aarch64.neon.fcvtas.v4i32.v4f32 * @llvm.aarch64.neon.fcvtas.v2i64.v2f64 */ - intrins = add_intrins2 (module, id, distinguishing_type, intrin_types [vw][ew + 2]); + intrins = add_intrins2 (module, id, distinguishing_type, intrin_types [vw][ew + 2], &intrins_type); } else if (kind == INTRIN_kind_widen) { /* * @llvm.aarch64.neon.saddlp.v2i64.v4i32 * @llvm.aarch64.neon.saddlp.v4i16.v8i8 */ - intrins = add_intrins2 (module, id, distinguishing_type, intrin_types [vw][ew - 1]); + intrins = add_intrins2 (module, id, distinguishing_type, intrin_types [vw][ew - 1], &intrins_type); } else if (kind == INTRIN_kind_widen_across) { /* * @llvm.aarch64.neon.saddlv.i64.v4i32 @@ -12747,7 +12754,7 @@ add_intrinsic (LLVMModuleRef module, int id) */ int associated_prim = MAX(ew + 1, 2); LLVMTypeRef associated_scalar_type = intrin_types [0][associated_prim]; - intrins = add_intrins2 (module, id, associated_scalar_type, distinguishing_type); + intrins = add_intrins2 (module, id, associated_scalar_type, distinguishing_type, &intrins_type); } else if (kind == INTRIN_kind_across) { /* * @llvm.aarch64.neon.uaddv.i64.v4i64 @@ -12758,18 +12765,19 @@ add_intrinsic (LLVMModuleRef module, int id) */ int associated_prim = MAX(ew, 2); LLVMTypeRef associated_scalar_type = intrin_types [0][associated_prim]; - intrins = add_intrins2 (module, id, associated_scalar_type, distinguishing_type); + intrins = add_intrins2 (module, id, associated_scalar_type, distinguishing_type, &intrins_type); } else if (kind == INTRIN_kind_arm64_dot_prod) { /* * @llvm.aarch64.neon.sdot.v2i32.v8i8 * @llvm.aarch64.neon.sdot.v4i32.v16i8 */ LLVMTypeRef associated_type = intrin_types [vw][0]; - intrins = add_intrins2 (module, id, distinguishing_type, associated_type); + intrins = add_intrins2 (module, id, distinguishing_type, associated_type, &intrins_type); } else - intrins = add_intrins1 (module, id, distinguishing_type); + intrins = add_intrins1 (module, id, distinguishing_type, &intrins_type); int key = key_from_id_and_tag (id, test); g_hash_table_insert (intrins_id_to_intrins, GINT_TO_POINTER (key), intrins); + g_hash_table_insert (intrins_id_to_type, GINT_TO_POINTER (key), intrins_type); } } } @@ -12779,9 +12787,9 @@ add_intrinsic (LLVMModuleRef module, int id) /* Register overloaded intrinsics */ switch (id) { #define INTRINS(intrin_name, llvm_id, arch) - #define INTRINS_OVR(intrin_name, llvm_id, arch, llvm_type) case INTRINS_ ## intrin_name: intrins = add_intrins1(module, id, llvm_type); break; - #define INTRINS_OVR_2_ARG(intrin_name, llvm_id, arch, llvm_type1, llvm_type2) case INTRINS_ ## intrin_name: intrins = add_intrins2(module, id, llvm_type1, llvm_type2); break; - #define INTRINS_OVR_3_ARG(intrin_name, llvm_id, arch, llvm_type1, llvm_type2, llvm_type3) case INTRINS_ ## intrin_name: intrins = add_intrins3(module, id, llvm_type1, llvm_type2, llvm_type3); break; + #define INTRINS_OVR(intrin_name, llvm_id, arch, llvm_type) case INTRINS_ ## intrin_name: intrins = add_intrins1(module, id, llvm_type, &intrins_type); break; + #define INTRINS_OVR_2_ARG(intrin_name, llvm_id, arch, llvm_type1, llvm_type2) case INTRINS_ ## intrin_name: intrins = add_intrins2(module, id, llvm_type1, llvm_type2, &intrins_type); break; + #define INTRINS_OVR_3_ARG(intrin_name, llvm_id, arch, llvm_type1, llvm_type2, llvm_type3) case INTRINS_ ## intrin_name: intrins = add_intrins3(module, id, llvm_type1, llvm_type2, llvm_type3, &intrins_type); break; #define INTRINS_OVR_TAG(...) #define INTRINS_OVR_TAG_KIND(...) #include "llvm-intrinsics.h" @@ -12792,6 +12800,7 @@ add_intrinsic (LLVMModuleRef module, int id) } g_assert (intrins); g_hash_table_insert (intrins_id_to_intrins, GINT_TO_POINTER (id), intrins); + g_hash_table_insert (intrins_id_to_type, GINT_TO_POINTER (id), intrins_type); } static LLVMValueRef @@ -12865,6 +12874,7 @@ mono_llvm_init (gboolean enable_jit) intrin_types [2][5] = v128_r8_t = sse_r8_t = type_to_sse_type (MONO_TYPE_R8); intrins_id_to_intrins = g_hash_table_new (NULL, NULL); + intrins_id_to_type = g_hash_table_new (NULL, NULL); void_func_t = LLVMFunctionType0 (LLVMVoidType (), FALSE); @@ -13285,6 +13295,7 @@ create_aot_info_var (MonoLLVMModule *module) info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info"); module->info_var = info_var; + module->info_var_type = file_info_type; module->info_var_eltypes = eltypes; } @@ -13454,7 +13465,7 @@ emit_aot_file_info (MonoLLVMModule *module) fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16); g_assert (tindex == nfields); - LLVMSetInitializer (info_var, LLVMConstNamedStruct (LLVMGetElementType (LLVMTypeOf (info_var)), fields, nfields)); + LLVMSetInitializer (info_var, LLVMConstNamedStruct (module->info_var_type, fields, nfields)); if (module->static_link) { char *s, *p;