X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fssa.c;h=d58d814e11fb0685d48c275cc497a968b8ab034a;hb=32455dbbe90d3f7826a2bae5a95360e050f04172;hp=25bc360bcab93864c78dd834aa573ff5e3f35068;hpb=0e93962a241c0e0567043a8d731cc6fdc36253bc;p=mono.git diff --git a/mono/mini/ssa.c b/mono/mini/ssa.c index 25bc360bcab..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) @@ -383,7 +382,7 @@ mono_ssa_compute (MonoCompile *cfg) MonoInst *var = cfg->varinfo [i]; #if SIZEOF_REGISTER == 4 - if (var->type == STACK_I8) + if (var->type == STACK_I8 && !COMPILE_LLVM (cfg)) continue; #endif if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) @@ -407,7 +406,7 @@ mono_ssa_compute (MonoCompile *cfg) /* fixme: create pruned SSA? we would need liveness information for that */ - if (bb == cfg->bb_exit) + if (bb == cfg->bb_exit && !COMPILE_LLVM (cfg)) continue; if ((cfg->comp_done & MONO_COMP_LIVENESS) && !mono_bitset_test_fast (bb->live_in_set, i)) { @@ -430,10 +429,14 @@ mono_ssa_compute (MonoCompile *cfg) break; case STACK_VTYPE: ins->opcode = MONO_CLASS_IS_SIMD (cfg, var->klass) ? OP_XPHI : OP_VPHI; - ins->klass = var->klass; break; } + if (var->inst_vtype->byref) + ins->klass = mono_defaults.int_class; + else + ins->klass = var->klass; + ins->inst_phi_args = mono_mempool_alloc0 (cfg->mempool, sizeof (int) * (cfg->bblocks [idx]->in_count + 1)); ins->inst_phi_args [0] = cfg->bblocks [idx]->in_count; @@ -468,6 +471,8 @@ mono_ssa_compute (MonoCompile *cfg) mono_ssa_rename_vars (cfg, cfg->num_varinfo, cfg->bb_entry, originals, stack, lvreg_stack, lvreg_defined, stack_history, stack_history_size); g_free (stack_history); g_free (originals); + g_free (lvreg_stack); + g_free (lvreg_defined); if (cfg->verbose_level >= 4) printf ("\nEND COMPUTE SSA.\n\n"); @@ -479,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); @@ -547,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) @@ -576,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) { @@ -679,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) { @@ -689,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) @@ -1103,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]); } @@ -1162,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) { @@ -1173,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)