Author: zoltan
Date: 2008-01-02 11:55:59 -0500 (Wed, 02 Jan 2008)
New Revision: 92117
Modified:
branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog
branches/vargaz/mini-linear-il/mono/mono/mini/local-propagation.c
branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c
branches/vargaz/mini-linear-il/mono/mono/mini/mini-codegen.c
branches/vargaz/mini-linear-il/mono/mono/mini/mini.c
branches/vargaz/mini-linear-il/mono/mono/mini/mini.h
branches/vargaz/mini-linear-il/mono/mono/mini/ssa2.c
Log:
2008-01-02 Zoltan Varga <[EMAIL PROTECTED]>
* method-to-ir.c (MONO_EMIT_NEW_BRANCH_BLOCK): Don't start a new basic
block here.
(mono_op_to_op_imm): Add OP_AMD64_ICOMPARE_MEMBASE_IMM.
* mini.h (MonoBasicBlock): Add an 'extended' flag to mark whenever this
bblock
is extended.
* mini.h (MonoCompile): Add a 'disable_extended_bblocks' flag.
* mini.c (optimize_branches): Add an optimization for merging basic
blocks into
an extended basic block.
* local-propagation.c ssa2.c mini-codegen.c: Add support for extended
basic
blocks.
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog 2008-01-02
16:53:11 UTC (rev 92116)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog 2008-01-02
16:55:59 UTC (rev 92117)
@@ -1,3 +1,19 @@
+2008-01-02 Zoltan Varga <[EMAIL PROTECTED]>
+
+ * method-to-ir.c (MONO_EMIT_NEW_BRANCH_BLOCK): Don't start a new basic
block here.
+ (mono_op_to_op_imm): Add OP_AMD64_ICOMPARE_MEMBASE_IMM.
+
+ * mini.h (MonoBasicBlock): Add an 'extended' flag to mark whenever this
bblock
+ is extended.
+
+ * mini.h (MonoCompile): Add a 'disable_extended_bblocks' flag.
+
+ * mini.c (optimize_branches): Add an optimization for merging basic
blocks into
+ an extended basic block.
+
+ * local-propagation.c ssa2.c mini-codegen.c: Add support for extended
basic
+ blocks.
+
2007-12-22 Zoltan Varga <[EMAIL PROTECTED]>
* cpu-amd64.md: Fix the size of int opcodes.
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/local-propagation.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/local-propagation.c
2008-01-02 16:53:11 UTC (rev 92116)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/local-propagation.c
2008-01-02 16:55:59 UTC (rev 92117)
@@ -1245,7 +1245,10 @@
guint32 *def_index;
int max = cfg->next_vreg;
+#if SIZEOF_VOID_P == 4
restart:
+#endif
+
defs = mono_mempool_alloc (cfg->mempool, sizeof (MonoInst*) *
(cfg->next_vreg + 1));
def_index = mono_mempool_alloc (cfg->mempool, sizeof (guint32) *
(cfg->next_vreg + 1));
@@ -1747,7 +1750,7 @@
* assignment to the same vreg later in the
same bblock.
*/
if (!mono_bitset_test_fast (used, ins->dreg) &&
- (!get_vreg_to_inst (cfg, ins->dreg) ||
(!vreg_is_volatile (cfg, ins->dreg) && mono_bitset_test_fast (defined,
ins->dreg)))) {
+ (!get_vreg_to_inst (cfg, ins->dreg) ||
(!bb->extended && !vreg_is_volatile (cfg, ins->dreg) && mono_bitset_test_fast
(defined, ins->dreg)))) {
/* FIXME: Add more instructions */
/* OP_ADD_IMM is generated by
spill_global_vars */
if (MONO_IS_MOVE (ins) || (ins->opcode
== OP_ICONST) || (ins->opcode == OP_I8CONST) || (ins->opcode == OP_VZERO) ||
(ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_R8CONST) || (ins->opcode ==
OP_LADD_IMM)) {
@@ -1814,13 +1817,15 @@
void
mono_branch_to_cmov (MonoCompile *cfg)
{
-#ifdef MONO_ARCH_HAVE_CMOV_OPTS
+#ifdef MONO_ARCH_HAVE_CMOV_OPS
MonoBasicBlock *bb;
gboolean changed = FALSE;
if (!(cfg->opt & MONO_OPT_CMOV))
return;
+ // FIXME: Make this work with extended bblocks
+
/*
* This pass requires somewhat optimized IR code so it should be run
after
* local cprop/deadce. Also, it should be run before dominator
computation, since
@@ -1840,7 +1845,7 @@
* <var> <- <b>
* br BB3
*/
- if (bb->out_count != 2)
+ if (!(bb->out_count == 2 && !bb->extended))
continue;
bb1 = bb->out_bb [0];
@@ -1999,7 +2004,7 @@
if ((bb->out_bb [0]->in_count == 1) && (bb->out_bb [0]
!= cfg->bb_exit) &&
(bb->region == bb->out_bb [0]->region)) {
// FIXME:
- mono_merge_basic_blocks (bb, bb->out_bb [0]);
+ mono_merge_basic_blocks (cfg, bb, bb->out_bb
[0]);
}
}
@@ -2140,11 +2145,46 @@
/* Merge bb and its successor if possible */
if ((bb->out_bb [0]->in_count == 1) && (bb->out_bb [0]
!= cfg->bb_exit) &&
(bb->region == bb->out_bb [0]->region)) {
- mono_merge_basic_blocks (bb, bb->out_bb [0]);
+ mono_merge_basic_blocks (cfg, bb, bb->out_bb
[0]);
}
}
}
+#if 0
+ for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+ MonoBasicBlock *bb1, *bb2;
+ MonoInst *prev, *compare, *branch, *ins1, *ins2, *cmov, *move,
*tmp;
+ gboolean simple, ret;
+ int dreg, tmp_reg;
+ CompType comp_type;
+
+ /* Look for the IR code generated from if (cond) <var> <- <a>
+ * after branch opts which is:
+ * BB:
+ * compare
+ * b<cond> [BB1]
+ * <var> <- <a>
+ * BB1:
+ */
+ if (!(bb->out_count == 1 && bb->extended && bb->code &&
bb->code->next && bb->code->next->next))
+ continue;
+
+ mono_print_bb (bb, "");
+
+ /* Find the compare instruction */
+ prev = NULL;
+ compare = bb->code;
+ g_assert (compare);
+ while (compare->next->next && compare->next->next !=
bb->last_ins) {
+ prev = compare;
+ compare = compare->next;
+ }
+ branch = compare->next;
+ if (!MONO_IS_COND_BRANCH_OP (branch))
+ continue;
+ }
+#endif
+
if (changed) {
if (cfg->opt & MONO_OPT_BRANCH)
mono_optimize_branches (cfg);
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c
2008-01-02 16:53:11 UTC (rev 92116)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c
2008-01-02 16:55:59 UTC (rev 92117)
@@ -878,25 +878,64 @@
MONO_INST_NEW ((cfg), (inst), OP_LABEL); \
} while (0)
-/* Emit a one-way conditional branch and start a new basic block */
-#define MONO_EMIT_NEW_BRANCH_BLOCK(cfg,op,truebb) do { \
+/* Emit a one-way conditional branch */
+/*
+ * The inst_false_bb field of the cond branch will not be set, the JIT code
should be
+ * prepared to deal with this.
+ */
+#ifdef DEBUG_EXTENDED_BBLOCKS
+static int ccount = 0;
+#define MONO_EMIT_NEW_BRANCH_BLOCK(cfg,op,truebb) do { \
MonoInst *ins; \
MonoBasicBlock *falsebb; \
- NEW_BBLOCK ((cfg), falsebb); \
MONO_INST_NEW ((cfg), (ins), (op)); \
if ((op) == OP_BR) { \
+ NEW_BBLOCK ((cfg), falsebb); \
ins->inst_target_bb = (truebb); \
link_bblock ((cfg), (cfg)->cbb, (truebb)); \
+ MONO_ADD_INS ((cfg)->cbb, ins); \
+ MONO_START_BB ((cfg), falsebb); \
} else { \
+ ccount ++; \
ins->inst_many_bb = mono_mempool_alloc (cfg->mempool,
sizeof(gpointer)*2); \
ins->inst_true_bb = (truebb); \
- ins->inst_false_bb = (falsebb); \
+ ins->inst_false_bb = NULL; \
link_bblock ((cfg), (cfg)->cbb, (truebb)); \
- link_bblock ((cfg), (cfg)->cbb, (falsebb)); \
+ MONO_ADD_INS ((cfg)->cbb, ins); \
+ if (getenv ("COUNT2") && ccount == atoi (getenv ("COUNT2")) - 1) {
printf ("HIT: %d\n", cfg->cbb->block_num); } \
+ if (getenv ("COUNT2") && ccount < atoi (getenv ("COUNT2"))) { \
+ cfg->cbb->extended = TRUE; \
+ } else { NEW_BBLOCK ((cfg), falsebb); ins->inst_false_bb =
(falsebb); link_bblock ((cfg), (cfg)->cbb, (falsebb)); MONO_START_BB ((cfg),
falsebb); } \
} \
- MONO_ADD_INS ((cfg)->cbb, ins); \
- MONO_START_BB ((cfg), falsebb); \
} while (0)
+#else
+#define MONO_EMIT_NEW_BRANCH_BLOCK(cfg,op,truebb) do { \
+ MonoInst *ins; \
+ MonoBasicBlock *falsebb; \
+ MONO_INST_NEW ((cfg), (ins), (op)); \
+ if ((op) == OP_BR) { \
+ NEW_BBLOCK ((cfg), falsebb); \
+ ins->inst_target_bb = (truebb); \
+ link_bblock ((cfg), (cfg)->cbb, (truebb)); \
+ MONO_ADD_INS ((cfg)->cbb, ins); \
+ MONO_START_BB ((cfg), falsebb); \
+ } else { \
+ ins->inst_many_bb = mono_mempool_alloc (cfg->mempool,
sizeof(gpointer)*2); \
+ ins->inst_true_bb = (truebb); \
+ ins->inst_false_bb = NULL; \
+ link_bblock ((cfg), (cfg)->cbb, (truebb)); \
+ MONO_ADD_INS ((cfg)->cbb, ins); \
+ if (cfg->disable_extended_bblocks) { \
+ NEW_BBLOCK ((cfg), falsebb); \
+ ins->inst_false_bb = falsebb; \
+ link_bblock ((cfg), (cfg)->cbb, (falsebb)); \
+ MONO_START_BB ((cfg), falsebb); \
+ } else { \
+ cfg->cbb->extended = TRUE; \
+ } \
+ } \
+ } while (0)
+#endif
/* Emit a two-way conditional branch */
#define MONO_EMIT_NEW_BRANCH_BLOCK2(cfg,op,truebb,falsebb) do { \
@@ -912,8 +951,11 @@
#define MONO_START_BB(cfg, bblock) do { \
ADD_BBLOCK ((cfg), (bblock)); \
- if (! (cfg->cbb->last_ins && ((cfg->cbb->last_ins->opcode == OP_BR) ||
(cfg->cbb->last_ins->opcode == OP_BR_REG) || MONO_IS_COND_BRANCH_OP
(cfg->cbb->last_ins)))) \
+ if (cfg->cbb->last_ins && MONO_IS_COND_BRANCH_OP (cfg->cbb->last_ins)
&& !cfg->cbb->last_ins->inst_false_bb) { \
+ cfg->cbb->last_ins->inst_false_bb = (bblock); \
link_bblock ((cfg), (cfg)->cbb, (bblock)); \
+ } else if (! (cfg->cbb->last_ins && ((cfg->cbb->last_ins->opcode ==
OP_BR) || (cfg->cbb->last_ins->opcode == OP_BR_REG) || MONO_IS_COND_BRANCH_OP
(cfg->cbb->last_ins)))) \
+ link_bblock ((cfg), (cfg)->cbb, (bblock)); \
(cfg)->cbb->next_bb = (bblock); \
(cfg)->cbb = (bblock); \
} while (0)
@@ -4342,14 +4384,14 @@
* Get rid of the begin and end bblocks if possible to aid local
* optimizations.
*/
- mono_merge_basic_blocks (prev_cbb, sbblock);
+ mono_merge_basic_blocks (cfg, prev_cbb, sbblock);
if ((prev_cbb->out_count == 1) && (prev_cbb->out_bb
[0]->in_count == 1) && (prev_cbb->out_bb [0] != ebblock))
- mono_merge_basic_blocks (prev_cbb, prev_cbb->out_bb
[0]);
+ mono_merge_basic_blocks (cfg, prev_cbb,
prev_cbb->out_bb [0]);
if ((ebblock->in_count == 1) && ebblock->in_bb [0]->out_count
== 1) {
MonoBasicBlock *prev = ebblock->in_bb [0];
- mono_merge_basic_blocks (prev, ebblock);
+ mono_merge_basic_blocks (cfg, prev, ebblock);
cfg->cbb = prev;
} else {
cfg->cbb = ebblock;
@@ -10040,7 +10082,10 @@
case OP_X86_COMPARE_MEMBASE_REG:
return OP_X86_COMPARE_MEMBASE_IMM;
#endif
-
+#if defined(__x86_64__)
+ case OP_AMD64_ICOMPARE_MEMBASE_REG:
+ return OP_AMD64_ICOMPARE_MEMBASE_IMM;
+#endif
case OP_VOIDCALL_REG:
return OP_VOIDCALL;
case OP_CALL_REG:
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-codegen.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-codegen.c
2008-01-02 16:53:11 UTC (rev 92116)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-codegen.c
2008-01-02 16:55:59 UTC (rev 92117)
@@ -301,8 +301,12 @@
case OP_LBGE_UN:
case OP_LBLE:
case OP_LBLE_UN:
- if (!(ins->flags & MONO_INST_BRLABEL))
- printf (" [B%dB%d]",
ins->inst_true_bb->block_num, ins->inst_false_bb->block_num);
+ if (!(ins->flags & MONO_INST_BRLABEL)) {
+ if (!ins->inst_false_bb)
+ printf (" [B%d]",
ins->inst_true_bb->block_num);
+ else
+ printf (" [B%dB%d]",
ins->inst_true_bb->block_num, ins->inst_false_bb->block_num);
+ }
break;
case OP_PHI:
case OP_FPHI: {
@@ -470,8 +474,12 @@
case OP_LBGE_UN:
case OP_LBLE:
case OP_LBLE_UN:
- if (!(ins->flags & MONO_INST_BRLABEL))
- printf (" [B%dB%d]", ins->inst_true_bb->block_num,
ins->inst_false_bb->block_num);
+ if (!(ins->flags & MONO_INST_BRLABEL)) {
+ if (!ins->inst_false_bb)
+ printf (" [B%d]", ins->inst_true_bb->block_num);
+ else
+ printf (" [B%dB%d]",
ins->inst_true_bb->block_num, ins->inst_false_bb->block_num);
+ }
break;
default:
break;
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini.c 2008-01-02
16:53:11 UTC (rev 92116)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini.c 2008-01-02
16:55:59 UTC (rev 92117)
@@ -926,6 +926,24 @@
}
}
+/*
+ * mono_bblocks_linked:
+ *
+ * Return whenever BB1 and BB2 are linked in the CFG.
+ */
+static gboolean
+mono_bblocks_linked (MonoBasicBlock *bb1, MonoBasicBlock *bb2)
+{
+ int i;
+
+ for (i = 0; i < bb1->out_count; ++i) {
+ if (bb1->out_bb [i] == bb2)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/**
* mono_find_block_region:
*
@@ -10787,71 +10805,47 @@
static void
replace_out_block_in_code (MonoBasicBlock *bb, MonoBasicBlock *orig,
MonoBasicBlock *repl) {
- MonoInst *inst;
+ MonoInst *ins;
- for (inst = bb->code; inst != NULL; inst = inst->next) {
- if (inst->opcode == OP_CALL_HANDLER) {
- if (inst->inst_target_bb == orig) {
- inst->inst_target_bb = repl;
- }
- }
- if (MONO_IS_JUMP_TABLE (inst)) {
- int i;
- MonoJumpInfoBBTable *table = MONO_JUMP_TABLE_FROM_INS
(inst);
- for (i = 0; i < table->table_size; i++ ) {
- if (table->table [i] == orig) {
- table->table [i] = repl;
- }
- }
- }
- }
- if (bb->last_ins != NULL) {
- switch (bb->last_ins->opcode) {
+ for (ins = bb->code; ins != NULL; ins = ins->next) {
+ switch (ins->opcode) {
case OP_BR:
- if (bb->last_ins->inst_target_bb == orig) {
- bb->last_ins->inst_target_bb = repl;
- }
+ if (ins->inst_target_bb == orig)
+ ins->inst_target_bb = repl;
break;
+ case OP_CALL_HANDLER:
+ if (ins->inst_target_bb == orig)
+ ins->inst_target_bb = repl;
+ break;
case OP_SWITCH: {
int i;
- int n = GPOINTER_TO_INT (bb->last_ins->klass);
+ int n = GPOINTER_TO_INT (ins->klass);
for (i = 0; i < n; i++ ) {
- if (bb->last_ins->inst_many_bb [i] == orig) {
- bb->last_ins->inst_many_bb [i] = repl;
- }
+ if (ins->inst_many_bb [i] == orig)
+ ins->inst_many_bb [i] = repl;
}
break;
}
default:
- if (MONO_IS_COND_BRANCH_OP (bb->last_ins)) {
- if (bb->last_ins->inst_true_bb == orig) {
- bb->last_ins->inst_true_bb = repl;
+ if (MONO_IS_COND_BRANCH_OP (ins)) {
+ if (ins->inst_true_bb == orig)
+ ins->inst_true_bb = repl;
+ if (ins->inst_false_bb == orig)
+ ins->inst_false_bb = repl;
+ } else if (MONO_IS_JUMP_TABLE (ins)) {
+ int i;
+ MonoJumpInfoBBTable *table =
MONO_JUMP_TABLE_FROM_INS (ins);
+ for (i = 0; i < table->table_size; i++ ) {
+ if (table->table [i] == orig)
+ table->table [i] = repl;
}
- if (bb->last_ins->inst_false_bb == orig) {
- bb->last_ins->inst_false_bb = repl;
- }
}
+
break;
}
}
}
-static void
-replace_basic_block (MonoBasicBlock *bb, MonoBasicBlock *orig, MonoBasicBlock
*repl)
-{
- int i, j;
-
- for (i = 0; i < bb->out_count; i++) {
- MonoBasicBlock *ob = bb->out_bb [i];
- for (j = 0; j < ob->in_count; j++) {
- if (ob->in_bb [j] == orig) {
- ob->in_bb [j] = repl;
- }
- }
- }
-
-}
-
/**
* Check if a bb is useless (is just made of NOPs and ends with an
* unconditional branch, or nothing).
@@ -10955,17 +10949,22 @@
}
void
-mono_merge_basic_blocks (MonoBasicBlock *bb, MonoBasicBlock *bbn)
+mono_merge_basic_blocks (MonoCompile *cfg, MonoBasicBlock *bb, MonoBasicBlock
*bbn)
{
MonoInst *inst;
+ MonoBasicBlock *prev_bb;
+ int i;
- bb->out_count = bbn->out_count;
- bb->out_bb = bbn->out_bb;
bb->has_array_access |= bbn->has_array_access;
+ bb->extended |= bbn->extended;
- replace_basic_block (bb, bbn, bb);
+ mono_unlink_bblock (cfg, bb, bbn);
+ for (i = 0; i < bbn->out_count; ++i)
+ mono_link_bblock (cfg, bb, bbn->out_bb [i]);
+ while (bbn->out_count)
+ mono_unlink_bblock (cfg, bbn, bbn->out_bb [0]);
- /* Nullify branch */
+ /* Handle the branch at the end of the bb */
for (inst = bb->code; inst != NULL; inst = inst->next) {
if (inst->opcode == OP_CALL_HANDLER) {
g_assert (inst->inst_target_bb == bbn);
@@ -10981,9 +10980,11 @@
/* Can't nullify this as later instructions depend on
it */
}
}
-
- /* Nullify branch at the end of bb */
- if (bb->last_ins && MONO_IS_BRANCH_OP (bb->last_ins)) {
+ if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins)) {
+ g_assert (bb->last_ins->inst_false_bb == bbn);
+ bb->last_ins->inst_false_bb = NULL;
+ bb->extended = TRUE;
+ } else if (bb->last_ins && MONO_IS_BRANCH_OP (bb->last_ins)) {
NULLIFY_INS (bb->last_ins);
}
@@ -10996,7 +10997,15 @@
bb->code = bbn->code;
bb->last_ins = bbn->last_ins;
}
- bb->next_bb = bbn->next_bb;
+ for (prev_bb = cfg->bb_entry; prev_bb && prev_bb->next_bb != bbn;
prev_bb = prev_bb->next_bb)
+ ;
+ if (prev_bb) {
+ prev_bb->next_bb = bbn->next_bb;
+ } else {
+ /* bbn might not be in the bb list yet */
+ if (bb->next_bb == bbn)
+ bb->next_bb = bbn->next_bb;
+ }
nullify_basic_block (bbn);
}
@@ -11233,12 +11242,11 @@
g_print ("br removal
triggered %d -> %d\n", bb->block_num, bbn->block_num);
}
- if (bbn->in_count == 1) {
-
+ if (bbn->in_count == 1 &&
!bb->extended) {
if (bbn != cfg->bb_exit) {
if (cfg->verbose_level
> 2)
g_print ("block
merge triggered %d -> %d\n", bb->block_num, bbn->block_num);
- mono_merge_basic_blocks
(bb, bbn);
+ mono_merge_basic_blocks
(cfg, bb, bbn);
changed = TRUE;
continue;
}
@@ -11310,7 +11318,8 @@
*/
bb->last_ins->opcode = OP_BR;
bb->last_ins->inst_target_bb =
taken_branch_target;
- mono_unlink_bblock (cfg, bb,
untaken_branch_target);
+ if (!bb->extended)
+ mono_unlink_bblock
(cfg, bb, untaken_branch_target);
changed = TRUE;
continue;
}
@@ -11340,7 +11349,7 @@
}
bbn = bb->last_ins->inst_false_bb;
- if (bb->region == bbn->region &&
bbn->code && bbn->code->opcode == OP_BR &&
+ if (bbn && bb->region == bbn->region &&
bbn->code && bbn->code->opcode == OP_BR &&
bbn->code->inst_target_bb->region
== bb->region) {
if (cfg->verbose_level > 2)
g_print ("cbranch2 to
branch triggered %d -> (%d) %d (0x%02x)\n",
@@ -11358,6 +11367,23 @@
changed = TRUE;
continue;
}
+
+ bbn = bb->last_ins->inst_false_bb;
+ /*
+ * If bb is an extended bb, it could
contain an inside branch to bbn.
+ * FIXME: Enable the optimization if
that is not true.
+ * If bblocks_linked () is true, then
merging bb and bbn
+ * would require addition of an extra
branch at the end of bbn
+ * slowing down loops.
+ */
+ if (cfg->new_ir && bbn && bb->region ==
bbn->region && bbn->in_count == 1 && !cfg->disable_extended_bblocks && bbn !=
cfg->bb_exit && !bb->extended && !bbn->out_of_line && !mono_bblocks_linked
(bbn, bb)) {
+ g_assert (bbn->in_bb [0] == bb);
+ if (cfg->verbose_level > 2)
+ g_print ("merge false
branch target triggered BB%d -> BB%d\n", bb->block_num, bbn->block_num);
+ mono_merge_basic_blocks (cfg,
bb, bbn);
+ changed = TRUE;
+ continue;
+ }
}
/* detect and optimize to unsigned compares
checks like: if (v < 0 || v > limit */
@@ -11370,7 +11396,7 @@
}
if (bb->last_ins && MONO_IS_COND_BRANCH_NOFP
(bb->last_ins)) {
- if
(bb->last_ins->inst_false_bb->out_of_line && (bb->region ==
bb->last_ins->inst_false_bb->region)) {
+ if (bb->last_ins->inst_false_bb &&
bb->last_ins->inst_false_bb->out_of_line && (bb->region ==
bb->last_ins->inst_false_bb->region)) {
/* Reverse the branch */
bb->last_ins->opcode =
reverse_branch_op (bb->last_ins->opcode);
bbn =
bb->last_ins->inst_false_bb;
@@ -11564,7 +11590,7 @@
for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
- bb->next_bb != bb->last_ins->inst_false_bb) {
+ bb->last_ins->inst_false_bb && bb->next_bb !=
bb->last_ins->inst_false_bb) {
/* we are careful when inverting, since bugs like #59580
* could show up when dealing with NaNs.
@@ -12085,6 +12111,10 @@
cfg->next_vreg = cfg->rs->next_vreg;
}
+ /* FIXME: Fix SSA to handle branches inside bblocks */
+ if (cfg->opt & (MONO_OPT_SSA | MONO_OPT_ABCREM | MONO_OPT_SSAPRE))
+ cfg->disable_extended_bblocks = TRUE;
+
/*
* create MonoInst* which represents arguments and local variables
*/
@@ -12206,8 +12236,6 @@
#endif
}
#else
-
- /* fixme: add all optimizations which requires SSA */
if (cfg->opt & (MONO_OPT_SSA | MONO_OPT_ABCREM | MONO_OPT_SSAPRE)) {
if (!(cfg->comp_done & MONO_COMP_SSA) && !header->num_clauses
&& !cfg->disable_ssa) {
#ifndef DISABLE_SSA
@@ -12386,8 +12414,7 @@
/* Add branches between non-consecutive bblocks */
for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
if (bb->last_ins && MONO_IS_COND_BRANCH_OP
(bb->last_ins) &&
- bb->next_bb != bb->last_ins->inst_false_bb) {
-
+ bb->last_ins->inst_false_bb && bb->next_bb !=
bb->last_ins->inst_false_bb) {
/* we are careful when inverting, since bugs
like #59580
* could show up when dealing with NaNs.
*/
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini.h
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini.h 2008-01-02
16:53:11 UTC (rev 92116)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini.h 2008-01-02
16:55:59 UTC (rev 92117)
@@ -197,7 +197,7 @@
} MonoStackSlot;
/*
- * The IR-level basic block.
+ * The IR-level extended basic block.
*
* A basic block can have multiple exits just fine, as long as the point of
* 'departure' is the last instruction in the basic block. Extended basic
@@ -270,6 +270,8 @@
guint not_useless : 1;
/* Whenever the decompose_array_access_opts () pass needs to process
this bblock */
guint has_array_access : 1;
+ /* Whenever this bblock is extended, ie. it has branches inside it */
+ guint extended : 1;
/* use for liveness analysis */
MonoBitSet *gen_set;
@@ -283,12 +285,12 @@
MonoInst **in_stack;
MonoStackSlot *stack_state; /* Verification stack state on enter to
bblock */
- /* we use that to prevent merging of bblock covered by different
clauses*/
+ /* we use that to prevent merging of bblocks covered by different
clauses*/
guint real_offset;
/*
* The region encodes whether the basic block is inside
- * a finally, catch, filter or none of thoese.
+ * a finally, catch, filter or none of these.
*
* If the value is -1, then it is neither finally, catch nor filter
*
@@ -685,6 +687,7 @@
gint32 sig_cookie;
guint disable_aot : 1;
guint disable_ssa : 1;
+ guint disable_extended_bblocks : 1;
guint run_cctors : 1;
guint need_lmf_area : 1;
guint compile_aot : 1;
@@ -1030,7 +1033,7 @@
void mono_link_bblock (MonoCompile *cfg, MonoBasicBlock
*from, MonoBasicBlock* to) MONO_INTERNAL;
void mono_unlink_bblock (MonoCompile *cfg, MonoBasicBlock
*from, MonoBasicBlock* to) MONO_INTERNAL;
void mono_remove_bblock (MonoCompile *cfg, MonoBasicBlock
*bb) MONO_INTERNAL;
-void mono_merge_basic_blocks (MonoBasicBlock *bb,
MonoBasicBlock *bbn) MONO_INTERNAL;
+void mono_merge_basic_blocks (MonoCompile *cfg, MonoBasicBlock
*bb, MonoBasicBlock *bbn) MONO_INTERNAL;
void mono_optimize_branches (MonoCompile *cfg) MONO_INTERNAL;
void mono_blockset_print (MonoCompile *cfg, MonoBitSet
*set, const char *name, guint idom) MONO_INTERNAL;
void mono_print_tree (MonoInst *tree) MONO_INTERNAL;
Modified: branches/vargaz/mini-linear-il/mono/mono/mini/ssa2.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/ssa2.c 2008-01-02
16:53:11 UTC (rev 92116)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/ssa2.c 2008-01-02
16:55:59 UTC (rev 92117)
@@ -1096,6 +1096,15 @@
int i;
MonoJumpInfoBBTable *table = ins->inst_p0;
+ if (ins->next->opcode != OP_PADD) {
+ /* The PADD was optimized away */
+ /* FIXME: handle this as well */
+ for (i = 0; i < table->table_size; i++)
+ if (table->table [i])
+ add_cprop_bb (cfg, table->table
[i], bblist);
+ return;
+ }
+
g_assert (ins->next->opcode == OP_PADD);
g_assert (ins->next->sreg1 == ins->dreg);
@@ -1150,10 +1159,12 @@
if (ins->flags & MONO_INST_CFOLD_TAKEN) {
add_cprop_bb (cfg, ins->inst_true_bb, bblist);
} else if (ins->flags & MONO_INST_CFOLD_NOT_TAKEN) {
- add_cprop_bb (cfg, ins->inst_false_bb, bblist);
+ if (ins->inst_false_bb)
+ add_cprop_bb (cfg, ins->inst_false_bb, bblist);
} else {
add_cprop_bb (cfg, ins->inst_true_bb, bblist);
- add_cprop_bb (cfg, ins->inst_false_bb, bblist);
+ if (ins->inst_false_bb)
+ add_cprop_bb (cfg, ins->inst_false_bb, bblist);
}
}
}
@@ -1195,6 +1206,12 @@
int i;
MonoJumpInfoBBTable *table = ins->inst_p0;
+ if (ins->next->opcode != OP_PADD) {
+ /* The PADD was optimized away */
+ /* FIXME: handle this as well */
+ return;
+ }
+
g_assert (ins->next->opcode == OP_PADD);
g_assert (ins->next->sreg1 == ins->dreg);
g_assert (ins->next->next->opcode == OP_LOAD_MEMBASE);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches