Skip to content

Commit

Permalink
Wed Apr 7 11:28:42 CEST 2010 Paolo Molaro <lupus@ximian.com>
Browse files Browse the repository at this point in the history
	* method-to-ir.c: optimize array accesses from generic interfaces.


svn path=/trunk/mono/; revision=154918
  • Loading branch information
illupus committed Apr 7, 2010
1 parent 320e91e commit 3f610de
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
5 changes: 5 additions & 0 deletions mono/mini/ChangeLog
@@ -1,3 +1,8 @@

Wed Apr 7 11:28:42 CEST 2010 Paolo Molaro <lupus@ximian.com>

* method-to-ir.c: optimize array accesses from generic interfaces.

2010-04-06 Zoltan Varga <vargaz@gmail.com>

* mini-llvm.c: Update after the memset/memcpy intrinsics changes in LLVM SVN.
Expand Down
43 changes: 28 additions & 15 deletions mono/mini/method-to-ir.c
Expand Up @@ -3731,7 +3731,7 @@ mini_field_access_needs_cctor_run (MonoCompile *cfg, MonoMethod *method, MonoVTa
}

static MonoInst*
mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index)
mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index, gboolean bcheck)
{
MonoInst *ins;
guint32 size;
Expand Down Expand Up @@ -3762,7 +3762,8 @@ mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, Mono
}
#endif

MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index2_reg);
if (bcheck)
MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index2_reg);

#if defined(TARGET_X86) || defined(TARGET_AMD64)
if (size == 1 || size == 2 || size == 4 || size == 8) {
Expand Down Expand Up @@ -3856,7 +3857,7 @@ mini_emit_ldelema_ins (MonoCompile *cfg, MonoMethod *cmethod, MonoInst **sp, uns
rank = mono_method_signature (cmethod)->param_count - (is_set? 1: 0);

if (rank == 1)
return mini_emit_ldelema_1_ins (cfg, cmethod->klass->element_class, sp [0], sp [1]);
return mini_emit_ldelema_1_ins (cfg, cmethod->klass->element_class, sp [0], sp [1], TRUE);

#ifndef MONO_ARCH_EMULATE_MUL_DIV
/* emit_ldelema_2 depends on OP_LMUL */
Expand Down Expand Up @@ -3919,6 +3920,25 @@ should_insert_brekpoint (MonoMethod *method) {
}
}

/* optimize the simple GetGenericValueImpl/SetGenericValueImpl generic icalls */
static MonoInst*
emit_array_generic_access (MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst **args, int is_set)
{
MonoInst *addr, *store, *load;
MonoClass *eklass = mono_class_from_mono_type (fsig->params [2]);

/* the bounds check is already done by the callers */
addr = mini_emit_ldelema_1_ins (cfg, eklass, args [0], args [1], FALSE);
if (is_set) {
EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, &eklass->byval_arg, args [2]->dreg, 0);
EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, &eklass->byval_arg, addr->dreg, 0, load->dreg);
} else {
EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, &eklass->byval_arg, addr->dreg, 0);
EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, &eklass->byval_arg, args [2]->dreg, 0, load->dreg);
}
return store;
}

static MonoInst*
mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
Expand Down Expand Up @@ -4007,6 +4027,8 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
} else
return NULL;
} else if (cmethod->klass == mono_defaults.array_class) {
if (strcmp (cmethod->name + 1, "etGenericValueImpl") == 0)
return emit_array_generic_access (cfg, fsig, args, *cmethod->name == 'S');
if (cmethod->name [0] != 'g')
return NULL;

Expand Down Expand Up @@ -4097,15 +4119,6 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign

return (MonoInst*)mono_emit_method_call (cfg, fast_method, args, NULL);
#endif
} else if (mini_class_is_system_array (cmethod->klass) &&
strcmp (cmethod->name, "GetGenericValueImpl") == 0) {
MonoInst *addr, *store, *load;
MonoClass *eklass = mono_class_from_mono_type (fsig->params [1]);

addr = mini_emit_ldelema_1_ins (cfg, eklass, args [0], args [1]);
EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, &eklass->byval_arg, addr->dreg, 0);
EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, &eklass->byval_arg, args [2]->dreg, 0, load->dreg);
return store;
} else if (cmethod->klass->image == mono_defaults.corlib &&
(strcmp (cmethod->klass->name_space, "System.Threading") == 0) &&
(strcmp (cmethod->klass->name, "Interlocked") == 0)) {
Expand Down Expand Up @@ -8489,7 +8502,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
}

readonly = FALSE;
ins = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1]);
ins = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE);
*sp++ = ins;
ip += 5;
break;
Expand Down Expand Up @@ -8533,7 +8546,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg);
EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, array_reg, offset);
} else {
addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1]);
addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE);
EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, addr->dreg, 0);
}
*sp++ = ins;
Expand Down Expand Up @@ -8597,7 +8610,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg);
EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, array_reg, offset, sp [2]->dreg);
} else {
addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1]);
addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE);
EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, addr->dreg, 0, sp [2]->dreg);
}
}
Expand Down

0 comments on commit 3f610de

Please sign in to comment.