Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormonojenkins <jo.shields+jenkins@xamarin.com>2018-03-07 17:54:59 +0300
committerLudovic Henry <luhenry@microsoft.com>2018-03-07 17:54:59 +0300
commit30441ea0ac8fa090d8fb88ad5ed79b4d84212a3b (patch)
tree97a80a5862321f8231167f8e3e81e3b1cf428ccb
parent835a98d855921868c27d6672814cc1d0e44f32fd (diff)
* Generalize commit 0c6932a985175a5cf0cbc59ffd3af4abf3db248e to support LDARG{0|1|2|3}, LDLOC{0|1|2|3}, LDARGS, LDLOCS, LDARG and LDLOC instead of LDLOC and LDLOCS. Improves generated code similar to issue #60945 (#7444)
-rw-r--r--mono/mini/method-to-ir.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c
index c9eab068478..3185a203fe8 100644
--- a/mono/mini/method-to-ir.c
+++ b/mono/mini/method-to-ir.c
@@ -7066,6 +7066,21 @@ is_supported_tail_call (MonoCompile *cfg, MonoMethod *method, MonoMethod *cmetho
}
/*
+ * is_adressable_valuetype_load
+ *
+ * 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
+ */
+static gboolean
+is_adressable_valuetype_load (MonoCompile* cfg, guint8* ip, MonoType* ldtype)
+{
+ /* Avoid loading a struct just to load one of its fields */
+ gboolean is_load_instruction = (*ip == CEE_LDFLD);
+ gboolean is_in_previous_bb = ip_in_bb(cfg, cfg->cbb, ip);
+ gboolean is_struct = MONO_TYPE_ISSTRUCT(ldtype);
+ return is_load_instruction && is_in_previous_bb && is_struct;
+}
+
+/*
* handle_ctor_call:
*
* Handle calls made to ctors from NEWOBJ opcodes.
@@ -7837,7 +7852,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
CHECK_STACK_OVF (1);
n = (*ip)-CEE_LDARG_0;
CHECK_ARG (n);
- EMIT_NEW_ARGLOAD (cfg, ins, n);
+ if (is_adressable_valuetype_load (cfg, ip + 1, cfg->arg_types[n])) {
+ EMIT_NEW_ARGLOADA (cfg, ins, n);
+ } else {
+ EMIT_NEW_ARGLOAD (cfg, ins, n);
+ }
ip++;
*sp++ = ins;
break;
@@ -7848,7 +7867,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
CHECK_STACK_OVF (1);
n = (*ip)-CEE_LDLOC_0;
CHECK_LOCAL (n);
- EMIT_NEW_LOCLOAD (cfg, ins, n);
+ if (is_adressable_valuetype_load (cfg, ip + 1, header->locals[n])) {
+ EMIT_NEW_LOCLOADA (cfg, ins, n);
+ } else {
+ EMIT_NEW_LOCLOAD (cfg, ins, n);
+ }
ip++;
*sp++ = ins;
break;
@@ -7872,7 +7895,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
CHECK_STACK_OVF (1);
n = ip [1];
CHECK_ARG (n);
- EMIT_NEW_ARGLOAD (cfg, ins, n);
+ if (is_adressable_valuetype_load (cfg, ip + 2, cfg->arg_types[n])) {
+ EMIT_NEW_ARGLOADA (cfg, ins, n);
+ } else {
+ EMIT_NEW_ARGLOAD (cfg, ins, n);
+ }
*sp++ = ins;
ip += 2;
break;
@@ -7902,8 +7929,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
CHECK_STACK_OVF (1);
n = ip [1];
CHECK_LOCAL (n);
- if ((ip [2] == CEE_LDFLD) && ip_in_bb (cfg, cfg->cbb, ip + 2) && MONO_TYPE_ISSTRUCT (header->locals [n])) {
- /* Avoid loading a struct just to load one of its fields */
+ if (is_adressable_valuetype_load (cfg, ip + 2, header->locals[n])) {
EMIT_NEW_LOCLOADA (cfg, ins, n);
} else {
EMIT_NEW_LOCLOAD (cfg, ins, n);
@@ -12365,7 +12391,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
CHECK_OPSIZE (4);
n = read16 (ip + 2);
CHECK_ARG (n);
- EMIT_NEW_ARGLOAD (cfg, ins, n);
+ if (is_adressable_valuetype_load (cfg, ip + 4, cfg->arg_types[n])) {
+ EMIT_NEW_ARGLOADA (cfg, ins, n);
+ } else {
+ EMIT_NEW_ARGLOAD (cfg, ins, n);
+ }
*sp++ = ins;
ip += 4;
break;
@@ -12395,8 +12425,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
CHECK_OPSIZE (4);
n = read16 (ip + 2);
CHECK_LOCAL (n);
- if ((ip [4] == CEE_LDFLD) && ip_in_bb (cfg, cfg->cbb, ip + 4) && header->locals [n]->type == MONO_TYPE_VALUETYPE) {
- /* Avoid loading a struct just to load one of its fields */
+ if (is_adressable_valuetype_load (cfg, ip + 4, header->locals[n])) {
EMIT_NEW_LOCLOADA (cfg, ins, n);
} else {
EMIT_NEW_LOCLOAD (cfg, ins, n);