[mono/mono] e4bf5439: [llvm] Decompose OP_STOREV_MEMBASE opcodes earlier since they might need write barriers.
"Zoltan Varga (
[email protected])" <
[email protected]>
Tue, 19 Nov 2013 11:56:57 +0000
| Newsgroups |
gmane.comp.gnome.mono.patches |
| Message-ID |
<00000142703873df-d4598afa-4155-417d-8846-3ff5c62d23e8-000000@email.amazonses.com> |
Branch: refs/heads/master
Home: https://github.com/mono/mono
Compare: https://github.com/mono/mono/compare/3a9ccd06832f...e4bf54392ad9
Commit: e4bf54392ad9a7c85531d99422f133b124c3d1a3
Author: Zoltan Varga <[email protected]> (vargaz)
Date: 2013-11-19 11:55:45 GMT
URL: https://github.com/mono/mono/commit/e4bf54392ad9a7c85531d99422f133b124c3d1a3
[llvm] Decompose OP_STOREV_MEMBASE opcodes earlier since they might need write barriers.
Changed paths:
M mono/mini/decompose.c
M mono/mini/mini-codegen.c
M mono/mini/mini-llvm.c
M mono/mini/mini.c
M mono/mini/mini.h
Modified: mono/mini/decompose.c
===================================================================
@@ -1361,6 +1361,71 @@
}
}
+void
+mono_decompose_vtype_opts_llvm (MonoCompile *cfg)
+{
+ MonoBasicBlock *bb, *first_bb;
+
+ /* Decompose only the OP_STOREV_MEMBASE opcodes, which need write barriers */
+
+ cfg->cbb = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoBasicBlock));
+ first_bb = cfg->cbb;
+
+ for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+ MonoInst *ins;
+ MonoInst *prev = NULL;
+ MonoInst *src_var, *src, *dest;
+ gboolean restart;
+ int dreg;
+
+ if (cfg->verbose_level > 2) mono_print_bb (bb, "BEFORE LOWER-VTYPE-OPTS(LLVM) ");
+
+ cfg->cbb->code = cfg->cbb->last_ins = NULL;
+ restart = TRUE;
+
+ while (restart) {
+ restart = FALSE;
+
+ for (ins = bb->code; ins; ins = ins->next) {
+ switch (ins->opcode) {
+ case OP_STOREV_MEMBASE: {
+ src_var = get_vreg_to_inst (cfg, ins->sreg1);
+
+ if (!src_var) {
+ g_assert (ins->klass);
+ src_var = mono_compile_create_var_for_vreg (cfg, &ins->klass->byval_arg, OP_LOCAL, ins->sreg1);
+ }
+
+ EMIT_NEW_VARLOADA_VREG ((cfg), (src), ins->sreg1, &ins->klass->byval_arg);
+
+ dreg = alloc_preg (cfg);
+ EMIT_NEW_BIALU_IMM (cfg, dest, OP_ADD_IMM, dreg, ins->inst_destbasereg, ins->inst_offset);
+ mini_emit_stobj (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke);
+ break;
+ }
+ default:
+ break;
+ }
+
+ g_assert (cfg->cbb == first_bb);
+
+ if (cfg->cbb->code || (cfg->cbb != first_bb)) {
+ /* Replace the original instruction with the new code sequence */
+
+ mono_replace_ins (cfg, bb, ins, &prev, first_bb, cfg->cbb);
+ first_bb->code = first_bb->last_ins = NULL;
+ first_bb->in_count = first_bb->out_count = 0;
+ cfg->cbb = first_bb;
+ }
+ else
+ prev = ins;
+ }
+ }
+
+ if (cfg->verbose_level > 2) mono_print_bb (bb, "AFTER LOWER-VTYPE-OPTS(LLVM) ");
+ }
+}
+
inline static MonoInst *
mono_get_domainvar (MonoCompile *cfg)
{
Modified: mono/mini/mini-codegen.c
===================================================================
@@ -453,9 +453,22 @@ static inline int translate_bank (MonoRegState *rs, int bank, int hreg) {
else
printf (" %s", mono_inst_name (ins->opcode));
if (spec == MONO_ARCH_CPU_SPEC) {
+ gboolean dest_base = FALSE;
+ switch (ins->opcode) {
+ case OP_STOREV_MEMBASE:
+ dest_base = TRUE;
+ break;
+ default:
+ break;
+ }
+
/* This is a lowered opcode */
- if (ins->dreg != -1)
- printf (" R%d <-", ins->dreg);
+ if (ins->dreg != -1) {
+ if (dest_base)
+ printf (" [R%d + 0x%lx] <-", ins->dreg, (long)ins->inst_offset);
+ else
+ printf (" R%d <-", ins->dreg);
+ }
if (ins->sreg1 != -1)
printf (" R%d", ins->sreg1);
if (ins->sreg2 != -1)
Modified: mono/mini/mini-llvm.c
===================================================================
@@ -3454,9 +3454,10 @@
switch (ins->opcode) {
case OP_STOREV_MEMBASE:
- if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
- /* FIXME: Emit write barriers like in mini_emit_stobj () */
- LLVM_FAILURE (ctx, "storev_membase + write barriers");
+ if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
+ LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
+ /* Decomposed earlier */
+ g_assert_not_reached ();
break;
}
if (!addresses [ins->sreg1]) {
@@ -4210,7 +4211,7 @@
#if 1
for (i = 0; i < header->num_clauses; ++i) {
clause = &header->clauses [i];
-
+
if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
/*
* FIXME: Some tests still fail with nested clauses.
Modified: mono/mini/mini.c
===================================================================
@@ -5379,7 +5379,9 @@ void *mono_global_codeman_reserve (int size)
if (COMPILE_SOFT_FLOAT (cfg))
mono_decompose_soft_float (cfg);
#endif
- if (!COMPILE_LLVM (cfg))
+ if (COMPILE_LLVM (cfg))
+ mono_decompose_vtype_opts_llvm (cfg);
+ else
mono_decompose_vtype_opts (cfg);
if (cfg->flags & MONO_CFG_HAS_ARRAY_ACCESS)
mono_decompose_array_access_opts (cfg);
Modified: mono/mini/mini.h
===================================================================
@@ -2221,6 +2221,7 @@ int mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoB
MonoInst *mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
void mono_decompose_long_opts (MonoCompile *cfg) MONO_INTERNAL;
void mono_decompose_vtype_opts (MonoCompile *cfg) MONO_INTERNAL;
+void mono_decompose_vtype_opts_llvm (MonoCompile *cfg) MONO_INTERNAL;
void mono_decompose_array_access_opts (MonoCompile *cfg) MONO_INTERNAL;
void mono_decompose_soft_float (MonoCompile *cfg) MONO_INTERNAL;
void mono_handle_global_vregs (MonoCompile *cfg) MONO_INTERNAL;
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches