[mono/mono] [2 commits] ce6ec03e: [regalloc2] Lazily allocate intervals.

"Mark Probst ([email protected])" <[email protected]>
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <00000141a4cd859e-239e65e6-a2a4-4911-93a1-e182c3cc66cf-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/cb04c5a12d3b...ace1e095ce0c

   Commit: ce6ec03e5d644526723f2cb7c2d84b8dc18784c7
   Author: Mark Probst <[email protected]> (schani)
     Date: 2013-10-10 23:55:01 GMT
      URL: https://github.com/mono/mono/commit/ce6ec03e5d644526723f2cb7c2d84b8dc18784c7

[regalloc2] Lazily allocate intervals.

Changed paths:
  M mono/mini/regalloc2.c

Modified: mono/mini/regalloc2.c
===================================================================
@@ -707,6 +707,17 @@
 #endif
 }
 
+static MonoLiveInterval*
+get_var_interval (MonoCompile *cfg, MonoRegallocContext *ctx, int idx)
+{
+	MonoLiveInterval *interval = ctx->varinfo [idx].interval;
+	if (interval)
+		return interval;
+	interval = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoLiveInterval));
+	ctx->varinfo [idx].interval = interval;
+	return interval;
+}
+
 static inline void
 update_liveness (MonoCompile *cfg, MonoRegallocContext *ctx, MonoInst *ins, int inst_num, gint32 *last_use)
 {
@@ -730,9 +741,9 @@
 					 * Avoid a hole in the liveness range, since the allocation code
 					 * could think the register is free there.
 					 */
-					mono_linterval_add_range (ctx->cfg, ctx->varinfo [ins->dreg].interval, inst_num, last_use [ins->dreg]);
+					mono_linterval_add_range (ctx->cfg, get_var_interval (cfg, ctx, ins->dreg), inst_num, last_use [ins->dreg]);
 				} else {
-					mono_linterval_add_range (ctx->cfg, ctx->varinfo [ins->dreg].interval, inst_num + INS_POS_DEF, last_use [ins->dreg]);
+					mono_linterval_add_range (ctx->cfg, get_var_interval (cfg, ctx, ins->dreg), inst_num + INS_POS_DEF, last_use [ins->dreg]);
 				}
 				last_use [ins->dreg] = 0;
 			}
@@ -743,7 +754,7 @@
 					spec = INS_INFO (ins->opcode);
 				} else {
 					LIVENESS_DEBUG (printf ("\tdead def of R%d, add range to R%d: [%x, %x]\n", ins->dreg, ins->dreg, inst_num + INS_POS_DEF, inst_num + INS_POS_DEF));
-					mono_linterval_add_range (ctx->cfg, ctx->varinfo [ins->dreg].interval, inst_num + INS_POS_DEF, inst_num + INS_POS_DEF);
+					mono_linterval_add_range (ctx->cfg, get_var_interval (cfg, ctx, ins->dreg), inst_num + INS_POS_DEF, inst_num + INS_POS_DEF);
 				}
 			}
 		}
@@ -830,15 +841,15 @@
 		if (clob == 'c') {
 			/* A call clobbers some int/fp registers */
 			for (l = mono_arch_get_iregs_clobbered_by_call ((MonoCallInst*)ins); l; l = l->next)
-				mono_linterval_add_range (ctx->cfg, ctx->varinfo [GPOINTER_TO_INT (l->data)].interval, inst_num + INS_POS_CLOB, inst_num + INS_POS_CLOB);
+				mono_linterval_add_range (ctx->cfg, get_var_interval (cfg, ctx, GPOINTER_TO_INT (l->data)), inst_num + INS_POS_CLOB, inst_num + INS_POS_CLOB);
 			for (l = mono_arch_get_fregs_clobbered_by_call ((MonoCallInst*)ins); l; l = l->next)
-				mono_linterval_add_range (ctx->cfg, ctx->varinfo [GPOINTER_TO_INT (l->data)].interval, inst_num + INS_POS_CLOB, inst_num + INS_POS_CLOB);
+				mono_linterval_add_range (ctx->cfg, get_var_interval (cfg, ctx, GPOINTER_TO_INT (l->data)), inst_num + INS_POS_CLOB, inst_num + INS_POS_CLOB);
 		}
 		else {
 			int clob_reg = MONO_ARCH_INST_FIXED_REG (clob);
 
 			if (clob_reg != -1)
-				mono_linterval_add_range (ctx->cfg, ctx->varinfo [clob_reg].interval, inst_num + INS_POS_CLOB, inst_num + INS_POS_CLOB);
+				mono_linterval_add_range (ctx->cfg, get_var_interval (cfg, ctx, clob_reg), inst_num + INS_POS_CLOB, inst_num + INS_POS_CLOB);
 		}
 	}
 }
@@ -861,10 +872,6 @@
 	reverse_len = 1024;
 	reverse = mono_mempool_alloc (cfg->mempool, sizeof (MonoInst*) * reverse_len);
 
-	for (idx = 0; idx < max_vars; ++idx) {
-		ctx->varinfo [idx].interval = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoLiveInterval));
-	}
-
 	/*
 	 * Process bblocks in reverse order, so the addition of new live ranges
 	 * to the intervals is faster.
@@ -931,7 +938,7 @@
 			if (last_use [idx] != 0) {
 				/* Live at exit, not written -> live on enter */
 				LIVENESS_DEBUG (printf ("Var R%d live at enter, add range to R%d: [%x, %x)\n", idx, idx, block_from, last_use [idx]));
-				mono_linterval_add_range (cfg, ctx->varinfo [idx].interval, block_from, last_use [idx]);
+				mono_linterval_add_range (cfg, get_var_interval (cfg, ctx, idx), block_from, last_use [idx]);
 			}
 		}
 	}
@@ -946,14 +953,14 @@
 	for (i = 0; i < cfg->num_varinfo; i ++) {
 		MonoMethodVar *vi = MONO_VARINFO (cfg, i);
 		if ((cfg->varinfo [vi->idx]->opcode == OP_ARG) && (cfg->varinfo [vi->idx] != cfg->ret))
-			mono_linterval_add_range (cfg, ctx->varinfo [cfg->varinfo [i]->dreg].interval, 0, 1);
+			mono_linterval_add_range (cfg, get_var_interval (cfg, ctx, cfg->varinfo [i]->dreg), 0, 1);
 	}
 #endif
 
 #if 0
 		for (idx = 0; idx < max_vars; ++idx) {
 			printf ("LIVENESS R%d: ", idx);
-			mono_linterval_print (ctx->varinfo [idx].interval);
+			mono_linterval_print (get_var_interval (cfg, ctx, idx));
 			printf ("\n");
 		}
 	}
@@ -1204,7 +1211,7 @@
 	/* Create list of allocatable variables */
 	vars = NULL;
 	for (i = MONO_FIRST_VREG; i < cfg->next_vreg; ++i) {
-		if (ctx->varinfo [i].interval->range)
+		if (get_var_interval (cfg, ctx, i)->range)
 			vars = g_list_prepend (vars, &ctx->varinfo [i]);
 	}
 
@@ -1222,7 +1229,7 @@
 	/* The hard registers are assigned to themselves */
 	for (i = 0; i < MONO_MAX_IREGS + MONO_MAX_FREGS; ++i) {
 		ctx->varinfo [i].hreg = i;
-		if (ctx->varinfo [i].interval->range)
+		if (get_var_interval (cfg, ctx, i)->range)
 			inactive = g_list_append (inactive, &ctx->varinfo [i]);		
 	}
 

   Commit: ace1e095ce0cda4481b35d07497611a834f7dd5c
   Author: Mark Probst <[email protected]> (schani)
     Date: 2013-10-10 23:55:01 GMT
      URL: https://github.com/mono/mono/commit/ace1e095ce0cda4481b35d07497611a834f7dd5c

[regalloc2] Handle sreg3.

Changed paths:
  M mono/mini/regalloc2.c

Modified: mono/mini/regalloc2.c
===================================================================
@@ -252,17 +252,20 @@
 		cfg->cbb = bb;
 		MONO_BB_FOR_EACH_INS (bb, ins) {
 			const char *spec = ins_get_spec (ins->opcode);
-			int dest_sreg1, dest_sreg2, dest_dreg;
+			int dest_sreg1, dest_sreg2, dest_sreg3, dest_dreg;
 
 			dest_sreg1 = MONO_ARCH_INST_FIXED_REG (spec [MONO_INST_SRC1]);
 			dest_sreg2 = MONO_ARCH_INST_FIXED_REG (spec [MONO_INST_SRC2]);
+			dest_sreg3 = MONO_ARCH_INST_FIXED_REG (spec [MONO_INST_SRC3]);
 			dest_dreg = MONO_ARCH_INST_FIXED_REG (spec [MONO_INST_DEST]);
 
 			if (MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_DEST]) ||
-				MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_SRC1]) ||
-				MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_SRC2]))
+					MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_SRC1]) ||
+					MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_SRC2]) ||
+					MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_SRC3])) {
 				/* FIXME: */
 				g_assert_not_reached ();
+			}
 
 			if (spec [MONO_INST_CLOB] == 'c') {
 				MonoCallInst *call = (MonoCallInst*)ins;
@@ -303,7 +306,7 @@
 
 			if (spec [MONO_INST_CLOB] == '1') {
 				/* Copying sreg1 to dreg could clobber sreg2 so make a copy of sreg2 */
-				if (spec [MONO_INST_SRC2] && (ins->dreg == ins->sreg2)) {
+				if (spec [MONO_INST_SRC2] != ' ' && (ins->dreg == ins->sreg2)) {
 					int new_sreg2 = mono_alloc_preg (cfg);
 					MonoInst *move;
 					g_assert (spec [MONO_INST_DEST] != 'f');
@@ -312,6 +315,7 @@
 					prev = move;
 					ins->sreg2 = new_sreg2;
 				}
+				g_assert (!(spec [MONO_INST_SRC3] != ' ' && (ins->dreg == ins->sreg3)));
 				if (spec [MONO_INST_DEST] == 'f')
 					emit_fp_move (cfg, ins->dreg, ins->sreg1, prev);
 				else
@@ -329,6 +333,11 @@
 				ins->sreg2 = dest_sreg2;
 			}
 
+			if (dest_sreg3 != -1) {
+				emit_move (cfg, dest_sreg3, ins->sreg3, prev);
+				ins->sreg3 = dest_sreg3;
+			}
+
 			if (dest_dreg != -1) {
 				emit_move (cfg, ins->dreg, dest_dreg, ins);
 				g_assert (spec [MONO_INST_CLOB] != '1');
@@ -497,6 +506,13 @@
 			mono_bitset_set_fast (bb->gen_set, sreg);
 	}
 
+	/* SREG3 */
+	sreg = ins->sreg3;
+	if (spec [MONO_INST_SRC3] != ' ') {
+		if (!mono_bitset_test_fast (bb->kill_set, sreg))
+			mono_bitset_set_fast (bb->gen_set, sreg);
+	}
+
 	/* DREG */
 	if (spec [MONO_INST_DEST] != ' ') {
 		if (MONO_IS_STORE_MEMBASE (ins)) {
@@ -800,6 +816,20 @@
 			last_use [sreg] = inst_num + INS_POS_USE;
 		}
 		ctx->varinfo [sreg].use_pos = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->varinfo [sreg].use_pos, GINT_TO_POINTER (inst_num));
+
+	/* SREG3 */
+	sreg = ins->sreg3;
+	if (spec [MONO_INST_SRC3] != ' ') {
+		if (last_use [sreg] == 0) {
+			LIVENESS_DEBUG (printf ("\tlast use of R%d set to %x\n", sreg, inst_num + INS_POS_USE));
+			last_use [sreg] = inst_num + INS_POS_USE;
+		}
+		ctx->varinfo [sreg].use_pos = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->varinfo [sreg].use_pos, GINT_TO_POINTER (inst_num));
+
+		/*
+		if (ins->sreg3 <= MONO_MAX_IREGS)
+			mono_linterval_add_range (ctx->cfg, get_var_interval (cfg, ctx, ins->sreg3), inst_num + INS_POS_DEF, inst_num + INS_POS_DEF);
+		*/
 	}
 
 	if (ins_get_spec (ins->opcode)[MONO_INST_CLOB] == 'c') {
@@ -2214,6 +2244,12 @@
 				ins->sreg2 = l->hreg;
 			}
 
+			if (spec [MONO_INST_SRC3] != ' ') {
+				MonoRegallocInterval *l = child_at (&ctx->varinfo [ins->sreg3], pos + INS_POS_USE);
+				g_assert (l->hreg != -1);
+				ins->sreg3 = l->hreg;
+			}
+
 			if (cfg->verbose_level > 1)
 				mono_print_ins_index (1, ins);
 


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.