[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