Skip to content

Commit

Permalink
[mono][llvm] Add a fastpath to calling mini_init_method_rgctx (). (#8…
Browse files Browse the repository at this point in the history
…4226)

* [mono][llvm] Add a fastpath to calling mini_init_method_rgctx ().

* Add arm64 JIT support.
  • Loading branch information
vargaz authored Apr 3, 2023
1 parent 877daf6 commit 6146bad
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/mono/mono/mini/cpu-arm64.mdesc
Original file line number Diff line number Diff line change
Expand Up @@ -523,5 +523,6 @@ expand_r8: dest:x src1:f len:4

generic_class_init: src1:a len:44 clob:c
gc_safe_point: src1:i len:12 clob:c
init_mrgctx: src1:a src2:i len:44 clob:c

fill_prof_call_ctx: src1:i len:128
10 changes: 9 additions & 1 deletion src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -6750,7 +6750,15 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
EMIT_NEW_PCONST (cfg, args [1], info);

cfg->init_method_rgctx_ins_arg = args [1];
cfg->init_method_rgctx_ins = mono_emit_jit_icall (cfg, mini_init_method_rgctx, args);
if (COMPILE_LLVM (cfg) || cfg->backend->have_init_mrgctx) {
MONO_INST_NEW (cfg, ins, OP_INIT_MRGCTX);
ins->sreg1 = args [0]->dreg;
ins->sreg2 = args [1]->dreg;
MONO_ADD_INS (cfg->cbb, ins);
cfg->init_method_rgctx_ins = ins;
} else {
cfg->init_method_rgctx_ins = mono_emit_jit_icall (cfg, mini_init_method_rgctx, args);
}
}

if (cfg->gsharedvt && cfg->method == method) {
Expand Down
21 changes: 21 additions & 0 deletions src/mono/mono/mini/mini-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -5023,6 +5023,27 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
mono_arm_patch (jump, code, MONO_R_ARM64_CBZ);
break;
}
case OP_INIT_MRGCTX: {
int field_offset;
guint8 *jump;

field_offset = MONO_STRUCT_OFFSET (MonoMethodRuntimeGenericContext, entries);

/* Load mrgxtx->entries */
arm_ldrx (code, ARMREG_IP0, sreg1, field_offset);
jump = code;
arm_cbnzx (code, ARMREG_IP0, 0);

/* Slowpath */
g_assert (sreg1 == ARMREG_R0);
if (sreg2 != ARMREG_R1)
arm_movx (code, ARMREG_R1, sreg2);
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID,
GUINT_TO_POINTER (MONO_JIT_ICALL_mini_init_method_rgctx));

mono_arm_patch (jump, code, MONO_R_ARM64_CBZ);
break;
}

case OP_CHECK_THIS:
arm_ldrb (code, ARMREG_LR, sreg1, 0);
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/mini-arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ typedef struct {
#define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
#define MONO_ARCH_FLOAT32_SUPPORTED 1
#define MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP 1
#define MONO_ARCH_HAVE_INIT_MRGCTX 1
#define MONO_ARCH_LLVM_TARGET_LAYOUT "e-i64:64-i128:128-n32:64-S128"
#ifdef TARGET_OSX
#define MONO_ARCH_FORCE_FLOAT32 1
Expand Down
46 changes: 46 additions & 0 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -7415,6 +7415,52 @@ MONO_RESTORE_WARNING
break;
}

case OP_INIT_MRGCTX: {
LLVMValueRef val, cmp, callee;
LLVMBasicBlockRef poll_bb, cont_bb;
LLVMValueRef args [2];
static LLVMTypeRef icall_sig;

g_assert (cfg->compile_aot);

/*
* if (!((MonoMethodRuntimeGenericContext)->lhs)->entries)
* mini_init_method_rgctx (lhs, rhs);
*/

LLVMValueRef offset = const_int32 (MONO_STRUCT_OFFSET (MonoMethodRuntimeGenericContext, entries));
LLVMValueRef ptr = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");

val = emit_load (builder, IntPtrType (), convert (ctx, ptr, pointer_type (IntPtrType ())), "", TRUE);
cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
poll_bb = gen_bb (ctx, "POLL_BB");
cont_bb = gen_bb (ctx, "CONT_BB");

args [0] = cmp;
args [1] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
cmp = call_intrins (ctx, INTRINS_EXPECT_I1, args, "");

mono_llvm_build_weighted_branch (builder, cmp, poll_bb, cont_bb, 1, 1000);

ctx->builder = builder = create_builder (ctx);
LLVMPositionBuilderAtEnd (builder, poll_bb);

if (!icall_sig)
icall_sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), IntPtrType (), FALSE);

args [0] = convert (ctx, lhs, IntPtrType ());
args [1] = convert (ctx, rhs, IntPtrType ());

callee = get_callee (ctx, icall_sig, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_init_method_rgctx));
LLVMBuildCall2 (builder, icall_sig, callee, args, 2, "");
LLVMBuildBr (builder, cont_bb);

ctx->builder = builder = create_builder (ctx);
LLVMPositionBuilderAtEnd (builder, cont_bb);
ctx->bblocks [bb->block_num].end_bblock = cont_bb;
break;
}

/*
* Overflow opcodes.
*/
Expand Down
7 changes: 7 additions & 0 deletions src/mono/mono/mini/mini-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,13 @@ MINI_OP(OP_GC_SAFE_POINT, "gc_safe_point", NONE, IREG, NONE)
*/
MINI_OP(OP_GENERIC_CLASS_INIT, "generic_class_init", NONE, IREG, NONE)

/*
* Call mini_init_method_rgctx () if needed.
* sreg1 is a MonoMethodRuntimeGenericContext.
* sreg2 is a MonoGSharedMethodInfo.
*/
MINI_OP(OP_INIT_MRGCTX, "init_mrgctx", NONE, IREG, IREG)

/* Arch specific opcodes */
#if defined(TARGET_X86) || defined(TARGET_AMD64)
MINI_OP(OP_X86_TEST_NULL, "x86_test_null", NONE, IREG, NONE)
Expand Down
3 changes: 3 additions & 0 deletions src/mono/mono/mini/mini.c
Original file line number Diff line number Diff line change
Expand Up @@ -3018,6 +3018,9 @@ init_backend (MonoBackend *backend)
#ifdef MONO_ARCH_FORCE_FLOAT32
backend->force_float32 = 1;
#endif
#ifdef MONO_ARCH_HAVE_INIT_MRGCTX
backend->have_init_mrgctx = 1;
#endif
}

static gboolean
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/mini.h
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,7 @@ typedef struct {
gboolean have_op_tailcall_membase : 1;
gboolean have_op_tailcall_reg : 1;
gboolean have_volatile_non_param_register : 1;
guint have_init_mrgctx : 1;
guint gshared_supported : 1;
guint ilp32 : 1;
guint need_got_var : 1;
Expand Down

0 comments on commit 6146bad

Please sign in to comment.