X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fssa.c;h=d58d814e11fb0685d48c275cc497a968b8ab034a;hb=0d40321933ac575314ab51efa3c62e8cf535a9d2;hp=df6d69ff167bdbec702ad6404a5444b8a40c3f8a;hpb=7bd0a7c7f857a2613876c09b061c8fac5ccb5da1;p=mono.git diff --git a/mono/mini/ssa.c b/mono/mini/ssa.c index df6d69ff167..d58d814e11f 100644 --- a/mono/mini/ssa.c +++ b/mono/mini/ssa.c @@ -5,6 +5,7 @@ * Dietmar Maurer (dietmar@ximian.com) * * (C) 2003 Ximian, Inc. + * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) */ #include #include @@ -268,7 +269,7 @@ mono_ssa_rename_vars (MonoCompile *cfg, int max_vars, MonoBasicBlock *bb, gboole } else if (G_UNLIKELY (!var && lvreg_defined [ins->dreg] && (ins->dreg >= MONO_MAX_IREGS))) { /* Perform renaming for local vregs */ - lvreg_stack [ins->dreg] = mono_alloc_preg (cfg); + lvreg_stack [ins->dreg] = vreg_is_ref (cfg, ins->dreg) ? mono_alloc_ireg_ref (cfg) : mono_alloc_preg (cfg); ins->dreg = lvreg_stack [ins->dreg]; } else @@ -340,8 +341,6 @@ mono_ssa_compute (MonoCompile *cfg) g_assert (!(cfg->comp_done & MONO_COMP_SSA)); - /* we dont support methods containing exception clauses */ - g_assert (mono_method_get_header (cfg->method)->num_clauses == 0); g_assert (!cfg->disable_ssa); if (cfg->verbose_level >= 4) @@ -485,7 +484,7 @@ void mono_ssa_remove (MonoCompile *cfg) { MonoInst *ins, *var, *move; - int i, j, first; + int bbindex, i, j, first; g_assert (cfg->comp_done & MONO_COMP_SSA); @@ -553,12 +552,12 @@ mono_ssa_remove (MonoCompile *cfg) * can coalesce them into the original variable. */ - for (i = 0; i < cfg->num_bblocks; ++i) { - MonoBasicBlock *bb = cfg->bblocks [i]; + for (bbindex = 0; bbindex < cfg->num_bblocks; ++bbindex) { + MonoBasicBlock *bb = cfg->bblocks [bbindex]; for (ins = bb->code; ins; ins = ins->next) { const char *spec = INS_INFO (ins->opcode); - int num_sregs, j; + int num_sregs; int sregs [MONO_MAX_SRC_REGS]; if (ins->opcode == OP_NOP) @@ -582,7 +581,7 @@ mono_ssa_remove (MonoCompile *cfg) } num_sregs = mono_inst_get_src_registers (ins, sregs); - for (j = 0; j < num_sregs; ++j) { + for (i = 0; i < num_sregs; ++i) { MonoInst *var = get_vreg_to_inst (cfg, sregs [i]); if (var) { @@ -685,7 +684,6 @@ mono_ssa_copyprop (MonoCompile *cfg) /* Rewrite all uses of var to be uses of var2 */ int dreg = var->dreg; int sreg1 = var2->dreg; - const char *spec; l = info->uses; while (l) { @@ -695,8 +693,6 @@ mono_ssa_copyprop (MonoCompile *cfg) int num_sregs; int sregs [MONO_MAX_SRC_REGS]; - spec = INS_INFO (ins->opcode); - num_sregs = mono_inst_get_src_registers (ins, sregs); for (i = 0; i < num_sregs; ++i) { if (sregs [i] == dreg) @@ -1109,7 +1105,7 @@ fold_ins (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, MonoInst **carray /* Unlink target bblocks */ for (i = 0; i < table->table_size; ++i) { - if (i != idx) { + if (table->table [i] != table->table [idx]) { remove_bb_from_phis (cfg, bb, table->table [i]); mono_unlink_bblock (cfg, bb, table->table [i]); } @@ -1168,6 +1164,15 @@ mono_ssa_cprop (MonoCompile *cfg) info->cpstate = 2; } + for (bb = cfg->bb_entry->next_bb; bb; bb = bb->next_bb) { + /* + * FIXME: This should be bb->flags & BB_FLAG_EXCEPTION_HANDLER, but + * that would still allow unreachable try's to be removed. + */ + if (bb->region) + add_cprop_bb (cfg, bb, &bblock_list); + } + cvars = NULL; while (bblock_list) { @@ -1179,11 +1184,13 @@ mono_ssa_cprop (MonoCompile *cfg) g_assert (bb->flags & BB_REACHABLE); - if (bb->out_count == 1) { - if (!(bb->out_bb [0]->flags & BB_REACHABLE)) { - bb->out_bb [0]->flags |= BB_REACHABLE; - bblock_list = g_list_prepend (bblock_list, bb->out_bb [0]); - } + /* + * Some bblocks are linked to 2 others even through they fall through to the + * next bblock. + */ + if (!(bb->last_ins && MONO_IS_BRANCH_OP (bb->last_ins))) { + for (i = 0; i < bb->out_count; ++i) + add_cprop_bb (cfg, bb->out_bb [i], &bblock_list); } if (cfg->verbose_level > 1)