2007-01-30 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Tue, 30 Jan 2007 17:38:11 +0000 (17:38 -0000)
committerZoltan Varga <vargaz@gmail.com>
Tue, 30 Jan 2007 17:38:11 +0000 (17:38 -0000)
* mini-amd64.c (peephole_pass): Optimize code common in initlocals blocks.

* mini.h (NULLIFY_INS): New macro.

svn path=/trunk/mono/; revision=71986

mono/mini/ChangeLog
mono/mini/mini-amd64.c
mono/mini/mini.h

index 96fa259d15f2f7b84ac5ec5391d3a6fef6e1ba83..5adb554aa9301722af8bf64cb6014af07db57227 100644 (file)
@@ -1,3 +1,8 @@
+2007-01-30  Zoltan Varga  <vargaz@gmail.com>
+
+       * mini-amd64.c (peephole_pass): Optimize code common in initlocals blocks.
+
+       * mini.h (NULLIFY_INS): New macro.
 
 Tue Jan 30 16:33:33 CET 2007 Paolo Molaro <lupus@ximian.com>
 
index 22b7d60358c78a6f5f26b7e7e8dea0d704ab67f5..3177585bdbd13d64cd8b990fbf2961a90c73c16a 100644 (file)
@@ -1552,6 +1552,21 @@ emit_call (MonoCompile *cfg, guint8 *code, guint32 patch_type, gconstpointer dat
        return emit_call_body (cfg, code, patch_type, data);
 }
 
+static inline int
+store_membase_imm_to_store_membase_reg (int opcode)
+{
+       switch (opcode) {
+       case OP_STORE_MEMBASE_IMM:
+               return OP_STORE_MEMBASE_REG;
+       case OP_STOREI4_MEMBASE_IMM:
+               return OP_STOREI4_MEMBASE_REG;
+       case OP_STOREI8_MEMBASE_IMM:
+               return OP_STOREI8_MEMBASE_REG;
+       }
+
+       return -1;
+}
+
 /* FIXME: Add more instructions */
 #define INST_IGNORES_CFLAGS(ins) (((ins)->opcode == CEE_BR) || ((ins)->opcode == OP_STORE_MEMBASE_IMM) || ((ins)->opcode == OP_STOREI8_MEMBASE_REG) || ((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_ICONST) || ((ins)->opcode == OP_I8CONST) || ((ins)->opcode == OP_LOAD_MEMBASE))
 
@@ -1572,6 +1587,33 @@ peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb)
                                ins->opcode = CEE_XOR;
                                ins->sreg1 = ins->dreg;
                                ins->sreg2 = ins->dreg;
+                               /* Fall through */
+                       }
+                       else
+                               break;
+               case CEE_XOR:
+                       if ((ins->sreg1 == ins->sreg2) && (ins->sreg1 == ins->dreg)) {
+                               MonoInst *ins2;
+
+                               /* 
+                                * Replace STORE_MEMBASE_IMM 0 with STORE_MEMBASE_REG since 
+                                * the latter has length 2-3 instead of 6 (reverse constant
+                                * propagation). These instruction sequences are very common
+                                * in the initlocals bblock.
+                                */
+                               for (ins2 = ins->next; ins2; ins2 = ins2->next) {
+                                       if (((ins2->opcode == OP_STORE_MEMBASE_IMM) || (ins2->opcode == OP_STOREI4_MEMBASE_IMM) || (ins2->opcode == OP_STOREI8_MEMBASE_IMM) || (ins2->opcode == OP_STORE_MEMBASE_IMM)) && (ins2->inst_imm == 0)) {
+                                               ins2->opcode = store_membase_imm_to_store_membase_reg (ins2->opcode);
+                                               ins2->sreg1 = ins->dreg;
+                                       } else if ((ins2->opcode == OP_STOREI1_MEMBASE_IMM) || (ins2->opcode == OP_STOREI2_MEMBASE_IMM) || (ins2->opcode == OP_STOREI8_MEMBASE_REG) || (ins2->opcode == OP_STORE_MEMBASE_REG)) {
+                                               /* Continue */
+                                       } else if (((ins2->opcode == OP_ICONST) || (ins2->opcode == OP_I8CONST)) && (ins2->dreg == ins->dreg) && (ins2->inst_c0 == 0)) {
+                                               NULLIFY_INS (ins2);
+                                               /* Continue */
+                                       } else {
+                                               break;
+                                       }
+                               }
                        }
                        break;
                case OP_MUL_IMM: 
@@ -3077,6 +3119,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_LABEL:
                        ins->inst_c0 = code - cfg->native_code;
                        break;
+               case CEE_NOP:
+                       break;
                case CEE_BR:
                        //g_print ("target: %p, next: %p, curr: %p, last: %p\n", ins->inst_target_bb, bb->next_bb, ins, bb->last_ins);
                        //if ((ins->inst_target_bb == bb->next_bb) && ins == bb->last_ins)
index f96a45cfe51d1bea0e6e8dcfa6cd75ce66e65f90..6c0c71ed68c676a4084c30f72b76ea2d5782e467 100644 (file)
@@ -105,6 +105,11 @@ enum {
                }       \
        } while (0)
 
+#define NULLIFY_INS(ins) do { \
+        (ins)->opcode = CEE_NOP; \
+        (ins)->dreg = (ins)->sreg1 = (ins)->sreg2 = -1; \
+    } while (0)
+
 typedef struct MonoInst MonoInst;
 typedef struct MonoCallInst MonoCallInst;
 typedef struct MonoCallArgParm MonoCallArgParm;