[mono/mono] [2 commits] e1e914a0: [jit] Avoid pushing the lmf in inlined methods. Allow the variable holding the lmf address to be allocated to a global register.

"Zoltan Varga ([email protected])" <[email protected]> Thu, 21 Nov 2013 10:49:58 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <000001427a47dabd-3b786db9-7dce-4b67-a7e5-67d5cd1da728-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/658753c9c8c2...cc4049bcf262

   Commit: e1e914a0cb7f0892b4a85f61147766dbf4564cb8
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-21 10:47:50 GMT
      URL: https://github.com/mono/mono/commit/e1e914a0cb7f0892b4a85f61147766dbf4564cb8

[jit] Avoid pushing the lmf in inlined methods. Allow the variable holding the lmf address to be allocated to a global register.

Changed paths:
  M mono/mini/method-to-ir.c

Modified: mono/mini/method-to-ir.c
===================================================================
@@ -1902,7 +1902,7 @@
 	 * lmf->prev_lmf = *lmf_addr
 	 * *lmf_addr = lmf
 	 */
-	int lmf_reg, lmf_addr_reg, prev_lmf_reg;
+	int lmf_reg, prev_lmf_reg;
 	MonoInst *ins, *lmf_ins;
 
 	if (!cfg->lmf_ir)
@@ -1920,25 +1920,28 @@
 		/* Set new LMF */
 		emit_tls_set (cfg, lmf_reg, OP_TLS_SET_REG);
 	} else {
+		/*
+		 * Store lmf_addr in a variable, so it can be allocated to a global register.
+		 */
+		if (!cfg->lmf_addr_var)
+			cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+
 		lmf_ins = mono_get_lmf_addr_intrinsic (cfg);
-		if (lmf_ins)
+		if (lmf_ins) 
 			MONO_ADD_INS (cfg->cbb, lmf_ins);
 		else
 			lmf_ins = mono_emit_jit_icall (cfg, mono_get_lmf_addr, NULL);
-		lmf_addr_reg = lmf_ins->dreg;
+		lmf_ins->dreg = cfg->lmf_addr_var->dreg;
 
 		EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
 		lmf_reg = ins->dreg;
-		/* Save lmf_addr */
-		if (!cfg->lmf_addr_var)
-			cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
-		EMIT_NEW_UNALU (cfg, ins, OP_MOVE, cfg->lmf_addr_var->dreg, lmf_ins->dreg);
+
 		prev_lmf_reg = alloc_preg (cfg);
 		/* Save previous_lmf */
-		EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, lmf_addr_reg, 0);
+		EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, cfg->lmf_addr_var->dreg, 0);
 		EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_reg, G_STRUCT_OFFSET (MonoLMF, previous_lmf), prev_lmf_reg);
 		/* Set new lmf */
-		EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_addr_reg, 0, lmf_reg);
+		EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, cfg->lmf_addr_var->dreg, 0, lmf_reg);
 	}
 }
 
@@ -1974,6 +1977,7 @@
 		if (!cfg->lmf_addr_var)
 			cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
 		lmf_addr_reg = cfg->lmf_addr_var->dreg;
+
 		prev_lmf_reg = alloc_preg (cfg);
 		EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, lmf_reg, G_STRUCT_OFFSET (MonoLMF, previous_lmf));
 		EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_addr_reg, 0, prev_lmf_reg);
@@ -11847,11 +11851,6 @@ gboolean check_linkdemand (MonoCompile *cfg, MonoMethod *caller, MonoMethod *cal
 		bblock->next_bb = end_bblock;
 	}
 
-	if (cfg->lmf_var) {
-		cfg->cbb = init_localsbb;
-		emit_push_lmf (cfg);
-	}
-
 	if (cfg->method == method && cfg->domainvar) {
 		MonoInst *store;
 		MonoInst *get_domain;
@@ -11897,6 +11896,11 @@ gboolean check_linkdemand (MonoCompile *cfg, MonoMethod *caller, MonoMethod *cal
 		}
 	}
 
+	if (cfg->lmf_var && cfg->method == method) {
+		cfg->cbb = init_localsbb;
+		emit_push_lmf (cfg);
+	}
+
 	if (seq_points) {
 		MonoBasicBlock *bb;
 
@@ -12620,7 +12624,7 @@ gboolean check_linkdemand (MonoCompile *cfg, MonoMethod *caller, MonoMethod *cal
 			/* Arguments are implicitly global */
 			/* Putting R4 vars into registers doesn't work currently */
 			/* The gsharedvt vars are implicitly referenced by ldaddr opcodes, but those opcodes are only generated later */
-			if ((var->opcode != OP_ARG) && (var != cfg->ret) && !(var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) && (vreg_to_bb [var->dreg] != -1) && (var->klass->byval_arg.type != MONO_TYPE_R4) && !cfg->disable_vreg_to_lvreg && var != cfg->gsharedvt_info_var && var != cfg->gsharedvt_locals_var) {
+			if ((var->opcode != OP_ARG) && (var != cfg->ret) && !(var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) && (vreg_to_bb [var->dreg] != -1) && (var->klass->byval_arg.type != MONO_TYPE_R4) && !cfg->disable_vreg_to_lvreg && var != cfg->gsharedvt_info_var && var != cfg->gsharedvt_locals_var && var != cfg->lmf_addr_var) {
 				/* 
 				 * Make that the variable's liveness interval doesn't contain a call, since
 				 * that would cause the lvreg to be spilled, making the whole optimization

   Commit: cc4049bcf262eed46790849a697d3b27bf8bc45a
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-21 10:47:50 GMT
      URL: https://github.com/mono/mono/commit/cc4049bcf262eed46790849a697d3b27bf8bc45a

[jit] Emit the push/pop LMF code as IR on amd64.

Changed paths:
  M mono/mini/mini-amd64.c

Modified: mono/mini/mini-amd64.c
===================================================================
@@ -2015,12 +2015,13 @@
 	cfg->arch.no_pushes = TRUE;
 #endif
 
-	if (cfg->method->save_lmf) {
-		MonoInst *lmf_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
-		lmf_var->flags |= MONO_INST_VOLATILE;
-		lmf_var->flags |= MONO_INST_LMF;
-		cfg->arch.lmf_var = lmf_var;
-	}
+	if (cfg->method->save_lmf)
+		cfg->create_lmf_var = TRUE;
+
+#if !defined(HOST_WIN32) && !defined(MONO_ARCH_ENABLE_MONO_LMF_VAR)
+	if (cfg->method->save_lmf)
+		cfg->lmf_ir = TRUE;
+#endif
 
 #ifndef MONO_AMD64_NO_PUSHES
 	cfg->arch_eh_jit_info = 1;
@@ -3761,13 +3762,18 @@
 }
 
 /*
- * emit_save_lmf:
+ * emit_push_lmf:
  *
  *   Emit code to push an LMF structure on the LMF stack.
  */
 static guint8*
-emit_save_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset, gboolean *args_clobbered)
+emit_push_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset, gboolean *args_clobbered)
 {
+	if (cfg->lmf_ir) {
+		*args_clobbered = TRUE;
+		return code;
+	}
+
 	if ((lmf_tls_offset != -1) && !optimize_for_xen) {
 		/*
 		 * Optimized version which uses the mono_lmf TLS variable instead of 
@@ -3823,13 +3829,16 @@
 }
 
 /*
- * emit_save_lmf:
+ * emit_pop_lmf:
  *
  *   Emit code to pop an LMF structure from the LMF stack.
  */
 static guint8*
-emit_restore_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
+emit_pop_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
 {
+	if (cfg->lmf_ir)
+		return code;
+
 	if ((lmf_tls_offset != -1) && !optimize_for_xen) {
 		/*
 		 * Optimized version which uses the mono_lmf TLS variable instead of indirection
@@ -4995,8 +5004,8 @@
 			break;
 		}
 		case OP_AMD64_SAVE_SP_TO_LMF: {
-			MonoInst *lmf_var = cfg->arch.lmf_var;
-			amd64_mov_membase_reg (code, cfg->frame_reg, lmf_var->inst_offset + G_STRUCT_OFFSET (MonoLMF, rsp), AMD64_RSP, 8);
+			MonoInst *lmf_var = cfg->lmf_var;
+			amd64_mov_membase_reg (code, lmf_var->inst_basereg, lmf_var->inst_offset + G_STRUCT_OFFSET (MonoLMF, rsp), AMD64_RSP, 8);
 			break;
 		}
 		case OP_X86_PUSH:
@@ -6644,7 +6653,7 @@
 	int alloc_size, pos, i, cfa_offset, quad, max_epilog_size;
 	guint8 *code;
 	CallInfo *cinfo;
-	MonoInst *lmf_var = cfg->arch.lmf_var;
+	MonoInst *lmf_var = cfg->lmf_var;
 	gboolean args_clobbered = FALSE;
 	gboolean trace = FALSE;
 #ifdef __native_client_codegen__
@@ -7088,7 +7097,7 @@
 	}
 
 	if (method->save_lmf) {
-		code = emit_save_lmf (cfg, code, lmf_var->inst_offset, &args_clobbered);
+		code = emit_push_lmf (cfg, code, lmf_var->inst_offset, &args_clobbered);
 	}
 
 	if (trace) {
@@ -7208,7 +7217,7 @@
 	guint8 *code;
 	int max_epilog_size;
 	CallInfo *cinfo;
-	gint32 lmf_offset = cfg->arch.lmf_var ? ((MonoInst*)cfg->arch.lmf_var)->inst_offset : -1;
+	gint32 lmf_offset = cfg->lmf_var ? ((MonoInst*)cfg->lmf_var)->inst_offset : -1;
 	
 	max_epilog_size = get_max_epilog_size (cfg);
 
@@ -7227,6 +7236,8 @@
 	pos = 0;
 	
 	if (method->save_lmf) {
+		code = emit_pop_lmf (cfg, code, lmf_offset);
+
 		/* check if we need to restore protection of the stack after a stack overflow */
 		if (mono_get_jit_tls_offset () != -1) {
 			guint8 *patch;
@@ -7245,8 +7256,6 @@
 			/* FIXME: maybe save the jit tls in the prolog */
 		}
 
-		code = emit_restore_lmf (cfg, code, lmf_offset);
-
 		/* Restore caller saved regs */
 		if (cfg->used_int_regs & (1 << AMD64_RBP)) {
 			amd64_mov_reg_membase (code, AMD64_RBP, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rbp), 8);


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches