2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/metadata/environment.h>
13 #include <mono/metadata/object-internals.h>
14 #include <mono/metadata/abi-details.h>
15 #include <mono/utils/mono-tls.h>
16 #include <mono/utils/mono-dl.h>
17 #include <mono/utils/mono-time.h>
18 #include <mono/utils/freebsd-dwarf.h>
20 #ifndef __STDC_LIMIT_MACROS
21 #define __STDC_LIMIT_MACROS
23 #ifndef __STDC_CONSTANT_MACROS
24 #define __STDC_CONSTANT_MACROS
27 #include "llvm-c/Core.h"
28 #include "llvm-c/ExecutionEngine.h"
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
49 * Information associated by mono with LLVM modules.
52 LLVMModuleRef lmodule;
53 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
54 GHashTable *llvm_types;
56 const char *got_symbol;
57 const char *get_method_symbol;
58 const char *get_unbox_tramp_symbol;
59 GHashTable *plt_entries;
60 GHashTable *plt_entries_ji;
61 GHashTable *method_to_lmethod;
62 GHashTable *direct_callables;
67 GPtrArray *subprogram_mds;
69 LLVMExecutionEngineRef ee;
70 gboolean external_symbols;
75 MonoAssembly *assembly;
77 MonoAotFileInfo aot_info;
78 const char *jit_got_symbol;
79 const char *eh_frame_symbol;
80 LLVMValueRef get_method, get_unbox_tramp;
81 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
82 LLVMValueRef code_start, code_end;
83 LLVMValueRef inited_var;
84 int max_inited_idx, max_method_idx;
85 gboolean has_jitted_code;
88 GHashTable *idx_to_lmethod;
89 GHashTable *idx_to_unbox_tramp;
90 /* Maps a MonoMethod to LLVM instructions representing it */
91 GHashTable *method_to_callers;
92 LLVMContextRef context;
93 LLVMValueRef sentinel_exception;
97 * Information associated by the backend with mono basic blocks.
100 LLVMBasicBlockRef bblock, end_bblock;
101 LLVMValueRef finally_ind;
102 gboolean added, invoke_target;
104 * If this bblock is the start of a finally clause, this is a list of bblocks it
105 * needs to branch to in ENDFINALLY.
107 GSList *call_handler_return_bbs;
109 * If this bblock is the start of a finally clause, this is the bblock that
110 * CALL_HANDLER needs to branch to.
112 LLVMBasicBlockRef call_handler_target_bb;
113 /* The list of switch statements generated by ENDFINALLY instructions */
114 GSList *endfinally_switch_ins_list;
119 * Structure containing emit state
122 MonoMemPool *mempool;
124 /* Maps method names to the corresponding LLVMValueRef */
125 GHashTable *emitted_method_decls;
128 LLVMValueRef lmethod;
129 MonoLLVMModule *module;
130 LLVMModuleRef lmodule;
132 int sindex, default_index, ex_index;
133 LLVMBuilderRef builder;
134 LLVMValueRef *values, *addresses;
135 MonoType **vreg_cli_types;
137 MonoMethodSignature *sig;
139 GHashTable *region_to_handler;
140 GHashTable *clause_to_handler;
141 LLVMBuilderRef alloca_builder;
142 LLVMValueRef last_alloca;
143 LLVMValueRef rgctx_arg;
144 LLVMValueRef this_arg;
145 LLVMTypeRef *vreg_types;
146 LLVMBasicBlockRef init_bb, inited_bb;
148 gboolean *unreachable;
150 gboolean has_got_access;
151 int this_arg_pindex, rgctx_arg_pindex;
152 LLVMValueRef imt_rgctx_loc;
153 GHashTable *llvm_types;
155 MonoDebugMethodInfo *minfo;
157 /* For every clause, the clauses it is nested in */
160 GHashTable *exc_meta;
161 GHashTable *method_to_callers;
167 MonoBasicBlock *in_bb;
172 * Instruction metadata
173 * This is the same as ins_info, but LREG != IREG.
181 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
182 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
189 /* keep in sync with the enum in mini.h */
192 #include "mini-ops.h"
197 #if SIZEOF_VOID_P == 4
198 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
200 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
203 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
206 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
208 #define TRACE_FAILURE(msg)
212 #define IS_TARGET_X86 1
214 #define IS_TARGET_X86 0
218 #define IS_TARGET_AMD64 1
220 #define IS_TARGET_AMD64 0
223 #define LLVM_FAILURE(ctx, reason) do { \
224 TRACE_FAILURE (reason); \
225 (ctx)->cfg->exception_message = g_strdup (reason); \
226 (ctx)->cfg->disable_llvm = TRUE; \
230 #define CHECK_FAILURE(ctx) do { \
231 if ((ctx)->cfg->disable_llvm) \
235 static LLVMIntPredicate cond_to_llvm_cond [] = {
248 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
261 static MonoNativeTlsKey current_cfg_tls_id;
263 static MonoLLVMModule aot_module;
264 static int memset_param_count, memcpy_param_count;
265 static const char *memset_func_name;
266 static const char *memcpy_func_name;
268 static void init_jit_module (MonoDomain *domain);
270 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
271 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
272 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
277 * The LLVM type with width == sizeof (gpointer)
282 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
288 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
294 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
300 * Return the size of the LLVM representation of the vtype T.
303 get_vtype_size (MonoType *t)
307 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
309 /* LLVMArgAsIArgs depends on this since it stores whole words */
310 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
317 * simd_class_to_llvm_type:
319 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
322 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
324 if (!strcmp (klass->name, "Vector2d")) {
325 return LLVMVectorType (LLVMDoubleType (), 2);
326 } else if (!strcmp (klass->name, "Vector2l")) {
327 return LLVMVectorType (LLVMInt64Type (), 2);
328 } else if (!strcmp (klass->name, "Vector2ul")) {
329 return LLVMVectorType (LLVMInt64Type (), 2);
330 } else if (!strcmp (klass->name, "Vector4i")) {
331 return LLVMVectorType (LLVMInt32Type (), 4);
332 } else if (!strcmp (klass->name, "Vector4ui")) {
333 return LLVMVectorType (LLVMInt32Type (), 4);
334 } else if (!strcmp (klass->name, "Vector4f")) {
335 return LLVMVectorType (LLVMFloatType (), 4);
336 } else if (!strcmp (klass->name, "Vector8s")) {
337 return LLVMVectorType (LLVMInt16Type (), 8);
338 } else if (!strcmp (klass->name, "Vector8us")) {
339 return LLVMVectorType (LLVMInt16Type (), 8);
340 } else if (!strcmp (klass->name, "Vector16sb")) {
341 return LLVMVectorType (LLVMInt8Type (), 16);
342 } else if (!strcmp (klass->name, "Vector16b")) {
343 return LLVMVectorType (LLVMInt8Type (), 16);
345 printf ("%s\n", klass->name);
351 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
352 static inline G_GNUC_UNUSED LLVMTypeRef
353 type_to_simd_type (int type)
357 return LLVMVectorType (LLVMInt8Type (), 16);
359 return LLVMVectorType (LLVMInt16Type (), 8);
361 return LLVMVectorType (LLVMInt32Type (), 4);
363 return LLVMVectorType (LLVMInt64Type (), 2);
365 return LLVMVectorType (LLVMDoubleType (), 2);
367 return LLVMVectorType (LLVMFloatType (), 4);
369 g_assert_not_reached ();
375 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
377 int i, size, nfields, esize;
378 LLVMTypeRef *eltypes;
383 t = &klass->byval_arg;
385 if (mini_type_is_hfa (t, &nfields, &esize)) {
387 * This is needed on arm64 where HFAs are returned in
391 eltypes = g_new (LLVMTypeRef, size);
392 for (i = 0; i < size; ++i)
393 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
395 size = get_vtype_size (t);
397 eltypes = g_new (LLVMTypeRef, size);
398 for (i = 0; i < size; ++i)
399 eltypes [i] = LLVMInt8Type ();
402 name = mono_type_full_name (&klass->byval_arg);
403 ltype = LLVMStructCreateNamed (module->context, name);
404 LLVMStructSetBody (ltype, eltypes, size, FALSE);
414 * Return the LLVM type corresponding to T.
417 type_to_llvm_type (EmitContext *ctx, MonoType *t)
419 t = mini_get_underlying_type (t);
423 return LLVMVoidType ();
425 return LLVMInt8Type ();
427 return LLVMInt16Type ();
429 return LLVMInt32Type ();
431 return LLVMInt8Type ();
433 return LLVMInt16Type ();
435 return LLVMInt32Type ();
436 case MONO_TYPE_BOOLEAN:
437 return LLVMInt8Type ();
440 return LLVMInt64Type ();
442 return LLVMInt16Type ();
444 return LLVMFloatType ();
446 return LLVMDoubleType ();
449 return IntPtrType ();
450 case MONO_TYPE_OBJECT:
451 case MONO_TYPE_CLASS:
452 case MONO_TYPE_ARRAY:
453 case MONO_TYPE_SZARRAY:
454 case MONO_TYPE_STRING:
456 return ObjRefType ();
459 /* Because of generic sharing */
460 return ObjRefType ();
461 case MONO_TYPE_GENERICINST:
462 if (!mono_type_generic_inst_is_valuetype (t))
463 return ObjRefType ();
465 case MONO_TYPE_VALUETYPE:
466 case MONO_TYPE_TYPEDBYREF: {
470 klass = mono_class_from_mono_type (t);
472 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
473 return simd_class_to_llvm_type (ctx, klass);
476 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
478 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
480 ltype = create_llvm_type_for_type (ctx->module, klass);
481 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
487 printf ("X: %d\n", t->type);
488 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
489 ctx->cfg->disable_llvm = TRUE;
497 * Return whenever T is an unsigned int type.
500 type_is_unsigned (EmitContext *ctx, MonoType *t)
517 * type_to_llvm_arg_type:
519 * Same as type_to_llvm_type, but treat i8/i16 as i32.
522 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
524 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
526 if (ctx->cfg->llvm_only)
530 * This works on all abis except arm64/ios which passes multiple
531 * arguments in one stack slot.
534 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
536 * LLVM generates code which only sets the lower bits, while JITted
537 * code expects all the bits to be set.
539 ptype = LLVMInt32Type ();
547 * llvm_type_to_stack_type:
549 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
552 static G_GNUC_UNUSED LLVMTypeRef
553 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
557 if (type == LLVMInt8Type ())
558 return LLVMInt32Type ();
559 else if (type == LLVMInt16Type ())
560 return LLVMInt32Type ();
561 else if (!cfg->r4fp && type == LLVMFloatType ())
562 return LLVMDoubleType ();
568 * regtype_to_llvm_type:
570 * Return the LLVM type corresponding to the regtype C used in instruction
574 regtype_to_llvm_type (char c)
578 return LLVMInt32Type ();
580 return LLVMInt64Type ();
582 return LLVMDoubleType ();
591 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
594 op_to_llvm_type (int opcode)
599 return LLVMInt8Type ();
602 return LLVMInt8Type ();
605 return LLVMInt16Type ();
608 return LLVMInt16Type ();
611 return LLVMInt32Type ();
614 return LLVMInt32Type ();
616 return LLVMInt64Type ();
618 return LLVMFloatType ();
620 return LLVMDoubleType ();
622 return LLVMInt64Type ();
624 return LLVMInt32Type ();
626 return LLVMInt64Type ();
631 return LLVMInt8Type ();
636 return LLVMInt16Type ();
638 return LLVMInt32Type ();
641 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
648 return LLVMInt32Type ();
655 return LLVMInt64Type ();
657 printf ("%s\n", mono_inst_name (opcode));
658 g_assert_not_reached ();
663 #define CLAUSE_START(clause) ((clause)->try_offset)
664 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
667 * load_store_to_llvm_type:
669 * Return the size/sign/zero extension corresponding to the load/store opcode
673 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
679 case OP_LOADI1_MEMBASE:
680 case OP_STOREI1_MEMBASE_REG:
681 case OP_STOREI1_MEMBASE_IMM:
682 case OP_ATOMIC_LOAD_I1:
683 case OP_ATOMIC_STORE_I1:
686 return LLVMInt8Type ();
687 case OP_LOADU1_MEMBASE:
689 case OP_ATOMIC_LOAD_U1:
690 case OP_ATOMIC_STORE_U1:
693 return LLVMInt8Type ();
694 case OP_LOADI2_MEMBASE:
695 case OP_STOREI2_MEMBASE_REG:
696 case OP_STOREI2_MEMBASE_IMM:
697 case OP_ATOMIC_LOAD_I2:
698 case OP_ATOMIC_STORE_I2:
701 return LLVMInt16Type ();
702 case OP_LOADU2_MEMBASE:
704 case OP_ATOMIC_LOAD_U2:
705 case OP_ATOMIC_STORE_U2:
708 return LLVMInt16Type ();
709 case OP_LOADI4_MEMBASE:
710 case OP_LOADU4_MEMBASE:
713 case OP_STOREI4_MEMBASE_REG:
714 case OP_STOREI4_MEMBASE_IMM:
715 case OP_ATOMIC_LOAD_I4:
716 case OP_ATOMIC_STORE_I4:
717 case OP_ATOMIC_LOAD_U4:
718 case OP_ATOMIC_STORE_U4:
720 return LLVMInt32Type ();
721 case OP_LOADI8_MEMBASE:
723 case OP_STOREI8_MEMBASE_REG:
724 case OP_STOREI8_MEMBASE_IMM:
725 case OP_ATOMIC_LOAD_I8:
726 case OP_ATOMIC_STORE_I8:
727 case OP_ATOMIC_LOAD_U8:
728 case OP_ATOMIC_STORE_U8:
730 return LLVMInt64Type ();
731 case OP_LOADR4_MEMBASE:
732 case OP_STORER4_MEMBASE_REG:
733 case OP_ATOMIC_LOAD_R4:
734 case OP_ATOMIC_STORE_R4:
736 return LLVMFloatType ();
737 case OP_LOADR8_MEMBASE:
738 case OP_STORER8_MEMBASE_REG:
739 case OP_ATOMIC_LOAD_R8:
740 case OP_ATOMIC_STORE_R8:
742 return LLVMDoubleType ();
743 case OP_LOAD_MEMBASE:
745 case OP_STORE_MEMBASE_REG:
746 case OP_STORE_MEMBASE_IMM:
747 *size = sizeof (gpointer);
748 return IntPtrType ();
750 g_assert_not_reached ();
758 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
761 ovf_op_to_intrins (int opcode)
765 return "llvm.sadd.with.overflow.i32";
767 return "llvm.uadd.with.overflow.i32";
769 return "llvm.ssub.with.overflow.i32";
771 return "llvm.usub.with.overflow.i32";
773 return "llvm.smul.with.overflow.i32";
775 return "llvm.umul.with.overflow.i32";
777 return "llvm.sadd.with.overflow.i64";
779 return "llvm.uadd.with.overflow.i64";
781 return "llvm.ssub.with.overflow.i64";
783 return "llvm.usub.with.overflow.i64";
785 return "llvm.smul.with.overflow.i64";
787 return "llvm.umul.with.overflow.i64";
789 g_assert_not_reached ();
795 simd_op_to_intrins (int opcode)
798 #if defined(TARGET_X86) || defined(TARGET_AMD64)
800 return "llvm.x86.sse2.min.pd";
802 return "llvm.x86.sse.min.ps";
804 return "llvm.x86.sse41.pminud";
806 return "llvm.x86.sse41.pminuw";
808 return "llvm.x86.sse2.pminu.b";
810 return "llvm.x86.sse2.pmins.w";
812 return "llvm.x86.sse2.max.pd";
814 return "llvm.x86.sse.max.ps";
816 return "llvm.x86.sse3.hadd.pd";
818 return "llvm.x86.sse3.hadd.ps";
820 return "llvm.x86.sse3.hsub.pd";
822 return "llvm.x86.sse3.hsub.ps";
824 return "llvm.x86.sse41.pmaxud";
826 return "llvm.x86.sse41.pmaxuw";
828 return "llvm.x86.sse2.pmaxu.b";
830 return "llvm.x86.sse3.addsub.ps";
832 return "llvm.x86.sse3.addsub.pd";
833 case OP_EXTRACT_MASK:
834 return "llvm.x86.sse2.pmovmskb.128";
837 return "llvm.x86.sse2.psrli.w";
840 return "llvm.x86.sse2.psrli.d";
843 return "llvm.x86.sse2.psrli.q";
846 return "llvm.x86.sse2.pslli.w";
849 return "llvm.x86.sse2.pslli.d";
852 return "llvm.x86.sse2.pslli.q";
855 return "llvm.x86.sse2.psrai.w";
858 return "llvm.x86.sse2.psrai.d";
860 return "llvm.x86.sse2.padds.b";
862 return "llvm.x86.sse2.padds.w";
864 return "llvm.x86.sse2.psubs.b";
866 return "llvm.x86.sse2.psubs.w";
867 case OP_PADDB_SAT_UN:
868 return "llvm.x86.sse2.paddus.b";
869 case OP_PADDW_SAT_UN:
870 return "llvm.x86.sse2.paddus.w";
871 case OP_PSUBB_SAT_UN:
872 return "llvm.x86.sse2.psubus.b";
873 case OP_PSUBW_SAT_UN:
874 return "llvm.x86.sse2.psubus.w";
876 return "llvm.x86.sse2.pavg.b";
878 return "llvm.x86.sse2.pavg.w";
880 return "llvm.x86.sse.sqrt.ps";
882 return "llvm.x86.sse2.sqrt.pd";
884 return "llvm.x86.sse.rsqrt.ps";
886 return "llvm.x86.sse.rcp.ps";
888 return "llvm.x86.sse2.cvtdq2pd";
890 return "llvm.x86.sse2.cvtdq2ps";
892 return "llvm.x86.sse2.cvtpd2dq";
894 return "llvm.x86.sse2.cvtps2dq";
896 return "llvm.x86.sse2.cvtpd2ps";
898 return "llvm.x86.sse2.cvtps2pd";
900 return "llvm.x86.sse2.cvttpd2dq";
902 return "llvm.x86.sse2.cvttps2dq";
904 return "llvm.x86.sse.cmp.ps";
906 return "llvm.x86.sse2.cmp.pd";
908 return "llvm.x86.sse2.packsswb.128";
910 return "llvm.x86.sse2.packssdw.128";
912 return "llvm.x86.sse2.packuswb.128";
914 return "llvm.x86.sse41.packusdw";
916 return "llvm.x86.sse2.pmulh.w";
917 case OP_PMULW_HIGH_UN:
918 return "llvm.x86.sse2.pmulhu.w";
921 g_assert_not_reached ();
927 simd_op_to_llvm_type (int opcode)
929 #if defined(TARGET_X86) || defined(TARGET_AMD64)
933 return type_to_simd_type (MONO_TYPE_R8);
936 return type_to_simd_type (MONO_TYPE_I8);
939 return type_to_simd_type (MONO_TYPE_I4);
944 return type_to_simd_type (MONO_TYPE_I2);
948 return type_to_simd_type (MONO_TYPE_I1);
950 return type_to_simd_type (MONO_TYPE_R4);
953 return type_to_simd_type (MONO_TYPE_I4);
957 return type_to_simd_type (MONO_TYPE_R8);
961 return type_to_simd_type (MONO_TYPE_R4);
962 case OP_EXTRACT_MASK:
963 return type_to_simd_type (MONO_TYPE_I1);
969 return type_to_simd_type (MONO_TYPE_R4);
972 return type_to_simd_type (MONO_TYPE_R8);
974 g_assert_not_reached ();
985 * Return the LLVM basic block corresponding to BB.
987 static LLVMBasicBlockRef
988 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
990 char bb_name_buf [128];
993 if (ctx->bblocks [bb->block_num].bblock == NULL) {
994 if (bb->flags & BB_EXCEPTION_HANDLER) {
995 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
996 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
997 bb_name = bb_name_buf;
998 } else if (bb->block_num < 256) {
999 if (!ctx->module->bb_names) {
1000 ctx->module->bb_names_len = 256;
1001 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1003 if (!ctx->module->bb_names [bb->block_num]) {
1006 n = g_strdup_printf ("BB%d", bb->block_num);
1007 mono_memory_barrier ();
1008 ctx->module->bb_names [bb->block_num] = n;
1010 bb_name = ctx->module->bb_names [bb->block_num];
1012 sprintf (bb_name_buf, "BB%d", bb->block_num);
1013 bb_name = bb_name_buf;
1016 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1017 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1020 return ctx->bblocks [bb->block_num].bblock;
1026 * Return the last LLVM bblock corresponding to BB.
1027 * This might not be equal to the bb returned by get_bb () since we need to generate
1028 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1030 static LLVMBasicBlockRef
1031 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1034 return ctx->bblocks [bb->block_num].end_bblock;
1037 static LLVMBasicBlockRef
1038 gen_bb (EmitContext *ctx, const char *prefix)
1042 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1043 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1049 * Return the target of the patch identified by TYPE and TARGET.
1052 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1056 memset (&ji, 0, sizeof (ji));
1058 ji.data.target = target;
1060 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1066 * Emit code to convert the LLVM value V to DTYPE.
1069 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1071 LLVMTypeRef stype = LLVMTypeOf (v);
1073 if (stype != dtype) {
1074 gboolean ext = FALSE;
1077 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1079 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1081 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1085 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1087 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1088 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1091 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1092 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1093 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1094 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1095 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1096 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1097 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1098 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1100 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1101 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1102 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1103 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1104 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1105 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1107 if (mono_arch_is_soft_float ()) {
1108 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1109 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1110 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1111 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1114 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1115 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1118 LLVMDumpValue (LLVMConstNull (dtype));
1119 g_assert_not_reached ();
1127 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1129 return convert_full (ctx, v, dtype, FALSE);
1133 * emit_volatile_load:
1135 * If vreg is volatile, emit a load from its address.
1138 emit_volatile_load (EmitContext *ctx, int vreg)
1142 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1143 t = ctx->vreg_cli_types [vreg];
1144 if (t && !t->byref) {
1146 * Might have to zero extend since llvm doesn't have
1149 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1150 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1151 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1152 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1153 else if (t->type == MONO_TYPE_U8)
1154 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1161 * emit_volatile_store:
1163 * If VREG is volatile, emit a store from its value to its address.
1166 emit_volatile_store (EmitContext *ctx, int vreg)
1168 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1170 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1171 g_assert (ctx->addresses [vreg]);
1172 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1177 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1179 LLVMTypeRef ret_type;
1180 LLVMTypeRef *param_types = NULL;
1185 rtype = mini_get_underlying_type (sig->ret);
1186 ret_type = type_to_llvm_type (ctx, rtype);
1187 CHECK_FAILURE (ctx);
1189 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1193 param_types [pindex ++] = ThisType ();
1194 for (i = 0; i < sig->param_count; ++i)
1195 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1197 CHECK_FAILURE (ctx);
1199 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1200 g_free (param_types);
1205 g_free (param_types);
1211 * sig_to_llvm_sig_full:
1213 * Return the LLVM signature corresponding to the mono signature SIG using the
1214 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1217 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1219 LLVMTypeRef ret_type;
1220 LLVMTypeRef *param_types = NULL;
1222 int i, j, pindex, vret_arg_pindex = 0;
1223 gboolean vretaddr = FALSE;
1227 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1229 rtype = mini_get_underlying_type (sig->ret);
1230 ret_type = type_to_llvm_type (ctx, rtype);
1231 CHECK_FAILURE (ctx);
1233 switch (cinfo->ret.storage) {
1234 case LLVMArgVtypeInReg:
1235 /* LLVM models this by returning an aggregate value */
1236 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1237 LLVMTypeRef members [2];
1239 members [0] = IntPtrType ();
1240 ret_type = LLVMStructType (members, 1, FALSE);
1241 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1243 ret_type = LLVMVoidType ();
1244 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1245 LLVMTypeRef members [2];
1247 members [0] = IntPtrType ();
1248 members [1] = IntPtrType ();
1249 ret_type = LLVMStructType (members, 2, FALSE);
1251 g_assert_not_reached ();
1254 case LLVMArgVtypeByVal:
1255 /* Vtype returned normally by val */
1257 case LLVMArgVtypeAsScalar:
1258 /* LLVM models this by returning an int */
1259 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1260 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1262 case LLVMArgFpStruct: {
1263 /* Vtype returned as a fp struct */
1264 LLVMTypeRef members [16];
1266 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1267 for (i = 0; i < cinfo->ret.nslots; ++i)
1268 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1269 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1272 case LLVMArgVtypeByRef:
1273 /* Vtype returned using a hidden argument */
1274 ret_type = LLVMVoidType ();
1276 case LLVMArgVtypeRetAddr:
1277 case LLVMArgScalarRetAddr:
1278 case LLVMArgGsharedvtFixed:
1279 case LLVMArgGsharedvtFixedVtype:
1280 case LLVMArgGsharedvtVariable:
1282 ret_type = LLVMVoidType ();
1288 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1290 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1292 * Has to be the first argument because of the sret argument attribute
1293 * FIXME: This might conflict with passing 'this' as the first argument, but
1294 * this is only used on arm64 which has a dedicated struct return register.
1296 cinfo->vret_arg_pindex = pindex;
1297 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1298 CHECK_FAILURE (ctx);
1299 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1302 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1303 cinfo->rgctx_arg_pindex = pindex;
1304 param_types [pindex] = ctx->module->ptr_type;
1307 if (cinfo->imt_arg) {
1308 cinfo->imt_arg_pindex = pindex;
1309 param_types [pindex] = ctx->module->ptr_type;
1313 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1314 vret_arg_pindex = pindex;
1315 if (cinfo->vret_arg_index == 1) {
1316 /* Add the slots consumed by the first argument */
1317 LLVMArgInfo *ainfo = &cinfo->args [0];
1318 switch (ainfo->storage) {
1319 case LLVMArgVtypeInReg:
1320 for (j = 0; j < 2; ++j) {
1321 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1330 cinfo->vret_arg_pindex = vret_arg_pindex;
1333 if (vretaddr && vret_arg_pindex == pindex)
1334 param_types [pindex ++] = IntPtrType ();
1336 cinfo->this_arg_pindex = pindex;
1337 param_types [pindex ++] = ThisType ();
1338 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1340 if (vretaddr && vret_arg_pindex == pindex)
1341 param_types [pindex ++] = IntPtrType ();
1342 for (i = 0; i < sig->param_count; ++i) {
1343 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1345 if (vretaddr && vret_arg_pindex == pindex)
1346 param_types [pindex ++] = IntPtrType ();
1347 ainfo->pindex = pindex;
1349 switch (ainfo->storage) {
1350 case LLVMArgVtypeInReg:
1351 for (j = 0; j < 2; ++j) {
1352 switch (ainfo->pair_storage [j]) {
1354 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1359 g_assert_not_reached ();
1363 case LLVMArgVtypeByVal:
1364 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1365 CHECK_FAILURE (ctx);
1366 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1369 case LLVMArgAsIArgs:
1370 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1373 case LLVMArgVtypeByRef:
1374 case LLVMArgScalarByRef:
1375 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1376 CHECK_FAILURE (ctx);
1377 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1380 case LLVMArgAsFpArgs: {
1383 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1384 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1385 param_types [pindex ++] = LLVMDoubleType ();
1386 for (j = 0; j < ainfo->nslots; ++j)
1387 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1390 case LLVMArgVtypeAsScalar:
1391 g_assert_not_reached ();
1393 case LLVMArgGsharedvtFixed:
1394 case LLVMArgGsharedvtFixedVtype:
1395 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1397 case LLVMArgGsharedvtVariable:
1398 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1401 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1405 if (vretaddr && vret_arg_pindex == pindex)
1406 param_types [pindex ++] = IntPtrType ();
1407 if (ctx->llvm_only && cinfo->rgctx_arg) {
1408 /* Pass the rgctx as the last argument */
1409 cinfo->rgctx_arg_pindex = pindex;
1410 param_types [pindex] = ctx->module->ptr_type;
1414 CHECK_FAILURE (ctx);
1416 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1417 g_free (param_types);
1422 g_free (param_types);
1428 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1430 return sig_to_llvm_sig_full (ctx, sig, NULL);
1434 * LLVMFunctionType1:
1436 * Create an LLVM function type from the arguments.
1438 static G_GNUC_UNUSED LLVMTypeRef
1439 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1442 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1446 * LLVMFunctionType1:
1448 * Create an LLVM function type from the arguments.
1450 static G_GNUC_UNUSED LLVMTypeRef
1451 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1452 LLVMTypeRef ParamType1,
1455 LLVMTypeRef param_types [1];
1457 param_types [0] = ParamType1;
1459 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1463 * LLVMFunctionType2:
1465 * Create an LLVM function type from the arguments.
1467 static G_GNUC_UNUSED LLVMTypeRef
1468 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1469 LLVMTypeRef ParamType1,
1470 LLVMTypeRef ParamType2,
1473 LLVMTypeRef param_types [2];
1475 param_types [0] = ParamType1;
1476 param_types [1] = ParamType2;
1478 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1482 * LLVMFunctionType3:
1484 * Create an LLVM function type from the arguments.
1486 static G_GNUC_UNUSED LLVMTypeRef
1487 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1488 LLVMTypeRef ParamType1,
1489 LLVMTypeRef ParamType2,
1490 LLVMTypeRef ParamType3,
1493 LLVMTypeRef param_types [3];
1495 param_types [0] = ParamType1;
1496 param_types [1] = ParamType2;
1497 param_types [2] = ParamType3;
1499 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1505 * Create an LLVM builder and remember it so it can be freed later.
1507 static LLVMBuilderRef
1508 create_builder (EmitContext *ctx)
1510 LLVMBuilderRef builder = LLVMCreateBuilder ();
1512 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1518 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1523 case MONO_PATCH_INFO_INTERNAL_METHOD:
1524 name = g_strdup_printf ("jit_icall_%s", data);
1526 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1527 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1528 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1532 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1540 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1544 LLVMValueRef indexes [2];
1546 LLVMValueRef got_entry_addr, load;
1547 LLVMBuilderRef builder = ctx->builder;
1552 ji = g_new0 (MonoJumpInfo, 1);
1554 ji->data.target = data;
1556 ji = mono_aot_patch_info_dup (ji);
1558 ji->next = cfg->patch_info;
1559 cfg->patch_info = ji;
1561 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1562 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1564 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1565 * explicitly initialize it.
1567 if (!mono_aot_is_shared_got_offset (got_offset)) {
1568 //mono_print_ji (ji);
1570 ctx->has_got_access = TRUE;
1573 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1574 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1575 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1577 name = get_aotconst_name (type, data, got_offset);
1579 load = convert (ctx, LLVMBuildLoad (builder, got_entry_addr, ""), llvm_type);
1580 LLVMSetValueName (load, name ? name : "");
1582 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1585 //set_invariant_load_flag (load);
1591 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1593 return get_aotconst_typed (ctx, type, data, NULL);
1597 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1599 LLVMValueRef callee;
1601 if (ctx->llvm_only) {
1602 callee_name = mono_aot_get_direct_call_symbol (type, data);
1604 /* Directly callable */
1606 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1608 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1610 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1612 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1614 g_free (callee_name);
1620 * Calls are made through the GOT.
1622 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1624 MonoJumpInfo *ji = NULL;
1626 callee_name = mono_aot_get_plt_symbol (type, data);
1630 if (ctx->cfg->compile_aot)
1631 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1632 mono_add_patch_info (ctx->cfg, 0, type, data);
1635 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1637 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1639 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1641 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1644 if (ctx->cfg->compile_aot) {
1645 ji = g_new0 (MonoJumpInfo, 1);
1647 ji->data.target = data;
1649 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1657 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1659 MonoMethodHeader *header = cfg->header;
1660 MonoExceptionClause *clause;
1664 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1665 return (bb->region >> 8) - 1;
1668 for (i = 0; i < header->num_clauses; ++i) {
1669 clause = &header->clauses [i];
1671 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1678 static MonoExceptionClause *
1679 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1681 // Since they're sorted by nesting we just need
1682 // the first one that the bb is a member of
1683 MonoExceptionClause *last = NULL;
1685 for (int i = 0; i < cfg->header->num_clauses; i++) {
1686 MonoExceptionClause *curr = &cfg->header->clauses [i];
1688 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1691 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1692 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1706 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1708 LLVMValueRef md_arg;
1711 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1712 md_arg = LLVMMDString ("mono", 4);
1713 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1717 set_invariant_load_flag (LLVMValueRef v)
1719 LLVMValueRef md_arg;
1721 const char *flag_name;
1723 // FIXME: Cache this
1724 flag_name = "invariant.load";
1725 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1726 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1727 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1733 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1737 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1739 MonoCompile *cfg = ctx->cfg;
1740 LLVMValueRef lcall = NULL;
1741 LLVMBuilderRef builder = *builder_ref;
1742 MonoExceptionClause *clause;
1744 if (ctx->llvm_only) {
1745 clause = get_most_deep_clause (cfg, ctx, bb);
1748 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1751 * Have to use an invoke instead of a call, branching to the
1752 * handler bblock of the clause containing this bblock.
1754 intptr_t key = CLAUSE_END(clause);
1756 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1758 // FIXME: Find the one that has the lowest end bound for the right start address
1759 // FIXME: Finally + nesting
1762 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1765 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1767 builder = ctx->builder = create_builder (ctx);
1768 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1770 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1774 int clause_index = get_handler_clause (cfg, bb);
1776 if (clause_index != -1) {
1777 MonoMethodHeader *header = cfg->header;
1778 MonoExceptionClause *ec = &header->clauses [clause_index];
1779 MonoBasicBlock *tblock;
1780 LLVMBasicBlockRef ex_bb, noex_bb;
1783 * Have to use an invoke instead of a call, branching to the
1784 * handler bblock of the clause containing this bblock.
1787 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1789 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1792 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1794 ex_bb = get_bb (ctx, tblock);
1796 noex_bb = gen_bb (ctx, "NOEX_BB");
1799 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1801 builder = ctx->builder = create_builder (ctx);
1802 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1804 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1809 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1810 ctx->builder = builder;
1814 *builder_ref = ctx->builder;
1820 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1822 const char *intrins_name;
1823 LLVMValueRef args [16], res;
1824 LLVMTypeRef addr_type;
1826 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1827 LLVMAtomicOrdering ordering;
1830 case LLVM_BARRIER_NONE:
1831 ordering = LLVMAtomicOrderingNotAtomic;
1833 case LLVM_BARRIER_ACQ:
1834 ordering = LLVMAtomicOrderingAcquire;
1836 case LLVM_BARRIER_SEQ:
1837 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1840 g_assert_not_reached ();
1845 * We handle loads which can fault by calling a mono specific intrinsic
1846 * using an invoke, so they are handled properly inside try blocks.
1847 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1848 * are marked with IntrReadArgMem.
1852 intrins_name = "llvm.mono.load.i8.p0i8";
1855 intrins_name = "llvm.mono.load.i16.p0i16";
1858 intrins_name = "llvm.mono.load.i32.p0i32";
1861 intrins_name = "llvm.mono.load.i64.p0i64";
1864 g_assert_not_reached ();
1867 addr_type = LLVMTypeOf (addr);
1868 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1869 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1872 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1873 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1874 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1875 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1877 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1878 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1879 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1880 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1887 * We emit volatile loads for loads which can fault, because otherwise
1888 * LLVM will generate invalid code when encountering a load from a
1891 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1893 /* Mark it with a custom metadata */
1896 set_metadata_flag (res, "mono.faulting.load");
1904 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1906 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1910 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1912 const char *intrins_name;
1913 LLVMValueRef args [16];
1915 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1916 LLVMAtomicOrdering ordering;
1919 case LLVM_BARRIER_NONE:
1920 ordering = LLVMAtomicOrderingNotAtomic;
1922 case LLVM_BARRIER_REL:
1923 ordering = LLVMAtomicOrderingRelease;
1925 case LLVM_BARRIER_SEQ:
1926 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1929 g_assert_not_reached ();
1935 intrins_name = "llvm.mono.store.i8.p0i8";
1938 intrins_name = "llvm.mono.store.i16.p0i16";
1941 intrins_name = "llvm.mono.store.i32.p0i32";
1944 intrins_name = "llvm.mono.store.i64.p0i64";
1947 g_assert_not_reached ();
1950 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1951 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1952 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1957 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1958 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1959 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1960 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
1962 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1967 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1969 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1973 * emit_cond_system_exception:
1975 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1976 * Might set the ctx exception.
1979 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1981 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
1982 LLVMBuilderRef builder;
1983 MonoClass *exc_class;
1984 LLVMValueRef args [2];
1985 LLVMValueRef callee;
1987 ex_bb = gen_bb (ctx, "EX_BB");
1989 ex2_bb = gen_bb (ctx, "EX2_BB");
1990 noex_bb = gen_bb (ctx, "NOEX_BB");
1992 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1994 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1995 g_assert (exc_class);
1997 /* Emit exception throwing code */
1998 ctx->builder = builder = create_builder (ctx);
1999 LLVMPositionBuilderAtEnd (builder, ex_bb);
2001 if (ctx->cfg->llvm_only) {
2002 static LLVMTypeRef sig;
2005 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2006 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_llvm_throw_corlib_exception");
2008 LLVMBuildBr (builder, ex2_bb);
2010 ctx->builder = builder = create_builder (ctx);
2011 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2013 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2014 emit_call (ctx, bb, &builder, callee, args, 1);
2015 LLVMBuildUnreachable (builder);
2017 ctx->builder = builder = create_builder (ctx);
2018 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2020 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2026 callee = ctx->module->throw_corlib_exception;
2029 const char *icall_name;
2031 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2032 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2034 if (ctx->cfg->compile_aot) {
2035 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2037 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2040 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2041 * - On x86, LLVM generated code doesn't push the arguments
2042 * - The trampoline takes the throw address as an arguments, not a pc offset.
2044 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2046 mono_memory_barrier ();
2047 ctx->module->throw_corlib_exception = callee;
2051 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2052 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2054 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2057 * The LLVM mono branch contains changes so a block address can be passed as an
2058 * argument to a call.
2060 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2061 emit_call (ctx, bb, &builder, callee, args, 2);
2063 LLVMBuildUnreachable (builder);
2065 ctx->builder = builder = create_builder (ctx);
2066 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2068 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2075 * emit_args_to_vtype:
2077 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2080 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2082 int j, size, nslots;
2084 size = get_vtype_size (t);
2086 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2087 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2090 if (ainfo->storage == LLVMArgAsFpArgs)
2091 nslots = ainfo->nslots;
2095 for (j = 0; j < nslots; ++j) {
2096 LLVMValueRef index [2], addr, daddr;
2097 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2098 LLVMTypeRef part_type;
2100 if (ainfo->pair_storage [j] == LLVMArgNone)
2103 switch (ainfo->pair_storage [j]) {
2104 case LLVMArgInIReg: {
2105 part_type = LLVMIntType (part_size * 8);
2106 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2107 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2108 addr = LLVMBuildGEP (builder, address, index, 1, "");
2110 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2111 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2112 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2114 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2117 case LLVMArgInFPReg: {
2118 LLVMTypeRef arg_type;
2120 if (ainfo->esize == 8)
2121 arg_type = LLVMDoubleType ();
2123 arg_type = LLVMFloatType ();
2125 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2126 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2127 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2128 LLVMBuildStore (builder, args [j], addr);
2134 g_assert_not_reached ();
2137 size -= sizeof (gpointer);
2142 * emit_vtype_to_args:
2144 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2145 * into ARGS, and the number of arguments into NARGS.
2148 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2151 int j, size, nslots;
2152 LLVMTypeRef arg_type;
2154 size = get_vtype_size (t);
2156 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2157 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2159 if (ainfo->storage == LLVMArgAsFpArgs)
2160 nslots = ainfo->nslots;
2163 for (j = 0; j < nslots; ++j) {
2164 LLVMValueRef index [2], addr, daddr;
2165 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2167 if (ainfo->pair_storage [j] == LLVMArgNone)
2170 switch (ainfo->pair_storage [j]) {
2172 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2173 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2174 addr = LLVMBuildGEP (builder, address, index, 1, "");
2176 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2177 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2178 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2180 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2182 case LLVMArgInFPReg:
2183 if (ainfo->esize == 8)
2184 arg_type = LLVMDoubleType ();
2186 arg_type = LLVMFloatType ();
2187 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2188 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2189 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2190 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2195 g_assert_not_reached ();
2197 size -= sizeof (gpointer);
2204 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2207 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2208 * get executed every time control reaches them.
2210 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2212 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2213 return ctx->last_alloca;
2217 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2219 return build_alloca_llvm_type_name (ctx, t, align, "");
2223 build_alloca (EmitContext *ctx, MonoType *t)
2225 MonoClass *k = mono_class_from_mono_type (t);
2228 g_assert (!mini_is_gsharedvt_variable_type (t));
2230 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2233 align = mono_class_min_align (k);
2235 /* Sometimes align is not a power of 2 */
2236 while (mono_is_power_of_two (align) == -1)
2239 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2243 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2247 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2249 MonoCompile *cfg = ctx->cfg;
2250 LLVMBuilderRef builder = ctx->builder;
2251 LLVMValueRef offset, offset_var;
2252 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2253 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2257 g_assert (info_var);
2258 g_assert (locals_var);
2260 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2262 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2263 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2265 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2266 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2268 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2272 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2275 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2278 module->used = g_ptr_array_sized_new (16);
2279 g_ptr_array_add (module->used, global);
2283 emit_llvm_used (MonoLLVMModule *module)
2285 LLVMModuleRef lmodule = module->lmodule;
2286 LLVMTypeRef used_type;
2287 LLVMValueRef used, *used_elem;
2293 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2294 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2295 used_elem = g_new0 (LLVMValueRef, module->used->len);
2296 for (i = 0; i < module->used->len; ++i)
2297 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2298 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2299 LLVMSetLinkage (used, LLVMAppendingLinkage);
2300 LLVMSetSection (used, "llvm.metadata");
2306 * Emit a function mapping method indexes to their code
2309 emit_get_method (MonoLLVMModule *module)
2311 LLVMModuleRef lmodule = module->lmodule;
2312 LLVMValueRef func, switch_ins, m;
2313 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2314 LLVMBasicBlockRef *bbs;
2316 LLVMBuilderRef builder;
2321 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2322 * but generating code seems safer.
2324 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2325 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2326 LLVMSetLinkage (func, LLVMExternalLinkage);
2327 LLVMSetVisibility (func, LLVMHiddenVisibility);
2328 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2329 module->get_method = func;
2331 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2334 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2335 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2336 * then we will have to find another solution.
2339 name = g_strdup_printf ("BB_CODE_START");
2340 code_start_bb = LLVMAppendBasicBlock (func, name);
2342 builder = LLVMCreateBuilder ();
2343 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2344 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2346 name = g_strdup_printf ("BB_CODE_END");
2347 code_end_bb = LLVMAppendBasicBlock (func, name);
2349 builder = LLVMCreateBuilder ();
2350 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2351 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2353 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2354 for (i = 0; i < module->max_method_idx + 1; ++i) {
2355 name = g_strdup_printf ("BB_%d", i);
2356 bb = LLVMAppendBasicBlock (func, name);
2360 builder = LLVMCreateBuilder ();
2361 LLVMPositionBuilderAtEnd (builder, bb);
2363 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2365 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2367 LLVMBuildRet (builder, LLVMConstNull (rtype));
2370 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2371 builder = LLVMCreateBuilder ();
2372 LLVMPositionBuilderAtEnd (builder, fail_bb);
2373 LLVMBuildRet (builder, LLVMConstNull (rtype));
2375 builder = LLVMCreateBuilder ();
2376 LLVMPositionBuilderAtEnd (builder, entry_bb);
2378 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2379 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2380 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2381 for (i = 0; i < module->max_method_idx + 1; ++i) {
2382 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2385 mark_as_used (module, func);
2389 * emit_get_unbox_tramp:
2391 * Emit a function mapping method indexes to their unbox trampoline
2394 emit_get_unbox_tramp (MonoLLVMModule *module)
2396 LLVMModuleRef lmodule = module->lmodule;
2397 LLVMValueRef func, switch_ins, m;
2398 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2399 LLVMBasicBlockRef *bbs;
2401 LLVMBuilderRef builder;
2405 /* Similar to emit_get_method () */
2407 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2408 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2409 LLVMSetLinkage (func, LLVMExternalLinkage);
2410 LLVMSetVisibility (func, LLVMHiddenVisibility);
2411 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2412 module->get_unbox_tramp = func;
2414 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2416 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2417 for (i = 0; i < module->max_method_idx + 1; ++i) {
2418 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2422 name = g_strdup_printf ("BB_%d", i);
2423 bb = LLVMAppendBasicBlock (func, name);
2427 builder = LLVMCreateBuilder ();
2428 LLVMPositionBuilderAtEnd (builder, bb);
2430 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2433 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2434 builder = LLVMCreateBuilder ();
2435 LLVMPositionBuilderAtEnd (builder, fail_bb);
2436 LLVMBuildRet (builder, LLVMConstNull (rtype));
2438 builder = LLVMCreateBuilder ();
2439 LLVMPositionBuilderAtEnd (builder, entry_bb);
2441 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2442 for (i = 0; i < module->max_method_idx + 1; ++i) {
2443 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2447 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2450 mark_as_used (module, func);
2453 /* Add a function to mark the beginning of LLVM code */
2455 emit_llvm_code_start (MonoLLVMModule *module)
2457 LLVMModuleRef lmodule = module->lmodule;
2459 LLVMBasicBlockRef entry_bb;
2460 LLVMBuilderRef builder;
2462 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2463 LLVMSetLinkage (func, LLVMInternalLinkage);
2464 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2465 module->code_start = func;
2466 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2467 builder = LLVMCreateBuilder ();
2468 LLVMPositionBuilderAtEnd (builder, entry_bb);
2469 LLVMBuildRetVoid (builder);
2473 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2475 LLVMModuleRef lmodule = module->lmodule;
2476 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2477 LLVMBasicBlockRef entry_bb;
2478 LLVMBuilderRef builder;
2485 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2486 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2491 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2492 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2495 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2496 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2499 g_assert_not_reached ();
2501 LLVMSetLinkage (func, LLVMInternalLinkage);
2502 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2503 mono_llvm_set_preserveall_cc (func);
2504 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2505 builder = LLVMCreateBuilder ();
2506 LLVMPositionBuilderAtEnd (builder, entry_bb);
2509 ji = g_new0 (MonoJumpInfo, 1);
2510 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2511 ji = mono_aot_patch_info_dup (ji);
2512 got_offset = mono_aot_get_got_offset (ji);
2513 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2514 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2515 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2516 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2517 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2518 args [1] = LLVMGetParam (func, 0);
2520 args [2] = LLVMGetParam (func, 1);
2522 ji = g_new0 (MonoJumpInfo, 1);
2523 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2524 ji->data.name = icall_name;
2525 ji = mono_aot_patch_info_dup (ji);
2526 got_offset = mono_aot_get_got_offset (ji);
2527 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2528 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2529 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2530 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2531 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2532 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2533 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2535 // Set the inited flag
2536 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2537 indexes [1] = LLVMGetParam (func, 0);
2538 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2540 LLVMBuildRetVoid (builder);
2542 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2547 * Emit wrappers around the C icalls used to initialize llvm methods, to
2548 * make the calling code smaller and to enable usage of the llvm
2549 * PreserveAll calling convention.
2552 emit_init_icall_wrappers (MonoLLVMModule *module)
2554 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2555 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2556 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2557 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2561 emit_llvm_code_end (MonoLLVMModule *module)
2563 LLVMModuleRef lmodule = module->lmodule;
2565 LLVMBasicBlockRef entry_bb;
2566 LLVMBuilderRef builder;
2568 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2569 LLVMSetLinkage (func, LLVMInternalLinkage);
2570 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2571 module->code_end = func;
2572 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2573 builder = LLVMCreateBuilder ();
2574 LLVMPositionBuilderAtEnd (builder, entry_bb);
2575 LLVMBuildRetVoid (builder);
2579 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2581 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2584 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2585 need_div_check = TRUE;
2587 if (!need_div_check)
2590 switch (ins->opcode) {
2603 case OP_IDIV_UN_IMM:
2604 case OP_LDIV_UN_IMM:
2605 case OP_IREM_UN_IMM:
2606 case OP_LREM_UN_IMM: {
2608 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2609 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2611 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2612 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2613 CHECK_FAILURE (ctx);
2614 builder = ctx->builder;
2616 /* b == -1 && a == 0x80000000 */
2618 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2619 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2620 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2622 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2623 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2624 CHECK_FAILURE (ctx);
2625 builder = ctx->builder;
2640 * Emit code to initialize the GOT slots used by the method.
2643 emit_init_method (EmitContext *ctx)
2645 LLVMValueRef indexes [16], args [16], callee;
2646 LLVMValueRef inited_var, cmp, call;
2647 LLVMBasicBlockRef inited_bb, notinited_bb;
2648 LLVMBuilderRef builder = ctx->builder;
2649 MonoCompile *cfg = ctx->cfg;
2651 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2653 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2654 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2655 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2657 args [0] = inited_var;
2658 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2659 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2661 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2663 inited_bb = ctx->inited_bb;
2664 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2666 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2668 builder = ctx->builder = create_builder (ctx);
2669 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2672 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2673 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2674 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2675 callee = ctx->module->init_method_gshared_mrgctx;
2676 call = LLVMBuildCall (builder, callee, args, 2, "");
2677 } else if (ctx->rgctx_arg) {
2678 /* A vtable is passed as the rgctx argument */
2679 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2680 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2681 callee = ctx->module->init_method_gshared_vtable;
2682 call = LLVMBuildCall (builder, callee, args, 2, "");
2683 } else if (cfg->gshared) {
2684 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2685 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2686 callee = ctx->module->init_method_gshared_this;
2687 call = LLVMBuildCall (builder, callee, args, 2, "");
2689 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2690 callee = ctx->module->init_method;
2691 call = LLVMBuildCall (builder, callee, args, 1, "");
2695 * This enables llvm to keep arguments in their original registers/
2696 * scratch registers, since the call will not clobber them.
2698 mono_llvm_set_call_preserveall_cc (call);
2700 LLVMBuildBr (builder, inited_bb);
2701 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2703 builder = ctx->builder = create_builder (ctx);
2704 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2708 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2711 * Emit unbox trampoline using a tail call
2713 LLVMValueRef tramp, call, *args;
2714 LLVMBuilderRef builder;
2715 LLVMBasicBlockRef lbb;
2719 tramp_name = g_strdup_printf ("ut_%s", method_name);
2720 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2721 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2722 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2723 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2725 lbb = LLVMAppendBasicBlock (tramp, "");
2726 builder = LLVMCreateBuilder ();
2727 LLVMPositionBuilderAtEnd (builder, lbb);
2729 nargs = LLVMCountParamTypes (method_type);
2730 args = g_new0 (LLVMValueRef, nargs);
2731 for (i = 0; i < nargs; ++i) {
2732 args [i] = LLVMGetParam (tramp, i);
2733 if (i == ctx->this_arg_pindex) {
2734 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2736 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2737 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2738 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2741 call = LLVMBuildCall (builder, method, args, nargs, "");
2742 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2743 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2744 mono_llvm_set_must_tail (call);
2745 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2746 LLVMBuildRetVoid (builder);
2748 LLVMBuildRet (builder, call);
2750 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2756 * Emit code to load/convert arguments.
2759 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2762 MonoCompile *cfg = ctx->cfg;
2763 MonoMethodSignature *sig = ctx->sig;
2764 LLVMCallInfo *linfo = ctx->linfo;
2768 LLVMBuilderRef old_builder = ctx->builder;
2769 ctx->builder = builder;
2771 ctx->alloca_builder = create_builder (ctx);
2774 * Handle indirect/volatile variables by allocating memory for them
2775 * using 'alloca', and storing their address in a temporary.
2777 for (i = 0; i < cfg->num_varinfo; ++i) {
2778 MonoInst *var = cfg->varinfo [i];
2781 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2782 } 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))) {
2783 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2784 CHECK_FAILURE (ctx);
2785 /* Could be already created by an OP_VPHI */
2786 if (!ctx->addresses [var->dreg])
2787 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2788 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2792 names = g_new (char *, sig->param_count);
2793 mono_method_get_param_names (cfg->method, (const char **) names);
2795 for (i = 0; i < sig->param_count; ++i) {
2796 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2797 int reg = cfg->args [i + sig->hasthis]->dreg;
2800 pindex = ainfo->pindex;
2802 switch (ainfo->storage) {
2803 case LLVMArgVtypeInReg:
2804 case LLVMArgAsFpArgs: {
2805 LLVMValueRef args [8];
2808 pindex += ainfo->ndummy_fpargs;
2810 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2811 memset (args, 0, sizeof (args));
2812 if (ainfo->storage == LLVMArgVtypeInReg) {
2813 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2814 if (ainfo->pair_storage [1] != LLVMArgNone)
2815 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2817 g_assert (ainfo->nslots <= 8);
2818 for (j = 0; j < ainfo->nslots; ++j)
2819 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2821 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2823 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2825 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2826 /* Treat these as normal values */
2827 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2831 case LLVMArgVtypeByVal: {
2832 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2834 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2835 /* Treat these as normal values */
2836 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2840 case LLVMArgVtypeByRef: {
2841 /* The argument is passed by ref */
2842 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2845 case LLVMArgScalarByRef: {
2847 name = g_strdup_printf ("arg_%s", names [i]);
2849 name = g_strdup_printf ("arg_%d", i);
2850 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2854 case LLVMArgAsIArgs: {
2855 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2857 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2859 /* The argument is received as an array of ints, store it into the real argument */
2860 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2863 case LLVMArgVtypeAsScalar:
2864 g_assert_not_reached ();
2866 case LLVMArgGsharedvtFixed: {
2867 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2868 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2871 name = g_strdup_printf ("arg_%s", names [i]);
2873 name = g_strdup_printf ("arg_%d", i);
2875 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2878 case LLVMArgGsharedvtFixedVtype: {
2879 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2882 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2884 name = g_strdup_printf ("vtype_arg_%d", i);
2886 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2887 g_assert (ctx->addresses [reg]);
2888 LLVMSetValueName (ctx->addresses [reg], name);
2889 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2892 case LLVMArgGsharedvtVariable:
2893 /* The IR treats these as variables with addresses */
2894 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2897 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));
2904 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2906 emit_volatile_store (ctx, cfg->args [0]->dreg);
2907 for (i = 0; i < sig->param_count; ++i)
2908 if (!mini_type_is_vtype (sig->params [i]))
2909 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2911 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2912 LLVMValueRef this_alloc;
2915 * The exception handling code needs the location where the this argument was
2916 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2917 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2918 * location into the LSDA.
2920 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2921 /* This volatile store will keep the alloca alive */
2922 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2924 set_metadata_flag (this_alloc, "mono.this");
2927 if (cfg->rgctx_var) {
2928 LLVMValueRef rgctx_alloc, store;
2931 * We handle the rgctx arg similarly to the this pointer.
2933 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2934 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2935 /* This volatile store will keep the alloca alive */
2936 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2938 set_metadata_flag (rgctx_alloc, "mono.this");
2941 /* Initialize the method if needed */
2942 if (cfg->compile_aot && ctx->llvm_only) {
2943 /* Emit a location for the initialization code */
2944 ctx->init_bb = gen_bb (ctx, "INIT_BB");
2945 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
2947 LLVMBuildBr (ctx->builder, ctx->init_bb);
2948 builder = ctx->builder = create_builder (ctx);
2949 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
2950 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
2953 /* Compute nesting between clauses */
2954 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2955 for (i = 0; i < cfg->header->num_clauses; ++i) {
2956 for (j = 0; j < cfg->header->num_clauses; ++j) {
2957 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2958 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2960 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2961 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2966 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2967 * it needs to continue normally, or return back to the exception handling system.
2969 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2973 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2976 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2977 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2978 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2980 if (bb->in_scount == 0) {
2983 sprintf (name, "finally_ind_bb%d", bb->block_num);
2984 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2985 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2987 ctx->bblocks [bb->block_num].finally_ind = val;
2989 /* Create a variable to hold the exception var */
2991 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2995 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2996 * LLVM bblock containing a landing pad causes problems for the
2997 * LLVM optimizer passes.
2999 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3000 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3007 ctx->builder = old_builder;
3011 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3013 MonoCompile *cfg = ctx->cfg;
3014 LLVMModuleRef lmodule = ctx->lmodule;
3015 LLVMValueRef *values = ctx->values;
3016 LLVMValueRef *addresses = ctx->addresses;
3017 MonoCallInst *call = (MonoCallInst*)ins;
3018 MonoMethodSignature *sig = call->signature;
3019 LLVMValueRef callee = NULL, lcall;
3021 LLVMCallInfo *cinfo;
3025 LLVMTypeRef llvm_sig;
3027 gboolean is_virtual, calli, preserveall;
3028 LLVMBuilderRef builder = *builder_ref;
3030 if (call->signature->call_convention != MONO_CALL_DEFAULT)
3031 LLVM_FAILURE (ctx, "non-default callconv");
3033 cinfo = call->cinfo;
3035 if (call->rgctx_arg_reg)
3036 cinfo->rgctx_arg = TRUE;
3037 if (call->imt_arg_reg)
3038 cinfo->imt_arg = TRUE;
3040 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgScalarRetAddr || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3042 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3043 CHECK_FAILURE (ctx);
3045 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);
3046 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);
3048 preserveall = FALSE;
3050 /* FIXME: Avoid creating duplicate methods */
3052 if (ins->flags & MONO_INST_HAS_METHOD) {
3056 if (cfg->compile_aot) {
3057 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3059 LLVM_FAILURE (ctx, "can't encode patch");
3061 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3063 * Collect instructions representing the callee into a hash so they can be replaced
3064 * by the llvm method for the callee if the callee turns out to be direct
3065 * callable. Currently this only requires it to not fail llvm compilation.
3067 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3068 l = g_slist_prepend (l, callee);
3069 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3072 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3075 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3077 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3081 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
3082 /* LLVM miscompiles async methods */
3083 LLVM_FAILURE (ctx, "#13734");
3086 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3092 memset (&ji, 0, sizeof (ji));
3093 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3094 ji.data.target = info->name;
3096 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3098 if (cfg->compile_aot) {
3099 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3101 LLVM_FAILURE (ctx, "can't encode patch");
3103 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3104 target = (gpointer)mono_icall_get_wrapper (info);
3105 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3108 if (cfg->compile_aot) {
3110 if (cfg->abs_patches) {
3111 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3113 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3115 LLVM_FAILURE (ctx, "can't encode patch");
3119 LLVM_FAILURE (ctx, "aot");
3121 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3123 if (cfg->abs_patches) {
3124 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3127 * FIXME: Some trampolines might have
3128 * their own calling convention on some platforms.
3130 #ifndef TARGET_AMD64
3131 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
3132 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
3133 LLVM_FAILURE (ctx, "trampoline with own cconv");
3135 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3136 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3140 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3146 int size = sizeof (gpointer);
3149 g_assert (ins->inst_offset % size == 0);
3150 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3152 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3154 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3156 if (ins->flags & MONO_INST_HAS_METHOD) {
3161 * Collect and convert arguments
3163 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3164 len = sizeof (LLVMValueRef) * nargs;
3165 args = (LLVMValueRef*)alloca (len);
3166 memset (args, 0, len);
3167 l = call->out_ireg_args;
3169 if (call->rgctx_arg_reg) {
3170 g_assert (values [call->rgctx_arg_reg]);
3171 g_assert (cinfo->rgctx_arg_pindex < nargs);
3173 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3174 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3175 * it using a volatile load.
3178 if (!ctx->imt_rgctx_loc)
3179 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3180 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3181 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3183 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3186 if (call->imt_arg_reg) {
3187 g_assert (!ctx->llvm_only);
3188 g_assert (values [call->imt_arg_reg]);
3189 g_assert (cinfo->imt_arg_pindex < nargs);
3191 if (!ctx->imt_rgctx_loc)
3192 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3193 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3194 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3196 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3199 switch (cinfo->ret.storage) {
3200 case LLVMArgGsharedvtVariable: {
3201 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3203 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3204 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3206 g_assert (addresses [call->inst.dreg]);
3207 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3213 if (!addresses [call->inst.dreg])
3214 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3215 g_assert (cinfo->vret_arg_pindex < nargs);
3216 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3217 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3219 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3225 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3226 * use the real callee for argument type conversion.
3228 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3229 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3230 LLVMGetParamTypes (callee_type, param_types);
3232 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3235 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3237 pindex = ainfo->pindex;
3239 regpair = (guint32)(gssize)(l->data);
3240 reg = regpair & 0xffffff;
3241 args [pindex] = values [reg];
3242 switch (ainfo->storage) {
3243 case LLVMArgVtypeInReg:
3244 case LLVMArgAsFpArgs: {
3248 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3249 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3250 pindex += ainfo->ndummy_fpargs;
3252 g_assert (addresses [reg]);
3253 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3257 // FIXME: Get rid of the VMOVE
3260 case LLVMArgVtypeByVal:
3261 g_assert (addresses [reg]);
3262 args [pindex] = addresses [reg];
3264 case LLVMArgVtypeByRef:
3265 case LLVMArgScalarByRef: {
3266 g_assert (addresses [reg]);
3267 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3270 case LLVMArgAsIArgs:
3271 g_assert (addresses [reg]);
3272 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3274 case LLVMArgVtypeAsScalar:
3275 g_assert_not_reached ();
3277 case LLVMArgGsharedvtFixed:
3278 case LLVMArgGsharedvtFixedVtype:
3279 g_assert (addresses [reg]);
3280 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3282 case LLVMArgGsharedvtVariable:
3283 g_assert (addresses [reg]);
3284 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3287 g_assert (args [pindex]);
3288 if (i == 0 && sig->hasthis)
3289 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3291 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3294 g_assert (pindex <= nargs);
3299 // FIXME: Align call sites
3305 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3308 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3310 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3311 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3313 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3314 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3315 if (!sig->pinvoke && !cfg->llvm_only)
3316 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3318 mono_llvm_set_call_preserveall_cc (lcall);
3320 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3321 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3322 if (!ctx->llvm_only && call->rgctx_arg_reg)
3323 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3324 if (call->imt_arg_reg)
3325 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3327 /* Add byval attributes if needed */
3328 for (i = 0; i < sig->param_count; ++i) {
3329 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3331 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3332 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3336 * Convert the result
3338 switch (cinfo->ret.storage) {
3339 case LLVMArgVtypeInReg: {
3340 LLVMValueRef regs [2];
3342 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3346 if (!addresses [ins->dreg])
3347 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3349 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3350 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3351 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3352 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3355 case LLVMArgVtypeByVal:
3356 if (!addresses [call->inst.dreg])
3357 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3358 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3360 case LLVMArgFpStruct:
3361 if (!addresses [call->inst.dreg])
3362 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3363 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3365 case LLVMArgVtypeAsScalar:
3366 if (!addresses [call->inst.dreg])
3367 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3368 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3370 case LLVMArgVtypeRetAddr:
3371 case LLVMArgVtypeByRef:
3373 case LLVMArgScalarRetAddr:
3374 /* Normal scalar returned using a vtype return argument */
3375 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3377 case LLVMArgGsharedvtVariable:
3379 case LLVMArgGsharedvtFixed:
3380 case LLVMArgGsharedvtFixedVtype:
3381 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3384 if (sig->ret->type != MONO_TYPE_VOID)
3385 /* If the method returns an unsigned value, need to zext it */
3386 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));
3390 *builder_ref = ctx->builder;
3398 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3400 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3401 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3403 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3406 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3408 if (ctx->cfg->compile_aot) {
3409 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3411 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3412 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3413 mono_memory_barrier ();
3416 ctx->module->rethrow = callee;
3418 ctx->module->throw_icall = callee;
3422 LLVMValueRef args [2];
3424 args [0] = convert (ctx, exc, exc_type);
3425 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3427 LLVMBuildUnreachable (ctx->builder);
3429 ctx->builder = create_builder (ctx);
3433 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3435 MonoMethodSignature *throw_sig;
3436 LLVMValueRef callee, arg;
3437 const char *icall_name;
3439 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3440 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3443 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3444 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3445 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3446 if (ctx->cfg->compile_aot) {
3447 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3449 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3453 * LLVM doesn't push the exception argument, so we need a different
3456 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3458 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3462 mono_memory_barrier ();
3464 ctx->module->rethrow = callee;
3466 ctx->module->throw_icall = callee;
3468 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3469 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3473 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3475 const char *icall_name = "mono_llvm_resume_exception";
3476 LLVMValueRef callee = ctx->module->resume_eh;
3478 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3481 if (ctx->cfg->compile_aot) {
3482 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3484 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3485 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3486 mono_memory_barrier ();
3488 ctx->module->resume_eh = callee;
3492 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3494 LLVMBuildUnreachable (ctx->builder);
3496 ctx->builder = create_builder (ctx);
3500 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3502 const char *icall_name = "mono_llvm_clear_exception";
3504 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3505 LLVMValueRef callee = NULL;
3508 if (ctx->cfg->compile_aot) {
3509 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3511 // FIXME: This is broken.
3512 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3516 g_assert (builder && callee);
3518 return LLVMBuildCall (builder, callee, NULL, 0, "");
3522 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3524 const char *icall_name = "mono_llvm_load_exception";
3526 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3527 LLVMValueRef callee = NULL;
3530 if (ctx->cfg->compile_aot) {
3531 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3533 // FIXME: This is broken.
3534 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3538 g_assert (builder && callee);
3540 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3545 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3547 const char *icall_name = "mono_llvm_match_exception";
3549 ctx->builder = builder;
3551 const int num_args = 3;
3552 LLVMValueRef args [num_args];
3553 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3554 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3555 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3557 LLVMTypeRef match_sig = LLVMFunctionType3 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), FALSE);
3558 LLVMValueRef callee = ctx->module->match_exc;
3561 if (ctx->cfg->compile_aot) {
3562 ctx->builder = builder;
3563 // get_callee expects ctx->builder to be the emitting builder
3564 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3566 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3567 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3568 ctx->module->match_exc = callee;
3569 mono_memory_barrier ();
3573 g_assert (builder && callee);
3575 g_assert (ctx->ex_var);
3577 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3580 // FIXME: This won't work because the code-finding makes this
3582 /*#define MONO_PERSONALITY_DEBUG*/
3584 #ifdef MONO_PERSONALITY_DEBUG
3585 static const gboolean use_debug_personality = TRUE;
3586 static const char *default_personality_name = "mono_debug_personality";
3588 static const gboolean use_debug_personality = FALSE;
3589 static const char *default_personality_name = "__gxx_personality_v0";
3593 default_cpp_lpad_exc_signature (void)
3595 static gboolean inited = FALSE;
3596 static LLVMTypeRef sig;
3599 LLVMTypeRef signature [2];
3600 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3601 signature [1] = LLVMInt32Type ();
3602 sig = LLVMStructType (signature, 2, FALSE);
3610 get_mono_personality (EmitContext *ctx)
3612 LLVMValueRef personality = NULL;
3613 static gint32 mapping_inited = FALSE;
3614 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3616 if (!use_debug_personality) {
3617 if (ctx->cfg->compile_aot) {
3618 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3619 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3620 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3621 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3624 if (ctx->cfg->compile_aot) {
3625 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3627 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3628 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3629 mono_memory_barrier ();
3633 g_assert (personality);
3637 static LLVMBasicBlockRef
3638 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3640 MonoCompile *cfg = ctx->cfg;
3641 LLVMBuilderRef old_builder = ctx->builder;
3642 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3644 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3645 ctx->builder = lpadBuilder;
3647 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3648 g_assert (handler_bb);
3650 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3651 LLVMValueRef personality = get_mono_personality (ctx);
3652 g_assert (personality);
3654 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3655 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3657 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3658 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3659 g_assert (landing_pad);
3661 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3662 LLVMAddClause (landing_pad, cast);
3664 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3665 LLVMBuilderRef resume_builder = create_builder (ctx);
3666 ctx->builder = resume_builder;
3667 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3669 emit_resume_eh (ctx, handler_bb);
3672 ctx->builder = lpadBuilder;
3673 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3675 gboolean finally_only = TRUE;
3677 MonoExceptionClause *group_cursor = group_start;
3679 for (int i = 0; i < group_size; i ++) {
3680 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3681 finally_only = FALSE;
3687 // Handle landing pad inlining
3689 if (!finally_only) {
3690 // So at each level of the exception stack we will match the exception again.
3691 // During that match, we need to compare against the handler types for the current
3692 // protected region. We send the try start and end so that we can only check against
3693 // handlers for this lexical protected region.
3694 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3696 // if returns -1, resume
3697 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3699 // else move to that target bb
3700 for (int i=0; i < group_size; i++) {
3701 MonoExceptionClause *clause = group_start + i;
3702 int clause_index = clause - cfg->header->clauses;
3703 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3704 g_assert (handler_bb);
3705 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3706 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3709 int clause_index = group_start - cfg->header->clauses;
3710 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3711 g_assert (finally_bb);
3713 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3716 ctx->builder = old_builder;
3723 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3725 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3726 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3728 // Make exception available to catch blocks
3729 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3730 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3732 g_assert (ctx->ex_var);
3733 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3735 if (bb->in_scount == 1) {
3736 MonoInst *exvar = bb->in_stack [0];
3737 g_assert (!ctx->values [exvar->dreg]);
3738 g_assert (ctx->ex_var);
3739 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3740 emit_volatile_store (ctx, exvar->dreg);
3743 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3746 LLVMBuilderRef handler_builder = create_builder (ctx);
3747 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3748 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3750 // Make the handler code end with a jump to cbb
3751 LLVMBuildBr (handler_builder, cbb);
3755 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3757 MonoCompile *cfg = ctx->cfg;
3758 LLVMValueRef *values = ctx->values;
3759 LLVMModuleRef lmodule = ctx->lmodule;
3760 BBInfo *bblocks = ctx->bblocks;
3762 LLVMValueRef personality;
3763 LLVMValueRef landing_pad;
3764 LLVMBasicBlockRef target_bb;
3766 static gint32 mapping_inited;
3767 static int ti_generator;
3770 LLVMValueRef type_info;
3774 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3776 if (cfg->compile_aot) {
3777 /* Use a dummy personality function */
3778 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3779 g_assert (personality);
3781 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3782 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3783 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3786 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3788 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3791 * Create the type info
3793 sprintf (ti_name, "type_info_%d", ti_generator);
3796 if (cfg->compile_aot) {
3797 /* decode_eh_frame () in aot-runtime.c will decode this */
3798 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3799 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3802 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3804 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3807 * After the cfg mempool is freed, the type info will point to stale memory,
3808 * but this is not a problem, since we decode it once in exception_cb during
3811 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3812 *(gint32*)ti = clause_index;
3814 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3816 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3820 LLVMTypeRef members [2], ret_type;
3822 members [0] = i8ptr;
3823 members [1] = LLVMInt32Type ();
3824 ret_type = LLVMStructType (members, 2, FALSE);
3826 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3827 LLVMAddClause (landing_pad, type_info);
3829 /* Store the exception into the exvar */
3831 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3835 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3836 * code expects control to be transferred to this landing pad even in the
3837 * presence of nested clauses. The landing pad needs to branch to the landing
3838 * pads belonging to nested clauses based on the selector value returned by
3839 * the landing pad instruction, which is passed to the landing pad in a
3840 * register by the EH code.
3842 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3843 g_assert (target_bb);
3846 * Branch to the correct landing pad
3848 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3849 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3851 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3852 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3853 MonoBasicBlock *handler_bb;
3855 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3856 g_assert (handler_bb);
3858 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3859 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3862 /* Start a new bblock which CALL_HANDLER can branch to */
3863 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3865 ctx->builder = builder = create_builder (ctx);
3866 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3868 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3870 /* Store the exception into the IL level exvar */
3871 if (bb->in_scount == 1) {
3872 g_assert (bb->in_scount == 1);
3873 exvar = bb->in_stack [0];
3875 // FIXME: This is shared with filter clauses ?
3876 g_assert (!values [exvar->dreg]);
3878 g_assert (ctx->ex_var);
3879 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3880 emit_volatile_store (ctx, exvar->dreg);
3886 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3888 MonoCompile *cfg = ctx->cfg;
3889 MonoMethodSignature *sig = ctx->sig;
3890 LLVMValueRef method = ctx->lmethod;
3891 LLVMValueRef *values = ctx->values;
3892 LLVMValueRef *addresses = ctx->addresses;
3893 LLVMCallInfo *linfo = ctx->linfo;
3894 LLVMModuleRef lmodule = ctx->lmodule;
3895 BBInfo *bblocks = ctx->bblocks;
3897 LLVMBasicBlockRef cbb;
3898 LLVMBuilderRef builder, starting_builder;
3899 gboolean has_terminator;
3901 LLVMValueRef lhs, rhs;
3904 cbb = get_end_bb (ctx, bb);
3906 builder = create_builder (ctx);
3907 ctx->builder = builder;
3908 LLVMPositionBuilderAtEnd (builder, cbb);
3910 CHECK_FAILURE (ctx);
3912 if (bb->flags & BB_EXCEPTION_HANDLER) {
3913 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3914 LLVM_FAILURE (ctx, "handler without invokes");
3918 emit_llvmonly_handler_start (ctx, bb, cbb);
3920 emit_handler_start (ctx, bb, builder);
3921 CHECK_FAILURE (ctx);
3922 builder = ctx->builder;
3925 has_terminator = FALSE;
3926 starting_builder = builder;
3927 for (ins = bb->code; ins; ins = ins->next) {
3928 const char *spec = LLVM_INS_INFO (ins->opcode);
3930 char dname_buf [128];
3932 emit_dbg_loc (ctx, builder, ins->cil_code);
3935 if (nins > 3000 && builder == starting_builder) {
3937 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
3938 * Start a new bblock. If the llvm optimization passes merge these, we
3939 * can work around that by doing a volatile load + cond branch from
3940 * localloc-ed memory.
3942 LLVM_FAILURE (ctx, "basic block too long");
3946 /* There could be instructions after a terminator, skip them */
3949 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
3950 sprintf (dname_buf, "t%d", ins->dreg);
3954 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
3955 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
3957 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
3958 lhs = emit_volatile_load (ctx, ins->sreg1);
3960 /* It is ok for SETRET to have an uninitialized argument */
3961 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
3962 LLVM_FAILURE (ctx, "sreg1");
3963 lhs = values [ins->sreg1];
3969 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
3970 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
3971 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
3972 rhs = emit_volatile_load (ctx, ins->sreg2);
3974 if (!values [ins->sreg2])
3975 LLVM_FAILURE (ctx, "sreg2");
3976 rhs = values [ins->sreg2];
3982 //mono_print_ins (ins);
3983 switch (ins->opcode) {
3986 case OP_LIVERANGE_START:
3987 case OP_LIVERANGE_END:
3990 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
3993 #if SIZEOF_VOID_P == 4
3994 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3996 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4000 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4004 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4006 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4008 case OP_DUMMY_ICONST:
4009 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4011 case OP_DUMMY_I8CONST:
4012 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4014 case OP_DUMMY_R8CONST:
4015 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4018 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4019 LLVMBuildBr (builder, target_bb);
4020 has_terminator = TRUE;
4027 LLVMBasicBlockRef new_bb;
4028 LLVMBuilderRef new_builder;
4030 // The default branch is already handled
4031 // FIXME: Handle it here
4033 /* Start new bblock */
4034 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4035 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4037 lhs = convert (ctx, lhs, LLVMInt32Type ());
4038 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4039 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4040 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4042 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4045 new_builder = create_builder (ctx);
4046 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4047 LLVMBuildUnreachable (new_builder);
4049 has_terminator = TRUE;
4050 g_assert (!ins->next);
4056 switch (linfo->ret.storage) {
4057 case LLVMArgVtypeInReg: {
4058 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4059 LLVMValueRef val, addr, retval;
4062 retval = LLVMGetUndef (ret_type);
4064 if (!addresses [ins->sreg1]) {
4066 * The return type is an LLVM vector type, have to convert between it and the
4067 * real return type which is a struct type.
4069 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4070 /* Convert to 2xi64 first */
4071 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4073 for (i = 0; i < 2; ++i) {
4074 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4075 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4077 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4081 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4082 for (i = 0; i < 2; ++i) {
4083 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4084 LLVMValueRef indexes [2], part_addr;
4086 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4087 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4088 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4090 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4092 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4096 LLVMBuildRet (builder, retval);
4099 case LLVMArgVtypeAsScalar: {
4100 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4101 LLVMValueRef retval;
4104 size = get_vtype_size (sig->ret);
4106 g_assert (addresses [ins->sreg1]);
4108 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4109 LLVMBuildRet (builder, retval);
4112 case LLVMArgVtypeByVal: {
4113 LLVMValueRef retval;
4115 g_assert (addresses [ins->sreg1]);
4116 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4117 LLVMBuildRet (builder, retval);
4120 case LLVMArgVtypeByRef: {
4121 LLVMBuildRetVoid (builder);
4124 case LLVMArgGsharedvtFixed: {
4125 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4126 /* The return value is in lhs, need to store to the vret argument */
4127 /* sreg1 might not be set */
4129 g_assert (cfg->vret_addr);
4130 g_assert (values [cfg->vret_addr->dreg]);
4131 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4133 LLVMBuildRetVoid (builder);
4136 case LLVMArgGsharedvtFixedVtype: {
4138 LLVMBuildRetVoid (builder);
4141 case LLVMArgGsharedvtVariable: {
4143 LLVMBuildRetVoid (builder);
4146 case LLVMArgVtypeRetAddr: {
4147 LLVMBuildRetVoid (builder);
4150 case LLVMArgScalarRetAddr: {
4151 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4152 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4154 /* sreg1 might not be set */
4156 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4157 LLVMBuildRetVoid (builder);
4160 case LLVMArgFpStruct: {
4161 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4162 LLVMValueRef retval;
4164 g_assert (addresses [ins->sreg1]);
4165 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4166 LLVMBuildRet (builder, retval);
4170 case LLVMArgNormal: {
4171 if (!lhs || ctx->is_dead [ins->sreg1]) {
4173 * The method did not set its return value, probably because it
4174 * ends with a throw.
4177 LLVMBuildRetVoid (builder);
4179 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4181 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4183 has_terminator = TRUE;
4187 g_assert_not_reached ();
4196 case OP_ICOMPARE_IMM:
4197 case OP_LCOMPARE_IMM:
4198 case OP_COMPARE_IMM: {
4200 LLVMValueRef cmp, args [16];
4201 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4203 if (ins->next->opcode == OP_NOP)
4206 if (ins->next->opcode == OP_BR)
4207 /* The comparison result is not needed */
4210 rel = mono_opcode_to_cond (ins->next->opcode);
4212 if (ins->opcode == OP_ICOMPARE_IMM) {
4213 lhs = convert (ctx, lhs, LLVMInt32Type ());
4214 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4216 if (ins->opcode == OP_LCOMPARE_IMM) {
4217 lhs = convert (ctx, lhs, LLVMInt64Type ());
4218 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4220 if (ins->opcode == OP_LCOMPARE) {
4221 lhs = convert (ctx, lhs, LLVMInt64Type ());
4222 rhs = convert (ctx, rhs, LLVMInt64Type ());
4224 if (ins->opcode == OP_ICOMPARE) {
4225 lhs = convert (ctx, lhs, LLVMInt32Type ());
4226 rhs = convert (ctx, rhs, LLVMInt32Type ());
4230 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4231 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4232 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4233 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4236 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4237 if (ins->opcode == OP_FCOMPARE) {
4238 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4239 } else if (ins->opcode == OP_RCOMPARE) {
4240 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4241 } else if (ins->opcode == OP_COMPARE_IMM) {
4242 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4243 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4245 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4246 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4247 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4248 /* The immediate is encoded in two fields */
4249 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4250 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4252 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4255 else if (ins->opcode == OP_COMPARE) {
4256 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4257 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4259 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4261 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4265 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4266 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4269 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4270 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4272 * If the target bb contains PHI instructions, LLVM requires
4273 * two PHI entries for this bblock, while we only generate one.
4274 * So convert this to an unconditional bblock. (bxc #171).
4276 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4278 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4280 has_terminator = TRUE;
4281 } else if (MONO_IS_SETCC (ins->next)) {
4282 sprintf (dname_buf, "t%d", ins->next->dreg);
4284 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4286 /* Add stores for volatile variables */
4287 emit_volatile_store (ctx, ins->next->dreg);
4288 } else if (MONO_IS_COND_EXC (ins->next)) {
4289 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4290 CHECK_FAILURE (ctx);
4291 builder = ctx->builder;
4293 LLVM_FAILURE (ctx, "next");
4307 rel = mono_opcode_to_cond (ins->opcode);
4309 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4310 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4321 rel = mono_opcode_to_cond (ins->opcode);
4323 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4324 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4332 gboolean empty = TRUE;
4334 /* Check that all input bblocks really branch to us */
4335 for (i = 0; i < bb->in_count; ++i) {
4336 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4337 ins->inst_phi_args [i + 1] = -1;
4343 /* LLVM doesn't like phi instructions with zero operands */
4344 ctx->is_dead [ins->dreg] = TRUE;
4348 /* Created earlier, insert it now */
4349 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4351 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4352 int sreg1 = ins->inst_phi_args [i + 1];
4356 * Count the number of times the incoming bblock branches to us,
4357 * since llvm requires a separate entry for each.
4359 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4360 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4363 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4364 if (switch_ins->inst_many_bb [j] == bb)
4371 /* Remember for later */
4372 for (j = 0; j < count; ++j) {
4373 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4376 node->in_bb = bb->in_bb [i];
4378 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);
4388 values [ins->dreg] = lhs;
4392 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4395 values [ins->dreg] = lhs;
4397 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4399 * This is added by the spilling pass in case of the JIT,
4400 * but we have to do it ourselves.
4402 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4406 case OP_MOVE_F_TO_I4: {
4407 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4410 case OP_MOVE_I4_TO_F: {
4411 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4414 case OP_MOVE_F_TO_I8: {
4415 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4418 case OP_MOVE_I8_TO_F: {
4419 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4452 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4453 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4455 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4456 CHECK_FAILURE (ctx);
4457 builder = ctx->builder;
4459 switch (ins->opcode) {
4462 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4466 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4470 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4474 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4478 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4482 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4486 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4490 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4494 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4498 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4502 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4506 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4510 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4514 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4518 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4521 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4524 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4528 g_assert_not_reached ();
4535 lhs = convert (ctx, lhs, LLVMFloatType ());
4536 rhs = convert (ctx, rhs, LLVMFloatType ());
4537 switch (ins->opcode) {
4539 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4542 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4545 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4548 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4551 g_assert_not_reached ();
4560 case OP_IREM_UN_IMM:
4562 case OP_IDIV_UN_IMM:
4568 case OP_ISHR_UN_IMM:
4578 case OP_LSHR_UN_IMM:
4584 case OP_SHR_UN_IMM: {
4587 if (spec [MONO_INST_SRC1] == 'l') {
4588 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4590 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4593 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4594 CHECK_FAILURE (ctx);
4595 builder = ctx->builder;
4597 #if SIZEOF_VOID_P == 4
4598 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4599 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4602 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4603 lhs = convert (ctx, lhs, IntPtrType ());
4604 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4605 switch (ins->opcode) {
4609 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4613 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4618 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4622 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4624 case OP_IDIV_UN_IMM:
4625 case OP_LDIV_UN_IMM:
4626 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4630 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4632 case OP_IREM_UN_IMM:
4633 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4638 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4642 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4646 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4651 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4656 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4658 case OP_ISHR_UN_IMM:
4659 /* This is used to implement conv.u4, so the lhs could be an i8 */
4660 lhs = convert (ctx, lhs, LLVMInt32Type ());
4661 imm = convert (ctx, imm, LLVMInt32Type ());
4662 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4664 case OP_LSHR_UN_IMM:
4666 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4669 g_assert_not_reached ();
4674 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4677 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4680 lhs = convert (ctx, lhs, LLVMDoubleType ());
4681 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4684 lhs = convert (ctx, lhs, LLVMFloatType ());
4685 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4688 guint32 v = 0xffffffff;
4689 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4693 guint64 v = 0xffffffffffffffffLL;
4694 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4697 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4699 LLVMValueRef v1, v2;
4701 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4702 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4703 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4708 case OP_ICONV_TO_I1:
4709 case OP_ICONV_TO_I2:
4710 case OP_ICONV_TO_I4:
4711 case OP_ICONV_TO_U1:
4712 case OP_ICONV_TO_U2:
4713 case OP_ICONV_TO_U4:
4714 case OP_LCONV_TO_I1:
4715 case OP_LCONV_TO_I2:
4716 case OP_LCONV_TO_U1:
4717 case OP_LCONV_TO_U2:
4718 case OP_LCONV_TO_U4: {
4721 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);
4723 /* Have to do two casts since our vregs have type int */
4724 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4726 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4728 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4731 case OP_ICONV_TO_I8:
4732 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4734 case OP_ICONV_TO_U8:
4735 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4737 case OP_FCONV_TO_I4:
4738 case OP_RCONV_TO_I4:
4739 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4741 case OP_FCONV_TO_I1:
4742 case OP_RCONV_TO_I1:
4743 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4745 case OP_FCONV_TO_U1:
4746 case OP_RCONV_TO_U1:
4747 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4749 case OP_FCONV_TO_I2:
4750 case OP_RCONV_TO_I2:
4751 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4753 case OP_FCONV_TO_U2:
4754 case OP_RCONV_TO_U2:
4755 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4757 case OP_RCONV_TO_U4:
4758 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4760 case OP_FCONV_TO_I8:
4761 case OP_RCONV_TO_I8:
4762 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4765 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4767 case OP_ICONV_TO_R8:
4768 case OP_LCONV_TO_R8:
4769 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4771 case OP_ICONV_TO_R_UN:
4772 case OP_LCONV_TO_R_UN:
4773 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4775 #if SIZEOF_VOID_P == 4
4778 case OP_LCONV_TO_I4:
4779 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4781 case OP_ICONV_TO_R4:
4782 case OP_LCONV_TO_R4:
4783 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4785 values [ins->dreg] = v;
4787 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4789 case OP_FCONV_TO_R4:
4790 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4792 values [ins->dreg] = v;
4794 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4796 case OP_RCONV_TO_R8:
4797 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4799 case OP_RCONV_TO_R4:
4800 values [ins->dreg] = lhs;
4803 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4806 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4809 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4811 case OP_LOCALLOC_IMM: {
4814 guint32 size = ins->inst_imm;
4815 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4817 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4819 if (ins->flags & MONO_INST_INIT) {
4820 LLVMValueRef args [5];
4823 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4824 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4825 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4826 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4827 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4830 values [ins->dreg] = v;
4834 LLVMValueRef v, size;
4836 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), "");
4838 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4840 if (ins->flags & MONO_INST_INIT) {
4841 LLVMValueRef args [5];
4844 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4846 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4847 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4848 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4850 values [ins->dreg] = v;
4854 case OP_LOADI1_MEMBASE:
4855 case OP_LOADU1_MEMBASE:
4856 case OP_LOADI2_MEMBASE:
4857 case OP_LOADU2_MEMBASE:
4858 case OP_LOADI4_MEMBASE:
4859 case OP_LOADU4_MEMBASE:
4860 case OP_LOADI8_MEMBASE:
4861 case OP_LOADR4_MEMBASE:
4862 case OP_LOADR8_MEMBASE:
4863 case OP_LOAD_MEMBASE:
4871 LLVMValueRef base, index, addr;
4873 gboolean sext = FALSE, zext = FALSE;
4874 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4876 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4881 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)) {
4882 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4887 if (ins->inst_offset == 0) {
4889 } else if (ins->inst_offset % size != 0) {
4890 /* Unaligned load */
4891 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4892 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4894 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4895 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4899 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4901 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4903 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4905 * These will signal LLVM that these loads do not alias any stores, and
4906 * they can't fail, allowing them to be hoisted out of loops.
4908 set_invariant_load_flag (values [ins->dreg]);
4909 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4913 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4915 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4916 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4917 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4921 case OP_STOREI1_MEMBASE_REG:
4922 case OP_STOREI2_MEMBASE_REG:
4923 case OP_STOREI4_MEMBASE_REG:
4924 case OP_STOREI8_MEMBASE_REG:
4925 case OP_STORER4_MEMBASE_REG:
4926 case OP_STORER8_MEMBASE_REG:
4927 case OP_STORE_MEMBASE_REG: {
4929 LLVMValueRef index, addr;
4931 gboolean sext = FALSE, zext = FALSE;
4932 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4934 if (!values [ins->inst_destbasereg])
4935 LLVM_FAILURE (ctx, "inst_destbasereg");
4937 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4939 if (ins->inst_offset % size != 0) {
4940 /* Unaligned store */
4941 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4942 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4944 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4945 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4947 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4951 case OP_STOREI1_MEMBASE_IMM:
4952 case OP_STOREI2_MEMBASE_IMM:
4953 case OP_STOREI4_MEMBASE_IMM:
4954 case OP_STOREI8_MEMBASE_IMM:
4955 case OP_STORE_MEMBASE_IMM: {
4957 LLVMValueRef index, addr;
4959 gboolean sext = FALSE, zext = FALSE;
4960 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4962 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4964 if (ins->inst_offset % size != 0) {
4965 /* Unaligned store */
4966 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4967 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4969 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4970 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4972 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4977 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
4979 case OP_OUTARG_VTRETADDR:
4987 case OP_VOIDCALL_MEMBASE:
4988 case OP_CALL_MEMBASE:
4989 case OP_LCALL_MEMBASE:
4990 case OP_FCALL_MEMBASE:
4991 case OP_RCALL_MEMBASE:
4992 case OP_VCALL_MEMBASE:
4993 case OP_VOIDCALL_REG:
4998 case OP_VCALL_REG: {
4999 process_call (ctx, bb, &builder, ins);
5000 CHECK_FAILURE (ctx);
5005 LLVMValueRef indexes [2];
5006 MonoJumpInfo *tmp_ji, *ji;
5007 LLVMValueRef got_entry_addr;
5011 * FIXME: Can't allocate from the cfg mempool since that is freed if
5012 * the LLVM compile fails.
5014 tmp_ji = g_new0 (MonoJumpInfo, 1);
5015 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5016 tmp_ji->data.target = ins->inst_p0;
5018 ji = mono_aot_patch_info_dup (tmp_ji);
5021 ji->next = cfg->patch_info;
5022 cfg->patch_info = ji;
5024 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5025 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5026 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5027 if (!mono_aot_is_shared_got_offset (got_offset)) {
5028 //mono_print_ji (ji);
5030 ctx->has_got_access = TRUE;
5033 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5034 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5035 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5037 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5038 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5040 set_invariant_load_flag (values [ins->dreg]);
5043 case OP_NOT_REACHED:
5044 LLVMBuildUnreachable (builder);
5045 has_terminator = TRUE;
5046 g_assert (bb->block_num < cfg->max_block_num);
5047 ctx->unreachable [bb->block_num] = TRUE;
5048 /* Might have instructions after this */
5050 MonoInst *next = ins->next;
5052 * FIXME: If later code uses the regs defined by these instructions,
5053 * compilation will fail.
5055 MONO_DELETE_INS (bb, next);
5059 MonoInst *var = ins->inst_i0;
5061 if (var->opcode == OP_VTARG_ADDR) {
5062 /* The variable contains the vtype address */
5063 values [ins->dreg] = values [var->dreg];
5064 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5065 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5067 values [ins->dreg] = addresses [var->dreg];
5072 LLVMValueRef args [1];
5074 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5075 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5079 LLVMValueRef args [1];
5081 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5082 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5086 LLVMValueRef args [1];
5089 /* This no longer seems to happen */
5091 * LLVM optimizes sqrt(nan) into undefined in
5092 * lib/Analysis/ConstantFolding.cpp
5093 * Also, sqrt(NegativeInfinity) is optimized into 0.
5095 LLVM_FAILURE (ctx, "sqrt");
5097 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5098 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5102 LLVMValueRef args [1];
5104 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5105 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5119 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5120 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5122 switch (ins->opcode) {
5125 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5129 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5133 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5137 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5140 g_assert_not_reached ();
5143 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5146 case OP_ATOMIC_EXCHANGE_I4:
5147 case OP_ATOMIC_EXCHANGE_I8: {
5148 LLVMValueRef args [2];
5151 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5152 t = LLVMInt32Type ();
5154 t = LLVMInt64Type ();
5156 g_assert (ins->inst_offset == 0);
5158 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5159 args [1] = convert (ctx, rhs, t);
5161 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5164 case OP_ATOMIC_ADD_I4:
5165 case OP_ATOMIC_ADD_I8: {
5166 LLVMValueRef args [2];
5169 if (ins->opcode == OP_ATOMIC_ADD_I4)
5170 t = LLVMInt32Type ();
5172 t = LLVMInt64Type ();
5174 g_assert (ins->inst_offset == 0);
5176 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5177 args [1] = convert (ctx, rhs, t);
5178 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5181 case OP_ATOMIC_CAS_I4:
5182 case OP_ATOMIC_CAS_I8: {
5183 LLVMValueRef args [3], val;
5186 if (ins->opcode == OP_ATOMIC_CAS_I4)
5187 t = LLVMInt32Type ();
5189 t = LLVMInt64Type ();
5191 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5193 args [1] = convert (ctx, values [ins->sreg3], t);
5195 args [2] = convert (ctx, values [ins->sreg2], t);
5196 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5197 /* cmpxchg returns a pair */
5198 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5201 case OP_MEMORY_BARRIER: {
5202 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5205 case OP_ATOMIC_LOAD_I1:
5206 case OP_ATOMIC_LOAD_I2:
5207 case OP_ATOMIC_LOAD_I4:
5208 case OP_ATOMIC_LOAD_I8:
5209 case OP_ATOMIC_LOAD_U1:
5210 case OP_ATOMIC_LOAD_U2:
5211 case OP_ATOMIC_LOAD_U4:
5212 case OP_ATOMIC_LOAD_U8:
5213 case OP_ATOMIC_LOAD_R4:
5214 case OP_ATOMIC_LOAD_R8: {
5215 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
5218 gboolean sext, zext;
5220 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5221 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5222 LLVMValueRef index, addr;
5224 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5229 if (ins->inst_offset != 0) {
5230 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5231 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5236 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5238 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5241 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5243 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5246 case OP_ATOMIC_STORE_I1:
5247 case OP_ATOMIC_STORE_I2:
5248 case OP_ATOMIC_STORE_I4:
5249 case OP_ATOMIC_STORE_I8:
5250 case OP_ATOMIC_STORE_U1:
5251 case OP_ATOMIC_STORE_U2:
5252 case OP_ATOMIC_STORE_U4:
5253 case OP_ATOMIC_STORE_U8:
5254 case OP_ATOMIC_STORE_R4:
5255 case OP_ATOMIC_STORE_R8: {
5256 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
5259 gboolean sext, zext;
5261 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5262 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5263 LLVMValueRef index, addr, value;
5265 if (!values [ins->inst_destbasereg])
5266 LLVM_FAILURE (ctx, "inst_destbasereg");
5268 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5270 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5271 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5272 value = convert (ctx, values [ins->sreg1], t);
5274 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5277 case OP_RELAXED_NOP: {
5278 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5279 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5286 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5288 // 257 == FS segment register
5289 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5291 // 256 == GS segment register
5292 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5295 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5296 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5297 /* See mono_amd64_emit_tls_get () */
5298 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5300 // 256 == GS segment register
5301 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5302 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5304 LLVM_FAILURE (ctx, "opcode tls-get");
5309 case OP_TLS_GET_REG: {
5310 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5311 /* See emit_tls_get_reg () */
5312 // 256 == GS segment register
5313 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5314 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5316 LLVM_FAILURE (ctx, "opcode tls-get");
5321 case OP_TLS_SET_REG: {
5322 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5323 /* See emit_tls_get_reg () */
5324 // 256 == GS segment register
5325 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5326 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5328 LLVM_FAILURE (ctx, "opcode tls-set-reg");
5337 case OP_IADD_OVF_UN:
5339 case OP_ISUB_OVF_UN:
5341 case OP_IMUL_OVF_UN:
5342 #if SIZEOF_VOID_P == 8
5344 case OP_LADD_OVF_UN:
5346 case OP_LSUB_OVF_UN:
5348 case OP_LMUL_OVF_UN:
5351 LLVMValueRef args [2], val, ovf, func;
5353 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5354 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5355 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5357 val = LLVMBuildCall (builder, func, args, 2, "");
5358 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5359 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5360 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5361 CHECK_FAILURE (ctx);
5362 builder = ctx->builder;
5368 * We currently model them using arrays. Promotion to local vregs is
5369 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5370 * so we always have an entry in cfg->varinfo for them.
5371 * FIXME: Is this needed ?
5374 MonoClass *klass = ins->klass;
5375 LLVMValueRef args [5];
5379 LLVM_FAILURE (ctx, "!klass");
5383 if (!addresses [ins->dreg])
5384 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5385 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5386 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5387 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5389 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5390 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5391 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5394 case OP_DUMMY_VZERO:
5397 case OP_STOREV_MEMBASE:
5398 case OP_LOADV_MEMBASE:
5400 MonoClass *klass = ins->klass;
5401 LLVMValueRef src = NULL, dst, args [5];
5402 gboolean done = FALSE;
5406 LLVM_FAILURE (ctx, "!klass");
5410 if (mini_is_gsharedvt_klass (klass)) {
5412 LLVM_FAILURE (ctx, "gsharedvt");
5416 switch (ins->opcode) {
5417 case OP_STOREV_MEMBASE:
5418 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5419 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5420 /* Decomposed earlier */
5421 g_assert_not_reached ();
5424 if (!addresses [ins->sreg1]) {
5426 g_assert (values [ins->sreg1]);
5427 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));
5428 LLVMBuildStore (builder, values [ins->sreg1], dst);
5431 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5432 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5435 case OP_LOADV_MEMBASE:
5436 if (!addresses [ins->dreg])
5437 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5438 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5439 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5442 if (!addresses [ins->sreg1])
5443 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5444 if (!addresses [ins->dreg])
5445 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5446 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5447 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5450 g_assert_not_reached ();
5452 CHECK_FAILURE (ctx);
5459 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5460 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5462 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5463 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5464 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5467 case OP_LLVM_OUTARG_VT: {
5468 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5469 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5471 if (ainfo->storage == LLVMArgScalarByRef) {
5472 LLVMTypeRef argtype;
5473 LLVMValueRef loc, v;
5475 argtype = type_to_llvm_arg_type (ctx, t);
5476 loc = build_alloca_llvm_type (ctx, argtype, 0);
5477 v = convert (ctx, values [ins->sreg1], argtype);
5478 LLVMBuildStore (ctx->builder, v, loc);
5479 addresses [ins->dreg] = loc;
5480 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5481 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5483 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5484 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5486 g_assert (addresses [ins->sreg1]);
5487 addresses [ins->dreg] = addresses [ins->sreg1];
5490 if (!addresses [ins->sreg1]) {
5491 addresses [ins->sreg1] = build_alloca (ctx, t);
5492 g_assert (values [ins->sreg1]);
5493 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5495 addresses [ins->dreg] = addresses [ins->sreg1];
5503 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5505 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5508 case OP_LOADX_MEMBASE: {
5509 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5512 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5513 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5516 case OP_STOREX_MEMBASE: {
5517 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5520 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5521 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5528 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5532 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5538 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5542 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5546 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5550 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5553 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5556 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5559 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5563 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5574 LLVMValueRef v = NULL;
5576 switch (ins->opcode) {
5581 t = LLVMVectorType (LLVMInt32Type (), 4);
5582 rt = LLVMVectorType (LLVMFloatType (), 4);
5588 t = LLVMVectorType (LLVMInt64Type (), 2);
5589 rt = LLVMVectorType (LLVMDoubleType (), 2);
5592 t = LLVMInt32Type ();
5593 rt = LLVMInt32Type ();
5594 g_assert_not_reached ();
5597 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5598 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5599 switch (ins->opcode) {
5602 v = LLVMBuildAnd (builder, lhs, rhs, "");
5606 v = LLVMBuildOr (builder, lhs, rhs, "");
5610 v = LLVMBuildXor (builder, lhs, rhs, "");
5614 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5617 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5641 case OP_PADDB_SAT_UN:
5642 case OP_PADDW_SAT_UN:
5643 case OP_PSUBB_SAT_UN:
5644 case OP_PSUBW_SAT_UN:
5652 case OP_PMULW_HIGH_UN: {
5653 LLVMValueRef args [2];
5658 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5665 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5669 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5677 case OP_EXTRACTX_U2:
5679 case OP_EXTRACT_U1: {
5681 gboolean zext = FALSE;
5683 t = simd_op_to_llvm_type (ins->opcode);
5685 switch (ins->opcode) {
5693 case OP_EXTRACTX_U2:
5698 t = LLVMInt32Type ();
5699 g_assert_not_reached ();
5702 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5703 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5705 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5714 case OP_EXPAND_R8: {
5715 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5716 LLVMValueRef mask [16], v;
5719 for (i = 0; i < 16; ++i)
5720 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5722 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5724 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5725 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5730 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5733 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5736 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5739 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5742 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5745 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5756 case OP_EXTRACT_MASK:
5763 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5765 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5771 LLVMValueRef args [3];
5775 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5777 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5782 /* This is only used for implementing shifts by non-immediate */
5783 values [ins->dreg] = lhs;
5794 LLVMValueRef args [3];
5797 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5799 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5810 case OP_PSHLQ_REG: {
5811 LLVMValueRef args [3];
5814 args [1] = values [ins->sreg2];
5816 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5823 case OP_PSHUFLEW_LOW:
5824 case OP_PSHUFLEW_HIGH: {
5826 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5827 int i, mask_size = 0;
5828 int imask = ins->inst_c0;
5830 /* Convert the x86 shuffle mask to LLVM's */
5831 switch (ins->opcode) {
5834 mask [0] = ((imask >> 0) & 3);
5835 mask [1] = ((imask >> 2) & 3);
5836 mask [2] = ((imask >> 4) & 3) + 4;
5837 mask [3] = ((imask >> 6) & 3) + 4;
5838 v1 = values [ins->sreg1];
5839 v2 = values [ins->sreg2];
5843 mask [0] = ((imask >> 0) & 1);
5844 mask [1] = ((imask >> 1) & 1) + 2;
5845 v1 = values [ins->sreg1];
5846 v2 = values [ins->sreg2];
5848 case OP_PSHUFLEW_LOW:
5850 mask [0] = ((imask >> 0) & 3);
5851 mask [1] = ((imask >> 2) & 3);
5852 mask [2] = ((imask >> 4) & 3);
5853 mask [3] = ((imask >> 6) & 3);
5858 v1 = values [ins->sreg1];
5859 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5861 case OP_PSHUFLEW_HIGH:
5867 mask [4] = 4 + ((imask >> 0) & 3);
5868 mask [5] = 4 + ((imask >> 2) & 3);
5869 mask [6] = 4 + ((imask >> 4) & 3);
5870 mask [7] = 4 + ((imask >> 6) & 3);
5871 v1 = values [ins->sreg1];
5872 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5876 mask [0] = ((imask >> 0) & 3);
5877 mask [1] = ((imask >> 2) & 3);
5878 mask [2] = ((imask >> 4) & 3);
5879 mask [3] = ((imask >> 6) & 3);
5880 v1 = values [ins->sreg1];
5881 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5884 g_assert_not_reached ();
5886 for (i = 0; i < mask_size; ++i)
5887 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5889 values [ins->dreg] =
5890 LLVMBuildShuffleVector (builder, v1, v2,
5891 LLVMConstVector (mask_values, mask_size), dname);
5895 case OP_UNPACK_LOWB:
5896 case OP_UNPACK_LOWW:
5897 case OP_UNPACK_LOWD:
5898 case OP_UNPACK_LOWQ:
5899 case OP_UNPACK_LOWPS:
5900 case OP_UNPACK_LOWPD:
5901 case OP_UNPACK_HIGHB:
5902 case OP_UNPACK_HIGHW:
5903 case OP_UNPACK_HIGHD:
5904 case OP_UNPACK_HIGHQ:
5905 case OP_UNPACK_HIGHPS:
5906 case OP_UNPACK_HIGHPD: {
5908 LLVMValueRef mask_values [16];
5909 int i, mask_size = 0;
5910 gboolean low = FALSE;
5912 switch (ins->opcode) {
5913 case OP_UNPACK_LOWB:
5917 case OP_UNPACK_LOWW:
5921 case OP_UNPACK_LOWD:
5922 case OP_UNPACK_LOWPS:
5926 case OP_UNPACK_LOWQ:
5927 case OP_UNPACK_LOWPD:
5931 case OP_UNPACK_HIGHB:
5934 case OP_UNPACK_HIGHW:
5937 case OP_UNPACK_HIGHD:
5938 case OP_UNPACK_HIGHPS:
5941 case OP_UNPACK_HIGHQ:
5942 case OP_UNPACK_HIGHPD:
5946 g_assert_not_reached ();
5950 for (i = 0; i < (mask_size / 2); ++i) {
5952 mask [(i * 2) + 1] = mask_size + i;
5955 for (i = 0; i < (mask_size / 2); ++i) {
5956 mask [(i * 2)] = (mask_size / 2) + i;
5957 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
5961 for (i = 0; i < mask_size; ++i)
5962 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5964 values [ins->dreg] =
5965 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
5966 LLVMConstVector (mask_values, mask_size), dname);
5971 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5972 LLVMValueRef v, val;
5974 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5975 val = LLVMConstNull (t);
5976 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5977 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
5979 values [ins->dreg] = val;
5983 case OP_DUPPS_HIGH: {
5984 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5985 LLVMValueRef v1, v2, val;
5988 if (ins->opcode == OP_DUPPS_LOW) {
5989 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5990 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5992 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5993 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5995 val = LLVMConstNull (t);
5996 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5997 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5998 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5999 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6001 values [ins->dreg] = val;
6011 * EXCEPTION HANDLING
6013 case OP_IMPLICIT_EXCEPTION:
6014 /* This marks a place where an implicit exception can happen */
6015 if (bb->region != -1)
6016 LLVM_FAILURE (ctx, "implicit-exception");
6020 gboolean rethrow = (ins->opcode == OP_RETHROW);
6021 if (ctx->llvm_only) {
6022 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6023 has_terminator = TRUE;
6024 ctx->unreachable [bb->block_num] = TRUE;
6026 emit_throw (ctx, bb, rethrow, lhs);
6027 builder = ctx->builder;
6031 case OP_CALL_HANDLER: {
6033 * We don't 'call' handlers, but instead simply branch to them.
6034 * The code generated by ENDFINALLY will branch back to us.
6036 LLVMBasicBlockRef noex_bb;
6038 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6040 bb_list = info->call_handler_return_bbs;
6043 * Set the indicator variable for the finally clause.
6045 lhs = info->finally_ind;
6047 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6049 /* Branch to the finally clause */
6050 LLVMBuildBr (builder, info->call_handler_target_bb);
6052 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6053 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6055 builder = ctx->builder = create_builder (ctx);
6056 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6058 bblocks [bb->block_num].end_bblock = noex_bb;
6061 case OP_START_HANDLER: {
6064 case OP_ENDFINALLY: {
6065 LLVMBasicBlockRef resume_bb;
6066 MonoBasicBlock *handler_bb;
6067 LLVMValueRef val, switch_ins, callee;
6071 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6072 g_assert (handler_bb);
6073 info = &bblocks [handler_bb->block_num];
6074 lhs = info->finally_ind;
6077 bb_list = info->call_handler_return_bbs;
6079 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6081 /* Load the finally variable */
6082 val = LLVMBuildLoad (builder, lhs, "");
6084 /* Reset the variable */
6085 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6087 /* Branch to either resume_bb, or to the bblocks in bb_list */
6088 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6090 * The other targets are added at the end to handle OP_CALL_HANDLER
6091 * opcodes processed later.
6093 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6095 builder = ctx->builder = create_builder (ctx);
6096 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6098 if (ctx->llvm_only) {
6099 emit_resume_eh (ctx, bb);
6101 if (ctx->cfg->compile_aot) {
6102 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6104 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6106 LLVMBuildCall (builder, callee, NULL, 0, "");
6107 LLVMBuildUnreachable (builder);
6110 has_terminator = TRUE;
6113 case OP_IL_SEQ_POINT:
6118 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6119 LLVM_FAILURE (ctx, reason);
6124 /* Convert the value to the type required by phi nodes */
6125 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6126 if (!values [ins->dreg])
6128 values [ins->dreg] = addresses [ins->dreg];
6130 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6133 /* Add stores for volatile variables */
6134 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6135 emit_volatile_store (ctx, ins->dreg);
6138 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6139 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6142 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6143 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6144 LLVMBuildRetVoid (builder);
6147 if (bb == cfg->bb_entry)
6148 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6157 * mono_llvm_check_method_supported:
6159 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6160 * compiling a method twice.
6163 mono_llvm_check_method_supported (MonoCompile *cfg)
6170 if (cfg->method->save_lmf) {
6171 cfg->exception_message = g_strdup ("lmf");
6172 cfg->disable_llvm = TRUE;
6174 if (cfg->disable_llvm)
6178 * Nested clauses where one of the clauses is a finally clause is
6179 * not supported, because LLVM can't figure out the control flow,
6180 * probably because we resume exception handling by calling our
6181 * own function instead of using the 'resume' llvm instruction.
6183 for (i = 0; i < cfg->header->num_clauses; ++i) {
6184 for (j = 0; j < cfg->header->num_clauses; ++j) {
6185 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6186 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6188 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6189 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6190 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6191 cfg->exception_message = g_strdup ("nested clauses");
6192 cfg->disable_llvm = TRUE;
6197 if (cfg->disable_llvm)
6201 if (cfg->method->dynamic) {
6202 cfg->exception_message = g_strdup ("dynamic.");
6203 cfg->disable_llvm = TRUE;
6205 if (cfg->disable_llvm)
6209 static LLVMCallInfo*
6210 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6212 LLVMCallInfo *linfo;
6215 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6219 * Gsharedvt methods have the following calling convention:
6220 * - all arguments are passed by ref, even non generic ones
6221 * - the return value is returned by ref too, using a vret
6222 * argument passed after 'this'.
6224 n = sig->param_count + sig->hasthis;
6225 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6229 linfo->args [pindex ++].storage = LLVMArgNormal;
6231 if (sig->ret->type != MONO_TYPE_VOID) {
6232 if (mini_is_gsharedvt_variable_type (sig->ret))
6233 linfo->ret.storage = LLVMArgGsharedvtVariable;
6234 else if (mini_type_is_vtype (sig->ret))
6235 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6237 linfo->ret.storage = LLVMArgGsharedvtFixed;
6238 linfo->vret_arg_index = pindex;
6240 linfo->ret.storage = LLVMArgNone;
6243 for (i = 0; i < sig->param_count; ++i) {
6244 if (sig->params [i]->byref)
6245 linfo->args [pindex].storage = LLVMArgNormal;
6246 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6247 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6248 else if (mini_type_is_vtype (sig->params [i]))
6249 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6251 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6252 linfo->args [pindex].type = sig->params [i];
6259 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6260 for (i = 0; i < sig->param_count; ++i)
6261 linfo->args [i + sig->hasthis].type = sig->params [i];
6267 * mono_llvm_emit_method:
6269 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6272 mono_llvm_emit_method (MonoCompile *cfg)
6275 MonoMethodSignature *sig;
6277 LLVMTypeRef method_type;
6278 LLVMValueRef method = NULL;
6280 LLVMValueRef *values;
6281 int i, max_block_num, bb_index;
6282 gboolean last = FALSE, is_linkonce = FALSE;
6283 GPtrArray *phi_values;
6284 LLVMCallInfo *linfo;
6286 LLVMModuleRef lmodule;
6288 GPtrArray *bblock_list;
6289 MonoMethodHeader *header;
6290 MonoExceptionClause *clause;
6293 /* The code below might acquire the loader lock, so use it for global locking */
6294 mono_loader_lock ();
6296 /* Used to communicate with the callbacks */
6297 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6299 ctx = g_new0 (EmitContext, 1);
6301 ctx->mempool = cfg->mempool;
6304 * This maps vregs to the LLVM instruction defining them
6306 values = g_new0 (LLVMValueRef, cfg->next_vreg);
6308 * This maps vregs for volatile variables to the LLVM instruction defining their
6311 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6312 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6313 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6314 phi_values = g_ptr_array_sized_new (256);
6316 * This signals whenever the vreg was defined by a phi node with no input vars
6317 * (i.e. all its input bblocks end with NOT_REACHABLE).
6319 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6320 /* Whenever the bblock is unreachable */
6321 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6322 bblock_list = g_ptr_array_sized_new (256);
6324 ctx->values = values;
6325 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6326 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6327 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6329 if (cfg->compile_aot) {
6330 ctx->module = &aot_module;
6334 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6335 * linkage for them. This requires the following:
6336 * - the method needs to have a unique mangled name
6337 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6339 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6341 method_name = mono_aot_get_mangled_method_name (cfg->method);
6343 is_linkonce = FALSE;
6346 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6348 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6352 method_name = mono_aot_get_method_name (cfg);
6353 cfg->llvm_method_name = g_strdup (method_name);
6355 init_jit_module (cfg->domain);
6356 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6357 method_name = mono_method_full_name (cfg->method, TRUE);
6360 lmodule = ctx->lmodule = ctx->module->lmodule;
6361 ctx->llvm_only = ctx->module->llvm_only;
6363 if (cfg->gsharedvt && !cfg->llvm_only)
6364 LLVM_FAILURE (ctx, "gsharedvt");
6368 static int count = 0;
6371 if (g_getenv ("LLVM_COUNT")) {
6372 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6373 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6377 if (count > atoi (g_getenv ("LLVM_COUNT")))
6378 LLVM_FAILURE (ctx, "");
6383 sig = mono_method_signature (cfg->method);
6386 linfo = get_llvm_call_info (cfg, sig);
6388 CHECK_FAILURE (ctx);
6391 linfo->rgctx_arg = TRUE;
6392 method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6393 CHECK_FAILURE (ctx);
6395 method = LLVMAddFunction (lmodule, method_name, method_type);
6396 ctx->lmethod = method;
6398 if (!cfg->llvm_only)
6399 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6400 LLVMSetLinkage (method, LLVMPrivateLinkage);
6402 LLVMAddFunctionAttr (method, LLVMUWTable);
6404 if (cfg->compile_aot) {
6405 LLVMSetLinkage (method, LLVMInternalLinkage);
6406 if (ctx->module->external_symbols) {
6407 LLVMSetLinkage (method, LLVMExternalLinkage);
6408 LLVMSetVisibility (method, LLVMHiddenVisibility);
6411 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6412 LLVMSetVisibility (method, LLVMDefaultVisibility);
6415 LLVMSetLinkage (method, LLVMPrivateLinkage);
6418 if (cfg->method->save_lmf && !cfg->llvm_only)
6419 LLVM_FAILURE (ctx, "lmf");
6421 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only)
6422 LLVM_FAILURE (ctx, "pinvoke signature");
6424 header = cfg->header;
6425 for (i = 0; i < header->num_clauses; ++i) {
6426 clause = &header->clauses [i];
6427 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
6428 LLVM_FAILURE (ctx, "non-finally/catch clause.");
6430 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
6431 /* We can't handle inlined methods with clauses */
6432 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6434 if (linfo->rgctx_arg) {
6435 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6436 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6438 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6439 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6440 * CC_X86_64_Mono in X86CallingConv.td.
6442 if (!ctx->llvm_only)
6443 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6444 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6446 ctx->rgctx_arg_pindex = -1;
6448 if (cfg->vret_addr) {
6449 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6450 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6451 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6452 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6453 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6455 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6456 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6457 LLVMSetValueName (param, "vret");
6461 ctx->this_arg_pindex = linfo->this_arg_pindex;
6462 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6463 values [cfg->args [0]->dreg] = ctx->this_arg;
6464 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6467 names = g_new (char *, sig->param_count);
6468 mono_method_get_param_names (cfg->method, (const char **) names);
6470 for (i = 0; i < sig->param_count; ++i) {
6471 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6473 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6476 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6477 name = g_strdup_printf ("dummy_%d_%d", i, j);
6478 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6482 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6483 if (ainfo->storage == LLVMArgScalarByRef) {
6484 if (names [i] && names [i][0] != '\0')
6485 name = g_strdup_printf ("p_arg_%s", names [i]);
6487 name = g_strdup_printf ("p_arg_%d", i);
6488 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6489 if (names [i] && names [i][0] != '\0')
6490 name = g_strdup_printf ("p_arg_%s", names [i]);
6492 name = g_strdup_printf ("p_arg_%d", i);
6494 if (names [i] && names [i][0] != '\0')
6495 name = g_strdup_printf ("arg_%s", names [i]);
6497 name = g_strdup_printf ("arg_%d", i);
6499 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6501 if (ainfo->storage == LLVMArgVtypeByVal)
6502 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6504 if (ainfo->storage == LLVMArgVtypeByRef) {
6506 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6511 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6512 ctx->minfo = mono_debug_lookup_method (cfg->method);
6513 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
6517 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6518 max_block_num = MAX (max_block_num, bb->block_num);
6519 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6521 /* Add branches between non-consecutive bblocks */
6522 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6523 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6524 bb->next_bb != bb->last_ins->inst_false_bb) {
6526 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6527 inst->opcode = OP_BR;
6528 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6529 mono_bblock_add_inst (bb, inst);
6534 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6535 * was later optimized away, so clear these flags, and add them back for the still
6536 * present OP_LDADDR instructions.
6538 for (i = 0; i < cfg->next_vreg; ++i) {
6541 ins = get_vreg_to_inst (cfg, i);
6542 if (ins && ins != cfg->rgctx_var)
6543 ins->flags &= ~MONO_INST_INDIRECT;
6547 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6549 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6551 LLVMBuilderRef builder;
6553 char dname_buf[128];
6555 builder = create_builder (ctx);
6557 for (ins = bb->code; ins; ins = ins->next) {
6558 switch (ins->opcode) {
6563 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6565 CHECK_FAILURE (ctx);
6567 if (ins->opcode == OP_VPHI) {
6568 /* Treat valuetype PHI nodes as operating on the address itself */
6569 g_assert (ins->klass);
6570 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6574 * Have to precreate these, as they can be referenced by
6575 * earlier instructions.
6577 sprintf (dname_buf, "t%d", ins->dreg);
6579 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6581 if (ins->opcode == OP_VPHI)
6582 ctx->addresses [ins->dreg] = values [ins->dreg];
6584 g_ptr_array_add (phi_values, values [ins->dreg]);
6587 * Set the expected type of the incoming arguments since these have
6588 * to have the same type.
6590 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6591 int sreg1 = ins->inst_phi_args [i + 1];
6594 ctx->vreg_types [sreg1] = phi_type;
6599 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6608 * Create an ordering for bblocks, use the depth first order first, then
6609 * put the exception handling bblocks last.
6611 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6612 bb = cfg->bblocks [bb_index];
6613 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6614 g_ptr_array_add (bblock_list, bb);
6615 bblocks [bb->block_num].added = TRUE;
6619 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6620 if (!bblocks [bb->block_num].added)
6621 g_ptr_array_add (bblock_list, bb);
6625 * Second pass: generate code.
6628 LLVMBuilderRef entry_builder = create_builder (ctx);
6629 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6630 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6631 emit_entry_bb (ctx, entry_builder);
6633 // Make landing pads first
6634 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6636 if (ctx->llvm_only) {
6637 size_t group_index = 0;
6638 while (group_index < cfg->header->num_clauses) {
6640 size_t cursor = group_index;
6641 while (cursor < cfg->header->num_clauses &&
6642 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6643 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6648 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6649 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6650 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6652 group_index = cursor;
6656 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6657 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6659 // Prune unreachable mono BBs.
6660 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6663 process_bb (ctx, bb);
6664 CHECK_FAILURE (ctx);
6666 g_hash_table_destroy (ctx->exc_meta);
6668 mono_memory_barrier ();
6670 /* Add incoming phi values */
6671 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6672 GSList *l, *ins_list;
6674 ins_list = bblocks [bb->block_num].phi_nodes;
6676 for (l = ins_list; l; l = l->next) {
6677 PhiNode *node = (PhiNode*)l->data;
6678 MonoInst *phi = node->phi;
6679 int sreg1 = node->sreg;
6680 LLVMBasicBlockRef in_bb;
6685 in_bb = get_end_bb (ctx, node->in_bb);
6687 if (ctx->unreachable [node->in_bb->block_num])
6690 if (!values [sreg1])
6691 /* Can happen with values in EH clauses */
6692 LLVM_FAILURE (ctx, "incoming phi sreg1");
6694 if (phi->opcode == OP_VPHI) {
6695 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6696 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6698 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
6700 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
6701 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6702 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6707 /* Nullify empty phi instructions */
6708 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6709 GSList *l, *ins_list;
6711 ins_list = bblocks [bb->block_num].phi_nodes;
6713 for (l = ins_list; l; l = l->next) {
6714 PhiNode *node = (PhiNode*)l->data;
6715 MonoInst *phi = node->phi;
6716 LLVMValueRef phi_ins = values [phi->dreg];
6719 /* Already removed */
6722 if (LLVMCountIncoming (phi_ins) == 0) {
6723 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6724 LLVMInstructionEraseFromParent (phi_ins);
6725 values [phi->dreg] = NULL;
6730 /* Create the SWITCH statements for ENDFINALLY instructions */
6731 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6732 BBInfo *info = &bblocks [bb->block_num];
6734 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6735 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6736 GSList *bb_list = info->call_handler_return_bbs;
6738 for (i = 0; i < g_slist_length (bb_list); ++i)
6739 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6743 /* Initialize the method if needed */
6744 if (cfg->compile_aot && ctx->llvm_only) {
6745 // FIXME: Add more shared got entries
6746 ctx->builder = create_builder (ctx);
6747 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6749 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6751 // FIXME: beforefieldinit
6752 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6753 emit_init_method (ctx);
6755 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6759 if (cfg->llvm_only) {
6760 GHashTableIter iter;
6762 GSList *callers, *l, *l2;
6765 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6766 * We can't do this earlier, as it contains llvm instructions which can be
6767 * freed if compilation fails.
6768 * FIXME: Get rid of this when all methods can be llvm compiled.
6770 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6771 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6772 for (l = callers; l; l = l->next) {
6773 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6774 l2 = g_slist_prepend (l2, l->data);
6775 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6780 if (cfg->verbose_level > 1)
6781 mono_llvm_dump_value (method);
6783 if (cfg->compile_aot && !cfg->llvm_only)
6784 mark_as_used (ctx->module, method);
6786 if (cfg->compile_aot) {
6787 LLVMValueRef md_args [16];
6788 LLVMValueRef md_node;
6791 method_index = mono_aot_get_method_index (cfg->orig_method);
6792 md_args [0] = LLVMMDString (method_name, strlen (method_name));
6793 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6794 md_node = LLVMMDNode (md_args, 2);
6795 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6796 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6799 if (cfg->compile_aot) {
6800 /* Don't generate native code, keep the LLVM IR */
6801 if (cfg->verbose_level)
6802 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
6804 int err = LLVMVerifyFunction(method, LLVMPrintMessageAction);
6805 g_assert (err == 0);
6807 //LLVMVerifyFunction(method, 0);
6808 mono_llvm_optimize_method (ctx->module->mono_ee, method);
6810 if (cfg->verbose_level > 1)
6811 mono_llvm_dump_value (method);
6813 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, method);
6815 /* Set by emit_cb */
6816 g_assert (cfg->code_len);
6818 /* FIXME: Free the LLVM IL for the function */
6821 if (ctx->module->method_to_lmethod)
6822 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, method);
6823 if (ctx->module->idx_to_lmethod)
6824 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), method);
6826 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6827 emit_unbox_tramp (ctx, method_name, method_type, method, cfg->method_index);
6834 /* Need to add unused phi nodes as they can be referenced by other values */
6835 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
6836 LLVMBuilderRef builder;
6838 builder = create_builder (ctx);
6839 LLVMPositionBuilderAtEnd (builder, phi_bb);
6841 for (i = 0; i < phi_values->len; ++i) {
6842 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (phi_values, i);
6843 if (LLVMGetInstructionParent (v) == NULL)
6844 LLVMInsertIntoBuilder (builder, v);
6847 LLVMDeleteFunction (method);
6852 g_free (ctx->addresses);
6853 g_free (ctx->vreg_types);
6854 g_free (ctx->vreg_cli_types);
6855 g_free (ctx->is_dead);
6856 g_free (ctx->unreachable);
6857 g_ptr_array_free (phi_values, TRUE);
6858 g_free (ctx->bblocks);
6859 g_hash_table_destroy (ctx->region_to_handler);
6860 g_hash_table_destroy (ctx->clause_to_handler);
6861 g_free (method_name);
6862 g_ptr_array_free (bblock_list, TRUE);
6864 for (l = ctx->builders; l; l = l->next) {
6865 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6866 LLVMDisposeBuilder (builder);
6871 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6873 mono_loader_unlock ();
6877 * mono_llvm_create_vars:
6879 * Same as mono_arch_create_vars () for LLVM.
6882 mono_llvm_create_vars (MonoCompile *cfg)
6884 MonoMethodSignature *sig;
6886 sig = mono_method_signature (cfg->method);
6887 if (cfg->gsharedvt && cfg->llvm_only) {
6888 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
6889 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_int32_class ()->byval_arg, OP_ARG);
6890 if (G_UNLIKELY (cfg->verbose_level > 1)) {
6891 printf ("vret_addr = ");
6892 mono_print_ins (cfg->vret_addr);
6896 mono_arch_create_vars (cfg);
6901 * mono_llvm_emit_call:
6903 * Same as mono_arch_emit_call () for LLVM.
6906 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
6909 MonoMethodSignature *sig;
6910 int i, n, stack_size;
6915 sig = call->signature;
6916 n = sig->param_count + sig->hasthis;
6918 call->cinfo = get_llvm_call_info (cfg, sig);
6920 if (cfg->disable_llvm)
6923 if (sig->call_convention == MONO_CALL_VARARG) {
6924 cfg->exception_message = g_strdup ("varargs");
6925 cfg->disable_llvm = TRUE;
6928 for (i = 0; i < n; ++i) {
6931 ainfo = call->cinfo->args + i;
6933 in = call->args [i];
6935 /* Simply remember the arguments */
6936 switch (ainfo->storage) {
6937 case LLVMArgNormal: {
6938 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
6941 opcode = mono_type_to_regmove (cfg, t);
6942 if (opcode == OP_FMOVE) {
6943 MONO_INST_NEW (cfg, ins, OP_FMOVE);
6944 ins->dreg = mono_alloc_freg (cfg);
6945 } else if (opcode == OP_LMOVE) {
6946 MONO_INST_NEW (cfg, ins, OP_LMOVE);
6947 ins->dreg = mono_alloc_lreg (cfg);
6948 } else if (opcode == OP_RMOVE) {
6949 MONO_INST_NEW (cfg, ins, OP_RMOVE);
6950 ins->dreg = mono_alloc_freg (cfg);
6952 MONO_INST_NEW (cfg, ins, OP_MOVE);
6953 ins->dreg = mono_alloc_ireg (cfg);
6955 ins->sreg1 = in->dreg;
6958 case LLVMArgVtypeByVal:
6959 case LLVMArgVtypeByRef:
6960 case LLVMArgVtypeInReg:
6961 case LLVMArgVtypeAsScalar:
6962 case LLVMArgScalarByRef:
6963 case LLVMArgAsIArgs:
6964 case LLVMArgAsFpArgs:
6965 case LLVMArgGsharedvtVariable:
6966 case LLVMArgGsharedvtFixed:
6967 case LLVMArgGsharedvtFixedVtype:
6968 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
6969 ins->dreg = mono_alloc_ireg (cfg);
6970 ins->sreg1 = in->dreg;
6971 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
6972 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
6973 ins->inst_vtype = ainfo->type;
6974 ins->klass = mono_class_from_mono_type (ainfo->type);
6977 cfg->exception_message = g_strdup ("ainfo->storage");
6978 cfg->disable_llvm = TRUE;
6982 if (!cfg->disable_llvm) {
6983 MONO_ADD_INS (cfg->cbb, ins);
6984 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
6989 static unsigned char*
6990 alloc_cb (LLVMValueRef function, int size)
6994 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
6998 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7000 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7005 emitted_cb (LLVMValueRef function, void *start, void *end)
7009 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7011 cfg->code_len = (guint8*)end - (guint8*)start;
7015 exception_cb (void *data)
7018 MonoJitExceptionInfo *ei;
7019 guint32 ei_len, i, j, nested_len, nindex;
7020 gpointer *type_info;
7021 int this_reg, this_offset;
7023 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7027 * data points to a DWARF FDE structure, convert it to our unwind format and
7029 * An alternative would be to save it directly, and modify our unwinder to work
7032 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);
7033 if (cfg->verbose_level > 1)
7034 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7036 /* Count nested clauses */
7038 for (i = 0; i < ei_len; ++i) {
7039 gint32 cindex1 = *(gint32*)type_info [i];
7040 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7042 for (j = 0; j < cfg->header->num_clauses; ++j) {
7044 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7046 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7052 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7053 cfg->llvm_ex_info_len = ei_len + nested_len;
7054 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7055 /* Fill the rest of the information from the type info */
7056 for (i = 0; i < ei_len; ++i) {
7057 gint32 clause_index = *(gint32*)type_info [i];
7058 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7060 cfg->llvm_ex_info [i].flags = clause->flags;
7061 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7062 cfg->llvm_ex_info [i].clause_index = clause_index;
7066 * For nested clauses, the LLVM produced exception info associates the try interval with
7067 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7068 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7069 * and everything else from the nested clause.
7072 for (i = 0; i < ei_len; ++i) {
7073 gint32 cindex1 = *(gint32*)type_info [i];
7074 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7076 for (j = 0; j < cfg->header->num_clauses; ++j) {
7078 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7079 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7081 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7082 /* clause1 is the nested clause */
7083 nested_ei = &cfg->llvm_ex_info [i];
7084 nesting_ei = &cfg->llvm_ex_info [nindex];
7087 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7089 nesting_ei->flags = clause2->flags;
7090 nesting_ei->data.catch_class = clause2->data.catch_class;
7091 nesting_ei->clause_index = cindex2;
7095 g_assert (nindex == ei_len + nested_len);
7096 cfg->llvm_this_reg = this_reg;
7097 cfg->llvm_this_offset = this_offset;
7099 /* type_info [i] is cfg mempool allocated, no need to free it */
7106 dlsym_cb (const char *name, void **symbol)
7112 if (!strcmp (name, "__bzero")) {
7113 *symbol = (void*)bzero;
7115 current = mono_dl_open (NULL, 0, NULL);
7118 err = mono_dl_symbol (current, name, symbol);
7120 mono_dl_close (current);
7122 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7123 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7129 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7131 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7135 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7137 LLVMTypeRef param_types [4];
7139 param_types [0] = param_type1;
7140 param_types [1] = param_type2;
7142 AddFunc (module, name, ret_type, param_types, 2);
7146 add_intrinsics (LLVMModuleRef module)
7148 /* Emit declarations of instrinsics */
7150 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7151 * type doesn't seem to do any locking.
7154 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7156 memset_param_count = 5;
7157 memset_func_name = "llvm.memset.p0i8.i32";
7159 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7163 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7165 memcpy_param_count = 5;
7166 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7168 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7172 LLVMTypeRef params [] = { LLVMDoubleType () };
7174 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7175 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7176 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7178 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7179 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7183 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7184 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7185 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7187 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7188 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7189 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7190 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7191 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7192 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7193 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7197 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7198 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7199 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7201 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7202 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7203 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7204 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7205 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7206 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7209 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7210 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7214 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7216 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7219 /* SSE intrinsics */
7220 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7222 LLVMTypeRef ret_type, arg_types [16];
7225 ret_type = type_to_simd_type (MONO_TYPE_I4);
7226 arg_types [0] = ret_type;
7227 arg_types [1] = ret_type;
7228 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7229 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7231 ret_type = type_to_simd_type (MONO_TYPE_I2);
7232 arg_types [0] = ret_type;
7233 arg_types [1] = ret_type;
7234 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7235 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7236 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7237 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7238 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7239 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7240 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7241 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7242 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7243 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7245 ret_type = type_to_simd_type (MONO_TYPE_I1);
7246 arg_types [0] = ret_type;
7247 arg_types [1] = ret_type;
7248 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7249 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7250 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7251 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7252 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7253 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7254 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7256 ret_type = type_to_simd_type (MONO_TYPE_R8);
7257 arg_types [0] = ret_type;
7258 arg_types [1] = ret_type;
7259 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7260 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7261 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7262 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7263 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7265 ret_type = type_to_simd_type (MONO_TYPE_R4);
7266 arg_types [0] = ret_type;
7267 arg_types [1] = ret_type;
7268 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7269 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7270 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7271 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7272 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7275 ret_type = type_to_simd_type (MONO_TYPE_I1);
7276 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7277 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7278 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7279 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7280 ret_type = type_to_simd_type (MONO_TYPE_I2);
7281 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7282 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7283 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7284 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7287 ret_type = type_to_simd_type (MONO_TYPE_R8);
7288 arg_types [0] = ret_type;
7289 arg_types [1] = ret_type;
7290 arg_types [2] = LLVMInt8Type ();
7291 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7292 ret_type = type_to_simd_type (MONO_TYPE_R4);
7293 arg_types [0] = ret_type;
7294 arg_types [1] = ret_type;
7295 arg_types [2] = LLVMInt8Type ();
7296 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7298 /* Conversion ops */
7299 ret_type = type_to_simd_type (MONO_TYPE_R8);
7300 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7301 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7302 ret_type = type_to_simd_type (MONO_TYPE_R4);
7303 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7304 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7305 ret_type = type_to_simd_type (MONO_TYPE_I4);
7306 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7307 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7308 ret_type = type_to_simd_type (MONO_TYPE_I4);
7309 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7310 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7311 ret_type = type_to_simd_type (MONO_TYPE_R4);
7312 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7313 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7314 ret_type = type_to_simd_type (MONO_TYPE_R8);
7315 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7316 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7318 ret_type = type_to_simd_type (MONO_TYPE_I4);
7319 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7320 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7321 ret_type = type_to_simd_type (MONO_TYPE_I4);
7322 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7323 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7326 ret_type = type_to_simd_type (MONO_TYPE_R8);
7327 arg_types [0] = ret_type;
7328 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7329 ret_type = type_to_simd_type (MONO_TYPE_R4);
7330 arg_types [0] = ret_type;
7331 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7332 ret_type = type_to_simd_type (MONO_TYPE_R4);
7333 arg_types [0] = ret_type;
7334 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7335 ret_type = type_to_simd_type (MONO_TYPE_R4);
7336 arg_types [0] = ret_type;
7337 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7340 ret_type = type_to_simd_type (MONO_TYPE_I2);
7341 arg_types [0] = ret_type;
7342 arg_types [1] = LLVMInt32Type ();
7343 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7344 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7345 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7346 ret_type = type_to_simd_type (MONO_TYPE_I4);
7347 arg_types [0] = ret_type;
7348 arg_types [1] = LLVMInt32Type ();
7349 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7350 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7351 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7352 ret_type = type_to_simd_type (MONO_TYPE_I8);
7353 arg_types [0] = ret_type;
7354 arg_types [1] = LLVMInt32Type ();
7355 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7356 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7359 ret_type = LLVMInt32Type ();
7360 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7361 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7364 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7367 /* Load/Store intrinsics */
7369 LLVMTypeRef arg_types [5];
7373 for (i = 1; i <= 8; i *= 2) {
7374 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7375 arg_types [1] = LLVMInt32Type ();
7376 arg_types [2] = LLVMInt1Type ();
7377 arg_types [3] = LLVMInt32Type ();
7378 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7379 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7381 arg_types [0] = LLVMIntType (i * 8);
7382 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7383 arg_types [2] = LLVMInt32Type ();
7384 arg_types [3] = LLVMInt1Type ();
7385 arg_types [4] = LLVMInt32Type ();
7386 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7387 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7393 add_types (MonoLLVMModule *module)
7395 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7399 mono_llvm_init (void)
7401 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7405 init_jit_module (MonoDomain *domain)
7407 MonoJitICallInfo *info;
7408 MonoJitDomainInfo *dinfo;
7409 MonoLLVMModule *module;
7412 dinfo = domain_jit_info (domain);
7413 if (dinfo->llvm_module)
7416 mono_loader_lock ();
7418 if (dinfo->llvm_module) {
7419 mono_loader_unlock ();
7423 module = g_new0 (MonoLLVMModule, 1);
7425 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7426 module->lmodule = LLVMModuleCreateWithName (name);
7427 module->context = LLVMGetGlobalContext ();
7429 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7431 add_intrinsics (module->lmodule);
7434 module->llvm_types = g_hash_table_new (NULL, NULL);
7436 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7438 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7440 mono_memory_barrier ();
7442 dinfo->llvm_module = module;
7444 mono_loader_unlock ();
7448 mono_llvm_cleanup (void)
7450 MonoLLVMModule *module = &aot_module;
7452 if (module->lmodule)
7453 LLVMDisposeModule (module->lmodule);
7455 if (module->context)
7456 LLVMContextDispose (module->context);
7460 mono_llvm_free_domain_info (MonoDomain *domain)
7462 MonoJitDomainInfo *info = domain_jit_info (domain);
7463 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7469 if (module->llvm_types)
7470 g_hash_table_destroy (module->llvm_types);
7472 mono_llvm_dispose_ee (module->mono_ee);
7474 if (module->bb_names) {
7475 for (i = 0; i < module->bb_names_len; ++i)
7476 g_free (module->bb_names [i]);
7477 g_free (module->bb_names);
7479 //LLVMDisposeModule (module->module);
7483 info->llvm_module = NULL;
7487 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7489 MonoLLVMModule *module = &aot_module;
7491 /* Delete previous module */
7492 if (module->plt_entries)
7493 g_hash_table_destroy (module->plt_entries);
7494 if (module->lmodule)
7495 LLVMDisposeModule (module->lmodule);
7497 memset (module, 0, sizeof (aot_module));
7499 module->lmodule = LLVMModuleCreateWithName ("aot");
7500 module->assembly = assembly;
7501 module->global_prefix = g_strdup (global_prefix);
7502 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7503 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7504 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7505 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7506 module->external_symbols = TRUE;
7507 module->emit_dwarf = emit_dwarf;
7508 module->static_link = static_link;
7509 module->llvm_only = llvm_only;
7510 /* The first few entries are reserved */
7511 module->max_got_offset = 16;
7512 module->context = LLVMContextCreate ();
7515 /* clang ignores our debug info because it has an invalid version */
7516 module->emit_dwarf = FALSE;
7518 add_intrinsics (module->lmodule);
7523 * We couldn't compute the type of the LLVM global representing the got because
7524 * its size is only known after all the methods have been emitted. So create
7525 * a dummy variable, and replace all uses it with the real got variable when
7526 * its size is known in mono_llvm_emit_aot_module ().
7529 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7531 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7532 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7535 /* Add initialization array */
7537 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7539 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7540 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7544 emit_init_icall_wrappers (module);
7546 emit_llvm_code_start (module);
7548 /* Add a dummy personality function */
7549 if (!use_debug_personality) {
7550 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7551 LLVMSetLinkage (personality, LLVMExternalLinkage);
7552 mark_as_used (module, personality);
7555 /* Add a reference to the c++ exception we throw/catch */
7557 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7558 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7559 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7560 mono_llvm_set_is_constant (module->sentinel_exception);
7563 module->llvm_types = g_hash_table_new (NULL, NULL);
7564 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7565 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7566 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7567 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7568 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7569 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7570 module->method_to_callers = g_hash_table_new (NULL, NULL);
7574 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7577 LLVMValueRef res, *vals;
7579 vals = g_new0 (LLVMValueRef, nvalues);
7580 for (i = 0; i < nvalues; ++i)
7581 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7582 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7588 * mono_llvm_emit_aot_file_info:
7590 * Emit the MonoAotFileInfo structure.
7591 * Same as emit_aot_file_info () in aot-compiler.c.
7594 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7596 MonoLLVMModule *module = &aot_module;
7598 /* Save these for later */
7599 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7600 module->has_jitted_code = has_jitted_code;
7604 * mono_llvm_emit_aot_data:
7606 * Emit the binary data DATA pointed to by symbol SYMBOL.
7609 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7611 MonoLLVMModule *module = &aot_module;
7615 type = LLVMArrayType (LLVMInt8Type (), data_len);
7616 d = LLVMAddGlobal (module->lmodule, type, symbol);
7617 LLVMSetVisibility (d, LLVMHiddenVisibility);
7618 LLVMSetLinkage (d, LLVMInternalLinkage);
7619 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7620 mono_llvm_set_is_constant (d);
7623 /* Add a reference to a global defined in JITted code */
7625 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7630 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7631 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7637 emit_aot_file_info (MonoLLVMModule *module)
7639 LLVMTypeRef file_info_type;
7640 LLVMTypeRef *eltypes, eltype;
7641 LLVMValueRef info_var;
7642 LLVMValueRef *fields;
7643 int i, nfields, tindex;
7644 MonoAotFileInfo *info;
7645 LLVMModuleRef lmodule = module->lmodule;
7647 info = &module->aot_info;
7649 /* Create an LLVM type to represent MonoAotFileInfo */
7650 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7651 eltypes = g_new (LLVMTypeRef, nfields);
7653 eltypes [tindex ++] = LLVMInt32Type ();
7654 eltypes [tindex ++] = LLVMInt32Type ();
7656 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7657 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7659 for (i = 0; i < 15; ++i)
7660 eltypes [tindex ++] = LLVMInt32Type ();
7662 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7663 for (i = 0; i < 4; ++i)
7664 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7665 g_assert (tindex == nfields);
7666 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7667 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7669 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7670 if (module->static_link) {
7671 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7672 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7674 fields = g_new (LLVMValueRef, nfields);
7676 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7677 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7681 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7682 * for symbols defined in the .s file emitted by the aot compiler.
7684 eltype = eltypes [tindex];
7685 if (module->llvm_only)
7686 fields [tindex ++] = LLVMConstNull (eltype);
7688 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7689 fields [tindex ++] = module->got_var;
7690 /* llc defines this directly */
7691 if (!module->llvm_only) {
7692 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7693 fields [tindex ++] = LLVMConstNull (eltype);
7694 fields [tindex ++] = LLVMConstNull (eltype);
7696 fields [tindex ++] = LLVMConstNull (eltype);
7697 fields [tindex ++] = module->get_method;
7698 fields [tindex ++] = module->get_unbox_tramp;
7700 if (module->has_jitted_code) {
7701 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7702 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7704 fields [tindex ++] = LLVMConstNull (eltype);
7705 fields [tindex ++] = LLVMConstNull (eltype);
7707 if (!module->llvm_only)
7708 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7710 fields [tindex ++] = LLVMConstNull (eltype);
7711 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7712 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7713 fields [tindex ++] = LLVMConstNull (eltype);
7715 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7716 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7717 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7718 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7719 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7720 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7721 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7722 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7723 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7724 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7726 /* Not needed (mem_end) */
7727 fields [tindex ++] = LLVMConstNull (eltype);
7728 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7729 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7730 if (info->trampoline_size [0]) {
7731 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7732 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7733 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7734 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7736 fields [tindex ++] = LLVMConstNull (eltype);
7737 fields [tindex ++] = LLVMConstNull (eltype);
7738 fields [tindex ++] = LLVMConstNull (eltype);
7739 fields [tindex ++] = LLVMConstNull (eltype);
7741 if (module->static_link && !module->llvm_only)
7742 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7744 fields [tindex ++] = LLVMConstNull (eltype);
7745 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7746 if (!module->llvm_only) {
7747 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7748 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7749 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7750 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7751 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7752 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7754 fields [tindex ++] = LLVMConstNull (eltype);
7755 fields [tindex ++] = LLVMConstNull (eltype);
7756 fields [tindex ++] = LLVMConstNull (eltype);
7757 fields [tindex ++] = LLVMConstNull (eltype);
7758 fields [tindex ++] = LLVMConstNull (eltype);
7759 fields [tindex ++] = LLVMConstNull (eltype);
7762 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7763 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7766 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7767 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7768 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7769 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7770 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7771 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7772 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7773 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7774 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7775 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7776 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7777 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7778 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7779 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7780 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7782 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7783 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7784 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7785 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7786 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7787 g_assert (tindex == nfields);
7789 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7791 if (module->static_link) {
7795 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7796 /* Get rid of characters which cannot occur in symbols */
7798 for (p = s; *p; ++p) {
7799 if (!(isalnum (*p) || *p == '_'))
7802 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7804 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7805 LLVMSetLinkage (var, LLVMExternalLinkage);
7810 * Emit the aot module into the LLVM bitcode file FILENAME.
7813 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7815 LLVMTypeRef got_type, inited_type;
7816 LLVMValueRef real_got, real_inited;
7817 MonoLLVMModule *module = &aot_module;
7819 emit_llvm_code_end (module);
7822 * Create the real got variable and replace all uses of the dummy variable with
7825 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7826 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7827 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7828 if (module->external_symbols) {
7829 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7830 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7832 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7834 mono_llvm_replace_uses_of (module->got_var, real_got);
7836 mark_as_used (&aot_module, real_got);
7838 /* Delete the dummy got so it doesn't become a global */
7839 LLVMDeleteGlobal (module->got_var);
7840 module->got_var = real_got;
7843 * Same for the init_var
7845 if (module->llvm_only) {
7846 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7847 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7848 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7849 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7850 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7851 LLVMDeleteGlobal (module->inited_var);
7854 if (module->llvm_only) {
7855 emit_get_method (&aot_module);
7856 emit_get_unbox_tramp (&aot_module);
7859 emit_llvm_used (&aot_module);
7860 emit_dbg_info (&aot_module, filename, cu_name);
7861 emit_aot_file_info (&aot_module);
7864 * Replace GOT entries for directly callable methods with the methods themselves.
7865 * It would be easier to implement this by predefining all methods before compiling
7866 * their bodies, but that couldn't handle the case when a method fails to compile
7869 if (module->llvm_only) {
7870 GHashTableIter iter;
7872 GSList *callers, *l;
7874 g_hash_table_iter_init (&iter, module->method_to_callers);
7875 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7876 LLVMValueRef lmethod;
7878 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
7880 for (l = callers; l; l = l->next) {
7881 LLVMValueRef caller = (LLVMValueRef)l->data;
7883 mono_llvm_replace_uses_of (caller, lmethod);
7889 /* Replace PLT entries for directly callable methods with the methods themselves */
7891 GHashTableIter iter;
7893 LLVMValueRef callee;
7895 g_hash_table_iter_init (&iter, module->plt_entries_ji);
7896 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
7897 if (mono_aot_is_direct_callable (ji)) {
7898 LLVMValueRef lmethod;
7900 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
7901 /* The types might not match because the caller might pass an rgctx */
7902 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
7903 mono_llvm_replace_uses_of (callee, lmethod);
7904 mono_aot_mark_unused_llvm_plt_entry (ji);
7914 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
7915 g_assert_not_reached ();
7920 LLVMWriteBitcodeToFile (module->lmodule, filename);
7925 md_string (const char *s)
7927 return LLVMMDString (s, strlen (s));
7930 /* Debugging support */
7933 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
7935 LLVMModuleRef lmodule = module->lmodule;
7936 LLVMValueRef args [16], cu_args [16], cu, ver;
7938 char *build_info, *s, *dir;
7941 * This can only be enabled when LLVM code is emitted into a separate object
7942 * file, since the AOT compiler also emits dwarf info,
7943 * and the abbrev indexes will not be correct since llvm has added its own
7946 if (!module->emit_dwarf)
7950 * Emit dwarf info in the form of LLVM metadata. There is some
7951 * out-of-date documentation at:
7952 * http://llvm.org/docs/SourceLevelDebugging.html
7953 * but most of this was gathered from the llvm and
7958 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
7959 /* CU name/compilation dir */
7960 dir = g_path_get_dirname (filename);
7961 args [0] = LLVMMDString (cu_name, strlen (cu_name));
7962 args [1] = LLVMMDString (dir, strlen (dir));
7963 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
7966 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
7968 build_info = mono_get_runtime_build_info ();
7969 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
7970 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
7971 g_free (build_info);
7973 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7975 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7976 /* Runtime version */
7977 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7979 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7980 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7982 if (module->subprogram_mds) {
7986 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
7987 for (i = 0; i < module->subprogram_mds->len; ++i)
7988 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
7989 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
7991 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7994 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7995 /* Imported modules */
7996 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7998 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7999 /* DebugEmissionKind = FullDebug */
8000 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8001 cu = LLVMMDNode (cu_args, n_cuargs);
8002 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8004 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8005 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8006 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8007 ver = LLVMMDNode (args, 3);
8008 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8010 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8011 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8012 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8013 ver = LLVMMDNode (args, 3);
8014 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8018 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8020 MonoLLVMModule *module = ctx->module;
8021 MonoDebugMethodInfo *minfo = ctx->minfo;
8022 char *source_file, *dir, *filename;
8023 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8024 MonoSymSeqPoint *sym_seq_points;
8030 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8032 source_file = g_strdup ("<unknown>");
8033 dir = g_path_get_dirname (source_file);
8034 filename = g_path_get_basename (source_file);
8036 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8037 args [0] = md_string (filename);
8038 args [1] = md_string (dir);
8039 ctx_args [1] = LLVMMDNode (args, 2);
8040 ctx_md = LLVMMDNode (ctx_args, 2);
8042 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8043 type_args [1] = NULL;
8044 type_args [2] = NULL;
8045 type_args [3] = LLVMMDString ("", 0);
8046 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8047 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8048 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8049 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8050 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8051 type_args [9] = NULL;
8052 type_args [10] = NULL;
8053 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8054 type_args [12] = NULL;
8055 type_args [13] = NULL;
8056 type_args [14] = NULL;
8057 type_md = LLVMMDNode (type_args, 14);
8059 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8060 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8061 /* Source directory + file pair */
8062 args [0] = md_string (filename);
8063 args [1] = md_string (dir);
8064 md_args [1] = LLVMMDNode (args ,2);
8065 md_args [2] = ctx_md;
8066 md_args [3] = md_string (cfg->method->name);
8067 md_args [4] = md_string (name);
8068 md_args [5] = md_string (name);
8071 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8073 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8075 md_args [7] = type_md;
8077 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8079 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8081 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8082 /* Index into a virtual function */
8083 md_args [11] = NULL;
8084 md_args [12] = NULL;
8086 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8088 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8089 /* Pointer to LLVM function */
8090 md_args [15] = method;
8091 /* Function template parameter */
8092 md_args [16] = NULL;
8093 /* Function declaration descriptor */
8094 md_args [17] = NULL;
8095 /* List of function variables */
8096 md_args [18] = LLVMMDNode (args, 0);
8098 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8099 md = LLVMMDNode (md_args, 20);
8101 if (!module->subprogram_mds)
8102 module->subprogram_mds = g_ptr_array_new ();
8103 g_ptr_array_add (module->subprogram_mds, md);
8107 g_free (source_file);
8108 g_free (sym_seq_points);
8114 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8116 MonoCompile *cfg = ctx->cfg;
8118 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8119 MonoDebugSourceLocation *loc;
8120 LLVMValueRef loc_md, md_args [16];
8123 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8127 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8128 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8129 md_args [nmd_args ++] = ctx->dbg_md;
8130 md_args [nmd_args ++] = NULL;
8131 loc_md = LLVMMDNode (md_args, nmd_args);
8132 LLVMSetCurrentDebugLocation (builder, loc_md);
8133 mono_debug_symfile_free_location (loc);
8139 default_mono_llvm_unhandled_exception (void)
8141 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8142 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8144 mono_unhandled_exception (target);
8145 exit (mono_environment_exitcode_get ());
8150 - Emit LLVM IR from the mono IR using the LLVM C API.
8151 - The original arch specific code remains, so we can fall back to it if we run
8152 into something we can't handle.
8156 A partial list of issues:
8157 - Handling of opcodes which can throw exceptions.
8159 In the mono JIT, these are implemented using code like this:
8166 push throw_pos - method
8167 call <exception trampoline>
8169 The problematic part is push throw_pos - method, which cannot be represented
8170 in the LLVM IR, since it does not support label values.
8171 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8172 be implemented in JIT mode ?
8173 -> a possible but slower implementation would use the normal exception
8174 throwing code but it would need to control the placement of the throw code
8175 (it needs to be exactly after the compare+branch).
8176 -> perhaps add a PC offset intrinsics ?
8178 - efficient implementation of .ovf opcodes.
8180 These are currently implemented as:
8181 <ins which sets the condition codes>
8184 Some overflow opcodes are now supported by LLVM SVN.
8186 - exception handling, unwinding.
8187 - SSA is disabled for methods with exception handlers
8188 - How to obtain unwind info for LLVM compiled methods ?
8189 -> this is now solved by converting the unwind info generated by LLVM
8191 - LLVM uses the c++ exception handling framework, while we use our home grown
8192 code, and couldn't use the c++ one:
8193 - its not supported under VC++, other exotic platforms.
8194 - it might be impossible to support filter clauses with it.
8198 The trampolines need a predictable call sequence, since they need to disasm
8199 the calling code to obtain register numbers / offsets.
8201 LLVM currently generates this code in non-JIT mode:
8202 mov -0x98(%rax),%eax
8204 Here, the vtable pointer is lost.
8205 -> solution: use one vtable trampoline per class.
8207 - passing/receiving the IMT pointer/RGCTX.
8208 -> solution: pass them as normal arguments ?
8212 LLVM does not allow the specification of argument registers etc. This means
8213 that all calls are made according to the platform ABI.
8215 - passing/receiving vtypes.
8217 Vtypes passed/received in registers are handled by the front end by using
8218 a signature with scalar arguments, and loading the parts of the vtype into those
8221 Vtypes passed on the stack are handled using the 'byval' attribute.
8225 Supported though alloca, we need to emit the load/store code.
8229 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8230 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8231 This is made easier because the IR is already in SSA form.
8232 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8233 types are frequently used incorrectly.
8238 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8239 it with the file containing the methods emitted by the JIT and the AOT data
8243 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8244 * - each bblock should end with a branch
8245 * - setting the return value, making cfg->ret non-volatile
8246 * - avoid some transformations in the JIT which make it harder for us to generate
8248 * - use pointer types to help optimizations.