From: Egor Bogatov Date: Sat, 31 Aug 2019 23:42:44 +0000 (+0300) Subject: LLVM: Make Buffer.Memmove intrinsic (mono/mono#16610) X-Git-Tag: submit/tizen/20210909.063632~10331^2~5^2~625 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9cdba4e09108cefa3b9a3e7708945fd02f4d90eb;p=platform%2Fupstream%2Fdotnet%2Fruntime.git LLVM: Make Buffer.Memmove intrinsic (mono/mono#16610) * Add memmove intrinsic * Fix typo * Add -lower-expect Commit migrated from https://github.com/mono/mono/commit/6327274b54cca5ad11207c79f5a611ca1623c60f --- diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index 2b1ced9..8eeb551 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -222,6 +222,17 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign } } + if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "Buffer")) { + if (!strcmp (cmethod->name, "Memmove") && fsig->param_count == 3 && fsig->params [0]->type == MONO_TYPE_PTR && fsig->params [1]->type == MONO_TYPE_PTR) { + opcode = OP_MEMMOVE; + MONO_INST_NEW (cfg, ins, opcode); + ins->sreg1 = args [0]->dreg; // i1* dst + ins->sreg2 = args [1]->dreg; // i1* src + ins->sreg3 = args [2]->dreg; // i32/i64 len + MONO_ADD_INS (cfg->cbb, ins); + } + } + return ins; } diff --git a/src/mono/mono/mini/llvm-jit.cpp b/src/mono/mono/mini/llvm-jit.cpp index 2fa9c60..4a36413 100644 --- a/src/mono/mono/mini/llvm-jit.cpp +++ b/src/mono/mono/mini/llvm-jit.cpp @@ -289,7 +289,7 @@ public: if (opts == NULL) { // FIXME: find optimal mono specific order of passes // see https://llvm.org/docs/Frontend/PerformanceTips.html#pass-ordering - opts = " -simplifycfg -sroa -instcombine -gvn"; + opts = " -simplifycfg -sroa -lower-expect -instcombine -gvn"; } char **args = g_strsplit (opts, " ", -1); diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 58c29e0..f15b320 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -278,6 +278,7 @@ static LLVMRealPredicate fpcond_to_llvm_cond [] = { typedef enum { INTRINS_MEMSET, INTRINS_MEMCPY, + INTRINS_MEMMOVE, INTRINS_SADD_OVF_I32, INTRINS_UADD_OVF_I32, INTRINS_SSUB_OVF_I32, @@ -5901,6 +5902,20 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) set_nonnull_load_flag (values [ins->dreg]); break; } + case OP_MEMMOVE: { + int argn = 0; + LLVMValueRef args [5]; + args [argn++] = convert (ctx, values [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0)); + args [argn++] = convert (ctx, values [ins->sreg2], LLVMPointerType (LLVMInt8Type (), 0)); + args [argn++] = convert (ctx, values [ins->sreg3], LLVMInt64Type ()); +#if LLVM_API_VERSION < 900 + args [argn++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE); // alignment +#endif + args [argn++] = LLVMConstInt (LLVMInt1Type (), 0, FALSE); // is_volatile + + LLVMBuildCall (builder, get_intrins (ctx, INTRINS_MEMMOVE), args, argn, ""); + break; + } case OP_NOT_REACHED: LLVMBuildUnreachable (builder); has_terminator = TRUE; @@ -8522,6 +8537,7 @@ typedef struct { static IntrinsicDesc intrinsics[] = { {INTRINS_MEMSET, "llvm.memset.p0i8.i32"}, {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"}, + {INTRINS_MEMMOVE, "llvm.memmove.p0i8.p0i8.i64"}, {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"}, {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"}, {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"}, @@ -8664,6 +8680,17 @@ add_intrinsic (LLVMModuleRef module, int id) #endif break; } + case INTRINS_MEMMOVE: { +#if LLVM_API_VERSION >= 900 + /* No alignment argument */ + LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt64Type (), LLVMInt1Type () }; + AddFunc (module, name, LLVMVoidType (), params, 4); +#else + LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt64Type (), LLVMInt32Type (), LLVMInt1Type () }; + AddFunc (module, name, LLVMVoidType (), params, 5); +#endif + break; + } case INTRINS_SADD_OVF_I32: case INTRINS_UADD_OVF_I32: case INTRINS_SSUB_OVF_I32: diff --git a/src/mono/mono/mini/mini-ops.h b/src/mono/mono/mini/mini-ops.h index 1696889..8d8425a 100644 --- a/src/mono/mono/mini/mini-ops.h +++ b/src/mono/mono/mini/mini-ops.h @@ -755,6 +755,8 @@ MINI_OP(OP_MEMSET, "memset", NONE, NONE, NONE) MINI_OP(OP_SAVE_LMF, "save_lmf", NONE, NONE, NONE) MINI_OP(OP_RESTORE_LMF, "restore_lmf", NONE, NONE, NONE) +MINI_OP3(OP_MEMMOVE, "memmove", NONE, IREG, IREG, IREG) + /* write barrier */ MINI_OP(OP_CARD_TABLE_WBARRIER, "card_table_wbarrier", NONE, IREG, IREG)