Skip to content

Commit

Permalink
Intrinsify SpanHelper API's (#101622)
Browse files Browse the repository at this point in the history
  • Loading branch information
fanyang-mono committed Apr 27, 2024
1 parent 6f549af commit dad01da
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 9 deletions.
37 changes: 36 additions & 1 deletion src/mono/mono/mini/intrinsics.c
Expand Up @@ -283,7 +283,7 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
}
}

if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "Buffer")) {
if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "SpanHelpers")) {
if (!strcmp (cmethod->name, "Memmove") && fsig->param_count == 3 && m_type_is_byref (fsig->params [0]) && m_type_is_byref (fsig->params [1]) && !cmethod->is_inflated) {
MonoBasicBlock *end_bb;
NEW_BBLOCK (cfg, end_bb);
Expand All @@ -304,6 +304,41 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
ins->sreg3 = args [2]->dreg; // i32/i64 len
MONO_ADD_INS (cfg->cbb, ins);
MONO_START_BB (cfg, end_bb);
} else if (!strcmp (cmethod->name, "ClearWithoutReferences") && fsig->param_count == 2 && m_type_is_byref (fsig->params [0]) && !cmethod->is_inflated) {
MonoBasicBlock *end_bb;
NEW_BBLOCK (cfg, end_bb);

// do nothing if len == 0 (even if src is null)
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [1]->dreg, 0);
MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, end_bb);

// throw NRE if src is null
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [0]->dreg, 0);
MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException");

MONO_INST_NEW (cfg, ins, OP_MEMSET_ZERO);
ins->sreg1 = args [0]->dreg; // i1* dst
ins->sreg2 = args [1]->dreg; // i32/i64 len
MONO_ADD_INS (cfg->cbb, ins);
MONO_START_BB (cfg, end_bb);
} else if (!strcmp (cmethod->name, "Fill") && fsig->param_count == 3 && m_type_is_byref (fsig->params [0]) && !cmethod->is_inflated) {
MonoBasicBlock *end_bb;
NEW_BBLOCK (cfg, end_bb);

// do nothing if len == 0 (even if src is null)
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [1]->dreg, 0);
MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, end_bb);

// throw NRE if src is null
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [0]->dreg, 0);
MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException");

MONO_INST_NEW (cfg, ins, OP_MEMSET);
ins->sreg1 = args [0]->dreg; // i1* dst
ins->sreg2 = args [1]->dreg; // i8 value
ins->sreg3 = args [2]->dreg; // i32/i64 len
MONO_ADD_INS (cfg->cbb, ins);
MONO_START_BB (cfg, end_bb);
}
}

Expand Down
32 changes: 24 additions & 8 deletions src/mono/mono/mini/mini-llvm.c
Expand Up @@ -1427,15 +1427,18 @@ convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
}

static void
emit_memset (EmitContext *ctx, LLVMValueRef v, LLVMValueRef size, int alignment)
emit_memset (EmitContext *ctx, LLVMValueRef dest, LLVMValueRef val, LLVMValueRef size, int alignment)
{
LLVMValueRef args [5];
int aindex = 0;

args [aindex ++] = v;
args [aindex ++] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
args [aindex ++] = dest;
if (val)
args [aindex ++] = val;
else
args [aindex ++] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
args [aindex ++] = size;
args [aindex ++] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
args [aindex ++] = LLVMConstInt (LLVMInt1Type (), 0, FALSE); // is_volatile
call_intrins (ctx, INTRINS_MEMSET, args, "");
}

Expand Down Expand Up @@ -6159,7 +6162,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
* load it into registers.
*/
LLVMValueRef buf = build_alloca_llvm_type_name (ctx, pointer_type (ret_type), 0, "ret_buf");
emit_memset (ctx, buf, LLVMSizeOf (ret_type), 1);
emit_memset (ctx, buf, NULL, LLVMSizeOf (ret_type), 1);

int width = mono_type_size (sig->ret, NULL);
LLVMValueRef args [] = {
Expand Down Expand Up @@ -7000,7 +7003,7 @@ MONO_RESTORE_WARNING
v = mono_llvm_build_alloca (builder, LLVMInt8Type (), const_int32 (size), MONO_ARCH_FRAME_ALIGNMENT, "");

if (ins->flags & MONO_INST_INIT)
emit_memset (ctx, v, const_int32 (size), MONO_ARCH_FRAME_ALIGNMENT);
emit_memset (ctx, v, NULL, const_int32 (size), MONO_ARCH_FRAME_ALIGNMENT);

values [ins->dreg] = v;
break;
Expand All @@ -7013,7 +7016,7 @@ MONO_RESTORE_WARNING
v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");

if (ins->flags & MONO_INST_INIT)
emit_memset (ctx, v, size, MONO_ARCH_FRAME_ALIGNMENT);
emit_memset (ctx, v, NULL, size, MONO_ARCH_FRAME_ALIGNMENT);
values [ins->dreg] = v;
break;
}
Expand Down Expand Up @@ -7231,6 +7234,19 @@ MONO_RESTORE_WARNING
call_intrins (ctx, INTRINS_MEMMOVE, args, "");
break;
}
case OP_MEMSET_ZERO: {
LLVMValueRef dest = convert (ctx, values [ins->sreg1], pointer_type (LLVMInt8Type ()));
LLVMValueRef size = convert (ctx, values [ins->sreg2], LLVMInt64Type ());
emit_memset (ctx, dest, NULL, size, MONO_ARCH_FRAME_ALIGNMENT);
break;
}
case OP_MEMSET: {
LLVMValueRef dest = convert (ctx, values [ins->sreg1], pointer_type (LLVMInt8Type ()));
LLVMValueRef val = convert (ctx, values [ins->sreg2], LLVMInt8Type ());
LLVMValueRef size = convert (ctx, values [ins->sreg3], LLVMInt64Type ());
emit_memset (ctx, dest, val, size, MONO_ARCH_FRAME_ALIGNMENT);
break;
}
case OP_NOT_REACHED:
LLVMBuildUnreachable (builder);
has_terminator = TRUE;
Expand Down Expand Up @@ -7863,7 +7879,7 @@ MONO_RESTORE_WARNING
addresses [ins->dreg] = create_address (ctx, build_named_alloca (ctx, m_class_get_byval_arg (klass), "vzero"), etype);
}
LLVMValueRef ptr = build_ptr_cast (builder, addresses [ins->dreg]->value, pointer_type (LLVMInt8Type ()));
emit_memset (ctx, ptr, const_int32 (mono_class_value_size (klass, NULL)), 0);
emit_memset (ctx, ptr, NULL, const_int32 (mono_class_value_size (klass, NULL)), 0);
break;
}
case OP_DUMMY_VZERO:
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/mini-ops.h
Expand Up @@ -775,6 +775,7 @@ MINI_OP(OP_LDELEMA2D, "ldelema2d", NONE, NONE, NONE)
MINI_OP(OP_MEMCPY, "memcpy", NONE, NONE, NONE)
/* inlined small memset with constant length */
MINI_OP(OP_MEMSET, "memset", NONE, NONE, NONE)
MINI_OP(OP_MEMSET_ZERO, "memset_zero", NONE, IREG, IREG)
/*
* A RuntimeType object, the result ldtoken+GetTypeFromHandle.
* inst_p0 is a MonoClass.
Expand Down

0 comments on commit dad01da

Please sign in to comment.