Skip to content
Merged
Show file tree
Hide file tree
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 @@ -530,23 +530,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 @@ -681,11 +685,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);
Copy link
Copy Markdown
Member

@lambdageek lambdageek Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imhameed, I'm curious, why do we use these element types that don't have anything to do with the actual elements of the original Mono type (and presumably we bitcast at the use sites?). Why not use the field layout of the Mono type to create the LLVM struct? (ie: for a mono class int x; double y; represent it as int32 x; int32 padding; double y instead of I think int32 el0; int32 el1; int32 el2; int32 el3)?

Is it to limit the number of unique llvm types that we have to create?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were only doing it for simplicity i think.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imhameed, I'm curious, why do we use these element types that don't have anything to do with the actual elements of the original Mono type (and presumably we bitcast at the use sites?). Why not use the field layout of the Mono type to create the LLVM struct? (ie: for a mono class int x; double y; represent it as int32 x; int32 padding; double y instead of I think int32 el0; int32 el1; int32 el2; int32 el3)?

Simplicity, mostly. The diff is small. I'd like to more accurately represent IL types in our LLVM IR in the future.

Reads and writes of individual fields are done via normal loads/stores, pointer coercion, and getelementpointer.

++size;
}
}
}

name = mono_type_full_name (m_class_get_byval_arg (klass));
Expand Down Expand Up @@ -2672,11 +2682,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 @@ -7342,7 +7352,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
3 changes: 0 additions & 3 deletions src/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2317,9 +2317,6 @@
<ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/CLR-x86-JIT/V1.1-M1-Beta1/b143840/b143840/*">
<Issue>https://github.com/dotnet/runtime/issues/48914</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/JIT/Performance/CodeQuality/Roslyn/CscBench/**">
<Issue>https://github.com/dotnet/runtime/issues/58062</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/tracing/eventpipe/eventsourceerror/**">
<Issue> needs triage </Issue>
</ExcludeList>
Expand Down