Skip to content

Commit dad01da

Browse files
authored
Intrinsify SpanHelper API's (#101622)
1 parent 6f549af commit dad01da

File tree

3 files changed

+61
-9
lines changed

3 files changed

+61
-9
lines changed

src/mono/mono/mini/intrinsics.c

+36-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
283283
}
284284
}
285285

286-
if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "Buffer")) {
286+
if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "SpanHelpers")) {
287287
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) {
288288
MonoBasicBlock *end_bb;
289289
NEW_BBLOCK (cfg, end_bb);
@@ -304,6 +304,41 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
304304
ins->sreg3 = args [2]->dreg; // i32/i64 len
305305
MONO_ADD_INS (cfg->cbb, ins);
306306
MONO_START_BB (cfg, end_bb);
307+
} else if (!strcmp (cmethod->name, "ClearWithoutReferences") && fsig->param_count == 2 && m_type_is_byref (fsig->params [0]) && !cmethod->is_inflated) {
308+
MonoBasicBlock *end_bb;
309+
NEW_BBLOCK (cfg, end_bb);
310+
311+
// do nothing if len == 0 (even if src is null)
312+
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [1]->dreg, 0);
313+
MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, end_bb);
314+
315+
// throw NRE if src is null
316+
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [0]->dreg, 0);
317+
MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException");
318+
319+
MONO_INST_NEW (cfg, ins, OP_MEMSET_ZERO);
320+
ins->sreg1 = args [0]->dreg; // i1* dst
321+
ins->sreg2 = args [1]->dreg; // i32/i64 len
322+
MONO_ADD_INS (cfg->cbb, ins);
323+
MONO_START_BB (cfg, end_bb);
324+
} else if (!strcmp (cmethod->name, "Fill") && fsig->param_count == 3 && m_type_is_byref (fsig->params [0]) && !cmethod->is_inflated) {
325+
MonoBasicBlock *end_bb;
326+
NEW_BBLOCK (cfg, end_bb);
327+
328+
// do nothing if len == 0 (even if src is null)
329+
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [1]->dreg, 0);
330+
MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, end_bb);
331+
332+
// throw NRE if src is null
333+
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [0]->dreg, 0);
334+
MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException");
335+
336+
MONO_INST_NEW (cfg, ins, OP_MEMSET);
337+
ins->sreg1 = args [0]->dreg; // i1* dst
338+
ins->sreg2 = args [1]->dreg; // i8 value
339+
ins->sreg3 = args [2]->dreg; // i32/i64 len
340+
MONO_ADD_INS (cfg->cbb, ins);
341+
MONO_START_BB (cfg, end_bb);
307342
}
308343
}
309344

src/mono/mono/mini/mini-llvm.c

+24-8
Original file line numberDiff line numberDiff line change
@@ -1427,15 +1427,18 @@ convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
14271427
}
14281428

14291429
static void
1430-
emit_memset (EmitContext *ctx, LLVMValueRef v, LLVMValueRef size, int alignment)
1430+
emit_memset (EmitContext *ctx, LLVMValueRef dest, LLVMValueRef val, LLVMValueRef size, int alignment)
14311431
{
14321432
LLVMValueRef args [5];
14331433
int aindex = 0;
14341434

1435-
args [aindex ++] = v;
1436-
args [aindex ++] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
1435+
args [aindex ++] = dest;
1436+
if (val)
1437+
args [aindex ++] = val;
1438+
else
1439+
args [aindex ++] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
14371440
args [aindex ++] = size;
1438-
args [aindex ++] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
1441+
args [aindex ++] = LLVMConstInt (LLVMInt1Type (), 0, FALSE); // is_volatile
14391442
call_intrins (ctx, INTRINS_MEMSET, args, "");
14401443
}
14411444

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

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

70027005
if (ins->flags & MONO_INST_INIT)
7003-
emit_memset (ctx, v, const_int32 (size), MONO_ARCH_FRAME_ALIGNMENT);
7006+
emit_memset (ctx, v, NULL, const_int32 (size), MONO_ARCH_FRAME_ALIGNMENT);
70047007

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

70157018
if (ins->flags & MONO_INST_INIT)
7016-
emit_memset (ctx, v, size, MONO_ARCH_FRAME_ALIGNMENT);
7019+
emit_memset (ctx, v, NULL, size, MONO_ARCH_FRAME_ALIGNMENT);
70177020
values [ins->dreg] = v;
70187021
break;
70197022
}
@@ -7231,6 +7234,19 @@ MONO_RESTORE_WARNING
72317234
call_intrins (ctx, INTRINS_MEMMOVE, args, "");
72327235
break;
72337236
}
7237+
case OP_MEMSET_ZERO: {
7238+
LLVMValueRef dest = convert (ctx, values [ins->sreg1], pointer_type (LLVMInt8Type ()));
7239+
LLVMValueRef size = convert (ctx, values [ins->sreg2], LLVMInt64Type ());
7240+
emit_memset (ctx, dest, NULL, size, MONO_ARCH_FRAME_ALIGNMENT);
7241+
break;
7242+
}
7243+
case OP_MEMSET: {
7244+
LLVMValueRef dest = convert (ctx, values [ins->sreg1], pointer_type (LLVMInt8Type ()));
7245+
LLVMValueRef val = convert (ctx, values [ins->sreg2], LLVMInt8Type ());
7246+
LLVMValueRef size = convert (ctx, values [ins->sreg3], LLVMInt64Type ());
7247+
emit_memset (ctx, dest, val, size, MONO_ARCH_FRAME_ALIGNMENT);
7248+
break;
7249+
}
72347250
case OP_NOT_REACHED:
72357251
LLVMBuildUnreachable (builder);
72367252
has_terminator = TRUE;
@@ -7863,7 +7879,7 @@ MONO_RESTORE_WARNING
78637879
addresses [ins->dreg] = create_address (ctx, build_named_alloca (ctx, m_class_get_byval_arg (klass), "vzero"), etype);
78647880
}
78657881
LLVMValueRef ptr = build_ptr_cast (builder, addresses [ins->dreg]->value, pointer_type (LLVMInt8Type ()));
7866-
emit_memset (ctx, ptr, const_int32 (mono_class_value_size (klass, NULL)), 0);
7882+
emit_memset (ctx, ptr, NULL, const_int32 (mono_class_value_size (klass, NULL)), 0);
78677883
break;
78687884
}
78697885
case OP_DUMMY_VZERO:

src/mono/mono/mini/mini-ops.h

+1
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,7 @@ MINI_OP(OP_LDELEMA2D, "ldelema2d", NONE, NONE, NONE)
775775
MINI_OP(OP_MEMCPY, "memcpy", NONE, NONE, NONE)
776776
/* inlined small memset with constant length */
777777
MINI_OP(OP_MEMSET, "memset", NONE, NONE, NONE)
778+
MINI_OP(OP_MEMSET_ZERO, "memset_zero", NONE, IREG, IREG)
778779
/*
779780
* A RuntimeType object, the result ldtoken+GetTypeFromHandle.
780781
* inst_p0 is a MonoClass.

0 commit comments

Comments
 (0)