X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Falias-analysis.c;h=c260dae2c7abcf706b005ef0fc5f7e10ea103c50;hb=48992d4b3f8b568be17180372160d2f3e03b8ccb;hp=9289285c95aef03e3e526f33054426e90a15a5c8;hpb=e2812813f9cd0a9342982f42f8b8b9818132a7fb;p=mono.git diff --git a/mono/mini/alias-analysis.c b/mono/mini/alias-analysis.c index 9289285c95a..c260dae2c7a 100644 --- a/mono/mini/alias-analysis.c +++ b/mono/mini/alias-analysis.c @@ -156,6 +156,7 @@ lower_memory_access (MonoCompile *cfg) g_hash_table_remove_all (addr_loads); for (ins = bb->code; ins; ins = ins->next) { +handle_instruction: switch (ins->opcode) { case OP_LDADDR: g_hash_table_insert (addr_loads, GINT_TO_POINTER (ins->dreg), ins); @@ -197,7 +198,11 @@ lower_memory_access (MonoCompile *cfg) tmp = g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->sreg1)); if (tmp) { if (cfg->verbose_level > 2) { printf ("Found candidate load:"); mono_print_ins (ins); } - needs_dce |= lower_load (cfg, ins, tmp); + if (lower_load (cfg, ins, tmp)) { + needs_dce = TRUE; + /* Try to propagate known aliases if an OP_MOVE was inserted */ + goto handle_instruction; + } } break; @@ -214,7 +219,11 @@ lower_memory_access (MonoCompile *cfg) tmp = g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->dreg)); if (tmp) { if (cfg->verbose_level > 2) { printf ("Found candidate store:"); mono_print_ins (ins); } - needs_dce |= lower_store (cfg, ins, tmp); + if (lower_store (cfg, ins, tmp)) { + needs_dce = TRUE; + /* Try to propagate known aliases if an OP_MOVE was inserted */ + goto handle_instruction; + } } break; @@ -229,6 +238,15 @@ lower_memory_access (MonoCompile *cfg) needs_dce |= lower_store_imm (cfg, ins, tmp); } break; + case OP_CHECK_THIS: + case OP_NOT_NULL: + tmp = g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->sreg1)); + if (tmp) { + if (cfg->verbose_level > 2) { printf ("Found null check over local: "); mono_print_ins (ins); } + NULLIFY_INS (ins); + needs_dce = TRUE; + } + break; } } } @@ -237,13 +255,14 @@ lower_memory_access (MonoCompile *cfg) } static gboolean -recompute_aliased_variables (MonoCompile *cfg) +recompute_aliased_variables (MonoCompile *cfg, int *restored_vars) { int i; MonoBasicBlock *bb; MonoInst *ins; int kills = 0; int adds = 0; + *restored_vars = 0; for (i = 0; i < cfg->num_varinfo; i++) { MonoInst *var = cfg->varinfo [i]; @@ -268,14 +287,15 @@ recompute_aliased_variables (MonoCompile *cfg) var = (MonoInst*)ins->inst_p0; if (!(var->flags & MONO_INST_INDIRECT)) { - if (cfg->verbose_level) { printf ("Restoring :"); mono_print_ins (var); } + if (cfg->verbose_level > 1) { printf ("Restoring :"); mono_print_ins (var); } ++adds; } var->flags |= MONO_INST_INDIRECT; } } } - + *restored_vars = adds; + mono_jit_stats.alias_found += kills; mono_jit_stats.alias_removed += kills - adds; if (kills > adds) { @@ -299,6 +319,7 @@ TODO: void mono_local_alias_analysis (MonoCompile *cfg) { + int i, restored_vars = 1; if (!cfg->has_indirection) return; @@ -319,17 +340,18 @@ mono_local_alias_analysis (MonoCompile *cfg) /* Some variables no longer need to be flagged as indirect, find them. + Since indirect vars are converted into global vregs, each pass eliminates only one level of indirection. + Most cases only need one pass and some 2. */ - if (!recompute_aliased_variables (cfg)) - goto done; - - /* - A lot of simplification just took place, we recompute local variables and do DCE to - really profit from the previous gains - */ - mono_handle_global_vregs (cfg); - if (cfg->opt & MONO_OPT_DEADCE) - mono_local_deadce (cfg); + for (i = 0; i < 3 && restored_vars > 0 && recompute_aliased_variables (cfg, &restored_vars); ++i) { + /* + A lot of simplification just took place, we recompute local variables and do DCE to + really profit from the previous gains + */ + mono_handle_global_vregs (cfg); + if (cfg->opt & MONO_OPT_DEADCE) + mono_local_deadce (cfg); + } done: if (cfg->verbose_level > 2)