Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/6.0] [mono] Use SROA-friendly struct type declarations #59060

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,23 +529,27 @@ ThisType (void)
return TARGET_SIZEOF_VOID_P == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
}

typedef struct {
int32_t size;
uint32_t align;
} MonoSizeAlign;

/*
* get_vtype_size:
*
* Return the size of the LLVM representation of the vtype T.
*/
static guint32
get_vtype_size (MonoType *t)
static MonoSizeAlign
get_vtype_size_align (MonoType *t)
{
int size;

size = mono_class_value_size (mono_class_from_mono_type_internal (t), NULL);
uint32_t align = 0;
int32_t size = mono_class_value_size (mono_class_from_mono_type_internal (t), &align);

/* LLVMArgAsIArgs depends on this since it stores whole words */
while (size < 2 * TARGET_SIZEOF_VOID_P && mono_is_power_of_two (size) == -1)
size ++;

return size;
MonoSizeAlign ret = { size, align };
return ret;
}

/*
Expand Down Expand Up @@ -680,11 +684,17 @@ create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
for (i = 0; i < size; ++i)
eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
} else {
size = get_vtype_size (t);

eltypes = g_new (LLVMTypeRef, size);
for (i = 0; i < size; ++i)
eltypes [i] = LLVMInt8Type ();
MonoSizeAlign size_align = get_vtype_size_align (t);
eltypes = g_new (LLVMTypeRef, size_align.size);
size = 0;
uint32_t bytes = 0;
uint32_t chunk = size_align.align < TARGET_SIZEOF_VOID_P ? size_align.align : TARGET_SIZEOF_VOID_P;
for (; chunk > 0; chunk = chunk >> 1) {
for (; (bytes + chunk) <= size_align.size; bytes += chunk) {
eltypes [size] = LLVMIntType (chunk * 8);
++size;
}
}
}

name = mono_type_full_name (m_class_get_byval_arg (klass));
Expand Down Expand Up @@ -2671,11 +2681,11 @@ static void
emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
{
int pindex = 0;
int j, size, nslots;
int j, nslots;
LLVMTypeRef arg_type;

t = mini_get_underlying_type (t);
size = get_vtype_size (t);
int32_t size = get_vtype_size_align (t).size;

if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (t)))
address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
Expand Down Expand Up @@ -7341,7 +7351,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
} else if (ainfo->storage == LLVMArgVtypeAddr || values [ins->sreg1] == addresses [ins->sreg1]) {
/* LLVMArgVtypeByRef/LLVMArgVtypeAddr, have to make a copy */
addresses [ins->dreg] = build_alloca (ctx, t);
LLVMValueRef v = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
LLVMValueRef v = LLVMBuildLoad (builder, addresses [ins->sreg1], "llvm_outarg_vt_copy");
LLVMBuildStore (builder, convert (ctx, v, type_to_llvm_type (ctx, t)), addresses [ins->dreg]);
} else {
addresses [ins->dreg] = addresses [ins->sreg1];
Expand Down