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

Reply via email to