2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/metadata/environment.h>
13 #include <mono/metadata/object-internals.h>
14 #include <mono/metadata/abi-details.h>
15 #include <mono/utils/mono-tls.h>
16 #include <mono/utils/mono-dl.h>
17 #include <mono/utils/mono-time.h>
18 #include <mono/utils/freebsd-dwarf.h>
20 #ifndef __STDC_LIMIT_MACROS
21 #define __STDC_LIMIT_MACROS
23 #ifndef __STDC_CONSTANT_MACROS
24 #define __STDC_CONSTANT_MACROS
27 #include "llvm-c/Core.h"
28 #include "llvm-c/ExecutionEngine.h"
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
49 * Information associated by mono with LLVM modules.
52 LLVMModuleRef lmodule;
53 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
54 GHashTable *llvm_types;
56 const char *got_symbol;
57 const char *get_method_symbol;
58 const char *get_unbox_tramp_symbol;
59 GHashTable *plt_entries;
60 GHashTable *plt_entries_ji;
61 GHashTable *method_to_lmethod;
62 GHashTable *direct_callables;
67 GPtrArray *subprogram_mds;
69 LLVMExecutionEngineRef ee;
70 gboolean external_symbols;
75 MonoAssembly *assembly;
77 MonoAotFileInfo aot_info;
78 const char *jit_got_symbol;
79 const char *eh_frame_symbol;
80 LLVMValueRef get_method, get_unbox_tramp;
81 LLVMValueRef init_method, init_method_gshared_rgctx, init_method_gshared_this;
82 LLVMValueRef code_start, code_end;
83 LLVMValueRef inited_var;
84 int max_inited_idx, max_method_idx;
85 gboolean has_jitted_code;
88 GHashTable *idx_to_lmethod;
89 GHashTable *idx_to_unbox_tramp;
90 /* Maps a MonoMethod to LLVM instructions representing it */
91 GHashTable *method_to_callers;
92 LLVMContextRef context;
93 LLVMValueRef sentinel_exception;
97 * Information associated by the backend with mono basic blocks.
100 LLVMBasicBlockRef bblock, end_bblock;
101 LLVMValueRef finally_ind;
102 gboolean added, invoke_target;
104 * If this bblock is the start of a finally clause, this is a list of bblocks it
105 * needs to branch to in ENDFINALLY.
107 GSList *call_handler_return_bbs;
109 * If this bblock is the start of a finally clause, this is the bblock that
110 * CALL_HANDLER needs to branch to.
112 LLVMBasicBlockRef call_handler_target_bb;
113 /* The list of switch statements generated by ENDFINALLY instructions */
114 GSList *endfinally_switch_ins_list;
119 * Structure containing emit state
122 MonoMemPool *mempool;
124 /* Maps method names to the corresponding LLVMValueRef */
125 GHashTable *emitted_method_decls;
128 LLVMValueRef lmethod;
129 MonoLLVMModule *module;
130 LLVMModuleRef lmodule;
132 int sindex, default_index, ex_index;
133 LLVMBuilderRef builder;
134 LLVMValueRef *values, *addresses;
135 MonoType **vreg_cli_types;
137 MonoMethodSignature *sig;
139 GHashTable *region_to_handler;
140 GHashTable *clause_to_handler;
141 LLVMBuilderRef alloca_builder;
142 LLVMValueRef last_alloca;
143 LLVMValueRef rgctx_arg;
144 LLVMValueRef this_arg;
145 LLVMTypeRef *vreg_types;
146 LLVMBasicBlockRef init_bb, inited_bb;
148 gboolean *unreachable;
150 gboolean has_got_access;
151 int this_arg_pindex, rgctx_arg_pindex;
152 LLVMValueRef imt_rgctx_loc;
153 GHashTable *llvm_types;
155 MonoDebugMethodInfo *minfo;
157 /* For every clause, the clauses it is nested in */
160 GHashTable *exc_meta;
161 GHashTable *method_to_callers;
167 MonoBasicBlock *in_bb;
172 * Instruction metadata
173 * This is the same as ins_info, but LREG != IREG.
181 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
182 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
189 /* keep in sync with the enum in mini.h */
192 #include "mini-ops.h"
197 #if SIZEOF_VOID_P == 4
198 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
200 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
203 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
206 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
208 #define TRACE_FAILURE(msg)
212 #define IS_TARGET_X86 1
214 #define IS_TARGET_X86 0
218 #define IS_TARGET_AMD64 1
220 #define IS_TARGET_AMD64 0
223 #define LLVM_FAILURE(ctx, reason) do { \
224 TRACE_FAILURE (reason); \
225 (ctx)->cfg->exception_message = g_strdup (reason); \
226 (ctx)->cfg->disable_llvm = TRUE; \
230 #define CHECK_FAILURE(ctx) do { \
231 if ((ctx)->cfg->disable_llvm) \
235 static LLVMIntPredicate cond_to_llvm_cond [] = {
248 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
261 static MonoNativeTlsKey current_cfg_tls_id;
263 static MonoLLVMModule aot_module;
264 static int memset_param_count, memcpy_param_count;
265 static const char *memset_func_name;
266 static const char *memcpy_func_name;
268 static void init_jit_module (MonoDomain *domain);
270 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
271 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
272 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
277 * The LLVM type with width == sizeof (gpointer)
282 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
288 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
294 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
300 * Return the size of the LLVM representation of the vtype T.
303 get_vtype_size (MonoType *t)
307 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
309 /* LLVMArgAsIArgs depends on this since it stores whole words */
310 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
317 * simd_class_to_llvm_type:
319 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
322 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
324 if (!strcmp (klass->name, "Vector2d")) {
325 return LLVMVectorType (LLVMDoubleType (), 2);
326 } else if (!strcmp (klass->name, "Vector2l")) {
327 return LLVMVectorType (LLVMInt64Type (), 2);
328 } else if (!strcmp (klass->name, "Vector2ul")) {
329 return LLVMVectorType (LLVMInt64Type (), 2);
330 } else if (!strcmp (klass->name, "Vector4i")) {
331 return LLVMVectorType (LLVMInt32Type (), 4);
332 } else if (!strcmp (klass->name, "Vector4ui")) {
333 return LLVMVectorType (LLVMInt32Type (), 4);
334 } else if (!strcmp (klass->name, "Vector4f")) {
335 return LLVMVectorType (LLVMFloatType (), 4);
336 } else if (!strcmp (klass->name, "Vector8s")) {
337 return LLVMVectorType (LLVMInt16Type (), 8);
338 } else if (!strcmp (klass->name, "Vector8us")) {
339 return LLVMVectorType (LLVMInt16Type (), 8);
340 } else if (!strcmp (klass->name, "Vector16sb")) {
341 return LLVMVectorType (LLVMInt8Type (), 16);
342 } else if (!strcmp (klass->name, "Vector16b")) {
343 return LLVMVectorType (LLVMInt8Type (), 16);
345 printf ("%s\n", klass->name);
351 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
352 static inline G_GNUC_UNUSED LLVMTypeRef
353 type_to_simd_type (int type)
357 return LLVMVectorType (LLVMInt8Type (), 16);
359 return LLVMVectorType (LLVMInt16Type (), 8);
361 return LLVMVectorType (LLVMInt32Type (), 4);
363 return LLVMVectorType (LLVMInt64Type (), 2);
365 return LLVMVectorType (LLVMDoubleType (), 2);
367 return LLVMVectorType (LLVMFloatType (), 4);
369 g_assert_not_reached ();
375 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
377 int i, size, nfields, esize;
378 LLVMTypeRef *eltypes;
383 t = &klass->byval_arg;
385 if (mini_type_is_hfa (t, &nfields, &esize)) {
387 * This is needed on arm64 where HFAs are returned in
391 eltypes = g_new (LLVMTypeRef, size);
392 for (i = 0; i < size; ++i)
393 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
395 size = get_vtype_size (t);
397 eltypes = g_new (LLVMTypeRef, size);
398 for (i = 0; i < size; ++i)
399 eltypes [i] = LLVMInt8Type ();
402 name = mono_type_full_name (&klass->byval_arg);
403 ltype = LLVMStructCreateNamed (module->context, name);
404 LLVMStructSetBody (ltype, eltypes, size, FALSE);
414 * Return the LLVM type corresponding to T.
417 type_to_llvm_type (EmitContext *ctx, MonoType *t)
419 t = mini_get_underlying_type (t);
423 return LLVMVoidType ();
425 return LLVMInt8Type ();
427 return LLVMInt16Type ();
429 return LLVMInt32Type ();
431 return LLVMInt8Type ();
433 return LLVMInt16Type ();
435 return LLVMInt32Type ();
436 case MONO_TYPE_BOOLEAN:
437 return LLVMInt8Type ();
440 return LLVMInt64Type ();
442 return LLVMInt16Type ();
444 return LLVMFloatType ();
446 return LLVMDoubleType ();
449 return IntPtrType ();
450 case MONO_TYPE_OBJECT:
451 case MONO_TYPE_CLASS:
452 case MONO_TYPE_ARRAY:
453 case MONO_TYPE_SZARRAY:
454 case MONO_TYPE_STRING:
456 return ObjRefType ();
459 /* Because of generic sharing */
460 return ObjRefType ();
461 case MONO_TYPE_GENERICINST:
462 if (!mono_type_generic_inst_is_valuetype (t))
463 return ObjRefType ();
465 case MONO_TYPE_VALUETYPE:
466 case MONO_TYPE_TYPEDBYREF: {
470 klass = mono_class_from_mono_type (t);
472 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
473 return simd_class_to_llvm_type (ctx, klass);
476 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
478 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
480 ltype = create_llvm_type_for_type (ctx->module, klass);
481 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
487 printf ("X: %d\n", t->type);
488 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
489 ctx->cfg->disable_llvm = TRUE;
497 * Return whenever T is an unsigned int type.
500 type_is_unsigned (EmitContext *ctx, MonoType *t)
517 * type_to_llvm_arg_type:
519 * Same as type_to_llvm_type, but treat i8/i16 as i32.
522 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
524 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
526 if (ctx->cfg->llvm_only)
530 * This works on all abis except arm64/ios which passes multiple
531 * arguments in one stack slot.
534 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
536 * LLVM generates code which only sets the lower bits, while JITted
537 * code expects all the bits to be set.
539 ptype = LLVMInt32Type ();
547 * llvm_type_to_stack_type:
549 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
552 static G_GNUC_UNUSED LLVMTypeRef
553 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
557 if (type == LLVMInt8Type ())
558 return LLVMInt32Type ();
559 else if (type == LLVMInt16Type ())
560 return LLVMInt32Type ();
561 else if (!cfg->r4fp && type == LLVMFloatType ())
562 return LLVMDoubleType ();
568 * regtype_to_llvm_type:
570 * Return the LLVM type corresponding to the regtype C used in instruction
574 regtype_to_llvm_type (char c)
578 return LLVMInt32Type ();
580 return LLVMInt64Type ();
582 return LLVMDoubleType ();
591 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
594 op_to_llvm_type (int opcode)
599 return LLVMInt8Type ();
602 return LLVMInt8Type ();
605 return LLVMInt16Type ();
608 return LLVMInt16Type ();
611 return LLVMInt32Type ();
614 return LLVMInt32Type ();
616 return LLVMInt64Type ();
618 return LLVMFloatType ();
620 return LLVMDoubleType ();
622 return LLVMInt64Type ();
624 return LLVMInt32Type ();
626 return LLVMInt64Type ();
631 return LLVMInt8Type ();
636 return LLVMInt16Type ();
639 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
646 return LLVMInt32Type ();
653 return LLVMInt64Type ();
655 printf ("%s\n", mono_inst_name (opcode));
656 g_assert_not_reached ();
661 #define CLAUSE_START(clause) ((clause)->try_offset)
662 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
665 * load_store_to_llvm_type:
667 * Return the size/sign/zero extension corresponding to the load/store opcode
671 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
677 case OP_LOADI1_MEMBASE:
678 case OP_STOREI1_MEMBASE_REG:
679 case OP_STOREI1_MEMBASE_IMM:
680 case OP_ATOMIC_LOAD_I1:
681 case OP_ATOMIC_STORE_I1:
684 return LLVMInt8Type ();
685 case OP_LOADU1_MEMBASE:
687 case OP_ATOMIC_LOAD_U1:
688 case OP_ATOMIC_STORE_U1:
691 return LLVMInt8Type ();
692 case OP_LOADI2_MEMBASE:
693 case OP_STOREI2_MEMBASE_REG:
694 case OP_STOREI2_MEMBASE_IMM:
695 case OP_ATOMIC_LOAD_I2:
696 case OP_ATOMIC_STORE_I2:
699 return LLVMInt16Type ();
700 case OP_LOADU2_MEMBASE:
702 case OP_ATOMIC_LOAD_U2:
703 case OP_ATOMIC_STORE_U2:
706 return LLVMInt16Type ();
707 case OP_LOADI4_MEMBASE:
708 case OP_LOADU4_MEMBASE:
711 case OP_STOREI4_MEMBASE_REG:
712 case OP_STOREI4_MEMBASE_IMM:
713 case OP_ATOMIC_LOAD_I4:
714 case OP_ATOMIC_STORE_I4:
715 case OP_ATOMIC_LOAD_U4:
716 case OP_ATOMIC_STORE_U4:
718 return LLVMInt32Type ();
719 case OP_LOADI8_MEMBASE:
721 case OP_STOREI8_MEMBASE_REG:
722 case OP_STOREI8_MEMBASE_IMM:
723 case OP_ATOMIC_LOAD_I8:
724 case OP_ATOMIC_STORE_I8:
725 case OP_ATOMIC_LOAD_U8:
726 case OP_ATOMIC_STORE_U8:
728 return LLVMInt64Type ();
729 case OP_LOADR4_MEMBASE:
730 case OP_STORER4_MEMBASE_REG:
731 case OP_ATOMIC_LOAD_R4:
732 case OP_ATOMIC_STORE_R4:
734 return LLVMFloatType ();
735 case OP_LOADR8_MEMBASE:
736 case OP_STORER8_MEMBASE_REG:
737 case OP_ATOMIC_LOAD_R8:
738 case OP_ATOMIC_STORE_R8:
740 return LLVMDoubleType ();
741 case OP_LOAD_MEMBASE:
743 case OP_STORE_MEMBASE_REG:
744 case OP_STORE_MEMBASE_IMM:
745 *size = sizeof (gpointer);
746 return IntPtrType ();
748 g_assert_not_reached ();
756 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
759 ovf_op_to_intrins (int opcode)
763 return "llvm.sadd.with.overflow.i32";
765 return "llvm.uadd.with.overflow.i32";
767 return "llvm.ssub.with.overflow.i32";
769 return "llvm.usub.with.overflow.i32";
771 return "llvm.smul.with.overflow.i32";
773 return "llvm.umul.with.overflow.i32";
775 return "llvm.sadd.with.overflow.i64";
777 return "llvm.uadd.with.overflow.i64";
779 return "llvm.ssub.with.overflow.i64";
781 return "llvm.usub.with.overflow.i64";
783 return "llvm.smul.with.overflow.i64";
785 return "llvm.umul.with.overflow.i64";
787 g_assert_not_reached ();
793 simd_op_to_intrins (int opcode)
796 #if defined(TARGET_X86) || defined(TARGET_AMD64)
798 return "llvm.x86.sse2.min.pd";
800 return "llvm.x86.sse.min.ps";
802 return "llvm.x86.sse41.pminud";
804 return "llvm.x86.sse41.pminuw";
806 return "llvm.x86.sse2.pminu.b";
808 return "llvm.x86.sse2.pmins.w";
810 return "llvm.x86.sse2.max.pd";
812 return "llvm.x86.sse.max.ps";
814 return "llvm.x86.sse3.hadd.pd";
816 return "llvm.x86.sse3.hadd.ps";
818 return "llvm.x86.sse3.hsub.pd";
820 return "llvm.x86.sse3.hsub.ps";
822 return "llvm.x86.sse41.pmaxud";
824 return "llvm.x86.sse41.pmaxuw";
826 return "llvm.x86.sse2.pmaxu.b";
828 return "llvm.x86.sse3.addsub.ps";
830 return "llvm.x86.sse3.addsub.pd";
831 case OP_EXTRACT_MASK:
832 return "llvm.x86.sse2.pmovmskb.128";
835 return "llvm.x86.sse2.psrli.w";
838 return "llvm.x86.sse2.psrli.d";
841 return "llvm.x86.sse2.psrli.q";
844 return "llvm.x86.sse2.pslli.w";
847 return "llvm.x86.sse2.pslli.d";
850 return "llvm.x86.sse2.pslli.q";
853 return "llvm.x86.sse2.psrai.w";
856 return "llvm.x86.sse2.psrai.d";
858 return "llvm.x86.sse2.padds.b";
860 return "llvm.x86.sse2.padds.w";
862 return "llvm.x86.sse2.psubs.b";
864 return "llvm.x86.sse2.psubs.w";
865 case OP_PADDB_SAT_UN:
866 return "llvm.x86.sse2.paddus.b";
867 case OP_PADDW_SAT_UN:
868 return "llvm.x86.sse2.paddus.w";
869 case OP_PSUBB_SAT_UN:
870 return "llvm.x86.sse2.psubus.b";
871 case OP_PSUBW_SAT_UN:
872 return "llvm.x86.sse2.psubus.w";
874 return "llvm.x86.sse2.pavg.b";
876 return "llvm.x86.sse2.pavg.w";
878 return "llvm.x86.sse.sqrt.ps";
880 return "llvm.x86.sse2.sqrt.pd";
882 return "llvm.x86.sse.rsqrt.ps";
884 return "llvm.x86.sse.rcp.ps";
886 return "llvm.x86.sse2.cvtdq2pd";
888 return "llvm.x86.sse2.cvtdq2ps";
890 return "llvm.x86.sse2.cvtpd2dq";
892 return "llvm.x86.sse2.cvtps2dq";
894 return "llvm.x86.sse2.cvtpd2ps";
896 return "llvm.x86.sse2.cvtps2pd";
898 return "llvm.x86.sse2.cvttpd2dq";
900 return "llvm.x86.sse2.cvttps2dq";
902 return "llvm.x86.sse.cmp.ps";
904 return "llvm.x86.sse2.cmp.pd";
906 return "llvm.x86.sse2.packsswb.128";
908 return "llvm.x86.sse2.packssdw.128";
910 return "llvm.x86.sse2.packuswb.128";
912 return "llvm.x86.sse41.packusdw";
914 return "llvm.x86.sse2.pmulh.w";
915 case OP_PMULW_HIGH_UN:
916 return "llvm.x86.sse2.pmulhu.w";
919 g_assert_not_reached ();
925 simd_op_to_llvm_type (int opcode)
927 #if defined(TARGET_X86) || defined(TARGET_AMD64)
931 return type_to_simd_type (MONO_TYPE_R8);
934 return type_to_simd_type (MONO_TYPE_I8);
937 return type_to_simd_type (MONO_TYPE_I4);
942 return type_to_simd_type (MONO_TYPE_I2);
946 return type_to_simd_type (MONO_TYPE_I1);
948 return type_to_simd_type (MONO_TYPE_R4);
951 return type_to_simd_type (MONO_TYPE_I4);
955 return type_to_simd_type (MONO_TYPE_R8);
959 return type_to_simd_type (MONO_TYPE_R4);
960 case OP_EXTRACT_MASK:
961 return type_to_simd_type (MONO_TYPE_I1);
967 return type_to_simd_type (MONO_TYPE_R4);
970 return type_to_simd_type (MONO_TYPE_R8);
972 g_assert_not_reached ();
983 * Return the LLVM basic block corresponding to BB.
985 static LLVMBasicBlockRef
986 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
988 char bb_name_buf [128];
991 if (ctx->bblocks [bb->block_num].bblock == NULL) {
992 if (bb->flags & BB_EXCEPTION_HANDLER) {
993 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
994 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
995 bb_name = bb_name_buf;
996 } else if (bb->block_num < 256) {
997 if (!ctx->module->bb_names) {
998 ctx->module->bb_names_len = 256;
999 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1001 if (!ctx->module->bb_names [bb->block_num]) {
1004 n = g_strdup_printf ("BB%d", bb->block_num);
1005 mono_memory_barrier ();
1006 ctx->module->bb_names [bb->block_num] = n;
1008 bb_name = ctx->module->bb_names [bb->block_num];
1010 sprintf (bb_name_buf, "BB%d", bb->block_num);
1011 bb_name = bb_name_buf;
1014 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1015 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1018 return ctx->bblocks [bb->block_num].bblock;
1024 * Return the last LLVM bblock corresponding to BB.
1025 * This might not be equal to the bb returned by get_bb () since we need to generate
1026 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1028 static LLVMBasicBlockRef
1029 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1032 return ctx->bblocks [bb->block_num].end_bblock;
1035 static LLVMBasicBlockRef
1036 gen_bb (EmitContext *ctx, const char *prefix)
1040 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1041 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1047 * Return the target of the patch identified by TYPE and TARGET.
1050 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1054 memset (&ji, 0, sizeof (ji));
1056 ji.data.target = target;
1058 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1064 * Emit code to convert the LLVM value V to DTYPE.
1067 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1069 LLVMTypeRef stype = LLVMTypeOf (v);
1071 if (stype != dtype) {
1072 gboolean ext = FALSE;
1075 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1077 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1079 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1083 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1085 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1086 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1089 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1090 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1091 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1092 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1093 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1094 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1095 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1096 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1098 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1099 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1100 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1101 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1102 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1103 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1105 if (mono_arch_is_soft_float ()) {
1106 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1107 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1108 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1109 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1112 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1113 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1116 LLVMDumpValue (LLVMConstNull (dtype));
1117 g_assert_not_reached ();
1125 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1127 return convert_full (ctx, v, dtype, FALSE);
1131 * emit_volatile_load:
1133 * If vreg is volatile, emit a load from its address.
1136 emit_volatile_load (EmitContext *ctx, int vreg)
1140 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1141 t = ctx->vreg_cli_types [vreg];
1142 if (t && !t->byref) {
1144 * Might have to zero extend since llvm doesn't have
1147 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1148 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1149 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1150 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1151 else if (t->type == MONO_TYPE_U8)
1152 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1159 * emit_volatile_store:
1161 * If VREG is volatile, emit a store from its value to its address.
1164 emit_volatile_store (EmitContext *ctx, int vreg)
1166 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1168 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1169 g_assert (ctx->addresses [vreg]);
1170 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1175 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1177 LLVMTypeRef ret_type;
1178 LLVMTypeRef *param_types = NULL;
1183 rtype = mini_get_underlying_type (sig->ret);
1184 ret_type = type_to_llvm_type (ctx, rtype);
1185 CHECK_FAILURE (ctx);
1187 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1191 param_types [pindex ++] = ThisType ();
1192 for (i = 0; i < sig->param_count; ++i)
1193 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1195 CHECK_FAILURE (ctx);
1197 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1198 g_free (param_types);
1203 g_free (param_types);
1209 * sig_to_llvm_sig_full:
1211 * Return the LLVM signature corresponding to the mono signature SIG using the
1212 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1215 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1217 LLVMTypeRef ret_type;
1218 LLVMTypeRef *param_types = NULL;
1220 int i, j, pindex, vret_arg_pindex = 0;
1221 gboolean vretaddr = FALSE;
1225 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1227 rtype = mini_get_underlying_type (sig->ret);
1228 ret_type = type_to_llvm_type (ctx, rtype);
1229 CHECK_FAILURE (ctx);
1231 switch (cinfo->ret.storage) {
1232 case LLVMArgVtypeInReg:
1233 /* LLVM models this by returning an aggregate value */
1234 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1235 LLVMTypeRef members [2];
1237 members [0] = IntPtrType ();
1238 ret_type = LLVMStructType (members, 1, FALSE);
1239 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1241 ret_type = LLVMVoidType ();
1242 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1243 LLVMTypeRef members [2];
1245 members [0] = IntPtrType ();
1246 members [1] = IntPtrType ();
1247 ret_type = LLVMStructType (members, 2, FALSE);
1249 g_assert_not_reached ();
1252 case LLVMArgVtypeByVal:
1253 /* Vtype returned normally by val */
1255 case LLVMArgVtypeAsScalar:
1256 /* LLVM models this by returning an int */
1257 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1258 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1260 case LLVMArgFpStruct: {
1261 /* Vtype returned as a fp struct */
1262 LLVMTypeRef members [16];
1264 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1265 for (i = 0; i < cinfo->ret.nslots; ++i)
1266 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1267 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1270 case LLVMArgVtypeByRef:
1271 /* Vtype returned using a hidden argument */
1272 ret_type = LLVMVoidType ();
1274 case LLVMArgVtypeRetAddr:
1275 case LLVMArgScalarRetAddr:
1276 case LLVMArgGsharedvtFixed:
1277 case LLVMArgGsharedvtFixedVtype:
1278 case LLVMArgGsharedvtVariable:
1280 ret_type = LLVMVoidType ();
1286 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1288 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1290 * Has to be the first argument because of the sret argument attribute
1291 * FIXME: This might conflict with passing 'this' as the first argument, but
1292 * this is only used on arm64 which has a dedicated struct return register.
1294 cinfo->vret_arg_pindex = pindex;
1295 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1296 CHECK_FAILURE (ctx);
1297 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1300 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1301 cinfo->rgctx_arg_pindex = pindex;
1302 param_types [pindex] = ctx->module->ptr_type;
1305 if (cinfo->imt_arg) {
1306 cinfo->imt_arg_pindex = pindex;
1307 param_types [pindex] = ctx->module->ptr_type;
1311 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1312 vret_arg_pindex = pindex;
1313 if (cinfo->vret_arg_index == 1) {
1314 /* Add the slots consumed by the first argument */
1315 LLVMArgInfo *ainfo = &cinfo->args [0];
1316 switch (ainfo->storage) {
1317 case LLVMArgVtypeInReg:
1318 for (j = 0; j < 2; ++j) {
1319 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1328 cinfo->vret_arg_pindex = vret_arg_pindex;
1331 if (vretaddr && vret_arg_pindex == pindex)
1332 param_types [pindex ++] = IntPtrType ();
1334 cinfo->this_arg_pindex = pindex;
1335 param_types [pindex ++] = ThisType ();
1336 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1338 if (vretaddr && vret_arg_pindex == pindex)
1339 param_types [pindex ++] = IntPtrType ();
1340 for (i = 0; i < sig->param_count; ++i) {
1341 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1343 if (vretaddr && vret_arg_pindex == pindex)
1344 param_types [pindex ++] = IntPtrType ();
1345 ainfo->pindex = pindex;
1347 switch (ainfo->storage) {
1348 case LLVMArgVtypeInReg:
1349 for (j = 0; j < 2; ++j) {
1350 switch (ainfo->pair_storage [j]) {
1352 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1357 g_assert_not_reached ();
1361 case LLVMArgVtypeByVal:
1362 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1363 CHECK_FAILURE (ctx);
1364 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1367 case LLVMArgAsIArgs:
1368 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1371 case LLVMArgVtypeByRef:
1372 case LLVMArgScalarByRef:
1373 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1374 CHECK_FAILURE (ctx);
1375 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1378 case LLVMArgAsFpArgs: {
1381 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1382 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1383 param_types [pindex ++] = LLVMDoubleType ();
1384 for (j = 0; j < ainfo->nslots; ++j)
1385 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1388 case LLVMArgVtypeAsScalar:
1389 g_assert_not_reached ();
1391 case LLVMArgGsharedvtFixed:
1392 case LLVMArgGsharedvtFixedVtype:
1393 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1395 case LLVMArgGsharedvtVariable:
1396 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1399 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1403 if (vretaddr && vret_arg_pindex == pindex)
1404 param_types [pindex ++] = IntPtrType ();
1405 if (ctx->llvm_only && cinfo->rgctx_arg) {
1406 /* Pass the rgctx as the last argument */
1407 cinfo->rgctx_arg_pindex = pindex;
1408 param_types [pindex] = ctx->module->ptr_type;
1412 CHECK_FAILURE (ctx);
1414 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1415 g_free (param_types);
1420 g_free (param_types);
1426 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1428 return sig_to_llvm_sig_full (ctx, sig, NULL);
1432 * LLVMFunctionType1:
1434 * Create an LLVM function type from the arguments.
1436 static G_GNUC_UNUSED LLVMTypeRef
1437 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1440 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1444 * LLVMFunctionType1:
1446 * Create an LLVM function type from the arguments.
1448 static G_GNUC_UNUSED LLVMTypeRef
1449 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1450 LLVMTypeRef ParamType1,
1453 LLVMTypeRef param_types [1];
1455 param_types [0] = ParamType1;
1457 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1461 * LLVMFunctionType2:
1463 * Create an LLVM function type from the arguments.
1465 static G_GNUC_UNUSED LLVMTypeRef
1466 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1467 LLVMTypeRef ParamType1,
1468 LLVMTypeRef ParamType2,
1471 LLVMTypeRef param_types [2];
1473 param_types [0] = ParamType1;
1474 param_types [1] = ParamType2;
1476 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1480 * LLVMFunctionType3:
1482 * Create an LLVM function type from the arguments.
1484 static G_GNUC_UNUSED LLVMTypeRef
1485 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1486 LLVMTypeRef ParamType1,
1487 LLVMTypeRef ParamType2,
1488 LLVMTypeRef ParamType3,
1491 LLVMTypeRef param_types [3];
1493 param_types [0] = ParamType1;
1494 param_types [1] = ParamType2;
1495 param_types [2] = ParamType3;
1497 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1503 * Create an LLVM builder and remember it so it can be freed later.
1505 static LLVMBuilderRef
1506 create_builder (EmitContext *ctx)
1508 LLVMBuilderRef builder = LLVMCreateBuilder ();
1510 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1516 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1521 case MONO_PATCH_INFO_INTERNAL_METHOD:
1522 name = g_strdup_printf ("jit_icall_%s", data);
1524 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1525 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1526 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1530 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1538 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1542 LLVMValueRef indexes [2];
1544 LLVMValueRef got_entry_addr, load;
1545 LLVMBuilderRef builder = ctx->builder;
1550 ji = g_new0 (MonoJumpInfo, 1);
1552 ji->data.target = data;
1554 ji = mono_aot_patch_info_dup (ji);
1556 ji->next = cfg->patch_info;
1557 cfg->patch_info = ji;
1559 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1560 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1562 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1563 * explicitly initialize it.
1565 if (!mono_aot_is_shared_got_offset (got_offset)) {
1566 //mono_print_ji (ji);
1568 ctx->has_got_access = TRUE;
1571 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1572 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1573 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1575 name = get_aotconst_name (type, data, got_offset);
1577 load = convert (ctx, LLVMBuildLoad (builder, got_entry_addr, ""), llvm_type);
1578 LLVMSetValueName (load, name ? name : "");
1580 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1583 //set_invariant_load_flag (load);
1589 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1591 return get_aotconst_typed (ctx, type, data, NULL);
1595 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1597 LLVMValueRef callee;
1599 if (ctx->llvm_only) {
1600 callee_name = mono_aot_get_direct_call_symbol (type, data);
1602 /* Directly callable */
1604 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1606 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1608 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1610 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1612 g_free (callee_name);
1618 * Calls are made through the GOT.
1620 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1622 MonoJumpInfo *ji = NULL;
1624 callee_name = mono_aot_get_plt_symbol (type, data);
1628 if (ctx->cfg->compile_aot)
1629 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1630 mono_add_patch_info (ctx->cfg, 0, type, data);
1633 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1635 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1637 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1639 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1642 if (ctx->cfg->compile_aot) {
1643 ji = g_new0 (MonoJumpInfo, 1);
1645 ji->data.target = data;
1647 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1655 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1657 MonoMethodHeader *header = cfg->header;
1658 MonoExceptionClause *clause;
1662 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1663 return (bb->region >> 8) - 1;
1666 for (i = 0; i < header->num_clauses; ++i) {
1667 clause = &header->clauses [i];
1669 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1676 static MonoExceptionClause *
1677 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1679 // Since they're sorted by nesting we just need
1680 // the first one that the bb is a member of
1681 MonoExceptionClause *last = NULL;
1683 for (int i = 0; i < cfg->header->num_clauses; i++) {
1684 MonoExceptionClause *curr = &cfg->header->clauses [i];
1686 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1689 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1690 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1704 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1706 LLVMValueRef md_arg;
1709 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1710 md_arg = LLVMMDString ("mono", 4);
1711 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1715 set_invariant_load_flag (LLVMValueRef v)
1717 LLVMValueRef md_arg;
1719 const char *flag_name;
1721 // FIXME: Cache this
1722 flag_name = "invariant.load";
1723 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1724 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1725 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1731 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1735 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1737 MonoCompile *cfg = ctx->cfg;
1738 LLVMValueRef lcall = NULL;
1739 LLVMBuilderRef builder = *builder_ref;
1740 MonoExceptionClause *clause;
1742 if (ctx->llvm_only) {
1743 clause = get_most_deep_clause (cfg, ctx, bb);
1746 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1749 * Have to use an invoke instead of a call, branching to the
1750 * handler bblock of the clause containing this bblock.
1752 intptr_t key = CLAUSE_END(clause);
1754 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1756 // FIXME: Find the one that has the lowest end bound for the right start address
1757 // FIXME: Finally + nesting
1760 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1763 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1765 builder = ctx->builder = create_builder (ctx);
1766 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1768 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1772 int clause_index = get_handler_clause (cfg, bb);
1774 if (clause_index != -1) {
1775 MonoMethodHeader *header = cfg->header;
1776 MonoExceptionClause *ec = &header->clauses [clause_index];
1777 MonoBasicBlock *tblock;
1778 LLVMBasicBlockRef ex_bb, noex_bb;
1781 * Have to use an invoke instead of a call, branching to the
1782 * handler bblock of the clause containing this bblock.
1785 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1787 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1790 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1792 ex_bb = get_bb (ctx, tblock);
1794 noex_bb = gen_bb (ctx, "NOEX_BB");
1797 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1799 builder = ctx->builder = create_builder (ctx);
1800 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1802 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1807 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1808 ctx->builder = builder;
1812 *builder_ref = ctx->builder;
1818 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1820 const char *intrins_name;
1821 LLVMValueRef args [16], res;
1822 LLVMTypeRef addr_type;
1824 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1825 LLVMAtomicOrdering ordering;
1828 case LLVM_BARRIER_NONE:
1829 ordering = LLVMAtomicOrderingNotAtomic;
1831 case LLVM_BARRIER_ACQ:
1832 ordering = LLVMAtomicOrderingAcquire;
1834 case LLVM_BARRIER_SEQ:
1835 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1838 g_assert_not_reached ();
1843 * We handle loads which can fault by calling a mono specific intrinsic
1844 * using an invoke, so they are handled properly inside try blocks.
1845 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1846 * are marked with IntrReadArgMem.
1850 intrins_name = "llvm.mono.load.i8.p0i8";
1853 intrins_name = "llvm.mono.load.i16.p0i16";
1856 intrins_name = "llvm.mono.load.i32.p0i32";
1859 intrins_name = "llvm.mono.load.i64.p0i64";
1862 g_assert_not_reached ();
1865 addr_type = LLVMTypeOf (addr);
1866 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1867 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1870 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1871 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1872 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1873 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1875 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1876 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1877 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1878 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1885 * We emit volatile loads for loads which can fault, because otherwise
1886 * LLVM will generate invalid code when encountering a load from a
1889 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1891 /* Mark it with a custom metadata */
1894 set_metadata_flag (res, "mono.faulting.load");
1902 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1904 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1908 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1910 const char *intrins_name;
1911 LLVMValueRef args [16];
1913 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1914 LLVMAtomicOrdering ordering;
1917 case LLVM_BARRIER_NONE:
1918 ordering = LLVMAtomicOrderingNotAtomic;
1920 case LLVM_BARRIER_REL:
1921 ordering = LLVMAtomicOrderingRelease;
1923 case LLVM_BARRIER_SEQ:
1924 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1927 g_assert_not_reached ();
1933 intrins_name = "llvm.mono.store.i8.p0i8";
1936 intrins_name = "llvm.mono.store.i16.p0i16";
1939 intrins_name = "llvm.mono.store.i32.p0i32";
1942 intrins_name = "llvm.mono.store.i64.p0i64";
1945 g_assert_not_reached ();
1948 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1949 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1950 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1955 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1956 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1957 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1958 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
1960 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1965 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1967 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1971 * emit_cond_system_exception:
1973 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1974 * Might set the ctx exception.
1977 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1979 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
1980 LLVMBuilderRef builder;
1981 MonoClass *exc_class;
1982 LLVMValueRef args [2];
1983 LLVMValueRef callee;
1985 ex_bb = gen_bb (ctx, "EX_BB");
1987 ex2_bb = gen_bb (ctx, "EX2_BB");
1988 noex_bb = gen_bb (ctx, "NOEX_BB");
1990 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1992 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1993 g_assert (exc_class);
1995 /* Emit exception throwing code */
1996 ctx->builder = builder = create_builder (ctx);
1997 LLVMPositionBuilderAtEnd (builder, ex_bb);
1999 if (ctx->cfg->llvm_only) {
2000 static LLVMTypeRef sig;
2003 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2004 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_llvm_throw_corlib_exception");
2006 LLVMBuildBr (builder, ex2_bb);
2008 ctx->builder = builder = create_builder (ctx);
2009 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2011 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2012 emit_call (ctx, bb, &builder, callee, args, 1);
2013 LLVMBuildUnreachable (builder);
2015 ctx->builder = builder = create_builder (ctx);
2016 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2018 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2024 callee = ctx->module->throw_corlib_exception;
2027 const char *icall_name;
2029 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2030 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2032 if (ctx->cfg->compile_aot) {
2033 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2035 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2038 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2039 * - On x86, LLVM generated code doesn't push the arguments
2040 * - The trampoline takes the throw address as an arguments, not a pc offset.
2042 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2044 mono_memory_barrier ();
2045 ctx->module->throw_corlib_exception = callee;
2049 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2050 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2052 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2055 * The LLVM mono branch contains changes so a block address can be passed as an
2056 * argument to a call.
2058 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2059 emit_call (ctx, bb, &builder, callee, args, 2);
2061 LLVMBuildUnreachable (builder);
2063 ctx->builder = builder = create_builder (ctx);
2064 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2066 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2073 * emit_args_to_vtype:
2075 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2078 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2080 int j, size, nslots;
2082 size = get_vtype_size (t);
2084 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2085 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2088 if (ainfo->storage == LLVMArgAsFpArgs)
2089 nslots = ainfo->nslots;
2093 for (j = 0; j < nslots; ++j) {
2094 LLVMValueRef index [2], addr, daddr;
2095 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2096 LLVMTypeRef part_type;
2098 if (ainfo->pair_storage [j] == LLVMArgNone)
2101 switch (ainfo->pair_storage [j]) {
2102 case LLVMArgInIReg: {
2103 part_type = LLVMIntType (part_size * 8);
2104 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2105 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2106 addr = LLVMBuildGEP (builder, address, index, 1, "");
2108 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2109 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2110 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2112 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2115 case LLVMArgInFPReg: {
2116 LLVMTypeRef arg_type;
2118 if (ainfo->esize == 8)
2119 arg_type = LLVMDoubleType ();
2121 arg_type = LLVMFloatType ();
2123 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2124 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2125 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2126 LLVMBuildStore (builder, args [j], addr);
2132 g_assert_not_reached ();
2135 size -= sizeof (gpointer);
2140 * emit_vtype_to_args:
2142 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2143 * into ARGS, and the number of arguments into NARGS.
2146 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2149 int j, size, nslots;
2150 LLVMTypeRef arg_type;
2152 size = get_vtype_size (t);
2154 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2155 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2157 if (ainfo->storage == LLVMArgAsFpArgs)
2158 nslots = ainfo->nslots;
2161 for (j = 0; j < nslots; ++j) {
2162 LLVMValueRef index [2], addr, daddr;
2163 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2165 if (ainfo->pair_storage [j] == LLVMArgNone)
2168 switch (ainfo->pair_storage [j]) {
2170 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2171 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2172 addr = LLVMBuildGEP (builder, address, index, 1, "");
2174 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2175 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2176 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2178 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2180 case LLVMArgInFPReg:
2181 if (ainfo->esize == 8)
2182 arg_type = LLVMDoubleType ();
2184 arg_type = LLVMFloatType ();
2185 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2186 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2187 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2188 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2193 g_assert_not_reached ();
2195 size -= sizeof (gpointer);
2202 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2205 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2206 * get executed every time control reaches them.
2208 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2210 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2211 return ctx->last_alloca;
2215 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2217 return build_alloca_llvm_type_name (ctx, t, align, "");
2221 build_alloca (EmitContext *ctx, MonoType *t)
2223 MonoClass *k = mono_class_from_mono_type (t);
2226 g_assert (!mini_is_gsharedvt_variable_type (t));
2228 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2231 align = mono_class_min_align (k);
2233 /* Sometimes align is not a power of 2 */
2234 while (mono_is_power_of_two (align) == -1)
2237 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2241 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2245 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2247 MonoCompile *cfg = ctx->cfg;
2248 LLVMBuilderRef builder = ctx->builder;
2249 LLVMValueRef offset, offset_var;
2250 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2251 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2255 g_assert (info_var);
2256 g_assert (locals_var);
2258 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2260 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2261 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2263 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2264 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2266 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2270 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2273 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2276 module->used = g_ptr_array_sized_new (16);
2277 g_ptr_array_add (module->used, global);
2281 emit_llvm_used (MonoLLVMModule *module)
2283 LLVMModuleRef lmodule = module->lmodule;
2284 LLVMTypeRef used_type;
2285 LLVMValueRef used, *used_elem;
2291 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2292 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2293 used_elem = g_new0 (LLVMValueRef, module->used->len);
2294 for (i = 0; i < module->used->len; ++i)
2295 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2296 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2297 LLVMSetLinkage (used, LLVMAppendingLinkage);
2298 LLVMSetSection (used, "llvm.metadata");
2304 * Emit a function mapping method indexes to their code
2307 emit_get_method (MonoLLVMModule *module)
2309 LLVMModuleRef lmodule = module->lmodule;
2310 LLVMValueRef func, switch_ins, m;
2311 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2312 LLVMBasicBlockRef *bbs;
2314 LLVMBuilderRef builder;
2319 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2320 * but generating code seems safer.
2322 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2323 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2324 LLVMSetLinkage (func, LLVMExternalLinkage);
2325 LLVMSetVisibility (func, LLVMHiddenVisibility);
2326 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2327 module->get_method = func;
2329 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2332 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2333 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2334 * then we will have to find another solution.
2337 name = g_strdup_printf ("BB_CODE_START");
2338 code_start_bb = LLVMAppendBasicBlock (func, name);
2340 builder = LLVMCreateBuilder ();
2341 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2342 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2344 name = g_strdup_printf ("BB_CODE_END");
2345 code_end_bb = LLVMAppendBasicBlock (func, name);
2347 builder = LLVMCreateBuilder ();
2348 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2349 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2351 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2352 for (i = 0; i < module->max_method_idx + 1; ++i) {
2353 name = g_strdup_printf ("BB_%d", i);
2354 bb = LLVMAppendBasicBlock (func, name);
2358 builder = LLVMCreateBuilder ();
2359 LLVMPositionBuilderAtEnd (builder, bb);
2361 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2363 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2365 LLVMBuildRet (builder, LLVMConstNull (rtype));
2368 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2369 builder = LLVMCreateBuilder ();
2370 LLVMPositionBuilderAtEnd (builder, fail_bb);
2371 LLVMBuildRet (builder, LLVMConstNull (rtype));
2373 builder = LLVMCreateBuilder ();
2374 LLVMPositionBuilderAtEnd (builder, entry_bb);
2376 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2377 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2378 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2379 for (i = 0; i < module->max_method_idx + 1; ++i) {
2380 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2383 mark_as_used (module, func);
2387 * emit_get_unbox_tramp:
2389 * Emit a function mapping method indexes to their unbox trampoline
2392 emit_get_unbox_tramp (MonoLLVMModule *module)
2394 LLVMModuleRef lmodule = module->lmodule;
2395 LLVMValueRef func, switch_ins, m;
2396 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2397 LLVMBasicBlockRef *bbs;
2399 LLVMBuilderRef builder;
2403 /* Similar to emit_get_method () */
2405 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2406 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2407 LLVMSetLinkage (func, LLVMExternalLinkage);
2408 LLVMSetVisibility (func, LLVMHiddenVisibility);
2409 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2410 module->get_unbox_tramp = func;
2412 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2414 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2415 for (i = 0; i < module->max_method_idx + 1; ++i) {
2416 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2420 name = g_strdup_printf ("BB_%d", i);
2421 bb = LLVMAppendBasicBlock (func, name);
2425 builder = LLVMCreateBuilder ();
2426 LLVMPositionBuilderAtEnd (builder, bb);
2428 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2431 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2432 builder = LLVMCreateBuilder ();
2433 LLVMPositionBuilderAtEnd (builder, fail_bb);
2434 LLVMBuildRet (builder, LLVMConstNull (rtype));
2436 builder = LLVMCreateBuilder ();
2437 LLVMPositionBuilderAtEnd (builder, entry_bb);
2439 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2440 for (i = 0; i < module->max_method_idx + 1; ++i) {
2441 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2445 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2448 mark_as_used (module, func);
2451 /* Add a function to mark the beginning of LLVM code */
2453 emit_llvm_code_start (MonoLLVMModule *module)
2455 LLVMModuleRef lmodule = module->lmodule;
2457 LLVMBasicBlockRef entry_bb;
2458 LLVMBuilderRef builder;
2460 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2461 LLVMSetLinkage (func, LLVMInternalLinkage);
2462 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2463 module->code_start = func;
2464 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2465 builder = LLVMCreateBuilder ();
2466 LLVMPositionBuilderAtEnd (builder, entry_bb);
2467 LLVMBuildRetVoid (builder);
2471 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2473 LLVMModuleRef lmodule = module->lmodule;
2474 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2475 LLVMBasicBlockRef entry_bb;
2476 LLVMBuilderRef builder;
2483 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2484 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2487 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2488 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2491 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2492 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2495 g_assert_not_reached ();
2497 LLVMSetLinkage (func, LLVMInternalLinkage);
2498 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2499 mono_llvm_set_preserveall_cc (func);
2500 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2501 builder = LLVMCreateBuilder ();
2502 LLVMPositionBuilderAtEnd (builder, entry_bb);
2505 ji = g_new0 (MonoJumpInfo, 1);
2506 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2507 ji = mono_aot_patch_info_dup (ji);
2508 got_offset = mono_aot_get_got_offset (ji);
2509 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2510 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2511 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2512 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2513 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2514 args [1] = LLVMGetParam (func, 0);
2516 args [2] = LLVMGetParam (func, 1);
2518 ji = g_new0 (MonoJumpInfo, 1);
2519 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2520 ji->data.name = icall_name;
2521 ji = mono_aot_patch_info_dup (ji);
2522 got_offset = mono_aot_get_got_offset (ji);
2523 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2524 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2525 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2526 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2527 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2528 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2529 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2531 // Set the inited flag
2532 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2533 indexes [1] = LLVMGetParam (func, 0);
2534 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2536 LLVMBuildRetVoid (builder);
2538 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2543 * Emit wrappers around the C icalls used to initialize llvm methods, to
2544 * make the calling code smaller and to enable usage of the llvm
2545 * PreserveAll calling convention.
2548 emit_init_icall_wrappers (MonoLLVMModule *module)
2550 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2551 module->init_method_gshared_rgctx = emit_init_icall_wrapper (module, "init_method_gshared_rgctx", "mono_aot_init_gshared_method_rgctx", 1);
2552 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2556 emit_llvm_code_end (MonoLLVMModule *module)
2558 LLVMModuleRef lmodule = module->lmodule;
2560 LLVMBasicBlockRef entry_bb;
2561 LLVMBuilderRef builder;
2563 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2564 LLVMSetLinkage (func, LLVMInternalLinkage);
2565 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2566 module->code_end = func;
2567 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2568 builder = LLVMCreateBuilder ();
2569 LLVMPositionBuilderAtEnd (builder, entry_bb);
2570 LLVMBuildRetVoid (builder);
2574 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2576 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2579 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2580 need_div_check = TRUE;
2582 if (!need_div_check)
2585 switch (ins->opcode) {
2598 case OP_IDIV_UN_IMM:
2599 case OP_LDIV_UN_IMM:
2600 case OP_IREM_UN_IMM:
2601 case OP_LREM_UN_IMM: {
2603 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2604 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2606 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2607 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2608 CHECK_FAILURE (ctx);
2609 builder = ctx->builder;
2611 /* b == -1 && a == 0x80000000 */
2613 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2614 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2615 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2617 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2618 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2619 CHECK_FAILURE (ctx);
2620 builder = ctx->builder;
2635 * Emit code to initialize the GOT slots used by the method.
2638 emit_init_method (EmitContext *ctx)
2640 LLVMValueRef indexes [16], args [16], callee;
2641 LLVMValueRef inited_var, cmp, call;
2642 LLVMBasicBlockRef inited_bb, notinited_bb;
2643 LLVMBuilderRef builder = ctx->builder;
2644 MonoCompile *cfg = ctx->cfg;
2646 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2648 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2649 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2650 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2652 args [0] = inited_var;
2653 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2654 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2656 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2658 inited_bb = ctx->inited_bb;
2659 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2661 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2663 builder = ctx->builder = create_builder (ctx);
2664 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2667 if (ctx->rgctx_arg) {
2668 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2669 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2670 callee = ctx->module->init_method_gshared_rgctx;
2671 call = LLVMBuildCall (builder, callee, args, 2, "");
2672 } else if (cfg->gshared) {
2673 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2674 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2675 callee = ctx->module->init_method_gshared_this;
2676 call = LLVMBuildCall (builder, callee, args, 2, "");
2678 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2679 callee = ctx->module->init_method;
2680 call = LLVMBuildCall (builder, callee, args, 1, "");
2684 * This enables llvm to keep arguments in their original registers/
2685 * scratch registers, since the call will not clobber them.
2687 mono_llvm_set_call_preserveall_cc (call);
2689 LLVMBuildBr (builder, inited_bb);
2690 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2692 builder = ctx->builder = create_builder (ctx);
2693 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2697 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2700 * Emit unbox trampoline using a tail call
2702 LLVMValueRef tramp, call, *args;
2703 LLVMBuilderRef builder;
2704 LLVMBasicBlockRef lbb;
2708 tramp_name = g_strdup_printf ("ut_%s", method_name);
2709 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2710 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2711 LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2712 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2713 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2715 lbb = LLVMAppendBasicBlock (tramp, "");
2716 builder = LLVMCreateBuilder ();
2717 LLVMPositionBuilderAtEnd (builder, lbb);
2719 nargs = LLVMCountParamTypes (method_type);
2720 args = g_new0 (LLVMValueRef, nargs);
2721 for (i = 0; i < nargs; ++i) {
2722 args [i] = LLVMGetParam (tramp, i);
2723 if (i == ctx->this_arg_pindex) {
2724 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2726 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2727 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2728 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2731 call = LLVMBuildCall (builder, method, args, nargs, "");
2732 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2733 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2734 mono_llvm_set_must_tail (call);
2735 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2736 LLVMBuildRetVoid (builder);
2738 LLVMBuildRet (builder, call);
2740 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2746 * Emit code to load/convert arguments.
2749 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2752 MonoCompile *cfg = ctx->cfg;
2753 MonoMethodSignature *sig = ctx->sig;
2754 LLVMCallInfo *linfo = ctx->linfo;
2758 LLVMBuilderRef old_builder = ctx->builder;
2759 ctx->builder = builder;
2761 ctx->alloca_builder = create_builder (ctx);
2764 * Handle indirect/volatile variables by allocating memory for them
2765 * using 'alloca', and storing their address in a temporary.
2767 for (i = 0; i < cfg->num_varinfo; ++i) {
2768 MonoInst *var = cfg->varinfo [i];
2771 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2772 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2773 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2774 CHECK_FAILURE (ctx);
2775 /* Could be already created by an OP_VPHI */
2776 if (!ctx->addresses [var->dreg])
2777 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2778 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2782 names = g_new (char *, sig->param_count);
2783 mono_method_get_param_names (cfg->method, (const char **) names);
2785 for (i = 0; i < sig->param_count; ++i) {
2786 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2787 int reg = cfg->args [i + sig->hasthis]->dreg;
2790 pindex = ainfo->pindex;
2792 switch (ainfo->storage) {
2793 case LLVMArgVtypeInReg:
2794 case LLVMArgAsFpArgs: {
2795 LLVMValueRef args [8];
2798 pindex += ainfo->ndummy_fpargs;
2800 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2801 memset (args, 0, sizeof (args));
2802 if (ainfo->storage == LLVMArgVtypeInReg) {
2803 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2804 if (ainfo->pair_storage [1] != LLVMArgNone)
2805 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2807 g_assert (ainfo->nslots <= 8);
2808 for (j = 0; j < ainfo->nslots; ++j)
2809 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2811 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2813 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2815 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2816 /* Treat these as normal values */
2817 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2821 case LLVMArgVtypeByVal: {
2822 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2824 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2825 /* Treat these as normal values */
2826 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2830 case LLVMArgVtypeByRef: {
2831 /* The argument is passed by ref */
2832 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2835 case LLVMArgScalarByRef: {
2837 name = g_strdup_printf ("arg_%s", names [i]);
2839 name = g_strdup_printf ("arg_%d", i);
2840 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2844 case LLVMArgAsIArgs: {
2845 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2847 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2849 /* The argument is received as an array of ints, store it into the real argument */
2850 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2853 case LLVMArgVtypeAsScalar:
2854 g_assert_not_reached ();
2856 case LLVMArgGsharedvtFixed: {
2857 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2858 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2861 name = g_strdup_printf ("arg_%s", names [i]);
2863 name = g_strdup_printf ("arg_%d", i);
2865 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2868 case LLVMArgGsharedvtFixedVtype: {
2869 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2872 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2874 name = g_strdup_printf ("vtype_arg_%d", i);
2876 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2877 g_assert (ctx->addresses [reg]);
2878 LLVMSetValueName (ctx->addresses [reg], name);
2879 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2882 case LLVMArgGsharedvtVariable:
2883 /* The IR treats these as variables with addresses */
2884 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2887 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
2894 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2896 emit_volatile_store (ctx, cfg->args [0]->dreg);
2897 for (i = 0; i < sig->param_count; ++i)
2898 if (!mini_type_is_vtype (sig->params [i]))
2899 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2901 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2902 LLVMValueRef this_alloc;
2905 * The exception handling code needs the location where the this argument was
2906 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2907 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2908 * location into the LSDA.
2910 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2911 /* This volatile store will keep the alloca alive */
2912 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2914 set_metadata_flag (this_alloc, "mono.this");
2917 if (cfg->rgctx_var) {
2918 LLVMValueRef rgctx_alloc, store;
2921 * We handle the rgctx arg similarly to the this pointer.
2923 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2924 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2925 /* This volatile store will keep the alloca alive */
2926 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2928 set_metadata_flag (rgctx_alloc, "mono.this");
2931 /* Initialize the method if needed */
2932 if (cfg->compile_aot && ctx->llvm_only) {
2933 /* Emit a location for the initialization code */
2934 ctx->init_bb = gen_bb (ctx, "INIT_BB");
2935 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
2937 LLVMBuildBr (ctx->builder, ctx->init_bb);
2938 builder = ctx->builder = create_builder (ctx);
2939 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
2940 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
2943 /* Compute nesting between clauses */
2944 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2945 for (i = 0; i < cfg->header->num_clauses; ++i) {
2946 for (j = 0; j < cfg->header->num_clauses; ++j) {
2947 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2948 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2950 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2951 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2956 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2957 * it needs to continue normally, or return back to the exception handling system.
2959 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2963 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2966 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2967 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2968 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2970 if (bb->in_scount == 0) {
2973 sprintf (name, "finally_ind_bb%d", bb->block_num);
2974 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2975 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2977 ctx->bblocks [bb->block_num].finally_ind = val;
2979 /* Create a variable to hold the exception var */
2981 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2985 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2986 * LLVM bblock containing a landing pad causes problems for the
2987 * LLVM optimizer passes.
2989 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
2990 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2997 ctx->builder = old_builder;
3001 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3003 MonoCompile *cfg = ctx->cfg;
3004 LLVMModuleRef lmodule = ctx->lmodule;
3005 LLVMValueRef *values = ctx->values;
3006 LLVMValueRef *addresses = ctx->addresses;
3007 MonoCallInst *call = (MonoCallInst*)ins;
3008 MonoMethodSignature *sig = call->signature;
3009 LLVMValueRef callee = NULL, lcall;
3011 LLVMCallInfo *cinfo;
3015 LLVMTypeRef llvm_sig;
3017 gboolean is_virtual, calli;
3018 LLVMBuilderRef builder = *builder_ref;
3020 if (call->signature->call_convention != MONO_CALL_DEFAULT)
3021 LLVM_FAILURE (ctx, "non-default callconv");
3023 cinfo = call->cinfo;
3025 if (call->rgctx_arg_reg)
3026 cinfo->rgctx_arg = TRUE;
3027 if (call->imt_arg_reg)
3028 cinfo->imt_arg = TRUE;
3030 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgScalarRetAddr || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3032 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3033 CHECK_FAILURE (ctx);
3035 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3036 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3038 /* FIXME: Avoid creating duplicate methods */
3040 if (ins->flags & MONO_INST_HAS_METHOD) {
3044 if (cfg->compile_aot) {
3045 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3047 LLVM_FAILURE (ctx, "can't encode patch");
3049 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3051 * Collect instructions representing the callee into a hash so they can be replaced
3052 * by the llvm method for the callee if the callee turns out to be direct
3053 * callable. Currently this only requires it to not fail llvm compilation.
3055 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3056 l = g_slist_prepend (l, callee);
3057 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3060 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3063 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3065 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3069 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
3070 /* LLVM miscompiles async methods */
3071 LLVM_FAILURE (ctx, "#13734");
3074 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3080 memset (&ji, 0, sizeof (ji));
3081 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3082 ji.data.target = info->name;
3084 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3086 if (cfg->compile_aot) {
3087 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3089 LLVM_FAILURE (ctx, "can't encode patch");
3091 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3092 target = (gpointer)mono_icall_get_wrapper (info);
3093 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3096 if (cfg->compile_aot) {
3098 if (cfg->abs_patches) {
3099 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3101 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3103 LLVM_FAILURE (ctx, "can't encode patch");
3107 LLVM_FAILURE (ctx, "aot");
3109 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3111 if (cfg->abs_patches) {
3112 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3115 * FIXME: Some trampolines might have
3116 * their own calling convention on some platforms.
3118 #ifndef TARGET_AMD64
3119 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
3120 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
3121 LLVM_FAILURE (ctx, "trampoline with own cconv");
3123 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3124 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3128 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3134 int size = sizeof (gpointer);
3137 g_assert (ins->inst_offset % size == 0);
3138 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3140 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3142 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3144 if (ins->flags & MONO_INST_HAS_METHOD) {
3149 * Collect and convert arguments
3151 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3152 len = sizeof (LLVMValueRef) * nargs;
3153 args = (LLVMValueRef*)alloca (len);
3154 memset (args, 0, len);
3155 l = call->out_ireg_args;
3157 if (call->rgctx_arg_reg) {
3158 g_assert (values [call->rgctx_arg_reg]);
3159 g_assert (cinfo->rgctx_arg_pindex < nargs);
3161 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3162 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3163 * it using a volatile load.
3166 if (!ctx->imt_rgctx_loc)
3167 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3168 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3169 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3171 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3174 if (call->imt_arg_reg) {
3175 g_assert (!ctx->llvm_only);
3176 g_assert (values [call->imt_arg_reg]);
3177 g_assert (cinfo->imt_arg_pindex < nargs);
3179 if (!ctx->imt_rgctx_loc)
3180 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3181 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3182 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3184 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3187 switch (cinfo->ret.storage) {
3188 case LLVMArgGsharedvtVariable: {
3189 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3191 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3192 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3194 g_assert (addresses [call->inst.dreg]);
3195 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3201 if (!addresses [call->inst.dreg])
3202 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3203 g_assert (cinfo->vret_arg_pindex < nargs);
3204 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3205 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3207 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3212 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3215 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3217 pindex = ainfo->pindex;
3219 regpair = (guint32)(gssize)(l->data);
3220 reg = regpair & 0xffffff;
3221 args [pindex] = values [reg];
3222 switch (ainfo->storage) {
3223 case LLVMArgVtypeInReg:
3224 case LLVMArgAsFpArgs: {
3228 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3229 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3230 pindex += ainfo->ndummy_fpargs;
3232 g_assert (addresses [reg]);
3233 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3237 // FIXME: Get rid of the VMOVE
3240 case LLVMArgVtypeByVal:
3241 g_assert (addresses [reg]);
3242 args [pindex] = addresses [reg];
3244 case LLVMArgVtypeByRef:
3245 case LLVMArgScalarByRef: {
3246 g_assert (addresses [reg]);
3247 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3250 case LLVMArgAsIArgs:
3251 g_assert (addresses [reg]);
3252 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3254 case LLVMArgVtypeAsScalar:
3255 g_assert_not_reached ();
3257 case LLVMArgGsharedvtFixed:
3258 case LLVMArgGsharedvtFixedVtype:
3259 g_assert (addresses [reg]);
3260 args [pindex] = addresses [reg];
3262 case LLVMArgGsharedvtVariable:
3263 g_assert (addresses [reg]);
3264 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3267 g_assert (args [pindex]);
3268 if (i == 0 && sig->hasthis)
3269 args [pindex] = convert (ctx, args [pindex], ThisType ());
3271 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3274 g_assert (pindex <= nargs);
3279 // FIXME: Align call sites
3285 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3288 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3290 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3291 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3293 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3294 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3295 if (!sig->pinvoke && !cfg->llvm_only)
3296 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3298 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3299 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3300 if (!ctx->llvm_only && call->rgctx_arg_reg)
3301 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3302 if (call->imt_arg_reg)
3303 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3305 /* Add byval attributes if needed */
3306 for (i = 0; i < sig->param_count; ++i) {
3307 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3309 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3310 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3314 * Convert the result
3316 switch (cinfo->ret.storage) {
3317 case LLVMArgVtypeInReg: {
3318 LLVMValueRef regs [2];
3320 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3324 if (!addresses [ins->dreg])
3325 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3327 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3328 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3329 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3330 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3333 case LLVMArgVtypeByVal:
3334 if (!addresses [call->inst.dreg])
3335 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3336 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3338 case LLVMArgFpStruct:
3339 if (!addresses [call->inst.dreg])
3340 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3341 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3343 case LLVMArgVtypeAsScalar:
3344 if (!addresses [call->inst.dreg])
3345 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3346 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3348 case LLVMArgVtypeRetAddr:
3349 case LLVMArgVtypeByRef:
3351 case LLVMArgScalarRetAddr:
3352 /* Normal scalar returned using a vtype return argument */
3353 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3355 case LLVMArgGsharedvtVariable:
3357 case LLVMArgGsharedvtFixed:
3358 case LLVMArgGsharedvtFixedVtype:
3359 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3362 if (sig->ret->type != MONO_TYPE_VOID)
3363 /* If the method returns an unsigned value, need to zext it */
3364 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
3368 *builder_ref = ctx->builder;
3376 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3378 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3379 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3381 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3384 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3386 if (ctx->cfg->compile_aot) {
3387 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3389 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3390 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3391 mono_memory_barrier ();
3394 ctx->module->rethrow = callee;
3396 ctx->module->throw_icall = callee;
3400 LLVMValueRef args [2];
3402 args [0] = convert (ctx, exc, exc_type);
3403 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3405 LLVMBuildUnreachable (ctx->builder);
3407 ctx->builder = create_builder (ctx);
3411 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3413 MonoMethodSignature *throw_sig;
3414 LLVMValueRef callee, arg;
3415 const char *icall_name;
3417 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3418 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3421 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3422 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3423 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3424 if (ctx->cfg->compile_aot) {
3425 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3427 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3431 * LLVM doesn't push the exception argument, so we need a different
3434 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3436 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3440 mono_memory_barrier ();
3442 ctx->module->rethrow = callee;
3444 ctx->module->throw_icall = callee;
3446 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3447 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3451 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3453 const char *icall_name = "mono_llvm_resume_exception";
3454 LLVMValueRef callee = ctx->module->resume_eh;
3456 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3459 if (ctx->cfg->compile_aot) {
3460 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3462 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3463 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3464 mono_memory_barrier ();
3466 ctx->module->resume_eh = callee;
3470 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3472 LLVMBuildUnreachable (ctx->builder);
3474 ctx->builder = create_builder (ctx);
3478 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3480 const char *icall_name = "mono_llvm_clear_exception";
3482 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3483 LLVMValueRef callee = NULL;
3486 if (ctx->cfg->compile_aot) {
3487 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3489 // FIXME: This is broken.
3490 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3494 g_assert (builder && callee);
3496 return LLVMBuildCall (builder, callee, NULL, 0, "");
3500 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3502 const char *icall_name = "mono_llvm_load_exception";
3504 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3505 LLVMValueRef callee = NULL;
3508 if (ctx->cfg->compile_aot) {
3509 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3511 // FIXME: This is broken.
3512 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3516 g_assert (builder && callee);
3518 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3523 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3525 const char *icall_name = "mono_llvm_match_exception";
3527 ctx->builder = builder;
3529 const int num_args = 3;
3530 LLVMValueRef args [num_args];
3531 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3532 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3533 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3535 LLVMTypeRef match_sig = LLVMFunctionType3 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), FALSE);
3536 LLVMValueRef callee = ctx->module->match_exc;
3539 if (ctx->cfg->compile_aot) {
3540 ctx->builder = builder;
3541 // get_callee expects ctx->builder to be the emitting builder
3542 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3544 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3545 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3546 ctx->module->match_exc = callee;
3547 mono_memory_barrier ();
3551 g_assert (builder && callee);
3553 g_assert (ctx->ex_var);
3555 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3558 // FIXME: This won't work because the code-finding makes this
3560 /*#define MONO_PERSONALITY_DEBUG*/
3562 #ifdef MONO_PERSONALITY_DEBUG
3563 static const gboolean use_debug_personality = TRUE;
3564 static const char *default_personality_name = "mono_debug_personality";
3566 static const gboolean use_debug_personality = FALSE;
3567 static const char *default_personality_name = "__gxx_personality_v0";
3571 default_cpp_lpad_exc_signature (void)
3573 static gboolean inited = FALSE;
3574 static LLVMTypeRef sig;
3577 LLVMTypeRef signature [2];
3578 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3579 signature [1] = LLVMInt32Type ();
3580 sig = LLVMStructType (signature, 2, FALSE);
3588 get_mono_personality (EmitContext *ctx)
3590 LLVMValueRef personality = NULL;
3591 static gint32 mapping_inited = FALSE;
3592 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3594 if (!use_debug_personality) {
3595 if (ctx->cfg->compile_aot) {
3596 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3597 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3598 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3599 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3602 if (ctx->cfg->compile_aot) {
3603 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3605 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3606 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3607 mono_memory_barrier ();
3611 g_assert (personality);
3615 static LLVMBasicBlockRef
3616 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3618 MonoCompile *cfg = ctx->cfg;
3619 LLVMBuilderRef old_builder = ctx->builder;
3620 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3622 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3623 ctx->builder = lpadBuilder;
3625 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3626 g_assert (handler_bb);
3628 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3629 LLVMValueRef personality = get_mono_personality (ctx);
3630 g_assert (personality);
3632 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3633 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3635 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3636 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3637 g_assert (landing_pad);
3639 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3640 LLVMAddClause (landing_pad, cast);
3642 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3643 LLVMBuilderRef resume_builder = create_builder (ctx);
3644 ctx->builder = resume_builder;
3645 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3647 emit_resume_eh (ctx, handler_bb);
3650 ctx->builder = lpadBuilder;
3651 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3653 gboolean finally_only = TRUE;
3655 MonoExceptionClause *group_cursor = group_start;
3657 for (int i = 0; i < group_size; i ++) {
3658 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3659 finally_only = FALSE;
3665 // Handle landing pad inlining
3667 if (!finally_only) {
3668 // So at each level of the exception stack we will match the exception again.
3669 // During that match, we need to compare against the handler types for the current
3670 // protected region. We send the try start and end so that we can only check against
3671 // handlers for this lexical protected region.
3672 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3674 // if returns -1, resume
3675 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3677 // else move to that target bb
3678 for (int i=0; i < group_size; i++) {
3679 MonoExceptionClause *clause = group_start + i;
3680 int clause_index = clause - cfg->header->clauses;
3681 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3682 g_assert (handler_bb);
3683 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3684 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3687 int clause_index = group_start - cfg->header->clauses;
3688 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3689 g_assert (finally_bb);
3691 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3694 ctx->builder = old_builder;
3701 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3703 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3704 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3706 // Make exception available to catch blocks
3707 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3708 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3710 g_assert (ctx->ex_var);
3711 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3713 if (bb->in_scount == 1) {
3714 MonoInst *exvar = bb->in_stack [0];
3715 g_assert (!ctx->values [exvar->dreg]);
3716 g_assert (ctx->ex_var);
3717 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3718 emit_volatile_store (ctx, exvar->dreg);
3721 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3724 LLVMBuilderRef handler_builder = create_builder (ctx);
3725 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3726 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3728 // Make the handler code end with a jump to cbb
3729 LLVMBuildBr (handler_builder, cbb);
3733 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3735 MonoCompile *cfg = ctx->cfg;
3736 LLVMValueRef *values = ctx->values;
3737 LLVMModuleRef lmodule = ctx->lmodule;
3738 BBInfo *bblocks = ctx->bblocks;
3740 LLVMValueRef personality;
3741 LLVMValueRef landing_pad;
3742 LLVMBasicBlockRef target_bb;
3744 static gint32 mapping_inited;
3745 static int ti_generator;
3748 LLVMValueRef type_info;
3752 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3754 if (cfg->compile_aot) {
3755 /* Use a dummy personality function */
3756 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3757 g_assert (personality);
3759 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3760 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3761 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3764 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3766 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3769 * Create the type info
3771 sprintf (ti_name, "type_info_%d", ti_generator);
3774 if (cfg->compile_aot) {
3775 /* decode_eh_frame () in aot-runtime.c will decode this */
3776 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3777 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3780 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3782 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3785 * After the cfg mempool is freed, the type info will point to stale memory,
3786 * but this is not a problem, since we decode it once in exception_cb during
3789 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3790 *(gint32*)ti = clause_index;
3792 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3794 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3798 LLVMTypeRef members [2], ret_type;
3800 members [0] = i8ptr;
3801 members [1] = LLVMInt32Type ();
3802 ret_type = LLVMStructType (members, 2, FALSE);
3804 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3805 LLVMAddClause (landing_pad, type_info);
3807 /* Store the exception into the exvar */
3809 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3813 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3814 * code expects control to be transferred to this landing pad even in the
3815 * presence of nested clauses. The landing pad needs to branch to the landing
3816 * pads belonging to nested clauses based on the selector value returned by
3817 * the landing pad instruction, which is passed to the landing pad in a
3818 * register by the EH code.
3820 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3821 g_assert (target_bb);
3824 * Branch to the correct landing pad
3826 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3827 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3829 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3830 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3831 MonoBasicBlock *handler_bb;
3833 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3834 g_assert (handler_bb);
3836 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3837 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3840 /* Start a new bblock which CALL_HANDLER can branch to */
3841 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3843 ctx->builder = builder = create_builder (ctx);
3844 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3846 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3848 /* Store the exception into the IL level exvar */
3849 if (bb->in_scount == 1) {
3850 g_assert (bb->in_scount == 1);
3851 exvar = bb->in_stack [0];
3853 // FIXME: This is shared with filter clauses ?
3854 g_assert (!values [exvar->dreg]);
3856 g_assert (ctx->ex_var);
3857 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3858 emit_volatile_store (ctx, exvar->dreg);
3864 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3866 MonoCompile *cfg = ctx->cfg;
3867 MonoMethodSignature *sig = ctx->sig;
3868 LLVMValueRef method = ctx->lmethod;
3869 LLVMValueRef *values = ctx->values;
3870 LLVMValueRef *addresses = ctx->addresses;
3871 LLVMCallInfo *linfo = ctx->linfo;
3872 LLVMModuleRef lmodule = ctx->lmodule;
3873 BBInfo *bblocks = ctx->bblocks;
3875 LLVMBasicBlockRef cbb;
3876 LLVMBuilderRef builder, starting_builder;
3877 gboolean has_terminator;
3879 LLVMValueRef lhs, rhs;
3882 cbb = get_end_bb (ctx, bb);
3884 builder = create_builder (ctx);
3885 ctx->builder = builder;
3886 LLVMPositionBuilderAtEnd (builder, cbb);
3888 CHECK_FAILURE (ctx);
3890 if (bb->flags & BB_EXCEPTION_HANDLER) {
3891 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3892 LLVM_FAILURE (ctx, "handler without invokes");
3896 emit_llvmonly_handler_start (ctx, bb, cbb);
3898 emit_handler_start (ctx, bb, builder);
3899 CHECK_FAILURE (ctx);
3900 builder = ctx->builder;
3903 has_terminator = FALSE;
3904 starting_builder = builder;
3905 for (ins = bb->code; ins; ins = ins->next) {
3906 const char *spec = LLVM_INS_INFO (ins->opcode);
3908 char dname_buf [128];
3910 emit_dbg_loc (ctx, builder, ins->cil_code);
3913 if (nins > 3000 && builder == starting_builder) {
3914 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
3915 LLVM_FAILURE (ctx, "basic block too long");
3919 /* There could be instructions after a terminator, skip them */
3922 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
3923 sprintf (dname_buf, "t%d", ins->dreg);
3927 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
3928 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
3930 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
3931 lhs = emit_volatile_load (ctx, ins->sreg1);
3933 /* It is ok for SETRET to have an uninitialized argument */
3934 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
3935 LLVM_FAILURE (ctx, "sreg1");
3936 lhs = values [ins->sreg1];
3942 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
3943 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
3944 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
3945 rhs = emit_volatile_load (ctx, ins->sreg2);
3947 if (!values [ins->sreg2])
3948 LLVM_FAILURE (ctx, "sreg2");
3949 rhs = values [ins->sreg2];
3955 //mono_print_ins (ins);
3956 switch (ins->opcode) {
3959 case OP_LIVERANGE_START:
3960 case OP_LIVERANGE_END:
3963 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
3966 #if SIZEOF_VOID_P == 4
3967 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3969 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
3973 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
3977 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
3979 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
3981 case OP_DUMMY_ICONST:
3982 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3984 case OP_DUMMY_I8CONST:
3985 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
3987 case OP_DUMMY_R8CONST:
3988 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
3991 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
3992 LLVMBuildBr (builder, target_bb);
3993 has_terminator = TRUE;
4000 LLVMBasicBlockRef new_bb;
4001 LLVMBuilderRef new_builder;
4003 // The default branch is already handled
4004 // FIXME: Handle it here
4006 /* Start new bblock */
4007 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4008 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4010 lhs = convert (ctx, lhs, LLVMInt32Type ());
4011 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4012 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4013 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4015 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4018 new_builder = create_builder (ctx);
4019 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4020 LLVMBuildUnreachable (new_builder);
4022 has_terminator = TRUE;
4023 g_assert (!ins->next);
4029 switch (linfo->ret.storage) {
4030 case LLVMArgVtypeInReg: {
4031 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4032 LLVMValueRef val, addr, retval;
4035 retval = LLVMGetUndef (ret_type);
4037 if (!addresses [ins->sreg1]) {
4039 * The return type is an LLVM vector type, have to convert between it and the
4040 * real return type which is a struct type.
4042 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4043 /* Convert to 2xi64 first */
4044 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4046 for (i = 0; i < 2; ++i) {
4047 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4048 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4050 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4054 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4055 for (i = 0; i < 2; ++i) {
4056 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4057 LLVMValueRef indexes [2], part_addr;
4059 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4060 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4061 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4063 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4065 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4069 LLVMBuildRet (builder, retval);
4072 case LLVMArgVtypeAsScalar: {
4073 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4074 LLVMValueRef retval;
4077 size = get_vtype_size (sig->ret);
4079 g_assert (addresses [ins->sreg1]);
4081 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4082 LLVMBuildRet (builder, retval);
4085 case LLVMArgVtypeByVal: {
4086 LLVMValueRef retval;
4088 g_assert (addresses [ins->sreg1]);
4089 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4090 LLVMBuildRet (builder, retval);
4093 case LLVMArgVtypeByRef: {
4094 LLVMBuildRetVoid (builder);
4097 case LLVMArgGsharedvtFixed: {
4098 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4099 /* The return value is in lhs, need to store to the vret argument */
4100 /* sreg1 might not be set */
4102 g_assert (cfg->vret_addr);
4103 g_assert (values [cfg->vret_addr->dreg]);
4104 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4106 LLVMBuildRetVoid (builder);
4109 case LLVMArgGsharedvtFixedVtype: {
4111 LLVMBuildRetVoid (builder);
4114 case LLVMArgGsharedvtVariable: {
4116 LLVMBuildRetVoid (builder);
4119 case LLVMArgVtypeRetAddr: {
4120 LLVMBuildRetVoid (builder);
4123 case LLVMArgScalarRetAddr: {
4124 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4125 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4127 /* sreg1 might not be set */
4129 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4130 LLVMBuildRetVoid (builder);
4133 case LLVMArgFpStruct: {
4134 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4135 LLVMValueRef retval;
4137 g_assert (addresses [ins->sreg1]);
4138 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4139 LLVMBuildRet (builder, retval);
4143 case LLVMArgNormal: {
4144 if (!lhs || ctx->is_dead [ins->sreg1]) {
4146 * The method did not set its return value, probably because it
4147 * ends with a throw.
4150 LLVMBuildRetVoid (builder);
4152 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4154 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4156 has_terminator = TRUE;
4160 g_assert_not_reached ();
4169 case OP_ICOMPARE_IMM:
4170 case OP_LCOMPARE_IMM:
4171 case OP_COMPARE_IMM: {
4175 if (ins->next->opcode == OP_NOP)
4178 if (ins->next->opcode == OP_BR)
4179 /* The comparison result is not needed */
4182 rel = mono_opcode_to_cond (ins->next->opcode);
4184 if (ins->opcode == OP_ICOMPARE_IMM) {
4185 lhs = convert (ctx, lhs, LLVMInt32Type ());
4186 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4188 if (ins->opcode == OP_LCOMPARE_IMM) {
4189 lhs = convert (ctx, lhs, LLVMInt64Type ());
4190 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4192 if (ins->opcode == OP_LCOMPARE) {
4193 lhs = convert (ctx, lhs, LLVMInt64Type ());
4194 rhs = convert (ctx, rhs, LLVMInt64Type ());
4196 if (ins->opcode == OP_ICOMPARE) {
4197 lhs = convert (ctx, lhs, LLVMInt32Type ());
4198 rhs = convert (ctx, rhs, LLVMInt32Type ());
4202 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4203 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4204 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4205 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4208 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4209 if (ins->opcode == OP_FCOMPARE) {
4210 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4211 } else if (ins->opcode == OP_RCOMPARE) {
4212 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4213 } else if (ins->opcode == OP_COMPARE_IMM) {
4214 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4215 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4217 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4218 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4219 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4220 /* The immediate is encoded in two fields */
4221 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4222 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4224 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4227 else if (ins->opcode == OP_COMPARE) {
4228 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4229 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4231 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4233 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4235 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4236 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4238 * If the target bb contains PHI instructions, LLVM requires
4239 * two PHI entries for this bblock, while we only generate one.
4240 * So convert this to an unconditional bblock. (bxc #171).
4242 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4244 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4246 has_terminator = TRUE;
4247 } else if (MONO_IS_SETCC (ins->next)) {
4248 sprintf (dname_buf, "t%d", ins->next->dreg);
4250 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4252 /* Add stores for volatile variables */
4253 emit_volatile_store (ctx, ins->next->dreg);
4254 } else if (MONO_IS_COND_EXC (ins->next)) {
4255 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4256 CHECK_FAILURE (ctx);
4257 builder = ctx->builder;
4259 LLVM_FAILURE (ctx, "next");
4273 rel = mono_opcode_to_cond (ins->opcode);
4275 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4276 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4287 rel = mono_opcode_to_cond (ins->opcode);
4289 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4290 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4298 gboolean empty = TRUE;
4300 /* Check that all input bblocks really branch to us */
4301 for (i = 0; i < bb->in_count; ++i) {
4302 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4303 ins->inst_phi_args [i + 1] = -1;
4309 /* LLVM doesn't like phi instructions with zero operands */
4310 ctx->is_dead [ins->dreg] = TRUE;
4314 /* Created earlier, insert it now */
4315 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4317 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4318 int sreg1 = ins->inst_phi_args [i + 1];
4322 * Count the number of times the incoming bblock branches to us,
4323 * since llvm requires a separate entry for each.
4325 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4326 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4329 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4330 if (switch_ins->inst_many_bb [j] == bb)
4337 /* Remember for later */
4338 for (j = 0; j < count; ++j) {
4339 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4342 node->in_bb = bb->in_bb [i];
4344 bblocks [bb->in_bb [i]->block_num].phi_nodes = g_slist_prepend_mempool (ctx->mempool, bblocks [bb->in_bb [i]->block_num].phi_nodes, node);
4354 values [ins->dreg] = lhs;
4358 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4361 values [ins->dreg] = lhs;
4363 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4365 * This is added by the spilling pass in case of the JIT,
4366 * but we have to do it ourselves.
4368 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4372 case OP_MOVE_F_TO_I4: {
4373 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4376 case OP_MOVE_I4_TO_F: {
4377 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4380 case OP_MOVE_F_TO_I8: {
4381 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4384 case OP_MOVE_I8_TO_F: {
4385 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4418 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4419 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4421 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4422 CHECK_FAILURE (ctx);
4423 builder = ctx->builder;
4425 switch (ins->opcode) {
4428 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4432 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4436 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4440 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4444 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4448 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4452 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4456 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4460 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4464 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4468 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4472 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4476 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4480 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4484 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4487 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4490 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4494 g_assert_not_reached ();
4501 lhs = convert (ctx, lhs, LLVMFloatType ());
4502 rhs = convert (ctx, rhs, LLVMFloatType ());
4503 switch (ins->opcode) {
4505 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4508 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4511 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4514 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4517 g_assert_not_reached ();
4526 case OP_IREM_UN_IMM:
4528 case OP_IDIV_UN_IMM:
4534 case OP_ISHR_UN_IMM:
4544 case OP_LSHR_UN_IMM:
4550 case OP_SHR_UN_IMM: {
4553 if (spec [MONO_INST_SRC1] == 'l') {
4554 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4556 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4559 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4560 CHECK_FAILURE (ctx);
4561 builder = ctx->builder;
4563 #if SIZEOF_VOID_P == 4
4564 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4565 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4568 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4569 lhs = convert (ctx, lhs, IntPtrType ());
4570 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4571 switch (ins->opcode) {
4575 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4579 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4584 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4588 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4590 case OP_IDIV_UN_IMM:
4591 case OP_LDIV_UN_IMM:
4592 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4596 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4598 case OP_IREM_UN_IMM:
4599 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4604 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4608 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4612 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4617 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4622 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4624 case OP_ISHR_UN_IMM:
4625 /* This is used to implement conv.u4, so the lhs could be an i8 */
4626 lhs = convert (ctx, lhs, LLVMInt32Type ());
4627 imm = convert (ctx, imm, LLVMInt32Type ());
4628 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4630 case OP_LSHR_UN_IMM:
4632 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4635 g_assert_not_reached ();
4640 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4643 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4646 lhs = convert (ctx, lhs, LLVMDoubleType ());
4647 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4650 lhs = convert (ctx, lhs, LLVMFloatType ());
4651 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4654 guint32 v = 0xffffffff;
4655 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4659 guint64 v = 0xffffffffffffffffLL;
4660 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4663 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4665 LLVMValueRef v1, v2;
4667 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4668 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4669 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4674 case OP_ICONV_TO_I1:
4675 case OP_ICONV_TO_I2:
4676 case OP_ICONV_TO_I4:
4677 case OP_ICONV_TO_U1:
4678 case OP_ICONV_TO_U2:
4679 case OP_ICONV_TO_U4:
4680 case OP_LCONV_TO_I1:
4681 case OP_LCONV_TO_I2:
4682 case OP_LCONV_TO_U1:
4683 case OP_LCONV_TO_U2:
4684 case OP_LCONV_TO_U4: {
4687 sign = (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_ICONV_TO_I4) || (ins->opcode == OP_LCONV_TO_I1) || (ins->opcode == OP_LCONV_TO_I2);
4689 /* Have to do two casts since our vregs have type int */
4690 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4692 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4694 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4697 case OP_ICONV_TO_I8:
4698 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4700 case OP_ICONV_TO_U8:
4701 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4703 case OP_FCONV_TO_I4:
4704 case OP_RCONV_TO_I4:
4705 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4707 case OP_FCONV_TO_I1:
4708 case OP_RCONV_TO_I1:
4709 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4711 case OP_FCONV_TO_U1:
4712 case OP_RCONV_TO_U1:
4713 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4715 case OP_FCONV_TO_I2:
4716 case OP_RCONV_TO_I2:
4717 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4719 case OP_FCONV_TO_U2:
4720 case OP_RCONV_TO_U2:
4721 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4723 case OP_FCONV_TO_I8:
4724 case OP_RCONV_TO_I8:
4725 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4728 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4730 case OP_ICONV_TO_R8:
4731 case OP_LCONV_TO_R8:
4732 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4734 case OP_ICONV_TO_R_UN:
4735 case OP_LCONV_TO_R_UN:
4736 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4738 #if SIZEOF_VOID_P == 4
4741 case OP_LCONV_TO_I4:
4742 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4744 case OP_ICONV_TO_R4:
4745 case OP_LCONV_TO_R4:
4746 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4748 values [ins->dreg] = v;
4750 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4752 case OP_FCONV_TO_R4:
4753 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4755 values [ins->dreg] = v;
4757 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4759 case OP_RCONV_TO_R8:
4760 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4762 case OP_RCONV_TO_R4:
4763 values [ins->dreg] = lhs;
4766 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4769 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4772 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4774 case OP_LOCALLOC_IMM: {
4777 guint32 size = ins->inst_imm;
4778 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4780 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4782 if (ins->flags & MONO_INST_INIT) {
4783 LLVMValueRef args [5];
4786 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4787 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4788 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4789 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4790 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4793 values [ins->dreg] = v;
4797 LLVMValueRef v, size;
4799 size = LLVMBuildAnd (builder, LLVMBuildAdd (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT - 1, FALSE), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT - 1), FALSE), "");
4801 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4803 if (ins->flags & MONO_INST_INIT) {
4804 LLVMValueRef args [5];
4807 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4809 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4810 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4811 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4813 values [ins->dreg] = v;
4817 case OP_LOADI1_MEMBASE:
4818 case OP_LOADU1_MEMBASE:
4819 case OP_LOADI2_MEMBASE:
4820 case OP_LOADU2_MEMBASE:
4821 case OP_LOADI4_MEMBASE:
4822 case OP_LOADU4_MEMBASE:
4823 case OP_LOADI8_MEMBASE:
4824 case OP_LOADR4_MEMBASE:
4825 case OP_LOADR8_MEMBASE:
4826 case OP_LOAD_MEMBASE:
4834 LLVMValueRef base, index, addr;
4836 gboolean sext = FALSE, zext = FALSE;
4837 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4839 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4844 if ((ins->opcode == OP_LOADI8_MEM) || (ins->opcode == OP_LOAD_MEM) || (ins->opcode == OP_LOADI4_MEM) || (ins->opcode == OP_LOADU4_MEM) || (ins->opcode == OP_LOADU1_MEM) || (ins->opcode == OP_LOADU2_MEM)) {
4845 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4850 if (ins->inst_offset == 0) {
4852 } else if (ins->inst_offset % size != 0) {
4853 /* Unaligned load */
4854 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4855 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4857 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4858 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4862 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4864 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4866 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4868 * These will signal LLVM that these loads do not alias any stores, and
4869 * they can't fail, allowing them to be hoisted out of loops.
4871 set_invariant_load_flag (values [ins->dreg]);
4872 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4876 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4878 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4879 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4880 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4884 case OP_STOREI1_MEMBASE_REG:
4885 case OP_STOREI2_MEMBASE_REG:
4886 case OP_STOREI4_MEMBASE_REG:
4887 case OP_STOREI8_MEMBASE_REG:
4888 case OP_STORER4_MEMBASE_REG:
4889 case OP_STORER8_MEMBASE_REG:
4890 case OP_STORE_MEMBASE_REG: {
4892 LLVMValueRef index, addr;
4894 gboolean sext = FALSE, zext = FALSE;
4895 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4897 if (!values [ins->inst_destbasereg])
4898 LLVM_FAILURE (ctx, "inst_destbasereg");
4900 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4902 if (ins->inst_offset % size != 0) {
4903 /* Unaligned store */
4904 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4905 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4907 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4908 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4910 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4914 case OP_STOREI1_MEMBASE_IMM:
4915 case OP_STOREI2_MEMBASE_IMM:
4916 case OP_STOREI4_MEMBASE_IMM:
4917 case OP_STOREI8_MEMBASE_IMM:
4918 case OP_STORE_MEMBASE_IMM: {
4920 LLVMValueRef index, addr;
4922 gboolean sext = FALSE, zext = FALSE;
4923 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4925 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4927 if (ins->inst_offset % size != 0) {
4928 /* Unaligned store */
4929 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4930 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4932 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4933 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4935 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4940 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
4942 case OP_OUTARG_VTRETADDR:
4950 case OP_VOIDCALL_MEMBASE:
4951 case OP_CALL_MEMBASE:
4952 case OP_LCALL_MEMBASE:
4953 case OP_FCALL_MEMBASE:
4954 case OP_RCALL_MEMBASE:
4955 case OP_VCALL_MEMBASE:
4956 case OP_VOIDCALL_REG:
4961 case OP_VCALL_REG: {
4962 process_call (ctx, bb, &builder, ins);
4963 CHECK_FAILURE (ctx);
4968 LLVMValueRef indexes [2];
4969 MonoJumpInfo *tmp_ji, *ji;
4970 LLVMValueRef got_entry_addr;
4974 * FIXME: Can't allocate from the cfg mempool since that is freed if
4975 * the LLVM compile fails.
4977 tmp_ji = g_new0 (MonoJumpInfo, 1);
4978 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
4979 tmp_ji->data.target = ins->inst_p0;
4981 ji = mono_aot_patch_info_dup (tmp_ji);
4984 ji->next = cfg->patch_info;
4985 cfg->patch_info = ji;
4987 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
4988 got_offset = mono_aot_get_got_offset (cfg->patch_info);
4989 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
4990 if (!mono_aot_is_shared_got_offset (got_offset)) {
4991 //mono_print_ji (ji);
4993 ctx->has_got_access = TRUE;
4996 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4997 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
4998 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5000 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5001 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5003 set_invariant_load_flag (values [ins->dreg]);
5006 case OP_NOT_REACHED:
5007 LLVMBuildUnreachable (builder);
5008 has_terminator = TRUE;
5009 g_assert (bb->block_num < cfg->max_block_num);
5010 ctx->unreachable [bb->block_num] = TRUE;
5011 /* Might have instructions after this */
5013 MonoInst *next = ins->next;
5015 * FIXME: If later code uses the regs defined by these instructions,
5016 * compilation will fail.
5018 MONO_DELETE_INS (bb, next);
5022 MonoInst *var = ins->inst_i0;
5024 if (var->opcode == OP_VTARG_ADDR) {
5025 /* The variable contains the vtype address */
5026 values [ins->dreg] = values [var->dreg];
5027 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5028 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5030 values [ins->dreg] = addresses [var->dreg];
5035 LLVMValueRef args [1];
5037 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5038 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5042 LLVMValueRef args [1];
5044 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5045 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5049 LLVMValueRef args [1];
5052 /* This no longer seems to happen */
5054 * LLVM optimizes sqrt(nan) into undefined in
5055 * lib/Analysis/ConstantFolding.cpp
5056 * Also, sqrt(NegativeInfinity) is optimized into 0.
5058 LLVM_FAILURE (ctx, "sqrt");
5060 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5061 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5065 LLVMValueRef args [1];
5067 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5068 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5082 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5083 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5085 switch (ins->opcode) {
5088 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5092 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5096 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5100 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5103 g_assert_not_reached ();
5106 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5109 case OP_ATOMIC_EXCHANGE_I4:
5110 case OP_ATOMIC_EXCHANGE_I8: {
5111 LLVMValueRef args [2];
5114 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5115 t = LLVMInt32Type ();
5117 t = LLVMInt64Type ();
5119 g_assert (ins->inst_offset == 0);
5121 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5122 args [1] = convert (ctx, rhs, t);
5124 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5127 case OP_ATOMIC_ADD_I4:
5128 case OP_ATOMIC_ADD_I8: {
5129 LLVMValueRef args [2];
5132 if (ins->opcode == OP_ATOMIC_ADD_I4)
5133 t = LLVMInt32Type ();
5135 t = LLVMInt64Type ();
5137 g_assert (ins->inst_offset == 0);
5139 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5140 args [1] = convert (ctx, rhs, t);
5141 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5144 case OP_ATOMIC_CAS_I4:
5145 case OP_ATOMIC_CAS_I8: {
5146 LLVMValueRef args [3], val;
5149 if (ins->opcode == OP_ATOMIC_CAS_I4)
5150 t = LLVMInt32Type ();
5152 t = LLVMInt64Type ();
5154 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5156 args [1] = convert (ctx, values [ins->sreg3], t);
5158 args [2] = convert (ctx, values [ins->sreg2], t);
5159 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5160 /* cmpxchg returns a pair */
5161 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5164 case OP_MEMORY_BARRIER: {
5165 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5168 case OP_ATOMIC_LOAD_I1:
5169 case OP_ATOMIC_LOAD_I2:
5170 case OP_ATOMIC_LOAD_I4:
5171 case OP_ATOMIC_LOAD_I8:
5172 case OP_ATOMIC_LOAD_U1:
5173 case OP_ATOMIC_LOAD_U2:
5174 case OP_ATOMIC_LOAD_U4:
5175 case OP_ATOMIC_LOAD_U8:
5176 case OP_ATOMIC_LOAD_R4:
5177 case OP_ATOMIC_LOAD_R8: {
5178 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
5181 gboolean sext, zext;
5183 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5184 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5185 LLVMValueRef index, addr;
5187 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5192 if (ins->inst_offset != 0) {
5193 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5194 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5199 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5201 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5204 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5206 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5209 case OP_ATOMIC_STORE_I1:
5210 case OP_ATOMIC_STORE_I2:
5211 case OP_ATOMIC_STORE_I4:
5212 case OP_ATOMIC_STORE_I8:
5213 case OP_ATOMIC_STORE_U1:
5214 case OP_ATOMIC_STORE_U2:
5215 case OP_ATOMIC_STORE_U4:
5216 case OP_ATOMIC_STORE_U8:
5217 case OP_ATOMIC_STORE_R4:
5218 case OP_ATOMIC_STORE_R8: {
5219 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
5222 gboolean sext, zext;
5224 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5225 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5226 LLVMValueRef index, addr, value;
5228 if (!values [ins->inst_destbasereg])
5229 LLVM_FAILURE (ctx, "inst_destbasereg");
5231 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5233 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5234 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5235 value = convert (ctx, values [ins->sreg1], t);
5237 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5240 case OP_RELAXED_NOP: {
5241 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5242 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5249 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5251 // 257 == FS segment register
5252 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5254 // 256 == GS segment register
5255 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5258 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5259 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5260 /* See mono_amd64_emit_tls_get () */
5261 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5263 // 256 == GS segment register
5264 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5265 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5267 LLVM_FAILURE (ctx, "opcode tls-get");
5272 case OP_TLS_GET_REG: {
5273 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5274 /* See emit_tls_get_reg () */
5275 // 256 == GS segment register
5276 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5277 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5279 LLVM_FAILURE (ctx, "opcode tls-get");
5284 case OP_TLS_SET_REG: {
5285 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5286 /* See emit_tls_get_reg () */
5287 // 256 == GS segment register
5288 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5289 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5291 LLVM_FAILURE (ctx, "opcode tls-set-reg");
5300 case OP_IADD_OVF_UN:
5302 case OP_ISUB_OVF_UN:
5304 case OP_IMUL_OVF_UN:
5305 #if SIZEOF_VOID_P == 8
5307 case OP_LADD_OVF_UN:
5309 case OP_LSUB_OVF_UN:
5311 case OP_LMUL_OVF_UN:
5314 LLVMValueRef args [2], val, ovf, func;
5316 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5317 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5318 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5320 val = LLVMBuildCall (builder, func, args, 2, "");
5321 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5322 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5323 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5324 CHECK_FAILURE (ctx);
5325 builder = ctx->builder;
5331 * We currently model them using arrays. Promotion to local vregs is
5332 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5333 * so we always have an entry in cfg->varinfo for them.
5334 * FIXME: Is this needed ?
5337 MonoClass *klass = ins->klass;
5338 LLVMValueRef args [5];
5342 LLVM_FAILURE (ctx, "!klass");
5346 if (!addresses [ins->dreg])
5347 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5348 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5349 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5350 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5352 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5353 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5354 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5357 case OP_DUMMY_VZERO:
5360 case OP_STOREV_MEMBASE:
5361 case OP_LOADV_MEMBASE:
5363 MonoClass *klass = ins->klass;
5364 LLVMValueRef src = NULL, dst, args [5];
5365 gboolean done = FALSE;
5369 LLVM_FAILURE (ctx, "!klass");
5373 if (mini_is_gsharedvt_klass (klass)) {
5375 LLVM_FAILURE (ctx, "gsharedvt");
5379 switch (ins->opcode) {
5380 case OP_STOREV_MEMBASE:
5381 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5382 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5383 /* Decomposed earlier */
5384 g_assert_not_reached ();
5387 if (!addresses [ins->sreg1]) {
5389 g_assert (values [ins->sreg1]);
5390 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (type_to_llvm_type (ctx, &klass->byval_arg), 0));
5391 LLVMBuildStore (builder, values [ins->sreg1], dst);
5394 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5395 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5398 case OP_LOADV_MEMBASE:
5399 if (!addresses [ins->dreg])
5400 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5401 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5402 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5405 if (!addresses [ins->sreg1])
5406 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5407 if (!addresses [ins->dreg])
5408 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5409 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5410 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5413 g_assert_not_reached ();
5415 CHECK_FAILURE (ctx);
5422 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5423 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5425 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5426 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5427 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5430 case OP_LLVM_OUTARG_VT: {
5431 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5432 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5434 if (ainfo->storage == LLVMArgScalarByRef) {
5435 LLVMTypeRef argtype;
5436 LLVMValueRef loc, v;
5438 argtype = type_to_llvm_arg_type (ctx, t);
5439 loc = build_alloca_llvm_type (ctx, argtype, 0);
5440 v = convert (ctx, values [ins->sreg1], argtype);
5441 LLVMBuildStore (ctx->builder, v, loc);
5442 addresses [ins->dreg] = loc;
5443 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5444 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5446 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5447 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5449 g_assert (addresses [ins->sreg1]);
5450 addresses [ins->dreg] = addresses [ins->sreg1];
5453 if (!addresses [ins->sreg1]) {
5454 addresses [ins->sreg1] = build_alloca (ctx, t);
5455 g_assert (values [ins->sreg1]);
5456 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5458 addresses [ins->dreg] = addresses [ins->sreg1];
5466 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5468 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5471 case OP_LOADX_MEMBASE: {
5472 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5475 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5476 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5479 case OP_STOREX_MEMBASE: {
5480 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5483 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5484 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5491 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5495 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5501 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5505 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5509 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5513 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5516 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5519 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5522 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5526 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5537 LLVMValueRef v = NULL;
5539 switch (ins->opcode) {
5544 t = LLVMVectorType (LLVMInt32Type (), 4);
5545 rt = LLVMVectorType (LLVMFloatType (), 4);
5551 t = LLVMVectorType (LLVMInt64Type (), 2);
5552 rt = LLVMVectorType (LLVMDoubleType (), 2);
5555 t = LLVMInt32Type ();
5556 rt = LLVMInt32Type ();
5557 g_assert_not_reached ();
5560 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5561 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5562 switch (ins->opcode) {
5565 v = LLVMBuildAnd (builder, lhs, rhs, "");
5569 v = LLVMBuildOr (builder, lhs, rhs, "");
5573 v = LLVMBuildXor (builder, lhs, rhs, "");
5577 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5580 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5604 case OP_PADDB_SAT_UN:
5605 case OP_PADDW_SAT_UN:
5606 case OP_PSUBB_SAT_UN:
5607 case OP_PSUBW_SAT_UN:
5615 case OP_PMULW_HIGH_UN: {
5616 LLVMValueRef args [2];
5621 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5628 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5632 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5640 case OP_EXTRACTX_U2:
5642 case OP_EXTRACT_U1: {
5644 gboolean zext = FALSE;
5646 t = simd_op_to_llvm_type (ins->opcode);
5648 switch (ins->opcode) {
5656 case OP_EXTRACTX_U2:
5661 t = LLVMInt32Type ();
5662 g_assert_not_reached ();
5665 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5666 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5668 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5677 case OP_EXPAND_R8: {
5678 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5679 LLVMValueRef mask [16], v;
5682 for (i = 0; i < 16; ++i)
5683 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5685 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5687 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5688 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5693 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5696 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5699 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5702 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5705 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5708 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5719 case OP_EXTRACT_MASK:
5726 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5728 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5734 LLVMValueRef args [3];
5738 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5740 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5745 /* This is only used for implementing shifts by non-immediate */
5746 values [ins->dreg] = lhs;
5757 LLVMValueRef args [3];
5760 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5762 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5773 case OP_PSHLQ_REG: {
5774 LLVMValueRef args [3];
5777 args [1] = values [ins->sreg2];
5779 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5786 case OP_PSHUFLEW_LOW:
5787 case OP_PSHUFLEW_HIGH: {
5789 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5790 int i, mask_size = 0;
5791 int imask = ins->inst_c0;
5793 /* Convert the x86 shuffle mask to LLVM's */
5794 switch (ins->opcode) {
5797 mask [0] = ((imask >> 0) & 3);
5798 mask [1] = ((imask >> 2) & 3);
5799 mask [2] = ((imask >> 4) & 3) + 4;
5800 mask [3] = ((imask >> 6) & 3) + 4;
5801 v1 = values [ins->sreg1];
5802 v2 = values [ins->sreg2];
5806 mask [0] = ((imask >> 0) & 1);
5807 mask [1] = ((imask >> 1) & 1) + 2;
5808 v1 = values [ins->sreg1];
5809 v2 = values [ins->sreg2];
5811 case OP_PSHUFLEW_LOW:
5813 mask [0] = ((imask >> 0) & 3);
5814 mask [1] = ((imask >> 2) & 3);
5815 mask [2] = ((imask >> 4) & 3);
5816 mask [3] = ((imask >> 6) & 3);
5821 v1 = values [ins->sreg1];
5822 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5824 case OP_PSHUFLEW_HIGH:
5830 mask [4] = 4 + ((imask >> 0) & 3);
5831 mask [5] = 4 + ((imask >> 2) & 3);
5832 mask [6] = 4 + ((imask >> 4) & 3);
5833 mask [7] = 4 + ((imask >> 6) & 3);
5834 v1 = values [ins->sreg1];
5835 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5839 mask [0] = ((imask >> 0) & 3);
5840 mask [1] = ((imask >> 2) & 3);
5841 mask [2] = ((imask >> 4) & 3);
5842 mask [3] = ((imask >> 6) & 3);
5843 v1 = values [ins->sreg1];
5844 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5847 g_assert_not_reached ();
5849 for (i = 0; i < mask_size; ++i)
5850 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5852 values [ins->dreg] =
5853 LLVMBuildShuffleVector (builder, v1, v2,
5854 LLVMConstVector (mask_values, mask_size), dname);
5858 case OP_UNPACK_LOWB:
5859 case OP_UNPACK_LOWW:
5860 case OP_UNPACK_LOWD:
5861 case OP_UNPACK_LOWQ:
5862 case OP_UNPACK_LOWPS:
5863 case OP_UNPACK_LOWPD:
5864 case OP_UNPACK_HIGHB:
5865 case OP_UNPACK_HIGHW:
5866 case OP_UNPACK_HIGHD:
5867 case OP_UNPACK_HIGHQ:
5868 case OP_UNPACK_HIGHPS:
5869 case OP_UNPACK_HIGHPD: {
5871 LLVMValueRef mask_values [16];
5872 int i, mask_size = 0;
5873 gboolean low = FALSE;
5875 switch (ins->opcode) {
5876 case OP_UNPACK_LOWB:
5880 case OP_UNPACK_LOWW:
5884 case OP_UNPACK_LOWD:
5885 case OP_UNPACK_LOWPS:
5889 case OP_UNPACK_LOWQ:
5890 case OP_UNPACK_LOWPD:
5894 case OP_UNPACK_HIGHB:
5897 case OP_UNPACK_HIGHW:
5900 case OP_UNPACK_HIGHD:
5901 case OP_UNPACK_HIGHPS:
5904 case OP_UNPACK_HIGHQ:
5905 case OP_UNPACK_HIGHPD:
5909 g_assert_not_reached ();
5913 for (i = 0; i < (mask_size / 2); ++i) {
5915 mask [(i * 2) + 1] = mask_size + i;
5918 for (i = 0; i < (mask_size / 2); ++i) {
5919 mask [(i * 2)] = (mask_size / 2) + i;
5920 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
5924 for (i = 0; i < mask_size; ++i)
5925 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5927 values [ins->dreg] =
5928 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
5929 LLVMConstVector (mask_values, mask_size), dname);
5934 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5935 LLVMValueRef v, val;
5937 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5938 val = LLVMConstNull (t);
5939 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5940 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
5942 values [ins->dreg] = val;
5946 case OP_DUPPS_HIGH: {
5947 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5948 LLVMValueRef v1, v2, val;
5951 if (ins->opcode == OP_DUPPS_LOW) {
5952 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5953 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5955 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5956 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5958 val = LLVMConstNull (t);
5959 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5960 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5961 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5962 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5964 values [ins->dreg] = val;
5974 * EXCEPTION HANDLING
5976 case OP_IMPLICIT_EXCEPTION:
5977 /* This marks a place where an implicit exception can happen */
5978 if (bb->region != -1)
5979 LLVM_FAILURE (ctx, "implicit-exception");
5983 gboolean rethrow = (ins->opcode == OP_RETHROW);
5984 if (ctx->llvm_only) {
5985 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
5986 has_terminator = TRUE;
5987 ctx->unreachable [bb->block_num] = TRUE;
5989 emit_throw (ctx, bb, rethrow, lhs);
5990 builder = ctx->builder;
5994 case OP_CALL_HANDLER: {
5996 * We don't 'call' handlers, but instead simply branch to them.
5997 * The code generated by ENDFINALLY will branch back to us.
5999 LLVMBasicBlockRef noex_bb;
6001 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6003 bb_list = info->call_handler_return_bbs;
6006 * Set the indicator variable for the finally clause.
6008 lhs = info->finally_ind;
6010 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6012 /* Branch to the finally clause */
6013 LLVMBuildBr (builder, info->call_handler_target_bb);
6015 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6016 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6018 builder = ctx->builder = create_builder (ctx);
6019 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6021 bblocks [bb->block_num].end_bblock = noex_bb;
6024 case OP_START_HANDLER: {
6027 case OP_ENDFINALLY: {
6028 LLVMBasicBlockRef resume_bb;
6029 MonoBasicBlock *handler_bb;
6030 LLVMValueRef val, switch_ins, callee;
6034 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6035 g_assert (handler_bb);
6036 info = &bblocks [handler_bb->block_num];
6037 lhs = info->finally_ind;
6040 bb_list = info->call_handler_return_bbs;
6042 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6044 /* Load the finally variable */
6045 val = LLVMBuildLoad (builder, lhs, "");
6047 /* Reset the variable */
6048 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6050 /* Branch to either resume_bb, or to the bblocks in bb_list */
6051 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6053 * The other targets are added at the end to handle OP_CALL_HANDLER
6054 * opcodes processed later.
6056 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6058 builder = ctx->builder = create_builder (ctx);
6059 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6061 if (ctx->llvm_only) {
6062 emit_resume_eh (ctx, bb);
6064 if (ctx->cfg->compile_aot) {
6065 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6067 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6069 LLVMBuildCall (builder, callee, NULL, 0, "");
6070 LLVMBuildUnreachable (builder);
6073 has_terminator = TRUE;
6079 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6080 LLVM_FAILURE (ctx, reason);
6085 /* Convert the value to the type required by phi nodes */
6086 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6087 if (!values [ins->dreg])
6089 values [ins->dreg] = addresses [ins->dreg];
6091 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6094 /* Add stores for volatile variables */
6095 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6096 emit_volatile_store (ctx, ins->dreg);
6099 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6100 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6103 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6104 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6105 LLVMBuildRetVoid (builder);
6108 if (bb == cfg->bb_entry)
6109 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6118 * mono_llvm_check_method_supported:
6120 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6121 * compiling a method twice.
6124 mono_llvm_check_method_supported (MonoCompile *cfg)
6131 if (cfg->method->save_lmf) {
6132 cfg->exception_message = g_strdup ("lmf");
6133 cfg->disable_llvm = TRUE;
6135 if (cfg->disable_llvm)
6139 * Nested clauses where one of the clauses is a finally clause is
6140 * not supported, because LLVM can't figure out the control flow,
6141 * probably because we resume exception handling by calling our
6142 * own function instead of using the 'resume' llvm instruction.
6144 for (i = 0; i < cfg->header->num_clauses; ++i) {
6145 for (j = 0; j < cfg->header->num_clauses; ++j) {
6146 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6147 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6149 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6150 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6151 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6152 cfg->exception_message = g_strdup ("nested clauses");
6153 cfg->disable_llvm = TRUE;
6158 if (cfg->disable_llvm)
6162 if (cfg->method->dynamic) {
6163 cfg->exception_message = g_strdup ("dynamic.");
6164 cfg->disable_llvm = TRUE;
6166 if (cfg->disable_llvm)
6170 static LLVMCallInfo*
6171 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6173 LLVMCallInfo *linfo;
6176 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6180 * Gsharedvt methods have the following calling convention:
6181 * - all arguments are passed by ref, even non generic ones
6182 * - the return value is returned by ref too, using a vret
6183 * argument passed after 'this'.
6185 n = sig->param_count + sig->hasthis;
6186 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6190 linfo->args [pindex ++].storage = LLVMArgNormal;
6192 if (sig->ret->type != MONO_TYPE_VOID) {
6193 if (mini_is_gsharedvt_variable_type (sig->ret))
6194 linfo->ret.storage = LLVMArgGsharedvtVariable;
6195 else if (mini_type_is_vtype (sig->ret))
6196 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6198 linfo->ret.storage = LLVMArgGsharedvtFixed;
6199 linfo->vret_arg_index = pindex;
6201 linfo->ret.storage = LLVMArgNone;
6204 for (i = 0; i < sig->param_count; ++i) {
6205 if (sig->params [i]->byref)
6206 linfo->args [pindex].storage = LLVMArgNormal;
6207 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6208 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6209 else if (mini_type_is_vtype (sig->params [i]))
6210 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6212 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6213 linfo->args [pindex].type = sig->params [i];
6220 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6221 for (i = 0; i < sig->param_count; ++i)
6222 linfo->args [i + sig->hasthis].type = sig->params [i];
6228 * mono_llvm_emit_method:
6230 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6233 mono_llvm_emit_method (MonoCompile *cfg)
6236 MonoMethodSignature *sig;
6238 LLVMTypeRef method_type;
6239 LLVMValueRef method = NULL;
6241 LLVMValueRef *values;
6242 int i, max_block_num, bb_index;
6243 gboolean last = FALSE;
6244 GPtrArray *phi_values;
6245 LLVMCallInfo *linfo;
6247 LLVMModuleRef lmodule;
6249 GPtrArray *bblock_list;
6250 MonoMethodHeader *header;
6251 MonoExceptionClause *clause;
6254 /* The code below might acquire the loader lock, so use it for global locking */
6255 mono_loader_lock ();
6257 /* Used to communicate with the callbacks */
6258 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6260 ctx = g_new0 (EmitContext, 1);
6262 ctx->mempool = cfg->mempool;
6265 * This maps vregs to the LLVM instruction defining them
6267 values = g_new0 (LLVMValueRef, cfg->next_vreg);
6269 * This maps vregs for volatile variables to the LLVM instruction defining their
6272 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6273 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6274 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6275 phi_values = g_ptr_array_sized_new (256);
6277 * This signals whenever the vreg was defined by a phi node with no input vars
6278 * (i.e. all its input bblocks end with NOT_REACHABLE).
6280 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6281 /* Whenever the bblock is unreachable */
6282 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6283 bblock_list = g_ptr_array_sized_new (256);
6285 ctx->values = values;
6286 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6287 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6288 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6290 if (cfg->compile_aot) {
6291 ctx->module = &aot_module;
6292 method_name = mono_aot_get_method_name (cfg);
6293 cfg->llvm_method_name = g_strdup (method_name);
6295 init_jit_module (cfg->domain);
6296 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6297 method_name = mono_method_full_name (cfg->method, TRUE);
6300 lmodule = ctx->lmodule = ctx->module->lmodule;
6301 ctx->llvm_only = ctx->module->llvm_only;
6303 if (cfg->gsharedvt && !cfg->llvm_only)
6304 LLVM_FAILURE (ctx, "gsharedvt");
6308 static int count = 0;
6311 if (g_getenv ("LLVM_COUNT")) {
6312 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6313 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6317 if (count > atoi (g_getenv ("LLVM_COUNT")))
6318 LLVM_FAILURE (ctx, "");
6323 sig = mono_method_signature (cfg->method);
6326 linfo = get_llvm_call_info (cfg, sig);
6328 CHECK_FAILURE (ctx);
6331 linfo->rgctx_arg = TRUE;
6332 method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6333 CHECK_FAILURE (ctx);
6335 method = LLVMAddFunction (lmodule, method_name, method_type);
6336 ctx->lmethod = method;
6338 if (!cfg->llvm_only)
6339 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6340 LLVMSetLinkage (method, LLVMPrivateLinkage);
6342 LLVMAddFunctionAttr (method, LLVMUWTable);
6344 if (cfg->compile_aot) {
6345 LLVMSetLinkage (method, LLVMInternalLinkage);
6346 if (ctx->module->external_symbols) {
6347 LLVMSetLinkage (method, LLVMExternalLinkage);
6348 LLVMSetVisibility (method, LLVMHiddenVisibility);
6351 LLVMSetLinkage (method, LLVMPrivateLinkage);
6354 if (cfg->method->save_lmf && !cfg->llvm_only)
6355 LLVM_FAILURE (ctx, "lmf");
6357 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only)
6358 LLVM_FAILURE (ctx, "pinvoke signature");
6360 header = cfg->header;
6361 for (i = 0; i < header->num_clauses; ++i) {
6362 clause = &header->clauses [i];
6363 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
6364 LLVM_FAILURE (ctx, "non-finally/catch clause.");
6366 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
6367 /* We can't handle inlined methods with clauses */
6368 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6370 if (linfo->rgctx_arg) {
6371 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6372 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6374 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6375 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6376 * CC_X86_64_Mono in X86CallingConv.td.
6378 if (!ctx->llvm_only)
6379 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6380 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6382 ctx->rgctx_arg_pindex = -1;
6384 if (cfg->vret_addr) {
6385 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6386 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6387 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6388 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6389 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6391 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6392 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6393 LLVMSetValueName (param, "vret");
6397 ctx->this_arg_pindex = linfo->this_arg_pindex;
6398 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6399 values [cfg->args [0]->dreg] = ctx->this_arg;
6400 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6403 names = g_new (char *, sig->param_count);
6404 mono_method_get_param_names (cfg->method, (const char **) names);
6406 for (i = 0; i < sig->param_count; ++i) {
6407 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6409 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6412 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6413 name = g_strdup_printf ("dummy_%d_%d", i, j);
6414 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6418 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6419 if (ainfo->storage == LLVMArgScalarByRef) {
6420 if (names [i] && names [i][0] != '\0')
6421 name = g_strdup_printf ("p_arg_%s", names [i]);
6423 name = g_strdup_printf ("p_arg_%d", i);
6424 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6425 if (names [i] && names [i][0] != '\0')
6426 name = g_strdup_printf ("p_arg_%s", names [i]);
6428 name = g_strdup_printf ("p_arg_%d", i);
6430 if (names [i] && names [i][0] != '\0')
6431 name = g_strdup_printf ("arg_%s", names [i]);
6433 name = g_strdup_printf ("arg_%d", i);
6435 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6437 if (ainfo->storage == LLVMArgVtypeByVal)
6438 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6440 if (ainfo->storage == LLVMArgVtypeByRef) {
6442 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6447 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6448 ctx->minfo = mono_debug_lookup_method (cfg->method);
6449 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
6453 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6454 max_block_num = MAX (max_block_num, bb->block_num);
6455 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6457 /* Add branches between non-consecutive bblocks */
6458 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6459 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6460 bb->next_bb != bb->last_ins->inst_false_bb) {
6462 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6463 inst->opcode = OP_BR;
6464 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6465 mono_bblock_add_inst (bb, inst);
6470 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6471 * was later optimized away, so clear these flags, and add them back for the still
6472 * present OP_LDADDR instructions.
6474 for (i = 0; i < cfg->next_vreg; ++i) {
6477 ins = get_vreg_to_inst (cfg, i);
6478 if (ins && ins != cfg->rgctx_var)
6479 ins->flags &= ~MONO_INST_INDIRECT;
6483 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6485 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6487 LLVMBuilderRef builder;
6489 char dname_buf[128];
6491 builder = create_builder (ctx);
6493 for (ins = bb->code; ins; ins = ins->next) {
6494 switch (ins->opcode) {
6499 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6501 CHECK_FAILURE (ctx);
6503 if (ins->opcode == OP_VPHI) {
6504 /* Treat valuetype PHI nodes as operating on the address itself */
6505 g_assert (ins->klass);
6506 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6510 * Have to precreate these, as they can be referenced by
6511 * earlier instructions.
6513 sprintf (dname_buf, "t%d", ins->dreg);
6515 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6517 if (ins->opcode == OP_VPHI)
6518 ctx->addresses [ins->dreg] = values [ins->dreg];
6520 g_ptr_array_add (phi_values, values [ins->dreg]);
6523 * Set the expected type of the incoming arguments since these have
6524 * to have the same type.
6526 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6527 int sreg1 = ins->inst_phi_args [i + 1];
6530 ctx->vreg_types [sreg1] = phi_type;
6535 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6544 * Create an ordering for bblocks, use the depth first order first, then
6545 * put the exception handling bblocks last.
6547 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6548 bb = cfg->bblocks [bb_index];
6549 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6550 g_ptr_array_add (bblock_list, bb);
6551 bblocks [bb->block_num].added = TRUE;
6555 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6556 if (!bblocks [bb->block_num].added)
6557 g_ptr_array_add (bblock_list, bb);
6561 * Second pass: generate code.
6564 LLVMBuilderRef entry_builder = create_builder (ctx);
6565 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6566 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6567 emit_entry_bb (ctx, entry_builder);
6569 // Make landing pads first
6570 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6572 if (ctx->llvm_only) {
6573 size_t group_index = 0;
6574 while (group_index < cfg->header->num_clauses) {
6576 size_t cursor = group_index;
6577 while (cursor < cfg->header->num_clauses &&
6578 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6579 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6584 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6585 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6586 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6588 group_index = cursor;
6592 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6593 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6595 // Prune unreachable mono BBs.
6596 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6599 process_bb (ctx, bb);
6600 CHECK_FAILURE (ctx);
6602 g_hash_table_destroy (ctx->exc_meta);
6604 mono_memory_barrier ();
6606 /* Add incoming phi values */
6607 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6608 GSList *l, *ins_list;
6610 ins_list = bblocks [bb->block_num].phi_nodes;
6612 for (l = ins_list; l; l = l->next) {
6613 PhiNode *node = (PhiNode*)l->data;
6614 MonoInst *phi = node->phi;
6615 int sreg1 = node->sreg;
6616 LLVMBasicBlockRef in_bb;
6621 in_bb = get_end_bb (ctx, node->in_bb);
6623 if (ctx->unreachable [node->in_bb->block_num])
6626 if (!values [sreg1])
6627 /* Can happen with values in EH clauses */
6628 LLVM_FAILURE (ctx, "incoming phi sreg1");
6630 if (phi->opcode == OP_VPHI) {
6631 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6632 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6634 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
6636 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
6637 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6638 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6643 /* Nullify empty phi instructions */
6644 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6645 GSList *l, *ins_list;
6647 ins_list = bblocks [bb->block_num].phi_nodes;
6649 for (l = ins_list; l; l = l->next) {
6650 PhiNode *node = (PhiNode*)l->data;
6651 MonoInst *phi = node->phi;
6652 LLVMValueRef phi_ins = values [phi->dreg];
6655 /* Already removed */
6658 if (LLVMCountIncoming (phi_ins) == 0) {
6659 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6660 LLVMInstructionEraseFromParent (phi_ins);
6661 values [phi->dreg] = NULL;
6666 /* Create the SWITCH statements for ENDFINALLY instructions */
6667 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6668 BBInfo *info = &bblocks [bb->block_num];
6670 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6671 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6672 GSList *bb_list = info->call_handler_return_bbs;
6674 for (i = 0; i < g_slist_length (bb_list); ++i)
6675 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6679 /* Initialize the method if needed */
6680 if (cfg->compile_aot && ctx->llvm_only) {
6681 // FIXME: Add more shared got entries
6682 ctx->builder = create_builder (ctx);
6683 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6685 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6687 // FIXME: beforefieldinit
6688 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6689 emit_init_method (ctx);
6691 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6695 if (cfg->llvm_only) {
6696 GHashTableIter iter;
6698 GSList *callers, *l, *l2;
6701 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6702 * We can't do this earlier, as it contains llvm instructions which can be
6703 * freed if compilation fails.
6704 * FIXME: Get rid of this when all methods can be llvm compiled.
6706 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6707 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6708 for (l = callers; l; l = l->next) {
6709 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6710 l2 = g_slist_prepend (l2, l->data);
6711 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6716 if (cfg->verbose_level > 1)
6717 mono_llvm_dump_value (method);
6719 if (cfg->compile_aot && !cfg->llvm_only)
6720 mark_as_used (ctx->module, method);
6722 if (cfg->compile_aot) {
6723 LLVMValueRef md_args [16];
6724 LLVMValueRef md_node;
6727 method_index = mono_aot_get_method_index (cfg->orig_method);
6728 md_args [0] = LLVMMDString (method_name, strlen (method_name));
6729 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6730 md_node = LLVMMDNode (md_args, 2);
6731 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6732 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6735 if (cfg->compile_aot) {
6736 /* Don't generate native code, keep the LLVM IR */
6737 if (cfg->verbose_level)
6738 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
6740 int err = LLVMVerifyFunction(method, LLVMPrintMessageAction);
6741 g_assert (err == 0);
6743 //LLVMVerifyFunction(method, 0);
6744 mono_llvm_optimize_method (ctx->module->mono_ee, method);
6746 if (cfg->verbose_level > 1)
6747 mono_llvm_dump_value (method);
6749 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, method);
6751 /* Set by emit_cb */
6752 g_assert (cfg->code_len);
6754 /* FIXME: Free the LLVM IL for the function */
6757 if (ctx->module->method_to_lmethod)
6758 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, method);
6759 if (ctx->module->idx_to_lmethod)
6760 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), method);
6762 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6763 emit_unbox_tramp (ctx, method_name, method_type, method, cfg->method_index);
6770 /* Need to add unused phi nodes as they can be referenced by other values */
6771 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
6772 LLVMBuilderRef builder;
6774 builder = create_builder (ctx);
6775 LLVMPositionBuilderAtEnd (builder, phi_bb);
6777 for (i = 0; i < phi_values->len; ++i) {
6778 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (phi_values, i);
6779 if (LLVMGetInstructionParent (v) == NULL)
6780 LLVMInsertIntoBuilder (builder, v);
6783 LLVMDeleteFunction (method);
6788 g_free (ctx->addresses);
6789 g_free (ctx->vreg_types);
6790 g_free (ctx->vreg_cli_types);
6791 g_free (ctx->is_dead);
6792 g_free (ctx->unreachable);
6793 g_ptr_array_free (phi_values, TRUE);
6794 g_free (ctx->bblocks);
6795 g_hash_table_destroy (ctx->region_to_handler);
6796 g_hash_table_destroy (ctx->clause_to_handler);
6797 g_free (method_name);
6798 g_ptr_array_free (bblock_list, TRUE);
6800 for (l = ctx->builders; l; l = l->next) {
6801 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6802 LLVMDisposeBuilder (builder);
6807 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6809 mono_loader_unlock ();
6813 * mono_llvm_create_vars:
6815 * Same as mono_arch_create_vars () for LLVM.
6818 mono_llvm_create_vars (MonoCompile *cfg)
6820 MonoMethodSignature *sig;
6822 sig = mono_method_signature (cfg->method);
6823 if (cfg->gsharedvt && cfg->llvm_only) {
6824 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
6825 cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
6826 if (G_UNLIKELY (cfg->verbose_level > 1)) {
6827 printf ("vret_addr = ");
6828 mono_print_ins (cfg->vret_addr);
6832 mono_arch_create_vars (cfg);
6837 * mono_llvm_emit_call:
6839 * Same as mono_arch_emit_call () for LLVM.
6842 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
6845 MonoMethodSignature *sig;
6846 int i, n, stack_size;
6851 sig = call->signature;
6852 n = sig->param_count + sig->hasthis;
6854 call->cinfo = get_llvm_call_info (cfg, sig);
6856 if (cfg->disable_llvm)
6859 if (sig->call_convention == MONO_CALL_VARARG) {
6860 cfg->exception_message = g_strdup ("varargs");
6861 cfg->disable_llvm = TRUE;
6864 for (i = 0; i < n; ++i) {
6867 ainfo = call->cinfo->args + i;
6869 in = call->args [i];
6871 /* Simply remember the arguments */
6872 switch (ainfo->storage) {
6873 case LLVMArgNormal: {
6874 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
6877 opcode = mono_type_to_regmove (cfg, t);
6878 if (opcode == OP_FMOVE) {
6879 MONO_INST_NEW (cfg, ins, OP_FMOVE);
6880 ins->dreg = mono_alloc_freg (cfg);
6881 } else if (opcode == OP_LMOVE) {
6882 MONO_INST_NEW (cfg, ins, OP_LMOVE);
6883 ins->dreg = mono_alloc_lreg (cfg);
6884 } else if (opcode == OP_RMOVE) {
6885 MONO_INST_NEW (cfg, ins, OP_RMOVE);
6886 ins->dreg = mono_alloc_freg (cfg);
6888 MONO_INST_NEW (cfg, ins, OP_MOVE);
6889 ins->dreg = mono_alloc_ireg (cfg);
6891 ins->sreg1 = in->dreg;
6894 case LLVMArgVtypeByVal:
6895 case LLVMArgVtypeByRef:
6896 case LLVMArgVtypeInReg:
6897 case LLVMArgVtypeAsScalar:
6898 case LLVMArgScalarByRef:
6899 case LLVMArgAsIArgs:
6900 case LLVMArgAsFpArgs:
6901 case LLVMArgGsharedvtVariable:
6902 case LLVMArgGsharedvtFixed:
6903 case LLVMArgGsharedvtFixedVtype:
6904 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
6905 ins->dreg = mono_alloc_ireg (cfg);
6906 ins->sreg1 = in->dreg;
6907 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
6908 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
6909 ins->inst_vtype = ainfo->type;
6910 ins->klass = mono_class_from_mono_type (ainfo->type);
6913 cfg->exception_message = g_strdup ("ainfo->storage");
6914 cfg->disable_llvm = TRUE;
6918 if (!cfg->disable_llvm) {
6919 MONO_ADD_INS (cfg->cbb, ins);
6920 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
6925 static unsigned char*
6926 alloc_cb (LLVMValueRef function, int size)
6930 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
6934 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
6936 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
6941 emitted_cb (LLVMValueRef function, void *start, void *end)
6945 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
6947 cfg->code_len = (guint8*)end - (guint8*)start;
6951 exception_cb (void *data)
6954 MonoJitExceptionInfo *ei;
6955 guint32 ei_len, i, j, nested_len, nindex;
6956 gpointer *type_info;
6957 int this_reg, this_offset;
6959 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
6963 * data points to a DWARF FDE structure, convert it to our unwind format and
6965 * An alternative would be to save it directly, and modify our unwinder to work
6968 cfg->encoded_unwind_ops = mono_unwind_decode_fde ((guint8*)data, &cfg->encoded_unwind_ops_len, NULL, &ei, &ei_len, &type_info, &this_reg, &this_offset);
6969 if (cfg->verbose_level > 1)
6970 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
6972 /* Count nested clauses */
6974 for (i = 0; i < ei_len; ++i) {
6975 gint32 cindex1 = *(gint32*)type_info [i];
6976 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
6978 for (j = 0; j < cfg->header->num_clauses; ++j) {
6980 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
6982 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6988 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
6989 cfg->llvm_ex_info_len = ei_len + nested_len;
6990 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
6991 /* Fill the rest of the information from the type info */
6992 for (i = 0; i < ei_len; ++i) {
6993 gint32 clause_index = *(gint32*)type_info [i];
6994 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
6996 cfg->llvm_ex_info [i].flags = clause->flags;
6997 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
6998 cfg->llvm_ex_info [i].clause_index = clause_index;
7002 * For nested clauses, the LLVM produced exception info associates the try interval with
7003 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7004 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7005 * and everything else from the nested clause.
7008 for (i = 0; i < ei_len; ++i) {
7009 gint32 cindex1 = *(gint32*)type_info [i];
7010 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7012 for (j = 0; j < cfg->header->num_clauses; ++j) {
7014 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7015 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7017 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7018 /* clause1 is the nested clause */
7019 nested_ei = &cfg->llvm_ex_info [i];
7020 nesting_ei = &cfg->llvm_ex_info [nindex];
7023 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7025 nesting_ei->flags = clause2->flags;
7026 nesting_ei->data.catch_class = clause2->data.catch_class;
7027 nesting_ei->clause_index = cindex2;
7031 g_assert (nindex == ei_len + nested_len);
7032 cfg->llvm_this_reg = this_reg;
7033 cfg->llvm_this_offset = this_offset;
7035 /* type_info [i] is cfg mempool allocated, no need to free it */
7042 dlsym_cb (const char *name, void **symbol)
7048 if (!strcmp (name, "__bzero")) {
7049 *symbol = (void*)bzero;
7051 current = mono_dl_open (NULL, 0, NULL);
7054 err = mono_dl_symbol (current, name, symbol);
7056 mono_dl_close (current);
7058 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7059 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7065 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7067 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7071 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7073 LLVMTypeRef param_types [4];
7075 param_types [0] = param_type1;
7076 param_types [1] = param_type2;
7078 AddFunc (module, name, ret_type, param_types, 2);
7082 add_intrinsics (LLVMModuleRef module)
7084 /* Emit declarations of instrinsics */
7086 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7087 * type doesn't seem to do any locking.
7090 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7092 memset_param_count = 5;
7093 memset_func_name = "llvm.memset.p0i8.i32";
7095 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7099 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7101 memcpy_param_count = 5;
7102 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7104 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7108 LLVMTypeRef params [] = { LLVMDoubleType () };
7110 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7111 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7112 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7114 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7115 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7119 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7120 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7121 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7123 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7124 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7125 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7126 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7127 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7128 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7129 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7133 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7134 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7135 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7137 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7138 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7139 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7140 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7141 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7142 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7145 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7149 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7151 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7154 /* SSE intrinsics */
7155 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7157 LLVMTypeRef ret_type, arg_types [16];
7160 ret_type = type_to_simd_type (MONO_TYPE_I4);
7161 arg_types [0] = ret_type;
7162 arg_types [1] = ret_type;
7163 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7164 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7166 ret_type = type_to_simd_type (MONO_TYPE_I2);
7167 arg_types [0] = ret_type;
7168 arg_types [1] = ret_type;
7169 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7170 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7171 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7172 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7173 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7174 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7175 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7176 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7177 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7178 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7180 ret_type = type_to_simd_type (MONO_TYPE_I1);
7181 arg_types [0] = ret_type;
7182 arg_types [1] = ret_type;
7183 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7184 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7185 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7186 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7187 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7188 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7189 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7191 ret_type = type_to_simd_type (MONO_TYPE_R8);
7192 arg_types [0] = ret_type;
7193 arg_types [1] = ret_type;
7194 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7195 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7196 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7197 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7198 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7200 ret_type = type_to_simd_type (MONO_TYPE_R4);
7201 arg_types [0] = ret_type;
7202 arg_types [1] = ret_type;
7203 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7204 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7205 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7206 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7207 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7210 ret_type = type_to_simd_type (MONO_TYPE_I1);
7211 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7212 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7213 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7214 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7215 ret_type = type_to_simd_type (MONO_TYPE_I2);
7216 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7217 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7218 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7219 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7222 ret_type = type_to_simd_type (MONO_TYPE_R8);
7223 arg_types [0] = ret_type;
7224 arg_types [1] = ret_type;
7225 arg_types [2] = LLVMInt8Type ();
7226 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7227 ret_type = type_to_simd_type (MONO_TYPE_R4);
7228 arg_types [0] = ret_type;
7229 arg_types [1] = ret_type;
7230 arg_types [2] = LLVMInt8Type ();
7231 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7233 /* Conversion ops */
7234 ret_type = type_to_simd_type (MONO_TYPE_R8);
7235 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7236 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7237 ret_type = type_to_simd_type (MONO_TYPE_R4);
7238 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7239 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7240 ret_type = type_to_simd_type (MONO_TYPE_I4);
7241 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7242 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7243 ret_type = type_to_simd_type (MONO_TYPE_I4);
7244 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7245 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7246 ret_type = type_to_simd_type (MONO_TYPE_R4);
7247 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7248 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7249 ret_type = type_to_simd_type (MONO_TYPE_R8);
7250 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7251 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7253 ret_type = type_to_simd_type (MONO_TYPE_I4);
7254 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7255 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7256 ret_type = type_to_simd_type (MONO_TYPE_I4);
7257 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7258 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7261 ret_type = type_to_simd_type (MONO_TYPE_R8);
7262 arg_types [0] = ret_type;
7263 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7264 ret_type = type_to_simd_type (MONO_TYPE_R4);
7265 arg_types [0] = ret_type;
7266 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7267 ret_type = type_to_simd_type (MONO_TYPE_R4);
7268 arg_types [0] = ret_type;
7269 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7270 ret_type = type_to_simd_type (MONO_TYPE_R4);
7271 arg_types [0] = ret_type;
7272 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7275 ret_type = type_to_simd_type (MONO_TYPE_I2);
7276 arg_types [0] = ret_type;
7277 arg_types [1] = LLVMInt32Type ();
7278 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7279 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7280 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7281 ret_type = type_to_simd_type (MONO_TYPE_I4);
7282 arg_types [0] = ret_type;
7283 arg_types [1] = LLVMInt32Type ();
7284 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7285 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7286 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7287 ret_type = type_to_simd_type (MONO_TYPE_I8);
7288 arg_types [0] = ret_type;
7289 arg_types [1] = LLVMInt32Type ();
7290 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7291 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7294 ret_type = LLVMInt32Type ();
7295 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7296 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7299 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7302 /* Load/Store intrinsics */
7304 LLVMTypeRef arg_types [5];
7308 for (i = 1; i <= 8; i *= 2) {
7309 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7310 arg_types [1] = LLVMInt32Type ();
7311 arg_types [2] = LLVMInt1Type ();
7312 arg_types [3] = LLVMInt32Type ();
7313 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7314 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7316 arg_types [0] = LLVMIntType (i * 8);
7317 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7318 arg_types [2] = LLVMInt32Type ();
7319 arg_types [3] = LLVMInt1Type ();
7320 arg_types [4] = LLVMInt32Type ();
7321 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7322 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7328 add_types (MonoLLVMModule *module)
7330 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7334 mono_llvm_init (void)
7336 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7340 init_jit_module (MonoDomain *domain)
7342 MonoJitICallInfo *info;
7343 MonoJitDomainInfo *dinfo;
7344 MonoLLVMModule *module;
7347 dinfo = domain_jit_info (domain);
7348 if (dinfo->llvm_module)
7351 mono_loader_lock ();
7353 if (dinfo->llvm_module) {
7354 mono_loader_unlock ();
7358 module = g_new0 (MonoLLVMModule, 1);
7360 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7361 module->lmodule = LLVMModuleCreateWithName (name);
7362 module->context = LLVMGetGlobalContext ();
7364 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7366 add_intrinsics (module->lmodule);
7369 module->llvm_types = g_hash_table_new (NULL, NULL);
7371 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7373 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7375 mono_memory_barrier ();
7377 dinfo->llvm_module = module;
7379 mono_loader_unlock ();
7383 mono_llvm_cleanup (void)
7385 MonoLLVMModule *module = &aot_module;
7387 if (module->lmodule)
7388 LLVMDisposeModule (module->lmodule);
7390 if (module->context)
7391 LLVMContextDispose (module->context);
7395 mono_llvm_free_domain_info (MonoDomain *domain)
7397 MonoJitDomainInfo *info = domain_jit_info (domain);
7398 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7404 if (module->llvm_types)
7405 g_hash_table_destroy (module->llvm_types);
7407 mono_llvm_dispose_ee (module->mono_ee);
7409 if (module->bb_names) {
7410 for (i = 0; i < module->bb_names_len; ++i)
7411 g_free (module->bb_names [i]);
7412 g_free (module->bb_names);
7414 //LLVMDisposeModule (module->module);
7418 info->llvm_module = NULL;
7422 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7424 MonoLLVMModule *module = &aot_module;
7426 /* Delete previous module */
7427 if (module->plt_entries)
7428 g_hash_table_destroy (module->plt_entries);
7429 if (module->lmodule)
7430 LLVMDisposeModule (module->lmodule);
7432 memset (module, 0, sizeof (aot_module));
7434 module->lmodule = LLVMModuleCreateWithName ("aot");
7435 module->assembly = assembly;
7436 module->global_prefix = g_strdup (global_prefix);
7437 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7438 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7439 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7440 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7441 module->external_symbols = TRUE;
7442 module->emit_dwarf = emit_dwarf;
7443 module->static_link = static_link;
7444 module->llvm_only = llvm_only;
7445 /* The first few entries are reserved */
7446 module->max_got_offset = 16;
7447 module->context = LLVMContextCreate ();
7449 add_intrinsics (module->lmodule);
7454 * We couldn't compute the type of the LLVM global representing the got because
7455 * its size is only known after all the methods have been emitted. So create
7456 * a dummy variable, and replace all uses it with the real got variable when
7457 * its size is known in mono_llvm_emit_aot_module ().
7460 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7462 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7463 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7466 /* Add initialization array */
7468 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7470 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7471 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7475 emit_init_icall_wrappers (module);
7477 emit_llvm_code_start (module);
7479 /* Add a dummy personality function */
7480 if (!use_debug_personality) {
7481 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7482 LLVMSetLinkage (personality, LLVMExternalLinkage);
7483 mark_as_used (module, personality);
7486 /* Add a reference to the c++ exception we throw/catch */
7488 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7489 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7490 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7491 mono_llvm_set_is_constant (module->sentinel_exception);
7494 module->llvm_types = g_hash_table_new (NULL, NULL);
7495 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7496 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7497 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7498 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7499 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7500 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7501 module->method_to_callers = g_hash_table_new (NULL, NULL);
7505 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7508 LLVMValueRef res, *vals;
7510 vals = g_new0 (LLVMValueRef, nvalues);
7511 for (i = 0; i < nvalues; ++i)
7512 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7513 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7519 * mono_llvm_emit_aot_file_info:
7521 * Emit the MonoAotFileInfo structure.
7522 * Same as emit_aot_file_info () in aot-compiler.c.
7525 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7527 MonoLLVMModule *module = &aot_module;
7529 /* Save these for later */
7530 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7531 module->has_jitted_code = has_jitted_code;
7535 * mono_llvm_emit_aot_data:
7537 * Emit the binary data DATA pointed to by symbol SYMBOL.
7540 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7542 MonoLLVMModule *module = &aot_module;
7546 type = LLVMArrayType (LLVMInt8Type (), data_len);
7547 d = LLVMAddGlobal (module->lmodule, type, symbol);
7548 LLVMSetVisibility (d, LLVMHiddenVisibility);
7549 LLVMSetLinkage (d, LLVMInternalLinkage);
7550 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7551 mono_llvm_set_is_constant (d);
7554 /* Add a reference to a global defined in JITted code */
7556 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7561 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7562 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7568 emit_aot_file_info (MonoLLVMModule *module)
7570 LLVMTypeRef file_info_type;
7571 LLVMTypeRef *eltypes, eltype;
7572 LLVMValueRef info_var;
7573 LLVMValueRef *fields;
7574 int i, nfields, tindex;
7575 MonoAotFileInfo *info;
7576 LLVMModuleRef lmodule = module->lmodule;
7578 info = &module->aot_info;
7580 /* Create an LLVM type to represent MonoAotFileInfo */
7581 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7582 eltypes = g_new (LLVMTypeRef, nfields);
7584 eltypes [tindex ++] = LLVMInt32Type ();
7585 eltypes [tindex ++] = LLVMInt32Type ();
7587 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7588 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7590 for (i = 0; i < 15; ++i)
7591 eltypes [tindex ++] = LLVMInt32Type ();
7593 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7594 for (i = 0; i < 4; ++i)
7595 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7596 g_assert (tindex == nfields);
7597 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7598 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7600 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7601 if (module->static_link) {
7602 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7603 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7605 fields = g_new (LLVMValueRef, nfields);
7607 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7608 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7612 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7613 * for symbols defined in the .s file emitted by the aot compiler.
7615 eltype = eltypes [tindex];
7616 if (module->llvm_only)
7617 fields [tindex ++] = LLVMConstNull (eltype);
7619 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7620 fields [tindex ++] = module->got_var;
7621 /* llc defines this directly */
7622 if (!module->llvm_only) {
7623 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7624 fields [tindex ++] = LLVMConstNull (eltype);
7625 fields [tindex ++] = LLVMConstNull (eltype);
7627 fields [tindex ++] = LLVMConstNull (eltype);
7628 fields [tindex ++] = module->get_method;
7629 fields [tindex ++] = module->get_unbox_tramp;
7631 if (module->has_jitted_code) {
7632 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7633 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7635 fields [tindex ++] = LLVMConstNull (eltype);
7636 fields [tindex ++] = LLVMConstNull (eltype);
7638 if (!module->llvm_only)
7639 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7641 fields [tindex ++] = LLVMConstNull (eltype);
7642 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7643 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7644 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7645 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7646 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7647 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7648 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7649 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7650 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7651 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7652 /* Not needed (mem_end) */
7653 fields [tindex ++] = LLVMConstNull (eltype);
7654 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7655 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7656 if (info->trampoline_size [0]) {
7657 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7658 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7659 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7660 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7662 fields [tindex ++] = LLVMConstNull (eltype);
7663 fields [tindex ++] = LLVMConstNull (eltype);
7664 fields [tindex ++] = LLVMConstNull (eltype);
7665 fields [tindex ++] = LLVMConstNull (eltype);
7667 if (module->static_link)
7668 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7670 fields [tindex ++] = LLVMConstNull (eltype);
7671 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7672 if (!module->llvm_only) {
7673 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7674 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7675 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7676 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7677 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7678 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7680 fields [tindex ++] = LLVMConstNull (eltype);
7681 fields [tindex ++] = LLVMConstNull (eltype);
7682 fields [tindex ++] = LLVMConstNull (eltype);
7683 fields [tindex ++] = LLVMConstNull (eltype);
7684 fields [tindex ++] = LLVMConstNull (eltype);
7685 fields [tindex ++] = LLVMConstNull (eltype);
7688 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7689 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7692 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7693 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7694 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7695 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7696 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7697 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7698 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7699 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7700 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7701 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7702 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7703 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7704 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7705 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7706 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7708 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7709 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7710 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7711 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7712 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7713 g_assert (tindex == nfields);
7715 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7717 if (module->static_link) {
7721 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7722 /* Get rid of characters which cannot occur in symbols */
7724 for (p = s; *p; ++p) {
7725 if (!(isalnum (*p) || *p == '_'))
7728 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7730 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7731 LLVMSetLinkage (var, LLVMExternalLinkage);
7736 * Emit the aot module into the LLVM bitcode file FILENAME.
7739 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7741 LLVMTypeRef got_type, inited_type;
7742 LLVMValueRef real_got, real_inited;
7743 MonoLLVMModule *module = &aot_module;
7745 emit_llvm_code_end (module);
7748 * Create the real got variable and replace all uses of the dummy variable with
7751 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7752 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7753 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7754 if (module->external_symbols) {
7755 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7756 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7758 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7760 mono_llvm_replace_uses_of (module->got_var, real_got);
7762 mark_as_used (&aot_module, real_got);
7764 /* Delete the dummy got so it doesn't become a global */
7765 LLVMDeleteGlobal (module->got_var);
7766 module->got_var = real_got;
7769 * Same for the init_var
7771 if (module->llvm_only) {
7772 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7773 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7774 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7775 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7776 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7777 LLVMDeleteGlobal (module->inited_var);
7780 if (module->llvm_only) {
7781 emit_get_method (&aot_module);
7782 emit_get_unbox_tramp (&aot_module);
7785 emit_llvm_used (&aot_module);
7786 emit_dbg_info (&aot_module, filename, cu_name);
7787 emit_aot_file_info (&aot_module);
7790 * Replace GOT entries for directly callable methods with the methods themselves.
7791 * It would be easier to implement this by predefining all methods before compiling
7792 * their bodies, but that couldn't handle the case when a method fails to compile
7795 if (module->llvm_only) {
7796 GHashTableIter iter;
7798 GSList *callers, *l;
7800 g_hash_table_iter_init (&iter, module->method_to_callers);
7801 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7802 LLVMValueRef lmethod;
7804 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
7806 for (l = callers; l; l = l->next) {
7807 LLVMValueRef caller = (LLVMValueRef)l->data;
7809 mono_llvm_replace_uses_of (caller, lmethod);
7815 /* Replace PLT entries for directly callable methods with the methods themselves */
7817 GHashTableIter iter;
7819 LLVMValueRef callee;
7821 g_hash_table_iter_init (&iter, module->plt_entries_ji);
7822 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
7823 if (mono_aot_is_direct_callable (ji)) {
7824 LLVMValueRef lmethod;
7826 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
7827 /* The types might not match because the caller might pass an rgctx */
7828 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
7829 mono_llvm_replace_uses_of (callee, lmethod);
7830 mono_aot_mark_unused_llvm_plt_entry (ji);
7840 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
7841 g_assert_not_reached ();
7846 LLVMWriteBitcodeToFile (module->lmodule, filename);
7851 md_string (const char *s)
7853 return LLVMMDString (s, strlen (s));
7856 /* Debugging support */
7859 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
7861 LLVMModuleRef lmodule = module->lmodule;
7862 LLVMValueRef args [16], cu_args [16], cu, ver;
7864 char *build_info, *s, *dir;
7867 * This can only be enabled when LLVM code is emitted into a separate object
7868 * file, since the AOT compiler also emits dwarf info,
7869 * and the abbrev indexes will not be correct since llvm has added its own
7872 if (!module->emit_dwarf)
7876 * Emit dwarf info in the form of LLVM metadata. There is some
7877 * out-of-date documentation at:
7878 * http://llvm.org/docs/SourceLevelDebugging.html
7879 * but most of this was gathered from the llvm and
7884 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
7885 /* CU name/compilation dir */
7886 dir = g_path_get_dirname (filename);
7887 args [0] = LLVMMDString (cu_name, strlen (cu_name));
7888 args [1] = LLVMMDString (dir, strlen (dir));
7889 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
7892 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
7894 build_info = mono_get_runtime_build_info ();
7895 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
7896 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
7897 g_free (build_info);
7899 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7901 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7902 /* Runtime version */
7903 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7905 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7906 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7908 if (module->subprogram_mds) {
7912 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
7913 for (i = 0; i < module->subprogram_mds->len; ++i)
7914 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
7915 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
7917 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7920 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7921 /* Imported modules */
7922 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7924 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7925 /* DebugEmissionKind = FullDebug */
7926 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7927 cu = LLVMMDNode (cu_args, n_cuargs);
7928 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
7930 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7931 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
7932 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
7933 ver = LLVMMDNode (args, 3);
7934 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
7936 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7937 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
7938 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7939 ver = LLVMMDNode (args, 3);
7940 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
7944 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
7946 MonoLLVMModule *module = ctx->module;
7947 MonoDebugMethodInfo *minfo = ctx->minfo;
7948 char *source_file, *dir, *filename;
7949 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
7950 MonoSymSeqPoint *sym_seq_points;
7956 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
7958 source_file = g_strdup ("<unknown>");
7959 dir = g_path_get_dirname (source_file);
7960 filename = g_path_get_basename (source_file);
7962 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
7963 args [0] = md_string (filename);
7964 args [1] = md_string (dir);
7965 ctx_args [1] = LLVMMDNode (args, 2);
7966 ctx_md = LLVMMDNode (ctx_args, 2);
7968 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
7969 type_args [1] = NULL;
7970 type_args [2] = NULL;
7971 type_args [3] = LLVMMDString ("", 0);
7972 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7973 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7974 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7975 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7976 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7977 type_args [9] = NULL;
7978 type_args [10] = NULL;
7979 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7980 type_args [12] = NULL;
7981 type_args [13] = NULL;
7982 type_args [14] = NULL;
7983 type_md = LLVMMDNode (type_args, 14);
7985 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
7986 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
7987 /* Source directory + file pair */
7988 args [0] = md_string (filename);
7989 args [1] = md_string (dir);
7990 md_args [1] = LLVMMDNode (args ,2);
7991 md_args [2] = ctx_md;
7992 md_args [3] = md_string (cfg->method->name);
7993 md_args [4] = md_string (name);
7994 md_args [5] = md_string (name);
7997 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
7999 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8001 md_args [7] = type_md;
8003 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8005 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8007 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8008 /* Index into a virtual function */
8009 md_args [11] = NULL;
8010 md_args [12] = NULL;
8012 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8014 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8015 /* Pointer to LLVM function */
8016 md_args [15] = method;
8017 /* Function template parameter */
8018 md_args [16] = NULL;
8019 /* Function declaration descriptor */
8020 md_args [17] = NULL;
8021 /* List of function variables */
8022 md_args [18] = LLVMMDNode (args, 0);
8024 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8025 md = LLVMMDNode (md_args, 20);
8027 if (!module->subprogram_mds)
8028 module->subprogram_mds = g_ptr_array_new ();
8029 g_ptr_array_add (module->subprogram_mds, md);
8033 g_free (source_file);
8034 g_free (sym_seq_points);
8040 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8042 MonoCompile *cfg = ctx->cfg;
8044 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8045 MonoDebugSourceLocation *loc;
8046 LLVMValueRef loc_md, md_args [16];
8049 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8053 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8054 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8055 md_args [nmd_args ++] = ctx->dbg_md;
8056 md_args [nmd_args ++] = NULL;
8057 loc_md = LLVMMDNode (md_args, nmd_args);
8058 LLVMSetCurrentDebugLocation (builder, loc_md);
8059 mono_debug_symfile_free_location (loc);
8065 default_mono_llvm_unhandled_exception (void)
8067 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8068 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8070 mono_unhandled_exception (target);
8071 exit (mono_environment_exitcode_get ());
8076 - Emit LLVM IR from the mono IR using the LLVM C API.
8077 - The original arch specific code remains, so we can fall back to it if we run
8078 into something we can't handle.
8082 A partial list of issues:
8083 - Handling of opcodes which can throw exceptions.
8085 In the mono JIT, these are implemented using code like this:
8092 push throw_pos - method
8093 call <exception trampoline>
8095 The problematic part is push throw_pos - method, which cannot be represented
8096 in the LLVM IR, since it does not support label values.
8097 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8098 be implemented in JIT mode ?
8099 -> a possible but slower implementation would use the normal exception
8100 throwing code but it would need to control the placement of the throw code
8101 (it needs to be exactly after the compare+branch).
8102 -> perhaps add a PC offset intrinsics ?
8104 - efficient implementation of .ovf opcodes.
8106 These are currently implemented as:
8107 <ins which sets the condition codes>
8110 Some overflow opcodes are now supported by LLVM SVN.
8112 - exception handling, unwinding.
8113 - SSA is disabled for methods with exception handlers
8114 - How to obtain unwind info for LLVM compiled methods ?
8115 -> this is now solved by converting the unwind info generated by LLVM
8117 - LLVM uses the c++ exception handling framework, while we use our home grown
8118 code, and couldn't use the c++ one:
8119 - its not supported under VC++, other exotic platforms.
8120 - it might be impossible to support filter clauses with it.
8124 The trampolines need a predictable call sequence, since they need to disasm
8125 the calling code to obtain register numbers / offsets.
8127 LLVM currently generates this code in non-JIT mode:
8128 mov -0x98(%rax),%eax
8130 Here, the vtable pointer is lost.
8131 -> solution: use one vtable trampoline per class.
8133 - passing/receiving the IMT pointer/RGCTX.
8134 -> solution: pass them as normal arguments ?
8138 LLVM does not allow the specification of argument registers etc. This means
8139 that all calls are made according to the platform ABI.
8141 - passing/receiving vtypes.
8143 Vtypes passed/received in registers are handled by the front end by using
8144 a signature with scalar arguments, and loading the parts of the vtype into those
8147 Vtypes passed on the stack are handled using the 'byval' attribute.
8151 Supported though alloca, we need to emit the load/store code.
8155 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8156 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8157 This is made easier because the IR is already in SSA form.
8158 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8159 types are frequently used incorrectly.
8164 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8165 it with the file containing the methods emitted by the JIT and the AOT data
8169 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8170 * - each bblock should end with a branch
8171 * - setting the return value, making cfg->ret non-volatile
8172 * - avoid some transformations in the JIT which make it harder for us to generate
8174 * - use pointer types to help optimizations.