[llvm] Use the generic IL code for generic class inits.
authorZoltan Varga <vargaz@gmail.com>
Fri, 29 May 2015 23:15:55 +0000 (19:15 -0400)
committerZoltan Varga <vargaz@gmail.com>
Fri, 29 May 2015 23:16:04 +0000 (19:16 -0400)
mono/mini/method-to-ir.c
mono/mini/mini-llvm.c

index 5115fdcfd7cd728b13b33da0578d0f4f80e80566..ef3d57a92088ee3f3a0a3f2d608bc20757b2ae2c 100644 (file)
@@ -3623,6 +3623,7 @@ emit_generic_class_init (MonoCompile *cfg, MonoClass *klass, MonoBasicBlock **ou
 {
        MonoInst *vtable_arg;
        int context_used;
+       gboolean use_op_generic_class_init = FALSE;
 
        *out_bblock = cfg->cbb;
 
@@ -3640,46 +3641,47 @@ emit_generic_class_init (MonoCompile *cfg, MonoClass *klass, MonoBasicBlock **ou
        }
 
 #ifdef MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT
-       MonoInst *ins;
+       if (!COMPILE_LLVM (cfg))
+               use_op_generic_class_init = TRUE;
+#endif
 
-       /*
-        * Using an opcode instead of emitting IR here allows the hiding of the call inside the opcode,
-        * so this doesn't have to clobber any regs and it doesn't break basic blocks.
-        */
-       /*
-        * For LLVM, this requires that the code in the generic trampoline obtain the vtable argument according to
-        * the normal calling convention of the platform.
-        */
-       MONO_INST_NEW (cfg, ins, OP_GENERIC_CLASS_INIT);
-       ins->sreg1 = vtable_arg->dreg;
-       MONO_ADD_INS (cfg->cbb, ins);
-#else
-       static int byte_offset = -1;
-       static guint8 bitmask;
-       int bits_reg, inited_reg;
-       MonoBasicBlock *inited_bb;
-       MonoInst *args [16];
+       if (use_op_generic_class_init) {
+               MonoInst *ins;
 
-       if (byte_offset < 0)
-               mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
+               /*
+                * Using an opcode instead of emitting IR here allows the hiding of the call inside the opcode,
+                * so this doesn't have to clobber any regs and it doesn't break basic blocks.
+                */
+               MONO_INST_NEW (cfg, ins, OP_GENERIC_CLASS_INIT);
+               ins->sreg1 = vtable_arg->dreg;
+               MONO_ADD_INS (cfg->cbb, ins);
+       } else {
+               static int byte_offset = -1;
+               static guint8 bitmask;
+               int bits_reg, inited_reg;
+               MonoBasicBlock *inited_bb;
+               MonoInst *args [16];
 
-       bits_reg = alloc_ireg (cfg);
-       inited_reg = alloc_ireg (cfg);
+               if (byte_offset < 0)
+                       mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
 
-       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, bits_reg, vtable_arg->dreg, byte_offset);
-       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IAND_IMM, inited_reg, bits_reg, bitmask);
+               bits_reg = alloc_ireg (cfg);
+               inited_reg = alloc_ireg (cfg);
 
-       NEW_BBLOCK (cfg, inited_bb);
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, bits_reg, vtable_arg->dreg, byte_offset);
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IAND_IMM, inited_reg, bits_reg, bitmask);
 
-       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, inited_reg, 0);
-       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBNE_UN, inited_bb);
+               NEW_BBLOCK (cfg, inited_bb);
 
-       args [0] = vtable_arg;
-       mono_emit_jit_icall (cfg, mono_generic_class_init, args);
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, inited_reg, 0);
+               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBNE_UN, inited_bb);
 
-       MONO_START_BB (cfg, inited_bb);
-       *out_bblock = inited_bb;
-#endif
+               args [0] = vtable_arg;
+               mono_emit_jit_icall (cfg, mono_generic_class_init, args);
+
+               MONO_START_BB (cfg, inited_bb);
+               *out_bblock = inited_bb;
+       }
 }
 
 
index 520c26931e1e92ceaf5a359eca788b4b20ec9511..3b0c2594d9437d4d1d113a4d7eb78cfb7085b633 100644 (file)
@@ -3680,58 +3680,6 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        CHECK_FAILURE (ctx);
                        break;
                }
-               case OP_GENERIC_CLASS_INIT: {
-                       static int byte_offset = -1;
-                       static guint8 bitmask;
-                       LLVMValueRef flags_load, cmp;
-                       MonoMethodSignature *sig;
-                       const char *icall_name;
-                       LLVMValueRef callee;
-                       LLVMBasicBlockRef init_bb, noinit_bb;
-                       LLVMValueRef args [16];
-
-                       if (byte_offset < 0)
-                               mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
-
-                       flags_load = emit_load (ctx, bb, &builder, 1, convert (ctx, lhs, LLVMPointerType (LLVMInt8Type(), 0)), "", FALSE);
-                       set_metadata_flag (flags_load, "mono.nofail.load");
-                       cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, flags_load, LLVMConstInt (LLVMInt8Type (), bitmask, 0), ""), LLVMConstInt (LLVMInt8Type (), 1, FALSE), "");
-
-                       callee = ctx->lmodule->generic_class_init_tramp;
-                       if (!callee) {
-                               icall_name = "specific_trampoline_generic_class_init";
-                               sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
-                               sig->ret = &mono_get_void_class ()->byval_arg;
-                               sig->params [0] = &mono_get_intptr_class ()->byval_arg;
-                               if (cfg->compile_aot) {
-                                       callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
-                               } else {
-                                       callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, sig));
-                                       LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
-                               }
-                               mono_memory_barrier ();
-                               ctx->lmodule->generic_class_init_tramp = callee;
-                       }
-
-                       init_bb = gen_bb (ctx, "INIT_BB");
-                       noinit_bb = gen_bb (ctx, "NOINIT_BB");
-
-                       LLVMBuildCondBr (ctx->builder, cmp, noinit_bb, init_bb);
-
-                       builder = create_builder (ctx);
-                       ctx->builder = builder;
-                       LLVMPositionBuilderAtEnd (builder, init_bb);
-                       args [0] = convert (ctx, lhs, IntPtrType ());
-                       emit_call (ctx, bb, &builder, callee, args, 1);
-                       LLVMBuildBr (builder, noinit_bb);
-
-                       builder = create_builder (ctx);
-                       ctx->builder = builder;
-                       LLVMPositionBuilderAtEnd (builder, noinit_bb);
-
-                       ctx->bblocks [bb->block_num].end_bblock = noinit_bb;
-                       break;
-               }
                case OP_AOTCONST: {
                        guint32 got_offset;
                        LLVMValueRef indexes [2];