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 module->get_unbox_tramp = func;
2413 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2415 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2416 for (i = 0; i < module->max_method_idx + 1; ++i) {
2417 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2421 name = g_strdup_printf ("BB_%d", i);
2422 bb = LLVMAppendBasicBlock (func, name);
2426 builder = LLVMCreateBuilder ();
2427 LLVMPositionBuilderAtEnd (builder, bb);
2429 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2432 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2433 builder = LLVMCreateBuilder ();
2434 LLVMPositionBuilderAtEnd (builder, fail_bb);
2435 LLVMBuildRet (builder, LLVMConstNull (rtype));
2437 builder = LLVMCreateBuilder ();
2438 LLVMPositionBuilderAtEnd (builder, entry_bb);
2440 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2441 for (i = 0; i < module->max_method_idx + 1; ++i) {
2442 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2446 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2449 mark_as_used (module, func);
2452 /* Add a function to mark the beginning of LLVM code */
2454 emit_llvm_code_start (MonoLLVMModule *module)
2456 LLVMModuleRef lmodule = module->lmodule;
2458 LLVMBasicBlockRef entry_bb;
2459 LLVMBuilderRef builder;
2461 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2462 LLVMSetLinkage (func, LLVMInternalLinkage);
2463 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2464 module->code_start = func;
2465 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2466 builder = LLVMCreateBuilder ();
2467 LLVMPositionBuilderAtEnd (builder, entry_bb);
2468 LLVMBuildRetVoid (builder);
2472 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2474 LLVMModuleRef lmodule = module->lmodule;
2475 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2476 LLVMBasicBlockRef entry_bb;
2477 LLVMBuilderRef builder;
2484 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2485 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2490 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2491 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2494 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2495 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2498 g_assert_not_reached ();
2500 LLVMSetLinkage (func, LLVMInternalLinkage);
2501 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2502 mono_llvm_set_preserveall_cc (func);
2503 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2504 builder = LLVMCreateBuilder ();
2505 LLVMPositionBuilderAtEnd (builder, entry_bb);
2508 ji = g_new0 (MonoJumpInfo, 1);
2509 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2510 ji = mono_aot_patch_info_dup (ji);
2511 got_offset = mono_aot_get_got_offset (ji);
2512 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2513 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2514 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2515 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2516 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2517 args [1] = LLVMGetParam (func, 0);
2519 args [2] = LLVMGetParam (func, 1);
2521 ji = g_new0 (MonoJumpInfo, 1);
2522 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2523 ji->data.name = icall_name;
2524 ji = mono_aot_patch_info_dup (ji);
2525 got_offset = mono_aot_get_got_offset (ji);
2526 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2527 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2528 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2529 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2530 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2531 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2532 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2534 // Set the inited flag
2535 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2536 indexes [1] = LLVMGetParam (func, 0);
2537 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2539 LLVMBuildRetVoid (builder);
2541 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2546 * Emit wrappers around the C icalls used to initialize llvm methods, to
2547 * make the calling code smaller and to enable usage of the llvm
2548 * PreserveAll calling convention.
2551 emit_init_icall_wrappers (MonoLLVMModule *module)
2553 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2554 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2555 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2556 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2560 emit_llvm_code_end (MonoLLVMModule *module)
2562 LLVMModuleRef lmodule = module->lmodule;
2564 LLVMBasicBlockRef entry_bb;
2565 LLVMBuilderRef builder;
2567 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2568 LLVMSetLinkage (func, LLVMInternalLinkage);
2569 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2570 module->code_end = func;
2571 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2572 builder = LLVMCreateBuilder ();
2573 LLVMPositionBuilderAtEnd (builder, entry_bb);
2574 LLVMBuildRetVoid (builder);
2578 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2580 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2583 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2584 need_div_check = TRUE;
2586 if (!need_div_check)
2589 switch (ins->opcode) {
2602 case OP_IDIV_UN_IMM:
2603 case OP_LDIV_UN_IMM:
2604 case OP_IREM_UN_IMM:
2605 case OP_LREM_UN_IMM: {
2607 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2608 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2610 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2611 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2612 CHECK_FAILURE (ctx);
2613 builder = ctx->builder;
2615 /* b == -1 && a == 0x80000000 */
2617 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2618 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2619 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2621 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2622 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2623 CHECK_FAILURE (ctx);
2624 builder = ctx->builder;
2639 * Emit code to initialize the GOT slots used by the method.
2642 emit_init_method (EmitContext *ctx)
2644 LLVMValueRef indexes [16], args [16], callee;
2645 LLVMValueRef inited_var, cmp, call;
2646 LLVMBasicBlockRef inited_bb, notinited_bb;
2647 LLVMBuilderRef builder = ctx->builder;
2648 MonoCompile *cfg = ctx->cfg;
2650 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2652 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2653 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2654 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2656 args [0] = inited_var;
2657 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2658 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2660 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2662 inited_bb = ctx->inited_bb;
2663 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2665 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2667 builder = ctx->builder = create_builder (ctx);
2668 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2671 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2672 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2673 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2674 callee = ctx->module->init_method_gshared_mrgctx;
2675 call = LLVMBuildCall (builder, callee, args, 2, "");
2676 } else if (ctx->rgctx_arg) {
2677 /* A vtable is passed as the rgctx argument */
2678 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2679 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2680 callee = ctx->module->init_method_gshared_vtable;
2681 call = LLVMBuildCall (builder, callee, args, 2, "");
2682 } else if (cfg->gshared) {
2683 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2684 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2685 callee = ctx->module->init_method_gshared_this;
2686 call = LLVMBuildCall (builder, callee, args, 2, "");
2688 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2689 callee = ctx->module->init_method;
2690 call = LLVMBuildCall (builder, callee, args, 1, "");
2694 * This enables llvm to keep arguments in their original registers/
2695 * scratch registers, since the call will not clobber them.
2697 mono_llvm_set_call_preserveall_cc (call);
2699 LLVMBuildBr (builder, inited_bb);
2700 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2702 builder = ctx->builder = create_builder (ctx);
2703 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2707 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2710 * Emit unbox trampoline using a tail call
2712 LLVMValueRef tramp, call, *args;
2713 LLVMBuilderRef builder;
2714 LLVMBasicBlockRef lbb;
2718 tramp_name = g_strdup_printf ("ut_%s", method_name);
2719 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2720 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2721 LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
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 (), "");
3224 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3227 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3229 pindex = ainfo->pindex;
3231 regpair = (guint32)(gssize)(l->data);
3232 reg = regpair & 0xffffff;
3233 args [pindex] = values [reg];
3234 switch (ainfo->storage) {
3235 case LLVMArgVtypeInReg:
3236 case LLVMArgAsFpArgs: {
3240 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3241 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3242 pindex += ainfo->ndummy_fpargs;
3244 g_assert (addresses [reg]);
3245 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3249 // FIXME: Get rid of the VMOVE
3252 case LLVMArgVtypeByVal:
3253 g_assert (addresses [reg]);
3254 args [pindex] = addresses [reg];
3256 case LLVMArgVtypeByRef:
3257 case LLVMArgScalarByRef: {
3258 g_assert (addresses [reg]);
3259 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3262 case LLVMArgAsIArgs:
3263 g_assert (addresses [reg]);
3264 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3266 case LLVMArgVtypeAsScalar:
3267 g_assert_not_reached ();
3269 case LLVMArgGsharedvtFixed:
3270 case LLVMArgGsharedvtFixedVtype:
3271 g_assert (addresses [reg]);
3272 args [pindex] = addresses [reg];
3274 case LLVMArgGsharedvtVariable:
3275 g_assert (addresses [reg]);
3276 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3279 g_assert (args [pindex]);
3280 if (i == 0 && sig->hasthis)
3281 args [pindex] = convert (ctx, args [pindex], ThisType ());
3283 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3286 g_assert (pindex <= nargs);
3291 // FIXME: Align call sites
3297 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3300 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3302 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3303 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3305 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3306 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3307 if (!sig->pinvoke && !cfg->llvm_only)
3308 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3310 mono_llvm_set_call_preserveall_cc (lcall);
3312 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3313 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3314 if (!ctx->llvm_only && call->rgctx_arg_reg)
3315 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3316 if (call->imt_arg_reg)
3317 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3319 /* Add byval attributes if needed */
3320 for (i = 0; i < sig->param_count; ++i) {
3321 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3323 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3324 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3328 * Convert the result
3330 switch (cinfo->ret.storage) {
3331 case LLVMArgVtypeInReg: {
3332 LLVMValueRef regs [2];
3334 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3338 if (!addresses [ins->dreg])
3339 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3341 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3342 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3343 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3344 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3347 case LLVMArgVtypeByVal:
3348 if (!addresses [call->inst.dreg])
3349 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3350 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3352 case LLVMArgFpStruct:
3353 if (!addresses [call->inst.dreg])
3354 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3355 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3357 case LLVMArgVtypeAsScalar:
3358 if (!addresses [call->inst.dreg])
3359 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3360 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3362 case LLVMArgVtypeRetAddr:
3363 case LLVMArgVtypeByRef:
3365 case LLVMArgScalarRetAddr:
3366 /* Normal scalar returned using a vtype return argument */
3367 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3369 case LLVMArgGsharedvtVariable:
3371 case LLVMArgGsharedvtFixed:
3372 case LLVMArgGsharedvtFixedVtype:
3373 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3376 if (sig->ret->type != MONO_TYPE_VOID)
3377 /* If the method returns an unsigned value, need to zext it */
3378 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));
3382 *builder_ref = ctx->builder;
3390 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3392 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3393 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3395 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3398 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3400 if (ctx->cfg->compile_aot) {
3401 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3403 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3404 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3405 mono_memory_barrier ();
3408 ctx->module->rethrow = callee;
3410 ctx->module->throw_icall = callee;
3414 LLVMValueRef args [2];
3416 args [0] = convert (ctx, exc, exc_type);
3417 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3419 LLVMBuildUnreachable (ctx->builder);
3421 ctx->builder = create_builder (ctx);
3425 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3427 MonoMethodSignature *throw_sig;
3428 LLVMValueRef callee, arg;
3429 const char *icall_name;
3431 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3432 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3435 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3436 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3437 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3438 if (ctx->cfg->compile_aot) {
3439 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3441 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3445 * LLVM doesn't push the exception argument, so we need a different
3448 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3450 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3454 mono_memory_barrier ();
3456 ctx->module->rethrow = callee;
3458 ctx->module->throw_icall = callee;
3460 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3461 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3465 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3467 const char *icall_name = "mono_llvm_resume_exception";
3468 LLVMValueRef callee = ctx->module->resume_eh;
3470 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3473 if (ctx->cfg->compile_aot) {
3474 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3476 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3477 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3478 mono_memory_barrier ();
3480 ctx->module->resume_eh = callee;
3484 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3486 LLVMBuildUnreachable (ctx->builder);
3488 ctx->builder = create_builder (ctx);
3492 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3494 const char *icall_name = "mono_llvm_clear_exception";
3496 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3497 LLVMValueRef callee = NULL;
3500 if (ctx->cfg->compile_aot) {
3501 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3503 // FIXME: This is broken.
3504 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3508 g_assert (builder && callee);
3510 return LLVMBuildCall (builder, callee, NULL, 0, "");
3514 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3516 const char *icall_name = "mono_llvm_load_exception";
3518 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3519 LLVMValueRef callee = NULL;
3522 if (ctx->cfg->compile_aot) {
3523 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3525 // FIXME: This is broken.
3526 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3530 g_assert (builder && callee);
3532 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3537 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3539 const char *icall_name = "mono_llvm_match_exception";
3541 ctx->builder = builder;
3543 const int num_args = 3;
3544 LLVMValueRef args [num_args];
3545 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3546 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3547 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3549 LLVMTypeRef match_sig = LLVMFunctionType3 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), FALSE);
3550 LLVMValueRef callee = ctx->module->match_exc;
3553 if (ctx->cfg->compile_aot) {
3554 ctx->builder = builder;
3555 // get_callee expects ctx->builder to be the emitting builder
3556 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3558 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3559 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3560 ctx->module->match_exc = callee;
3561 mono_memory_barrier ();
3565 g_assert (builder && callee);
3567 g_assert (ctx->ex_var);
3569 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3572 // FIXME: This won't work because the code-finding makes this
3574 /*#define MONO_PERSONALITY_DEBUG*/
3576 #ifdef MONO_PERSONALITY_DEBUG
3577 static const gboolean use_debug_personality = TRUE;
3578 static const char *default_personality_name = "mono_debug_personality";
3580 static const gboolean use_debug_personality = FALSE;
3581 static const char *default_personality_name = "__gxx_personality_v0";
3585 default_cpp_lpad_exc_signature (void)
3587 static gboolean inited = FALSE;
3588 static LLVMTypeRef sig;
3591 LLVMTypeRef signature [2];
3592 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3593 signature [1] = LLVMInt32Type ();
3594 sig = LLVMStructType (signature, 2, FALSE);
3602 get_mono_personality (EmitContext *ctx)
3604 LLVMValueRef personality = NULL;
3605 static gint32 mapping_inited = FALSE;
3606 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3608 if (!use_debug_personality) {
3609 if (ctx->cfg->compile_aot) {
3610 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3611 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3612 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3613 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3616 if (ctx->cfg->compile_aot) {
3617 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3619 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3620 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3621 mono_memory_barrier ();
3625 g_assert (personality);
3629 static LLVMBasicBlockRef
3630 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3632 MonoCompile *cfg = ctx->cfg;
3633 LLVMBuilderRef old_builder = ctx->builder;
3634 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3636 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3637 ctx->builder = lpadBuilder;
3639 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3640 g_assert (handler_bb);
3642 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3643 LLVMValueRef personality = get_mono_personality (ctx);
3644 g_assert (personality);
3646 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3647 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3649 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3650 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3651 g_assert (landing_pad);
3653 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3654 LLVMAddClause (landing_pad, cast);
3656 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3657 LLVMBuilderRef resume_builder = create_builder (ctx);
3658 ctx->builder = resume_builder;
3659 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3661 emit_resume_eh (ctx, handler_bb);
3664 ctx->builder = lpadBuilder;
3665 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3667 gboolean finally_only = TRUE;
3669 MonoExceptionClause *group_cursor = group_start;
3671 for (int i = 0; i < group_size; i ++) {
3672 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3673 finally_only = FALSE;
3679 // Handle landing pad inlining
3681 if (!finally_only) {
3682 // So at each level of the exception stack we will match the exception again.
3683 // During that match, we need to compare against the handler types for the current
3684 // protected region. We send the try start and end so that we can only check against
3685 // handlers for this lexical protected region.
3686 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3688 // if returns -1, resume
3689 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3691 // else move to that target bb
3692 for (int i=0; i < group_size; i++) {
3693 MonoExceptionClause *clause = group_start + i;
3694 int clause_index = clause - cfg->header->clauses;
3695 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3696 g_assert (handler_bb);
3697 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3698 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3701 int clause_index = group_start - cfg->header->clauses;
3702 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3703 g_assert (finally_bb);
3705 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3708 ctx->builder = old_builder;
3715 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3717 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3718 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3720 // Make exception available to catch blocks
3721 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3722 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3724 g_assert (ctx->ex_var);
3725 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3727 if (bb->in_scount == 1) {
3728 MonoInst *exvar = bb->in_stack [0];
3729 g_assert (!ctx->values [exvar->dreg]);
3730 g_assert (ctx->ex_var);
3731 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3732 emit_volatile_store (ctx, exvar->dreg);
3735 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3738 LLVMBuilderRef handler_builder = create_builder (ctx);
3739 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3740 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3742 // Make the handler code end with a jump to cbb
3743 LLVMBuildBr (handler_builder, cbb);
3747 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3749 MonoCompile *cfg = ctx->cfg;
3750 LLVMValueRef *values = ctx->values;
3751 LLVMModuleRef lmodule = ctx->lmodule;
3752 BBInfo *bblocks = ctx->bblocks;
3754 LLVMValueRef personality;
3755 LLVMValueRef landing_pad;
3756 LLVMBasicBlockRef target_bb;
3758 static gint32 mapping_inited;
3759 static int ti_generator;
3762 LLVMValueRef type_info;
3766 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3768 if (cfg->compile_aot) {
3769 /* Use a dummy personality function */
3770 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3771 g_assert (personality);
3773 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3774 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3775 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3778 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3780 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3783 * Create the type info
3785 sprintf (ti_name, "type_info_%d", ti_generator);
3788 if (cfg->compile_aot) {
3789 /* decode_eh_frame () in aot-runtime.c will decode this */
3790 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3791 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3794 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3796 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3799 * After the cfg mempool is freed, the type info will point to stale memory,
3800 * but this is not a problem, since we decode it once in exception_cb during
3803 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3804 *(gint32*)ti = clause_index;
3806 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3808 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3812 LLVMTypeRef members [2], ret_type;
3814 members [0] = i8ptr;
3815 members [1] = LLVMInt32Type ();
3816 ret_type = LLVMStructType (members, 2, FALSE);
3818 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3819 LLVMAddClause (landing_pad, type_info);
3821 /* Store the exception into the exvar */
3823 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3827 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3828 * code expects control to be transferred to this landing pad even in the
3829 * presence of nested clauses. The landing pad needs to branch to the landing
3830 * pads belonging to nested clauses based on the selector value returned by
3831 * the landing pad instruction, which is passed to the landing pad in a
3832 * register by the EH code.
3834 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3835 g_assert (target_bb);
3838 * Branch to the correct landing pad
3840 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3841 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3843 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3844 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3845 MonoBasicBlock *handler_bb;
3847 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3848 g_assert (handler_bb);
3850 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3851 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3854 /* Start a new bblock which CALL_HANDLER can branch to */
3855 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3857 ctx->builder = builder = create_builder (ctx);
3858 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3860 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3862 /* Store the exception into the IL level exvar */
3863 if (bb->in_scount == 1) {
3864 g_assert (bb->in_scount == 1);
3865 exvar = bb->in_stack [0];
3867 // FIXME: This is shared with filter clauses ?
3868 g_assert (!values [exvar->dreg]);
3870 g_assert (ctx->ex_var);
3871 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3872 emit_volatile_store (ctx, exvar->dreg);
3878 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3880 MonoCompile *cfg = ctx->cfg;
3881 MonoMethodSignature *sig = ctx->sig;
3882 LLVMValueRef method = ctx->lmethod;
3883 LLVMValueRef *values = ctx->values;
3884 LLVMValueRef *addresses = ctx->addresses;
3885 LLVMCallInfo *linfo = ctx->linfo;
3886 LLVMModuleRef lmodule = ctx->lmodule;
3887 BBInfo *bblocks = ctx->bblocks;
3889 LLVMBasicBlockRef cbb;
3890 LLVMBuilderRef builder, starting_builder;
3891 gboolean has_terminator;
3893 LLVMValueRef lhs, rhs;
3896 cbb = get_end_bb (ctx, bb);
3898 builder = create_builder (ctx);
3899 ctx->builder = builder;
3900 LLVMPositionBuilderAtEnd (builder, cbb);
3902 CHECK_FAILURE (ctx);
3904 if (bb->flags & BB_EXCEPTION_HANDLER) {
3905 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3906 LLVM_FAILURE (ctx, "handler without invokes");
3910 emit_llvmonly_handler_start (ctx, bb, cbb);
3912 emit_handler_start (ctx, bb, builder);
3913 CHECK_FAILURE (ctx);
3914 builder = ctx->builder;
3917 has_terminator = FALSE;
3918 starting_builder = builder;
3919 for (ins = bb->code; ins; ins = ins->next) {
3920 const char *spec = LLVM_INS_INFO (ins->opcode);
3922 char dname_buf [128];
3924 emit_dbg_loc (ctx, builder, ins->cil_code);
3927 if (nins > 3000 && builder == starting_builder) {
3928 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
3929 LLVM_FAILURE (ctx, "basic block too long");
3933 /* There could be instructions after a terminator, skip them */
3936 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
3937 sprintf (dname_buf, "t%d", ins->dreg);
3941 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
3942 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
3944 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
3945 lhs = emit_volatile_load (ctx, ins->sreg1);
3947 /* It is ok for SETRET to have an uninitialized argument */
3948 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
3949 LLVM_FAILURE (ctx, "sreg1");
3950 lhs = values [ins->sreg1];
3956 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
3957 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
3958 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
3959 rhs = emit_volatile_load (ctx, ins->sreg2);
3961 if (!values [ins->sreg2])
3962 LLVM_FAILURE (ctx, "sreg2");
3963 rhs = values [ins->sreg2];
3969 //mono_print_ins (ins);
3970 switch (ins->opcode) {
3973 case OP_LIVERANGE_START:
3974 case OP_LIVERANGE_END:
3977 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
3980 #if SIZEOF_VOID_P == 4
3981 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3983 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
3987 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
3991 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
3993 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
3995 case OP_DUMMY_ICONST:
3996 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3998 case OP_DUMMY_I8CONST:
3999 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4001 case OP_DUMMY_R8CONST:
4002 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4005 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4006 LLVMBuildBr (builder, target_bb);
4007 has_terminator = TRUE;
4014 LLVMBasicBlockRef new_bb;
4015 LLVMBuilderRef new_builder;
4017 // The default branch is already handled
4018 // FIXME: Handle it here
4020 /* Start new bblock */
4021 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4022 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4024 lhs = convert (ctx, lhs, LLVMInt32Type ());
4025 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4026 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4027 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4029 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4032 new_builder = create_builder (ctx);
4033 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4034 LLVMBuildUnreachable (new_builder);
4036 has_terminator = TRUE;
4037 g_assert (!ins->next);
4043 switch (linfo->ret.storage) {
4044 case LLVMArgVtypeInReg: {
4045 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4046 LLVMValueRef val, addr, retval;
4049 retval = LLVMGetUndef (ret_type);
4051 if (!addresses [ins->sreg1]) {
4053 * The return type is an LLVM vector type, have to convert between it and the
4054 * real return type which is a struct type.
4056 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4057 /* Convert to 2xi64 first */
4058 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4060 for (i = 0; i < 2; ++i) {
4061 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4062 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4064 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4068 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4069 for (i = 0; i < 2; ++i) {
4070 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4071 LLVMValueRef indexes [2], part_addr;
4073 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4074 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4075 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4077 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4079 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4083 LLVMBuildRet (builder, retval);
4086 case LLVMArgVtypeAsScalar: {
4087 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4088 LLVMValueRef retval;
4091 size = get_vtype_size (sig->ret);
4093 g_assert (addresses [ins->sreg1]);
4095 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4096 LLVMBuildRet (builder, retval);
4099 case LLVMArgVtypeByVal: {
4100 LLVMValueRef retval;
4102 g_assert (addresses [ins->sreg1]);
4103 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4104 LLVMBuildRet (builder, retval);
4107 case LLVMArgVtypeByRef: {
4108 LLVMBuildRetVoid (builder);
4111 case LLVMArgGsharedvtFixed: {
4112 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4113 /* The return value is in lhs, need to store to the vret argument */
4114 /* sreg1 might not be set */
4116 g_assert (cfg->vret_addr);
4117 g_assert (values [cfg->vret_addr->dreg]);
4118 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4120 LLVMBuildRetVoid (builder);
4123 case LLVMArgGsharedvtFixedVtype: {
4125 LLVMBuildRetVoid (builder);
4128 case LLVMArgGsharedvtVariable: {
4130 LLVMBuildRetVoid (builder);
4133 case LLVMArgVtypeRetAddr: {
4134 LLVMBuildRetVoid (builder);
4137 case LLVMArgScalarRetAddr: {
4138 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4139 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4141 /* sreg1 might not be set */
4143 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4144 LLVMBuildRetVoid (builder);
4147 case LLVMArgFpStruct: {
4148 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4149 LLVMValueRef retval;
4151 g_assert (addresses [ins->sreg1]);
4152 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4153 LLVMBuildRet (builder, retval);
4157 case LLVMArgNormal: {
4158 if (!lhs || ctx->is_dead [ins->sreg1]) {
4160 * The method did not set its return value, probably because it
4161 * ends with a throw.
4164 LLVMBuildRetVoid (builder);
4166 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4168 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4170 has_terminator = TRUE;
4174 g_assert_not_reached ();
4183 case OP_ICOMPARE_IMM:
4184 case OP_LCOMPARE_IMM:
4185 case OP_COMPARE_IMM: {
4187 LLVMValueRef cmp, args [16];
4188 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4190 if (ins->next->opcode == OP_NOP)
4193 if (ins->next->opcode == OP_BR)
4194 /* The comparison result is not needed */
4197 rel = mono_opcode_to_cond (ins->next->opcode);
4199 if (ins->opcode == OP_ICOMPARE_IMM) {
4200 lhs = convert (ctx, lhs, LLVMInt32Type ());
4201 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4203 if (ins->opcode == OP_LCOMPARE_IMM) {
4204 lhs = convert (ctx, lhs, LLVMInt64Type ());
4205 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4207 if (ins->opcode == OP_LCOMPARE) {
4208 lhs = convert (ctx, lhs, LLVMInt64Type ());
4209 rhs = convert (ctx, rhs, LLVMInt64Type ());
4211 if (ins->opcode == OP_ICOMPARE) {
4212 lhs = convert (ctx, lhs, LLVMInt32Type ());
4213 rhs = convert (ctx, rhs, LLVMInt32Type ());
4217 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4218 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4219 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4220 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4223 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4224 if (ins->opcode == OP_FCOMPARE) {
4225 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4226 } else if (ins->opcode == OP_RCOMPARE) {
4227 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4228 } else if (ins->opcode == OP_COMPARE_IMM) {
4229 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4230 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4232 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4233 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4234 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4235 /* The immediate is encoded in two fields */
4236 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4237 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4239 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4242 else if (ins->opcode == OP_COMPARE) {
4243 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4244 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4246 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4248 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4252 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4253 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4256 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4257 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4259 * If the target bb contains PHI instructions, LLVM requires
4260 * two PHI entries for this bblock, while we only generate one.
4261 * So convert this to an unconditional bblock. (bxc #171).
4263 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4265 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4267 has_terminator = TRUE;
4268 } else if (MONO_IS_SETCC (ins->next)) {
4269 sprintf (dname_buf, "t%d", ins->next->dreg);
4271 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4273 /* Add stores for volatile variables */
4274 emit_volatile_store (ctx, ins->next->dreg);
4275 } else if (MONO_IS_COND_EXC (ins->next)) {
4276 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4277 CHECK_FAILURE (ctx);
4278 builder = ctx->builder;
4280 LLVM_FAILURE (ctx, "next");
4294 rel = mono_opcode_to_cond (ins->opcode);
4296 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4297 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4308 rel = mono_opcode_to_cond (ins->opcode);
4310 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4311 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4319 gboolean empty = TRUE;
4321 /* Check that all input bblocks really branch to us */
4322 for (i = 0; i < bb->in_count; ++i) {
4323 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4324 ins->inst_phi_args [i + 1] = -1;
4330 /* LLVM doesn't like phi instructions with zero operands */
4331 ctx->is_dead [ins->dreg] = TRUE;
4335 /* Created earlier, insert it now */
4336 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4338 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4339 int sreg1 = ins->inst_phi_args [i + 1];
4343 * Count the number of times the incoming bblock branches to us,
4344 * since llvm requires a separate entry for each.
4346 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4347 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4350 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4351 if (switch_ins->inst_many_bb [j] == bb)
4358 /* Remember for later */
4359 for (j = 0; j < count; ++j) {
4360 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4363 node->in_bb = bb->in_bb [i];
4365 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);
4375 values [ins->dreg] = lhs;
4379 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4382 values [ins->dreg] = lhs;
4384 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4386 * This is added by the spilling pass in case of the JIT,
4387 * but we have to do it ourselves.
4389 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4393 case OP_MOVE_F_TO_I4: {
4394 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4397 case OP_MOVE_I4_TO_F: {
4398 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4401 case OP_MOVE_F_TO_I8: {
4402 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4405 case OP_MOVE_I8_TO_F: {
4406 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4439 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4440 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4442 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4443 CHECK_FAILURE (ctx);
4444 builder = ctx->builder;
4446 switch (ins->opcode) {
4449 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4453 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4457 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4461 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4465 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4469 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4473 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4477 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4481 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4485 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4489 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4493 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4497 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4501 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4505 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4508 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4511 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4515 g_assert_not_reached ();
4522 lhs = convert (ctx, lhs, LLVMFloatType ());
4523 rhs = convert (ctx, rhs, LLVMFloatType ());
4524 switch (ins->opcode) {
4526 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4529 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4532 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4535 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4538 g_assert_not_reached ();
4547 case OP_IREM_UN_IMM:
4549 case OP_IDIV_UN_IMM:
4555 case OP_ISHR_UN_IMM:
4565 case OP_LSHR_UN_IMM:
4571 case OP_SHR_UN_IMM: {
4574 if (spec [MONO_INST_SRC1] == 'l') {
4575 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4577 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4580 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4581 CHECK_FAILURE (ctx);
4582 builder = ctx->builder;
4584 #if SIZEOF_VOID_P == 4
4585 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4586 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4589 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4590 lhs = convert (ctx, lhs, IntPtrType ());
4591 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4592 switch (ins->opcode) {
4596 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4600 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4605 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4609 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4611 case OP_IDIV_UN_IMM:
4612 case OP_LDIV_UN_IMM:
4613 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4617 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4619 case OP_IREM_UN_IMM:
4620 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4625 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4629 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4633 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4638 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4643 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4645 case OP_ISHR_UN_IMM:
4646 /* This is used to implement conv.u4, so the lhs could be an i8 */
4647 lhs = convert (ctx, lhs, LLVMInt32Type ());
4648 imm = convert (ctx, imm, LLVMInt32Type ());
4649 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4651 case OP_LSHR_UN_IMM:
4653 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4656 g_assert_not_reached ();
4661 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4664 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4667 lhs = convert (ctx, lhs, LLVMDoubleType ());
4668 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4671 lhs = convert (ctx, lhs, LLVMFloatType ());
4672 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4675 guint32 v = 0xffffffff;
4676 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4680 guint64 v = 0xffffffffffffffffLL;
4681 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4684 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4686 LLVMValueRef v1, v2;
4688 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4689 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4690 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4695 case OP_ICONV_TO_I1:
4696 case OP_ICONV_TO_I2:
4697 case OP_ICONV_TO_I4:
4698 case OP_ICONV_TO_U1:
4699 case OP_ICONV_TO_U2:
4700 case OP_ICONV_TO_U4:
4701 case OP_LCONV_TO_I1:
4702 case OP_LCONV_TO_I2:
4703 case OP_LCONV_TO_U1:
4704 case OP_LCONV_TO_U2:
4705 case OP_LCONV_TO_U4: {
4708 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);
4710 /* Have to do two casts since our vregs have type int */
4711 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4713 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4715 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4718 case OP_ICONV_TO_I8:
4719 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4721 case OP_ICONV_TO_U8:
4722 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4724 case OP_FCONV_TO_I4:
4725 case OP_RCONV_TO_I4:
4726 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4728 case OP_FCONV_TO_I1:
4729 case OP_RCONV_TO_I1:
4730 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4732 case OP_FCONV_TO_U1:
4733 case OP_RCONV_TO_U1:
4734 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4736 case OP_FCONV_TO_I2:
4737 case OP_RCONV_TO_I2:
4738 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4740 case OP_FCONV_TO_U2:
4741 case OP_RCONV_TO_U2:
4742 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4744 case OP_RCONV_TO_U4:
4745 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4747 case OP_FCONV_TO_I8:
4748 case OP_RCONV_TO_I8:
4749 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4752 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4754 case OP_ICONV_TO_R8:
4755 case OP_LCONV_TO_R8:
4756 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4758 case OP_ICONV_TO_R_UN:
4759 case OP_LCONV_TO_R_UN:
4760 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4762 #if SIZEOF_VOID_P == 4
4765 case OP_LCONV_TO_I4:
4766 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4768 case OP_ICONV_TO_R4:
4769 case OP_LCONV_TO_R4:
4770 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4772 values [ins->dreg] = v;
4774 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4776 case OP_FCONV_TO_R4:
4777 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4779 values [ins->dreg] = v;
4781 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4783 case OP_RCONV_TO_R8:
4784 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4786 case OP_RCONV_TO_R4:
4787 values [ins->dreg] = lhs;
4790 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4793 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4796 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4798 case OP_LOCALLOC_IMM: {
4801 guint32 size = ins->inst_imm;
4802 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4804 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4806 if (ins->flags & MONO_INST_INIT) {
4807 LLVMValueRef args [5];
4810 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4811 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4812 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4813 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4814 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4817 values [ins->dreg] = v;
4821 LLVMValueRef v, size;
4823 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), "");
4825 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4827 if (ins->flags & MONO_INST_INIT) {
4828 LLVMValueRef args [5];
4831 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4833 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4834 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4835 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4837 values [ins->dreg] = v;
4841 case OP_LOADI1_MEMBASE:
4842 case OP_LOADU1_MEMBASE:
4843 case OP_LOADI2_MEMBASE:
4844 case OP_LOADU2_MEMBASE:
4845 case OP_LOADI4_MEMBASE:
4846 case OP_LOADU4_MEMBASE:
4847 case OP_LOADI8_MEMBASE:
4848 case OP_LOADR4_MEMBASE:
4849 case OP_LOADR8_MEMBASE:
4850 case OP_LOAD_MEMBASE:
4858 LLVMValueRef base, index, addr;
4860 gboolean sext = FALSE, zext = FALSE;
4861 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4863 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4868 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)) {
4869 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4874 if (ins->inst_offset == 0) {
4876 } else if (ins->inst_offset % size != 0) {
4877 /* Unaligned load */
4878 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4879 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4881 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4882 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4886 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4888 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4890 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4892 * These will signal LLVM that these loads do not alias any stores, and
4893 * they can't fail, allowing them to be hoisted out of loops.
4895 set_invariant_load_flag (values [ins->dreg]);
4896 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4900 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4902 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4903 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4904 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4908 case OP_STOREI1_MEMBASE_REG:
4909 case OP_STOREI2_MEMBASE_REG:
4910 case OP_STOREI4_MEMBASE_REG:
4911 case OP_STOREI8_MEMBASE_REG:
4912 case OP_STORER4_MEMBASE_REG:
4913 case OP_STORER8_MEMBASE_REG:
4914 case OP_STORE_MEMBASE_REG: {
4916 LLVMValueRef index, addr;
4918 gboolean sext = FALSE, zext = FALSE;
4919 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4921 if (!values [ins->inst_destbasereg])
4922 LLVM_FAILURE (ctx, "inst_destbasereg");
4924 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4926 if (ins->inst_offset % size != 0) {
4927 /* Unaligned store */
4928 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4929 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4931 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4932 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4934 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4938 case OP_STOREI1_MEMBASE_IMM:
4939 case OP_STOREI2_MEMBASE_IMM:
4940 case OP_STOREI4_MEMBASE_IMM:
4941 case OP_STOREI8_MEMBASE_IMM:
4942 case OP_STORE_MEMBASE_IMM: {
4944 LLVMValueRef index, addr;
4946 gboolean sext = FALSE, zext = FALSE;
4947 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4949 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4951 if (ins->inst_offset % size != 0) {
4952 /* Unaligned store */
4953 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4954 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4956 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4957 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4959 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4964 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
4966 case OP_OUTARG_VTRETADDR:
4974 case OP_VOIDCALL_MEMBASE:
4975 case OP_CALL_MEMBASE:
4976 case OP_LCALL_MEMBASE:
4977 case OP_FCALL_MEMBASE:
4978 case OP_RCALL_MEMBASE:
4979 case OP_VCALL_MEMBASE:
4980 case OP_VOIDCALL_REG:
4985 case OP_VCALL_REG: {
4986 process_call (ctx, bb, &builder, ins);
4987 CHECK_FAILURE (ctx);
4992 LLVMValueRef indexes [2];
4993 MonoJumpInfo *tmp_ji, *ji;
4994 LLVMValueRef got_entry_addr;
4998 * FIXME: Can't allocate from the cfg mempool since that is freed if
4999 * the LLVM compile fails.
5001 tmp_ji = g_new0 (MonoJumpInfo, 1);
5002 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5003 tmp_ji->data.target = ins->inst_p0;
5005 ji = mono_aot_patch_info_dup (tmp_ji);
5008 ji->next = cfg->patch_info;
5009 cfg->patch_info = ji;
5011 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5012 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5013 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5014 if (!mono_aot_is_shared_got_offset (got_offset)) {
5015 //mono_print_ji (ji);
5017 ctx->has_got_access = TRUE;
5020 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5021 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5022 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5024 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5025 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5027 set_invariant_load_flag (values [ins->dreg]);
5030 case OP_NOT_REACHED:
5031 LLVMBuildUnreachable (builder);
5032 has_terminator = TRUE;
5033 g_assert (bb->block_num < cfg->max_block_num);
5034 ctx->unreachable [bb->block_num] = TRUE;
5035 /* Might have instructions after this */
5037 MonoInst *next = ins->next;
5039 * FIXME: If later code uses the regs defined by these instructions,
5040 * compilation will fail.
5042 MONO_DELETE_INS (bb, next);
5046 MonoInst *var = ins->inst_i0;
5048 if (var->opcode == OP_VTARG_ADDR) {
5049 /* The variable contains the vtype address */
5050 values [ins->dreg] = values [var->dreg];
5051 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5052 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5054 values [ins->dreg] = addresses [var->dreg];
5059 LLVMValueRef args [1];
5061 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5062 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5066 LLVMValueRef args [1];
5068 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5069 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5073 LLVMValueRef args [1];
5076 /* This no longer seems to happen */
5078 * LLVM optimizes sqrt(nan) into undefined in
5079 * lib/Analysis/ConstantFolding.cpp
5080 * Also, sqrt(NegativeInfinity) is optimized into 0.
5082 LLVM_FAILURE (ctx, "sqrt");
5084 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5085 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5089 LLVMValueRef args [1];
5091 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5092 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5106 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5107 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5109 switch (ins->opcode) {
5112 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5116 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5120 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5124 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5127 g_assert_not_reached ();
5130 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5133 case OP_ATOMIC_EXCHANGE_I4:
5134 case OP_ATOMIC_EXCHANGE_I8: {
5135 LLVMValueRef args [2];
5138 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5139 t = LLVMInt32Type ();
5141 t = LLVMInt64Type ();
5143 g_assert (ins->inst_offset == 0);
5145 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5146 args [1] = convert (ctx, rhs, t);
5148 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5151 case OP_ATOMIC_ADD_I4:
5152 case OP_ATOMIC_ADD_I8: {
5153 LLVMValueRef args [2];
5156 if (ins->opcode == OP_ATOMIC_ADD_I4)
5157 t = LLVMInt32Type ();
5159 t = LLVMInt64Type ();
5161 g_assert (ins->inst_offset == 0);
5163 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5164 args [1] = convert (ctx, rhs, t);
5165 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5168 case OP_ATOMIC_CAS_I4:
5169 case OP_ATOMIC_CAS_I8: {
5170 LLVMValueRef args [3], val;
5173 if (ins->opcode == OP_ATOMIC_CAS_I4)
5174 t = LLVMInt32Type ();
5176 t = LLVMInt64Type ();
5178 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5180 args [1] = convert (ctx, values [ins->sreg3], t);
5182 args [2] = convert (ctx, values [ins->sreg2], t);
5183 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5184 /* cmpxchg returns a pair */
5185 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5188 case OP_MEMORY_BARRIER: {
5189 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5192 case OP_ATOMIC_LOAD_I1:
5193 case OP_ATOMIC_LOAD_I2:
5194 case OP_ATOMIC_LOAD_I4:
5195 case OP_ATOMIC_LOAD_I8:
5196 case OP_ATOMIC_LOAD_U1:
5197 case OP_ATOMIC_LOAD_U2:
5198 case OP_ATOMIC_LOAD_U4:
5199 case OP_ATOMIC_LOAD_U8:
5200 case OP_ATOMIC_LOAD_R4:
5201 case OP_ATOMIC_LOAD_R8: {
5202 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
5205 gboolean sext, zext;
5207 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5208 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5209 LLVMValueRef index, addr;
5211 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5216 if (ins->inst_offset != 0) {
5217 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5218 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5223 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5225 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5228 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5230 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5233 case OP_ATOMIC_STORE_I1:
5234 case OP_ATOMIC_STORE_I2:
5235 case OP_ATOMIC_STORE_I4:
5236 case OP_ATOMIC_STORE_I8:
5237 case OP_ATOMIC_STORE_U1:
5238 case OP_ATOMIC_STORE_U2:
5239 case OP_ATOMIC_STORE_U4:
5240 case OP_ATOMIC_STORE_U8:
5241 case OP_ATOMIC_STORE_R4:
5242 case OP_ATOMIC_STORE_R8: {
5243 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
5246 gboolean sext, zext;
5248 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5249 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5250 LLVMValueRef index, addr, value;
5252 if (!values [ins->inst_destbasereg])
5253 LLVM_FAILURE (ctx, "inst_destbasereg");
5255 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5257 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5258 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5259 value = convert (ctx, values [ins->sreg1], t);
5261 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5264 case OP_RELAXED_NOP: {
5265 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5266 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5273 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5275 // 257 == FS segment register
5276 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5278 // 256 == GS segment register
5279 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5282 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5283 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5284 /* See mono_amd64_emit_tls_get () */
5285 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5287 // 256 == GS segment register
5288 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5289 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5291 LLVM_FAILURE (ctx, "opcode tls-get");
5296 case OP_TLS_GET_REG: {
5297 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5298 /* See emit_tls_get_reg () */
5299 // 256 == GS segment register
5300 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5301 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5303 LLVM_FAILURE (ctx, "opcode tls-get");
5308 case OP_TLS_SET_REG: {
5309 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5310 /* See emit_tls_get_reg () */
5311 // 256 == GS segment register
5312 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5313 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5315 LLVM_FAILURE (ctx, "opcode tls-set-reg");
5324 case OP_IADD_OVF_UN:
5326 case OP_ISUB_OVF_UN:
5328 case OP_IMUL_OVF_UN:
5329 #if SIZEOF_VOID_P == 8
5331 case OP_LADD_OVF_UN:
5333 case OP_LSUB_OVF_UN:
5335 case OP_LMUL_OVF_UN:
5338 LLVMValueRef args [2], val, ovf, func;
5340 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5341 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5342 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5344 val = LLVMBuildCall (builder, func, args, 2, "");
5345 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5346 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5347 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5348 CHECK_FAILURE (ctx);
5349 builder = ctx->builder;
5355 * We currently model them using arrays. Promotion to local vregs is
5356 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5357 * so we always have an entry in cfg->varinfo for them.
5358 * FIXME: Is this needed ?
5361 MonoClass *klass = ins->klass;
5362 LLVMValueRef args [5];
5366 LLVM_FAILURE (ctx, "!klass");
5370 if (!addresses [ins->dreg])
5371 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5372 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5373 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5374 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5376 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5377 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5378 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5381 case OP_DUMMY_VZERO:
5384 case OP_STOREV_MEMBASE:
5385 case OP_LOADV_MEMBASE:
5387 MonoClass *klass = ins->klass;
5388 LLVMValueRef src = NULL, dst, args [5];
5389 gboolean done = FALSE;
5393 LLVM_FAILURE (ctx, "!klass");
5397 if (mini_is_gsharedvt_klass (klass)) {
5399 LLVM_FAILURE (ctx, "gsharedvt");
5403 switch (ins->opcode) {
5404 case OP_STOREV_MEMBASE:
5405 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5406 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5407 /* Decomposed earlier */
5408 g_assert_not_reached ();
5411 if (!addresses [ins->sreg1]) {
5413 g_assert (values [ins->sreg1]);
5414 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));
5415 LLVMBuildStore (builder, values [ins->sreg1], dst);
5418 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5419 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5422 case OP_LOADV_MEMBASE:
5423 if (!addresses [ins->dreg])
5424 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5425 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5426 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5429 if (!addresses [ins->sreg1])
5430 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5431 if (!addresses [ins->dreg])
5432 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5433 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5434 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5437 g_assert_not_reached ();
5439 CHECK_FAILURE (ctx);
5446 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5447 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5449 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5450 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5451 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5454 case OP_LLVM_OUTARG_VT: {
5455 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5456 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5458 if (ainfo->storage == LLVMArgScalarByRef) {
5459 LLVMTypeRef argtype;
5460 LLVMValueRef loc, v;
5462 argtype = type_to_llvm_arg_type (ctx, t);
5463 loc = build_alloca_llvm_type (ctx, argtype, 0);
5464 v = convert (ctx, values [ins->sreg1], argtype);
5465 LLVMBuildStore (ctx->builder, v, loc);
5466 addresses [ins->dreg] = loc;
5467 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5468 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5470 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5471 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5473 g_assert (addresses [ins->sreg1]);
5474 addresses [ins->dreg] = addresses [ins->sreg1];
5477 if (!addresses [ins->sreg1]) {
5478 addresses [ins->sreg1] = build_alloca (ctx, t);
5479 g_assert (values [ins->sreg1]);
5480 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5482 addresses [ins->dreg] = addresses [ins->sreg1];
5490 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5492 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5495 case OP_LOADX_MEMBASE: {
5496 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5499 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5500 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5503 case OP_STOREX_MEMBASE: {
5504 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5507 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5508 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5515 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5519 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5525 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5529 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5533 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5537 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5540 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5543 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5546 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5550 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5561 LLVMValueRef v = NULL;
5563 switch (ins->opcode) {
5568 t = LLVMVectorType (LLVMInt32Type (), 4);
5569 rt = LLVMVectorType (LLVMFloatType (), 4);
5575 t = LLVMVectorType (LLVMInt64Type (), 2);
5576 rt = LLVMVectorType (LLVMDoubleType (), 2);
5579 t = LLVMInt32Type ();
5580 rt = LLVMInt32Type ();
5581 g_assert_not_reached ();
5584 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5585 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5586 switch (ins->opcode) {
5589 v = LLVMBuildAnd (builder, lhs, rhs, "");
5593 v = LLVMBuildOr (builder, lhs, rhs, "");
5597 v = LLVMBuildXor (builder, lhs, rhs, "");
5601 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5604 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5628 case OP_PADDB_SAT_UN:
5629 case OP_PADDW_SAT_UN:
5630 case OP_PSUBB_SAT_UN:
5631 case OP_PSUBW_SAT_UN:
5639 case OP_PMULW_HIGH_UN: {
5640 LLVMValueRef args [2];
5645 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5652 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5656 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5664 case OP_EXTRACTX_U2:
5666 case OP_EXTRACT_U1: {
5668 gboolean zext = FALSE;
5670 t = simd_op_to_llvm_type (ins->opcode);
5672 switch (ins->opcode) {
5680 case OP_EXTRACTX_U2:
5685 t = LLVMInt32Type ();
5686 g_assert_not_reached ();
5689 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5690 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5692 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5701 case OP_EXPAND_R8: {
5702 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5703 LLVMValueRef mask [16], v;
5706 for (i = 0; i < 16; ++i)
5707 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5709 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5711 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5712 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5717 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5720 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5723 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5726 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5729 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5732 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5743 case OP_EXTRACT_MASK:
5750 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5752 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5758 LLVMValueRef args [3];
5762 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5764 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5769 /* This is only used for implementing shifts by non-immediate */
5770 values [ins->dreg] = lhs;
5781 LLVMValueRef args [3];
5784 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5786 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5797 case OP_PSHLQ_REG: {
5798 LLVMValueRef args [3];
5801 args [1] = values [ins->sreg2];
5803 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5810 case OP_PSHUFLEW_LOW:
5811 case OP_PSHUFLEW_HIGH: {
5813 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5814 int i, mask_size = 0;
5815 int imask = ins->inst_c0;
5817 /* Convert the x86 shuffle mask to LLVM's */
5818 switch (ins->opcode) {
5821 mask [0] = ((imask >> 0) & 3);
5822 mask [1] = ((imask >> 2) & 3);
5823 mask [2] = ((imask >> 4) & 3) + 4;
5824 mask [3] = ((imask >> 6) & 3) + 4;
5825 v1 = values [ins->sreg1];
5826 v2 = values [ins->sreg2];
5830 mask [0] = ((imask >> 0) & 1);
5831 mask [1] = ((imask >> 1) & 1) + 2;
5832 v1 = values [ins->sreg1];
5833 v2 = values [ins->sreg2];
5835 case OP_PSHUFLEW_LOW:
5837 mask [0] = ((imask >> 0) & 3);
5838 mask [1] = ((imask >> 2) & 3);
5839 mask [2] = ((imask >> 4) & 3);
5840 mask [3] = ((imask >> 6) & 3);
5845 v1 = values [ins->sreg1];
5846 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5848 case OP_PSHUFLEW_HIGH:
5854 mask [4] = 4 + ((imask >> 0) & 3);
5855 mask [5] = 4 + ((imask >> 2) & 3);
5856 mask [6] = 4 + ((imask >> 4) & 3);
5857 mask [7] = 4 + ((imask >> 6) & 3);
5858 v1 = values [ins->sreg1];
5859 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5863 mask [0] = ((imask >> 0) & 3);
5864 mask [1] = ((imask >> 2) & 3);
5865 mask [2] = ((imask >> 4) & 3);
5866 mask [3] = ((imask >> 6) & 3);
5867 v1 = values [ins->sreg1];
5868 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5871 g_assert_not_reached ();
5873 for (i = 0; i < mask_size; ++i)
5874 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5876 values [ins->dreg] =
5877 LLVMBuildShuffleVector (builder, v1, v2,
5878 LLVMConstVector (mask_values, mask_size), dname);
5882 case OP_UNPACK_LOWB:
5883 case OP_UNPACK_LOWW:
5884 case OP_UNPACK_LOWD:
5885 case OP_UNPACK_LOWQ:
5886 case OP_UNPACK_LOWPS:
5887 case OP_UNPACK_LOWPD:
5888 case OP_UNPACK_HIGHB:
5889 case OP_UNPACK_HIGHW:
5890 case OP_UNPACK_HIGHD:
5891 case OP_UNPACK_HIGHQ:
5892 case OP_UNPACK_HIGHPS:
5893 case OP_UNPACK_HIGHPD: {
5895 LLVMValueRef mask_values [16];
5896 int i, mask_size = 0;
5897 gboolean low = FALSE;
5899 switch (ins->opcode) {
5900 case OP_UNPACK_LOWB:
5904 case OP_UNPACK_LOWW:
5908 case OP_UNPACK_LOWD:
5909 case OP_UNPACK_LOWPS:
5913 case OP_UNPACK_LOWQ:
5914 case OP_UNPACK_LOWPD:
5918 case OP_UNPACK_HIGHB:
5921 case OP_UNPACK_HIGHW:
5924 case OP_UNPACK_HIGHD:
5925 case OP_UNPACK_HIGHPS:
5928 case OP_UNPACK_HIGHQ:
5929 case OP_UNPACK_HIGHPD:
5933 g_assert_not_reached ();
5937 for (i = 0; i < (mask_size / 2); ++i) {
5939 mask [(i * 2) + 1] = mask_size + i;
5942 for (i = 0; i < (mask_size / 2); ++i) {
5943 mask [(i * 2)] = (mask_size / 2) + i;
5944 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
5948 for (i = 0; i < mask_size; ++i)
5949 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5951 values [ins->dreg] =
5952 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
5953 LLVMConstVector (mask_values, mask_size), dname);
5958 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5959 LLVMValueRef v, val;
5961 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5962 val = LLVMConstNull (t);
5963 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5964 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
5966 values [ins->dreg] = val;
5970 case OP_DUPPS_HIGH: {
5971 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5972 LLVMValueRef v1, v2, val;
5975 if (ins->opcode == OP_DUPPS_LOW) {
5976 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5977 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5979 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5980 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5982 val = LLVMConstNull (t);
5983 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5984 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5985 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5986 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5988 values [ins->dreg] = val;
5998 * EXCEPTION HANDLING
6000 case OP_IMPLICIT_EXCEPTION:
6001 /* This marks a place where an implicit exception can happen */
6002 if (bb->region != -1)
6003 LLVM_FAILURE (ctx, "implicit-exception");
6007 gboolean rethrow = (ins->opcode == OP_RETHROW);
6008 if (ctx->llvm_only) {
6009 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6010 has_terminator = TRUE;
6011 ctx->unreachable [bb->block_num] = TRUE;
6013 emit_throw (ctx, bb, rethrow, lhs);
6014 builder = ctx->builder;
6018 case OP_CALL_HANDLER: {
6020 * We don't 'call' handlers, but instead simply branch to them.
6021 * The code generated by ENDFINALLY will branch back to us.
6023 LLVMBasicBlockRef noex_bb;
6025 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6027 bb_list = info->call_handler_return_bbs;
6030 * Set the indicator variable for the finally clause.
6032 lhs = info->finally_ind;
6034 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6036 /* Branch to the finally clause */
6037 LLVMBuildBr (builder, info->call_handler_target_bb);
6039 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6040 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6042 builder = ctx->builder = create_builder (ctx);
6043 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6045 bblocks [bb->block_num].end_bblock = noex_bb;
6048 case OP_START_HANDLER: {
6051 case OP_ENDFINALLY: {
6052 LLVMBasicBlockRef resume_bb;
6053 MonoBasicBlock *handler_bb;
6054 LLVMValueRef val, switch_ins, callee;
6058 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6059 g_assert (handler_bb);
6060 info = &bblocks [handler_bb->block_num];
6061 lhs = info->finally_ind;
6064 bb_list = info->call_handler_return_bbs;
6066 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6068 /* Load the finally variable */
6069 val = LLVMBuildLoad (builder, lhs, "");
6071 /* Reset the variable */
6072 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6074 /* Branch to either resume_bb, or to the bblocks in bb_list */
6075 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6077 * The other targets are added at the end to handle OP_CALL_HANDLER
6078 * opcodes processed later.
6080 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6082 builder = ctx->builder = create_builder (ctx);
6083 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6085 if (ctx->llvm_only) {
6086 emit_resume_eh (ctx, bb);
6088 if (ctx->cfg->compile_aot) {
6089 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6091 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6093 LLVMBuildCall (builder, callee, NULL, 0, "");
6094 LLVMBuildUnreachable (builder);
6097 has_terminator = TRUE;
6100 case OP_IL_SEQ_POINT:
6105 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6106 LLVM_FAILURE (ctx, reason);
6111 /* Convert the value to the type required by phi nodes */
6112 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6113 if (!values [ins->dreg])
6115 values [ins->dreg] = addresses [ins->dreg];
6117 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6120 /* Add stores for volatile variables */
6121 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6122 emit_volatile_store (ctx, ins->dreg);
6125 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6126 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6129 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6130 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6131 LLVMBuildRetVoid (builder);
6134 if (bb == cfg->bb_entry)
6135 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6144 * mono_llvm_check_method_supported:
6146 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6147 * compiling a method twice.
6150 mono_llvm_check_method_supported (MonoCompile *cfg)
6157 if (cfg->method->save_lmf) {
6158 cfg->exception_message = g_strdup ("lmf");
6159 cfg->disable_llvm = TRUE;
6161 if (cfg->disable_llvm)
6165 * Nested clauses where one of the clauses is a finally clause is
6166 * not supported, because LLVM can't figure out the control flow,
6167 * probably because we resume exception handling by calling our
6168 * own function instead of using the 'resume' llvm instruction.
6170 for (i = 0; i < cfg->header->num_clauses; ++i) {
6171 for (j = 0; j < cfg->header->num_clauses; ++j) {
6172 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6173 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6175 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6176 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6177 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6178 cfg->exception_message = g_strdup ("nested clauses");
6179 cfg->disable_llvm = TRUE;
6184 if (cfg->disable_llvm)
6188 if (cfg->method->dynamic) {
6189 cfg->exception_message = g_strdup ("dynamic.");
6190 cfg->disable_llvm = TRUE;
6192 if (cfg->disable_llvm)
6196 static LLVMCallInfo*
6197 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6199 LLVMCallInfo *linfo;
6202 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6206 * Gsharedvt methods have the following calling convention:
6207 * - all arguments are passed by ref, even non generic ones
6208 * - the return value is returned by ref too, using a vret
6209 * argument passed after 'this'.
6211 n = sig->param_count + sig->hasthis;
6212 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6216 linfo->args [pindex ++].storage = LLVMArgNormal;
6218 if (sig->ret->type != MONO_TYPE_VOID) {
6219 if (mini_is_gsharedvt_variable_type (sig->ret))
6220 linfo->ret.storage = LLVMArgGsharedvtVariable;
6221 else if (mini_type_is_vtype (sig->ret))
6222 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6224 linfo->ret.storage = LLVMArgGsharedvtFixed;
6225 linfo->vret_arg_index = pindex;
6227 linfo->ret.storage = LLVMArgNone;
6230 for (i = 0; i < sig->param_count; ++i) {
6231 if (sig->params [i]->byref)
6232 linfo->args [pindex].storage = LLVMArgNormal;
6233 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6234 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6235 else if (mini_type_is_vtype (sig->params [i]))
6236 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6238 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6239 linfo->args [pindex].type = sig->params [i];
6246 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6247 for (i = 0; i < sig->param_count; ++i)
6248 linfo->args [i + sig->hasthis].type = sig->params [i];
6254 * mono_llvm_emit_method:
6256 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6259 mono_llvm_emit_method (MonoCompile *cfg)
6262 MonoMethodSignature *sig;
6264 LLVMTypeRef method_type;
6265 LLVMValueRef method = NULL;
6267 LLVMValueRef *values;
6268 int i, max_block_num, bb_index;
6269 gboolean last = FALSE, is_linkonce = FALSE;
6270 GPtrArray *phi_values;
6271 LLVMCallInfo *linfo;
6273 LLVMModuleRef lmodule;
6275 GPtrArray *bblock_list;
6276 MonoMethodHeader *header;
6277 MonoExceptionClause *clause;
6280 /* The code below might acquire the loader lock, so use it for global locking */
6281 mono_loader_lock ();
6283 /* Used to communicate with the callbacks */
6284 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6286 ctx = g_new0 (EmitContext, 1);
6288 ctx->mempool = cfg->mempool;
6291 * This maps vregs to the LLVM instruction defining them
6293 values = g_new0 (LLVMValueRef, cfg->next_vreg);
6295 * This maps vregs for volatile variables to the LLVM instruction defining their
6298 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6299 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6300 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6301 phi_values = g_ptr_array_sized_new (256);
6303 * This signals whenever the vreg was defined by a phi node with no input vars
6304 * (i.e. all its input bblocks end with NOT_REACHABLE).
6306 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6307 /* Whenever the bblock is unreachable */
6308 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6309 bblock_list = g_ptr_array_sized_new (256);
6311 ctx->values = values;
6312 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6313 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6314 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6316 if (cfg->compile_aot) {
6317 ctx->module = &aot_module;
6321 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6322 * linkage for them. This requires the following:
6323 * - the method needs to have a unique mangled name
6324 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6326 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6328 method_name = mono_aot_get_mangled_method_name (cfg->method);
6330 is_linkonce = FALSE;
6333 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6335 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6339 method_name = mono_aot_get_method_name (cfg);
6340 cfg->llvm_method_name = g_strdup (method_name);
6342 init_jit_module (cfg->domain);
6343 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6344 method_name = mono_method_full_name (cfg->method, TRUE);
6347 lmodule = ctx->lmodule = ctx->module->lmodule;
6348 ctx->llvm_only = ctx->module->llvm_only;
6350 if (cfg->gsharedvt && !cfg->llvm_only)
6351 LLVM_FAILURE (ctx, "gsharedvt");
6355 static int count = 0;
6358 if (g_getenv ("LLVM_COUNT")) {
6359 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6360 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6364 if (count > atoi (g_getenv ("LLVM_COUNT")))
6365 LLVM_FAILURE (ctx, "");
6370 sig = mono_method_signature (cfg->method);
6373 linfo = get_llvm_call_info (cfg, sig);
6375 CHECK_FAILURE (ctx);
6378 linfo->rgctx_arg = TRUE;
6379 method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6380 CHECK_FAILURE (ctx);
6382 method = LLVMAddFunction (lmodule, method_name, method_type);
6383 ctx->lmethod = method;
6385 if (!cfg->llvm_only)
6386 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6387 LLVMSetLinkage (method, LLVMPrivateLinkage);
6389 LLVMAddFunctionAttr (method, LLVMUWTable);
6391 if (cfg->compile_aot) {
6392 LLVMSetLinkage (method, LLVMInternalLinkage);
6393 if (ctx->module->external_symbols) {
6394 LLVMSetLinkage (method, LLVMExternalLinkage);
6395 LLVMSetVisibility (method, LLVMHiddenVisibility);
6398 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6399 LLVMSetVisibility (method, LLVMDefaultVisibility);
6402 LLVMSetLinkage (method, LLVMPrivateLinkage);
6405 if (cfg->method->save_lmf && !cfg->llvm_only)
6406 LLVM_FAILURE (ctx, "lmf");
6408 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only)
6409 LLVM_FAILURE (ctx, "pinvoke signature");
6411 header = cfg->header;
6412 for (i = 0; i < header->num_clauses; ++i) {
6413 clause = &header->clauses [i];
6414 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
6415 LLVM_FAILURE (ctx, "non-finally/catch clause.");
6417 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
6418 /* We can't handle inlined methods with clauses */
6419 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6421 if (linfo->rgctx_arg) {
6422 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6423 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6425 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6426 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6427 * CC_X86_64_Mono in X86CallingConv.td.
6429 if (!ctx->llvm_only)
6430 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6431 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6433 ctx->rgctx_arg_pindex = -1;
6435 if (cfg->vret_addr) {
6436 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6437 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6438 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6439 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6440 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6442 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6443 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6444 LLVMSetValueName (param, "vret");
6448 ctx->this_arg_pindex = linfo->this_arg_pindex;
6449 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6450 values [cfg->args [0]->dreg] = ctx->this_arg;
6451 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6454 names = g_new (char *, sig->param_count);
6455 mono_method_get_param_names (cfg->method, (const char **) names);
6457 for (i = 0; i < sig->param_count; ++i) {
6458 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6460 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6463 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6464 name = g_strdup_printf ("dummy_%d_%d", i, j);
6465 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6469 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6470 if (ainfo->storage == LLVMArgScalarByRef) {
6471 if (names [i] && names [i][0] != '\0')
6472 name = g_strdup_printf ("p_arg_%s", names [i]);
6474 name = g_strdup_printf ("p_arg_%d", i);
6475 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6476 if (names [i] && names [i][0] != '\0')
6477 name = g_strdup_printf ("p_arg_%s", names [i]);
6479 name = g_strdup_printf ("p_arg_%d", i);
6481 if (names [i] && names [i][0] != '\0')
6482 name = g_strdup_printf ("arg_%s", names [i]);
6484 name = g_strdup_printf ("arg_%d", i);
6486 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6488 if (ainfo->storage == LLVMArgVtypeByVal)
6489 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6491 if (ainfo->storage == LLVMArgVtypeByRef) {
6493 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6498 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6499 ctx->minfo = mono_debug_lookup_method (cfg->method);
6500 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
6504 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6505 max_block_num = MAX (max_block_num, bb->block_num);
6506 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6508 /* Add branches between non-consecutive bblocks */
6509 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6510 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6511 bb->next_bb != bb->last_ins->inst_false_bb) {
6513 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6514 inst->opcode = OP_BR;
6515 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6516 mono_bblock_add_inst (bb, inst);
6521 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6522 * was later optimized away, so clear these flags, and add them back for the still
6523 * present OP_LDADDR instructions.
6525 for (i = 0; i < cfg->next_vreg; ++i) {
6528 ins = get_vreg_to_inst (cfg, i);
6529 if (ins && ins != cfg->rgctx_var)
6530 ins->flags &= ~MONO_INST_INDIRECT;
6534 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6536 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6538 LLVMBuilderRef builder;
6540 char dname_buf[128];
6542 builder = create_builder (ctx);
6544 for (ins = bb->code; ins; ins = ins->next) {
6545 switch (ins->opcode) {
6550 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6552 CHECK_FAILURE (ctx);
6554 if (ins->opcode == OP_VPHI) {
6555 /* Treat valuetype PHI nodes as operating on the address itself */
6556 g_assert (ins->klass);
6557 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6561 * Have to precreate these, as they can be referenced by
6562 * earlier instructions.
6564 sprintf (dname_buf, "t%d", ins->dreg);
6566 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6568 if (ins->opcode == OP_VPHI)
6569 ctx->addresses [ins->dreg] = values [ins->dreg];
6571 g_ptr_array_add (phi_values, values [ins->dreg]);
6574 * Set the expected type of the incoming arguments since these have
6575 * to have the same type.
6577 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6578 int sreg1 = ins->inst_phi_args [i + 1];
6581 ctx->vreg_types [sreg1] = phi_type;
6586 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6595 * Create an ordering for bblocks, use the depth first order first, then
6596 * put the exception handling bblocks last.
6598 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6599 bb = cfg->bblocks [bb_index];
6600 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6601 g_ptr_array_add (bblock_list, bb);
6602 bblocks [bb->block_num].added = TRUE;
6606 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6607 if (!bblocks [bb->block_num].added)
6608 g_ptr_array_add (bblock_list, bb);
6612 * Second pass: generate code.
6615 LLVMBuilderRef entry_builder = create_builder (ctx);
6616 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6617 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6618 emit_entry_bb (ctx, entry_builder);
6620 // Make landing pads first
6621 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6623 if (ctx->llvm_only) {
6624 size_t group_index = 0;
6625 while (group_index < cfg->header->num_clauses) {
6627 size_t cursor = group_index;
6628 while (cursor < cfg->header->num_clauses &&
6629 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6630 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6635 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6636 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6637 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6639 group_index = cursor;
6643 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6644 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6646 // Prune unreachable mono BBs.
6647 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6650 process_bb (ctx, bb);
6651 CHECK_FAILURE (ctx);
6653 g_hash_table_destroy (ctx->exc_meta);
6655 mono_memory_barrier ();
6657 /* Add incoming phi values */
6658 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6659 GSList *l, *ins_list;
6661 ins_list = bblocks [bb->block_num].phi_nodes;
6663 for (l = ins_list; l; l = l->next) {
6664 PhiNode *node = (PhiNode*)l->data;
6665 MonoInst *phi = node->phi;
6666 int sreg1 = node->sreg;
6667 LLVMBasicBlockRef in_bb;
6672 in_bb = get_end_bb (ctx, node->in_bb);
6674 if (ctx->unreachable [node->in_bb->block_num])
6677 if (!values [sreg1])
6678 /* Can happen with values in EH clauses */
6679 LLVM_FAILURE (ctx, "incoming phi sreg1");
6681 if (phi->opcode == OP_VPHI) {
6682 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6683 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6685 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
6687 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
6688 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6689 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6694 /* Nullify empty phi instructions */
6695 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6696 GSList *l, *ins_list;
6698 ins_list = bblocks [bb->block_num].phi_nodes;
6700 for (l = ins_list; l; l = l->next) {
6701 PhiNode *node = (PhiNode*)l->data;
6702 MonoInst *phi = node->phi;
6703 LLVMValueRef phi_ins = values [phi->dreg];
6706 /* Already removed */
6709 if (LLVMCountIncoming (phi_ins) == 0) {
6710 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6711 LLVMInstructionEraseFromParent (phi_ins);
6712 values [phi->dreg] = NULL;
6717 /* Create the SWITCH statements for ENDFINALLY instructions */
6718 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6719 BBInfo *info = &bblocks [bb->block_num];
6721 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6722 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6723 GSList *bb_list = info->call_handler_return_bbs;
6725 for (i = 0; i < g_slist_length (bb_list); ++i)
6726 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6730 /* Initialize the method if needed */
6731 if (cfg->compile_aot && ctx->llvm_only) {
6732 // FIXME: Add more shared got entries
6733 ctx->builder = create_builder (ctx);
6734 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6736 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6738 // FIXME: beforefieldinit
6739 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6740 emit_init_method (ctx);
6742 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6746 if (cfg->llvm_only) {
6747 GHashTableIter iter;
6749 GSList *callers, *l, *l2;
6752 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6753 * We can't do this earlier, as it contains llvm instructions which can be
6754 * freed if compilation fails.
6755 * FIXME: Get rid of this when all methods can be llvm compiled.
6757 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6758 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6759 for (l = callers; l; l = l->next) {
6760 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6761 l2 = g_slist_prepend (l2, l->data);
6762 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6767 if (cfg->verbose_level > 1)
6768 mono_llvm_dump_value (method);
6770 if (cfg->compile_aot && !cfg->llvm_only)
6771 mark_as_used (ctx->module, method);
6773 if (cfg->compile_aot) {
6774 LLVMValueRef md_args [16];
6775 LLVMValueRef md_node;
6778 method_index = mono_aot_get_method_index (cfg->orig_method);
6779 md_args [0] = LLVMMDString (method_name, strlen (method_name));
6780 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6781 md_node = LLVMMDNode (md_args, 2);
6782 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6783 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6786 if (cfg->compile_aot) {
6787 /* Don't generate native code, keep the LLVM IR */
6788 if (cfg->verbose_level)
6789 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
6791 int err = LLVMVerifyFunction(method, LLVMPrintMessageAction);
6792 g_assert (err == 0);
6794 //LLVMVerifyFunction(method, 0);
6795 mono_llvm_optimize_method (ctx->module->mono_ee, method);
6797 if (cfg->verbose_level > 1)
6798 mono_llvm_dump_value (method);
6800 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, method);
6802 /* Set by emit_cb */
6803 g_assert (cfg->code_len);
6805 /* FIXME: Free the LLVM IL for the function */
6808 if (ctx->module->method_to_lmethod)
6809 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, method);
6810 if (ctx->module->idx_to_lmethod)
6811 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), method);
6813 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6814 emit_unbox_tramp (ctx, method_name, method_type, method, cfg->method_index);
6821 /* Need to add unused phi nodes as they can be referenced by other values */
6822 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
6823 LLVMBuilderRef builder;
6825 builder = create_builder (ctx);
6826 LLVMPositionBuilderAtEnd (builder, phi_bb);
6828 for (i = 0; i < phi_values->len; ++i) {
6829 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (phi_values, i);
6830 if (LLVMGetInstructionParent (v) == NULL)
6831 LLVMInsertIntoBuilder (builder, v);
6834 LLVMDeleteFunction (method);
6839 g_free (ctx->addresses);
6840 g_free (ctx->vreg_types);
6841 g_free (ctx->vreg_cli_types);
6842 g_free (ctx->is_dead);
6843 g_free (ctx->unreachable);
6844 g_ptr_array_free (phi_values, TRUE);
6845 g_free (ctx->bblocks);
6846 g_hash_table_destroy (ctx->region_to_handler);
6847 g_hash_table_destroy (ctx->clause_to_handler);
6848 g_free (method_name);
6849 g_ptr_array_free (bblock_list, TRUE);
6851 for (l = ctx->builders; l; l = l->next) {
6852 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6853 LLVMDisposeBuilder (builder);
6858 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6860 mono_loader_unlock ();
6864 * mono_llvm_create_vars:
6866 * Same as mono_arch_create_vars () for LLVM.
6869 mono_llvm_create_vars (MonoCompile *cfg)
6871 MonoMethodSignature *sig;
6873 sig = mono_method_signature (cfg->method);
6874 if (cfg->gsharedvt && cfg->llvm_only) {
6875 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
6876 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_int32_class ()->byval_arg, OP_ARG);
6877 if (G_UNLIKELY (cfg->verbose_level > 1)) {
6878 printf ("vret_addr = ");
6879 mono_print_ins (cfg->vret_addr);
6883 mono_arch_create_vars (cfg);
6888 * mono_llvm_emit_call:
6890 * Same as mono_arch_emit_call () for LLVM.
6893 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
6896 MonoMethodSignature *sig;
6897 int i, n, stack_size;
6902 sig = call->signature;
6903 n = sig->param_count + sig->hasthis;
6905 call->cinfo = get_llvm_call_info (cfg, sig);
6907 if (cfg->disable_llvm)
6910 if (sig->call_convention == MONO_CALL_VARARG) {
6911 cfg->exception_message = g_strdup ("varargs");
6912 cfg->disable_llvm = TRUE;
6915 for (i = 0; i < n; ++i) {
6918 ainfo = call->cinfo->args + i;
6920 in = call->args [i];
6922 /* Simply remember the arguments */
6923 switch (ainfo->storage) {
6924 case LLVMArgNormal: {
6925 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
6928 opcode = mono_type_to_regmove (cfg, t);
6929 if (opcode == OP_FMOVE) {
6930 MONO_INST_NEW (cfg, ins, OP_FMOVE);
6931 ins->dreg = mono_alloc_freg (cfg);
6932 } else if (opcode == OP_LMOVE) {
6933 MONO_INST_NEW (cfg, ins, OP_LMOVE);
6934 ins->dreg = mono_alloc_lreg (cfg);
6935 } else if (opcode == OP_RMOVE) {
6936 MONO_INST_NEW (cfg, ins, OP_RMOVE);
6937 ins->dreg = mono_alloc_freg (cfg);
6939 MONO_INST_NEW (cfg, ins, OP_MOVE);
6940 ins->dreg = mono_alloc_ireg (cfg);
6942 ins->sreg1 = in->dreg;
6945 case LLVMArgVtypeByVal:
6946 case LLVMArgVtypeByRef:
6947 case LLVMArgVtypeInReg:
6948 case LLVMArgVtypeAsScalar:
6949 case LLVMArgScalarByRef:
6950 case LLVMArgAsIArgs:
6951 case LLVMArgAsFpArgs:
6952 case LLVMArgGsharedvtVariable:
6953 case LLVMArgGsharedvtFixed:
6954 case LLVMArgGsharedvtFixedVtype:
6955 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
6956 ins->dreg = mono_alloc_ireg (cfg);
6957 ins->sreg1 = in->dreg;
6958 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
6959 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
6960 ins->inst_vtype = ainfo->type;
6961 ins->klass = mono_class_from_mono_type (ainfo->type);
6964 cfg->exception_message = g_strdup ("ainfo->storage");
6965 cfg->disable_llvm = TRUE;
6969 if (!cfg->disable_llvm) {
6970 MONO_ADD_INS (cfg->cbb, ins);
6971 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
6976 static unsigned char*
6977 alloc_cb (LLVMValueRef function, int size)
6981 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
6985 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
6987 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
6992 emitted_cb (LLVMValueRef function, void *start, void *end)
6996 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
6998 cfg->code_len = (guint8*)end - (guint8*)start;
7002 exception_cb (void *data)
7005 MonoJitExceptionInfo *ei;
7006 guint32 ei_len, i, j, nested_len, nindex;
7007 gpointer *type_info;
7008 int this_reg, this_offset;
7010 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7014 * data points to a DWARF FDE structure, convert it to our unwind format and
7016 * An alternative would be to save it directly, and modify our unwinder to work
7019 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);
7020 if (cfg->verbose_level > 1)
7021 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7023 /* Count nested clauses */
7025 for (i = 0; i < ei_len; ++i) {
7026 gint32 cindex1 = *(gint32*)type_info [i];
7027 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7029 for (j = 0; j < cfg->header->num_clauses; ++j) {
7031 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7033 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7039 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7040 cfg->llvm_ex_info_len = ei_len + nested_len;
7041 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7042 /* Fill the rest of the information from the type info */
7043 for (i = 0; i < ei_len; ++i) {
7044 gint32 clause_index = *(gint32*)type_info [i];
7045 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7047 cfg->llvm_ex_info [i].flags = clause->flags;
7048 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7049 cfg->llvm_ex_info [i].clause_index = clause_index;
7053 * For nested clauses, the LLVM produced exception info associates the try interval with
7054 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7055 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7056 * and everything else from the nested clause.
7059 for (i = 0; i < ei_len; ++i) {
7060 gint32 cindex1 = *(gint32*)type_info [i];
7061 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7063 for (j = 0; j < cfg->header->num_clauses; ++j) {
7065 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7066 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7068 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7069 /* clause1 is the nested clause */
7070 nested_ei = &cfg->llvm_ex_info [i];
7071 nesting_ei = &cfg->llvm_ex_info [nindex];
7074 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7076 nesting_ei->flags = clause2->flags;
7077 nesting_ei->data.catch_class = clause2->data.catch_class;
7078 nesting_ei->clause_index = cindex2;
7082 g_assert (nindex == ei_len + nested_len);
7083 cfg->llvm_this_reg = this_reg;
7084 cfg->llvm_this_offset = this_offset;
7086 /* type_info [i] is cfg mempool allocated, no need to free it */
7093 dlsym_cb (const char *name, void **symbol)
7099 if (!strcmp (name, "__bzero")) {
7100 *symbol = (void*)bzero;
7102 current = mono_dl_open (NULL, 0, NULL);
7105 err = mono_dl_symbol (current, name, symbol);
7107 mono_dl_close (current);
7109 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7110 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7116 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7118 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7122 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7124 LLVMTypeRef param_types [4];
7126 param_types [0] = param_type1;
7127 param_types [1] = param_type2;
7129 AddFunc (module, name, ret_type, param_types, 2);
7133 add_intrinsics (LLVMModuleRef module)
7135 /* Emit declarations of instrinsics */
7137 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7138 * type doesn't seem to do any locking.
7141 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7143 memset_param_count = 5;
7144 memset_func_name = "llvm.memset.p0i8.i32";
7146 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7150 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7152 memcpy_param_count = 5;
7153 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7155 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7159 LLVMTypeRef params [] = { LLVMDoubleType () };
7161 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7162 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7163 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7165 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7166 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7170 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7171 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7172 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7174 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7175 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7176 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7177 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7178 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7179 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7180 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7184 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7185 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7186 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7188 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7189 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7190 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7191 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7192 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7193 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7196 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7197 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7201 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7203 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7206 /* SSE intrinsics */
7207 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7209 LLVMTypeRef ret_type, arg_types [16];
7212 ret_type = type_to_simd_type (MONO_TYPE_I4);
7213 arg_types [0] = ret_type;
7214 arg_types [1] = ret_type;
7215 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7216 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7218 ret_type = type_to_simd_type (MONO_TYPE_I2);
7219 arg_types [0] = ret_type;
7220 arg_types [1] = ret_type;
7221 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7222 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7223 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7224 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7225 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7226 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7227 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7228 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7229 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7230 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7232 ret_type = type_to_simd_type (MONO_TYPE_I1);
7233 arg_types [0] = ret_type;
7234 arg_types [1] = ret_type;
7235 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7236 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7237 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7238 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7239 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7240 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7241 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7243 ret_type = type_to_simd_type (MONO_TYPE_R8);
7244 arg_types [0] = ret_type;
7245 arg_types [1] = ret_type;
7246 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7247 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7248 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7249 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7250 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7252 ret_type = type_to_simd_type (MONO_TYPE_R4);
7253 arg_types [0] = ret_type;
7254 arg_types [1] = ret_type;
7255 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7256 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7257 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7258 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7259 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7262 ret_type = type_to_simd_type (MONO_TYPE_I1);
7263 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7264 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7265 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7266 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7267 ret_type = type_to_simd_type (MONO_TYPE_I2);
7268 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7269 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7270 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7271 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7274 ret_type = type_to_simd_type (MONO_TYPE_R8);
7275 arg_types [0] = ret_type;
7276 arg_types [1] = ret_type;
7277 arg_types [2] = LLVMInt8Type ();
7278 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7279 ret_type = type_to_simd_type (MONO_TYPE_R4);
7280 arg_types [0] = ret_type;
7281 arg_types [1] = ret_type;
7282 arg_types [2] = LLVMInt8Type ();
7283 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7285 /* Conversion ops */
7286 ret_type = type_to_simd_type (MONO_TYPE_R8);
7287 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7288 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7289 ret_type = type_to_simd_type (MONO_TYPE_R4);
7290 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7291 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7292 ret_type = type_to_simd_type (MONO_TYPE_I4);
7293 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7294 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7295 ret_type = type_to_simd_type (MONO_TYPE_I4);
7296 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7297 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7298 ret_type = type_to_simd_type (MONO_TYPE_R4);
7299 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7300 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7301 ret_type = type_to_simd_type (MONO_TYPE_R8);
7302 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7303 AddFunc (module, "llvm.x86.sse2.cvtps2pd", 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.cvttpd2dq", 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.cvttps2dq", ret_type, arg_types, 1);
7313 ret_type = type_to_simd_type (MONO_TYPE_R8);
7314 arg_types [0] = ret_type;
7315 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7316 ret_type = type_to_simd_type (MONO_TYPE_R4);
7317 arg_types [0] = ret_type;
7318 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7319 ret_type = type_to_simd_type (MONO_TYPE_R4);
7320 arg_types [0] = ret_type;
7321 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7322 ret_type = type_to_simd_type (MONO_TYPE_R4);
7323 arg_types [0] = ret_type;
7324 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7327 ret_type = type_to_simd_type (MONO_TYPE_I2);
7328 arg_types [0] = ret_type;
7329 arg_types [1] = LLVMInt32Type ();
7330 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7331 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7332 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7333 ret_type = type_to_simd_type (MONO_TYPE_I4);
7334 arg_types [0] = ret_type;
7335 arg_types [1] = LLVMInt32Type ();
7336 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7337 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7338 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7339 ret_type = type_to_simd_type (MONO_TYPE_I8);
7340 arg_types [0] = ret_type;
7341 arg_types [1] = LLVMInt32Type ();
7342 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7343 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7346 ret_type = LLVMInt32Type ();
7347 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7348 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7351 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7354 /* Load/Store intrinsics */
7356 LLVMTypeRef arg_types [5];
7360 for (i = 1; i <= 8; i *= 2) {
7361 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7362 arg_types [1] = LLVMInt32Type ();
7363 arg_types [2] = LLVMInt1Type ();
7364 arg_types [3] = LLVMInt32Type ();
7365 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7366 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7368 arg_types [0] = LLVMIntType (i * 8);
7369 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7370 arg_types [2] = LLVMInt32Type ();
7371 arg_types [3] = LLVMInt1Type ();
7372 arg_types [4] = LLVMInt32Type ();
7373 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7374 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7380 add_types (MonoLLVMModule *module)
7382 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7386 mono_llvm_init (void)
7388 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7392 init_jit_module (MonoDomain *domain)
7394 MonoJitICallInfo *info;
7395 MonoJitDomainInfo *dinfo;
7396 MonoLLVMModule *module;
7399 dinfo = domain_jit_info (domain);
7400 if (dinfo->llvm_module)
7403 mono_loader_lock ();
7405 if (dinfo->llvm_module) {
7406 mono_loader_unlock ();
7410 module = g_new0 (MonoLLVMModule, 1);
7412 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7413 module->lmodule = LLVMModuleCreateWithName (name);
7414 module->context = LLVMGetGlobalContext ();
7416 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7418 add_intrinsics (module->lmodule);
7421 module->llvm_types = g_hash_table_new (NULL, NULL);
7423 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7425 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7427 mono_memory_barrier ();
7429 dinfo->llvm_module = module;
7431 mono_loader_unlock ();
7435 mono_llvm_cleanup (void)
7437 MonoLLVMModule *module = &aot_module;
7439 if (module->lmodule)
7440 LLVMDisposeModule (module->lmodule);
7442 if (module->context)
7443 LLVMContextDispose (module->context);
7447 mono_llvm_free_domain_info (MonoDomain *domain)
7449 MonoJitDomainInfo *info = domain_jit_info (domain);
7450 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7456 if (module->llvm_types)
7457 g_hash_table_destroy (module->llvm_types);
7459 mono_llvm_dispose_ee (module->mono_ee);
7461 if (module->bb_names) {
7462 for (i = 0; i < module->bb_names_len; ++i)
7463 g_free (module->bb_names [i]);
7464 g_free (module->bb_names);
7466 //LLVMDisposeModule (module->module);
7470 info->llvm_module = NULL;
7474 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7476 MonoLLVMModule *module = &aot_module;
7478 /* Delete previous module */
7479 if (module->plt_entries)
7480 g_hash_table_destroy (module->plt_entries);
7481 if (module->lmodule)
7482 LLVMDisposeModule (module->lmodule);
7484 memset (module, 0, sizeof (aot_module));
7486 module->lmodule = LLVMModuleCreateWithName ("aot");
7487 module->assembly = assembly;
7488 module->global_prefix = g_strdup (global_prefix);
7489 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7490 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7491 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7492 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7493 module->external_symbols = TRUE;
7494 module->emit_dwarf = emit_dwarf;
7495 module->static_link = static_link;
7496 module->llvm_only = llvm_only;
7497 /* The first few entries are reserved */
7498 module->max_got_offset = 16;
7499 module->context = LLVMContextCreate ();
7502 /* clang ignores our debug info because it has an invalid version */
7503 module->emit_dwarf = FALSE;
7505 add_intrinsics (module->lmodule);
7510 * We couldn't compute the type of the LLVM global representing the got because
7511 * its size is only known after all the methods have been emitted. So create
7512 * a dummy variable, and replace all uses it with the real got variable when
7513 * its size is known in mono_llvm_emit_aot_module ().
7516 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7518 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7519 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7522 /* Add initialization array */
7524 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7526 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7527 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7531 emit_init_icall_wrappers (module);
7533 emit_llvm_code_start (module);
7535 /* Add a dummy personality function */
7536 if (!use_debug_personality) {
7537 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7538 LLVMSetLinkage (personality, LLVMExternalLinkage);
7539 mark_as_used (module, personality);
7542 /* Add a reference to the c++ exception we throw/catch */
7544 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7545 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7546 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7547 mono_llvm_set_is_constant (module->sentinel_exception);
7550 module->llvm_types = g_hash_table_new (NULL, NULL);
7551 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7552 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7553 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7554 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7555 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7556 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7557 module->method_to_callers = g_hash_table_new (NULL, NULL);
7561 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7564 LLVMValueRef res, *vals;
7566 vals = g_new0 (LLVMValueRef, nvalues);
7567 for (i = 0; i < nvalues; ++i)
7568 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7569 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7575 * mono_llvm_emit_aot_file_info:
7577 * Emit the MonoAotFileInfo structure.
7578 * Same as emit_aot_file_info () in aot-compiler.c.
7581 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7583 MonoLLVMModule *module = &aot_module;
7585 /* Save these for later */
7586 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7587 module->has_jitted_code = has_jitted_code;
7591 * mono_llvm_emit_aot_data:
7593 * Emit the binary data DATA pointed to by symbol SYMBOL.
7596 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7598 MonoLLVMModule *module = &aot_module;
7602 type = LLVMArrayType (LLVMInt8Type (), data_len);
7603 d = LLVMAddGlobal (module->lmodule, type, symbol);
7604 LLVMSetVisibility (d, LLVMHiddenVisibility);
7605 LLVMSetLinkage (d, LLVMInternalLinkage);
7606 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7607 mono_llvm_set_is_constant (d);
7610 /* Add a reference to a global defined in JITted code */
7612 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7617 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7618 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7624 emit_aot_file_info (MonoLLVMModule *module)
7626 LLVMTypeRef file_info_type;
7627 LLVMTypeRef *eltypes, eltype;
7628 LLVMValueRef info_var;
7629 LLVMValueRef *fields;
7630 int i, nfields, tindex;
7631 MonoAotFileInfo *info;
7632 LLVMModuleRef lmodule = module->lmodule;
7634 info = &module->aot_info;
7636 /* Create an LLVM type to represent MonoAotFileInfo */
7637 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7638 eltypes = g_new (LLVMTypeRef, nfields);
7640 eltypes [tindex ++] = LLVMInt32Type ();
7641 eltypes [tindex ++] = LLVMInt32Type ();
7643 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7644 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7646 for (i = 0; i < 15; ++i)
7647 eltypes [tindex ++] = LLVMInt32Type ();
7649 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7650 for (i = 0; i < 4; ++i)
7651 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7652 g_assert (tindex == nfields);
7653 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7654 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7656 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7657 if (module->static_link) {
7658 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7659 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7661 fields = g_new (LLVMValueRef, nfields);
7663 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7664 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7668 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7669 * for symbols defined in the .s file emitted by the aot compiler.
7671 eltype = eltypes [tindex];
7672 if (module->llvm_only)
7673 fields [tindex ++] = LLVMConstNull (eltype);
7675 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7676 fields [tindex ++] = module->got_var;
7677 /* llc defines this directly */
7678 if (!module->llvm_only) {
7679 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7680 fields [tindex ++] = LLVMConstNull (eltype);
7681 fields [tindex ++] = LLVMConstNull (eltype);
7683 fields [tindex ++] = LLVMConstNull (eltype);
7684 fields [tindex ++] = module->get_method;
7685 fields [tindex ++] = module->get_unbox_tramp;
7687 if (module->has_jitted_code) {
7688 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7689 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7691 fields [tindex ++] = LLVMConstNull (eltype);
7692 fields [tindex ++] = LLVMConstNull (eltype);
7694 if (!module->llvm_only)
7695 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7697 fields [tindex ++] = LLVMConstNull (eltype);
7698 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7699 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7700 fields [tindex ++] = LLVMConstNull (eltype);
7702 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7703 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7704 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7705 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7706 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7707 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7708 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7709 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7710 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7711 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7713 /* Not needed (mem_end) */
7714 fields [tindex ++] = LLVMConstNull (eltype);
7715 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7716 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7717 if (info->trampoline_size [0]) {
7718 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7719 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7720 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7721 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7723 fields [tindex ++] = LLVMConstNull (eltype);
7724 fields [tindex ++] = LLVMConstNull (eltype);
7725 fields [tindex ++] = LLVMConstNull (eltype);
7726 fields [tindex ++] = LLVMConstNull (eltype);
7728 if (module->static_link && !module->llvm_only)
7729 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7731 fields [tindex ++] = LLVMConstNull (eltype);
7732 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7733 if (!module->llvm_only) {
7734 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7735 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7736 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7737 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7738 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7739 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7741 fields [tindex ++] = LLVMConstNull (eltype);
7742 fields [tindex ++] = LLVMConstNull (eltype);
7743 fields [tindex ++] = LLVMConstNull (eltype);
7744 fields [tindex ++] = LLVMConstNull (eltype);
7745 fields [tindex ++] = LLVMConstNull (eltype);
7746 fields [tindex ++] = LLVMConstNull (eltype);
7749 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7750 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7753 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7754 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7755 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7756 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7757 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7758 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7759 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7760 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7761 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7762 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7763 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7764 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7765 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7766 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7767 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7769 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7770 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7771 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7772 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7773 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7774 g_assert (tindex == nfields);
7776 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7778 if (module->static_link) {
7782 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7783 /* Get rid of characters which cannot occur in symbols */
7785 for (p = s; *p; ++p) {
7786 if (!(isalnum (*p) || *p == '_'))
7789 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7791 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7792 LLVMSetLinkage (var, LLVMExternalLinkage);
7797 * Emit the aot module into the LLVM bitcode file FILENAME.
7800 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7802 LLVMTypeRef got_type, inited_type;
7803 LLVMValueRef real_got, real_inited;
7804 MonoLLVMModule *module = &aot_module;
7806 emit_llvm_code_end (module);
7809 * Create the real got variable and replace all uses of the dummy variable with
7812 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7813 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7814 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7815 if (module->external_symbols) {
7816 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7817 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7819 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7821 mono_llvm_replace_uses_of (module->got_var, real_got);
7823 mark_as_used (&aot_module, real_got);
7825 /* Delete the dummy got so it doesn't become a global */
7826 LLVMDeleteGlobal (module->got_var);
7827 module->got_var = real_got;
7830 * Same for the init_var
7832 if (module->llvm_only) {
7833 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7834 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7835 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7836 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7837 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7838 LLVMDeleteGlobal (module->inited_var);
7841 if (module->llvm_only) {
7842 emit_get_method (&aot_module);
7843 emit_get_unbox_tramp (&aot_module);
7846 emit_llvm_used (&aot_module);
7847 emit_dbg_info (&aot_module, filename, cu_name);
7848 emit_aot_file_info (&aot_module);
7851 * Replace GOT entries for directly callable methods with the methods themselves.
7852 * It would be easier to implement this by predefining all methods before compiling
7853 * their bodies, but that couldn't handle the case when a method fails to compile
7856 if (module->llvm_only) {
7857 GHashTableIter iter;
7859 GSList *callers, *l;
7861 g_hash_table_iter_init (&iter, module->method_to_callers);
7862 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7863 LLVMValueRef lmethod;
7865 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
7867 for (l = callers; l; l = l->next) {
7868 LLVMValueRef caller = (LLVMValueRef)l->data;
7870 mono_llvm_replace_uses_of (caller, lmethod);
7876 /* Replace PLT entries for directly callable methods with the methods themselves */
7878 GHashTableIter iter;
7880 LLVMValueRef callee;
7882 g_hash_table_iter_init (&iter, module->plt_entries_ji);
7883 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
7884 if (mono_aot_is_direct_callable (ji)) {
7885 LLVMValueRef lmethod;
7887 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
7888 /* The types might not match because the caller might pass an rgctx */
7889 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
7890 mono_llvm_replace_uses_of (callee, lmethod);
7891 mono_aot_mark_unused_llvm_plt_entry (ji);
7901 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
7902 g_assert_not_reached ();
7907 LLVMWriteBitcodeToFile (module->lmodule, filename);
7912 md_string (const char *s)
7914 return LLVMMDString (s, strlen (s));
7917 /* Debugging support */
7920 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
7922 LLVMModuleRef lmodule = module->lmodule;
7923 LLVMValueRef args [16], cu_args [16], cu, ver;
7925 char *build_info, *s, *dir;
7928 * This can only be enabled when LLVM code is emitted into a separate object
7929 * file, since the AOT compiler also emits dwarf info,
7930 * and the abbrev indexes will not be correct since llvm has added its own
7933 if (!module->emit_dwarf)
7937 * Emit dwarf info in the form of LLVM metadata. There is some
7938 * out-of-date documentation at:
7939 * http://llvm.org/docs/SourceLevelDebugging.html
7940 * but most of this was gathered from the llvm and
7945 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
7946 /* CU name/compilation dir */
7947 dir = g_path_get_dirname (filename);
7948 args [0] = LLVMMDString (cu_name, strlen (cu_name));
7949 args [1] = LLVMMDString (dir, strlen (dir));
7950 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
7953 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
7955 build_info = mono_get_runtime_build_info ();
7956 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
7957 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
7958 g_free (build_info);
7960 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7962 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7963 /* Runtime version */
7964 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7966 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7967 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7969 if (module->subprogram_mds) {
7973 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
7974 for (i = 0; i < module->subprogram_mds->len; ++i)
7975 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
7976 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
7978 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7981 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7982 /* Imported modules */
7983 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7985 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7986 /* DebugEmissionKind = FullDebug */
7987 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7988 cu = LLVMMDNode (cu_args, n_cuargs);
7989 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
7991 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7992 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
7993 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
7994 ver = LLVMMDNode (args, 3);
7995 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
7997 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7998 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
7999 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8000 ver = LLVMMDNode (args, 3);
8001 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8005 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8007 MonoLLVMModule *module = ctx->module;
8008 MonoDebugMethodInfo *minfo = ctx->minfo;
8009 char *source_file, *dir, *filename;
8010 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8011 MonoSymSeqPoint *sym_seq_points;
8017 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8019 source_file = g_strdup ("<unknown>");
8020 dir = g_path_get_dirname (source_file);
8021 filename = g_path_get_basename (source_file);
8023 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8024 args [0] = md_string (filename);
8025 args [1] = md_string (dir);
8026 ctx_args [1] = LLVMMDNode (args, 2);
8027 ctx_md = LLVMMDNode (ctx_args, 2);
8029 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8030 type_args [1] = NULL;
8031 type_args [2] = NULL;
8032 type_args [3] = LLVMMDString ("", 0);
8033 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8034 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8035 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8036 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8037 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8038 type_args [9] = NULL;
8039 type_args [10] = NULL;
8040 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8041 type_args [12] = NULL;
8042 type_args [13] = NULL;
8043 type_args [14] = NULL;
8044 type_md = LLVMMDNode (type_args, 14);
8046 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8047 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8048 /* Source directory + file pair */
8049 args [0] = md_string (filename);
8050 args [1] = md_string (dir);
8051 md_args [1] = LLVMMDNode (args ,2);
8052 md_args [2] = ctx_md;
8053 md_args [3] = md_string (cfg->method->name);
8054 md_args [4] = md_string (name);
8055 md_args [5] = md_string (name);
8058 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8060 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8062 md_args [7] = type_md;
8064 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8066 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8068 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8069 /* Index into a virtual function */
8070 md_args [11] = NULL;
8071 md_args [12] = NULL;
8073 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8075 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8076 /* Pointer to LLVM function */
8077 md_args [15] = method;
8078 /* Function template parameter */
8079 md_args [16] = NULL;
8080 /* Function declaration descriptor */
8081 md_args [17] = NULL;
8082 /* List of function variables */
8083 md_args [18] = LLVMMDNode (args, 0);
8085 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8086 md = LLVMMDNode (md_args, 20);
8088 if (!module->subprogram_mds)
8089 module->subprogram_mds = g_ptr_array_new ();
8090 g_ptr_array_add (module->subprogram_mds, md);
8094 g_free (source_file);
8095 g_free (sym_seq_points);
8101 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8103 MonoCompile *cfg = ctx->cfg;
8105 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8106 MonoDebugSourceLocation *loc;
8107 LLVMValueRef loc_md, md_args [16];
8110 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8114 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8115 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8116 md_args [nmd_args ++] = ctx->dbg_md;
8117 md_args [nmd_args ++] = NULL;
8118 loc_md = LLVMMDNode (md_args, nmd_args);
8119 LLVMSetCurrentDebugLocation (builder, loc_md);
8120 mono_debug_symfile_free_location (loc);
8126 default_mono_llvm_unhandled_exception (void)
8128 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8129 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8131 mono_unhandled_exception (target);
8132 exit (mono_environment_exitcode_get ());
8137 - Emit LLVM IR from the mono IR using the LLVM C API.
8138 - The original arch specific code remains, so we can fall back to it if we run
8139 into something we can't handle.
8143 A partial list of issues:
8144 - Handling of opcodes which can throw exceptions.
8146 In the mono JIT, these are implemented using code like this:
8153 push throw_pos - method
8154 call <exception trampoline>
8156 The problematic part is push throw_pos - method, which cannot be represented
8157 in the LLVM IR, since it does not support label values.
8158 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8159 be implemented in JIT mode ?
8160 -> a possible but slower implementation would use the normal exception
8161 throwing code but it would need to control the placement of the throw code
8162 (it needs to be exactly after the compare+branch).
8163 -> perhaps add a PC offset intrinsics ?
8165 - efficient implementation of .ovf opcodes.
8167 These are currently implemented as:
8168 <ins which sets the condition codes>
8171 Some overflow opcodes are now supported by LLVM SVN.
8173 - exception handling, unwinding.
8174 - SSA is disabled for methods with exception handlers
8175 - How to obtain unwind info for LLVM compiled methods ?
8176 -> this is now solved by converting the unwind info generated by LLVM
8178 - LLVM uses the c++ exception handling framework, while we use our home grown
8179 code, and couldn't use the c++ one:
8180 - its not supported under VC++, other exotic platforms.
8181 - it might be impossible to support filter clauses with it.
8185 The trampolines need a predictable call sequence, since they need to disasm
8186 the calling code to obtain register numbers / offsets.
8188 LLVM currently generates this code in non-JIT mode:
8189 mov -0x98(%rax),%eax
8191 Here, the vtable pointer is lost.
8192 -> solution: use one vtable trampoline per class.
8194 - passing/receiving the IMT pointer/RGCTX.
8195 -> solution: pass them as normal arguments ?
8199 LLVM does not allow the specification of argument registers etc. This means
8200 that all calls are made according to the platform ABI.
8202 - passing/receiving vtypes.
8204 Vtypes passed/received in registers are handled by the front end by using
8205 a signature with scalar arguments, and loading the parts of the vtype into those
8208 Vtypes passed on the stack are handled using the 'byval' attribute.
8212 Supported though alloca, we need to emit the load/store code.
8216 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8217 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8218 This is made easier because the IR is already in SSA form.
8219 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8220 types are frequently used incorrectly.
8225 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8226 it with the file containing the methods emitted by the JIT and the AOT data
8230 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8231 * - each bblock should end with a branch
8232 * - setting the return value, making cfg->ret non-volatile
8233 * - avoid some transformations in the JIT which make it harder for us to generate
8235 * - use pointer types to help optimizations.