2007-04-24 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Tue, 24 Apr 2007 18:21:17 +0000 (18:21 -0000)
committerZoltan Varga <vargaz@gmail.com>
Tue, 24 Apr 2007 18:21:17 +0000 (18:21 -0000)
* liveness.c (optimize_initlocals): New mini-pass to optimize away dead assignments
created becase of initlocals.

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

mono/mini/ChangeLog
mono/mini/liveness.c

index 35a33455c52021daeb59399c3f2313ff2361559c..37be1b1fae17f4a7f46f5ecdec2ea38e10435804 100644 (file)
@@ -1,3 +1,8 @@
+2007-04-24  Zoltan Varga  <vargaz@gmail.com>
+
+       * liveness.c (optimize_initlocals): New mini-pass to optimize away dead assignments
+       created becase of initlocals.
+
 2007-04-23  Zoltan Varga  <vargaz@gmail.com>
 
        * mini-alpha.c cpu-alpha.md: More alpha port work from 
index 8c2eecc15cbdee137f474cef20e50ae5041782df..58c34afd917187d585a12d73faa752aca991d4e8 100644 (file)
@@ -21,6 +21,9 @@
 #define BITS_PER_CHUNK 32
 #endif
 
+static void
+optimize_initlocals (MonoCompile *cfg);
+
 /* mono_bitset_mp_new:
  * 
  * allocates a MonoBitSet inside a memory pool
@@ -497,4 +500,65 @@ mono_analyze_liveness (MonoCompile *cfg)
                mono_bitset_print (bb->live_out_set); 
        }
 #endif
+
+       optimize_initlocals (cfg);
+}
+
+static void
+update_used (MonoCompile *cfg, MonoInst *inst, MonoBitSet *used)
+{
+       int arity = mono_burg_arity [inst->opcode];
+
+       if (arity)
+               update_used (cfg, inst->inst_i0, used);
+
+       if (arity > 1)
+               update_used (cfg, inst->inst_i1, used);
+
+       if (inst->ssa_op & MONO_SSA_LOAD_STORE) {
+               if (inst->ssa_op == MONO_SSA_LOAD) {
+                       int idx = inst->inst_i0->inst_c0;
+
+                       mono_bitset_set_fast (used, idx);
+               }
+       }
+} 
+
+/**
+ * optimize_initlocals:
+ *
+ * Try to optimize away some of the redundant initialization code inserted because of
+ * 'locals init' using the liveness information.
+ */
+static void
+optimize_initlocals (MonoCompile *cfg)
+{
+       MonoBitSet *used;
+       MonoInst *ins;
+       MonoBasicBlock *initlocals_bb;
+
+       used = mono_bitset_new (cfg->num_varinfo, 0);
+
+       mono_bitset_clear_all (used);
+       initlocals_bb = cfg->bb_entry->next_bb;
+       for (ins = initlocals_bb->code; ins; ins = ins->next) {
+               update_used (cfg, ins, used);
+       }
+
+       for (ins = initlocals_bb->code; ins; ins = ins->next) {
+               if (ins->ssa_op == MONO_SSA_STORE) {
+                       int idx = ins->inst_i0->inst_c0;
+                       MonoInst *var = cfg->varinfo [idx];
+
+                       if (var && !mono_bitset_test_fast (used, idx) && !mono_bitset_test_fast (initlocals_bb->live_out_set, var->inst_c0) && (var != cfg->ret) && !(var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT))) {
+                               if (ins->inst_i1 && ((ins->inst_i1->opcode == OP_ICONST) || (ins->inst_i1->opcode == OP_I8CONST))) {
+                                       NULLIFY_INS (ins);
+                                       ins->ssa_op = MONO_SSA_NOP;
+                                       MONO_VARINFO (cfg, var->inst_c0)->spill_costs -= 1;                                     
+                               }
+                       }
+               }
+       }
+
+       g_free (used);
 }