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/BitWriter.h"
28 #include "llvm-c/Analysis.h"
30 #include "mini-llvm-cpp.h"
32 #include "aot-compiler.h"
33 #include "mini-llvm.h"
38 extern void *memset(void *, int, size_t);
39 void bzero (void *to, size_t count) { memset (to, 0, count); }
43 #if LLVM_API_VERSION < 4
44 #error "The version of the mono llvm repository is too old."
47 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
50 * Information associated by mono with LLVM modules.
53 LLVMModuleRef lmodule;
54 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
55 GHashTable *llvm_types;
57 const char *got_symbol;
58 const char *get_method_symbol;
59 const char *get_unbox_tramp_symbol;
60 GHashTable *plt_entries;
61 GHashTable *plt_entries_ji;
62 GHashTable *method_to_lmethod;
63 GHashTable *direct_callables;
68 GPtrArray *subprogram_mds;
70 LLVMExecutionEngineRef ee;
71 gboolean external_symbols;
76 MonoAssembly *assembly;
78 MonoAotFileInfo aot_info;
79 const char *jit_got_symbol;
80 const char *eh_frame_symbol;
81 LLVMValueRef get_method, get_unbox_tramp;
82 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
83 LLVMValueRef code_start, code_end;
84 LLVMValueRef inited_var;
85 int max_inited_idx, max_method_idx;
86 gboolean has_jitted_code;
89 GHashTable *idx_to_lmethod;
90 GHashTable *idx_to_unbox_tramp;
91 /* Maps a MonoMethod to LLVM instructions representing it */
92 GHashTable *method_to_callers;
93 LLVMContextRef context;
94 LLVMValueRef sentinel_exception;
95 void *di_builder, *cu;
99 * Information associated by the backend with mono basic blocks.
102 LLVMBasicBlockRef bblock, end_bblock;
103 LLVMValueRef finally_ind;
104 gboolean added, invoke_target;
106 * If this bblock is the start of a finally clause, this is a list of bblocks it
107 * needs to branch to in ENDFINALLY.
109 GSList *call_handler_return_bbs;
111 * If this bblock is the start of a finally clause, this is the bblock that
112 * CALL_HANDLER needs to branch to.
114 LLVMBasicBlockRef call_handler_target_bb;
115 /* The list of switch statements generated by ENDFINALLY instructions */
116 GSList *endfinally_switch_ins_list;
121 * Structure containing emit state
124 MonoMemPool *mempool;
126 /* Maps method names to the corresponding LLVMValueRef */
127 GHashTable *emitted_method_decls;
130 LLVMValueRef lmethod;
131 MonoLLVMModule *module;
132 LLVMModuleRef lmodule;
134 int sindex, default_index, ex_index;
135 LLVMBuilderRef builder;
136 LLVMValueRef *values, *addresses;
137 MonoType **vreg_cli_types;
139 MonoMethodSignature *sig;
141 GHashTable *region_to_handler;
142 GHashTable *clause_to_handler;
143 LLVMBuilderRef alloca_builder;
144 LLVMValueRef last_alloca;
145 LLVMValueRef rgctx_arg;
146 LLVMValueRef this_arg;
147 LLVMTypeRef *vreg_types;
148 LLVMTypeRef method_type;
149 LLVMBasicBlockRef init_bb, inited_bb;
151 gboolean *unreachable;
153 gboolean has_got_access;
154 gboolean is_linkonce;
155 int this_arg_pindex, rgctx_arg_pindex;
156 LLVMValueRef imt_rgctx_loc;
157 GHashTable *llvm_types;
159 MonoDebugMethodInfo *minfo;
161 /* For every clause, the clauses it is nested in */
164 GHashTable *exc_meta;
165 GHashTable *method_to_callers;
166 GPtrArray *phi_values;
167 GPtrArray *bblock_list;
169 GHashTable *jit_callees;
175 MonoBasicBlock *in_bb;
180 * Instruction metadata
181 * This is the same as ins_info, but LREG != IREG.
189 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
190 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
197 /* keep in sync with the enum in mini.h */
200 #include "mini-ops.h"
205 #if SIZEOF_VOID_P == 4
206 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
208 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
211 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
214 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
216 #define TRACE_FAILURE(msg)
220 #define IS_TARGET_X86 1
222 #define IS_TARGET_X86 0
226 #define IS_TARGET_AMD64 1
228 #define IS_TARGET_AMD64 0
231 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
233 static LLVMIntPredicate cond_to_llvm_cond [] = {
246 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
259 static MonoNativeTlsKey current_cfg_tls_id;
261 static MonoLLVMModule aot_module;
263 static GHashTable *intrins_id_to_name;
264 static GHashTable *intrins_name_to_id;
266 static void init_jit_module (MonoDomain *domain);
268 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
269 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
270 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
271 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
272 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
273 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
276 set_failure (EmitContext *ctx, const char *message)
278 TRACE_FAILURE (reason);
279 ctx->cfg->exception_message = g_strdup (message);
280 ctx->cfg->disable_llvm = TRUE;
286 * The LLVM type with width == sizeof (gpointer)
291 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
297 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
303 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
309 * Return the size of the LLVM representation of the vtype T.
312 get_vtype_size (MonoType *t)
316 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
318 /* LLVMArgAsIArgs depends on this since it stores whole words */
319 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
326 * simd_class_to_llvm_type:
328 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
331 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
333 if (!strcmp (klass->name, "Vector2d")) {
334 return LLVMVectorType (LLVMDoubleType (), 2);
335 } else if (!strcmp (klass->name, "Vector2l")) {
336 return LLVMVectorType (LLVMInt64Type (), 2);
337 } else if (!strcmp (klass->name, "Vector2ul")) {
338 return LLVMVectorType (LLVMInt64Type (), 2);
339 } else if (!strcmp (klass->name, "Vector4i")) {
340 return LLVMVectorType (LLVMInt32Type (), 4);
341 } else if (!strcmp (klass->name, "Vector4ui")) {
342 return LLVMVectorType (LLVMInt32Type (), 4);
343 } else if (!strcmp (klass->name, "Vector4f")) {
344 return LLVMVectorType (LLVMFloatType (), 4);
345 } else if (!strcmp (klass->name, "Vector8s")) {
346 return LLVMVectorType (LLVMInt16Type (), 8);
347 } else if (!strcmp (klass->name, "Vector8us")) {
348 return LLVMVectorType (LLVMInt16Type (), 8);
349 } else if (!strcmp (klass->name, "Vector16sb")) {
350 return LLVMVectorType (LLVMInt8Type (), 16);
351 } else if (!strcmp (klass->name, "Vector16b")) {
352 return LLVMVectorType (LLVMInt8Type (), 16);
354 printf ("%s\n", klass->name);
360 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
361 static inline G_GNUC_UNUSED LLVMTypeRef
362 type_to_simd_type (int type)
366 return LLVMVectorType (LLVMInt8Type (), 16);
368 return LLVMVectorType (LLVMInt16Type (), 8);
370 return LLVMVectorType (LLVMInt32Type (), 4);
372 return LLVMVectorType (LLVMInt64Type (), 2);
374 return LLVMVectorType (LLVMDoubleType (), 2);
376 return LLVMVectorType (LLVMFloatType (), 4);
378 g_assert_not_reached ();
384 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
386 int i, size, nfields, esize;
387 LLVMTypeRef *eltypes;
392 t = &klass->byval_arg;
394 if (mini_type_is_hfa (t, &nfields, &esize)) {
396 * This is needed on arm64 where HFAs are returned in
400 eltypes = g_new (LLVMTypeRef, size);
401 for (i = 0; i < size; ++i)
402 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
404 size = get_vtype_size (t);
406 eltypes = g_new (LLVMTypeRef, size);
407 for (i = 0; i < size; ++i)
408 eltypes [i] = LLVMInt8Type ();
411 name = mono_type_full_name (&klass->byval_arg);
412 ltype = LLVMStructCreateNamed (module->context, name);
413 LLVMStructSetBody (ltype, eltypes, size, FALSE);
423 * Return the LLVM type corresponding to T.
426 type_to_llvm_type (EmitContext *ctx, MonoType *t)
428 t = mini_get_underlying_type (t);
432 return LLVMVoidType ();
434 return LLVMInt8Type ();
436 return LLVMInt16Type ();
438 return LLVMInt32Type ();
440 return LLVMInt8Type ();
442 return LLVMInt16Type ();
444 return LLVMInt32Type ();
445 case MONO_TYPE_BOOLEAN:
446 return LLVMInt8Type ();
449 return LLVMInt64Type ();
451 return LLVMInt16Type ();
453 return LLVMFloatType ();
455 return LLVMDoubleType ();
458 return IntPtrType ();
459 case MONO_TYPE_OBJECT:
460 case MONO_TYPE_CLASS:
461 case MONO_TYPE_ARRAY:
462 case MONO_TYPE_SZARRAY:
463 case MONO_TYPE_STRING:
465 return ObjRefType ();
468 /* Because of generic sharing */
469 return ObjRefType ();
470 case MONO_TYPE_GENERICINST:
471 if (!mono_type_generic_inst_is_valuetype (t))
472 return ObjRefType ();
474 case MONO_TYPE_VALUETYPE:
475 case MONO_TYPE_TYPEDBYREF: {
479 klass = mono_class_from_mono_type (t);
481 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
482 return simd_class_to_llvm_type (ctx, klass);
485 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
487 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
489 ltype = create_llvm_type_for_type (ctx->module, klass);
490 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
496 printf ("X: %d\n", t->type);
497 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
498 ctx->cfg->disable_llvm = TRUE;
506 * Return whenever T is an unsigned int type.
509 type_is_unsigned (EmitContext *ctx, MonoType *t)
511 t = mini_get_underlying_type (t);
527 * type_to_llvm_arg_type:
529 * Same as type_to_llvm_type, but treat i8/i16 as i32.
532 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
534 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
536 if (ctx->cfg->llvm_only)
540 * This works on all abis except arm64/ios which passes multiple
541 * arguments in one stack slot.
544 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
546 * LLVM generates code which only sets the lower bits, while JITted
547 * code expects all the bits to be set.
549 ptype = LLVMInt32Type ();
557 * llvm_type_to_stack_type:
559 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
562 static G_GNUC_UNUSED LLVMTypeRef
563 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
567 if (type == LLVMInt8Type ())
568 return LLVMInt32Type ();
569 else if (type == LLVMInt16Type ())
570 return LLVMInt32Type ();
571 else if (!cfg->r4fp && type == LLVMFloatType ())
572 return LLVMDoubleType ();
578 * regtype_to_llvm_type:
580 * Return the LLVM type corresponding to the regtype C used in instruction
584 regtype_to_llvm_type (char c)
588 return LLVMInt32Type ();
590 return LLVMInt64Type ();
592 return LLVMDoubleType ();
601 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
604 op_to_llvm_type (int opcode)
609 return LLVMInt8Type ();
612 return LLVMInt8Type ();
615 return LLVMInt16Type ();
618 return LLVMInt16Type ();
621 return LLVMInt32Type ();
624 return LLVMInt32Type ();
626 return LLVMInt64Type ();
628 return LLVMFloatType ();
630 return LLVMDoubleType ();
632 return LLVMInt64Type ();
634 return LLVMInt32Type ();
636 return LLVMInt64Type ();
641 return LLVMInt8Type ();
646 return LLVMInt16Type ();
648 return LLVMInt32Type ();
651 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
658 return LLVMInt32Type ();
665 return LLVMInt64Type ();
667 printf ("%s\n", mono_inst_name (opcode));
668 g_assert_not_reached ();
673 #define CLAUSE_START(clause) ((clause)->try_offset)
674 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
677 * load_store_to_llvm_type:
679 * Return the size/sign/zero extension corresponding to the load/store opcode
683 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
689 case OP_LOADI1_MEMBASE:
690 case OP_STOREI1_MEMBASE_REG:
691 case OP_STOREI1_MEMBASE_IMM:
692 case OP_ATOMIC_LOAD_I1:
693 case OP_ATOMIC_STORE_I1:
696 return LLVMInt8Type ();
697 case OP_LOADU1_MEMBASE:
699 case OP_ATOMIC_LOAD_U1:
700 case OP_ATOMIC_STORE_U1:
703 return LLVMInt8Type ();
704 case OP_LOADI2_MEMBASE:
705 case OP_STOREI2_MEMBASE_REG:
706 case OP_STOREI2_MEMBASE_IMM:
707 case OP_ATOMIC_LOAD_I2:
708 case OP_ATOMIC_STORE_I2:
711 return LLVMInt16Type ();
712 case OP_LOADU2_MEMBASE:
714 case OP_ATOMIC_LOAD_U2:
715 case OP_ATOMIC_STORE_U2:
718 return LLVMInt16Type ();
719 case OP_LOADI4_MEMBASE:
720 case OP_LOADU4_MEMBASE:
723 case OP_STOREI4_MEMBASE_REG:
724 case OP_STOREI4_MEMBASE_IMM:
725 case OP_ATOMIC_LOAD_I4:
726 case OP_ATOMIC_STORE_I4:
727 case OP_ATOMIC_LOAD_U4:
728 case OP_ATOMIC_STORE_U4:
730 return LLVMInt32Type ();
731 case OP_LOADI8_MEMBASE:
733 case OP_STOREI8_MEMBASE_REG:
734 case OP_STOREI8_MEMBASE_IMM:
735 case OP_ATOMIC_LOAD_I8:
736 case OP_ATOMIC_STORE_I8:
737 case OP_ATOMIC_LOAD_U8:
738 case OP_ATOMIC_STORE_U8:
740 return LLVMInt64Type ();
741 case OP_LOADR4_MEMBASE:
742 case OP_STORER4_MEMBASE_REG:
743 case OP_ATOMIC_LOAD_R4:
744 case OP_ATOMIC_STORE_R4:
746 return LLVMFloatType ();
747 case OP_LOADR8_MEMBASE:
748 case OP_STORER8_MEMBASE_REG:
749 case OP_ATOMIC_LOAD_R8:
750 case OP_ATOMIC_STORE_R8:
752 return LLVMDoubleType ();
753 case OP_LOAD_MEMBASE:
755 case OP_STORE_MEMBASE_REG:
756 case OP_STORE_MEMBASE_IMM:
757 *size = sizeof (gpointer);
758 return IntPtrType ();
760 g_assert_not_reached ();
768 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
771 ovf_op_to_intrins (int opcode)
775 return "llvm.sadd.with.overflow.i32";
777 return "llvm.uadd.with.overflow.i32";
779 return "llvm.ssub.with.overflow.i32";
781 return "llvm.usub.with.overflow.i32";
783 return "llvm.smul.with.overflow.i32";
785 return "llvm.umul.with.overflow.i32";
787 return "llvm.sadd.with.overflow.i64";
789 return "llvm.uadd.with.overflow.i64";
791 return "llvm.ssub.with.overflow.i64";
793 return "llvm.usub.with.overflow.i64";
795 return "llvm.smul.with.overflow.i64";
797 return "llvm.umul.with.overflow.i64";
799 g_assert_not_reached ();
805 simd_op_to_intrins (int opcode)
808 #if defined(TARGET_X86) || defined(TARGET_AMD64)
810 return "llvm.x86.sse2.min.pd";
812 return "llvm.x86.sse.min.ps";
814 return "llvm.x86.sse41.pminud";
816 return "llvm.x86.sse41.pminuw";
818 return "llvm.x86.sse2.pminu.b";
820 return "llvm.x86.sse2.pmins.w";
822 return "llvm.x86.sse2.max.pd";
824 return "llvm.x86.sse.max.ps";
826 return "llvm.x86.sse3.hadd.pd";
828 return "llvm.x86.sse3.hadd.ps";
830 return "llvm.x86.sse3.hsub.pd";
832 return "llvm.x86.sse3.hsub.ps";
834 return "llvm.x86.sse41.pmaxud";
836 return "llvm.x86.sse41.pmaxuw";
838 return "llvm.x86.sse2.pmaxu.b";
840 return "llvm.x86.sse3.addsub.ps";
842 return "llvm.x86.sse3.addsub.pd";
843 case OP_EXTRACT_MASK:
844 return "llvm.x86.sse2.pmovmskb.128";
847 return "llvm.x86.sse2.psrli.w";
850 return "llvm.x86.sse2.psrli.d";
853 return "llvm.x86.sse2.psrli.q";
856 return "llvm.x86.sse2.pslli.w";
859 return "llvm.x86.sse2.pslli.d";
862 return "llvm.x86.sse2.pslli.q";
865 return "llvm.x86.sse2.psrai.w";
868 return "llvm.x86.sse2.psrai.d";
870 return "llvm.x86.sse2.padds.b";
872 return "llvm.x86.sse2.padds.w";
874 return "llvm.x86.sse2.psubs.b";
876 return "llvm.x86.sse2.psubs.w";
877 case OP_PADDB_SAT_UN:
878 return "llvm.x86.sse2.paddus.b";
879 case OP_PADDW_SAT_UN:
880 return "llvm.x86.sse2.paddus.w";
881 case OP_PSUBB_SAT_UN:
882 return "llvm.x86.sse2.psubus.b";
883 case OP_PSUBW_SAT_UN:
884 return "llvm.x86.sse2.psubus.w";
886 return "llvm.x86.sse2.pavg.b";
888 return "llvm.x86.sse2.pavg.w";
890 return "llvm.x86.sse.sqrt.ps";
892 return "llvm.x86.sse2.sqrt.pd";
894 return "llvm.x86.sse.rsqrt.ps";
896 return "llvm.x86.sse.rcp.ps";
898 return "llvm.x86.sse2.cvtdq2pd";
900 return "llvm.x86.sse2.cvtdq2ps";
902 return "llvm.x86.sse2.cvtpd2dq";
904 return "llvm.x86.sse2.cvtps2dq";
906 return "llvm.x86.sse2.cvtpd2ps";
908 return "llvm.x86.sse2.cvtps2pd";
910 return "llvm.x86.sse2.cvttpd2dq";
912 return "llvm.x86.sse2.cvttps2dq";
914 return "llvm.x86.sse.cmp.ps";
916 return "llvm.x86.sse2.cmp.pd";
918 return "llvm.x86.sse2.packsswb.128";
920 return "llvm.x86.sse2.packssdw.128";
922 return "llvm.x86.sse2.packuswb.128";
924 return "llvm.x86.sse41.packusdw";
926 return "llvm.x86.sse2.pmulh.w";
927 case OP_PMULW_HIGH_UN:
928 return "llvm.x86.sse2.pmulhu.w";
931 g_assert_not_reached ();
937 simd_op_to_llvm_type (int opcode)
939 #if defined(TARGET_X86) || defined(TARGET_AMD64)
943 return type_to_simd_type (MONO_TYPE_R8);
946 return type_to_simd_type (MONO_TYPE_I8);
949 return type_to_simd_type (MONO_TYPE_I4);
954 return type_to_simd_type (MONO_TYPE_I2);
958 return type_to_simd_type (MONO_TYPE_I1);
960 return type_to_simd_type (MONO_TYPE_R4);
963 return type_to_simd_type (MONO_TYPE_I4);
967 return type_to_simd_type (MONO_TYPE_R8);
971 return type_to_simd_type (MONO_TYPE_R4);
972 case OP_EXTRACT_MASK:
973 return type_to_simd_type (MONO_TYPE_I1);
979 return type_to_simd_type (MONO_TYPE_R4);
982 return type_to_simd_type (MONO_TYPE_R8);
984 g_assert_not_reached ();
995 * Return the LLVM basic block corresponding to BB.
997 static LLVMBasicBlockRef
998 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1000 char bb_name_buf [128];
1003 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1004 if (bb->flags & BB_EXCEPTION_HANDLER) {
1005 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1006 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1007 bb_name = bb_name_buf;
1008 } else if (bb->block_num < 256) {
1009 if (!ctx->module->bb_names) {
1010 ctx->module->bb_names_len = 256;
1011 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1013 if (!ctx->module->bb_names [bb->block_num]) {
1016 n = g_strdup_printf ("BB%d", bb->block_num);
1017 mono_memory_barrier ();
1018 ctx->module->bb_names [bb->block_num] = n;
1020 bb_name = ctx->module->bb_names [bb->block_num];
1022 sprintf (bb_name_buf, "BB%d", bb->block_num);
1023 bb_name = bb_name_buf;
1026 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1027 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1030 return ctx->bblocks [bb->block_num].bblock;
1036 * Return the last LLVM bblock corresponding to BB.
1037 * This might not be equal to the bb returned by get_bb () since we need to generate
1038 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1040 static LLVMBasicBlockRef
1041 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1044 return ctx->bblocks [bb->block_num].end_bblock;
1047 static LLVMBasicBlockRef
1048 gen_bb (EmitContext *ctx, const char *prefix)
1052 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1053 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1059 * Return the target of the patch identified by TYPE and TARGET.
1062 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1068 memset (&ji, 0, sizeof (ji));
1070 ji.data.target = target;
1072 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1073 mono_error_assert_ok (&error);
1081 * Emit code to convert the LLVM value V to DTYPE.
1084 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1086 LLVMTypeRef stype = LLVMTypeOf (v);
1088 if (stype != dtype) {
1089 gboolean ext = FALSE;
1092 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1094 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1096 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1100 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1102 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1103 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1106 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1107 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1108 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1109 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1110 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1111 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1112 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1113 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1115 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1116 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1117 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1118 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1119 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1120 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1122 if (mono_arch_is_soft_float ()) {
1123 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1124 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1125 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1126 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1129 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1130 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1133 LLVMDumpValue (LLVMConstNull (dtype));
1134 g_assert_not_reached ();
1142 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1144 return convert_full (ctx, v, dtype, FALSE);
1148 * emit_volatile_load:
1150 * If vreg is volatile, emit a load from its address.
1153 emit_volatile_load (EmitContext *ctx, int vreg)
1157 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1158 t = ctx->vreg_cli_types [vreg];
1159 if (t && !t->byref) {
1161 * Might have to zero extend since llvm doesn't have
1164 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1165 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1166 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1167 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1168 else if (t->type == MONO_TYPE_U8)
1169 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1176 * emit_volatile_store:
1178 * If VREG is volatile, emit a store from its value to its address.
1181 emit_volatile_store (EmitContext *ctx, int vreg)
1183 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1185 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1186 g_assert (ctx->addresses [vreg]);
1187 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1192 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1194 LLVMTypeRef ret_type;
1195 LLVMTypeRef *param_types = NULL;
1200 rtype = mini_get_underlying_type (sig->ret);
1201 ret_type = type_to_llvm_type (ctx, rtype);
1205 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1209 param_types [pindex ++] = ThisType ();
1210 for (i = 0; i < sig->param_count; ++i)
1211 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1213 if (!ctx_ok (ctx)) {
1214 g_free (param_types);
1218 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1219 g_free (param_types);
1225 * sig_to_llvm_sig_full:
1227 * Return the LLVM signature corresponding to the mono signature SIG using the
1228 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1231 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1233 LLVMTypeRef ret_type;
1234 LLVMTypeRef *param_types = NULL;
1236 int i, j, pindex, vret_arg_pindex = 0;
1237 gboolean vretaddr = FALSE;
1241 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1243 rtype = mini_get_underlying_type (sig->ret);
1244 ret_type = type_to_llvm_type (ctx, rtype);
1248 switch (cinfo->ret.storage) {
1249 case LLVMArgVtypeInReg:
1250 /* LLVM models this by returning an aggregate value */
1251 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1252 LLVMTypeRef members [2];
1254 members [0] = IntPtrType ();
1255 ret_type = LLVMStructType (members, 1, FALSE);
1256 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1258 ret_type = LLVMVoidType ();
1259 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1260 LLVMTypeRef members [2];
1262 members [0] = IntPtrType ();
1263 members [1] = IntPtrType ();
1264 ret_type = LLVMStructType (members, 2, FALSE);
1266 g_assert_not_reached ();
1269 case LLVMArgVtypeByVal:
1270 /* Vtype returned normally by val */
1272 case LLVMArgVtypeAsScalar: {
1273 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1274 /* LLVM models this by returning an int */
1275 if (size < SIZEOF_VOID_P) {
1276 g_assert (cinfo->ret.nslots == 1);
1277 ret_type = LLVMIntType (size * 8);
1279 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1280 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1284 case LLVMArgFpStruct: {
1285 /* Vtype returned as a fp struct */
1286 LLVMTypeRef members [16];
1288 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1289 for (i = 0; i < cinfo->ret.nslots; ++i)
1290 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1291 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1294 case LLVMArgVtypeByRef:
1295 /* Vtype returned using a hidden argument */
1296 ret_type = LLVMVoidType ();
1298 case LLVMArgVtypeRetAddr:
1299 case LLVMArgGsharedvtFixed:
1300 case LLVMArgGsharedvtFixedVtype:
1301 case LLVMArgGsharedvtVariable:
1303 ret_type = LLVMVoidType ();
1309 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1311 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1313 * Has to be the first argument because of the sret argument attribute
1314 * FIXME: This might conflict with passing 'this' as the first argument, but
1315 * this is only used on arm64 which has a dedicated struct return register.
1317 cinfo->vret_arg_pindex = pindex;
1318 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1319 if (!ctx_ok (ctx)) {
1320 g_free (param_types);
1323 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1326 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1327 cinfo->rgctx_arg_pindex = pindex;
1328 param_types [pindex] = ctx->module->ptr_type;
1331 if (cinfo->imt_arg) {
1332 cinfo->imt_arg_pindex = pindex;
1333 param_types [pindex] = ctx->module->ptr_type;
1337 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1338 vret_arg_pindex = pindex;
1339 if (cinfo->vret_arg_index == 1) {
1340 /* Add the slots consumed by the first argument */
1341 LLVMArgInfo *ainfo = &cinfo->args [0];
1342 switch (ainfo->storage) {
1343 case LLVMArgVtypeInReg:
1344 for (j = 0; j < 2; ++j) {
1345 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1354 cinfo->vret_arg_pindex = vret_arg_pindex;
1357 if (vretaddr && vret_arg_pindex == pindex)
1358 param_types [pindex ++] = IntPtrType ();
1360 cinfo->this_arg_pindex = pindex;
1361 param_types [pindex ++] = ThisType ();
1362 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1364 if (vretaddr && vret_arg_pindex == pindex)
1365 param_types [pindex ++] = IntPtrType ();
1366 for (i = 0; i < sig->param_count; ++i) {
1367 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1369 if (vretaddr && vret_arg_pindex == pindex)
1370 param_types [pindex ++] = IntPtrType ();
1371 ainfo->pindex = pindex;
1373 switch (ainfo->storage) {
1374 case LLVMArgVtypeInReg:
1375 for (j = 0; j < 2; ++j) {
1376 switch (ainfo->pair_storage [j]) {
1378 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1383 g_assert_not_reached ();
1387 case LLVMArgVtypeByVal:
1388 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1391 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1394 case LLVMArgAsIArgs:
1395 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1398 case LLVMArgVtypeByRef:
1399 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1402 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1405 case LLVMArgAsFpArgs: {
1408 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1409 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1410 param_types [pindex ++] = LLVMDoubleType ();
1411 for (j = 0; j < ainfo->nslots; ++j)
1412 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1415 case LLVMArgVtypeAsScalar:
1416 g_assert_not_reached ();
1418 case LLVMArgGsharedvtFixed:
1419 case LLVMArgGsharedvtFixedVtype:
1420 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1422 case LLVMArgGsharedvtVariable:
1423 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1426 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1430 if (!ctx_ok (ctx)) {
1431 g_free (param_types);
1434 if (vretaddr && vret_arg_pindex == pindex)
1435 param_types [pindex ++] = IntPtrType ();
1436 if (ctx->llvm_only && cinfo->rgctx_arg) {
1437 /* Pass the rgctx as the last argument */
1438 cinfo->rgctx_arg_pindex = pindex;
1439 param_types [pindex] = ctx->module->ptr_type;
1443 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1444 g_free (param_types);
1450 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1452 return sig_to_llvm_sig_full (ctx, sig, NULL);
1456 * LLVMFunctionType1:
1458 * Create an LLVM function type from the arguments.
1460 static G_GNUC_UNUSED LLVMTypeRef
1461 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1464 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1468 * LLVMFunctionType1:
1470 * Create an LLVM function type from the arguments.
1472 static G_GNUC_UNUSED LLVMTypeRef
1473 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1474 LLVMTypeRef ParamType1,
1477 LLVMTypeRef param_types [1];
1479 param_types [0] = ParamType1;
1481 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1485 * LLVMFunctionType2:
1487 * Create an LLVM function type from the arguments.
1489 static G_GNUC_UNUSED LLVMTypeRef
1490 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1491 LLVMTypeRef ParamType1,
1492 LLVMTypeRef ParamType2,
1495 LLVMTypeRef param_types [2];
1497 param_types [0] = ParamType1;
1498 param_types [1] = ParamType2;
1500 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1504 * LLVMFunctionType3:
1506 * Create an LLVM function type from the arguments.
1508 static G_GNUC_UNUSED LLVMTypeRef
1509 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1510 LLVMTypeRef ParamType1,
1511 LLVMTypeRef ParamType2,
1512 LLVMTypeRef ParamType3,
1515 LLVMTypeRef param_types [3];
1517 param_types [0] = ParamType1;
1518 param_types [1] = ParamType2;
1519 param_types [2] = ParamType3;
1521 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1524 static G_GNUC_UNUSED LLVMTypeRef
1525 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1526 LLVMTypeRef ParamType1,
1527 LLVMTypeRef ParamType2,
1528 LLVMTypeRef ParamType3,
1529 LLVMTypeRef ParamType4,
1530 LLVMTypeRef ParamType5,
1533 LLVMTypeRef param_types [5];
1535 param_types [0] = ParamType1;
1536 param_types [1] = ParamType2;
1537 param_types [2] = ParamType3;
1538 param_types [3] = ParamType4;
1539 param_types [4] = ParamType5;
1541 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1547 * Create an LLVM builder and remember it so it can be freed later.
1549 static LLVMBuilderRef
1550 create_builder (EmitContext *ctx)
1552 LLVMBuilderRef builder = LLVMCreateBuilder ();
1554 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1560 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1565 case MONO_PATCH_INFO_INTERNAL_METHOD:
1566 name = g_strdup_printf ("jit_icall_%s", data);
1568 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1569 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1570 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1574 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1582 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1586 LLVMValueRef indexes [2];
1588 LLVMValueRef got_entry_addr, load;
1589 LLVMBuilderRef builder = ctx->builder;
1594 ji = g_new0 (MonoJumpInfo, 1);
1596 ji->data.target = data;
1598 ji = mono_aot_patch_info_dup (ji);
1600 ji->next = cfg->patch_info;
1601 cfg->patch_info = ji;
1603 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1604 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1606 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1607 * explicitly initialize it.
1609 if (!mono_aot_is_shared_got_offset (got_offset)) {
1610 //mono_print_ji (ji);
1612 ctx->has_got_access = TRUE;
1615 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1616 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1617 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1619 name = get_aotconst_name (type, data, got_offset);
1621 load = LLVMBuildLoad (builder, got_entry_addr, "");
1622 load = convert (ctx, load, llvm_type);
1623 LLVMSetValueName (load, name ? name : "");
1625 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1628 //set_invariant_load_flag (load);
1634 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1636 return get_aotconst_typed (ctx, type, data, NULL);
1640 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1642 LLVMValueRef callee;
1644 if (ctx->llvm_only) {
1645 callee_name = mono_aot_get_direct_call_symbol (type, data);
1647 /* Directly callable */
1649 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1651 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1653 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1655 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1657 /* LLVMTypeRef's are uniqued */
1658 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1659 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1661 g_free (callee_name);
1667 * Calls are made through the GOT.
1669 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1671 MonoJumpInfo *ji = NULL;
1673 callee_name = mono_aot_get_plt_symbol (type, data);
1677 if (ctx->cfg->compile_aot)
1678 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1679 mono_add_patch_info (ctx->cfg, 0, type, data);
1682 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1684 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1686 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1688 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1691 if (ctx->cfg->compile_aot) {
1692 ji = g_new0 (MonoJumpInfo, 1);
1694 ji->data.target = data;
1696 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1704 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1706 #if LLVM_API_VERSION > 100
1707 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1708 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1709 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1710 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1713 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1714 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1720 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1722 MonoMethodHeader *header = cfg->header;
1723 MonoExceptionClause *clause;
1727 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1728 return (bb->region >> 8) - 1;
1731 for (i = 0; i < header->num_clauses; ++i) {
1732 clause = &header->clauses [i];
1734 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1741 static MonoExceptionClause *
1742 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1744 // Since they're sorted by nesting we just need
1745 // the first one that the bb is a member of
1746 MonoExceptionClause *last = NULL;
1748 for (int i = 0; i < cfg->header->num_clauses; i++) {
1749 MonoExceptionClause *curr = &cfg->header->clauses [i];
1751 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1754 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1755 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1769 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1771 LLVMValueRef md_arg;
1774 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1775 md_arg = LLVMMDString ("mono", 4);
1776 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1780 set_invariant_load_flag (LLVMValueRef v)
1782 LLVMValueRef md_arg;
1784 const char *flag_name;
1786 // FIXME: Cache this
1787 flag_name = "invariant.load";
1788 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1789 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1790 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1796 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1800 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1802 MonoCompile *cfg = ctx->cfg;
1803 LLVMValueRef lcall = NULL;
1804 LLVMBuilderRef builder = *builder_ref;
1805 MonoExceptionClause *clause;
1807 if (ctx->llvm_only) {
1808 clause = get_most_deep_clause (cfg, ctx, bb);
1811 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1814 * Have to use an invoke instead of a call, branching to the
1815 * handler bblock of the clause containing this bblock.
1817 intptr_t key = CLAUSE_END(clause);
1819 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1821 // FIXME: Find the one that has the lowest end bound for the right start address
1822 // FIXME: Finally + nesting
1825 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1828 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1830 builder = ctx->builder = create_builder (ctx);
1831 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1833 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1837 int clause_index = get_handler_clause (cfg, bb);
1839 if (clause_index != -1) {
1840 MonoMethodHeader *header = cfg->header;
1841 MonoExceptionClause *ec = &header->clauses [clause_index];
1842 MonoBasicBlock *tblock;
1843 LLVMBasicBlockRef ex_bb, noex_bb;
1846 * Have to use an invoke instead of a call, branching to the
1847 * handler bblock of the clause containing this bblock.
1850 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1852 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1855 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1857 ex_bb = get_bb (ctx, tblock);
1859 noex_bb = gen_bb (ctx, "NOEX_BB");
1862 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1864 builder = ctx->builder = create_builder (ctx);
1865 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1867 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1872 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1873 ctx->builder = builder;
1877 *builder_ref = ctx->builder;
1883 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1885 const char *intrins_name;
1886 LLVMValueRef args [16], res;
1887 LLVMTypeRef addr_type;
1888 gboolean use_intrinsics = TRUE;
1890 #if LLVM_API_VERSION > 100
1891 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1892 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1893 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1894 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1895 *builder_ref = ctx->builder;
1896 use_intrinsics = FALSE;
1900 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1901 LLVMAtomicOrdering ordering;
1904 case LLVM_BARRIER_NONE:
1905 ordering = LLVMAtomicOrderingNotAtomic;
1907 case LLVM_BARRIER_ACQ:
1908 ordering = LLVMAtomicOrderingAcquire;
1910 case LLVM_BARRIER_SEQ:
1911 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1914 g_assert_not_reached ();
1919 * We handle loads which can fault by calling a mono specific intrinsic
1920 * using an invoke, so they are handled properly inside try blocks.
1921 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1922 * are marked with IntrReadArgMem.
1926 intrins_name = "llvm.mono.load.i8.p0i8";
1929 intrins_name = "llvm.mono.load.i16.p0i16";
1932 intrins_name = "llvm.mono.load.i32.p0i32";
1935 intrins_name = "llvm.mono.load.i64.p0i64";
1938 g_assert_not_reached ();
1941 addr_type = LLVMTypeOf (addr);
1942 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1943 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1946 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1947 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1948 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1949 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1951 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1952 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1953 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1954 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1961 * We emit volatile loads for loads which can fault, because otherwise
1962 * LLVM will generate invalid code when encountering a load from a
1965 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1967 /* Mark it with a custom metadata */
1970 set_metadata_flag (res, "mono.faulting.load");
1978 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1980 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1984 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1986 const char *intrins_name;
1987 LLVMValueRef args [16];
1988 gboolean use_intrinsics = TRUE;
1990 #if LLVM_API_VERSION > 100
1991 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1992 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1993 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1994 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1995 *builder_ref = ctx->builder;
1996 use_intrinsics = FALSE;
2000 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2001 LLVMAtomicOrdering ordering;
2004 case LLVM_BARRIER_NONE:
2005 ordering = LLVMAtomicOrderingNotAtomic;
2007 case LLVM_BARRIER_REL:
2008 ordering = LLVMAtomicOrderingRelease;
2010 case LLVM_BARRIER_SEQ:
2011 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2014 g_assert_not_reached ();
2020 intrins_name = "llvm.mono.store.i8.p0i8";
2023 intrins_name = "llvm.mono.store.i16.p0i16";
2026 intrins_name = "llvm.mono.store.i32.p0i32";
2029 intrins_name = "llvm.mono.store.i64.p0i64";
2032 g_assert_not_reached ();
2035 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2036 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2037 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2042 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2043 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2044 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2045 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2047 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2052 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2054 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2058 * emit_cond_system_exception:
2060 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2061 * Might set the ctx exception.
2064 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2066 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2067 LLVMBuilderRef builder;
2068 MonoClass *exc_class;
2069 LLVMValueRef args [2];
2070 LLVMValueRef callee;
2072 ex_bb = gen_bb (ctx, "EX_BB");
2074 ex2_bb = gen_bb (ctx, "EX2_BB");
2075 noex_bb = gen_bb (ctx, "NOEX_BB");
2077 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2079 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2081 /* Emit exception throwing code */
2082 ctx->builder = builder = create_builder (ctx);
2083 LLVMPositionBuilderAtEnd (builder, ex_bb);
2085 if (ctx->cfg->llvm_only) {
2086 static LLVMTypeRef sig;
2089 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2090 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2092 LLVMBuildBr (builder, ex2_bb);
2094 ctx->builder = builder = create_builder (ctx);
2095 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2097 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2098 emit_call (ctx, bb, &builder, callee, args, 1);
2099 LLVMBuildUnreachable (builder);
2101 ctx->builder = builder = create_builder (ctx);
2102 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2104 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2110 callee = ctx->module->throw_corlib_exception;
2113 const char *icall_name;
2115 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2116 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2118 if (ctx->cfg->compile_aot) {
2119 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2122 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2123 * - On x86, LLVM generated code doesn't push the arguments
2124 * - The trampoline takes the throw address as an arguments, not a pc offset.
2126 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2127 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2129 #if LLVM_API_VERSION > 100
2131 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2132 * added by emit_jit_callee ().
2134 ex2_bb = gen_bb (ctx, "EX2_BB");
2135 LLVMBuildBr (builder, ex2_bb);
2138 ctx->builder = builder = create_builder (ctx);
2139 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2141 mono_memory_barrier ();
2142 ctx->module->throw_corlib_exception = callee;
2147 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2150 * The LLVM mono branch contains changes so a block address can be passed as an
2151 * argument to a call.
2153 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2154 emit_call (ctx, bb, &builder, callee, args, 2);
2156 LLVMBuildUnreachable (builder);
2158 ctx->builder = builder = create_builder (ctx);
2159 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2161 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2168 * emit_args_to_vtype:
2170 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2173 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2175 int j, size, nslots;
2177 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2179 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2180 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2183 if (ainfo->storage == LLVMArgAsFpArgs)
2184 nslots = ainfo->nslots;
2188 for (j = 0; j < nslots; ++j) {
2189 LLVMValueRef index [2], addr, daddr;
2190 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2191 LLVMTypeRef part_type;
2193 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2196 if (ainfo->pair_storage [j] == LLVMArgNone)
2199 switch (ainfo->pair_storage [j]) {
2200 case LLVMArgInIReg: {
2201 part_type = LLVMIntType (part_size * 8);
2202 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2203 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2204 addr = LLVMBuildGEP (builder, address, index, 1, "");
2206 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2207 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2208 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2210 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2213 case LLVMArgInFPReg: {
2214 LLVMTypeRef arg_type;
2216 if (ainfo->esize == 8)
2217 arg_type = LLVMDoubleType ();
2219 arg_type = LLVMFloatType ();
2221 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2222 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2223 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2224 LLVMBuildStore (builder, args [j], addr);
2230 g_assert_not_reached ();
2233 size -= sizeof (gpointer);
2238 * emit_vtype_to_args:
2240 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2241 * into ARGS, and the number of arguments into NARGS.
2244 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2247 int j, size, nslots;
2248 LLVMTypeRef arg_type;
2250 size = get_vtype_size (t);
2252 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2253 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2255 if (ainfo->storage == LLVMArgAsFpArgs)
2256 nslots = ainfo->nslots;
2259 for (j = 0; j < nslots; ++j) {
2260 LLVMValueRef index [2], addr, daddr;
2261 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2263 if (ainfo->pair_storage [j] == LLVMArgNone)
2266 switch (ainfo->pair_storage [j]) {
2268 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2269 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2270 addr = LLVMBuildGEP (builder, address, index, 1, "");
2272 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2273 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2274 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2276 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2278 case LLVMArgInFPReg:
2279 if (ainfo->esize == 8)
2280 arg_type = LLVMDoubleType ();
2282 arg_type = LLVMFloatType ();
2283 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2284 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2285 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2286 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2291 g_assert_not_reached ();
2293 size -= sizeof (gpointer);
2300 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2303 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2304 * get executed every time control reaches them.
2306 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2308 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2309 return ctx->last_alloca;
2313 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2315 return build_alloca_llvm_type_name (ctx, t, align, "");
2319 build_alloca (EmitContext *ctx, MonoType *t)
2321 MonoClass *k = mono_class_from_mono_type (t);
2324 g_assert (!mini_is_gsharedvt_variable_type (t));
2326 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2329 align = mono_class_min_align (k);
2331 /* Sometimes align is not a power of 2 */
2332 while (mono_is_power_of_two (align) == -1)
2335 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2339 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2343 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2345 MonoCompile *cfg = ctx->cfg;
2346 LLVMBuilderRef builder = ctx->builder;
2347 LLVMValueRef offset, offset_var;
2348 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2349 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2353 g_assert (info_var);
2354 g_assert (locals_var);
2356 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2358 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2359 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2361 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2362 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2364 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2368 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2371 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2374 module->used = g_ptr_array_sized_new (16);
2375 g_ptr_array_add (module->used, global);
2379 emit_llvm_used (MonoLLVMModule *module)
2381 LLVMModuleRef lmodule = module->lmodule;
2382 LLVMTypeRef used_type;
2383 LLVMValueRef used, *used_elem;
2389 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2390 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2391 used_elem = g_new0 (LLVMValueRef, module->used->len);
2392 for (i = 0; i < module->used->len; ++i)
2393 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2394 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2395 LLVMSetLinkage (used, LLVMAppendingLinkage);
2396 LLVMSetSection (used, "llvm.metadata");
2402 * Emit a function mapping method indexes to their code
2405 emit_get_method (MonoLLVMModule *module)
2407 LLVMModuleRef lmodule = module->lmodule;
2408 LLVMValueRef func, switch_ins, m;
2409 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2410 LLVMBasicBlockRef *bbs;
2412 LLVMBuilderRef builder;
2417 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2418 * but generating code seems safer.
2420 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2421 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2422 LLVMSetLinkage (func, LLVMExternalLinkage);
2423 LLVMSetVisibility (func, LLVMHiddenVisibility);
2424 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2425 module->get_method = func;
2427 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2430 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2431 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2432 * then we will have to find another solution.
2435 name = g_strdup_printf ("BB_CODE_START");
2436 code_start_bb = LLVMAppendBasicBlock (func, name);
2438 builder = LLVMCreateBuilder ();
2439 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2440 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2442 name = g_strdup_printf ("BB_CODE_END");
2443 code_end_bb = LLVMAppendBasicBlock (func, name);
2445 builder = LLVMCreateBuilder ();
2446 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2447 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2449 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2450 for (i = 0; i < module->max_method_idx + 1; ++i) {
2451 name = g_strdup_printf ("BB_%d", i);
2452 bb = LLVMAppendBasicBlock (func, name);
2456 builder = LLVMCreateBuilder ();
2457 LLVMPositionBuilderAtEnd (builder, bb);
2459 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2461 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2463 LLVMBuildRet (builder, LLVMConstNull (rtype));
2466 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2467 builder = LLVMCreateBuilder ();
2468 LLVMPositionBuilderAtEnd (builder, fail_bb);
2469 LLVMBuildRet (builder, LLVMConstNull (rtype));
2471 builder = LLVMCreateBuilder ();
2472 LLVMPositionBuilderAtEnd (builder, entry_bb);
2474 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2475 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2476 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2477 for (i = 0; i < module->max_method_idx + 1; ++i) {
2478 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2481 mark_as_used (module, func);
2485 * emit_get_unbox_tramp:
2487 * Emit a function mapping method indexes to their unbox trampoline
2490 emit_get_unbox_tramp (MonoLLVMModule *module)
2492 LLVMModuleRef lmodule = module->lmodule;
2493 LLVMValueRef func, switch_ins, m;
2494 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2495 LLVMBasicBlockRef *bbs;
2497 LLVMBuilderRef builder;
2501 /* Similar to emit_get_method () */
2503 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2504 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2505 LLVMSetLinkage (func, LLVMExternalLinkage);
2506 LLVMSetVisibility (func, LLVMHiddenVisibility);
2507 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2508 module->get_unbox_tramp = func;
2510 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2512 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2513 for (i = 0; i < module->max_method_idx + 1; ++i) {
2514 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2518 name = g_strdup_printf ("BB_%d", i);
2519 bb = LLVMAppendBasicBlock (func, name);
2523 builder = LLVMCreateBuilder ();
2524 LLVMPositionBuilderAtEnd (builder, bb);
2526 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2529 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2530 builder = LLVMCreateBuilder ();
2531 LLVMPositionBuilderAtEnd (builder, fail_bb);
2532 LLVMBuildRet (builder, LLVMConstNull (rtype));
2534 builder = LLVMCreateBuilder ();
2535 LLVMPositionBuilderAtEnd (builder, entry_bb);
2537 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2538 for (i = 0; i < module->max_method_idx + 1; ++i) {
2539 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2543 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2546 mark_as_used (module, func);
2549 /* Add a function to mark the beginning of LLVM code */
2551 emit_llvm_code_start (MonoLLVMModule *module)
2553 LLVMModuleRef lmodule = module->lmodule;
2555 LLVMBasicBlockRef entry_bb;
2556 LLVMBuilderRef builder;
2558 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2559 LLVMSetLinkage (func, LLVMInternalLinkage);
2560 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2561 module->code_start = func;
2562 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2563 builder = LLVMCreateBuilder ();
2564 LLVMPositionBuilderAtEnd (builder, entry_bb);
2565 LLVMBuildRetVoid (builder);
2569 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2571 LLVMModuleRef lmodule = module->lmodule;
2572 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2573 LLVMBasicBlockRef entry_bb;
2574 LLVMBuilderRef builder;
2581 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2582 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2587 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2588 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2591 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2592 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2595 g_assert_not_reached ();
2597 LLVMSetLinkage (func, LLVMInternalLinkage);
2598 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2599 mono_llvm_set_preserveall_cc (func);
2600 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2601 builder = LLVMCreateBuilder ();
2602 LLVMPositionBuilderAtEnd (builder, entry_bb);
2605 ji = g_new0 (MonoJumpInfo, 1);
2606 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2607 ji = mono_aot_patch_info_dup (ji);
2608 got_offset = mono_aot_get_got_offset (ji);
2609 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2610 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2611 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2612 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2613 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2614 args [1] = LLVMGetParam (func, 0);
2616 args [2] = LLVMGetParam (func, 1);
2618 ji = g_new0 (MonoJumpInfo, 1);
2619 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2620 ji->data.name = icall_name;
2621 ji = mono_aot_patch_info_dup (ji);
2622 got_offset = mono_aot_get_got_offset (ji);
2623 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2624 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2625 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2626 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2627 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2628 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2629 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2631 // Set the inited flag
2632 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2633 indexes [1] = LLVMGetParam (func, 0);
2634 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2636 LLVMBuildRetVoid (builder);
2638 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2643 * Emit wrappers around the C icalls used to initialize llvm methods, to
2644 * make the calling code smaller and to enable usage of the llvm
2645 * PreserveAll calling convention.
2648 emit_init_icall_wrappers (MonoLLVMModule *module)
2650 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2651 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2652 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2653 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2657 emit_llvm_code_end (MonoLLVMModule *module)
2659 LLVMModuleRef lmodule = module->lmodule;
2661 LLVMBasicBlockRef entry_bb;
2662 LLVMBuilderRef builder;
2664 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2665 LLVMSetLinkage (func, LLVMInternalLinkage);
2666 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2667 module->code_end = func;
2668 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2669 builder = LLVMCreateBuilder ();
2670 LLVMPositionBuilderAtEnd (builder, entry_bb);
2671 LLVMBuildRetVoid (builder);
2675 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2677 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2680 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2681 need_div_check = TRUE;
2683 if (!need_div_check)
2686 switch (ins->opcode) {
2699 case OP_IDIV_UN_IMM:
2700 case OP_LDIV_UN_IMM:
2701 case OP_IREM_UN_IMM:
2702 case OP_LREM_UN_IMM: {
2704 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2705 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2707 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2708 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2711 builder = ctx->builder;
2713 /* b == -1 && a == 0x80000000 */
2715 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2716 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2717 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2719 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2720 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2723 builder = ctx->builder;
2735 * Emit code to initialize the GOT slots used by the method.
2738 emit_init_method (EmitContext *ctx)
2740 LLVMValueRef indexes [16], args [16], callee;
2741 LLVMValueRef inited_var, cmp, call;
2742 LLVMBasicBlockRef inited_bb, notinited_bb;
2743 LLVMBuilderRef builder = ctx->builder;
2744 MonoCompile *cfg = ctx->cfg;
2746 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2748 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2749 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2750 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2752 args [0] = inited_var;
2753 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2754 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2756 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2758 inited_bb = ctx->inited_bb;
2759 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2761 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2763 builder = ctx->builder = create_builder (ctx);
2764 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2767 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2768 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2769 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2770 callee = ctx->module->init_method_gshared_mrgctx;
2771 call = LLVMBuildCall (builder, callee, args, 2, "");
2772 } else if (ctx->rgctx_arg) {
2773 /* A vtable is passed as the rgctx argument */
2774 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2775 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2776 callee = ctx->module->init_method_gshared_vtable;
2777 call = LLVMBuildCall (builder, callee, args, 2, "");
2778 } else if (cfg->gshared) {
2779 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2780 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2781 callee = ctx->module->init_method_gshared_this;
2782 call = LLVMBuildCall (builder, callee, args, 2, "");
2784 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2785 callee = ctx->module->init_method;
2786 call = LLVMBuildCall (builder, callee, args, 1, "");
2790 * This enables llvm to keep arguments in their original registers/
2791 * scratch registers, since the call will not clobber them.
2793 mono_llvm_set_call_preserveall_cc (call);
2795 LLVMBuildBr (builder, inited_bb);
2796 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2798 builder = ctx->builder = create_builder (ctx);
2799 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2803 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2806 * Emit unbox trampoline using a tail call
2808 LLVMValueRef tramp, call, *args;
2809 LLVMBuilderRef builder;
2810 LLVMBasicBlockRef lbb;
2811 LLVMCallInfo *linfo;
2815 tramp_name = g_strdup_printf ("ut_%s", method_name);
2816 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2817 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2818 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2819 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2821 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2822 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2823 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2824 if (ctx->cfg->vret_addr) {
2825 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2826 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2827 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2828 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2832 lbb = LLVMAppendBasicBlock (tramp, "");
2833 builder = LLVMCreateBuilder ();
2834 LLVMPositionBuilderAtEnd (builder, lbb);
2836 nargs = LLVMCountParamTypes (method_type);
2837 args = g_new0 (LLVMValueRef, nargs);
2838 for (i = 0; i < nargs; ++i) {
2839 args [i] = LLVMGetParam (tramp, i);
2840 if (i == ctx->this_arg_pindex) {
2841 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2843 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2844 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2845 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2848 call = LLVMBuildCall (builder, method, args, nargs, "");
2849 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2850 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2851 if (linfo->ret.storage == LLVMArgVtypeByRef)
2852 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2854 // FIXME: This causes assertions in clang
2855 //mono_llvm_set_must_tail (call);
2856 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2857 LLVMBuildRetVoid (builder);
2859 LLVMBuildRet (builder, call);
2861 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2867 * Emit code to load/convert arguments.
2870 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2873 MonoCompile *cfg = ctx->cfg;
2874 MonoMethodSignature *sig = ctx->sig;
2875 LLVMCallInfo *linfo = ctx->linfo;
2879 LLVMBuilderRef old_builder = ctx->builder;
2880 ctx->builder = builder;
2882 ctx->alloca_builder = create_builder (ctx);
2885 * Handle indirect/volatile variables by allocating memory for them
2886 * using 'alloca', and storing their address in a temporary.
2888 for (i = 0; i < cfg->num_varinfo; ++i) {
2889 MonoInst *var = cfg->varinfo [i];
2892 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2893 } 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))) {
2894 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2897 /* Could be already created by an OP_VPHI */
2898 if (!ctx->addresses [var->dreg]) {
2899 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2900 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2902 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2906 names = g_new (char *, sig->param_count);
2907 mono_method_get_param_names (cfg->method, (const char **) names);
2909 for (i = 0; i < sig->param_count; ++i) {
2910 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2911 int reg = cfg->args [i + sig->hasthis]->dreg;
2914 pindex = ainfo->pindex;
2916 switch (ainfo->storage) {
2917 case LLVMArgVtypeInReg:
2918 case LLVMArgAsFpArgs: {
2919 LLVMValueRef args [8];
2922 pindex += ainfo->ndummy_fpargs;
2924 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2925 memset (args, 0, sizeof (args));
2926 if (ainfo->storage == LLVMArgVtypeInReg) {
2927 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2928 if (ainfo->pair_storage [1] != LLVMArgNone)
2929 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2931 g_assert (ainfo->nslots <= 8);
2932 for (j = 0; j < ainfo->nslots; ++j)
2933 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2935 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2937 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2939 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2940 /* Treat these as normal values */
2941 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2945 case LLVMArgVtypeByVal: {
2946 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2948 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2949 /* Treat these as normal values */
2950 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2954 case LLVMArgVtypeByRef: {
2955 /* The argument is passed by ref */
2956 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2959 case LLVMArgAsIArgs: {
2960 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2963 /* The argument is received as an array of ints, store it into the real argument */
2964 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2966 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2967 if (size < SIZEOF_VOID_P) {
2968 /* The upper bits of the registers might not be valid */
2969 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2970 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2971 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2973 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2977 case LLVMArgVtypeAsScalar:
2978 g_assert_not_reached ();
2980 case LLVMArgGsharedvtFixed: {
2981 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2982 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2985 name = g_strdup_printf ("arg_%s", names [i]);
2987 name = g_strdup_printf ("arg_%d", i);
2989 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2992 case LLVMArgGsharedvtFixedVtype: {
2993 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2996 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2998 name = g_strdup_printf ("vtype_arg_%d", i);
3000 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3001 g_assert (ctx->addresses [reg]);
3002 LLVMSetValueName (ctx->addresses [reg], name);
3003 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3006 case LLVMArgGsharedvtVariable:
3007 /* The IR treats these as variables with addresses */
3008 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3011 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));
3018 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3020 emit_volatile_store (ctx, cfg->args [0]->dreg);
3021 for (i = 0; i < sig->param_count; ++i)
3022 if (!mini_type_is_vtype (sig->params [i]))
3023 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3025 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3026 LLVMValueRef this_alloc;
3029 * The exception handling code needs the location where the this argument was
3030 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3031 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3032 * location into the LSDA.
3034 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3035 /* This volatile store will keep the alloca alive */
3036 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3038 set_metadata_flag (this_alloc, "mono.this");
3041 if (cfg->rgctx_var) {
3042 LLVMValueRef rgctx_alloc, store;
3045 * We handle the rgctx arg similarly to the this pointer.
3047 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3048 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3049 /* This volatile store will keep the alloca alive */
3050 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3052 set_metadata_flag (rgctx_alloc, "mono.this");
3055 /* Initialize the method if needed */
3056 if (cfg->compile_aot && ctx->llvm_only) {
3057 /* Emit a location for the initialization code */
3058 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3059 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3061 LLVMBuildBr (ctx->builder, ctx->init_bb);
3062 builder = ctx->builder = create_builder (ctx);
3063 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3064 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3067 /* Compute nesting between clauses */
3068 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3069 for (i = 0; i < cfg->header->num_clauses; ++i) {
3070 for (j = 0; j < cfg->header->num_clauses; ++j) {
3071 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3072 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3074 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3075 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3080 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3081 * it needs to continue normally, or return back to the exception handling system.
3083 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3087 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3090 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3091 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3092 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3094 if (bb->in_scount == 0) {
3097 sprintf (name, "finally_ind_bb%d", bb->block_num);
3098 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3099 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3101 ctx->bblocks [bb->block_num].finally_ind = val;
3103 /* Create a variable to hold the exception var */
3105 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3109 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3110 * LLVM bblock containing a landing pad causes problems for the
3111 * LLVM optimizer passes.
3113 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3114 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3116 ctx->builder = old_builder;
3120 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3122 MonoCompile *cfg = ctx->cfg;
3123 LLVMValueRef *values = ctx->values;
3124 LLVMValueRef *addresses = ctx->addresses;
3125 MonoCallInst *call = (MonoCallInst*)ins;
3126 MonoMethodSignature *sig = call->signature;
3127 LLVMValueRef callee = NULL, lcall;
3129 LLVMCallInfo *cinfo;
3133 LLVMTypeRef llvm_sig;
3135 gboolean is_virtual, calli, preserveall;
3136 LLVMBuilderRef builder = *builder_ref;
3138 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3139 set_failure (ctx, "non-default callconv");
3143 cinfo = call->cinfo;
3145 if (call->rgctx_arg_reg)
3146 cinfo->rgctx_arg = TRUE;
3147 if (call->imt_arg_reg)
3148 cinfo->imt_arg = TRUE;
3150 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3152 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3156 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);
3157 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);
3159 preserveall = FALSE;
3161 /* FIXME: Avoid creating duplicate methods */
3163 if (ins->flags & MONO_INST_HAS_METHOD) {
3167 if (cfg->compile_aot) {
3168 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3170 set_failure (ctx, "can't encode patch");
3173 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3175 * Collect instructions representing the callee into a hash so they can be replaced
3176 * by the llvm method for the callee if the callee turns out to be direct
3177 * callable. Currently this only requires it to not fail llvm compilation.
3179 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3180 l = g_slist_prepend (l, callee);
3181 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3185 static int tramp_index;
3188 name = g_strdup_printf ("tramp_%d", tramp_index);
3191 #if LLVM_API_VERSION > 100
3193 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3194 * Make all calls through a global. The address of the global will be saved in
3195 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3198 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3201 mono_create_jit_trampoline (mono_domain_get (),
3202 call->method, &error);
3203 if (!mono_error_ok (&error))
3204 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3205 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3206 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3207 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3208 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3210 callee = LLVMBuildLoad (builder, tramp_var, "");
3213 mono_create_jit_trampoline (mono_domain_get (),
3214 call->method, &error);
3215 if (!mono_error_ok (&error))
3216 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3218 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3221 if (!mono_error_ok (&error))
3222 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3223 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3228 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3229 /* LLVM miscompiles async methods */
3230 set_failure (ctx, "#13734");
3235 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3241 memset (&ji, 0, sizeof (ji));
3242 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3243 ji.data.target = info->name;
3245 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3247 if (cfg->compile_aot) {
3248 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3250 set_failure (ctx, "can't encode patch");
3254 target = (gpointer)mono_icall_get_wrapper (info);
3255 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3258 if (cfg->compile_aot) {
3260 if (cfg->abs_patches) {
3261 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3263 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3265 set_failure (ctx, "can't encode patch");
3271 set_failure (ctx, "aot");
3275 #if LLVM_API_VERSION > 100
3276 if (cfg->abs_patches) {
3277 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3281 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3282 mono_error_assert_ok (&error);
3283 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3285 g_assert_not_reached ();
3288 g_assert_not_reached ();
3291 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3293 if (cfg->abs_patches) {
3294 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3299 * FIXME: Some trampolines might have
3300 * their own calling convention on some platforms.
3302 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3303 mono_error_assert_ok (&error);
3304 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3308 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3315 int size = sizeof (gpointer);
3318 g_assert (ins->inst_offset % size == 0);
3319 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3321 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3323 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3325 if (ins->flags & MONO_INST_HAS_METHOD) {
3330 * Collect and convert arguments
3332 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3333 len = sizeof (LLVMValueRef) * nargs;
3334 args = (LLVMValueRef*)alloca (len);
3335 memset (args, 0, len);
3336 l = call->out_ireg_args;
3338 if (call->rgctx_arg_reg) {
3339 g_assert (values [call->rgctx_arg_reg]);
3340 g_assert (cinfo->rgctx_arg_pindex < nargs);
3342 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3343 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3344 * it using a volatile load.
3347 if (!ctx->imt_rgctx_loc)
3348 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3349 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3350 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3352 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3355 if (call->imt_arg_reg) {
3356 g_assert (!ctx->llvm_only);
3357 g_assert (values [call->imt_arg_reg]);
3358 g_assert (cinfo->imt_arg_pindex < nargs);
3360 if (!ctx->imt_rgctx_loc)
3361 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3362 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3363 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3365 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3368 switch (cinfo->ret.storage) {
3369 case LLVMArgGsharedvtVariable: {
3370 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3372 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3373 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3375 g_assert (addresses [call->inst.dreg]);
3376 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3382 if (!addresses [call->inst.dreg])
3383 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3384 g_assert (cinfo->vret_arg_pindex < nargs);
3385 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3386 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3388 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3394 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3395 * use the real callee for argument type conversion.
3397 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3398 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3399 LLVMGetParamTypes (callee_type, param_types);
3401 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3404 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3406 pindex = ainfo->pindex;
3408 regpair = (guint32)(gssize)(l->data);
3409 reg = regpair & 0xffffff;
3410 args [pindex] = values [reg];
3411 switch (ainfo->storage) {
3412 case LLVMArgVtypeInReg:
3413 case LLVMArgAsFpArgs: {
3417 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3418 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3419 pindex += ainfo->ndummy_fpargs;
3421 g_assert (addresses [reg]);
3422 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3426 // FIXME: Get rid of the VMOVE
3429 case LLVMArgVtypeByVal:
3430 g_assert (addresses [reg]);
3431 args [pindex] = addresses [reg];
3433 case LLVMArgVtypeByRef: {
3434 g_assert (addresses [reg]);
3435 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3438 case LLVMArgAsIArgs:
3439 g_assert (addresses [reg]);
3440 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3442 case LLVMArgVtypeAsScalar:
3443 g_assert_not_reached ();
3445 case LLVMArgGsharedvtFixed:
3446 case LLVMArgGsharedvtFixedVtype:
3447 g_assert (addresses [reg]);
3448 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3450 case LLVMArgGsharedvtVariable:
3451 g_assert (addresses [reg]);
3452 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3455 g_assert (args [pindex]);
3456 if (i == 0 && sig->hasthis)
3457 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3459 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3462 g_assert (pindex <= nargs);
3467 // FIXME: Align call sites
3473 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3476 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3478 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3479 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3481 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3482 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3483 if (!sig->pinvoke && !cfg->llvm_only)
3484 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3486 mono_llvm_set_call_preserveall_cc (lcall);
3488 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3489 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3490 if (!ctx->llvm_only && call->rgctx_arg_reg)
3491 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3492 if (call->imt_arg_reg)
3493 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3495 /* Add byval attributes if needed */
3496 for (i = 0; i < sig->param_count; ++i) {
3497 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3499 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3500 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3504 * Convert the result
3506 switch (cinfo->ret.storage) {
3507 case LLVMArgVtypeInReg: {
3508 LLVMValueRef regs [2];
3510 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3514 if (!addresses [ins->dreg])
3515 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3517 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3518 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3519 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3520 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3523 case LLVMArgVtypeByVal:
3524 if (!addresses [call->inst.dreg])
3525 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3526 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3528 case LLVMArgFpStruct:
3529 if (!addresses [call->inst.dreg])
3530 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3531 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3533 case LLVMArgVtypeAsScalar:
3534 if (!addresses [call->inst.dreg])
3535 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3536 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3538 case LLVMArgVtypeRetAddr:
3539 case LLVMArgVtypeByRef:
3540 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3541 /* Some opcodes like STOREX_MEMBASE access these by value */
3542 g_assert (addresses [call->inst.dreg]);
3543 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3546 case LLVMArgGsharedvtVariable:
3548 case LLVMArgGsharedvtFixed:
3549 case LLVMArgGsharedvtFixedVtype:
3550 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3553 if (sig->ret->type != MONO_TYPE_VOID)
3554 /* If the method returns an unsigned value, need to zext it */
3555 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));
3559 *builder_ref = ctx->builder;
3563 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3565 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3566 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3568 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3571 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3573 if (ctx->cfg->compile_aot) {
3574 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3576 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3577 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3578 mono_memory_barrier ();
3581 ctx->module->rethrow = callee;
3583 ctx->module->throw_icall = callee;
3587 LLVMValueRef args [2];
3589 args [0] = convert (ctx, exc, exc_type);
3590 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3592 LLVMBuildUnreachable (ctx->builder);
3594 ctx->builder = create_builder (ctx);
3598 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3600 MonoMethodSignature *throw_sig;
3601 LLVMValueRef callee, arg;
3602 const char *icall_name;
3604 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3605 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3608 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3609 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3610 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3611 if (ctx->cfg->compile_aot) {
3612 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3617 * LLVM doesn't push the exception argument, so we need a different
3620 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3622 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3624 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3627 mono_memory_barrier ();
3628 #if LLVM_API_VERSION < 100
3630 ctx->module->rethrow = callee;
3632 ctx->module->throw_icall = callee;
3635 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3636 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3640 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3642 const char *icall_name = "mono_llvm_resume_exception";
3643 LLVMValueRef callee = ctx->module->resume_eh;
3645 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3648 if (ctx->cfg->compile_aot) {
3649 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3651 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3652 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3653 mono_memory_barrier ();
3655 ctx->module->resume_eh = callee;
3659 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3661 LLVMBuildUnreachable (ctx->builder);
3663 ctx->builder = create_builder (ctx);
3667 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3669 const char *icall_name = "mono_llvm_clear_exception";
3671 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3672 LLVMValueRef callee = NULL;
3675 if (ctx->cfg->compile_aot) {
3676 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3678 // FIXME: This is broken.
3679 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3683 g_assert (builder && callee);
3685 return LLVMBuildCall (builder, callee, NULL, 0, "");
3689 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3691 const char *icall_name = "mono_llvm_load_exception";
3693 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3694 LLVMValueRef callee = NULL;
3697 if (ctx->cfg->compile_aot) {
3698 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3700 // FIXME: This is broken.
3701 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3705 g_assert (builder && callee);
3707 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3712 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3714 const char *icall_name = "mono_llvm_match_exception";
3716 ctx->builder = builder;
3718 const int num_args = 5;
3719 LLVMValueRef args [num_args];
3720 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3721 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3722 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3723 if (ctx->cfg->rgctx_var) {
3724 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3725 g_assert (rgctx_alloc);
3726 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3728 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3731 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3733 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3735 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3736 LLVMValueRef callee = ctx->module->match_exc;
3739 if (ctx->cfg->compile_aot) {
3740 ctx->builder = builder;
3741 // get_callee expects ctx->builder to be the emitting builder
3742 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3744 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3745 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3746 ctx->module->match_exc = callee;
3747 mono_memory_barrier ();
3751 g_assert (builder && callee);
3753 g_assert (ctx->ex_var);
3755 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3758 // FIXME: This won't work because the code-finding makes this
3760 /*#define MONO_PERSONALITY_DEBUG*/
3762 #ifdef MONO_PERSONALITY_DEBUG
3763 static const gboolean use_debug_personality = TRUE;
3764 static const char *default_personality_name = "mono_debug_personality";
3766 static const gboolean use_debug_personality = FALSE;
3767 static const char *default_personality_name = "__gxx_personality_v0";
3771 default_cpp_lpad_exc_signature (void)
3773 static gboolean inited = FALSE;
3774 static LLVMTypeRef sig;
3777 LLVMTypeRef signature [2];
3778 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3779 signature [1] = LLVMInt32Type ();
3780 sig = LLVMStructType (signature, 2, FALSE);
3788 get_mono_personality (EmitContext *ctx)
3790 LLVMValueRef personality = NULL;
3791 static gint32 mapping_inited = FALSE;
3792 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3794 if (!use_debug_personality) {
3795 if (ctx->cfg->compile_aot) {
3796 personality = get_intrinsic (ctx, default_personality_name);
3797 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3798 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3799 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3802 if (ctx->cfg->compile_aot) {
3803 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3805 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3806 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3807 mono_memory_barrier ();
3811 g_assert (personality);
3815 static LLVMBasicBlockRef
3816 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3818 MonoCompile *cfg = ctx->cfg;
3819 LLVMBuilderRef old_builder = ctx->builder;
3820 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3822 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3823 ctx->builder = lpadBuilder;
3825 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3826 g_assert (handler_bb);
3828 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3829 LLVMValueRef personality = get_mono_personality (ctx);
3830 g_assert (personality);
3832 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3833 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3835 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3836 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3837 g_assert (landing_pad);
3839 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3840 LLVMAddClause (landing_pad, cast);
3842 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3843 LLVMBuilderRef resume_builder = create_builder (ctx);
3844 ctx->builder = resume_builder;
3845 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3847 emit_resume_eh (ctx, handler_bb);
3850 ctx->builder = lpadBuilder;
3851 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3853 gboolean finally_only = TRUE;
3855 MonoExceptionClause *group_cursor = group_start;
3857 for (int i = 0; i < group_size; i ++) {
3858 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3859 finally_only = FALSE;
3865 // Handle landing pad inlining
3867 if (!finally_only) {
3868 // So at each level of the exception stack we will match the exception again.
3869 // During that match, we need to compare against the handler types for the current
3870 // protected region. We send the try start and end so that we can only check against
3871 // handlers for this lexical protected region.
3872 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3874 // if returns -1, resume
3875 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3877 // else move to that target bb
3878 for (int i=0; i < group_size; i++) {
3879 MonoExceptionClause *clause = group_start + i;
3880 int clause_index = clause - cfg->header->clauses;
3881 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3882 g_assert (handler_bb);
3883 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3884 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3887 int clause_index = group_start - cfg->header->clauses;
3888 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3889 g_assert (finally_bb);
3891 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3894 ctx->builder = old_builder;
3901 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3903 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3904 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3906 // Make exception available to catch blocks
3907 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3908 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3910 g_assert (ctx->ex_var);
3911 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3913 if (bb->in_scount == 1) {
3914 MonoInst *exvar = bb->in_stack [0];
3915 g_assert (!ctx->values [exvar->dreg]);
3916 g_assert (ctx->ex_var);
3917 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3918 emit_volatile_store (ctx, exvar->dreg);
3921 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3924 LLVMBuilderRef handler_builder = create_builder (ctx);
3925 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3926 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3928 // Make the handler code end with a jump to cbb
3929 LLVMBuildBr (handler_builder, cbb);
3933 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3935 MonoCompile *cfg = ctx->cfg;
3936 LLVMValueRef *values = ctx->values;
3937 LLVMModuleRef lmodule = ctx->lmodule;
3938 BBInfo *bblocks = ctx->bblocks;
3940 LLVMValueRef personality;
3941 LLVMValueRef landing_pad;
3942 LLVMBasicBlockRef target_bb;
3944 static int ti_generator;
3946 LLVMValueRef type_info;
3950 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3952 if (cfg->compile_aot) {
3953 /* Use a dummy personality function */
3954 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3955 g_assert (personality);
3957 #if LLVM_API_VERSION > 100
3958 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3959 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3960 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3961 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3962 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3963 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3964 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3966 static gint32 mapping_inited;
3968 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3970 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3971 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3975 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3977 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3980 * Create the type info
3982 sprintf (ti_name, "type_info_%d", ti_generator);
3985 if (cfg->compile_aot) {
3986 /* decode_eh_frame () in aot-runtime.c will decode this */
3987 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3988 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3991 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3993 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3995 #if LLVM_API_VERSION > 100
3996 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3997 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4002 * After the cfg mempool is freed, the type info will point to stale memory,
4003 * but this is not a problem, since we decode it once in exception_cb during
4006 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4007 *(gint32*)ti = clause_index;
4009 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4011 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4016 LLVMTypeRef members [2], ret_type;
4018 members [0] = i8ptr;
4019 members [1] = LLVMInt32Type ();
4020 ret_type = LLVMStructType (members, 2, FALSE);
4022 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4023 LLVMAddClause (landing_pad, type_info);
4025 /* Store the exception into the exvar */
4027 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4031 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4032 * code expects control to be transferred to this landing pad even in the
4033 * presence of nested clauses. The landing pad needs to branch to the landing
4034 * pads belonging to nested clauses based on the selector value returned by
4035 * the landing pad instruction, which is passed to the landing pad in a
4036 * register by the EH code.
4038 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4039 g_assert (target_bb);
4042 * Branch to the correct landing pad
4044 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4045 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4047 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4048 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4049 MonoBasicBlock *handler_bb;
4051 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4052 g_assert (handler_bb);
4054 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4055 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4058 /* Start a new bblock which CALL_HANDLER can branch to */
4059 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4061 ctx->builder = builder = create_builder (ctx);
4062 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4064 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4066 /* Store the exception into the IL level exvar */
4067 if (bb->in_scount == 1) {
4068 g_assert (bb->in_scount == 1);
4069 exvar = bb->in_stack [0];
4071 // FIXME: This is shared with filter clauses ?
4072 g_assert (!values [exvar->dreg]);
4074 g_assert (ctx->ex_var);
4075 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4076 emit_volatile_store (ctx, exvar->dreg);
4082 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4084 MonoCompile *cfg = ctx->cfg;
4085 MonoMethodSignature *sig = ctx->sig;
4086 LLVMValueRef method = ctx->lmethod;
4087 LLVMValueRef *values = ctx->values;
4088 LLVMValueRef *addresses = ctx->addresses;
4089 LLVMCallInfo *linfo = ctx->linfo;
4090 BBInfo *bblocks = ctx->bblocks;
4092 LLVMBasicBlockRef cbb;
4093 LLVMBuilderRef builder, starting_builder;
4094 gboolean has_terminator;
4096 LLVMValueRef lhs, rhs;
4099 cbb = get_end_bb (ctx, bb);
4101 builder = create_builder (ctx);
4102 ctx->builder = builder;
4103 LLVMPositionBuilderAtEnd (builder, cbb);
4108 if (bb->flags & BB_EXCEPTION_HANDLER) {
4109 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4110 set_failure (ctx, "handler without invokes");
4115 emit_llvmonly_handler_start (ctx, bb, cbb);
4117 emit_handler_start (ctx, bb, builder);
4120 builder = ctx->builder;
4123 has_terminator = FALSE;
4124 starting_builder = builder;
4125 for (ins = bb->code; ins; ins = ins->next) {
4126 const char *spec = LLVM_INS_INFO (ins->opcode);
4128 char dname_buf [128];
4130 emit_dbg_loc (ctx, builder, ins->cil_code);
4135 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4136 * Start a new bblock. If the llvm optimization passes merge these, we
4137 * can work around that by doing a volatile load + cond branch from
4138 * localloc-ed memory.
4140 //set_failure (ctx, "basic block too long");
4141 cbb = gen_bb (ctx, "CONT_LONG_BB");
4142 LLVMBuildBr (ctx->builder, cbb);
4143 ctx->builder = builder = create_builder (ctx);
4144 LLVMPositionBuilderAtEnd (builder, cbb);
4145 ctx->bblocks [bb->block_num].end_bblock = cbb;
4150 /* There could be instructions after a terminator, skip them */
4153 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4154 sprintf (dname_buf, "t%d", ins->dreg);
4158 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4159 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4161 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4162 lhs = emit_volatile_load (ctx, ins->sreg1);
4164 /* It is ok for SETRET to have an uninitialized argument */
4165 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4166 set_failure (ctx, "sreg1");
4169 lhs = values [ins->sreg1];
4175 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4176 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4177 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4178 rhs = emit_volatile_load (ctx, ins->sreg2);
4180 if (!values [ins->sreg2]) {
4181 set_failure (ctx, "sreg2");
4184 rhs = values [ins->sreg2];
4190 //mono_print_ins (ins);
4191 switch (ins->opcode) {
4194 case OP_LIVERANGE_START:
4195 case OP_LIVERANGE_END:
4198 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4201 #if SIZEOF_VOID_P == 4
4202 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4204 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4208 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4212 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4214 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4216 case OP_DUMMY_ICONST:
4217 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4219 case OP_DUMMY_I8CONST:
4220 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4222 case OP_DUMMY_R8CONST:
4223 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4226 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4227 LLVMBuildBr (builder, target_bb);
4228 has_terminator = TRUE;
4235 LLVMBasicBlockRef new_bb;
4236 LLVMBuilderRef new_builder;
4238 // The default branch is already handled
4239 // FIXME: Handle it here
4241 /* Start new bblock */
4242 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4243 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4245 lhs = convert (ctx, lhs, LLVMInt32Type ());
4246 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4247 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4248 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4250 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4253 new_builder = create_builder (ctx);
4254 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4255 LLVMBuildUnreachable (new_builder);
4257 has_terminator = TRUE;
4258 g_assert (!ins->next);
4264 switch (linfo->ret.storage) {
4265 case LLVMArgVtypeInReg: {
4266 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4267 LLVMValueRef val, addr, retval;
4270 retval = LLVMGetUndef (ret_type);
4272 if (!addresses [ins->sreg1]) {
4274 * The return type is an LLVM vector type, have to convert between it and the
4275 * real return type which is a struct type.
4277 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4278 /* Convert to 2xi64 first */
4279 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4281 for (i = 0; i < 2; ++i) {
4282 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4283 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4285 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4289 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4290 for (i = 0; i < 2; ++i) {
4291 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4292 LLVMValueRef indexes [2], part_addr;
4294 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4295 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4296 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4298 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4300 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4304 LLVMBuildRet (builder, retval);
4307 case LLVMArgVtypeAsScalar: {
4308 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4309 LLVMValueRef retval;
4311 g_assert (addresses [ins->sreg1]);
4313 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4314 LLVMBuildRet (builder, retval);
4317 case LLVMArgVtypeByVal: {
4318 LLVMValueRef retval;
4320 g_assert (addresses [ins->sreg1]);
4321 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4322 LLVMBuildRet (builder, retval);
4325 case LLVMArgVtypeByRef: {
4326 LLVMBuildRetVoid (builder);
4329 case LLVMArgGsharedvtFixed: {
4330 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4331 /* The return value is in lhs, need to store to the vret argument */
4332 /* sreg1 might not be set */
4334 g_assert (cfg->vret_addr);
4335 g_assert (values [cfg->vret_addr->dreg]);
4336 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4338 LLVMBuildRetVoid (builder);
4341 case LLVMArgGsharedvtFixedVtype: {
4343 LLVMBuildRetVoid (builder);
4346 case LLVMArgGsharedvtVariable: {
4348 LLVMBuildRetVoid (builder);
4351 case LLVMArgVtypeRetAddr: {
4352 LLVMBuildRetVoid (builder);
4355 case LLVMArgFpStruct: {
4356 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4357 LLVMValueRef retval;
4359 g_assert (addresses [ins->sreg1]);
4360 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4361 LLVMBuildRet (builder, retval);
4365 case LLVMArgNormal: {
4366 if (!lhs || ctx->is_dead [ins->sreg1]) {
4368 * The method did not set its return value, probably because it
4369 * ends with a throw.
4372 LLVMBuildRetVoid (builder);
4374 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4376 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4378 has_terminator = TRUE;
4382 g_assert_not_reached ();
4391 case OP_ICOMPARE_IMM:
4392 case OP_LCOMPARE_IMM:
4393 case OP_COMPARE_IMM: {
4395 LLVMValueRef cmp, args [16];
4396 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4398 if (ins->next->opcode == OP_NOP)
4401 if (ins->next->opcode == OP_BR)
4402 /* The comparison result is not needed */
4405 rel = mono_opcode_to_cond (ins->next->opcode);
4407 if (ins->opcode == OP_ICOMPARE_IMM) {
4408 lhs = convert (ctx, lhs, LLVMInt32Type ());
4409 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4411 if (ins->opcode == OP_LCOMPARE_IMM) {
4412 lhs = convert (ctx, lhs, LLVMInt64Type ());
4413 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4415 if (ins->opcode == OP_LCOMPARE) {
4416 lhs = convert (ctx, lhs, LLVMInt64Type ());
4417 rhs = convert (ctx, rhs, LLVMInt64Type ());
4419 if (ins->opcode == OP_ICOMPARE) {
4420 lhs = convert (ctx, lhs, LLVMInt32Type ());
4421 rhs = convert (ctx, rhs, LLVMInt32Type ());
4425 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4426 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4427 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4428 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4431 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4432 if (ins->opcode == OP_FCOMPARE) {
4433 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4434 } else if (ins->opcode == OP_RCOMPARE) {
4435 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4436 } else if (ins->opcode == OP_COMPARE_IMM) {
4437 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4438 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4440 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4441 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4442 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4443 /* The immediate is encoded in two fields */
4444 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4445 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4447 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4450 else if (ins->opcode == OP_COMPARE) {
4451 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4452 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4454 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4456 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4460 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4461 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4464 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4465 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4467 * If the target bb contains PHI instructions, LLVM requires
4468 * two PHI entries for this bblock, while we only generate one.
4469 * So convert this to an unconditional bblock. (bxc #171).
4471 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4473 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4475 has_terminator = TRUE;
4476 } else if (MONO_IS_SETCC (ins->next)) {
4477 sprintf (dname_buf, "t%d", ins->next->dreg);
4479 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4481 /* Add stores for volatile variables */
4482 emit_volatile_store (ctx, ins->next->dreg);
4483 } else if (MONO_IS_COND_EXC (ins->next)) {
4484 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4487 builder = ctx->builder;
4489 set_failure (ctx, "next");
4507 rel = mono_opcode_to_cond (ins->opcode);
4509 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4510 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4521 rel = mono_opcode_to_cond (ins->opcode);
4523 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4524 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4532 gboolean empty = TRUE;
4534 /* Check that all input bblocks really branch to us */
4535 for (i = 0; i < bb->in_count; ++i) {
4536 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4537 ins->inst_phi_args [i + 1] = -1;
4543 /* LLVM doesn't like phi instructions with zero operands */
4544 ctx->is_dead [ins->dreg] = TRUE;
4548 /* Created earlier, insert it now */
4549 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4551 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4552 int sreg1 = ins->inst_phi_args [i + 1];
4556 * Count the number of times the incoming bblock branches to us,
4557 * since llvm requires a separate entry for each.
4559 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4560 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4563 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4564 if (switch_ins->inst_many_bb [j] == bb)
4571 /* Remember for later */
4572 for (j = 0; j < count; ++j) {
4573 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4576 node->in_bb = bb->in_bb [i];
4578 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);
4588 values [ins->dreg] = lhs;
4592 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4595 values [ins->dreg] = lhs;
4597 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4599 * This is added by the spilling pass in case of the JIT,
4600 * but we have to do it ourselves.
4602 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4606 case OP_MOVE_F_TO_I4: {
4607 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4610 case OP_MOVE_I4_TO_F: {
4611 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4614 case OP_MOVE_F_TO_I8: {
4615 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4618 case OP_MOVE_I8_TO_F: {
4619 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4652 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4653 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4655 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4658 builder = ctx->builder;
4660 switch (ins->opcode) {
4663 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4667 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4671 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4675 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4679 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4683 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4687 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4691 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4695 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4699 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4703 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4707 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4711 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4715 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4719 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4722 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4725 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4729 g_assert_not_reached ();
4736 lhs = convert (ctx, lhs, LLVMFloatType ());
4737 rhs = convert (ctx, rhs, LLVMFloatType ());
4738 switch (ins->opcode) {
4740 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4743 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4746 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4749 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4752 g_assert_not_reached ();
4761 case OP_IREM_UN_IMM:
4763 case OP_IDIV_UN_IMM:
4769 case OP_ISHR_UN_IMM:
4779 case OP_LSHR_UN_IMM:
4785 case OP_SHR_UN_IMM: {
4788 if (spec [MONO_INST_SRC1] == 'l') {
4789 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4791 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4794 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4797 builder = ctx->builder;
4799 #if SIZEOF_VOID_P == 4
4800 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4801 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4804 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4805 lhs = convert (ctx, lhs, IntPtrType ());
4806 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4807 switch (ins->opcode) {
4811 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4815 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4820 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4824 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4826 case OP_IDIV_UN_IMM:
4827 case OP_LDIV_UN_IMM:
4828 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4832 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4834 case OP_IREM_UN_IMM:
4835 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4840 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4844 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4848 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4853 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4858 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4860 case OP_ISHR_UN_IMM:
4861 /* This is used to implement conv.u4, so the lhs could be an i8 */
4862 lhs = convert (ctx, lhs, LLVMInt32Type ());
4863 imm = convert (ctx, imm, LLVMInt32Type ());
4864 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4866 case OP_LSHR_UN_IMM:
4868 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4871 g_assert_not_reached ();
4876 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4879 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4882 lhs = convert (ctx, lhs, LLVMDoubleType ());
4883 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4886 lhs = convert (ctx, lhs, LLVMFloatType ());
4887 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4890 guint32 v = 0xffffffff;
4891 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4895 guint64 v = 0xffffffffffffffffLL;
4896 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4899 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4901 LLVMValueRef v1, v2;
4903 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4904 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4905 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4910 case OP_ICONV_TO_I1:
4911 case OP_ICONV_TO_I2:
4912 case OP_ICONV_TO_I4:
4913 case OP_ICONV_TO_U1:
4914 case OP_ICONV_TO_U2:
4915 case OP_ICONV_TO_U4:
4916 case OP_LCONV_TO_I1:
4917 case OP_LCONV_TO_I2:
4918 case OP_LCONV_TO_U1:
4919 case OP_LCONV_TO_U2:
4920 case OP_LCONV_TO_U4: {
4923 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);
4925 /* Have to do two casts since our vregs have type int */
4926 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4928 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4930 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4933 case OP_ICONV_TO_I8:
4934 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4936 case OP_ICONV_TO_U8:
4937 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4939 case OP_FCONV_TO_I4:
4940 case OP_RCONV_TO_I4:
4941 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4943 case OP_FCONV_TO_I1:
4944 case OP_RCONV_TO_I1:
4945 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4947 case OP_FCONV_TO_U1:
4948 case OP_RCONV_TO_U1:
4949 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4951 case OP_FCONV_TO_I2:
4952 case OP_RCONV_TO_I2:
4953 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4955 case OP_FCONV_TO_U2:
4956 case OP_RCONV_TO_U2:
4957 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4959 case OP_RCONV_TO_U4:
4960 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4962 case OP_FCONV_TO_I8:
4963 case OP_RCONV_TO_I8:
4964 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4967 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4969 case OP_ICONV_TO_R8:
4970 case OP_LCONV_TO_R8:
4971 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4973 case OP_ICONV_TO_R_UN:
4974 case OP_LCONV_TO_R_UN:
4975 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4977 #if SIZEOF_VOID_P == 4
4980 case OP_LCONV_TO_I4:
4981 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4983 case OP_ICONV_TO_R4:
4984 case OP_LCONV_TO_R4:
4985 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4987 values [ins->dreg] = v;
4989 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4991 case OP_FCONV_TO_R4:
4992 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4994 values [ins->dreg] = v;
4996 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4998 case OP_RCONV_TO_R8:
4999 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5001 case OP_RCONV_TO_R4:
5002 values [ins->dreg] = lhs;
5005 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5008 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5011 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5013 case OP_LOCALLOC_IMM: {
5016 guint32 size = ins->inst_imm;
5017 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5019 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5021 if (ins->flags & MONO_INST_INIT) {
5022 LLVMValueRef args [5];
5025 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5026 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5027 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5028 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5029 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5032 values [ins->dreg] = v;
5036 LLVMValueRef v, size;
5038 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), "");
5040 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5042 if (ins->flags & MONO_INST_INIT) {
5043 LLVMValueRef args [5];
5046 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5048 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5049 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5050 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5052 values [ins->dreg] = v;
5056 case OP_LOADI1_MEMBASE:
5057 case OP_LOADU1_MEMBASE:
5058 case OP_LOADI2_MEMBASE:
5059 case OP_LOADU2_MEMBASE:
5060 case OP_LOADI4_MEMBASE:
5061 case OP_LOADU4_MEMBASE:
5062 case OP_LOADI8_MEMBASE:
5063 case OP_LOADR4_MEMBASE:
5064 case OP_LOADR8_MEMBASE:
5065 case OP_LOAD_MEMBASE:
5073 LLVMValueRef base, index, addr;
5075 gboolean sext = FALSE, zext = FALSE;
5076 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5078 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5083 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)) {
5084 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5089 if (ins->inst_offset == 0) {
5091 } else if (ins->inst_offset % size != 0) {
5092 /* Unaligned load */
5093 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5094 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5096 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5097 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5101 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5103 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5105 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5107 * These will signal LLVM that these loads do not alias any stores, and
5108 * they can't fail, allowing them to be hoisted out of loops.
5110 set_invariant_load_flag (values [ins->dreg]);
5111 #if LLVM_API_VERSION < 100
5112 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5117 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5119 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5120 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5121 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5125 case OP_STOREI1_MEMBASE_REG:
5126 case OP_STOREI2_MEMBASE_REG:
5127 case OP_STOREI4_MEMBASE_REG:
5128 case OP_STOREI8_MEMBASE_REG:
5129 case OP_STORER4_MEMBASE_REG:
5130 case OP_STORER8_MEMBASE_REG:
5131 case OP_STORE_MEMBASE_REG: {
5133 LLVMValueRef index, addr;
5135 gboolean sext = FALSE, zext = FALSE;
5136 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5138 if (!values [ins->inst_destbasereg]) {
5139 set_failure (ctx, "inst_destbasereg");
5143 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5145 if (ins->inst_offset % size != 0) {
5146 /* Unaligned store */
5147 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5148 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5150 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5151 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5153 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5157 case OP_STOREI1_MEMBASE_IMM:
5158 case OP_STOREI2_MEMBASE_IMM:
5159 case OP_STOREI4_MEMBASE_IMM:
5160 case OP_STOREI8_MEMBASE_IMM:
5161 case OP_STORE_MEMBASE_IMM: {
5163 LLVMValueRef index, addr;
5165 gboolean sext = FALSE, zext = FALSE;
5166 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5168 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5170 if (ins->inst_offset % size != 0) {
5171 /* Unaligned store */
5172 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5173 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5175 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5176 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5178 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5183 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5185 case OP_OUTARG_VTRETADDR:
5193 case OP_VOIDCALL_MEMBASE:
5194 case OP_CALL_MEMBASE:
5195 case OP_LCALL_MEMBASE:
5196 case OP_FCALL_MEMBASE:
5197 case OP_RCALL_MEMBASE:
5198 case OP_VCALL_MEMBASE:
5199 case OP_VOIDCALL_REG:
5204 case OP_VCALL_REG: {
5205 process_call (ctx, bb, &builder, ins);
5210 LLVMValueRef indexes [2];
5211 MonoJumpInfo *tmp_ji, *ji;
5212 LLVMValueRef got_entry_addr;
5216 * FIXME: Can't allocate from the cfg mempool since that is freed if
5217 * the LLVM compile fails.
5219 tmp_ji = g_new0 (MonoJumpInfo, 1);
5220 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5221 tmp_ji->data.target = ins->inst_p0;
5223 ji = mono_aot_patch_info_dup (tmp_ji);
5226 ji->next = cfg->patch_info;
5227 cfg->patch_info = ji;
5229 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5230 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5231 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5232 if (!mono_aot_is_shared_got_offset (got_offset)) {
5233 //mono_print_ji (ji);
5235 ctx->has_got_access = TRUE;
5238 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5239 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5240 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5242 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5243 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5245 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5246 if (!cfg->llvm_only)
5247 set_invariant_load_flag (values [ins->dreg]);
5250 case OP_NOT_REACHED:
5251 LLVMBuildUnreachable (builder);
5252 has_terminator = TRUE;
5253 g_assert (bb->block_num < cfg->max_block_num);
5254 ctx->unreachable [bb->block_num] = TRUE;
5255 /* Might have instructions after this */
5257 MonoInst *next = ins->next;
5259 * FIXME: If later code uses the regs defined by these instructions,
5260 * compilation will fail.
5262 MONO_DELETE_INS (bb, next);
5266 MonoInst *var = ins->inst_i0;
5268 if (var->opcode == OP_VTARG_ADDR) {
5269 /* The variable contains the vtype address */
5270 values [ins->dreg] = values [var->dreg];
5271 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5272 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5274 values [ins->dreg] = addresses [var->dreg];
5279 LLVMValueRef args [1];
5281 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5282 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5286 LLVMValueRef args [1];
5288 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5289 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5293 LLVMValueRef args [1];
5295 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5296 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5300 LLVMValueRef args [1];
5302 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5303 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5317 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5318 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5320 switch (ins->opcode) {
5323 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5327 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5331 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5335 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5338 g_assert_not_reached ();
5341 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5344 case OP_ATOMIC_EXCHANGE_I4:
5345 case OP_ATOMIC_EXCHANGE_I8: {
5346 LLVMValueRef args [2];
5349 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5350 t = LLVMInt32Type ();
5352 t = LLVMInt64Type ();
5354 g_assert (ins->inst_offset == 0);
5356 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5357 args [1] = convert (ctx, rhs, t);
5359 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5362 case OP_ATOMIC_ADD_I4:
5363 case OP_ATOMIC_ADD_I8: {
5364 LLVMValueRef args [2];
5367 if (ins->opcode == OP_ATOMIC_ADD_I4)
5368 t = LLVMInt32Type ();
5370 t = LLVMInt64Type ();
5372 g_assert (ins->inst_offset == 0);
5374 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5375 args [1] = convert (ctx, rhs, t);
5376 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5379 case OP_ATOMIC_CAS_I4:
5380 case OP_ATOMIC_CAS_I8: {
5381 LLVMValueRef args [3], val;
5384 if (ins->opcode == OP_ATOMIC_CAS_I4)
5385 t = LLVMInt32Type ();
5387 t = LLVMInt64Type ();
5389 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5391 args [1] = convert (ctx, values [ins->sreg3], t);
5393 args [2] = convert (ctx, values [ins->sreg2], t);
5394 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5395 /* cmpxchg returns a pair */
5396 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5399 case OP_MEMORY_BARRIER: {
5400 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5403 case OP_ATOMIC_LOAD_I1:
5404 case OP_ATOMIC_LOAD_I2:
5405 case OP_ATOMIC_LOAD_I4:
5406 case OP_ATOMIC_LOAD_I8:
5407 case OP_ATOMIC_LOAD_U1:
5408 case OP_ATOMIC_LOAD_U2:
5409 case OP_ATOMIC_LOAD_U4:
5410 case OP_ATOMIC_LOAD_U8:
5411 case OP_ATOMIC_LOAD_R4:
5412 case OP_ATOMIC_LOAD_R8: {
5413 set_failure (ctx, "atomic mono.load intrinsic");
5417 gboolean sext, zext;
5419 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5420 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5421 LLVMValueRef index, addr;
5423 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5428 if (ins->inst_offset != 0) {
5429 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5430 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5435 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5437 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5440 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5442 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5446 case OP_ATOMIC_STORE_I1:
5447 case OP_ATOMIC_STORE_I2:
5448 case OP_ATOMIC_STORE_I4:
5449 case OP_ATOMIC_STORE_I8:
5450 case OP_ATOMIC_STORE_U1:
5451 case OP_ATOMIC_STORE_U2:
5452 case OP_ATOMIC_STORE_U4:
5453 case OP_ATOMIC_STORE_U8:
5454 case OP_ATOMIC_STORE_R4:
5455 case OP_ATOMIC_STORE_R8: {
5456 set_failure (ctx, "atomic mono.store intrinsic");
5460 gboolean sext, zext;
5462 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5463 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5464 LLVMValueRef index, addr, value;
5466 if (!values [ins->inst_destbasereg]) {
5467 set_failure (ctx, "inst_destbasereg");
5471 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5473 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5474 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5475 value = convert (ctx, values [ins->sreg1], t);
5477 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5481 case OP_RELAXED_NOP: {
5482 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5483 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5490 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5492 // 257 == FS segment register
5493 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5495 // 256 == GS segment register
5496 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5499 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5500 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5501 /* See mono_amd64_emit_tls_get () */
5502 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5504 // 256 == GS segment register
5505 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5506 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5508 set_failure (ctx, "opcode tls-get");
5514 case OP_TLS_GET_REG: {
5515 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5516 /* See emit_tls_get_reg () */
5517 // 256 == GS segment register
5518 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5519 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5521 set_failure (ctx, "opcode tls-get");
5527 case OP_TLS_SET_REG: {
5528 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5529 /* See emit_tls_get_reg () */
5530 // 256 == GS segment register
5531 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5532 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5534 set_failure (ctx, "opcode tls-set-reg");
5544 case OP_IADD_OVF_UN:
5546 case OP_ISUB_OVF_UN:
5548 case OP_IMUL_OVF_UN:
5549 #if SIZEOF_VOID_P == 8
5551 case OP_LADD_OVF_UN:
5553 case OP_LSUB_OVF_UN:
5555 case OP_LMUL_OVF_UN:
5558 LLVMValueRef args [2], val, ovf, func;
5560 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5561 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5562 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5564 val = LLVMBuildCall (builder, func, args, 2, "");
5565 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5566 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5567 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5570 builder = ctx->builder;
5576 * We currently model them using arrays. Promotion to local vregs is
5577 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5578 * so we always have an entry in cfg->varinfo for them.
5579 * FIXME: Is this needed ?
5582 MonoClass *klass = ins->klass;
5583 LLVMValueRef args [5];
5587 set_failure (ctx, "!klass");
5591 if (!addresses [ins->dreg])
5592 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5593 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5594 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5595 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5597 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5598 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5599 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5602 case OP_DUMMY_VZERO:
5605 case OP_STOREV_MEMBASE:
5606 case OP_LOADV_MEMBASE:
5608 MonoClass *klass = ins->klass;
5609 LLVMValueRef src = NULL, dst, args [5];
5610 gboolean done = FALSE;
5614 set_failure (ctx, "!klass");
5618 if (mini_is_gsharedvt_klass (klass)) {
5620 set_failure (ctx, "gsharedvt");
5624 switch (ins->opcode) {
5625 case OP_STOREV_MEMBASE:
5626 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5627 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5628 /* Decomposed earlier */
5629 g_assert_not_reached ();
5632 if (!addresses [ins->sreg1]) {
5634 g_assert (values [ins->sreg1]);
5635 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));
5636 LLVMBuildStore (builder, values [ins->sreg1], dst);
5639 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5640 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5643 case OP_LOADV_MEMBASE:
5644 if (!addresses [ins->dreg])
5645 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5646 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5647 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5650 if (!addresses [ins->sreg1])
5651 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5652 if (!addresses [ins->dreg])
5653 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5654 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5655 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5658 g_assert_not_reached ();
5668 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5669 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5671 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5672 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5673 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5676 case OP_LLVM_OUTARG_VT: {
5677 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5678 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5680 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5681 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5683 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5684 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5686 g_assert (addresses [ins->sreg1]);
5687 addresses [ins->dreg] = addresses [ins->sreg1];
5689 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5690 if (!addresses [ins->sreg1]) {
5691 addresses [ins->sreg1] = build_alloca (ctx, t);
5692 g_assert (values [ins->sreg1]);
5694 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5695 addresses [ins->dreg] = addresses [ins->sreg1];
5697 if (!addresses [ins->sreg1]) {
5698 addresses [ins->sreg1] = build_alloca (ctx, t);
5699 g_assert (values [ins->sreg1]);
5700 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5702 addresses [ins->dreg] = addresses [ins->sreg1];
5710 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5712 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5715 case OP_LOADX_MEMBASE: {
5716 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5719 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5720 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5723 case OP_STOREX_MEMBASE: {
5724 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5727 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5728 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5735 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5739 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5745 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5749 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5753 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5757 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5760 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5763 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5766 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5770 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5781 LLVMValueRef v = NULL;
5783 switch (ins->opcode) {
5788 t = LLVMVectorType (LLVMInt32Type (), 4);
5789 rt = LLVMVectorType (LLVMFloatType (), 4);
5795 t = LLVMVectorType (LLVMInt64Type (), 2);
5796 rt = LLVMVectorType (LLVMDoubleType (), 2);
5799 t = LLVMInt32Type ();
5800 rt = LLVMInt32Type ();
5801 g_assert_not_reached ();
5804 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5805 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5806 switch (ins->opcode) {
5809 v = LLVMBuildAnd (builder, lhs, rhs, "");
5813 v = LLVMBuildOr (builder, lhs, rhs, "");
5817 v = LLVMBuildXor (builder, lhs, rhs, "");
5821 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5824 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5848 case OP_PADDB_SAT_UN:
5849 case OP_PADDW_SAT_UN:
5850 case OP_PSUBB_SAT_UN:
5851 case OP_PSUBW_SAT_UN:
5859 case OP_PMULW_HIGH_UN: {
5860 LLVMValueRef args [2];
5865 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5872 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5876 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5884 case OP_EXTRACTX_U2:
5886 case OP_EXTRACT_U1: {
5888 gboolean zext = FALSE;
5890 t = simd_op_to_llvm_type (ins->opcode);
5892 switch (ins->opcode) {
5900 case OP_EXTRACTX_U2:
5905 t = LLVMInt32Type ();
5906 g_assert_not_reached ();
5909 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5910 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5912 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5921 case OP_EXPAND_R8: {
5922 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5923 LLVMValueRef mask [16], v;
5926 for (i = 0; i < 16; ++i)
5927 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5929 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5931 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5932 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5937 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5940 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5943 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5946 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5949 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5952 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5963 case OP_EXTRACT_MASK:
5970 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5972 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5978 LLVMValueRef args [3];
5982 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5984 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5989 /* This is only used for implementing shifts by non-immediate */
5990 values [ins->dreg] = lhs;
6001 LLVMValueRef args [3];
6004 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6006 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6017 case OP_PSHLQ_REG: {
6018 LLVMValueRef args [3];
6021 args [1] = values [ins->sreg2];
6023 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6030 case OP_PSHUFLEW_LOW:
6031 case OP_PSHUFLEW_HIGH: {
6033 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6034 int i, mask_size = 0;
6035 int imask = ins->inst_c0;
6037 /* Convert the x86 shuffle mask to LLVM's */
6038 switch (ins->opcode) {
6041 mask [0] = ((imask >> 0) & 3);
6042 mask [1] = ((imask >> 2) & 3);
6043 mask [2] = ((imask >> 4) & 3) + 4;
6044 mask [3] = ((imask >> 6) & 3) + 4;
6045 v1 = values [ins->sreg1];
6046 v2 = values [ins->sreg2];
6050 mask [0] = ((imask >> 0) & 1);
6051 mask [1] = ((imask >> 1) & 1) + 2;
6052 v1 = values [ins->sreg1];
6053 v2 = values [ins->sreg2];
6055 case OP_PSHUFLEW_LOW:
6057 mask [0] = ((imask >> 0) & 3);
6058 mask [1] = ((imask >> 2) & 3);
6059 mask [2] = ((imask >> 4) & 3);
6060 mask [3] = ((imask >> 6) & 3);
6065 v1 = values [ins->sreg1];
6066 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6068 case OP_PSHUFLEW_HIGH:
6074 mask [4] = 4 + ((imask >> 0) & 3);
6075 mask [5] = 4 + ((imask >> 2) & 3);
6076 mask [6] = 4 + ((imask >> 4) & 3);
6077 mask [7] = 4 + ((imask >> 6) & 3);
6078 v1 = values [ins->sreg1];
6079 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6083 mask [0] = ((imask >> 0) & 3);
6084 mask [1] = ((imask >> 2) & 3);
6085 mask [2] = ((imask >> 4) & 3);
6086 mask [3] = ((imask >> 6) & 3);
6087 v1 = values [ins->sreg1];
6088 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6091 g_assert_not_reached ();
6093 for (i = 0; i < mask_size; ++i)
6094 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6096 values [ins->dreg] =
6097 LLVMBuildShuffleVector (builder, v1, v2,
6098 LLVMConstVector (mask_values, mask_size), dname);
6102 case OP_UNPACK_LOWB:
6103 case OP_UNPACK_LOWW:
6104 case OP_UNPACK_LOWD:
6105 case OP_UNPACK_LOWQ:
6106 case OP_UNPACK_LOWPS:
6107 case OP_UNPACK_LOWPD:
6108 case OP_UNPACK_HIGHB:
6109 case OP_UNPACK_HIGHW:
6110 case OP_UNPACK_HIGHD:
6111 case OP_UNPACK_HIGHQ:
6112 case OP_UNPACK_HIGHPS:
6113 case OP_UNPACK_HIGHPD: {
6115 LLVMValueRef mask_values [16];
6116 int i, mask_size = 0;
6117 gboolean low = FALSE;
6119 switch (ins->opcode) {
6120 case OP_UNPACK_LOWB:
6124 case OP_UNPACK_LOWW:
6128 case OP_UNPACK_LOWD:
6129 case OP_UNPACK_LOWPS:
6133 case OP_UNPACK_LOWQ:
6134 case OP_UNPACK_LOWPD:
6138 case OP_UNPACK_HIGHB:
6141 case OP_UNPACK_HIGHW:
6144 case OP_UNPACK_HIGHD:
6145 case OP_UNPACK_HIGHPS:
6148 case OP_UNPACK_HIGHQ:
6149 case OP_UNPACK_HIGHPD:
6153 g_assert_not_reached ();
6157 for (i = 0; i < (mask_size / 2); ++i) {
6159 mask [(i * 2) + 1] = mask_size + i;
6162 for (i = 0; i < (mask_size / 2); ++i) {
6163 mask [(i * 2)] = (mask_size / 2) + i;
6164 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6168 for (i = 0; i < mask_size; ++i)
6169 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6171 values [ins->dreg] =
6172 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6173 LLVMConstVector (mask_values, mask_size), dname);
6178 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6179 LLVMValueRef v, val;
6181 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6182 val = LLVMConstNull (t);
6183 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6184 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6186 values [ins->dreg] = val;
6190 case OP_DUPPS_HIGH: {
6191 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6192 LLVMValueRef v1, v2, val;
6195 if (ins->opcode == OP_DUPPS_LOW) {
6196 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6197 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6199 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6200 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6202 val = LLVMConstNull (t);
6203 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6204 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6205 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6206 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6208 values [ins->dreg] = val;
6218 * EXCEPTION HANDLING
6220 case OP_IMPLICIT_EXCEPTION:
6221 /* This marks a place where an implicit exception can happen */
6222 if (bb->region != -1)
6223 set_failure (ctx, "implicit-exception");
6227 gboolean rethrow = (ins->opcode == OP_RETHROW);
6228 if (ctx->llvm_only) {
6229 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6230 has_terminator = TRUE;
6231 ctx->unreachable [bb->block_num] = TRUE;
6233 emit_throw (ctx, bb, rethrow, lhs);
6234 builder = ctx->builder;
6238 case OP_CALL_HANDLER: {
6240 * We don't 'call' handlers, but instead simply branch to them.
6241 * The code generated by ENDFINALLY will branch back to us.
6243 LLVMBasicBlockRef noex_bb;
6245 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6247 bb_list = info->call_handler_return_bbs;
6250 * Set the indicator variable for the finally clause.
6252 lhs = info->finally_ind;
6254 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6256 /* Branch to the finally clause */
6257 LLVMBuildBr (builder, info->call_handler_target_bb);
6259 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6260 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6262 builder = ctx->builder = create_builder (ctx);
6263 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6265 bblocks [bb->block_num].end_bblock = noex_bb;
6268 case OP_START_HANDLER: {
6271 case OP_ENDFINALLY: {
6272 LLVMBasicBlockRef resume_bb;
6273 MonoBasicBlock *handler_bb;
6274 LLVMValueRef val, switch_ins, callee;
6278 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6279 g_assert (handler_bb);
6280 info = &bblocks [handler_bb->block_num];
6281 lhs = info->finally_ind;
6284 bb_list = info->call_handler_return_bbs;
6286 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6288 /* Load the finally variable */
6289 val = LLVMBuildLoad (builder, lhs, "");
6291 /* Reset the variable */
6292 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6294 /* Branch to either resume_bb, or to the bblocks in bb_list */
6295 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6297 * The other targets are added at the end to handle OP_CALL_HANDLER
6298 * opcodes processed later.
6300 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6302 builder = ctx->builder = create_builder (ctx);
6303 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6305 if (ctx->llvm_only) {
6306 emit_resume_eh (ctx, bb);
6308 if (ctx->cfg->compile_aot) {
6309 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6311 #if LLVM_API_VERSION > 100
6312 MonoJitICallInfo *info;
6314 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6316 gpointer target = (void*)info->func;
6317 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6318 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6320 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6323 LLVMBuildCall (builder, callee, NULL, 0, "");
6324 LLVMBuildUnreachable (builder);
6327 has_terminator = TRUE;
6330 case OP_IL_SEQ_POINT:
6335 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6336 set_failure (ctx, reason);
6344 /* Convert the value to the type required by phi nodes */
6345 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6346 if (!values [ins->dreg])
6348 values [ins->dreg] = addresses [ins->dreg];
6350 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6353 /* Add stores for volatile variables */
6354 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6355 emit_volatile_store (ctx, ins->dreg);
6361 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6362 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6365 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6366 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6367 LLVMBuildRetVoid (builder);
6370 if (bb == cfg->bb_entry)
6371 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6375 * mono_llvm_check_method_supported:
6377 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6378 * compiling a method twice.
6381 mono_llvm_check_method_supported (MonoCompile *cfg)
6388 if (cfg->method->save_lmf) {
6389 cfg->exception_message = g_strdup ("lmf");
6390 cfg->disable_llvm = TRUE;
6392 if (cfg->disable_llvm)
6396 * Nested clauses where one of the clauses is a finally clause is
6397 * not supported, because LLVM can't figure out the control flow,
6398 * probably because we resume exception handling by calling our
6399 * own function instead of using the 'resume' llvm instruction.
6401 for (i = 0; i < cfg->header->num_clauses; ++i) {
6402 for (j = 0; j < cfg->header->num_clauses; ++j) {
6403 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6404 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6406 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6407 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6408 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6409 cfg->exception_message = g_strdup ("nested clauses");
6410 cfg->disable_llvm = TRUE;
6415 if (cfg->disable_llvm)
6419 if (cfg->method->dynamic) {
6420 cfg->exception_message = g_strdup ("dynamic.");
6421 cfg->disable_llvm = TRUE;
6423 if (cfg->disable_llvm)
6427 static LLVMCallInfo*
6428 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6430 LLVMCallInfo *linfo;
6433 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6437 * Gsharedvt methods have the following calling convention:
6438 * - all arguments are passed by ref, even non generic ones
6439 * - the return value is returned by ref too, using a vret
6440 * argument passed after 'this'.
6442 n = sig->param_count + sig->hasthis;
6443 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6447 linfo->args [pindex ++].storage = LLVMArgNormal;
6449 if (sig->ret->type != MONO_TYPE_VOID) {
6450 if (mini_is_gsharedvt_variable_type (sig->ret))
6451 linfo->ret.storage = LLVMArgGsharedvtVariable;
6452 else if (mini_type_is_vtype (sig->ret))
6453 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6455 linfo->ret.storage = LLVMArgGsharedvtFixed;
6456 linfo->vret_arg_index = pindex;
6458 linfo->ret.storage = LLVMArgNone;
6461 for (i = 0; i < sig->param_count; ++i) {
6462 if (sig->params [i]->byref)
6463 linfo->args [pindex].storage = LLVMArgNormal;
6464 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6465 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6466 else if (mini_type_is_vtype (sig->params [i]))
6467 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6469 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6470 linfo->args [pindex].type = sig->params [i];
6477 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6478 for (i = 0; i < sig->param_count; ++i)
6479 linfo->args [i + sig->hasthis].type = sig->params [i];
6485 emit_method_inner (EmitContext *ctx);
6488 free_ctx (EmitContext *ctx)
6492 g_free (ctx->values);
6493 g_free (ctx->addresses);
6494 g_free (ctx->vreg_types);
6495 g_free (ctx->vreg_cli_types);
6496 g_free (ctx->is_dead);
6497 g_free (ctx->unreachable);
6498 g_ptr_array_free (ctx->phi_values, TRUE);
6499 g_free (ctx->bblocks);
6500 g_hash_table_destroy (ctx->region_to_handler);
6501 g_hash_table_destroy (ctx->clause_to_handler);
6502 g_hash_table_destroy (ctx->jit_callees);
6503 g_free (ctx->method_name);
6504 g_ptr_array_free (ctx->bblock_list, TRUE);
6506 for (l = ctx->builders; l; l = l->next) {
6507 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6508 LLVMDisposeBuilder (builder);
6515 * mono_llvm_emit_method:
6517 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6520 mono_llvm_emit_method (MonoCompile *cfg)
6524 gboolean is_linkonce = FALSE;
6527 /* The code below might acquire the loader lock, so use it for global locking */
6528 mono_loader_lock ();
6530 /* Used to communicate with the callbacks */
6531 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6533 ctx = g_new0 (EmitContext, 1);
6535 ctx->mempool = cfg->mempool;
6538 * This maps vregs to the LLVM instruction defining them
6540 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6542 * This maps vregs for volatile variables to the LLVM instruction defining their
6545 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6546 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6547 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6548 ctx->phi_values = g_ptr_array_sized_new (256);
6550 * This signals whenever the vreg was defined by a phi node with no input vars
6551 * (i.e. all its input bblocks end with NOT_REACHABLE).
6553 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6554 /* Whenever the bblock is unreachable */
6555 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6556 ctx->bblock_list = g_ptr_array_sized_new (256);
6558 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6559 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6560 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6561 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6562 if (cfg->compile_aot) {
6563 ctx->module = &aot_module;
6567 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6568 * linkage for them. This requires the following:
6569 * - the method needs to have a unique mangled name
6570 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6572 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6574 method_name = mono_aot_get_mangled_method_name (cfg->method);
6576 is_linkonce = FALSE;
6579 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6581 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6585 method_name = mono_aot_get_method_name (cfg);
6586 cfg->llvm_method_name = g_strdup (method_name);
6588 init_jit_module (cfg->domain);
6589 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6590 method_name = mono_method_full_name (cfg->method, TRUE);
6592 ctx->method_name = method_name;
6593 ctx->is_linkonce = is_linkonce;
6595 #if LLVM_API_VERSION > 100
6596 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6598 ctx->lmodule = ctx->module->lmodule;
6600 ctx->llvm_only = ctx->module->llvm_only;
6602 emit_method_inner (ctx);
6604 if (!ctx_ok (ctx)) {
6606 /* Need to add unused phi nodes as they can be referenced by other values */
6607 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6608 LLVMBuilderRef builder;
6610 builder = create_builder (ctx);
6611 LLVMPositionBuilderAtEnd (builder, phi_bb);
6613 for (i = 0; i < ctx->phi_values->len; ++i) {
6614 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6615 if (LLVMGetInstructionParent (v) == NULL)
6616 LLVMInsertIntoBuilder (builder, v);
6619 LLVMDeleteFunction (ctx->lmethod);
6625 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6627 mono_loader_unlock ();
6631 emit_method_inner (EmitContext *ctx)
6633 MonoCompile *cfg = ctx->cfg;
6634 MonoMethodSignature *sig;
6636 LLVMTypeRef method_type;
6637 LLVMValueRef method = NULL;
6638 LLVMValueRef *values = ctx->values;
6639 int i, max_block_num, bb_index;
6640 gboolean last = FALSE;
6641 LLVMCallInfo *linfo;
6642 LLVMModuleRef lmodule = ctx->lmodule;
6644 GPtrArray *bblock_list = ctx->bblock_list;
6645 MonoMethodHeader *header;
6646 MonoExceptionClause *clause;
6649 if (cfg->gsharedvt && !cfg->llvm_only) {
6650 set_failure (ctx, "gsharedvt");
6656 static int count = 0;
6659 if (g_getenv ("LLVM_COUNT")) {
6660 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6661 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6665 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6666 set_failure (ctx, "count");
6673 sig = mono_method_signature (cfg->method);
6676 linfo = get_llvm_call_info (cfg, sig);
6682 linfo->rgctx_arg = TRUE;
6683 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6687 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6688 ctx->lmethod = method;
6690 if (!cfg->llvm_only)
6691 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6692 LLVMSetLinkage (method, LLVMPrivateLinkage);
6694 LLVMAddFunctionAttr (method, LLVMUWTable);
6696 if (cfg->compile_aot) {
6697 LLVMSetLinkage (method, LLVMInternalLinkage);
6698 if (ctx->module->external_symbols) {
6699 LLVMSetLinkage (method, LLVMExternalLinkage);
6700 LLVMSetVisibility (method, LLVMHiddenVisibility);
6702 if (ctx->is_linkonce) {
6703 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6704 LLVMSetVisibility (method, LLVMDefaultVisibility);
6707 #if LLVM_API_VERSION > 100
6708 LLVMSetLinkage (method, LLVMExternalLinkage);
6710 LLVMSetLinkage (method, LLVMPrivateLinkage);
6714 if (cfg->method->save_lmf && !cfg->llvm_only) {
6715 set_failure (ctx, "lmf");
6719 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6720 set_failure (ctx, "pinvoke signature");
6724 header = cfg->header;
6725 for (i = 0; i < header->num_clauses; ++i) {
6726 clause = &header->clauses [i];
6727 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6728 set_failure (ctx, "non-finally/catch clause.");
6732 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6733 /* We can't handle inlined methods with clauses */
6734 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6736 if (linfo->rgctx_arg) {
6737 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6738 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6740 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6741 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6742 * CC_X86_64_Mono in X86CallingConv.td.
6744 if (!ctx->llvm_only)
6745 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6746 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6748 ctx->rgctx_arg_pindex = -1;
6750 if (cfg->vret_addr) {
6751 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6752 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6753 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6754 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6755 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6760 ctx->this_arg_pindex = linfo->this_arg_pindex;
6761 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6762 values [cfg->args [0]->dreg] = ctx->this_arg;
6763 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6766 names = g_new (char *, sig->param_count);
6767 mono_method_get_param_names (cfg->method, (const char **) names);
6769 for (i = 0; i < sig->param_count; ++i) {
6770 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6772 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6775 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6776 name = g_strdup_printf ("dummy_%d_%d", i, j);
6777 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6781 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6782 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6783 if (names [i] && names [i][0] != '\0')
6784 name = g_strdup_printf ("p_arg_%s", names [i]);
6786 name = g_strdup_printf ("p_arg_%d", i);
6788 if (names [i] && names [i][0] != '\0')
6789 name = g_strdup_printf ("arg_%s", names [i]);
6791 name = g_strdup_printf ("arg_%d", i);
6793 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6795 if (ainfo->storage == LLVMArgVtypeByVal)
6796 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6798 if (ainfo->storage == LLVMArgVtypeByRef) {
6800 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6805 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6806 ctx->minfo = mono_debug_lookup_method (cfg->method);
6807 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6811 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6812 max_block_num = MAX (max_block_num, bb->block_num);
6813 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6815 /* Add branches between non-consecutive bblocks */
6816 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6817 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6818 bb->next_bb != bb->last_ins->inst_false_bb) {
6820 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6821 inst->opcode = OP_BR;
6822 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6823 mono_bblock_add_inst (bb, inst);
6828 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6829 * was later optimized away, so clear these flags, and add them back for the still
6830 * present OP_LDADDR instructions.
6832 for (i = 0; i < cfg->next_vreg; ++i) {
6835 ins = get_vreg_to_inst (cfg, i);
6836 if (ins && ins != cfg->rgctx_var)
6837 ins->flags &= ~MONO_INST_INDIRECT;
6841 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6843 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6845 LLVMBuilderRef builder;
6847 char dname_buf[128];
6849 builder = create_builder (ctx);
6851 for (ins = bb->code; ins; ins = ins->next) {
6852 switch (ins->opcode) {
6857 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6862 if (ins->opcode == OP_VPHI) {
6863 /* Treat valuetype PHI nodes as operating on the address itself */
6864 g_assert (ins->klass);
6865 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6869 * Have to precreate these, as they can be referenced by
6870 * earlier instructions.
6872 sprintf (dname_buf, "t%d", ins->dreg);
6874 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6876 if (ins->opcode == OP_VPHI)
6877 ctx->addresses [ins->dreg] = values [ins->dreg];
6879 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6882 * Set the expected type of the incoming arguments since these have
6883 * to have the same type.
6885 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6886 int sreg1 = ins->inst_phi_args [i + 1];
6889 ctx->vreg_types [sreg1] = phi_type;
6894 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6903 * Create an ordering for bblocks, use the depth first order first, then
6904 * put the exception handling bblocks last.
6906 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6907 bb = cfg->bblocks [bb_index];
6908 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6909 g_ptr_array_add (bblock_list, bb);
6910 bblocks [bb->block_num].added = TRUE;
6914 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6915 if (!bblocks [bb->block_num].added)
6916 g_ptr_array_add (bblock_list, bb);
6920 * Second pass: generate code.
6923 LLVMBuilderRef entry_builder = create_builder (ctx);
6924 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6925 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6926 emit_entry_bb (ctx, entry_builder);
6928 // Make landing pads first
6929 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6931 if (ctx->llvm_only) {
6932 size_t group_index = 0;
6933 while (group_index < cfg->header->num_clauses) {
6935 size_t cursor = group_index;
6936 while (cursor < cfg->header->num_clauses &&
6937 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6938 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6943 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6944 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6945 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6947 group_index = cursor;
6951 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6952 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6954 // Prune unreachable mono BBs.
6955 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6958 process_bb (ctx, bb);
6962 g_hash_table_destroy (ctx->exc_meta);
6964 mono_memory_barrier ();
6966 /* Add incoming phi values */
6967 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6968 GSList *l, *ins_list;
6970 ins_list = bblocks [bb->block_num].phi_nodes;
6972 for (l = ins_list; l; l = l->next) {
6973 PhiNode *node = (PhiNode*)l->data;
6974 MonoInst *phi = node->phi;
6975 int sreg1 = node->sreg;
6976 LLVMBasicBlockRef in_bb;
6981 in_bb = get_end_bb (ctx, node->in_bb);
6983 if (ctx->unreachable [node->in_bb->block_num])
6986 if (!values [sreg1]) {
6987 /* Can happen with values in EH clauses */
6988 set_failure (ctx, "incoming phi sreg1");
6992 if (phi->opcode == OP_VPHI) {
6993 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6994 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6996 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6997 set_failure (ctx, "incoming phi arg type mismatch");
7000 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7001 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7006 /* Nullify empty phi instructions */
7007 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7008 GSList *l, *ins_list;
7010 ins_list = bblocks [bb->block_num].phi_nodes;
7012 for (l = ins_list; l; l = l->next) {
7013 PhiNode *node = (PhiNode*)l->data;
7014 MonoInst *phi = node->phi;
7015 LLVMValueRef phi_ins = values [phi->dreg];
7018 /* Already removed */
7021 if (LLVMCountIncoming (phi_ins) == 0) {
7022 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7023 LLVMInstructionEraseFromParent (phi_ins);
7024 values [phi->dreg] = NULL;
7029 /* Create the SWITCH statements for ENDFINALLY instructions */
7030 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7031 BBInfo *info = &bblocks [bb->block_num];
7033 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7034 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7035 GSList *bb_list = info->call_handler_return_bbs;
7037 for (i = 0; i < g_slist_length (bb_list); ++i)
7038 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7042 /* Initialize the method if needed */
7043 if (cfg->compile_aot && ctx->llvm_only) {
7044 // FIXME: Add more shared got entries
7045 ctx->builder = create_builder (ctx);
7046 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7048 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7050 // FIXME: beforefieldinit
7051 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7052 emit_init_method (ctx);
7054 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7058 if (cfg->llvm_only) {
7059 GHashTableIter iter;
7061 GSList *callers, *l, *l2;
7064 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7065 * We can't do this earlier, as it contains llvm instructions which can be
7066 * freed if compilation fails.
7067 * FIXME: Get rid of this when all methods can be llvm compiled.
7069 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7070 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7071 for (l = callers; l; l = l->next) {
7072 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7073 l2 = g_slist_prepend (l2, l->data);
7074 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7079 if (cfg->verbose_level > 1)
7080 mono_llvm_dump_value (method);
7082 if (cfg->compile_aot && !cfg->llvm_only)
7083 mark_as_used (ctx->module, method);
7085 if (cfg->compile_aot && !cfg->llvm_only) {
7086 LLVMValueRef md_args [16];
7087 LLVMValueRef md_node;
7090 method_index = mono_aot_get_method_index (cfg->orig_method);
7091 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7092 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7093 md_node = LLVMMDNode (md_args, 2);
7094 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7095 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7098 if (cfg->compile_aot) {
7099 /* Don't generate native code, keep the LLVM IR */
7100 if (cfg->verbose_level)
7101 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7103 #if LLVM_API_VERSION < 100
7104 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7105 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7106 g_assert (err == 0);
7109 //LLVMVerifyFunction(method, 0);
7110 #if LLVM_API_VERSION > 100
7111 MonoDomain *domain = mono_domain_get ();
7112 MonoJitDomainInfo *domain_info;
7113 int nvars = g_hash_table_size (ctx->jit_callees);
7114 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7115 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7116 GHashTableIter iter;
7122 * Compute the addresses of the LLVM globals pointing to the
7123 * methods called by the current method. Pass it to the trampoline
7124 * code so it can update them after their corresponding method was
7127 g_hash_table_iter_init (&iter, ctx->jit_callees);
7129 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7130 callee_vars [i ++] = var;
7132 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7134 decode_llvm_eh_info (ctx, eh_frame);
7136 mono_domain_lock (domain);
7137 domain_info = domain_jit_info (domain);
7138 if (!domain_info->llvm_jit_callees)
7139 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7140 g_hash_table_iter_init (&iter, ctx->jit_callees);
7142 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7143 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7144 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7145 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7148 mono_domain_unlock (domain);
7150 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7152 if (cfg->verbose_level > 1)
7153 mono_llvm_dump_value (ctx->lmethod);
7155 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7157 /* Set by emit_cb */
7158 g_assert (cfg->code_len);
7162 if (ctx->module->method_to_lmethod)
7163 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7164 if (ctx->module->idx_to_lmethod)
7165 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7167 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7168 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7172 * mono_llvm_create_vars:
7174 * Same as mono_arch_create_vars () for LLVM.
7177 mono_llvm_create_vars (MonoCompile *cfg)
7179 MonoMethodSignature *sig;
7181 sig = mono_method_signature (cfg->method);
7182 if (cfg->gsharedvt && cfg->llvm_only) {
7183 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7184 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7185 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7186 printf ("vret_addr = ");
7187 mono_print_ins (cfg->vret_addr);
7191 mono_arch_create_vars (cfg);
7196 * mono_llvm_emit_call:
7198 * Same as mono_arch_emit_call () for LLVM.
7201 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7204 MonoMethodSignature *sig;
7205 int i, n, stack_size;
7210 sig = call->signature;
7211 n = sig->param_count + sig->hasthis;
7213 call->cinfo = get_llvm_call_info (cfg, sig);
7215 if (cfg->disable_llvm)
7218 if (sig->call_convention == MONO_CALL_VARARG) {
7219 cfg->exception_message = g_strdup ("varargs");
7220 cfg->disable_llvm = TRUE;
7223 for (i = 0; i < n; ++i) {
7226 ainfo = call->cinfo->args + i;
7228 in = call->args [i];
7230 /* Simply remember the arguments */
7231 switch (ainfo->storage) {
7232 case LLVMArgNormal: {
7233 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7236 opcode = mono_type_to_regmove (cfg, t);
7237 if (opcode == OP_FMOVE) {
7238 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7239 ins->dreg = mono_alloc_freg (cfg);
7240 } else if (opcode == OP_LMOVE) {
7241 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7242 ins->dreg = mono_alloc_lreg (cfg);
7243 } else if (opcode == OP_RMOVE) {
7244 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7245 ins->dreg = mono_alloc_freg (cfg);
7247 MONO_INST_NEW (cfg, ins, OP_MOVE);
7248 ins->dreg = mono_alloc_ireg (cfg);
7250 ins->sreg1 = in->dreg;
7253 case LLVMArgVtypeByVal:
7254 case LLVMArgVtypeByRef:
7255 case LLVMArgVtypeInReg:
7256 case LLVMArgVtypeAsScalar:
7257 case LLVMArgAsIArgs:
7258 case LLVMArgAsFpArgs:
7259 case LLVMArgGsharedvtVariable:
7260 case LLVMArgGsharedvtFixed:
7261 case LLVMArgGsharedvtFixedVtype:
7262 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7263 ins->dreg = mono_alloc_ireg (cfg);
7264 ins->sreg1 = in->dreg;
7265 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7266 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7267 ins->inst_vtype = ainfo->type;
7268 ins->klass = mono_class_from_mono_type (ainfo->type);
7271 cfg->exception_message = g_strdup ("ainfo->storage");
7272 cfg->disable_llvm = TRUE;
7276 if (!cfg->disable_llvm) {
7277 MONO_ADD_INS (cfg->cbb, ins);
7278 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7283 static unsigned char*
7284 alloc_cb (LLVMValueRef function, int size)
7288 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7292 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7294 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7299 emitted_cb (LLVMValueRef function, void *start, void *end)
7303 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7305 cfg->code_len = (guint8*)end - (guint8*)start;
7309 exception_cb (void *data)
7312 MonoJitExceptionInfo *ei;
7313 guint32 ei_len, i, j, nested_len, nindex;
7314 gpointer *type_info;
7315 int this_reg, this_offset;
7317 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7321 * data points to a DWARF FDE structure, convert it to our unwind format and
7323 * An alternative would be to save it directly, and modify our unwinder to work
7326 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);
7327 if (cfg->verbose_level > 1)
7328 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7330 /* Count nested clauses */
7332 for (i = 0; i < ei_len; ++i) {
7333 gint32 cindex1 = *(gint32*)type_info [i];
7334 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7336 for (j = 0; j < cfg->header->num_clauses; ++j) {
7338 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7340 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7346 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7347 cfg->llvm_ex_info_len = ei_len + nested_len;
7348 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7349 /* Fill the rest of the information from the type info */
7350 for (i = 0; i < ei_len; ++i) {
7351 gint32 clause_index = *(gint32*)type_info [i];
7352 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7354 cfg->llvm_ex_info [i].flags = clause->flags;
7355 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7356 cfg->llvm_ex_info [i].clause_index = clause_index;
7360 * For nested clauses, the LLVM produced exception info associates the try interval with
7361 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7362 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7363 * and everything else from the nested clause.
7366 for (i = 0; i < ei_len; ++i) {
7367 gint32 cindex1 = *(gint32*)type_info [i];
7368 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7370 for (j = 0; j < cfg->header->num_clauses; ++j) {
7372 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7373 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7375 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7376 /* clause1 is the nested clause */
7377 nested_ei = &cfg->llvm_ex_info [i];
7378 nesting_ei = &cfg->llvm_ex_info [nindex];
7381 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7383 nesting_ei->flags = clause2->flags;
7384 nesting_ei->data.catch_class = clause2->data.catch_class;
7385 nesting_ei->clause_index = cindex2;
7389 g_assert (nindex == ei_len + nested_len);
7390 cfg->llvm_this_reg = this_reg;
7391 cfg->llvm_this_offset = this_offset;
7393 /* type_info [i] is cfg mempool allocated, no need to free it */
7399 #if LLVM_API_VERSION > 100
7401 * decode_llvm_eh_info:
7403 * Decode the EH table emitted by llvm in jit mode, and store
7404 * the result into cfg.
7407 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7409 MonoCompile *cfg = ctx->cfg;
7412 MonoLLVMFDEInfo info;
7413 MonoJitExceptionInfo *ei;
7414 guint8 *p = eh_frame;
7415 int version, fde_count, fde_offset;
7416 guint32 ei_len, i, nested_len;
7417 gpointer *type_info;
7421 * Decode the one element EH table emitted by the MonoException class
7425 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7428 g_assert (version == 3);
7431 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7433 fde_count = *(guint32*)p;
7437 g_assert (fde_count == 1);
7439 /* The only table entry */
7440 fde_offset = table [1];
7443 cfg->code_len = table [0];
7444 fde_len = table [1] - fde_offset;
7447 fde = (guint8*)eh_frame + fde_offset;
7448 cie = (guint8*)table;
7450 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7452 cfg->encoded_unwind_ops = info.unw_info;
7453 cfg->encoded_unwind_ops_len = info.unw_info_len;
7454 if (cfg->verbose_level > 1)
7455 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7456 if (info.this_reg != -1) {
7457 cfg->llvm_this_reg = info.this_reg;
7458 cfg->llvm_this_offset = info.this_offset;
7462 ei_len = info.ex_info_len;
7463 type_info = info.type_info;
7465 // Nested clauses are currently disabled
7468 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7469 cfg->llvm_ex_info_len = ei_len + nested_len;
7470 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7471 /* Fill the rest of the information from the type info */
7472 for (i = 0; i < ei_len; ++i) {
7473 gint32 clause_index = *(gint32*)type_info [i];
7474 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7476 cfg->llvm_ex_info [i].flags = clause->flags;
7477 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7478 cfg->llvm_ex_info [i].clause_index = clause_index;
7484 dlsym_cb (const char *name, void **symbol)
7490 if (!strcmp (name, "__bzero")) {
7491 *symbol = (void*)bzero;
7493 current = mono_dl_open (NULL, 0, NULL);
7496 err = mono_dl_symbol (current, name, symbol);
7498 mono_dl_close (current);
7500 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7501 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7507 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7509 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7513 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7515 LLVMTypeRef param_types [4];
7517 param_types [0] = param_type1;
7518 param_types [1] = param_type2;
7520 AddFunc (module, name, ret_type, param_types, 2);
7526 INTRINS_SADD_OVF_I32,
7527 INTRINS_UADD_OVF_I32,
7528 INTRINS_SSUB_OVF_I32,
7529 INTRINS_USUB_OVF_I32,
7530 INTRINS_SMUL_OVF_I32,
7531 INTRINS_UMUL_OVF_I32,
7532 INTRINS_SADD_OVF_I64,
7533 INTRINS_UADD_OVF_I64,
7534 INTRINS_SSUB_OVF_I64,
7535 INTRINS_USUB_OVF_I64,
7536 INTRINS_SMUL_OVF_I64,
7537 INTRINS_UMUL_OVF_I64,
7544 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7545 INTRINS_SSE_PMOVMSKB,
7546 INTRINS_SSE_PSRLI_W,
7547 INTRINS_SSE_PSRAI_W,
7548 INTRINS_SSE_PSLLI_W,
7549 INTRINS_SSE_PSRLI_D,
7550 INTRINS_SSE_PSRAI_D,
7551 INTRINS_SSE_PSLLI_D,
7552 INTRINS_SSE_PSRLI_Q,
7553 INTRINS_SSE_PSLLI_Q,
7554 INTRINS_SSE_SQRT_PD,
7555 INTRINS_SSE_SQRT_PS,
7556 INTRINS_SSE_RSQRT_PS,
7558 INTRINS_SSE_CVTTPD2DQ,
7559 INTRINS_SSE_CVTTPS2DQ,
7560 INTRINS_SSE_CVTDQ2PD,
7561 INTRINS_SSE_CVTDQ2PS,
7562 INTRINS_SSE_CVTPD2DQ,
7563 INTRINS_SSE_CVTPS2DQ,
7564 INTRINS_SSE_CVTPD2PS,
7565 INTRINS_SSE_CVTPS2PD,
7568 INTRINS_SSE_PACKSSWB,
7569 INTRINS_SSE_PACKUSWB,
7570 INTRINS_SSE_PACKSSDW,
7571 INTRINS_SSE_PACKUSDW,
7576 INTRINS_SSE_ADDSUBPS,
7581 INTRINS_SSE_ADDSUBPD,
7589 INTRINS_SSE_PADDUSW,
7590 INTRINS_SSE_PSUBUSW,
7598 INTRINS_SSE_PADDUSB,
7599 INTRINS_SSE_PSUBUSB,
7611 static IntrinsicDesc intrinsics[] = {
7612 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7613 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7614 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7615 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7616 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7617 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7618 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7619 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7620 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7621 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7622 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7623 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7624 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7625 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7626 {INTRINS_SIN, "llvm.sin.f64"},
7627 {INTRINS_COS, "llvm.cos.f64"},
7628 {INTRINS_SQRT, "llvm.sqrt.f64"},
7629 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7630 {INTRINS_FABS, "fabs"},
7631 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7632 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7633 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7634 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7635 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7636 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7637 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7638 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7639 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7640 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7641 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7642 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7643 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7644 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7645 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7646 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7647 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7648 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7649 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7650 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7651 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7652 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7653 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7654 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7655 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7656 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7657 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7658 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7659 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7660 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7661 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7662 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7663 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7664 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7665 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7666 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7667 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7668 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7669 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7670 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7671 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7672 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7673 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7674 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7675 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7676 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7677 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7678 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7679 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7680 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7681 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7682 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7683 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7684 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7685 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7686 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7687 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7688 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7689 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7690 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7695 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7697 LLVMTypeRef ret_type = type_to_simd_type (type);
7698 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7702 add_intrinsic (LLVMModuleRef module, int id)
7705 LLVMTypeRef ret_type, arg_types [16];
7707 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7711 case INTRINS_MEMSET: {
7712 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7714 AddFunc (module, name, LLVMVoidType (), params, 5);
7717 case INTRINS_MEMCPY: {
7718 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7720 AddFunc (module, name, LLVMVoidType (), params, 5);
7723 case INTRINS_SADD_OVF_I32:
7724 case INTRINS_UADD_OVF_I32:
7725 case INTRINS_SSUB_OVF_I32:
7726 case INTRINS_USUB_OVF_I32:
7727 case INTRINS_SMUL_OVF_I32:
7728 case INTRINS_UMUL_OVF_I32: {
7729 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7730 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7731 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7733 AddFunc (module, name, ret_type, params, 2);
7736 case INTRINS_SADD_OVF_I64:
7737 case INTRINS_UADD_OVF_I64:
7738 case INTRINS_SSUB_OVF_I64:
7739 case INTRINS_USUB_OVF_I64:
7740 case INTRINS_SMUL_OVF_I64:
7741 case INTRINS_UMUL_OVF_I64: {
7742 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7743 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7744 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7746 AddFunc (module, name, ret_type, params, 2);
7752 case INTRINS_FABS: {
7753 LLVMTypeRef params [] = { LLVMDoubleType () };
7755 AddFunc (module, name, LLVMDoubleType (), params, 1);
7758 case INTRINS_EXPECT_I8:
7759 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7761 case INTRINS_EXPECT_I1:
7762 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7764 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7765 case INTRINS_SSE_PMOVMSKB:
7767 ret_type = LLVMInt32Type ();
7768 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7769 AddFunc (module, name, ret_type, arg_types, 1);
7771 case INTRINS_SSE_PSRLI_W:
7772 case INTRINS_SSE_PSRAI_W:
7773 case INTRINS_SSE_PSLLI_W:
7775 ret_type = type_to_simd_type (MONO_TYPE_I2);
7776 arg_types [0] = ret_type;
7777 arg_types [1] = LLVMInt32Type ();
7778 AddFunc (module, name, ret_type, arg_types, 2);
7780 case INTRINS_SSE_PSRLI_D:
7781 case INTRINS_SSE_PSRAI_D:
7782 case INTRINS_SSE_PSLLI_D:
7783 ret_type = type_to_simd_type (MONO_TYPE_I4);
7784 arg_types [0] = ret_type;
7785 arg_types [1] = LLVMInt32Type ();
7786 AddFunc (module, name, ret_type, arg_types, 2);
7788 case INTRINS_SSE_PSRLI_Q:
7789 case INTRINS_SSE_PSLLI_Q:
7790 ret_type = type_to_simd_type (MONO_TYPE_I8);
7791 arg_types [0] = ret_type;
7792 arg_types [1] = LLVMInt32Type ();
7793 AddFunc (module, name, ret_type, arg_types, 2);
7795 case INTRINS_SSE_SQRT_PD:
7797 ret_type = type_to_simd_type (MONO_TYPE_R8);
7798 arg_types [0] = ret_type;
7799 AddFunc (module, name, ret_type, arg_types, 1);
7801 case INTRINS_SSE_SQRT_PS:
7802 ret_type = type_to_simd_type (MONO_TYPE_R4);
7803 arg_types [0] = ret_type;
7804 AddFunc (module, name, ret_type, arg_types, 1);
7806 case INTRINS_SSE_RSQRT_PS:
7807 ret_type = type_to_simd_type (MONO_TYPE_R4);
7808 arg_types [0] = ret_type;
7809 AddFunc (module, name, ret_type, arg_types, 1);
7811 case INTRINS_SSE_RCP_PS:
7812 ret_type = type_to_simd_type (MONO_TYPE_R4);
7813 arg_types [0] = ret_type;
7814 AddFunc (module, name, ret_type, arg_types, 1);
7816 case INTRINS_SSE_CVTTPD2DQ:
7817 ret_type = type_to_simd_type (MONO_TYPE_I4);
7818 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7819 AddFunc (module, name, ret_type, arg_types, 1);
7821 case INTRINS_SSE_CVTTPS2DQ:
7822 ret_type = type_to_simd_type (MONO_TYPE_I4);
7823 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7824 AddFunc (module, name, ret_type, arg_types, 1);
7826 case INTRINS_SSE_CVTDQ2PD:
7827 /* Conversion ops */
7828 ret_type = type_to_simd_type (MONO_TYPE_R8);
7829 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7830 AddFunc (module, name, ret_type, arg_types, 1);
7832 case INTRINS_SSE_CVTDQ2PS:
7833 ret_type = type_to_simd_type (MONO_TYPE_R4);
7834 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7835 AddFunc (module, name, ret_type, arg_types, 1);
7837 case INTRINS_SSE_CVTPD2DQ:
7838 ret_type = type_to_simd_type (MONO_TYPE_I4);
7839 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7840 AddFunc (module, name, ret_type, arg_types, 1);
7842 case INTRINS_SSE_CVTPS2DQ:
7843 ret_type = type_to_simd_type (MONO_TYPE_I4);
7844 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7845 AddFunc (module, name, ret_type, arg_types, 1);
7847 case INTRINS_SSE_CVTPD2PS:
7848 ret_type = type_to_simd_type (MONO_TYPE_R4);
7849 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7850 AddFunc (module, name, ret_type, arg_types, 1);
7852 case INTRINS_SSE_CVTPS2PD:
7853 ret_type = type_to_simd_type (MONO_TYPE_R8);
7854 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7855 AddFunc (module, name, ret_type, arg_types, 1);
7857 case INTRINS_SSE_CMPPD:
7859 ret_type = type_to_simd_type (MONO_TYPE_R8);
7860 arg_types [0] = ret_type;
7861 arg_types [1] = ret_type;
7862 arg_types [2] = LLVMInt8Type ();
7863 AddFunc (module, name, ret_type, arg_types, 3);
7865 case INTRINS_SSE_CMPPS:
7866 ret_type = type_to_simd_type (MONO_TYPE_R4);
7867 arg_types [0] = ret_type;
7868 arg_types [1] = ret_type;
7869 arg_types [2] = LLVMInt8Type ();
7870 AddFunc (module, name, ret_type, arg_types, 3);
7872 case INTRINS_SSE_PACKSSWB:
7873 case INTRINS_SSE_PACKUSWB:
7874 case INTRINS_SSE_PACKSSDW:
7876 ret_type = type_to_simd_type (MONO_TYPE_I1);
7877 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7878 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7879 AddFunc (module, name, ret_type, arg_types, 2);
7881 case INTRINS_SSE_PACKUSDW:
7882 ret_type = type_to_simd_type (MONO_TYPE_I2);
7883 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7884 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7885 AddFunc (module, name, ret_type, arg_types, 2);
7887 /* SSE Binary ops */
7888 case INTRINS_SSE_PMINUD:
7889 case INTRINS_SSE_PMAXUD:
7890 add_sse_binary (module, name, MONO_TYPE_I4);
7892 case INTRINS_SSE_PMINUW:
7893 case INTRINS_SSE_PMINSW:
7894 case INTRINS_SSE_PMAXUW:
7895 case INTRINS_SSE_PADDSW:
7896 case INTRINS_SSE_PSUBSW:
7897 case INTRINS_SSE_PADDUSW:
7898 case INTRINS_SSE_PSUBUSW:
7899 case INTRINS_SSE_PAVGW:
7900 case INTRINS_SSE_PMULHW:
7901 case INTRINS_SSE_PMULHU:
7902 add_sse_binary (module, name, MONO_TYPE_I2);
7904 case INTRINS_SSE_MINPS:
7905 case INTRINS_SSE_MAXPS:
7906 case INTRINS_SSE_HADDPS:
7907 case INTRINS_SSE_HSUBPS:
7908 case INTRINS_SSE_ADDSUBPS:
7909 add_sse_binary (module, name, MONO_TYPE_R4);
7911 case INTRINS_SSE_MINPD:
7912 case INTRINS_SSE_MAXPD:
7913 case INTRINS_SSE_HADDPD:
7914 case INTRINS_SSE_HSUBPD:
7915 case INTRINS_SSE_ADDSUBPD:
7916 add_sse_binary (module, name, MONO_TYPE_R8);
7918 case INTRINS_SSE_PMINUB:
7919 case INTRINS_SSE_PMAXUB:
7920 case INTRINS_SE_PADDSB:
7921 case INTRINS_SSE_PSUBSB:
7922 case INTRINS_SSE_PADDUSB:
7923 case INTRINS_SSE_PSUBUSB:
7924 case INTRINS_SSE_PAVGB:
7925 add_sse_binary (module, name, MONO_TYPE_I1);
7927 case INTRINS_SSE_PAUSE:
7928 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7932 g_assert_not_reached ();
7938 get_intrinsic (EmitContext *ctx, const char *name)
7940 #if LLVM_API_VERSION > 100
7944 * Every method is emitted into its own module so
7945 * we can add intrinsics on demand.
7947 res = LLVMGetNamedFunction (ctx->lmodule, name);
7951 /* No locking needed */
7952 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
7955 printf ("%s\n", name);
7956 g_assert (id != -1);
7957 add_intrinsic (ctx->lmodule, id);
7958 res = LLVMGetNamedFunction (ctx->lmodule, name);
7966 res = LLVMGetNamedFunction (ctx->lmodule, name);
7973 add_intrinsics (LLVMModuleRef module)
7977 /* Emit declarations of instrinsics */
7979 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7980 * type doesn't seem to do any locking.
7982 for (i = 0; i < INTRINS_NUM; ++i)
7983 add_intrinsic (module, i);
7987 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7989 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7992 /* SSE intrinsics */
7993 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7997 /* Load/Store intrinsics */
7999 LLVMTypeRef arg_types [5];
8003 for (i = 1; i <= 8; i *= 2) {
8004 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8005 arg_types [1] = LLVMInt32Type ();
8006 arg_types [2] = LLVMInt1Type ();
8007 arg_types [3] = LLVMInt32Type ();
8008 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8009 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8011 arg_types [0] = LLVMIntType (i * 8);
8012 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8013 arg_types [2] = LLVMInt32Type ();
8014 arg_types [3] = LLVMInt1Type ();
8015 arg_types [4] = LLVMInt32Type ();
8016 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8017 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8023 add_types (MonoLLVMModule *module)
8025 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8029 mono_llvm_init (void)
8034 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8036 h = g_hash_table_new (NULL, NULL);
8037 for (i = 0; i < INTRINS_NUM; ++i)
8038 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8039 intrins_id_to_name = h;
8041 h = g_hash_table_new (g_str_hash, g_str_equal);
8042 for (i = 0; i < INTRINS_NUM; ++i)
8043 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8044 intrins_name_to_id = h;
8048 init_jit_module (MonoDomain *domain)
8050 MonoJitDomainInfo *dinfo;
8051 MonoLLVMModule *module;
8054 dinfo = domain_jit_info (domain);
8055 if (dinfo->llvm_module)
8058 mono_loader_lock ();
8060 if (dinfo->llvm_module) {
8061 mono_loader_unlock ();
8065 module = g_new0 (MonoLLVMModule, 1);
8067 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8068 module->lmodule = LLVMModuleCreateWithName (name);
8069 module->context = LLVMGetGlobalContext ();
8071 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8073 add_intrinsics (module->lmodule);
8076 module->llvm_types = g_hash_table_new (NULL, NULL);
8078 #if LLVM_API_VERSION < 100
8079 MonoJitICallInfo *info;
8081 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8083 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8086 mono_memory_barrier ();
8088 dinfo->llvm_module = module;
8090 mono_loader_unlock ();
8094 mono_llvm_cleanup (void)
8096 MonoLLVMModule *module = &aot_module;
8098 if (module->lmodule)
8099 LLVMDisposeModule (module->lmodule);
8101 if (module->context)
8102 LLVMContextDispose (module->context);
8106 mono_llvm_free_domain_info (MonoDomain *domain)
8108 MonoJitDomainInfo *info = domain_jit_info (domain);
8109 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8115 if (module->llvm_types)
8116 g_hash_table_destroy (module->llvm_types);
8118 mono_llvm_dispose_ee (module->mono_ee);
8120 if (module->bb_names) {
8121 for (i = 0; i < module->bb_names_len; ++i)
8122 g_free (module->bb_names [i]);
8123 g_free (module->bb_names);
8125 //LLVMDisposeModule (module->module);
8129 info->llvm_module = NULL;
8133 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8135 MonoLLVMModule *module = &aot_module;
8137 /* Delete previous module */
8138 if (module->plt_entries)
8139 g_hash_table_destroy (module->plt_entries);
8140 if (module->lmodule)
8141 LLVMDisposeModule (module->lmodule);
8143 memset (module, 0, sizeof (aot_module));
8145 module->lmodule = LLVMModuleCreateWithName ("aot");
8146 module->assembly = assembly;
8147 module->global_prefix = g_strdup (global_prefix);
8148 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8149 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8150 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8151 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8152 module->external_symbols = TRUE;
8153 module->emit_dwarf = emit_dwarf;
8154 module->static_link = static_link;
8155 module->llvm_only = llvm_only;
8156 /* The first few entries are reserved */
8157 module->max_got_offset = 16;
8158 module->context = LLVMContextCreate ();
8161 /* clang ignores our debug info because it has an invalid version */
8162 module->emit_dwarf = FALSE;
8164 #if LLVM_API_VERSION > 100
8165 module->emit_dwarf = FALSE;
8168 add_intrinsics (module->lmodule);
8171 #if LLVM_API_VERSION > 100
8172 if (module->emit_dwarf) {
8173 char *dir, *build_info, *s, *cu_name;
8175 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8178 dir = g_strdup (".");
8179 build_info = mono_get_runtime_build_info ();
8180 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8181 cu_name = g_path_get_basename (assembly->image->name);
8182 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8184 g_free (build_info);
8191 * We couldn't compute the type of the LLVM global representing the got because
8192 * its size is only known after all the methods have been emitted. So create
8193 * a dummy variable, and replace all uses it with the real got variable when
8194 * its size is known in mono_llvm_emit_aot_module ().
8197 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8199 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8200 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8203 /* Add initialization array */
8205 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8207 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8208 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8212 emit_init_icall_wrappers (module);
8214 emit_llvm_code_start (module);
8216 /* Add a dummy personality function */
8217 if (!use_debug_personality) {
8218 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8219 LLVMSetLinkage (personality, LLVMExternalLinkage);
8220 mark_as_used (module, personality);
8223 /* Add a reference to the c++ exception we throw/catch */
8225 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8226 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8227 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8228 mono_llvm_set_is_constant (module->sentinel_exception);
8231 module->llvm_types = g_hash_table_new (NULL, NULL);
8232 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8233 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8234 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8235 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8236 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8237 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8238 module->method_to_callers = g_hash_table_new (NULL, NULL);
8242 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8245 LLVMValueRef res, *vals;
8247 vals = g_new0 (LLVMValueRef, nvalues);
8248 for (i = 0; i < nvalues; ++i)
8249 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8250 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8256 * mono_llvm_emit_aot_file_info:
8258 * Emit the MonoAotFileInfo structure.
8259 * Same as emit_aot_file_info () in aot-compiler.c.
8262 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8264 MonoLLVMModule *module = &aot_module;
8266 /* Save these for later */
8267 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8268 module->has_jitted_code = has_jitted_code;
8272 * mono_llvm_emit_aot_data:
8274 * Emit the binary data DATA pointed to by symbol SYMBOL.
8277 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8279 MonoLLVMModule *module = &aot_module;
8283 type = LLVMArrayType (LLVMInt8Type (), data_len);
8284 d = LLVMAddGlobal (module->lmodule, type, symbol);
8285 LLVMSetVisibility (d, LLVMHiddenVisibility);
8286 LLVMSetLinkage (d, LLVMInternalLinkage);
8287 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8288 mono_llvm_set_is_constant (d);
8291 /* Add a reference to a global defined in JITted code */
8293 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8298 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8299 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8305 emit_aot_file_info (MonoLLVMModule *module)
8307 LLVMTypeRef file_info_type;
8308 LLVMTypeRef *eltypes, eltype;
8309 LLVMValueRef info_var;
8310 LLVMValueRef *fields;
8311 int i, nfields, tindex;
8312 MonoAotFileInfo *info;
8313 LLVMModuleRef lmodule = module->lmodule;
8315 info = &module->aot_info;
8317 /* Create an LLVM type to represent MonoAotFileInfo */
8318 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8319 eltypes = g_new (LLVMTypeRef, nfields);
8321 eltypes [tindex ++] = LLVMInt32Type ();
8322 eltypes [tindex ++] = LLVMInt32Type ();
8324 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8325 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8327 for (i = 0; i < 15; ++i)
8328 eltypes [tindex ++] = LLVMInt32Type ();
8330 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8331 for (i = 0; i < 4; ++i)
8332 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8333 g_assert (tindex == nfields);
8334 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8335 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8337 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8338 if (module->static_link) {
8339 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8340 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8342 fields = g_new (LLVMValueRef, nfields);
8344 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8345 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8349 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8350 * for symbols defined in the .s file emitted by the aot compiler.
8352 eltype = eltypes [tindex];
8353 if (module->llvm_only)
8354 fields [tindex ++] = LLVMConstNull (eltype);
8356 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8357 fields [tindex ++] = module->got_var;
8358 /* llc defines this directly */
8359 if (!module->llvm_only) {
8360 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8361 fields [tindex ++] = LLVMConstNull (eltype);
8362 fields [tindex ++] = LLVMConstNull (eltype);
8364 fields [tindex ++] = LLVMConstNull (eltype);
8365 fields [tindex ++] = module->get_method;
8366 fields [tindex ++] = module->get_unbox_tramp;
8368 if (module->has_jitted_code) {
8369 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8370 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8372 fields [tindex ++] = LLVMConstNull (eltype);
8373 fields [tindex ++] = LLVMConstNull (eltype);
8375 if (!module->llvm_only)
8376 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8378 fields [tindex ++] = LLVMConstNull (eltype);
8379 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8380 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8381 fields [tindex ++] = LLVMConstNull (eltype);
8383 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8384 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8385 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8386 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8387 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8388 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8389 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8390 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8391 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8392 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8394 /* Not needed (mem_end) */
8395 fields [tindex ++] = LLVMConstNull (eltype);
8396 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8397 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8398 if (info->trampoline_size [0]) {
8399 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8400 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8401 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8402 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8404 fields [tindex ++] = LLVMConstNull (eltype);
8405 fields [tindex ++] = LLVMConstNull (eltype);
8406 fields [tindex ++] = LLVMConstNull (eltype);
8407 fields [tindex ++] = LLVMConstNull (eltype);
8409 if (module->static_link && !module->llvm_only)
8410 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8412 fields [tindex ++] = LLVMConstNull (eltype);
8413 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8414 if (!module->llvm_only) {
8415 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8416 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8417 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8418 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8419 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8420 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8422 fields [tindex ++] = LLVMConstNull (eltype);
8423 fields [tindex ++] = LLVMConstNull (eltype);
8424 fields [tindex ++] = LLVMConstNull (eltype);
8425 fields [tindex ++] = LLVMConstNull (eltype);
8426 fields [tindex ++] = LLVMConstNull (eltype);
8427 fields [tindex ++] = LLVMConstNull (eltype);
8430 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8431 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8434 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8435 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8436 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8437 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8438 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8439 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8440 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8441 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8442 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8443 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8444 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8445 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8446 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8447 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8448 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8450 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8451 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8452 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8453 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8454 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8455 g_assert (tindex == nfields);
8457 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8459 if (module->static_link) {
8463 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8464 /* Get rid of characters which cannot occur in symbols */
8466 for (p = s; *p; ++p) {
8467 if (!(isalnum (*p) || *p == '_'))
8470 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8472 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8473 LLVMSetLinkage (var, LLVMExternalLinkage);
8478 * Emit the aot module into the LLVM bitcode file FILENAME.
8481 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8483 LLVMTypeRef got_type, inited_type;
8484 LLVMValueRef real_got, real_inited;
8485 MonoLLVMModule *module = &aot_module;
8487 emit_llvm_code_end (module);
8490 * Create the real got variable and replace all uses of the dummy variable with
8493 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8494 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8495 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8496 if (module->external_symbols) {
8497 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8498 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8500 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8502 mono_llvm_replace_uses_of (module->got_var, real_got);
8504 mark_as_used (&aot_module, real_got);
8506 /* Delete the dummy got so it doesn't become a global */
8507 LLVMDeleteGlobal (module->got_var);
8508 module->got_var = real_got;
8511 * Same for the init_var
8513 if (module->llvm_only) {
8514 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8515 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8516 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8517 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8518 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8519 LLVMDeleteGlobal (module->inited_var);
8522 if (module->llvm_only) {
8523 emit_get_method (&aot_module);
8524 emit_get_unbox_tramp (&aot_module);
8527 emit_llvm_used (&aot_module);
8528 emit_dbg_info (&aot_module, filename, cu_name);
8529 emit_aot_file_info (&aot_module);
8532 * Replace GOT entries for directly callable methods with the methods themselves.
8533 * It would be easier to implement this by predefining all methods before compiling
8534 * their bodies, but that couldn't handle the case when a method fails to compile
8537 if (module->llvm_only) {
8538 GHashTableIter iter;
8540 GSList *callers, *l;
8542 g_hash_table_iter_init (&iter, module->method_to_callers);
8543 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8544 LLVMValueRef lmethod;
8546 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8548 for (l = callers; l; l = l->next) {
8549 LLVMValueRef caller = (LLVMValueRef)l->data;
8551 mono_llvm_replace_uses_of (caller, lmethod);
8557 /* Replace PLT entries for directly callable methods with the methods themselves */
8559 GHashTableIter iter;
8561 LLVMValueRef callee;
8563 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8564 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8565 if (mono_aot_is_direct_callable (ji)) {
8566 LLVMValueRef lmethod;
8568 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8569 /* The types might not match because the caller might pass an rgctx */
8570 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8571 mono_llvm_replace_uses_of (callee, lmethod);
8572 mono_aot_mark_unused_llvm_plt_entry (ji);
8582 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8583 g_assert_not_reached ();
8588 LLVMWriteBitcodeToFile (module->lmodule, filename);
8593 md_string (const char *s)
8595 return LLVMMDString (s, strlen (s));
8598 /* Debugging support */
8601 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8603 LLVMModuleRef lmodule = module->lmodule;
8604 LLVMValueRef args [16], ver;
8607 * This can only be enabled when LLVM code is emitted into a separate object
8608 * file, since the AOT compiler also emits dwarf info,
8609 * and the abbrev indexes will not be correct since llvm has added its own
8612 if (!module->emit_dwarf)
8615 #if LLVM_API_VERSION > 100
8616 mono_llvm_di_builder_finalize (module->di_builder);
8618 LLVMValueRef cu_args [16], cu;
8620 char *build_info, *s, *dir;
8623 * Emit dwarf info in the form of LLVM metadata. There is some
8624 * out-of-date documentation at:
8625 * http://llvm.org/docs/SourceLevelDebugging.html
8626 * but most of this was gathered from the llvm and
8631 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8632 /* CU name/compilation dir */
8633 dir = g_path_get_dirname (filename);
8634 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8635 args [1] = LLVMMDString (dir, strlen (dir));
8636 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8639 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8641 build_info = mono_get_runtime_build_info ();
8642 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8643 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8644 g_free (build_info);
8646 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8648 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8649 /* Runtime version */
8650 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8652 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8653 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8655 if (module->subprogram_mds) {
8659 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8660 for (i = 0; i < module->subprogram_mds->len; ++i)
8661 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8662 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8664 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8667 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8668 /* Imported modules */
8669 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8671 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8672 /* DebugEmissionKind = FullDebug */
8673 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8674 cu = LLVMMDNode (cu_args, n_cuargs);
8675 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8678 #if LLVM_API_VERSION > 100
8679 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8680 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8681 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8682 ver = LLVMMDNode (args, 3);
8683 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8685 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8686 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8687 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8688 ver = LLVMMDNode (args, 3);
8689 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8691 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8692 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8693 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8694 ver = LLVMMDNode (args, 3);
8695 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8697 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8698 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8699 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8700 ver = LLVMMDNode (args, 3);
8701 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8706 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8708 MonoLLVMModule *module = ctx->module;
8709 MonoDebugMethodInfo *minfo = ctx->minfo;
8710 char *source_file, *dir, *filename;
8711 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8712 MonoSymSeqPoint *sym_seq_points;
8718 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8720 source_file = g_strdup ("<unknown>");
8721 dir = g_path_get_dirname (source_file);
8722 filename = g_path_get_basename (source_file);
8724 #if LLVM_API_VERSION > 100
8725 return mono_llvm_di_create_function (module->di_builder, module->cu, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
8728 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8729 args [0] = md_string (filename);
8730 args [1] = md_string (dir);
8731 ctx_args [1] = LLVMMDNode (args, 2);
8732 ctx_md = LLVMMDNode (ctx_args, 2);
8734 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8735 type_args [1] = NULL;
8736 type_args [2] = NULL;
8737 type_args [3] = LLVMMDString ("", 0);
8738 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8739 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8740 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8741 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8742 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8743 type_args [9] = NULL;
8744 type_args [10] = NULL;
8745 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8746 type_args [12] = NULL;
8747 type_args [13] = NULL;
8748 type_args [14] = NULL;
8749 type_md = LLVMMDNode (type_args, 14);
8751 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8752 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8753 /* Source directory + file pair */
8754 args [0] = md_string (filename);
8755 args [1] = md_string (dir);
8756 md_args [1] = LLVMMDNode (args ,2);
8757 md_args [2] = ctx_md;
8758 md_args [3] = md_string (cfg->method->name);
8759 md_args [4] = md_string (name);
8760 md_args [5] = md_string (name);
8763 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8765 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8767 md_args [7] = type_md;
8769 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8771 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8773 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8774 /* Index into a virtual function */
8775 md_args [11] = NULL;
8776 md_args [12] = NULL;
8778 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8780 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8781 /* Pointer to LLVM function */
8782 md_args [15] = method;
8783 /* Function template parameter */
8784 md_args [16] = NULL;
8785 /* Function declaration descriptor */
8786 md_args [17] = NULL;
8787 /* List of function variables */
8788 md_args [18] = LLVMMDNode (args, 0);
8790 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8791 md = LLVMMDNode (md_args, 20);
8793 if (!module->subprogram_mds)
8794 module->subprogram_mds = g_ptr_array_new ();
8795 g_ptr_array_add (module->subprogram_mds, md);
8799 g_free (source_file);
8800 g_free (sym_seq_points);
8806 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8808 MonoCompile *cfg = ctx->cfg;
8810 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8811 MonoDebugSourceLocation *loc;
8812 LLVMValueRef loc_md;
8814 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8817 #if LLVM_API_VERSION > 100
8818 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8819 mono_llvm_di_set_location (builder, loc_md);
8821 LLVMValueRef md_args [16];
8825 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8826 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8827 md_args [nmd_args ++] = ctx->dbg_md;
8828 md_args [nmd_args ++] = NULL;
8829 loc_md = LLVMMDNode (md_args, nmd_args);
8830 LLVMSetCurrentDebugLocation (builder, loc_md);
8832 mono_debug_symfile_free_location (loc);
8838 default_mono_llvm_unhandled_exception (void)
8840 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8841 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8843 mono_unhandled_exception (target);
8844 exit (mono_environment_exitcode_get ());
8849 - Emit LLVM IR from the mono IR using the LLVM C API.
8850 - The original arch specific code remains, so we can fall back to it if we run
8851 into something we can't handle.
8855 A partial list of issues:
8856 - Handling of opcodes which can throw exceptions.
8858 In the mono JIT, these are implemented using code like this:
8865 push throw_pos - method
8866 call <exception trampoline>
8868 The problematic part is push throw_pos - method, which cannot be represented
8869 in the LLVM IR, since it does not support label values.
8870 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8871 be implemented in JIT mode ?
8872 -> a possible but slower implementation would use the normal exception
8873 throwing code but it would need to control the placement of the throw code
8874 (it needs to be exactly after the compare+branch).
8875 -> perhaps add a PC offset intrinsics ?
8877 - efficient implementation of .ovf opcodes.
8879 These are currently implemented as:
8880 <ins which sets the condition codes>
8883 Some overflow opcodes are now supported by LLVM SVN.
8885 - exception handling, unwinding.
8886 - SSA is disabled for methods with exception handlers
8887 - How to obtain unwind info for LLVM compiled methods ?
8888 -> this is now solved by converting the unwind info generated by LLVM
8890 - LLVM uses the c++ exception handling framework, while we use our home grown
8891 code, and couldn't use the c++ one:
8892 - its not supported under VC++, other exotic platforms.
8893 - it might be impossible to support filter clauses with it.
8897 The trampolines need a predictable call sequence, since they need to disasm
8898 the calling code to obtain register numbers / offsets.
8900 LLVM currently generates this code in non-JIT mode:
8901 mov -0x98(%rax),%eax
8903 Here, the vtable pointer is lost.
8904 -> solution: use one vtable trampoline per class.
8906 - passing/receiving the IMT pointer/RGCTX.
8907 -> solution: pass them as normal arguments ?
8911 LLVM does not allow the specification of argument registers etc. This means
8912 that all calls are made according to the platform ABI.
8914 - passing/receiving vtypes.
8916 Vtypes passed/received in registers are handled by the front end by using
8917 a signature with scalar arguments, and loading the parts of the vtype into those
8920 Vtypes passed on the stack are handled using the 'byval' attribute.
8924 Supported though alloca, we need to emit the load/store code.
8928 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8929 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8930 This is made easier because the IR is already in SSA form.
8931 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8932 types are frequently used incorrectly.
8937 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8938 it with the file containing the methods emitted by the JIT and the AOT data
8942 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8943 * - each bblock should end with a branch
8944 * - setting the return value, making cfg->ret non-volatile
8945 * - avoid some transformations in the JIT which make it harder for us to generate
8947 * - use pointer types to help optimizations.