Skip to content

Commit 68e4d5a

Browse files
authored
Merge pull request #1339 from Unity-Technologies/unity-master-fix-1276888
Fix performance regression due to ldfld usage by Roslyn (case 1276888)
2 parents 4c55376 + 844813b commit 68e4d5a

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

mono/mini/method-to-ir.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7076,6 +7076,21 @@ is_supported_tail_call (MonoCompile *cfg, MonoMethod *method, MonoMethod *cmetho
70767076
return supported_tail_call;
70777077
}
70787078

7079+
/*
7080+
* is_adressable_valuetype_load
7081+
*
7082+
* Returns true if a previous load can be done without doing an extra copy, given the new instruction ip and the type of the object being loaded ldtype
7083+
*/
7084+
static gboolean
7085+
is_adressable_valuetype_load (MonoCompile* cfg, guint8* ip, MonoType* ldtype)
7086+
{
7087+
/* Avoid loading a struct just to load one of its fields */
7088+
gboolean is_load_instruction = (*ip == CEE_LDFLD);
7089+
gboolean is_in_previous_bb = ip_in_bb(cfg, cfg->cbb, ip);
7090+
gboolean is_struct = MONO_TYPE_ISSTRUCT(ldtype);
7091+
return is_load_instruction && is_in_previous_bb && is_struct;
7092+
}
7093+
70797094
/*
70807095
* handle_ctor_call:
70817096
*
@@ -7851,7 +7866,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
78517866
CHECK_STACK_OVF (1);
78527867
n = (*ip)-CEE_LDARG_0;
78537868
CHECK_ARG (n);
7854-
EMIT_NEW_ARGLOAD (cfg, ins, n);
7869+
if (is_adressable_valuetype_load (cfg, ip + 1, cfg->arg_types[n])) {
7870+
EMIT_NEW_ARGLOADA (cfg, ins, n);
7871+
} else {
7872+
EMIT_NEW_ARGLOAD (cfg, ins, n);
7873+
}
78557874
ip++;
78567875
*sp++ = ins;
78577876
break;
@@ -7862,7 +7881,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
78627881
CHECK_STACK_OVF (1);
78637882
n = (*ip)-CEE_LDLOC_0;
78647883
CHECK_LOCAL (n);
7865-
EMIT_NEW_LOCLOAD (cfg, ins, n);
7884+
if (is_adressable_valuetype_load (cfg, ip + 1, header->locals[n])) {
7885+
EMIT_NEW_LOCLOADA (cfg, ins, n);
7886+
} else {
7887+
EMIT_NEW_LOCLOAD (cfg, ins, n);
7888+
}
78667889
ip++;
78677890
*sp++ = ins;
78687891
break;
@@ -7886,7 +7909,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
78867909
CHECK_STACK_OVF (1);
78877910
n = ip [1];
78887911
CHECK_ARG (n);
7889-
EMIT_NEW_ARGLOAD (cfg, ins, n);
7912+
if (is_adressable_valuetype_load (cfg, ip + 2, cfg->arg_types[n])) {
7913+
EMIT_NEW_ARGLOADA (cfg, ins, n);
7914+
} else {
7915+
EMIT_NEW_ARGLOAD (cfg, ins, n);
7916+
}
78907917
*sp++ = ins;
78917918
ip += 2;
78927919
break;
@@ -7916,8 +7943,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
79167943
CHECK_STACK_OVF (1);
79177944
n = ip [1];
79187945
CHECK_LOCAL (n);
7919-
if ((ip [2] == CEE_LDFLD) && ip_in_bb (cfg, cfg->cbb, ip + 2) && MONO_TYPE_ISSTRUCT (header->locals [n])) {
7920-
/* Avoid loading a struct just to load one of its fields */
7946+
if (is_adressable_valuetype_load (cfg, ip + 2, header->locals[n])) {
79217947
EMIT_NEW_LOCLOADA (cfg, ins, n);
79227948
} else {
79237949
EMIT_NEW_LOCLOAD (cfg, ins, n);
@@ -12428,7 +12454,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
1242812454
CHECK_OPSIZE (4);
1242912455
n = read16 (ip + 2);
1243012456
CHECK_ARG (n);
12431-
EMIT_NEW_ARGLOAD (cfg, ins, n);
12457+
if (is_adressable_valuetype_load (cfg, ip + 4, cfg->arg_types[n])) {
12458+
EMIT_NEW_ARGLOADA (cfg, ins, n);
12459+
} else {
12460+
EMIT_NEW_ARGLOAD (cfg, ins, n);
12461+
}
1243212462
*sp++ = ins;
1243312463
ip += 4;
1243412464
break;
@@ -12458,8 +12488,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
1245812488
CHECK_OPSIZE (4);
1245912489
n = read16 (ip + 2);
1246012490
CHECK_LOCAL (n);
12461-
if ((ip [4] == CEE_LDFLD) && ip_in_bb (cfg, cfg->cbb, ip + 4) && MONO_TYPE_ISSTRUCT (header->locals [n])) {
12462-
/* Avoid loading a struct just to load one of its fields */
12491+
if (is_adressable_valuetype_load (cfg, ip + 4, header->locals[n])) {
1246312492
EMIT_NEW_LOCLOADA (cfg, ins, n);
1246412493
} else {
1246512494
EMIT_NEW_LOCLOAD (cfg, ins, n);

0 commit comments

Comments
 (0)