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)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #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."
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
54 LLVMModuleRef lmodule;
55 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
56 GHashTable *llvm_types;
58 const char *got_symbol;
59 const char *get_method_symbol;
60 const char *get_unbox_tramp_symbol;
61 GHashTable *plt_entries;
62 GHashTable *plt_entries_ji;
63 GHashTable *method_to_lmethod;
64 GHashTable *direct_callables;
69 GPtrArray *subprogram_mds;
71 LLVMExecutionEngineRef ee;
72 gboolean external_symbols;
75 LLVMValueRef personality;
78 MonoAssembly *assembly;
80 MonoAotFileInfo aot_info;
81 const char *jit_got_symbol;
82 const char *eh_frame_symbol;
83 LLVMValueRef get_method, get_unbox_tramp;
84 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
85 LLVMValueRef code_start, code_end;
86 LLVMValueRef inited_var;
87 int max_inited_idx, max_method_idx;
88 gboolean has_jitted_code;
91 GHashTable *idx_to_lmethod;
92 GHashTable *idx_to_unbox_tramp;
93 /* Maps a MonoMethod to LLVM instructions representing it */
94 GHashTable *method_to_callers;
95 LLVMContextRef context;
96 LLVMValueRef sentinel_exception;
97 void *di_builder, *cu;
98 GHashTable *objc_selector_to_var;
102 * Information associated by the backend with mono basic blocks.
105 LLVMBasicBlockRef bblock, end_bblock;
106 LLVMValueRef finally_ind;
107 gboolean added, invoke_target;
109 * If this bblock is the start of a finally clause, this is a list of bblocks it
110 * needs to branch to in ENDFINALLY.
112 GSList *call_handler_return_bbs;
114 * If this bblock is the start of a finally clause, this is the bblock that
115 * CALL_HANDLER needs to branch to.
117 LLVMBasicBlockRef call_handler_target_bb;
118 /* The list of switch statements generated by ENDFINALLY instructions */
119 GSList *endfinally_switch_ins_list;
124 * Structure containing emit state
127 MonoMemPool *mempool;
129 /* Maps method names to the corresponding LLVMValueRef */
130 GHashTable *emitted_method_decls;
133 LLVMValueRef lmethod;
134 MonoLLVMModule *module;
135 LLVMModuleRef lmodule;
137 int sindex, default_index, ex_index;
138 LLVMBuilderRef builder;
139 LLVMValueRef *values, *addresses;
140 MonoType **vreg_cli_types;
142 MonoMethodSignature *sig;
144 GHashTable *region_to_handler;
145 GHashTable *clause_to_handler;
146 LLVMBuilderRef alloca_builder;
147 LLVMValueRef last_alloca;
148 LLVMValueRef rgctx_arg;
149 LLVMValueRef this_arg;
150 LLVMTypeRef *vreg_types;
152 LLVMTypeRef method_type;
153 LLVMBasicBlockRef init_bb, inited_bb;
155 gboolean *unreachable;
157 gboolean has_got_access;
158 gboolean is_linkonce;
159 int this_arg_pindex, rgctx_arg_pindex;
160 LLVMValueRef imt_rgctx_loc;
161 GHashTable *llvm_types;
163 MonoDebugMethodInfo *minfo;
165 /* For every clause, the clauses it is nested in */
168 GHashTable *exc_meta;
169 GHashTable *method_to_callers;
170 GPtrArray *phi_values;
171 GPtrArray *bblock_list;
173 GHashTable *jit_callees;
174 LLVMValueRef long_bb_break_var;
180 MonoBasicBlock *in_bb;
185 * Instruction metadata
186 * This is the same as ins_info, but LREG != IREG.
194 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
195 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
202 /* keep in sync with the enum in mini.h */
205 #include "mini-ops.h"
210 #if SIZEOF_VOID_P == 4
211 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
213 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
216 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
219 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
221 #define TRACE_FAILURE(msg)
225 #define IS_TARGET_X86 1
227 #define IS_TARGET_X86 0
231 #define IS_TARGET_AMD64 1
233 #define IS_TARGET_AMD64 0
236 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
238 static LLVMIntPredicate cond_to_llvm_cond [] = {
251 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
264 static MonoNativeTlsKey current_cfg_tls_id;
266 static MonoLLVMModule aot_module;
268 static GHashTable *intrins_id_to_name;
269 static GHashTable *intrins_name_to_id;
271 static void init_jit_module (MonoDomain *domain);
273 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
274 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
275 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
276 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
277 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
278 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
281 set_failure (EmitContext *ctx, const char *message)
283 TRACE_FAILURE (reason);
284 ctx->cfg->exception_message = g_strdup (message);
285 ctx->cfg->disable_llvm = TRUE;
291 * The LLVM type with width == sizeof (gpointer)
296 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
302 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
308 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
314 * Return the size of the LLVM representation of the vtype T.
317 get_vtype_size (MonoType *t)
321 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
323 /* LLVMArgAsIArgs depends on this since it stores whole words */
324 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
331 * simd_class_to_llvm_type:
333 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
336 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
338 if (!strcmp (klass->name, "Vector2d")) {
339 return LLVMVectorType (LLVMDoubleType (), 2);
340 } else if (!strcmp (klass->name, "Vector2l")) {
341 return LLVMVectorType (LLVMInt64Type (), 2);
342 } else if (!strcmp (klass->name, "Vector2ul")) {
343 return LLVMVectorType (LLVMInt64Type (), 2);
344 } else if (!strcmp (klass->name, "Vector4i")) {
345 return LLVMVectorType (LLVMInt32Type (), 4);
346 } else if (!strcmp (klass->name, "Vector4ui")) {
347 return LLVMVectorType (LLVMInt32Type (), 4);
348 } else if (!strcmp (klass->name, "Vector4f")) {
349 return LLVMVectorType (LLVMFloatType (), 4);
350 } else if (!strcmp (klass->name, "Vector8s")) {
351 return LLVMVectorType (LLVMInt16Type (), 8);
352 } else if (!strcmp (klass->name, "Vector8us")) {
353 return LLVMVectorType (LLVMInt16Type (), 8);
354 } else if (!strcmp (klass->name, "Vector16sb")) {
355 return LLVMVectorType (LLVMInt8Type (), 16);
356 } else if (!strcmp (klass->name, "Vector16b")) {
357 return LLVMVectorType (LLVMInt8Type (), 16);
359 printf ("%s\n", klass->name);
365 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
366 static inline G_GNUC_UNUSED LLVMTypeRef
367 type_to_simd_type (int type)
371 return LLVMVectorType (LLVMInt8Type (), 16);
373 return LLVMVectorType (LLVMInt16Type (), 8);
375 return LLVMVectorType (LLVMInt32Type (), 4);
377 return LLVMVectorType (LLVMInt64Type (), 2);
379 return LLVMVectorType (LLVMDoubleType (), 2);
381 return LLVMVectorType (LLVMFloatType (), 4);
383 g_assert_not_reached ();
389 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
391 int i, size, nfields, esize;
392 LLVMTypeRef *eltypes;
397 t = &klass->byval_arg;
399 if (mini_type_is_hfa (t, &nfields, &esize)) {
401 * This is needed on arm64 where HFAs are returned in
405 eltypes = g_new (LLVMTypeRef, size);
406 for (i = 0; i < size; ++i)
407 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
409 size = get_vtype_size (t);
411 eltypes = g_new (LLVMTypeRef, size);
412 for (i = 0; i < size; ++i)
413 eltypes [i] = LLVMInt8Type ();
416 name = mono_type_full_name (&klass->byval_arg);
417 ltype = LLVMStructCreateNamed (module->context, name);
418 LLVMStructSetBody (ltype, eltypes, size, FALSE);
428 * Return the LLVM type corresponding to T.
431 type_to_llvm_type (EmitContext *ctx, MonoType *t)
433 t = mini_get_underlying_type (t);
437 return LLVMVoidType ();
439 return LLVMInt8Type ();
441 return LLVMInt16Type ();
443 return LLVMInt32Type ();
445 return LLVMInt8Type ();
447 return LLVMInt16Type ();
449 return LLVMInt32Type ();
450 case MONO_TYPE_BOOLEAN:
451 return LLVMInt8Type ();
454 return LLVMInt64Type ();
456 return LLVMInt16Type ();
458 return LLVMFloatType ();
460 return LLVMDoubleType ();
463 return IntPtrType ();
464 case MONO_TYPE_OBJECT:
465 case MONO_TYPE_CLASS:
466 case MONO_TYPE_ARRAY:
467 case MONO_TYPE_SZARRAY:
468 case MONO_TYPE_STRING:
470 return ObjRefType ();
473 /* Because of generic sharing */
474 return ObjRefType ();
475 case MONO_TYPE_GENERICINST:
476 if (!mono_type_generic_inst_is_valuetype (t))
477 return ObjRefType ();
479 case MONO_TYPE_VALUETYPE:
480 case MONO_TYPE_TYPEDBYREF: {
484 klass = mono_class_from_mono_type (t);
486 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
487 return simd_class_to_llvm_type (ctx, klass);
490 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
492 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
494 ltype = create_llvm_type_for_type (ctx->module, klass);
495 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
501 printf ("X: %d\n", t->type);
502 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
503 ctx->cfg->disable_llvm = TRUE;
511 * Return whenever T is an unsigned int type.
514 type_is_unsigned (EmitContext *ctx, MonoType *t)
516 t = mini_get_underlying_type (t);
532 * type_to_llvm_arg_type:
534 * Same as type_to_llvm_type, but treat i8/i16 as i32.
537 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
539 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
541 if (ctx->cfg->llvm_only)
545 * This works on all abis except arm64/ios which passes multiple
546 * arguments in one stack slot.
549 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
551 * LLVM generates code which only sets the lower bits, while JITted
552 * code expects all the bits to be set.
554 ptype = LLVMInt32Type ();
562 * llvm_type_to_stack_type:
564 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
567 static G_GNUC_UNUSED LLVMTypeRef
568 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
572 if (type == LLVMInt8Type ())
573 return LLVMInt32Type ();
574 else if (type == LLVMInt16Type ())
575 return LLVMInt32Type ();
576 else if (!cfg->r4fp && type == LLVMFloatType ())
577 return LLVMDoubleType ();
583 * regtype_to_llvm_type:
585 * Return the LLVM type corresponding to the regtype C used in instruction
589 regtype_to_llvm_type (char c)
593 return LLVMInt32Type ();
595 return LLVMInt64Type ();
597 return LLVMDoubleType ();
606 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
609 op_to_llvm_type (int opcode)
614 return LLVMInt8Type ();
617 return LLVMInt8Type ();
620 return LLVMInt16Type ();
623 return LLVMInt16Type ();
626 return LLVMInt32Type ();
629 return LLVMInt32Type ();
631 return LLVMInt64Type ();
633 return LLVMFloatType ();
635 return LLVMDoubleType ();
637 return LLVMInt64Type ();
639 return LLVMInt32Type ();
641 return LLVMInt64Type ();
646 return LLVMInt8Type ();
651 return LLVMInt16Type ();
653 return LLVMInt32Type ();
656 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
663 return LLVMInt32Type ();
670 return LLVMInt64Type ();
672 printf ("%s\n", mono_inst_name (opcode));
673 g_assert_not_reached ();
678 #define CLAUSE_START(clause) ((clause)->try_offset)
679 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
682 * load_store_to_llvm_type:
684 * Return the size/sign/zero extension corresponding to the load/store opcode
688 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
694 case OP_LOADI1_MEMBASE:
695 case OP_STOREI1_MEMBASE_REG:
696 case OP_STOREI1_MEMBASE_IMM:
697 case OP_ATOMIC_LOAD_I1:
698 case OP_ATOMIC_STORE_I1:
701 return LLVMInt8Type ();
702 case OP_LOADU1_MEMBASE:
704 case OP_ATOMIC_LOAD_U1:
705 case OP_ATOMIC_STORE_U1:
708 return LLVMInt8Type ();
709 case OP_LOADI2_MEMBASE:
710 case OP_STOREI2_MEMBASE_REG:
711 case OP_STOREI2_MEMBASE_IMM:
712 case OP_ATOMIC_LOAD_I2:
713 case OP_ATOMIC_STORE_I2:
716 return LLVMInt16Type ();
717 case OP_LOADU2_MEMBASE:
719 case OP_ATOMIC_LOAD_U2:
720 case OP_ATOMIC_STORE_U2:
723 return LLVMInt16Type ();
724 case OP_LOADI4_MEMBASE:
725 case OP_LOADU4_MEMBASE:
728 case OP_STOREI4_MEMBASE_REG:
729 case OP_STOREI4_MEMBASE_IMM:
730 case OP_ATOMIC_LOAD_I4:
731 case OP_ATOMIC_STORE_I4:
732 case OP_ATOMIC_LOAD_U4:
733 case OP_ATOMIC_STORE_U4:
735 return LLVMInt32Type ();
736 case OP_LOADI8_MEMBASE:
738 case OP_STOREI8_MEMBASE_REG:
739 case OP_STOREI8_MEMBASE_IMM:
740 case OP_ATOMIC_LOAD_I8:
741 case OP_ATOMIC_STORE_I8:
742 case OP_ATOMIC_LOAD_U8:
743 case OP_ATOMIC_STORE_U8:
745 return LLVMInt64Type ();
746 case OP_LOADR4_MEMBASE:
747 case OP_STORER4_MEMBASE_REG:
748 case OP_ATOMIC_LOAD_R4:
749 case OP_ATOMIC_STORE_R4:
751 return LLVMFloatType ();
752 case OP_LOADR8_MEMBASE:
753 case OP_STORER8_MEMBASE_REG:
754 case OP_ATOMIC_LOAD_R8:
755 case OP_ATOMIC_STORE_R8:
757 return LLVMDoubleType ();
758 case OP_LOAD_MEMBASE:
760 case OP_STORE_MEMBASE_REG:
761 case OP_STORE_MEMBASE_IMM:
762 *size = sizeof (gpointer);
763 return IntPtrType ();
765 g_assert_not_reached ();
773 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
776 ovf_op_to_intrins (int opcode)
780 return "llvm.sadd.with.overflow.i32";
782 return "llvm.uadd.with.overflow.i32";
784 return "llvm.ssub.with.overflow.i32";
786 return "llvm.usub.with.overflow.i32";
788 return "llvm.smul.with.overflow.i32";
790 return "llvm.umul.with.overflow.i32";
792 return "llvm.sadd.with.overflow.i64";
794 return "llvm.uadd.with.overflow.i64";
796 return "llvm.ssub.with.overflow.i64";
798 return "llvm.usub.with.overflow.i64";
800 return "llvm.smul.with.overflow.i64";
802 return "llvm.umul.with.overflow.i64";
804 g_assert_not_reached ();
810 simd_op_to_intrins (int opcode)
813 #if defined(TARGET_X86) || defined(TARGET_AMD64)
815 return "llvm.x86.sse2.min.pd";
817 return "llvm.x86.sse.min.ps";
819 return "llvm.x86.sse2.max.pd";
821 return "llvm.x86.sse.max.ps";
823 return "llvm.x86.sse3.hadd.pd";
825 return "llvm.x86.sse3.hadd.ps";
827 return "llvm.x86.sse3.hsub.pd";
829 return "llvm.x86.sse3.hsub.ps";
831 return "llvm.x86.sse3.addsub.ps";
833 return "llvm.x86.sse3.addsub.pd";
834 case OP_EXTRACT_MASK:
835 return "llvm.x86.sse2.pmovmskb.128";
838 return "llvm.x86.sse2.psrli.w";
841 return "llvm.x86.sse2.psrli.d";
844 return "llvm.x86.sse2.psrli.q";
847 return "llvm.x86.sse2.pslli.w";
850 return "llvm.x86.sse2.pslli.d";
853 return "llvm.x86.sse2.pslli.q";
856 return "llvm.x86.sse2.psrai.w";
859 return "llvm.x86.sse2.psrai.d";
861 return "llvm.x86.sse2.padds.b";
863 return "llvm.x86.sse2.padds.w";
865 return "llvm.x86.sse2.psubs.b";
867 return "llvm.x86.sse2.psubs.w";
868 case OP_PADDB_SAT_UN:
869 return "llvm.x86.sse2.paddus.b";
870 case OP_PADDW_SAT_UN:
871 return "llvm.x86.sse2.paddus.w";
872 case OP_PSUBB_SAT_UN:
873 return "llvm.x86.sse2.psubus.b";
874 case OP_PSUBW_SAT_UN:
875 return "llvm.x86.sse2.psubus.w";
877 return "llvm.x86.sse2.pavg.b";
879 return "llvm.x86.sse2.pavg.w";
881 return "llvm.x86.sse.sqrt.ps";
883 return "llvm.x86.sse2.sqrt.pd";
885 return "llvm.x86.sse.rsqrt.ps";
887 return "llvm.x86.sse.rcp.ps";
889 return "llvm.x86.sse2.cvtdq2pd";
891 return "llvm.x86.sse2.cvtdq2ps";
893 return "llvm.x86.sse2.cvtpd2dq";
895 return "llvm.x86.sse2.cvtps2dq";
897 return "llvm.x86.sse2.cvtpd2ps";
899 return "llvm.x86.sse2.cvtps2pd";
901 return "llvm.x86.sse2.cvttpd2dq";
903 return "llvm.x86.sse2.cvttps2dq";
905 return "llvm.x86.sse2.packsswb.128";
907 return "llvm.x86.sse2.packssdw.128";
909 return "llvm.x86.sse2.packuswb.128";
911 return "llvm.x86.sse41.packusdw";
913 return "llvm.x86.sse2.pmulh.w";
914 case OP_PMULW_HIGH_UN:
915 return "llvm.x86.sse2.pmulhu.w";
918 g_assert_not_reached ();
924 simd_op_to_llvm_type (int opcode)
926 #if defined(TARGET_X86) || defined(TARGET_AMD64)
930 return type_to_simd_type (MONO_TYPE_R8);
933 return type_to_simd_type (MONO_TYPE_I8);
936 return type_to_simd_type (MONO_TYPE_I4);
941 return type_to_simd_type (MONO_TYPE_I2);
945 return type_to_simd_type (MONO_TYPE_I1);
947 return type_to_simd_type (MONO_TYPE_R4);
950 return type_to_simd_type (MONO_TYPE_I4);
954 return type_to_simd_type (MONO_TYPE_R8);
958 return type_to_simd_type (MONO_TYPE_R4);
959 case OP_EXTRACT_MASK:
960 return type_to_simd_type (MONO_TYPE_I1);
966 return type_to_simd_type (MONO_TYPE_R4);
969 return type_to_simd_type (MONO_TYPE_R8);
971 g_assert_not_reached ();
982 * Return the LLVM basic block corresponding to BB.
984 static LLVMBasicBlockRef
985 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
987 char bb_name_buf [128];
990 if (ctx->bblocks [bb->block_num].bblock == NULL) {
991 if (bb->flags & BB_EXCEPTION_HANDLER) {
992 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
993 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
994 bb_name = bb_name_buf;
995 } else if (bb->block_num < 256) {
996 if (!ctx->module->bb_names) {
997 ctx->module->bb_names_len = 256;
998 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1000 if (!ctx->module->bb_names [bb->block_num]) {
1003 n = g_strdup_printf ("BB%d", bb->block_num);
1004 mono_memory_barrier ();
1005 ctx->module->bb_names [bb->block_num] = n;
1007 bb_name = ctx->module->bb_names [bb->block_num];
1009 sprintf (bb_name_buf, "BB%d", bb->block_num);
1010 bb_name = bb_name_buf;
1013 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1014 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1017 return ctx->bblocks [bb->block_num].bblock;
1023 * Return the last LLVM bblock corresponding to BB.
1024 * This might not be equal to the bb returned by get_bb () since we need to generate
1025 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1027 static LLVMBasicBlockRef
1028 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1031 return ctx->bblocks [bb->block_num].end_bblock;
1034 static LLVMBasicBlockRef
1035 gen_bb (EmitContext *ctx, const char *prefix)
1039 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1040 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1046 * Return the target of the patch identified by TYPE and TARGET.
1049 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1055 memset (&ji, 0, sizeof (ji));
1057 ji.data.target = target;
1059 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1060 mono_error_assert_ok (&error);
1068 * Emit code to convert the LLVM value V to DTYPE.
1071 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1073 LLVMTypeRef stype = LLVMTypeOf (v);
1075 if (stype != dtype) {
1076 gboolean ext = FALSE;
1079 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1081 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1083 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1087 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1089 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1090 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1093 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1094 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1095 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1096 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1097 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1098 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1099 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1100 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1102 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1103 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1104 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1105 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1106 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1107 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1109 if (mono_arch_is_soft_float ()) {
1110 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1111 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1112 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1113 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1116 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1117 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1120 LLVMDumpValue (LLVMConstNull (dtype));
1121 g_assert_not_reached ();
1129 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1131 return convert_full (ctx, v, dtype, FALSE);
1135 * emit_volatile_load:
1137 * If vreg is volatile, emit a load from its address.
1140 emit_volatile_load (EmitContext *ctx, int vreg)
1146 // FIXME: This hack is required because we pass the rgctx in a callee saved
1147 // register on arm64 (x15), and llvm might keep the value in that register
1148 // even through the register is marked as 'reserved' inside llvm.
1149 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1150 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1152 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1154 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1156 t = ctx->vreg_cli_types [vreg];
1157 if (t && !t->byref) {
1159 * Might have to zero extend since llvm doesn't have
1162 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1163 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1164 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1165 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1166 else if (t->type == MONO_TYPE_U8)
1167 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1174 * emit_volatile_store:
1176 * If VREG is volatile, emit a store from its value to its address.
1179 emit_volatile_store (EmitContext *ctx, int vreg)
1181 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1183 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1184 g_assert (ctx->addresses [vreg]);
1185 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1190 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1192 LLVMTypeRef ret_type;
1193 LLVMTypeRef *param_types = NULL;
1198 rtype = mini_get_underlying_type (sig->ret);
1199 ret_type = type_to_llvm_type (ctx, rtype);
1203 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1207 param_types [pindex ++] = ThisType ();
1208 for (i = 0; i < sig->param_count; ++i)
1209 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1211 if (!ctx_ok (ctx)) {
1212 g_free (param_types);
1216 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1217 g_free (param_types);
1223 * sig_to_llvm_sig_full:
1225 * Return the LLVM signature corresponding to the mono signature SIG using the
1226 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1229 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1231 LLVMTypeRef ret_type;
1232 LLVMTypeRef *param_types = NULL;
1234 int i, j, pindex, vret_arg_pindex = 0;
1235 gboolean vretaddr = FALSE;
1239 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1241 rtype = mini_get_underlying_type (sig->ret);
1242 ret_type = type_to_llvm_type (ctx, rtype);
1246 switch (cinfo->ret.storage) {
1247 case LLVMArgVtypeInReg:
1248 /* LLVM models this by returning an aggregate value */
1249 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1250 LLVMTypeRef members [2];
1252 members [0] = IntPtrType ();
1253 ret_type = LLVMStructType (members, 1, FALSE);
1254 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1256 ret_type = LLVMVoidType ();
1257 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1258 LLVMTypeRef members [2];
1260 members [0] = IntPtrType ();
1261 members [1] = IntPtrType ();
1262 ret_type = LLVMStructType (members, 2, FALSE);
1264 g_assert_not_reached ();
1267 case LLVMArgVtypeByVal:
1268 /* Vtype returned normally by val */
1270 case LLVMArgVtypeAsScalar: {
1271 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1272 /* LLVM models this by returning an int */
1273 if (size < SIZEOF_VOID_P) {
1274 g_assert (cinfo->ret.nslots == 1);
1275 ret_type = LLVMIntType (size * 8);
1277 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1278 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1282 case LLVMArgAsIArgs:
1283 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1285 case LLVMArgFpStruct: {
1286 /* Vtype returned as a fp struct */
1287 LLVMTypeRef members [16];
1289 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1290 for (i = 0; i < cinfo->ret.nslots; ++i)
1291 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1292 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1295 case LLVMArgVtypeByRef:
1296 /* Vtype returned using a hidden argument */
1297 ret_type = LLVMVoidType ();
1299 case LLVMArgVtypeRetAddr:
1300 case LLVMArgGsharedvtFixed:
1301 case LLVMArgGsharedvtFixedVtype:
1302 case LLVMArgGsharedvtVariable:
1304 ret_type = LLVMVoidType ();
1310 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1312 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1314 * Has to be the first argument because of the sret argument attribute
1315 * FIXME: This might conflict with passing 'this' as the first argument, but
1316 * this is only used on arm64 which has a dedicated struct return register.
1318 cinfo->vret_arg_pindex = pindex;
1319 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1320 if (!ctx_ok (ctx)) {
1321 g_free (param_types);
1324 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1327 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1328 cinfo->rgctx_arg_pindex = pindex;
1329 param_types [pindex] = ctx->module->ptr_type;
1332 if (cinfo->imt_arg) {
1333 cinfo->imt_arg_pindex = pindex;
1334 param_types [pindex] = ctx->module->ptr_type;
1338 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1339 vret_arg_pindex = pindex;
1340 if (cinfo->vret_arg_index == 1) {
1341 /* Add the slots consumed by the first argument */
1342 LLVMArgInfo *ainfo = &cinfo->args [0];
1343 switch (ainfo->storage) {
1344 case LLVMArgVtypeInReg:
1345 for (j = 0; j < 2; ++j) {
1346 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1355 cinfo->vret_arg_pindex = vret_arg_pindex;
1358 if (vretaddr && vret_arg_pindex == pindex)
1359 param_types [pindex ++] = IntPtrType ();
1361 cinfo->this_arg_pindex = pindex;
1362 param_types [pindex ++] = ThisType ();
1363 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 for (i = 0; i < sig->param_count; ++i) {
1368 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1370 if (vretaddr && vret_arg_pindex == pindex)
1371 param_types [pindex ++] = IntPtrType ();
1372 ainfo->pindex = pindex;
1374 switch (ainfo->storage) {
1375 case LLVMArgVtypeInReg:
1376 for (j = 0; j < 2; ++j) {
1377 switch (ainfo->pair_storage [j]) {
1379 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1384 g_assert_not_reached ();
1388 case LLVMArgVtypeByVal:
1389 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1392 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1395 case LLVMArgAsIArgs:
1396 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1399 case LLVMArgVtypeByRef:
1400 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1403 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1406 case LLVMArgAsFpArgs: {
1409 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1410 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1411 param_types [pindex ++] = LLVMDoubleType ();
1412 for (j = 0; j < ainfo->nslots; ++j)
1413 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1416 case LLVMArgVtypeAsScalar:
1417 g_assert_not_reached ();
1419 case LLVMArgGsharedvtFixed:
1420 case LLVMArgGsharedvtFixedVtype:
1421 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1423 case LLVMArgGsharedvtVariable:
1424 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1427 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1431 if (!ctx_ok (ctx)) {
1432 g_free (param_types);
1435 if (vretaddr && vret_arg_pindex == pindex)
1436 param_types [pindex ++] = IntPtrType ();
1437 if (ctx->llvm_only && cinfo->rgctx_arg) {
1438 /* Pass the rgctx as the last argument */
1439 cinfo->rgctx_arg_pindex = pindex;
1440 param_types [pindex] = ctx->module->ptr_type;
1444 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1445 g_free (param_types);
1451 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1453 return sig_to_llvm_sig_full (ctx, sig, NULL);
1457 * LLVMFunctionType1:
1459 * Create an LLVM function type from the arguments.
1461 static G_GNUC_UNUSED LLVMTypeRef
1462 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1465 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1469 * LLVMFunctionType1:
1471 * Create an LLVM function type from the arguments.
1473 static G_GNUC_UNUSED LLVMTypeRef
1474 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1475 LLVMTypeRef ParamType1,
1478 LLVMTypeRef param_types [1];
1480 param_types [0] = ParamType1;
1482 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1486 * LLVMFunctionType2:
1488 * Create an LLVM function type from the arguments.
1490 static G_GNUC_UNUSED LLVMTypeRef
1491 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1492 LLVMTypeRef ParamType1,
1493 LLVMTypeRef ParamType2,
1496 LLVMTypeRef param_types [2];
1498 param_types [0] = ParamType1;
1499 param_types [1] = ParamType2;
1501 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1505 * LLVMFunctionType3:
1507 * Create an LLVM function type from the arguments.
1509 static G_GNUC_UNUSED LLVMTypeRef
1510 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1511 LLVMTypeRef ParamType1,
1512 LLVMTypeRef ParamType2,
1513 LLVMTypeRef ParamType3,
1516 LLVMTypeRef param_types [3];
1518 param_types [0] = ParamType1;
1519 param_types [1] = ParamType2;
1520 param_types [2] = ParamType3;
1522 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1525 static G_GNUC_UNUSED LLVMTypeRef
1526 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1527 LLVMTypeRef ParamType1,
1528 LLVMTypeRef ParamType2,
1529 LLVMTypeRef ParamType3,
1530 LLVMTypeRef ParamType4,
1531 LLVMTypeRef ParamType5,
1534 LLVMTypeRef param_types [5];
1536 param_types [0] = ParamType1;
1537 param_types [1] = ParamType2;
1538 param_types [2] = ParamType3;
1539 param_types [3] = ParamType4;
1540 param_types [4] = ParamType5;
1542 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1548 * Create an LLVM builder and remember it so it can be freed later.
1550 static LLVMBuilderRef
1551 create_builder (EmitContext *ctx)
1553 LLVMBuilderRef builder = LLVMCreateBuilder ();
1555 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1561 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1566 case MONO_PATCH_INFO_INTERNAL_METHOD:
1567 name = g_strdup_printf ("jit_icall_%s", data);
1569 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1570 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1571 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1575 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1583 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1587 LLVMValueRef indexes [2];
1588 LLVMValueRef got_entry_addr, load;
1589 LLVMBuilderRef builder = ctx->builder;
1594 MonoJumpInfo tmp_ji;
1596 tmp_ji.data.target = data;
1598 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1600 ji->next = cfg->patch_info;
1601 cfg->patch_info = ji;
1603 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1604 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1606 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1607 * explicitly initialize it.
1609 if (!mono_aot_is_shared_got_offset (got_offset)) {
1610 //mono_print_ji (ji);
1612 ctx->has_got_access = TRUE;
1615 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1616 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1617 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1619 name = get_aotconst_name (type, data, got_offset);
1621 load = LLVMBuildLoad (builder, got_entry_addr, "");
1622 load = convert (ctx, load, llvm_type);
1623 LLVMSetValueName (load, name ? name : "");
1625 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1628 //set_invariant_load_flag (load);
1634 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1636 return get_aotconst_typed (ctx, type, data, NULL);
1640 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1642 LLVMValueRef callee;
1644 if (ctx->llvm_only) {
1645 callee_name = mono_aot_get_direct_call_symbol (type, data);
1647 /* Directly callable */
1649 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1651 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1653 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1655 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1657 /* LLVMTypeRef's are uniqued */
1658 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1659 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1661 g_free (callee_name);
1667 * Calls are made through the GOT.
1669 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1671 MonoJumpInfo *ji = NULL;
1673 callee_name = mono_aot_get_plt_symbol (type, data);
1677 if (ctx->cfg->compile_aot)
1678 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1679 mono_add_patch_info (ctx->cfg, 0, type, data);
1682 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1684 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1686 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1688 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1691 if (ctx->cfg->compile_aot) {
1692 ji = g_new0 (MonoJumpInfo, 1);
1694 ji->data.target = data;
1696 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1704 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1706 #if LLVM_API_VERSION > 100
1707 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1708 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1709 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1710 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1713 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1714 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1720 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1722 MonoMethodHeader *header = cfg->header;
1723 MonoExceptionClause *clause;
1727 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1728 return (bb->region >> 8) - 1;
1731 for (i = 0; i < header->num_clauses; ++i) {
1732 clause = &header->clauses [i];
1734 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1741 static MonoExceptionClause *
1742 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1744 if (bb == cfg->bb_init)
1746 // Since they're sorted by nesting we just need
1747 // the first one that the bb is a member of
1748 for (int i = 0; i < cfg->header->num_clauses; i++) {
1749 MonoExceptionClause *curr = &cfg->header->clauses [i];
1751 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1759 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1761 LLVMValueRef md_arg;
1764 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1765 md_arg = LLVMMDString ("mono", 4);
1766 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1770 set_invariant_load_flag (LLVMValueRef v)
1772 LLVMValueRef md_arg;
1774 const char *flag_name;
1776 // FIXME: Cache this
1777 flag_name = "invariant.load";
1778 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1779 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1780 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1786 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1790 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1792 MonoCompile *cfg = ctx->cfg;
1793 LLVMValueRef lcall = NULL;
1794 LLVMBuilderRef builder = *builder_ref;
1795 MonoExceptionClause *clause;
1797 if (ctx->llvm_only) {
1798 clause = get_most_deep_clause (cfg, ctx, bb);
1801 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1804 * Have to use an invoke instead of a call, branching to the
1805 * handler bblock of the clause containing this bblock.
1807 intptr_t key = CLAUSE_END(clause);
1809 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1811 // FIXME: Find the one that has the lowest end bound for the right start address
1812 // FIXME: Finally + nesting
1815 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1818 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1820 builder = ctx->builder = create_builder (ctx);
1821 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1823 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1827 int clause_index = get_handler_clause (cfg, bb);
1829 if (clause_index != -1) {
1830 MonoMethodHeader *header = cfg->header;
1831 MonoExceptionClause *ec = &header->clauses [clause_index];
1832 MonoBasicBlock *tblock;
1833 LLVMBasicBlockRef ex_bb, noex_bb;
1836 * Have to use an invoke instead of a call, branching to the
1837 * handler bblock of the clause containing this bblock.
1840 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1842 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1845 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1847 ex_bb = get_bb (ctx, tblock);
1849 noex_bb = gen_bb (ctx, "NOEX_BB");
1852 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1854 builder = ctx->builder = create_builder (ctx);
1855 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1857 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1862 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1863 ctx->builder = builder;
1867 *builder_ref = ctx->builder;
1873 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1875 const char *intrins_name;
1876 LLVMValueRef args [16], res;
1877 LLVMTypeRef addr_type;
1878 gboolean use_intrinsics = TRUE;
1880 #if LLVM_API_VERSION > 100
1881 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1882 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1885 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1886 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1887 *builder_ref = ctx->builder;
1888 use_intrinsics = FALSE;
1892 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1893 LLVMAtomicOrdering ordering;
1896 case LLVM_BARRIER_NONE:
1897 ordering = LLVMAtomicOrderingNotAtomic;
1899 case LLVM_BARRIER_ACQ:
1900 ordering = LLVMAtomicOrderingAcquire;
1902 case LLVM_BARRIER_SEQ:
1903 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1906 g_assert_not_reached ();
1911 * We handle loads which can fault by calling a mono specific intrinsic
1912 * using an invoke, so they are handled properly inside try blocks.
1913 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1914 * are marked with IntrReadArgMem.
1918 intrins_name = "llvm.mono.load.i8.p0i8";
1921 intrins_name = "llvm.mono.load.i16.p0i16";
1924 intrins_name = "llvm.mono.load.i32.p0i32";
1927 intrins_name = "llvm.mono.load.i64.p0i64";
1930 g_assert_not_reached ();
1933 addr_type = LLVMTypeOf (addr);
1934 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1935 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1938 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1939 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1940 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1941 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1943 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1944 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1945 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1946 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1953 * We emit volatile loads for loads which can fault, because otherwise
1954 * LLVM will generate invalid code when encountering a load from a
1957 if (barrier != LLVM_BARRIER_NONE)
1958 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1960 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1962 /* Mark it with a custom metadata */
1965 set_metadata_flag (res, "mono.faulting.load");
1973 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1975 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
1979 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
1981 const char *intrins_name;
1982 LLVMValueRef args [16];
1983 gboolean use_intrinsics = TRUE;
1985 #if LLVM_API_VERSION > 100
1986 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1987 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1988 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1989 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1990 *builder_ref = ctx->builder;
1991 use_intrinsics = FALSE;
1995 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1996 LLVMAtomicOrdering ordering;
1999 case LLVM_BARRIER_NONE:
2000 ordering = LLVMAtomicOrderingNotAtomic;
2002 case LLVM_BARRIER_REL:
2003 ordering = LLVMAtomicOrderingRelease;
2005 case LLVM_BARRIER_SEQ:
2006 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2009 g_assert_not_reached ();
2015 intrins_name = "llvm.mono.store.i8.p0i8";
2018 intrins_name = "llvm.mono.store.i16.p0i16";
2021 intrins_name = "llvm.mono.store.i32.p0i32";
2024 intrins_name = "llvm.mono.store.i64.p0i64";
2027 g_assert_not_reached ();
2030 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2031 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2032 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2037 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2038 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2039 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2040 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2042 if (barrier != LLVM_BARRIER_NONE)
2043 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2045 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2050 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2052 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2056 * emit_cond_system_exception:
2058 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2059 * Might set the ctx exception.
2062 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2064 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2065 LLVMBuilderRef builder;
2066 MonoClass *exc_class;
2067 LLVMValueRef args [2];
2068 LLVMValueRef callee;
2069 gboolean no_pc = FALSE;
2071 if (IS_TARGET_AMD64)
2072 /* Some platforms don't require the pc argument */
2075 ex_bb = gen_bb (ctx, "EX_BB");
2077 ex2_bb = gen_bb (ctx, "EX2_BB");
2078 noex_bb = gen_bb (ctx, "NOEX_BB");
2080 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2082 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2084 /* Emit exception throwing code */
2085 ctx->builder = builder = create_builder (ctx);
2086 LLVMPositionBuilderAtEnd (builder, ex_bb);
2088 if (ctx->cfg->llvm_only) {
2089 static LLVMTypeRef sig;
2092 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2093 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2095 LLVMBuildBr (builder, ex2_bb);
2097 ctx->builder = builder = create_builder (ctx);
2098 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2100 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2101 emit_call (ctx, bb, &builder, callee, args, 1);
2102 LLVMBuildUnreachable (builder);
2104 ctx->builder = builder = create_builder (ctx);
2105 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2107 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2113 callee = ctx->module->throw_corlib_exception;
2116 const char *icall_name;
2119 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2121 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2122 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2124 if (ctx->cfg->compile_aot) {
2125 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2128 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2129 * - On x86, LLVM generated code doesn't push the arguments
2130 * - The trampoline takes the throw address as an arguments, not a pc offset.
2132 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2133 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2135 #if LLVM_API_VERSION > 100
2137 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2138 * added by emit_jit_callee ().
2140 ex2_bb = gen_bb (ctx, "EX2_BB");
2141 LLVMBuildBr (builder, ex2_bb);
2144 ctx->builder = builder = create_builder (ctx);
2145 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2147 mono_memory_barrier ();
2148 ctx->module->throw_corlib_exception = callee;
2153 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2156 * The LLVM mono branch contains changes so a block address can be passed as an
2157 * argument to a call.
2160 emit_call (ctx, bb, &builder, callee, args, 1);
2162 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2163 emit_call (ctx, bb, &builder, callee, args, 2);
2166 LLVMBuildUnreachable (builder);
2168 ctx->builder = builder = create_builder (ctx);
2169 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2171 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2178 * emit_args_to_vtype:
2180 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2183 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2185 int j, size, nslots;
2187 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2189 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2190 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2193 if (ainfo->storage == LLVMArgAsFpArgs)
2194 nslots = ainfo->nslots;
2198 for (j = 0; j < nslots; ++j) {
2199 LLVMValueRef index [2], addr, daddr;
2200 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2201 LLVMTypeRef part_type;
2203 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2206 if (ainfo->pair_storage [j] == LLVMArgNone)
2209 switch (ainfo->pair_storage [j]) {
2210 case LLVMArgInIReg: {
2211 part_type = LLVMIntType (part_size * 8);
2212 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2213 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2214 addr = LLVMBuildGEP (builder, address, index, 1, "");
2216 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2217 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2218 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2220 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2223 case LLVMArgInFPReg: {
2224 LLVMTypeRef arg_type;
2226 if (ainfo->esize == 8)
2227 arg_type = LLVMDoubleType ();
2229 arg_type = LLVMFloatType ();
2231 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2232 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2233 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2234 LLVMBuildStore (builder, args [j], addr);
2240 g_assert_not_reached ();
2243 size -= sizeof (gpointer);
2248 * emit_vtype_to_args:
2250 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2251 * into ARGS, and the number of arguments into NARGS.
2254 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2257 int j, size, nslots;
2258 LLVMTypeRef arg_type;
2260 size = get_vtype_size (t);
2262 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2263 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2265 if (ainfo->storage == LLVMArgAsFpArgs)
2266 nslots = ainfo->nslots;
2269 for (j = 0; j < nslots; ++j) {
2270 LLVMValueRef index [2], addr, daddr;
2271 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2273 if (ainfo->pair_storage [j] == LLVMArgNone)
2276 switch (ainfo->pair_storage [j]) {
2278 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2279 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2280 addr = LLVMBuildGEP (builder, address, index, 1, "");
2282 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2283 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2284 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2286 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2288 case LLVMArgInFPReg:
2289 if (ainfo->esize == 8)
2290 arg_type = LLVMDoubleType ();
2292 arg_type = LLVMFloatType ();
2293 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2294 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2295 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2296 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2301 g_assert_not_reached ();
2303 size -= sizeof (gpointer);
2310 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2313 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2314 * get executed every time control reaches them.
2316 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2318 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2319 return ctx->last_alloca;
2323 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2325 return build_alloca_llvm_type_name (ctx, t, align, "");
2329 build_alloca (EmitContext *ctx, MonoType *t)
2331 MonoClass *k = mono_class_from_mono_type (t);
2334 g_assert (!mini_is_gsharedvt_variable_type (t));
2336 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2339 align = mono_class_min_align (k);
2341 /* Sometimes align is not a power of 2 */
2342 while (mono_is_power_of_two (align) == -1)
2345 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2349 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2353 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2355 MonoCompile *cfg = ctx->cfg;
2356 LLVMBuilderRef builder = ctx->builder;
2357 LLVMValueRef offset, offset_var;
2358 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2359 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2363 g_assert (info_var);
2364 g_assert (locals_var);
2366 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2368 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2369 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2371 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2372 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2374 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2378 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2381 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2384 module->used = g_ptr_array_sized_new (16);
2385 g_ptr_array_add (module->used, global);
2389 emit_llvm_used (MonoLLVMModule *module)
2391 LLVMModuleRef lmodule = module->lmodule;
2392 LLVMTypeRef used_type;
2393 LLVMValueRef used, *used_elem;
2399 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2400 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2401 used_elem = g_new0 (LLVMValueRef, module->used->len);
2402 for (i = 0; i < module->used->len; ++i)
2403 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2404 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2405 LLVMSetLinkage (used, LLVMAppendingLinkage);
2406 LLVMSetSection (used, "llvm.metadata");
2412 * Emit a function mapping method indexes to their code
2415 emit_get_method (MonoLLVMModule *module)
2417 LLVMModuleRef lmodule = module->lmodule;
2418 LLVMValueRef func, switch_ins, m;
2419 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2420 LLVMBasicBlockRef *bbs;
2422 LLVMBuilderRef builder = LLVMCreateBuilder ();
2427 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2428 * but generating code seems safer.
2430 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2431 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2432 LLVMSetLinkage (func, LLVMExternalLinkage);
2433 LLVMSetVisibility (func, LLVMHiddenVisibility);
2434 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2435 module->get_method = func;
2437 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2440 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2441 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2442 * then we will have to find another solution.
2445 name = g_strdup_printf ("BB_CODE_START");
2446 code_start_bb = LLVMAppendBasicBlock (func, name);
2448 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2449 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2451 name = g_strdup_printf ("BB_CODE_END");
2452 code_end_bb = LLVMAppendBasicBlock (func, name);
2454 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2455 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2457 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2458 for (i = 0; i < module->max_method_idx + 1; ++i) {
2459 name = g_strdup_printf ("BB_%d", i);
2460 bb = LLVMAppendBasicBlock (func, name);
2464 LLVMPositionBuilderAtEnd (builder, bb);
2466 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2468 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2470 LLVMBuildRet (builder, LLVMConstNull (rtype));
2473 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2474 LLVMPositionBuilderAtEnd (builder, fail_bb);
2475 LLVMBuildRet (builder, LLVMConstNull (rtype));
2477 LLVMPositionBuilderAtEnd (builder, entry_bb);
2479 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2480 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2481 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2482 for (i = 0; i < module->max_method_idx + 1; ++i) {
2483 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2486 mark_as_used (module, func);
2488 LLVMDisposeBuilder (builder);
2492 * emit_get_unbox_tramp:
2494 * Emit a function mapping method indexes to their unbox trampoline
2497 emit_get_unbox_tramp (MonoLLVMModule *module)
2499 LLVMModuleRef lmodule = module->lmodule;
2500 LLVMValueRef func, switch_ins, m;
2501 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2502 LLVMBasicBlockRef *bbs;
2504 LLVMBuilderRef builder = LLVMCreateBuilder ();
2508 /* Similar to emit_get_method () */
2510 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2511 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2512 LLVMSetLinkage (func, LLVMExternalLinkage);
2513 LLVMSetVisibility (func, LLVMHiddenVisibility);
2514 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2515 module->get_unbox_tramp = func;
2517 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2519 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2520 for (i = 0; i < module->max_method_idx + 1; ++i) {
2521 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2525 name = g_strdup_printf ("BB_%d", i);
2526 bb = LLVMAppendBasicBlock (func, name);
2530 LLVMPositionBuilderAtEnd (builder, bb);
2532 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2535 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2536 LLVMPositionBuilderAtEnd (builder, fail_bb);
2537 LLVMBuildRet (builder, LLVMConstNull (rtype));
2539 LLVMPositionBuilderAtEnd (builder, entry_bb);
2541 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2542 for (i = 0; i < module->max_method_idx + 1; ++i) {
2543 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2547 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2550 mark_as_used (module, func);
2551 LLVMDisposeBuilder (builder);
2554 /* Add a function to mark the beginning of LLVM code */
2556 emit_llvm_code_start (MonoLLVMModule *module)
2558 LLVMModuleRef lmodule = module->lmodule;
2560 LLVMBasicBlockRef entry_bb;
2561 LLVMBuilderRef builder;
2563 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2564 LLVMSetLinkage (func, LLVMInternalLinkage);
2565 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2566 module->code_start = func;
2567 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2568 builder = LLVMCreateBuilder ();
2569 LLVMPositionBuilderAtEnd (builder, entry_bb);
2570 LLVMBuildRetVoid (builder);
2571 LLVMDisposeBuilder (builder);
2575 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2577 LLVMModuleRef lmodule = module->lmodule;
2578 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2579 LLVMBasicBlockRef entry_bb;
2580 LLVMBuilderRef builder;
2587 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2588 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2593 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2594 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2597 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2598 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2601 g_assert_not_reached ();
2603 LLVMSetLinkage (func, LLVMInternalLinkage);
2604 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2605 mono_llvm_set_preserveall_cc (func);
2606 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2607 builder = LLVMCreateBuilder ();
2608 LLVMPositionBuilderAtEnd (builder, entry_bb);
2611 ji = g_new0 (MonoJumpInfo, 1);
2612 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2613 ji = mono_aot_patch_info_dup (ji);
2614 got_offset = mono_aot_get_got_offset (ji);
2615 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2616 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2617 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2618 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2619 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2620 args [1] = LLVMGetParam (func, 0);
2622 args [2] = LLVMGetParam (func, 1);
2624 ji = g_new0 (MonoJumpInfo, 1);
2625 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2626 ji->data.name = icall_name;
2627 ji = mono_aot_patch_info_dup (ji);
2628 got_offset = mono_aot_get_got_offset (ji);
2629 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2630 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2631 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2632 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2633 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2634 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2635 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2637 // Set the inited flag
2638 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2639 indexes [1] = LLVMGetParam (func, 0);
2640 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2642 LLVMBuildRetVoid (builder);
2644 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2645 LLVMDisposeBuilder (builder);
2650 * Emit wrappers around the C icalls used to initialize llvm methods, to
2651 * make the calling code smaller and to enable usage of the llvm
2652 * PreserveAll calling convention.
2655 emit_init_icall_wrappers (MonoLLVMModule *module)
2657 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2658 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2659 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2660 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2664 emit_llvm_code_end (MonoLLVMModule *module)
2666 LLVMModuleRef lmodule = module->lmodule;
2668 LLVMBasicBlockRef entry_bb;
2669 LLVMBuilderRef builder;
2671 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2672 LLVMSetLinkage (func, LLVMInternalLinkage);
2673 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2674 module->code_end = func;
2675 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2676 builder = LLVMCreateBuilder ();
2677 LLVMPositionBuilderAtEnd (builder, entry_bb);
2678 LLVMBuildRetVoid (builder);
2679 LLVMDisposeBuilder (builder);
2683 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2685 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2688 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2689 need_div_check = TRUE;
2691 if (!need_div_check)
2694 switch (ins->opcode) {
2707 case OP_IDIV_UN_IMM:
2708 case OP_LDIV_UN_IMM:
2709 case OP_IREM_UN_IMM:
2710 case OP_LREM_UN_IMM: {
2712 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2713 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2715 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2716 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2719 builder = ctx->builder;
2721 /* b == -1 && a == 0x80000000 */
2723 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2724 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2725 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2727 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2728 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2731 builder = ctx->builder;
2743 * Emit code to initialize the GOT slots used by the method.
2746 emit_init_method (EmitContext *ctx)
2748 LLVMValueRef indexes [16], args [16], callee;
2749 LLVMValueRef inited_var, cmp, call;
2750 LLVMBasicBlockRef inited_bb, notinited_bb;
2751 LLVMBuilderRef builder = ctx->builder;
2752 MonoCompile *cfg = ctx->cfg;
2754 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2756 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2757 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2758 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2760 args [0] = inited_var;
2761 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2762 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2764 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2766 inited_bb = ctx->inited_bb;
2767 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2769 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2771 builder = ctx->builder = create_builder (ctx);
2772 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2775 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2776 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2777 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2778 callee = ctx->module->init_method_gshared_mrgctx;
2779 call = LLVMBuildCall (builder, callee, args, 2, "");
2780 } else if (ctx->rgctx_arg) {
2781 /* A vtable is passed as the rgctx argument */
2782 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2783 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2784 callee = ctx->module->init_method_gshared_vtable;
2785 call = LLVMBuildCall (builder, callee, args, 2, "");
2786 } else if (cfg->gshared) {
2787 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2788 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2789 callee = ctx->module->init_method_gshared_this;
2790 call = LLVMBuildCall (builder, callee, args, 2, "");
2792 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2793 callee = ctx->module->init_method;
2794 call = LLVMBuildCall (builder, callee, args, 1, "");
2798 * This enables llvm to keep arguments in their original registers/
2799 * scratch registers, since the call will not clobber them.
2801 mono_llvm_set_call_preserveall_cc (call);
2803 LLVMBuildBr (builder, inited_bb);
2804 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2806 builder = ctx->builder = create_builder (ctx);
2807 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2811 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2814 * Emit unbox trampoline using a tail call
2816 LLVMValueRef tramp, call, *args;
2817 LLVMBuilderRef builder;
2818 LLVMBasicBlockRef lbb;
2819 LLVMCallInfo *linfo;
2823 tramp_name = g_strdup_printf ("ut_%s", method_name);
2824 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2825 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2826 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2827 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2829 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2830 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2831 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2832 if (ctx->cfg->vret_addr) {
2833 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2834 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2835 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2836 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2840 lbb = LLVMAppendBasicBlock (tramp, "");
2841 builder = LLVMCreateBuilder ();
2842 LLVMPositionBuilderAtEnd (builder, lbb);
2844 nargs = LLVMCountParamTypes (method_type);
2845 args = g_new0 (LLVMValueRef, nargs);
2846 for (i = 0; i < nargs; ++i) {
2847 args [i] = LLVMGetParam (tramp, i);
2848 if (i == ctx->this_arg_pindex) {
2849 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2851 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2852 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2853 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2856 call = LLVMBuildCall (builder, method, args, nargs, "");
2857 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2858 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2859 if (linfo->ret.storage == LLVMArgVtypeByRef)
2860 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2862 // FIXME: This causes assertions in clang
2863 //mono_llvm_set_must_tail (call);
2864 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2865 LLVMBuildRetVoid (builder);
2867 LLVMBuildRet (builder, call);
2869 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2870 LLVMDisposeBuilder (builder);
2876 * Emit code to load/convert arguments.
2879 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2882 MonoCompile *cfg = ctx->cfg;
2883 MonoMethodSignature *sig = ctx->sig;
2884 LLVMCallInfo *linfo = ctx->linfo;
2888 LLVMBuilderRef old_builder = ctx->builder;
2889 ctx->builder = builder;
2891 ctx->alloca_builder = create_builder (ctx);
2894 * Handle indirect/volatile variables by allocating memory for them
2895 * using 'alloca', and storing their address in a temporary.
2897 for (i = 0; i < cfg->num_varinfo; ++i) {
2898 MonoInst *var = cfg->varinfo [i];
2901 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2902 } 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))) {
2903 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2906 /* Could be already created by an OP_VPHI */
2907 if (!ctx->addresses [var->dreg]) {
2908 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2909 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2911 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2915 names = g_new (char *, sig->param_count);
2916 mono_method_get_param_names (cfg->method, (const char **) names);
2918 for (i = 0; i < sig->param_count; ++i) {
2919 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2920 int reg = cfg->args [i + sig->hasthis]->dreg;
2923 pindex = ainfo->pindex;
2925 switch (ainfo->storage) {
2926 case LLVMArgVtypeInReg:
2927 case LLVMArgAsFpArgs: {
2928 LLVMValueRef args [8];
2931 pindex += ainfo->ndummy_fpargs;
2933 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2934 memset (args, 0, sizeof (args));
2935 if (ainfo->storage == LLVMArgVtypeInReg) {
2936 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2937 if (ainfo->pair_storage [1] != LLVMArgNone)
2938 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2940 g_assert (ainfo->nslots <= 8);
2941 for (j = 0; j < ainfo->nslots; ++j)
2942 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2944 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2946 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2948 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2949 /* Treat these as normal values */
2950 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2954 case LLVMArgVtypeByVal: {
2955 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2957 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2958 /* Treat these as normal values */
2959 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2963 case LLVMArgVtypeByRef: {
2964 /* The argument is passed by ref */
2965 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2968 case LLVMArgAsIArgs: {
2969 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2972 /* The argument is received as an array of ints, store it into the real argument */
2973 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2975 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2976 if (size < SIZEOF_VOID_P) {
2977 /* The upper bits of the registers might not be valid */
2978 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2979 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2980 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2982 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2986 case LLVMArgVtypeAsScalar:
2987 g_assert_not_reached ();
2989 case LLVMArgGsharedvtFixed: {
2990 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2991 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2994 name = g_strdup_printf ("arg_%s", names [i]);
2996 name = g_strdup_printf ("arg_%d", i);
2998 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3001 case LLVMArgGsharedvtFixedVtype: {
3002 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3005 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3007 name = g_strdup_printf ("vtype_arg_%d", i);
3009 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3010 g_assert (ctx->addresses [reg]);
3011 LLVMSetValueName (ctx->addresses [reg], name);
3012 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3015 case LLVMArgGsharedvtVariable:
3016 /* The IR treats these as variables with addresses */
3017 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3020 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));
3027 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3029 emit_volatile_store (ctx, cfg->args [0]->dreg);
3030 for (i = 0; i < sig->param_count; ++i)
3031 if (!mini_type_is_vtype (sig->params [i]))
3032 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3034 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3035 LLVMValueRef this_alloc;
3038 * The exception handling code needs the location where the this argument was
3039 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3040 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3041 * location into the LSDA.
3043 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3044 /* This volatile store will keep the alloca alive */
3045 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3047 set_metadata_flag (this_alloc, "mono.this");
3050 if (cfg->rgctx_var) {
3051 LLVMValueRef rgctx_alloc, store;
3054 * We handle the rgctx arg similarly to the this pointer.
3056 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3057 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3058 /* This volatile store will keep the alloca alive */
3059 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3061 set_metadata_flag (rgctx_alloc, "mono.this");
3064 /* Initialize the method if needed */
3065 if (cfg->compile_aot && ctx->llvm_only) {
3066 /* Emit a location for the initialization code */
3067 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3068 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3070 LLVMBuildBr (ctx->builder, ctx->init_bb);
3071 builder = ctx->builder = create_builder (ctx);
3072 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3073 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3076 /* Compute nesting between clauses */
3077 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3078 for (i = 0; i < cfg->header->num_clauses; ++i) {
3079 for (j = 0; j < cfg->header->num_clauses; ++j) {
3080 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3081 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3083 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3084 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3089 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3090 * it needs to continue normally, or return back to the exception handling system.
3092 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3096 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3099 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3100 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3101 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3103 if (bb->in_scount == 0) {
3106 sprintf (name, "finally_ind_bb%d", bb->block_num);
3107 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3108 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3110 ctx->bblocks [bb->block_num].finally_ind = val;
3112 /* Create a variable to hold the exception var */
3114 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3118 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3119 * LLVM bblock containing a landing pad causes problems for the
3120 * LLVM optimizer passes.
3122 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3123 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3125 ctx->builder = old_builder;
3129 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3131 MonoCompile *cfg = ctx->cfg;
3132 LLVMValueRef *values = ctx->values;
3133 LLVMValueRef *addresses = ctx->addresses;
3134 MonoCallInst *call = (MonoCallInst*)ins;
3135 MonoMethodSignature *sig = call->signature;
3136 LLVMValueRef callee = NULL, lcall;
3138 LLVMCallInfo *cinfo;
3142 LLVMTypeRef llvm_sig;
3144 gboolean is_virtual, calli, preserveall;
3145 LLVMBuilderRef builder = *builder_ref;
3147 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3148 set_failure (ctx, "non-default callconv");
3152 cinfo = call->cinfo;
3154 if (call->rgctx_arg_reg)
3155 cinfo->rgctx_arg = TRUE;
3156 if (call->imt_arg_reg)
3157 cinfo->imt_arg = TRUE;
3159 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3161 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3165 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);
3166 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);
3168 preserveall = FALSE;
3170 /* FIXME: Avoid creating duplicate methods */
3172 if (ins->flags & MONO_INST_HAS_METHOD) {
3176 if (cfg->compile_aot) {
3177 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3179 set_failure (ctx, "can't encode patch");
3182 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3184 * Collect instructions representing the callee into a hash so they can be replaced
3185 * by the llvm method for the callee if the callee turns out to be direct
3186 * callable. Currently this only requires it to not fail llvm compilation.
3188 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3189 l = g_slist_prepend (l, callee);
3190 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3194 static int tramp_index;
3197 name = g_strdup_printf ("tramp_%d", tramp_index);
3200 #if LLVM_API_VERSION > 100
3202 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3203 * Make all calls through a global. The address of the global will be saved in
3204 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3207 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3210 mono_create_jit_trampoline (mono_domain_get (),
3211 call->method, &error);
3212 if (!is_ok (&error)) {
3213 set_failure (ctx, mono_error_get_message (&error));
3214 mono_error_cleanup (&error);
3218 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3219 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3220 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3221 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3223 callee = LLVMBuildLoad (builder, tramp_var, "");
3226 mono_create_jit_trampoline (mono_domain_get (),
3227 call->method, &error);
3228 if (!is_ok (&error)) {
3230 set_failure (ctx, mono_error_get_message (&error));
3231 mono_error_cleanup (&error);
3235 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3238 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3243 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3244 /* LLVM miscompiles async methods */
3245 set_failure (ctx, "#13734");
3250 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3256 memset (&ji, 0, sizeof (ji));
3257 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3258 ji.data.target = info->name;
3260 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3262 if (cfg->compile_aot) {
3263 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3265 set_failure (ctx, "can't encode patch");
3269 target = (gpointer)mono_icall_get_wrapper (info);
3270 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3273 if (cfg->compile_aot) {
3275 if (cfg->abs_patches) {
3276 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3278 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3280 set_failure (ctx, "can't encode patch");
3286 set_failure (ctx, "aot");
3290 #if LLVM_API_VERSION > 100
3291 if (cfg->abs_patches) {
3292 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3296 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3297 mono_error_assert_ok (&error);
3298 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3300 g_assert_not_reached ();
3303 g_assert_not_reached ();
3306 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3308 if (cfg->abs_patches) {
3309 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3314 * FIXME: Some trampolines might have
3315 * their own calling convention on some platforms.
3317 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3318 mono_error_assert_ok (&error);
3319 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3323 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3330 int size = sizeof (gpointer);
3333 g_assert (ins->inst_offset % size == 0);
3334 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3336 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3338 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3340 if (ins->flags & MONO_INST_HAS_METHOD) {
3345 * Collect and convert arguments
3347 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3348 len = sizeof (LLVMValueRef) * nargs;
3349 args = (LLVMValueRef*)alloca (len);
3350 memset (args, 0, len);
3351 l = call->out_ireg_args;
3353 if (call->rgctx_arg_reg) {
3354 g_assert (values [call->rgctx_arg_reg]);
3355 g_assert (cinfo->rgctx_arg_pindex < nargs);
3357 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3358 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3359 * it using a volatile load.
3362 if (!ctx->imt_rgctx_loc)
3363 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3364 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3365 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3367 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3370 if (call->imt_arg_reg) {
3371 g_assert (!ctx->llvm_only);
3372 g_assert (values [call->imt_arg_reg]);
3373 g_assert (cinfo->imt_arg_pindex < nargs);
3375 if (!ctx->imt_rgctx_loc)
3376 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3377 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3378 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3380 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3383 switch (cinfo->ret.storage) {
3384 case LLVMArgGsharedvtVariable: {
3385 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3387 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3388 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3390 g_assert (addresses [call->inst.dreg]);
3391 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3397 if (!addresses [call->inst.dreg])
3398 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3399 g_assert (cinfo->vret_arg_pindex < nargs);
3400 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3401 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3403 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3409 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3410 * use the real callee for argument type conversion.
3412 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3413 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3414 LLVMGetParamTypes (callee_type, param_types);
3416 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3419 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3421 pindex = ainfo->pindex;
3423 regpair = (guint32)(gssize)(l->data);
3424 reg = regpair & 0xffffff;
3425 args [pindex] = values [reg];
3426 switch (ainfo->storage) {
3427 case LLVMArgVtypeInReg:
3428 case LLVMArgAsFpArgs: {
3432 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3433 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3434 pindex += ainfo->ndummy_fpargs;
3436 g_assert (addresses [reg]);
3437 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3441 // FIXME: Get rid of the VMOVE
3444 case LLVMArgVtypeByVal:
3445 g_assert (addresses [reg]);
3446 args [pindex] = addresses [reg];
3448 case LLVMArgVtypeByRef: {
3449 g_assert (addresses [reg]);
3450 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3453 case LLVMArgAsIArgs:
3454 g_assert (addresses [reg]);
3455 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3457 case LLVMArgVtypeAsScalar:
3458 g_assert_not_reached ();
3460 case LLVMArgGsharedvtFixed:
3461 case LLVMArgGsharedvtFixedVtype:
3462 g_assert (addresses [reg]);
3463 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3465 case LLVMArgGsharedvtVariable:
3466 g_assert (addresses [reg]);
3467 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3470 g_assert (args [pindex]);
3471 if (i == 0 && sig->hasthis)
3472 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3474 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3477 g_assert (pindex <= nargs);
3482 // FIXME: Align call sites
3488 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3490 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3491 mono_llvm_set_call_notail (lcall);
3494 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3496 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3497 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3499 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3500 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3501 if (!sig->pinvoke && !cfg->llvm_only)
3502 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3504 mono_llvm_set_call_preserveall_cc (lcall);
3506 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3507 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3508 if (!ctx->llvm_only && call->rgctx_arg_reg)
3509 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3510 if (call->imt_arg_reg)
3511 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3513 /* Add byval attributes if needed */
3514 for (i = 0; i < sig->param_count; ++i) {
3515 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3517 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3518 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3522 * Convert the result
3524 switch (cinfo->ret.storage) {
3525 case LLVMArgVtypeInReg: {
3526 LLVMValueRef regs [2];
3528 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3532 if (!addresses [ins->dreg])
3533 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3535 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3536 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3537 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3538 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3541 case LLVMArgVtypeByVal:
3542 if (!addresses [call->inst.dreg])
3543 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3544 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3546 case LLVMArgAsIArgs:
3547 case LLVMArgFpStruct:
3548 if (!addresses [call->inst.dreg])
3549 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3550 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3552 case LLVMArgVtypeAsScalar:
3553 if (!addresses [call->inst.dreg])
3554 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3555 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3557 case LLVMArgVtypeRetAddr:
3558 case LLVMArgVtypeByRef:
3559 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3560 /* Some opcodes like STOREX_MEMBASE access these by value */
3561 g_assert (addresses [call->inst.dreg]);
3562 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3565 case LLVMArgGsharedvtVariable:
3567 case LLVMArgGsharedvtFixed:
3568 case LLVMArgGsharedvtFixedVtype:
3569 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3572 if (sig->ret->type != MONO_TYPE_VOID)
3573 /* If the method returns an unsigned value, need to zext it */
3574 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));
3578 *builder_ref = ctx->builder;
3582 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3584 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3585 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3587 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3590 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3592 if (ctx->cfg->compile_aot) {
3593 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3595 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3596 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3597 mono_memory_barrier ();
3600 ctx->module->rethrow = callee;
3602 ctx->module->throw_icall = callee;
3606 LLVMValueRef args [2];
3608 args [0] = convert (ctx, exc, exc_type);
3609 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3611 LLVMBuildUnreachable (ctx->builder);
3613 ctx->builder = create_builder (ctx);
3617 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3619 MonoMethodSignature *throw_sig;
3620 LLVMValueRef callee, arg;
3621 const char *icall_name;
3623 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3624 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3627 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3628 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3629 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3630 if (ctx->cfg->compile_aot) {
3631 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3636 * LLVM doesn't push the exception argument, so we need a different
3639 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3641 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3643 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3646 mono_memory_barrier ();
3647 #if LLVM_API_VERSION < 100
3649 ctx->module->rethrow = callee;
3651 ctx->module->throw_icall = callee;
3654 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3655 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3659 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3661 const char *icall_name = "mono_llvm_resume_exception";
3662 LLVMValueRef callee = ctx->module->resume_eh;
3664 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3667 if (ctx->cfg->compile_aot) {
3668 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3670 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3671 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3672 mono_memory_barrier ();
3674 ctx->module->resume_eh = callee;
3678 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3680 LLVMBuildUnreachable (ctx->builder);
3682 ctx->builder = create_builder (ctx);
3686 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3688 const char *icall_name = "mono_llvm_clear_exception";
3690 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3691 LLVMValueRef callee = NULL;
3694 if (ctx->cfg->compile_aot) {
3695 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3697 // FIXME: This is broken.
3698 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3702 g_assert (builder && callee);
3704 return LLVMBuildCall (builder, callee, NULL, 0, "");
3708 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3710 const char *icall_name = "mono_llvm_load_exception";
3712 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3713 LLVMValueRef callee = NULL;
3716 if (ctx->cfg->compile_aot) {
3717 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3719 // FIXME: This is broken.
3720 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3724 g_assert (builder && callee);
3726 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3731 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3733 const char *icall_name = "mono_llvm_match_exception";
3735 ctx->builder = builder;
3737 const int num_args = 5;
3738 LLVMValueRef args [num_args];
3739 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3740 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3741 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3742 if (ctx->cfg->rgctx_var) {
3743 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3744 g_assert (rgctx_alloc);
3745 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3747 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3750 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3752 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3754 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3755 LLVMValueRef callee = ctx->module->match_exc;
3758 if (ctx->cfg->compile_aot) {
3759 ctx->builder = builder;
3760 // get_callee expects ctx->builder to be the emitting builder
3761 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3763 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3764 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3765 ctx->module->match_exc = callee;
3766 mono_memory_barrier ();
3770 g_assert (builder && callee);
3772 g_assert (ctx->ex_var);
3774 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3777 // FIXME: This won't work because the code-finding makes this
3779 /*#define MONO_PERSONALITY_DEBUG*/
3781 #ifdef MONO_PERSONALITY_DEBUG
3782 static const gboolean use_debug_personality = TRUE;
3783 static const char *default_personality_name = "mono_debug_personality";
3785 static const gboolean use_debug_personality = FALSE;
3786 static const char *default_personality_name = "__gxx_personality_v0";
3790 default_cpp_lpad_exc_signature (void)
3792 static gboolean inited = FALSE;
3793 static LLVMTypeRef sig;
3796 LLVMTypeRef signature [2];
3797 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3798 signature [1] = LLVMInt32Type ();
3799 sig = LLVMStructType (signature, 2, FALSE);
3807 get_mono_personality (EmitContext *ctx)
3809 LLVMValueRef personality = NULL;
3810 static gint32 mapping_inited = FALSE;
3811 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3813 if (!use_debug_personality) {
3814 if (ctx->cfg->compile_aot) {
3815 personality = get_intrinsic (ctx, default_personality_name);
3816 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3817 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3818 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3821 if (ctx->cfg->compile_aot) {
3822 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3824 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3825 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3826 mono_memory_barrier ();
3830 g_assert (personality);
3834 static LLVMBasicBlockRef
3835 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3837 MonoCompile *cfg = ctx->cfg;
3838 LLVMBuilderRef old_builder = ctx->builder;
3839 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3841 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3842 ctx->builder = lpadBuilder;
3844 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3845 g_assert (handler_bb);
3847 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3848 LLVMValueRef personality = get_mono_personality (ctx);
3849 g_assert (personality);
3851 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3852 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3854 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3855 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3856 g_assert (landing_pad);
3858 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3859 LLVMAddClause (landing_pad, cast);
3861 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3862 LLVMBuilderRef resume_builder = create_builder (ctx);
3863 ctx->builder = resume_builder;
3864 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3866 emit_resume_eh (ctx, handler_bb);
3869 ctx->builder = lpadBuilder;
3870 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3872 gboolean finally_only = TRUE;
3874 MonoExceptionClause *group_cursor = group_start;
3876 for (int i = 0; i < group_size; i ++) {
3877 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3878 finally_only = FALSE;
3884 // Handle landing pad inlining
3886 if (!finally_only) {
3887 // So at each level of the exception stack we will match the exception again.
3888 // During that match, we need to compare against the handler types for the current
3889 // protected region. We send the try start and end so that we can only check against
3890 // handlers for this lexical protected region.
3891 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3893 // if returns -1, resume
3894 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3896 // else move to that target bb
3897 for (int i=0; i < group_size; i++) {
3898 MonoExceptionClause *clause = group_start + i;
3899 int clause_index = clause - cfg->header->clauses;
3900 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3901 g_assert (handler_bb);
3902 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3903 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3906 int clause_index = group_start - cfg->header->clauses;
3907 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3908 g_assert (finally_bb);
3910 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3913 ctx->builder = old_builder;
3920 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3922 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3923 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3925 // Make exception available to catch blocks
3926 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3927 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3929 g_assert (ctx->ex_var);
3930 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3932 if (bb->in_scount == 1) {
3933 MonoInst *exvar = bb->in_stack [0];
3934 g_assert (!ctx->values [exvar->dreg]);
3935 g_assert (ctx->ex_var);
3936 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3937 emit_volatile_store (ctx, exvar->dreg);
3940 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3943 LLVMBuilderRef handler_builder = create_builder (ctx);
3944 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3945 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3947 // Make the handler code end with a jump to cbb
3948 LLVMBuildBr (handler_builder, cbb);
3952 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3954 MonoCompile *cfg = ctx->cfg;
3955 LLVMValueRef *values = ctx->values;
3956 LLVMModuleRef lmodule = ctx->lmodule;
3957 BBInfo *bblocks = ctx->bblocks;
3959 LLVMValueRef personality;
3960 LLVMValueRef landing_pad;
3961 LLVMBasicBlockRef target_bb;
3963 static int ti_generator;
3965 LLVMValueRef type_info;
3969 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3971 if (cfg->compile_aot) {
3972 /* Use a dummy personality function */
3973 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3974 g_assert (personality);
3976 #if LLVM_API_VERSION > 100
3977 personality = ctx->module->personality;
3979 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3980 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3981 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3982 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3983 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3984 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3985 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3986 ctx->module->personality = personality;
3987 LLVMDisposeBuilder (builder2);
3990 static gint32 mapping_inited;
3992 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3994 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3995 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3999 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4001 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4004 * Create the type info
4006 sprintf (ti_name, "type_info_%d", ti_generator);
4009 if (cfg->compile_aot) {
4010 /* decode_eh_frame () in aot-runtime.c will decode this */
4011 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4012 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4015 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4017 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4019 #if LLVM_API_VERSION > 100
4020 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4021 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4026 * After the cfg mempool is freed, the type info will point to stale memory,
4027 * but this is not a problem, since we decode it once in exception_cb during
4030 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4031 *(gint32*)ti = clause_index;
4033 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4035 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4040 LLVMTypeRef members [2], ret_type;
4042 members [0] = i8ptr;
4043 members [1] = LLVMInt32Type ();
4044 ret_type = LLVMStructType (members, 2, FALSE);
4046 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4047 LLVMAddClause (landing_pad, type_info);
4049 /* Store the exception into the exvar */
4051 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4055 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4056 * code expects control to be transferred to this landing pad even in the
4057 * presence of nested clauses. The landing pad needs to branch to the landing
4058 * pads belonging to nested clauses based on the selector value returned by
4059 * the landing pad instruction, which is passed to the landing pad in a
4060 * register by the EH code.
4062 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4063 g_assert (target_bb);
4066 * Branch to the correct landing pad
4068 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4069 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4071 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4072 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4073 MonoBasicBlock *handler_bb;
4075 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4076 g_assert (handler_bb);
4078 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4079 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4082 /* Start a new bblock which CALL_HANDLER can branch to */
4083 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4085 ctx->builder = builder = create_builder (ctx);
4086 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4088 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4090 /* Store the exception into the IL level exvar */
4091 if (bb->in_scount == 1) {
4092 g_assert (bb->in_scount == 1);
4093 exvar = bb->in_stack [0];
4095 // FIXME: This is shared with filter clauses ?
4096 g_assert (!values [exvar->dreg]);
4098 g_assert (ctx->ex_var);
4099 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4100 emit_volatile_store (ctx, exvar->dreg);
4106 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4108 MonoCompile *cfg = ctx->cfg;
4109 MonoMethodSignature *sig = ctx->sig;
4110 LLVMValueRef method = ctx->lmethod;
4111 LLVMValueRef *values = ctx->values;
4112 LLVMValueRef *addresses = ctx->addresses;
4113 LLVMCallInfo *linfo = ctx->linfo;
4114 BBInfo *bblocks = ctx->bblocks;
4116 LLVMBasicBlockRef cbb;
4117 LLVMBuilderRef builder, starting_builder;
4118 gboolean has_terminator;
4120 LLVMValueRef lhs, rhs;
4123 cbb = get_end_bb (ctx, bb);
4125 builder = create_builder (ctx);
4126 ctx->builder = builder;
4127 LLVMPositionBuilderAtEnd (builder, cbb);
4132 if (bb->flags & BB_EXCEPTION_HANDLER) {
4133 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4134 set_failure (ctx, "handler without invokes");
4139 emit_llvmonly_handler_start (ctx, bb, cbb);
4141 emit_handler_start (ctx, bb, builder);
4144 builder = ctx->builder;
4147 has_terminator = FALSE;
4148 starting_builder = builder;
4149 for (ins = bb->code; ins; ins = ins->next) {
4150 const char *spec = LLVM_INS_INFO (ins->opcode);
4152 char dname_buf [128];
4154 emit_dbg_loc (ctx, builder, ins->cil_code);
4159 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4160 * Start a new bblock.
4161 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4162 * from localloc-ed memory.
4164 if (!cfg->llvm_only)
4165 ;//set_failure (ctx, "basic block too long");
4167 if (!ctx->long_bb_break_var) {
4168 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4169 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4172 cbb = gen_bb (ctx, "CONT_LONG_BB");
4173 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4175 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4177 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4178 * but llvm doesn't know that, so the branch is not going to be eliminated.
4180 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4182 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4184 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4185 ctx->builder = builder = create_builder (ctx);
4186 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4187 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4188 LLVMBuildBr (builder, cbb);
4190 ctx->builder = builder = create_builder (ctx);
4191 LLVMPositionBuilderAtEnd (builder, cbb);
4192 ctx->bblocks [bb->block_num].end_bblock = cbb;
4197 /* There could be instructions after a terminator, skip them */
4200 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4201 sprintf (dname_buf, "t%d", ins->dreg);
4205 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4206 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4208 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4209 lhs = emit_volatile_load (ctx, ins->sreg1);
4211 /* It is ok for SETRET to have an uninitialized argument */
4212 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4213 set_failure (ctx, "sreg1");
4216 lhs = values [ins->sreg1];
4222 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4223 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4224 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4225 rhs = emit_volatile_load (ctx, ins->sreg2);
4227 if (!values [ins->sreg2]) {
4228 set_failure (ctx, "sreg2");
4231 rhs = values [ins->sreg2];
4237 //mono_print_ins (ins);
4238 switch (ins->opcode) {
4241 case OP_LIVERANGE_START:
4242 case OP_LIVERANGE_END:
4245 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4248 #if SIZEOF_VOID_P == 4
4249 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4251 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4255 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4259 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4261 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4263 case OP_DUMMY_ICONST:
4264 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4266 case OP_DUMMY_I8CONST:
4267 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4269 case OP_DUMMY_R8CONST:
4270 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4273 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4274 LLVMBuildBr (builder, target_bb);
4275 has_terminator = TRUE;
4282 LLVMBasicBlockRef new_bb;
4283 LLVMBuilderRef new_builder;
4285 // The default branch is already handled
4286 // FIXME: Handle it here
4288 /* Start new bblock */
4289 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4290 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4292 lhs = convert (ctx, lhs, LLVMInt32Type ());
4293 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4294 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4295 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4297 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4300 new_builder = create_builder (ctx);
4301 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4302 LLVMBuildUnreachable (new_builder);
4304 has_terminator = TRUE;
4305 g_assert (!ins->next);
4311 switch (linfo->ret.storage) {
4312 case LLVMArgVtypeInReg: {
4313 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4314 LLVMValueRef val, addr, retval;
4317 retval = LLVMGetUndef (ret_type);
4319 if (!addresses [ins->sreg1]) {
4321 * The return type is an LLVM vector type, have to convert between it and the
4322 * real return type which is a struct type.
4324 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4325 /* Convert to 2xi64 first */
4326 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4328 for (i = 0; i < 2; ++i) {
4329 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4330 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4332 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4336 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4337 for (i = 0; i < 2; ++i) {
4338 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4339 LLVMValueRef indexes [2], part_addr;
4341 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4342 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4343 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4345 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4347 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4351 LLVMBuildRet (builder, retval);
4354 case LLVMArgVtypeAsScalar: {
4355 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4356 LLVMValueRef retval;
4358 g_assert (addresses [ins->sreg1]);
4360 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4361 LLVMBuildRet (builder, retval);
4364 case LLVMArgVtypeByVal: {
4365 LLVMValueRef retval;
4367 g_assert (addresses [ins->sreg1]);
4368 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4369 LLVMBuildRet (builder, retval);
4372 case LLVMArgVtypeByRef: {
4373 LLVMBuildRetVoid (builder);
4376 case LLVMArgGsharedvtFixed: {
4377 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4378 /* The return value is in lhs, need to store to the vret argument */
4379 /* sreg1 might not be set */
4381 g_assert (cfg->vret_addr);
4382 g_assert (values [cfg->vret_addr->dreg]);
4383 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4385 LLVMBuildRetVoid (builder);
4388 case LLVMArgGsharedvtFixedVtype: {
4390 LLVMBuildRetVoid (builder);
4393 case LLVMArgGsharedvtVariable: {
4395 LLVMBuildRetVoid (builder);
4398 case LLVMArgVtypeRetAddr: {
4399 LLVMBuildRetVoid (builder);
4402 case LLVMArgAsIArgs:
4403 case LLVMArgFpStruct: {
4404 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4405 LLVMValueRef retval;
4407 g_assert (addresses [ins->sreg1]);
4408 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4409 LLVMBuildRet (builder, retval);
4413 case LLVMArgNormal: {
4414 if (!lhs || ctx->is_dead [ins->sreg1]) {
4416 * The method did not set its return value, probably because it
4417 * ends with a throw.
4420 LLVMBuildRetVoid (builder);
4422 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4424 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4426 has_terminator = TRUE;
4430 g_assert_not_reached ();
4439 case OP_ICOMPARE_IMM:
4440 case OP_LCOMPARE_IMM:
4441 case OP_COMPARE_IMM: {
4443 LLVMValueRef cmp, args [16];
4444 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4446 if (ins->next->opcode == OP_NOP)
4449 if (ins->next->opcode == OP_BR)
4450 /* The comparison result is not needed */
4453 rel = mono_opcode_to_cond (ins->next->opcode);
4455 if (ins->opcode == OP_ICOMPARE_IMM) {
4456 lhs = convert (ctx, lhs, LLVMInt32Type ());
4457 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4459 if (ins->opcode == OP_LCOMPARE_IMM) {
4460 lhs = convert (ctx, lhs, LLVMInt64Type ());
4461 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4463 if (ins->opcode == OP_LCOMPARE) {
4464 lhs = convert (ctx, lhs, LLVMInt64Type ());
4465 rhs = convert (ctx, rhs, LLVMInt64Type ());
4467 if (ins->opcode == OP_ICOMPARE) {
4468 lhs = convert (ctx, lhs, LLVMInt32Type ());
4469 rhs = convert (ctx, rhs, LLVMInt32Type ());
4473 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4474 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4475 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4476 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4479 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4480 if (ins->opcode == OP_FCOMPARE) {
4481 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4482 } else if (ins->opcode == OP_RCOMPARE) {
4483 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4484 } else if (ins->opcode == OP_COMPARE_IMM) {
4485 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4486 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4488 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4489 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4490 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4491 /* The immediate is encoded in two fields */
4492 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4493 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4495 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4498 else if (ins->opcode == OP_COMPARE) {
4499 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4500 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4502 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4504 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4508 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4509 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4512 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4513 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4515 * If the target bb contains PHI instructions, LLVM requires
4516 * two PHI entries for this bblock, while we only generate one.
4517 * So convert this to an unconditional bblock. (bxc #171).
4519 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4521 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4523 has_terminator = TRUE;
4524 } else if (MONO_IS_SETCC (ins->next)) {
4525 sprintf (dname_buf, "t%d", ins->next->dreg);
4527 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4529 /* Add stores for volatile variables */
4530 emit_volatile_store (ctx, ins->next->dreg);
4531 } else if (MONO_IS_COND_EXC (ins->next)) {
4532 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4535 builder = ctx->builder;
4537 set_failure (ctx, "next");
4555 rel = mono_opcode_to_cond (ins->opcode);
4557 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4558 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4569 rel = mono_opcode_to_cond (ins->opcode);
4571 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4572 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4580 gboolean empty = TRUE;
4582 /* Check that all input bblocks really branch to us */
4583 for (i = 0; i < bb->in_count; ++i) {
4584 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4585 ins->inst_phi_args [i + 1] = -1;
4591 /* LLVM doesn't like phi instructions with zero operands */
4592 ctx->is_dead [ins->dreg] = TRUE;
4596 /* Created earlier, insert it now */
4597 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4599 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4600 int sreg1 = ins->inst_phi_args [i + 1];
4604 * Count the number of times the incoming bblock branches to us,
4605 * since llvm requires a separate entry for each.
4607 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4608 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4611 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4612 if (switch_ins->inst_many_bb [j] == bb)
4619 /* Remember for later */
4620 for (j = 0; j < count; ++j) {
4621 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4624 node->in_bb = bb->in_bb [i];
4626 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);
4636 values [ins->dreg] = lhs;
4640 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4643 values [ins->dreg] = lhs;
4645 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4647 * This is added by the spilling pass in case of the JIT,
4648 * but we have to do it ourselves.
4650 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4654 case OP_MOVE_F_TO_I4: {
4655 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4658 case OP_MOVE_I4_TO_F: {
4659 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4662 case OP_MOVE_F_TO_I8: {
4663 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4666 case OP_MOVE_I8_TO_F: {
4667 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4700 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4701 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4703 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4706 builder = ctx->builder;
4708 switch (ins->opcode) {
4711 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4715 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4719 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4723 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4727 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4731 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4735 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4739 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4743 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4747 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4751 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4755 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4759 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4763 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4767 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4770 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4773 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4777 g_assert_not_reached ();
4784 lhs = convert (ctx, lhs, LLVMFloatType ());
4785 rhs = convert (ctx, rhs, LLVMFloatType ());
4786 switch (ins->opcode) {
4788 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4791 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4794 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4797 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4800 g_assert_not_reached ();
4809 case OP_IREM_UN_IMM:
4811 case OP_IDIV_UN_IMM:
4817 case OP_ISHR_UN_IMM:
4827 case OP_LSHR_UN_IMM:
4833 case OP_SHR_UN_IMM: {
4836 if (spec [MONO_INST_SRC1] == 'l') {
4837 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4839 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4842 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4845 builder = ctx->builder;
4847 #if SIZEOF_VOID_P == 4
4848 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4849 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4852 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4853 lhs = convert (ctx, lhs, IntPtrType ());
4854 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4855 switch (ins->opcode) {
4859 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4863 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4868 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4872 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4874 case OP_IDIV_UN_IMM:
4875 case OP_LDIV_UN_IMM:
4876 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4880 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4882 case OP_IREM_UN_IMM:
4883 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4888 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4892 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4896 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4901 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4906 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4908 case OP_ISHR_UN_IMM:
4909 /* This is used to implement conv.u4, so the lhs could be an i8 */
4910 lhs = convert (ctx, lhs, LLVMInt32Type ());
4911 imm = convert (ctx, imm, LLVMInt32Type ());
4912 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4914 case OP_LSHR_UN_IMM:
4916 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4919 g_assert_not_reached ();
4924 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4927 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4930 lhs = convert (ctx, lhs, LLVMDoubleType ());
4931 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4934 lhs = convert (ctx, lhs, LLVMFloatType ());
4935 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4938 guint32 v = 0xffffffff;
4939 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4943 guint64 v = 0xffffffffffffffffLL;
4944 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4947 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4949 LLVMValueRef v1, v2;
4951 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4952 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4953 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4958 case OP_ICONV_TO_I1:
4959 case OP_ICONV_TO_I2:
4960 case OP_ICONV_TO_I4:
4961 case OP_ICONV_TO_U1:
4962 case OP_ICONV_TO_U2:
4963 case OP_ICONV_TO_U4:
4964 case OP_LCONV_TO_I1:
4965 case OP_LCONV_TO_I2:
4966 case OP_LCONV_TO_U1:
4967 case OP_LCONV_TO_U2:
4968 case OP_LCONV_TO_U4: {
4971 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);
4973 /* Have to do two casts since our vregs have type int */
4974 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4976 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4978 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4981 case OP_ICONV_TO_I8:
4982 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4984 case OP_ICONV_TO_U8:
4985 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4987 case OP_FCONV_TO_I4:
4988 case OP_RCONV_TO_I4:
4989 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4991 case OP_FCONV_TO_I1:
4992 case OP_RCONV_TO_I1:
4993 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4995 case OP_FCONV_TO_U1:
4996 case OP_RCONV_TO_U1:
4997 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4999 case OP_FCONV_TO_I2:
5000 case OP_RCONV_TO_I2:
5001 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5003 case OP_FCONV_TO_U2:
5004 case OP_RCONV_TO_U2:
5005 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5007 case OP_RCONV_TO_U4:
5008 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5010 case OP_FCONV_TO_I8:
5011 case OP_RCONV_TO_I8:
5012 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5015 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5017 case OP_ICONV_TO_R8:
5018 case OP_LCONV_TO_R8:
5019 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5021 case OP_ICONV_TO_R_UN:
5022 case OP_LCONV_TO_R_UN:
5023 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5025 #if SIZEOF_VOID_P == 4
5028 case OP_LCONV_TO_I4:
5029 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5031 case OP_ICONV_TO_R4:
5032 case OP_LCONV_TO_R4:
5033 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5035 values [ins->dreg] = v;
5037 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5039 case OP_FCONV_TO_R4:
5040 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5042 values [ins->dreg] = v;
5044 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5046 case OP_RCONV_TO_R8:
5047 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5049 case OP_RCONV_TO_R4:
5050 values [ins->dreg] = lhs;
5053 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5056 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5059 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5061 case OP_LOCALLOC_IMM: {
5064 guint32 size = ins->inst_imm;
5065 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5067 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5069 if (ins->flags & MONO_INST_INIT) {
5070 LLVMValueRef args [5];
5073 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5074 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5075 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5076 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5077 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5080 values [ins->dreg] = v;
5084 LLVMValueRef v, size;
5086 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), "");
5088 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5090 if (ins->flags & MONO_INST_INIT) {
5091 LLVMValueRef args [5];
5094 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5096 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5097 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5098 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5100 values [ins->dreg] = v;
5104 case OP_LOADI1_MEMBASE:
5105 case OP_LOADU1_MEMBASE:
5106 case OP_LOADI2_MEMBASE:
5107 case OP_LOADU2_MEMBASE:
5108 case OP_LOADI4_MEMBASE:
5109 case OP_LOADU4_MEMBASE:
5110 case OP_LOADI8_MEMBASE:
5111 case OP_LOADR4_MEMBASE:
5112 case OP_LOADR8_MEMBASE:
5113 case OP_LOAD_MEMBASE:
5121 LLVMValueRef base, index, addr;
5123 gboolean sext = FALSE, zext = FALSE;
5124 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5126 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5131 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)) {
5132 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5138 if (ins->inst_offset == 0) {
5140 } else if (ins->inst_offset % size != 0) {
5141 /* Unaligned load */
5142 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5143 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5145 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5146 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5150 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5152 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5154 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5156 * These will signal LLVM that these loads do not alias any stores, and
5157 * they can't fail, allowing them to be hoisted out of loops.
5159 set_invariant_load_flag (values [ins->dreg]);
5160 #if LLVM_API_VERSION < 100
5161 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5166 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5168 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5169 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5170 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5174 case OP_STOREI1_MEMBASE_REG:
5175 case OP_STOREI2_MEMBASE_REG:
5176 case OP_STOREI4_MEMBASE_REG:
5177 case OP_STOREI8_MEMBASE_REG:
5178 case OP_STORER4_MEMBASE_REG:
5179 case OP_STORER8_MEMBASE_REG:
5180 case OP_STORE_MEMBASE_REG: {
5182 LLVMValueRef index, addr, base;
5184 gboolean sext = FALSE, zext = FALSE;
5185 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5187 if (!values [ins->inst_destbasereg]) {
5188 set_failure (ctx, "inst_destbasereg");
5192 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5194 base = values [ins->inst_destbasereg];
5195 if (ins->inst_offset % size != 0) {
5196 /* Unaligned store */
5197 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5198 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5200 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5201 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5203 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5207 case OP_STOREI1_MEMBASE_IMM:
5208 case OP_STOREI2_MEMBASE_IMM:
5209 case OP_STOREI4_MEMBASE_IMM:
5210 case OP_STOREI8_MEMBASE_IMM:
5211 case OP_STORE_MEMBASE_IMM: {
5213 LLVMValueRef index, addr, base;
5215 gboolean sext = FALSE, zext = FALSE;
5216 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5218 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5220 base = values [ins->inst_destbasereg];
5221 if (ins->inst_offset % size != 0) {
5222 /* Unaligned store */
5223 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5224 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5226 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5227 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5229 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5234 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5236 case OP_OUTARG_VTRETADDR:
5244 case OP_VOIDCALL_MEMBASE:
5245 case OP_CALL_MEMBASE:
5246 case OP_LCALL_MEMBASE:
5247 case OP_FCALL_MEMBASE:
5248 case OP_RCALL_MEMBASE:
5249 case OP_VCALL_MEMBASE:
5250 case OP_VOIDCALL_REG:
5255 case OP_VCALL_REG: {
5256 process_call (ctx, bb, &builder, ins);
5261 LLVMValueRef indexes [2];
5262 MonoJumpInfo *tmp_ji, *ji;
5263 LLVMValueRef got_entry_addr;
5267 * FIXME: Can't allocate from the cfg mempool since that is freed if
5268 * the LLVM compile fails.
5270 tmp_ji = g_new0 (MonoJumpInfo, 1);
5271 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5272 tmp_ji->data.target = ins->inst_p0;
5274 ji = mono_aot_patch_info_dup (tmp_ji);
5277 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5278 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5281 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5282 * resolvable at runtime using dlsym ().
5285 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5290 ji->next = cfg->patch_info;
5291 cfg->patch_info = ji;
5293 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5294 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5295 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5296 if (!mono_aot_is_shared_got_offset (got_offset)) {
5297 //mono_print_ji (ji);
5299 ctx->has_got_access = TRUE;
5302 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5303 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5304 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5306 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5307 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5309 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5310 if (!cfg->llvm_only)
5311 set_invariant_load_flag (values [ins->dreg]);
5314 case OP_NOT_REACHED:
5315 LLVMBuildUnreachable (builder);
5316 has_terminator = TRUE;
5317 g_assert (bb->block_num < cfg->max_block_num);
5318 ctx->unreachable [bb->block_num] = TRUE;
5319 /* Might have instructions after this */
5321 MonoInst *next = ins->next;
5323 * FIXME: If later code uses the regs defined by these instructions,
5324 * compilation will fail.
5326 MONO_DELETE_INS (bb, next);
5330 MonoInst *var = ins->inst_i0;
5332 if (var->opcode == OP_VTARG_ADDR) {
5333 /* The variable contains the vtype address */
5334 values [ins->dreg] = values [var->dreg];
5335 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5336 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5338 values [ins->dreg] = addresses [var->dreg];
5343 LLVMValueRef args [1];
5345 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5346 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5350 LLVMValueRef args [1];
5352 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5353 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5357 LLVMValueRef args [1];
5359 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5360 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5364 LLVMValueRef args [1];
5366 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5367 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5381 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5382 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5384 switch (ins->opcode) {
5387 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5391 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5395 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5399 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5402 g_assert_not_reached ();
5405 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5410 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5411 * hack is necessary (for now).
5414 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5416 #define ARM64_ATOMIC_FENCE_FIX
5419 case OP_ATOMIC_EXCHANGE_I4:
5420 case OP_ATOMIC_EXCHANGE_I8: {
5421 LLVMValueRef args [2];
5424 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5425 t = LLVMInt32Type ();
5427 t = LLVMInt64Type ();
5429 g_assert (ins->inst_offset == 0);
5431 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5432 args [1] = convert (ctx, rhs, t);
5434 ARM64_ATOMIC_FENCE_FIX;
5435 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5436 ARM64_ATOMIC_FENCE_FIX;
5439 case OP_ATOMIC_ADD_I4:
5440 case OP_ATOMIC_ADD_I8: {
5441 LLVMValueRef args [2];
5444 if (ins->opcode == OP_ATOMIC_ADD_I4)
5445 t = LLVMInt32Type ();
5447 t = LLVMInt64Type ();
5449 g_assert (ins->inst_offset == 0);
5451 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5452 args [1] = convert (ctx, rhs, t);
5453 ARM64_ATOMIC_FENCE_FIX;
5454 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5455 ARM64_ATOMIC_FENCE_FIX;
5458 case OP_ATOMIC_CAS_I4:
5459 case OP_ATOMIC_CAS_I8: {
5460 LLVMValueRef args [3], val;
5463 if (ins->opcode == OP_ATOMIC_CAS_I4)
5464 t = LLVMInt32Type ();
5466 t = LLVMInt64Type ();
5468 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5470 args [1] = convert (ctx, values [ins->sreg3], t);
5472 args [2] = convert (ctx, values [ins->sreg2], t);
5473 ARM64_ATOMIC_FENCE_FIX;
5474 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5475 ARM64_ATOMIC_FENCE_FIX;
5476 /* cmpxchg returns a pair */
5477 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5480 case OP_MEMORY_BARRIER: {
5481 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5484 case OP_ATOMIC_LOAD_I1:
5485 case OP_ATOMIC_LOAD_I2:
5486 case OP_ATOMIC_LOAD_I4:
5487 case OP_ATOMIC_LOAD_I8:
5488 case OP_ATOMIC_LOAD_U1:
5489 case OP_ATOMIC_LOAD_U2:
5490 case OP_ATOMIC_LOAD_U4:
5491 case OP_ATOMIC_LOAD_U8:
5492 case OP_ATOMIC_LOAD_R4:
5493 case OP_ATOMIC_LOAD_R8: {
5494 #if LLVM_API_VERSION > 100
5496 gboolean sext, zext;
5498 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5499 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5500 LLVMValueRef index, addr;
5502 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5507 if (ins->inst_offset != 0) {
5508 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5509 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5514 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5516 ARM64_ATOMIC_FENCE_FIX;
5517 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5518 ARM64_ATOMIC_FENCE_FIX;
5521 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5523 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5526 set_failure (ctx, "atomic mono.load intrinsic");
5530 case OP_ATOMIC_STORE_I1:
5531 case OP_ATOMIC_STORE_I2:
5532 case OP_ATOMIC_STORE_I4:
5533 case OP_ATOMIC_STORE_I8:
5534 case OP_ATOMIC_STORE_U1:
5535 case OP_ATOMIC_STORE_U2:
5536 case OP_ATOMIC_STORE_U4:
5537 case OP_ATOMIC_STORE_U8:
5538 case OP_ATOMIC_STORE_R4:
5539 case OP_ATOMIC_STORE_R8: {
5541 gboolean sext, zext;
5543 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5544 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5545 LLVMValueRef index, addr, value, base;
5547 #if LLVM_API_VERSION < 100
5548 if (!cfg->llvm_only) {
5549 set_failure (ctx, "atomic mono.store intrinsic");
5554 if (!values [ins->inst_destbasereg]) {
5555 set_failure (ctx, "inst_destbasereg");
5559 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5561 base = values [ins->inst_destbasereg];
5562 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5563 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5564 value = convert (ctx, values [ins->sreg1], t);
5566 ARM64_ATOMIC_FENCE_FIX;
5567 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5568 ARM64_ATOMIC_FENCE_FIX;
5571 case OP_RELAXED_NOP: {
5572 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5573 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5580 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5582 // 257 == FS segment register
5583 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5585 // 256 == GS segment register
5586 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5589 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5590 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5591 /* See mono_amd64_emit_tls_get () */
5592 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5594 // 256 == GS segment register
5595 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5596 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5598 set_failure (ctx, "opcode tls-get");
5604 case OP_TLS_GET_REG: {
5605 #if defined(TARGET_AMD64) && defined(__linux__)
5606 // 257 == FS segment register
5607 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5608 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt64Type ()), ptrtype, ""), "");
5609 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5610 /* See emit_tls_get_reg () */
5611 // 256 == GS segment register
5612 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5613 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5615 set_failure (ctx, "opcode tls-get");
5621 case OP_TLS_SET_REG: {
5622 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5623 /* See emit_tls_get_reg () */
5624 // 256 == GS segment register
5625 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5626 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5628 set_failure (ctx, "opcode tls-set-reg");
5633 case OP_GC_SAFE_POINT: {
5634 LLVMValueRef val, cmp, callee;
5635 LLVMBasicBlockRef poll_bb, cont_bb;
5636 static LLVMTypeRef sig;
5637 const char *icall_name = "mono_threads_state_poll";
5640 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5644 * mono_threads_state_poll ();
5645 * FIXME: Use a preserveall wrapper
5647 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5648 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5649 poll_bb = gen_bb (ctx, "POLL_BB");
5650 cont_bb = gen_bb (ctx, "CONT_BB");
5651 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5653 ctx->builder = builder = create_builder (ctx);
5654 LLVMPositionBuilderAtEnd (builder, poll_bb);
5656 if (ctx->cfg->compile_aot) {
5657 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5659 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5660 callee = emit_jit_callee (ctx, icall_name, sig, target);
5662 LLVMBuildCall (builder, callee, NULL, 0, "");
5663 LLVMBuildBr (builder, cont_bb);
5665 ctx->builder = builder = create_builder (ctx);
5666 LLVMPositionBuilderAtEnd (builder, cont_bb);
5667 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5675 case OP_IADD_OVF_UN:
5677 case OP_ISUB_OVF_UN:
5679 case OP_IMUL_OVF_UN:
5681 case OP_LADD_OVF_UN:
5683 case OP_LSUB_OVF_UN:
5685 case OP_LMUL_OVF_UN:
5687 LLVMValueRef args [2], val, ovf, func;
5689 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5690 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5691 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5693 val = LLVMBuildCall (builder, func, args, 2, "");
5694 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5695 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5696 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5699 builder = ctx->builder;
5705 * We currently model them using arrays. Promotion to local vregs is
5706 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5707 * so we always have an entry in cfg->varinfo for them.
5708 * FIXME: Is this needed ?
5711 MonoClass *klass = ins->klass;
5712 LLVMValueRef args [5];
5716 set_failure (ctx, "!klass");
5720 if (!addresses [ins->dreg])
5721 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5722 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5723 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5724 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5726 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5727 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5728 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5731 case OP_DUMMY_VZERO:
5734 case OP_STOREV_MEMBASE:
5735 case OP_LOADV_MEMBASE:
5737 MonoClass *klass = ins->klass;
5738 LLVMValueRef src = NULL, dst, args [5];
5739 gboolean done = FALSE;
5743 set_failure (ctx, "!klass");
5747 if (mini_is_gsharedvt_klass (klass)) {
5749 set_failure (ctx, "gsharedvt");
5753 switch (ins->opcode) {
5754 case OP_STOREV_MEMBASE:
5755 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5756 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5757 /* Decomposed earlier */
5758 g_assert_not_reached ();
5761 if (!addresses [ins->sreg1]) {
5763 g_assert (values [ins->sreg1]);
5764 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));
5765 LLVMBuildStore (builder, values [ins->sreg1], dst);
5768 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5769 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5772 case OP_LOADV_MEMBASE:
5773 if (!addresses [ins->dreg])
5774 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5775 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5776 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5779 if (!addresses [ins->sreg1])
5780 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5781 if (!addresses [ins->dreg])
5782 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5783 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5784 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5787 g_assert_not_reached ();
5797 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5798 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5800 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5801 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5802 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5805 case OP_LLVM_OUTARG_VT: {
5806 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5807 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5809 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5810 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5812 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5813 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5815 g_assert (addresses [ins->sreg1]);
5816 addresses [ins->dreg] = addresses [ins->sreg1];
5818 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5819 if (!addresses [ins->sreg1]) {
5820 addresses [ins->sreg1] = build_alloca (ctx, t);
5821 g_assert (values [ins->sreg1]);
5823 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5824 addresses [ins->dreg] = addresses [ins->sreg1];
5826 if (!addresses [ins->sreg1]) {
5827 addresses [ins->sreg1] = build_alloca (ctx, t);
5828 g_assert (values [ins->sreg1]);
5829 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5831 addresses [ins->dreg] = addresses [ins->sreg1];
5835 case OP_OBJC_GET_SELECTOR: {
5836 const char *name = (const char*)ins->inst_p0;
5839 if (!ctx->module->objc_selector_to_var)
5840 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5841 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5843 LLVMValueRef indexes [16];
5845 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5846 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5847 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5848 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5849 mark_as_used (ctx->module, name_var);
5851 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5853 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5854 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5855 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5856 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5857 LLVMSetExternallyInitialized (ref_var, TRUE);
5858 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5859 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5860 mark_as_used (ctx->module, ref_var);
5862 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5866 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5873 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5875 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5878 case OP_LOADX_MEMBASE: {
5879 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5882 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5883 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5886 case OP_STOREX_MEMBASE: {
5887 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5890 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5891 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5898 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5902 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5908 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5912 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5916 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5920 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5923 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5926 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5929 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5933 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5944 LLVMValueRef v = NULL;
5946 switch (ins->opcode) {
5951 t = LLVMVectorType (LLVMInt32Type (), 4);
5952 rt = LLVMVectorType (LLVMFloatType (), 4);
5958 t = LLVMVectorType (LLVMInt64Type (), 2);
5959 rt = LLVMVectorType (LLVMDoubleType (), 2);
5962 t = LLVMInt32Type ();
5963 rt = LLVMInt32Type ();
5964 g_assert_not_reached ();
5967 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5968 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5969 switch (ins->opcode) {
5972 v = LLVMBuildAnd (builder, lhs, rhs, "");
5976 v = LLVMBuildOr (builder, lhs, rhs, "");
5980 v = LLVMBuildXor (builder, lhs, rhs, "");
5984 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5987 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5993 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
5994 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6000 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6001 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6005 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6006 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6023 case OP_PADDB_SAT_UN:
6024 case OP_PADDW_SAT_UN:
6025 case OP_PSUBB_SAT_UN:
6026 case OP_PSUBW_SAT_UN:
6034 case OP_PMULW_HIGH_UN: {
6035 LLVMValueRef args [2];
6040 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6047 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6051 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6059 case OP_EXTRACTX_U2:
6061 case OP_EXTRACT_U1: {
6063 gboolean zext = FALSE;
6065 t = simd_op_to_llvm_type (ins->opcode);
6067 switch (ins->opcode) {
6075 case OP_EXTRACTX_U2:
6080 t = LLVMInt32Type ();
6081 g_assert_not_reached ();
6084 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6085 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6087 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6096 case OP_EXPAND_R8: {
6097 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6098 LLVMValueRef mask [16], v;
6101 for (i = 0; i < 16; ++i)
6102 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6104 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6106 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6107 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6112 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6115 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6118 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6121 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6124 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6127 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6131 // Requires a later llvm version
6133 LLVMValueRef indexes [16];
6135 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6136 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6137 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6138 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6139 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6143 LLVMValueRef indexes [16];
6145 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6146 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6147 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6148 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6149 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6153 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6165 case OP_EXTRACT_MASK:
6172 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6174 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6179 LLVMRealPredicate op;
6181 switch (ins->inst_c0) {
6191 case SIMD_COMP_UNORD:
6207 g_assert_not_reached ();
6210 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6211 if (ins->opcode == OP_COMPPD)
6212 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6214 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6218 /* This is only used for implementing shifts by non-immediate */
6219 values [ins->dreg] = lhs;
6230 LLVMValueRef args [3];
6233 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6235 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6246 case OP_PSHLQ_REG: {
6247 LLVMValueRef args [3];
6250 args [1] = values [ins->sreg2];
6252 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6259 case OP_PSHUFLEW_LOW:
6260 case OP_PSHUFLEW_HIGH: {
6262 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6263 int i, mask_size = 0;
6264 int imask = ins->inst_c0;
6266 /* Convert the x86 shuffle mask to LLVM's */
6267 switch (ins->opcode) {
6270 mask [0] = ((imask >> 0) & 3);
6271 mask [1] = ((imask >> 2) & 3);
6272 mask [2] = ((imask >> 4) & 3) + 4;
6273 mask [3] = ((imask >> 6) & 3) + 4;
6274 v1 = values [ins->sreg1];
6275 v2 = values [ins->sreg2];
6279 mask [0] = ((imask >> 0) & 1);
6280 mask [1] = ((imask >> 1) & 1) + 2;
6281 v1 = values [ins->sreg1];
6282 v2 = values [ins->sreg2];
6284 case OP_PSHUFLEW_LOW:
6286 mask [0] = ((imask >> 0) & 3);
6287 mask [1] = ((imask >> 2) & 3);
6288 mask [2] = ((imask >> 4) & 3);
6289 mask [3] = ((imask >> 6) & 3);
6294 v1 = values [ins->sreg1];
6295 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6297 case OP_PSHUFLEW_HIGH:
6303 mask [4] = 4 + ((imask >> 0) & 3);
6304 mask [5] = 4 + ((imask >> 2) & 3);
6305 mask [6] = 4 + ((imask >> 4) & 3);
6306 mask [7] = 4 + ((imask >> 6) & 3);
6307 v1 = values [ins->sreg1];
6308 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6312 mask [0] = ((imask >> 0) & 3);
6313 mask [1] = ((imask >> 2) & 3);
6314 mask [2] = ((imask >> 4) & 3);
6315 mask [3] = ((imask >> 6) & 3);
6316 v1 = values [ins->sreg1];
6317 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6320 g_assert_not_reached ();
6322 for (i = 0; i < mask_size; ++i)
6323 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6325 values [ins->dreg] =
6326 LLVMBuildShuffleVector (builder, v1, v2,
6327 LLVMConstVector (mask_values, mask_size), dname);
6331 case OP_UNPACK_LOWB:
6332 case OP_UNPACK_LOWW:
6333 case OP_UNPACK_LOWD:
6334 case OP_UNPACK_LOWQ:
6335 case OP_UNPACK_LOWPS:
6336 case OP_UNPACK_LOWPD:
6337 case OP_UNPACK_HIGHB:
6338 case OP_UNPACK_HIGHW:
6339 case OP_UNPACK_HIGHD:
6340 case OP_UNPACK_HIGHQ:
6341 case OP_UNPACK_HIGHPS:
6342 case OP_UNPACK_HIGHPD: {
6344 LLVMValueRef mask_values [16];
6345 int i, mask_size = 0;
6346 gboolean low = FALSE;
6348 switch (ins->opcode) {
6349 case OP_UNPACK_LOWB:
6353 case OP_UNPACK_LOWW:
6357 case OP_UNPACK_LOWD:
6358 case OP_UNPACK_LOWPS:
6362 case OP_UNPACK_LOWQ:
6363 case OP_UNPACK_LOWPD:
6367 case OP_UNPACK_HIGHB:
6370 case OP_UNPACK_HIGHW:
6373 case OP_UNPACK_HIGHD:
6374 case OP_UNPACK_HIGHPS:
6377 case OP_UNPACK_HIGHQ:
6378 case OP_UNPACK_HIGHPD:
6382 g_assert_not_reached ();
6386 for (i = 0; i < (mask_size / 2); ++i) {
6388 mask [(i * 2) + 1] = mask_size + i;
6391 for (i = 0; i < (mask_size / 2); ++i) {
6392 mask [(i * 2)] = (mask_size / 2) + i;
6393 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6397 for (i = 0; i < mask_size; ++i)
6398 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6400 values [ins->dreg] =
6401 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6402 LLVMConstVector (mask_values, mask_size), dname);
6407 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6408 LLVMValueRef v, val;
6410 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6411 val = LLVMConstNull (t);
6412 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6413 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6415 values [ins->dreg] = val;
6419 case OP_DUPPS_HIGH: {
6420 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6421 LLVMValueRef v1, v2, val;
6424 if (ins->opcode == OP_DUPPS_LOW) {
6425 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6426 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6428 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6429 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6431 val = LLVMConstNull (t);
6432 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6433 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6434 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6435 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6437 values [ins->dreg] = val;
6447 * EXCEPTION HANDLING
6449 case OP_IMPLICIT_EXCEPTION:
6450 /* This marks a place where an implicit exception can happen */
6451 if (bb->region != -1)
6452 set_failure (ctx, "implicit-exception");
6456 gboolean rethrow = (ins->opcode == OP_RETHROW);
6457 if (ctx->llvm_only) {
6458 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6459 has_terminator = TRUE;
6460 ctx->unreachable [bb->block_num] = TRUE;
6462 emit_throw (ctx, bb, rethrow, lhs);
6463 builder = ctx->builder;
6467 case OP_CALL_HANDLER: {
6469 * We don't 'call' handlers, but instead simply branch to them.
6470 * The code generated by ENDFINALLY will branch back to us.
6472 LLVMBasicBlockRef noex_bb;
6474 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6476 bb_list = info->call_handler_return_bbs;
6479 * Set the indicator variable for the finally clause.
6481 lhs = info->finally_ind;
6483 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6485 /* Branch to the finally clause */
6486 LLVMBuildBr (builder, info->call_handler_target_bb);
6488 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6489 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6491 builder = ctx->builder = create_builder (ctx);
6492 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6494 bblocks [bb->block_num].end_bblock = noex_bb;
6497 case OP_START_HANDLER: {
6500 case OP_ENDFINALLY: {
6501 LLVMBasicBlockRef resume_bb;
6502 MonoBasicBlock *handler_bb;
6503 LLVMValueRef val, switch_ins, callee;
6507 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6508 g_assert (handler_bb);
6509 info = &bblocks [handler_bb->block_num];
6510 lhs = info->finally_ind;
6513 bb_list = info->call_handler_return_bbs;
6515 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6517 /* Load the finally variable */
6518 val = LLVMBuildLoad (builder, lhs, "");
6520 /* Reset the variable */
6521 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6523 /* Branch to either resume_bb, or to the bblocks in bb_list */
6524 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6526 * The other targets are added at the end to handle OP_CALL_HANDLER
6527 * opcodes processed later.
6529 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6531 builder = ctx->builder = create_builder (ctx);
6532 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6534 if (ctx->llvm_only) {
6535 emit_resume_eh (ctx, bb);
6537 if (ctx->cfg->compile_aot) {
6538 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6540 #if LLVM_API_VERSION > 100
6541 MonoJitICallInfo *info;
6543 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6545 gpointer target = (void*)info->func;
6546 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6547 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6549 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6552 LLVMBuildCall (builder, callee, NULL, 0, "");
6553 LLVMBuildUnreachable (builder);
6556 has_terminator = TRUE;
6559 case OP_IL_SEQ_POINT:
6564 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6565 set_failure (ctx, reason);
6573 /* Convert the value to the type required by phi nodes */
6574 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6575 if (ctx->is_vphi [ins->dreg])
6577 values [ins->dreg] = addresses [ins->dreg];
6579 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6582 /* Add stores for volatile variables */
6583 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6584 emit_volatile_store (ctx, ins->dreg);
6590 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6591 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6594 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6595 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6596 LLVMBuildRetVoid (builder);
6599 if (bb == cfg->bb_entry)
6600 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6604 * mono_llvm_check_method_supported:
6606 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6607 * compiling a method twice.
6610 mono_llvm_check_method_supported (MonoCompile *cfg)
6617 if (cfg->method->save_lmf) {
6618 cfg->exception_message = g_strdup ("lmf");
6619 cfg->disable_llvm = TRUE;
6621 if (cfg->disable_llvm)
6625 * Nested clauses where one of the clauses is a finally clause is
6626 * not supported, because LLVM can't figure out the control flow,
6627 * probably because we resume exception handling by calling our
6628 * own function instead of using the 'resume' llvm instruction.
6630 for (i = 0; i < cfg->header->num_clauses; ++i) {
6631 for (j = 0; j < cfg->header->num_clauses; ++j) {
6632 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6633 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6635 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6636 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6637 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6638 cfg->exception_message = g_strdup ("nested clauses");
6639 cfg->disable_llvm = TRUE;
6644 if (cfg->disable_llvm)
6648 if (cfg->method->dynamic) {
6649 cfg->exception_message = g_strdup ("dynamic.");
6650 cfg->disable_llvm = TRUE;
6652 if (cfg->disable_llvm)
6656 static LLVMCallInfo*
6657 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6659 LLVMCallInfo *linfo;
6662 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6666 * Gsharedvt methods have the following calling convention:
6667 * - all arguments are passed by ref, even non generic ones
6668 * - the return value is returned by ref too, using a vret
6669 * argument passed after 'this'.
6671 n = sig->param_count + sig->hasthis;
6672 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6676 linfo->args [pindex ++].storage = LLVMArgNormal;
6678 if (sig->ret->type != MONO_TYPE_VOID) {
6679 if (mini_is_gsharedvt_variable_type (sig->ret))
6680 linfo->ret.storage = LLVMArgGsharedvtVariable;
6681 else if (mini_type_is_vtype (sig->ret))
6682 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6684 linfo->ret.storage = LLVMArgGsharedvtFixed;
6685 linfo->vret_arg_index = pindex;
6687 linfo->ret.storage = LLVMArgNone;
6690 for (i = 0; i < sig->param_count; ++i) {
6691 if (sig->params [i]->byref)
6692 linfo->args [pindex].storage = LLVMArgNormal;
6693 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6694 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6695 else if (mini_type_is_vtype (sig->params [i]))
6696 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6698 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6699 linfo->args [pindex].type = sig->params [i];
6706 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6707 for (i = 0; i < sig->param_count; ++i)
6708 linfo->args [i + sig->hasthis].type = sig->params [i];
6714 emit_method_inner (EmitContext *ctx);
6717 free_ctx (EmitContext *ctx)
6721 g_free (ctx->values);
6722 g_free (ctx->addresses);
6723 g_free (ctx->vreg_types);
6724 g_free (ctx->is_vphi);
6725 g_free (ctx->vreg_cli_types);
6726 g_free (ctx->is_dead);
6727 g_free (ctx->unreachable);
6728 g_ptr_array_free (ctx->phi_values, TRUE);
6729 g_free (ctx->bblocks);
6730 g_hash_table_destroy (ctx->region_to_handler);
6731 g_hash_table_destroy (ctx->clause_to_handler);
6732 g_hash_table_destroy (ctx->jit_callees);
6734 GHashTableIter iter;
6735 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6736 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6739 g_hash_table_destroy (ctx->method_to_callers);
6741 g_free (ctx->method_name);
6742 g_ptr_array_free (ctx->bblock_list, TRUE);
6744 for (l = ctx->builders; l; l = l->next) {
6745 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6746 LLVMDisposeBuilder (builder);
6753 * mono_llvm_emit_method:
6755 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6758 mono_llvm_emit_method (MonoCompile *cfg)
6762 gboolean is_linkonce = FALSE;
6765 /* The code below might acquire the loader lock, so use it for global locking */
6766 mono_loader_lock ();
6768 /* Used to communicate with the callbacks */
6769 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6771 ctx = g_new0 (EmitContext, 1);
6773 ctx->mempool = cfg->mempool;
6776 * This maps vregs to the LLVM instruction defining them
6778 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6780 * This maps vregs for volatile variables to the LLVM instruction defining their
6783 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6784 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6785 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6786 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6787 ctx->phi_values = g_ptr_array_sized_new (256);
6789 * This signals whenever the vreg was defined by a phi node with no input vars
6790 * (i.e. all its input bblocks end with NOT_REACHABLE).
6792 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6793 /* Whenever the bblock is unreachable */
6794 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6795 ctx->bblock_list = g_ptr_array_sized_new (256);
6797 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6798 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6799 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6800 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6801 if (cfg->compile_aot) {
6802 ctx->module = &aot_module;
6806 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6807 * linkage for them. This requires the following:
6808 * - the method needs to have a unique mangled name
6809 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6811 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6813 method_name = mono_aot_get_mangled_method_name (cfg->method);
6815 is_linkonce = FALSE;
6818 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6820 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6824 method_name = mono_aot_get_method_name (cfg);
6825 cfg->llvm_method_name = g_strdup (method_name);
6827 init_jit_module (cfg->domain);
6828 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6829 method_name = mono_method_full_name (cfg->method, TRUE);
6831 ctx->method_name = method_name;
6832 ctx->is_linkonce = is_linkonce;
6834 #if LLVM_API_VERSION > 100
6835 if (cfg->compile_aot)
6836 ctx->lmodule = ctx->module->lmodule;
6838 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6840 ctx->lmodule = ctx->module->lmodule;
6842 ctx->llvm_only = ctx->module->llvm_only;
6844 emit_method_inner (ctx);
6846 if (!ctx_ok (ctx)) {
6848 /* Need to add unused phi nodes as they can be referenced by other values */
6849 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6850 LLVMBuilderRef builder;
6852 builder = create_builder (ctx);
6853 LLVMPositionBuilderAtEnd (builder, phi_bb);
6855 for (i = 0; i < ctx->phi_values->len; ++i) {
6856 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6857 if (LLVMGetInstructionParent (v) == NULL)
6858 LLVMInsertIntoBuilder (builder, v);
6861 LLVMDeleteFunction (ctx->lmethod);
6867 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6869 mono_loader_unlock ();
6873 emit_method_inner (EmitContext *ctx)
6875 MonoCompile *cfg = ctx->cfg;
6876 MonoMethodSignature *sig;
6878 LLVMTypeRef method_type;
6879 LLVMValueRef method = NULL;
6880 LLVMValueRef *values = ctx->values;
6881 int i, max_block_num, bb_index;
6882 gboolean last = FALSE;
6883 LLVMCallInfo *linfo;
6884 LLVMModuleRef lmodule = ctx->lmodule;
6886 GPtrArray *bblock_list = ctx->bblock_list;
6887 MonoMethodHeader *header;
6888 MonoExceptionClause *clause;
6891 if (cfg->gsharedvt && !cfg->llvm_only) {
6892 set_failure (ctx, "gsharedvt");
6898 static int count = 0;
6901 if (g_getenv ("LLVM_COUNT")) {
6902 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6903 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6907 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6908 set_failure (ctx, "count");
6915 sig = mono_method_signature (cfg->method);
6918 linfo = get_llvm_call_info (cfg, sig);
6924 linfo->rgctx_arg = TRUE;
6925 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6929 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6930 ctx->lmethod = method;
6932 if (!cfg->llvm_only)
6933 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6934 LLVMSetLinkage (method, LLVMPrivateLinkage);
6936 LLVMAddFunctionAttr (method, LLVMUWTable);
6938 if (cfg->compile_aot) {
6939 LLVMSetLinkage (method, LLVMInternalLinkage);
6940 if (ctx->module->external_symbols) {
6941 LLVMSetLinkage (method, LLVMExternalLinkage);
6942 LLVMSetVisibility (method, LLVMHiddenVisibility);
6944 if (ctx->is_linkonce) {
6945 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6946 LLVMSetVisibility (method, LLVMDefaultVisibility);
6949 #if LLVM_API_VERSION > 100
6950 LLVMSetLinkage (method, LLVMExternalLinkage);
6952 LLVMSetLinkage (method, LLVMPrivateLinkage);
6956 if (cfg->method->save_lmf && !cfg->llvm_only) {
6957 set_failure (ctx, "lmf");
6961 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6962 set_failure (ctx, "pinvoke signature");
6966 header = cfg->header;
6967 for (i = 0; i < header->num_clauses; ++i) {
6968 clause = &header->clauses [i];
6969 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6970 set_failure (ctx, "non-finally/catch clause.");
6974 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6975 /* We can't handle inlined methods with clauses */
6976 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6978 if (linfo->rgctx_arg) {
6979 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6980 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6982 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6983 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6984 * CC_X86_64_Mono in X86CallingConv.td.
6986 if (!ctx->llvm_only)
6987 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6988 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6990 ctx->rgctx_arg_pindex = -1;
6992 if (cfg->vret_addr) {
6993 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6994 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6995 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6996 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6997 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7002 ctx->this_arg_pindex = linfo->this_arg_pindex;
7003 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7004 values [cfg->args [0]->dreg] = ctx->this_arg;
7005 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7008 names = g_new (char *, sig->param_count);
7009 mono_method_get_param_names (cfg->method, (const char **) names);
7011 /* Set parameter names/attributes */
7012 for (i = 0; i < sig->param_count; ++i) {
7013 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7015 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7018 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7019 name = g_strdup_printf ("dummy_%d_%d", i, j);
7020 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7024 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7027 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7028 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7029 if (names [i] && names [i][0] != '\0')
7030 name = g_strdup_printf ("p_arg_%s", names [i]);
7032 name = g_strdup_printf ("p_arg_%d", i);
7034 if (names [i] && names [i][0] != '\0')
7035 name = g_strdup_printf ("arg_%s", names [i]);
7037 name = g_strdup_printf ("arg_%d", i);
7039 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7041 if (ainfo->storage == LLVMArgVtypeByVal)
7042 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7044 if (ainfo->storage == LLVMArgVtypeByRef) {
7046 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7051 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7052 ctx->minfo = mono_debug_lookup_method (cfg->method);
7053 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7057 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7058 max_block_num = MAX (max_block_num, bb->block_num);
7059 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7061 /* Add branches between non-consecutive bblocks */
7062 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7063 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7064 bb->next_bb != bb->last_ins->inst_false_bb) {
7066 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7067 inst->opcode = OP_BR;
7068 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7069 mono_bblock_add_inst (bb, inst);
7074 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7075 * was later optimized away, so clear these flags, and add them back for the still
7076 * present OP_LDADDR instructions.
7078 for (i = 0; i < cfg->next_vreg; ++i) {
7081 ins = get_vreg_to_inst (cfg, i);
7082 if (ins && ins != cfg->rgctx_var)
7083 ins->flags &= ~MONO_INST_INDIRECT;
7087 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7089 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7091 LLVMBuilderRef builder;
7093 char dname_buf[128];
7095 builder = create_builder (ctx);
7097 for (ins = bb->code; ins; ins = ins->next) {
7098 switch (ins->opcode) {
7103 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7108 if (ins->opcode == OP_VPHI) {
7109 /* Treat valuetype PHI nodes as operating on the address itself */
7110 g_assert (ins->klass);
7111 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7115 * Have to precreate these, as they can be referenced by
7116 * earlier instructions.
7118 sprintf (dname_buf, "t%d", ins->dreg);
7120 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7122 if (ins->opcode == OP_VPHI)
7123 ctx->addresses [ins->dreg] = values [ins->dreg];
7125 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7128 * Set the expected type of the incoming arguments since these have
7129 * to have the same type.
7131 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7132 int sreg1 = ins->inst_phi_args [i + 1];
7135 if (ins->opcode == OP_VPHI)
7136 ctx->is_vphi [sreg1] = TRUE;
7137 ctx->vreg_types [sreg1] = phi_type;
7143 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7152 * Create an ordering for bblocks, use the depth first order first, then
7153 * put the exception handling bblocks last.
7155 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7156 bb = cfg->bblocks [bb_index];
7157 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7158 g_ptr_array_add (bblock_list, bb);
7159 bblocks [bb->block_num].added = TRUE;
7163 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7164 if (!bblocks [bb->block_num].added)
7165 g_ptr_array_add (bblock_list, bb);
7169 * Second pass: generate code.
7172 LLVMBuilderRef entry_builder = create_builder (ctx);
7173 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7174 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7175 emit_entry_bb (ctx, entry_builder);
7177 // Make landing pads first
7178 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7180 if (ctx->llvm_only) {
7181 size_t group_index = 0;
7182 while (group_index < cfg->header->num_clauses) {
7184 size_t cursor = group_index;
7185 while (cursor < cfg->header->num_clauses &&
7186 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7187 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7192 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7193 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7194 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7196 group_index = cursor;
7200 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7201 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7203 // Prune unreachable mono BBs.
7204 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7207 process_bb (ctx, bb);
7211 g_hash_table_destroy (ctx->exc_meta);
7213 mono_memory_barrier ();
7215 /* Add incoming phi values */
7216 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7217 GSList *l, *ins_list;
7219 ins_list = bblocks [bb->block_num].phi_nodes;
7221 for (l = ins_list; l; l = l->next) {
7222 PhiNode *node = (PhiNode*)l->data;
7223 MonoInst *phi = node->phi;
7224 int sreg1 = node->sreg;
7225 LLVMBasicBlockRef in_bb;
7230 in_bb = get_end_bb (ctx, node->in_bb);
7232 if (ctx->unreachable [node->in_bb->block_num])
7235 if (!values [sreg1]) {
7236 /* Can happen with values in EH clauses */
7237 set_failure (ctx, "incoming phi sreg1");
7241 if (phi->opcode == OP_VPHI) {
7242 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7243 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7245 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7246 set_failure (ctx, "incoming phi arg type mismatch");
7249 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7250 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7255 /* Nullify empty phi instructions */
7256 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7257 GSList *l, *ins_list;
7259 ins_list = bblocks [bb->block_num].phi_nodes;
7261 for (l = ins_list; l; l = l->next) {
7262 PhiNode *node = (PhiNode*)l->data;
7263 MonoInst *phi = node->phi;
7264 LLVMValueRef phi_ins = values [phi->dreg];
7267 /* Already removed */
7270 if (LLVMCountIncoming (phi_ins) == 0) {
7271 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7272 LLVMInstructionEraseFromParent (phi_ins);
7273 values [phi->dreg] = NULL;
7278 /* Create the SWITCH statements for ENDFINALLY instructions */
7279 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7280 BBInfo *info = &bblocks [bb->block_num];
7282 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7283 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7284 GSList *bb_list = info->call_handler_return_bbs;
7286 for (i = 0; i < g_slist_length (bb_list); ++i)
7287 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7291 /* Initialize the method if needed */
7292 if (cfg->compile_aot && ctx->llvm_only) {
7293 // FIXME: Add more shared got entries
7294 ctx->builder = create_builder (ctx);
7295 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7297 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7299 // FIXME: beforefieldinit
7301 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7302 * in load_method ().
7304 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7306 * linkonce methods shouldn't have initialization,
7307 * because they might belong to assemblies which
7308 * haven't been loaded yet.
7310 g_assert (!ctx->is_linkonce);
7311 emit_init_method (ctx);
7313 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7317 if (cfg->llvm_only) {
7318 GHashTableIter iter;
7320 GSList *callers, *l, *l2;
7323 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7324 * We can't do this earlier, as it contains llvm instructions which can be
7325 * freed if compilation fails.
7326 * FIXME: Get rid of this when all methods can be llvm compiled.
7328 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7329 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7330 for (l = callers; l; l = l->next) {
7331 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7332 l2 = g_slist_prepend (l2, l->data);
7333 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7338 if (cfg->verbose_level > 1)
7339 mono_llvm_dump_value (method);
7341 if (cfg->compile_aot && !cfg->llvm_only)
7342 mark_as_used (ctx->module, method);
7344 if (!cfg->llvm_only) {
7345 LLVMValueRef md_args [16];
7346 LLVMValueRef md_node;
7349 if (cfg->compile_aot)
7350 method_index = mono_aot_get_method_index (cfg->orig_method);
7353 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7354 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7355 md_node = LLVMMDNode (md_args, 2);
7356 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7357 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7360 if (cfg->compile_aot) {
7361 /* Don't generate native code, keep the LLVM IR */
7362 if (cfg->verbose_level)
7363 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7365 #if LLVM_API_VERSION < 100
7366 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7367 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7368 g_assert (err == 0);
7371 //LLVMVerifyFunction(method, 0);
7372 #if LLVM_API_VERSION > 100
7373 MonoDomain *domain = mono_domain_get ();
7374 MonoJitDomainInfo *domain_info;
7375 int nvars = g_hash_table_size (ctx->jit_callees);
7376 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7377 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7378 GHashTableIter iter;
7384 * Compute the addresses of the LLVM globals pointing to the
7385 * methods called by the current method. Pass it to the trampoline
7386 * code so it can update them after their corresponding method was
7389 g_hash_table_iter_init (&iter, ctx->jit_callees);
7391 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7392 callee_vars [i ++] = var;
7394 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7396 decode_llvm_eh_info (ctx, eh_frame);
7398 mono_domain_lock (domain);
7399 domain_info = domain_jit_info (domain);
7400 if (!domain_info->llvm_jit_callees)
7401 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7402 g_hash_table_iter_init (&iter, ctx->jit_callees);
7404 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7405 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7406 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7407 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7410 mono_domain_unlock (domain);
7412 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7414 if (cfg->verbose_level > 1)
7415 mono_llvm_dump_value (ctx->lmethod);
7417 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7419 /* Set by emit_cb */
7420 g_assert (cfg->code_len);
7424 if (ctx->module->method_to_lmethod)
7425 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7426 if (ctx->module->idx_to_lmethod)
7427 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7429 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7430 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7434 * mono_llvm_create_vars:
7436 * Same as mono_arch_create_vars () for LLVM.
7439 mono_llvm_create_vars (MonoCompile *cfg)
7441 MonoMethodSignature *sig;
7443 sig = mono_method_signature (cfg->method);
7444 if (cfg->gsharedvt && cfg->llvm_only) {
7445 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7446 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7447 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7448 printf ("vret_addr = ");
7449 mono_print_ins (cfg->vret_addr);
7453 mono_arch_create_vars (cfg);
7458 * mono_llvm_emit_call:
7460 * Same as mono_arch_emit_call () for LLVM.
7463 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7466 MonoMethodSignature *sig;
7467 int i, n, stack_size;
7472 sig = call->signature;
7473 n = sig->param_count + sig->hasthis;
7475 call->cinfo = get_llvm_call_info (cfg, sig);
7477 if (cfg->disable_llvm)
7480 if (sig->call_convention == MONO_CALL_VARARG) {
7481 cfg->exception_message = g_strdup ("varargs");
7482 cfg->disable_llvm = TRUE;
7485 for (i = 0; i < n; ++i) {
7488 ainfo = call->cinfo->args + i;
7490 in = call->args [i];
7492 /* Simply remember the arguments */
7493 switch (ainfo->storage) {
7494 case LLVMArgNormal: {
7495 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7498 opcode = mono_type_to_regmove (cfg, t);
7499 if (opcode == OP_FMOVE) {
7500 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7501 ins->dreg = mono_alloc_freg (cfg);
7502 } else if (opcode == OP_LMOVE) {
7503 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7504 ins->dreg = mono_alloc_lreg (cfg);
7505 } else if (opcode == OP_RMOVE) {
7506 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7507 ins->dreg = mono_alloc_freg (cfg);
7509 MONO_INST_NEW (cfg, ins, OP_MOVE);
7510 ins->dreg = mono_alloc_ireg (cfg);
7512 ins->sreg1 = in->dreg;
7515 case LLVMArgVtypeByVal:
7516 case LLVMArgVtypeByRef:
7517 case LLVMArgVtypeInReg:
7518 case LLVMArgVtypeAsScalar:
7519 case LLVMArgAsIArgs:
7520 case LLVMArgAsFpArgs:
7521 case LLVMArgGsharedvtVariable:
7522 case LLVMArgGsharedvtFixed:
7523 case LLVMArgGsharedvtFixedVtype:
7524 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7525 ins->dreg = mono_alloc_ireg (cfg);
7526 ins->sreg1 = in->dreg;
7527 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7528 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7529 ins->inst_vtype = ainfo->type;
7530 ins->klass = mono_class_from_mono_type (ainfo->type);
7533 cfg->exception_message = g_strdup ("ainfo->storage");
7534 cfg->disable_llvm = TRUE;
7538 if (!cfg->disable_llvm) {
7539 MONO_ADD_INS (cfg->cbb, ins);
7540 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7545 static unsigned char*
7546 alloc_cb (LLVMValueRef function, int size)
7550 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7554 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7556 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7561 emitted_cb (LLVMValueRef function, void *start, void *end)
7565 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7567 cfg->code_len = (guint8*)end - (guint8*)start;
7571 exception_cb (void *data)
7574 MonoJitExceptionInfo *ei;
7575 guint32 ei_len, i, j, nested_len, nindex;
7576 gpointer *type_info;
7577 int this_reg, this_offset;
7579 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7583 * data points to a DWARF FDE structure, convert it to our unwind format and
7585 * An alternative would be to save it directly, and modify our unwinder to work
7588 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);
7589 if (cfg->verbose_level > 1)
7590 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7592 /* Count nested clauses */
7594 for (i = 0; i < ei_len; ++i) {
7595 gint32 cindex1 = *(gint32*)type_info [i];
7596 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7598 for (j = 0; j < cfg->header->num_clauses; ++j) {
7600 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7602 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7608 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7609 cfg->llvm_ex_info_len = ei_len + nested_len;
7610 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7611 /* Fill the rest of the information from the type info */
7612 for (i = 0; i < ei_len; ++i) {
7613 gint32 clause_index = *(gint32*)type_info [i];
7614 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7616 cfg->llvm_ex_info [i].flags = clause->flags;
7617 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7618 cfg->llvm_ex_info [i].clause_index = clause_index;
7622 * For nested clauses, the LLVM produced exception info associates the try interval with
7623 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7624 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7625 * and everything else from the nested clause.
7628 for (i = 0; i < ei_len; ++i) {
7629 gint32 cindex1 = *(gint32*)type_info [i];
7630 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7632 for (j = 0; j < cfg->header->num_clauses; ++j) {
7634 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7635 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7637 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7638 /* clause1 is the nested clause */
7639 nested_ei = &cfg->llvm_ex_info [i];
7640 nesting_ei = &cfg->llvm_ex_info [nindex];
7643 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7645 nesting_ei->flags = clause2->flags;
7646 nesting_ei->data.catch_class = clause2->data.catch_class;
7647 nesting_ei->clause_index = cindex2;
7651 g_assert (nindex == ei_len + nested_len);
7652 cfg->llvm_this_reg = this_reg;
7653 cfg->llvm_this_offset = this_offset;
7655 /* type_info [i] is cfg mempool allocated, no need to free it */
7661 #if LLVM_API_VERSION > 100
7663 * decode_llvm_eh_info:
7665 * Decode the EH table emitted by llvm in jit mode, and store
7666 * the result into cfg.
7669 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7671 MonoCompile *cfg = ctx->cfg;
7674 MonoLLVMFDEInfo info;
7675 MonoJitExceptionInfo *ei;
7676 guint8 *p = eh_frame;
7677 int version, fde_count, fde_offset;
7678 guint32 ei_len, i, nested_len;
7679 gpointer *type_info;
7683 * Decode the one element EH table emitted by the MonoException class
7687 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7690 g_assert (version == 3);
7693 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7695 fde_count = *(guint32*)p;
7699 g_assert (fde_count <= 2);
7701 /* The first entry is the real method */
7702 g_assert (table [0] == 1);
7703 fde_offset = table [1];
7704 table += fde_count * 2;
7706 cfg->code_len = table [0];
7707 fde_len = table [1] - fde_offset;
7710 fde = (guint8*)eh_frame + fde_offset;
7711 cie = (guint8*)table;
7713 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7715 cfg->encoded_unwind_ops = info.unw_info;
7716 cfg->encoded_unwind_ops_len = info.unw_info_len;
7717 if (cfg->verbose_level > 1)
7718 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7719 if (info.this_reg != -1) {
7720 cfg->llvm_this_reg = info.this_reg;
7721 cfg->llvm_this_offset = info.this_offset;
7725 ei_len = info.ex_info_len;
7726 type_info = info.type_info;
7728 // Nested clauses are currently disabled
7731 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7732 cfg->llvm_ex_info_len = ei_len + nested_len;
7733 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7734 /* Fill the rest of the information from the type info */
7735 for (i = 0; i < ei_len; ++i) {
7736 gint32 clause_index = *(gint32*)type_info [i];
7737 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7739 cfg->llvm_ex_info [i].flags = clause->flags;
7740 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7741 cfg->llvm_ex_info [i].clause_index = clause_index;
7747 dlsym_cb (const char *name, void **symbol)
7753 if (!strcmp (name, "__bzero")) {
7754 *symbol = (void*)bzero;
7756 current = mono_dl_open (NULL, 0, NULL);
7759 err = mono_dl_symbol (current, name, symbol);
7761 mono_dl_close (current);
7763 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7764 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7770 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7772 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7776 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7778 LLVMTypeRef param_types [4];
7780 param_types [0] = param_type1;
7781 param_types [1] = param_type2;
7783 AddFunc (module, name, ret_type, param_types, 2);
7789 INTRINS_SADD_OVF_I32,
7790 INTRINS_UADD_OVF_I32,
7791 INTRINS_SSUB_OVF_I32,
7792 INTRINS_USUB_OVF_I32,
7793 INTRINS_SMUL_OVF_I32,
7794 INTRINS_UMUL_OVF_I32,
7795 INTRINS_SADD_OVF_I64,
7796 INTRINS_UADD_OVF_I64,
7797 INTRINS_SSUB_OVF_I64,
7798 INTRINS_USUB_OVF_I64,
7799 INTRINS_SMUL_OVF_I64,
7800 INTRINS_UMUL_OVF_I64,
7807 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7808 INTRINS_SSE_PMOVMSKB,
7809 INTRINS_SSE_PSRLI_W,
7810 INTRINS_SSE_PSRAI_W,
7811 INTRINS_SSE_PSLLI_W,
7812 INTRINS_SSE_PSRLI_D,
7813 INTRINS_SSE_PSRAI_D,
7814 INTRINS_SSE_PSLLI_D,
7815 INTRINS_SSE_PSRLI_Q,
7816 INTRINS_SSE_PSLLI_Q,
7817 INTRINS_SSE_SQRT_PD,
7818 INTRINS_SSE_SQRT_PS,
7819 INTRINS_SSE_RSQRT_PS,
7821 INTRINS_SSE_CVTTPD2DQ,
7822 INTRINS_SSE_CVTTPS2DQ,
7823 INTRINS_SSE_CVTDQ2PD,
7824 INTRINS_SSE_CVTDQ2PS,
7825 INTRINS_SSE_CVTPD2DQ,
7826 INTRINS_SSE_CVTPS2DQ,
7827 INTRINS_SSE_CVTPD2PS,
7828 INTRINS_SSE_CVTPS2PD,
7831 INTRINS_SSE_PACKSSWB,
7832 INTRINS_SSE_PACKUSWB,
7833 INTRINS_SSE_PACKSSDW,
7834 INTRINS_SSE_PACKUSDW,
7839 INTRINS_SSE_ADDSUBPS,
7844 INTRINS_SSE_ADDSUBPD,
7847 INTRINS_SSE_PADDUSW,
7848 INTRINS_SSE_PSUBUSW,
7854 INTRINS_SSE_PADDUSB,
7855 INTRINS_SSE_PSUBUSB,
7867 static IntrinsicDesc intrinsics[] = {
7868 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7869 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7870 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7871 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7872 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7873 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7874 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7875 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7876 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7877 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7878 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7879 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7880 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7881 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7882 {INTRINS_SIN, "llvm.sin.f64"},
7883 {INTRINS_COS, "llvm.cos.f64"},
7884 {INTRINS_SQRT, "llvm.sqrt.f64"},
7885 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7886 {INTRINS_FABS, "fabs"},
7887 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7888 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7889 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7890 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7891 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7892 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7893 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7894 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7895 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7896 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7897 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7898 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7899 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7900 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7901 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7902 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7903 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7904 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7905 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7906 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7907 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7908 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7909 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7910 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7911 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7912 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7913 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7914 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7915 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7916 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7917 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7918 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7919 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7920 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7921 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7922 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7923 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7924 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7925 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7926 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7927 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7928 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7929 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7930 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7931 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7932 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7933 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7934 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7935 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7936 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7937 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7938 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7939 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7944 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7946 LLVMTypeRef ret_type = type_to_simd_type (type);
7947 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7951 add_intrinsic (LLVMModuleRef module, int id)
7954 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7955 LLVMTypeRef ret_type, arg_types [16];
7958 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7962 case INTRINS_MEMSET: {
7963 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7965 AddFunc (module, name, LLVMVoidType (), params, 5);
7968 case INTRINS_MEMCPY: {
7969 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7971 AddFunc (module, name, LLVMVoidType (), params, 5);
7974 case INTRINS_SADD_OVF_I32:
7975 case INTRINS_UADD_OVF_I32:
7976 case INTRINS_SSUB_OVF_I32:
7977 case INTRINS_USUB_OVF_I32:
7978 case INTRINS_SMUL_OVF_I32:
7979 case INTRINS_UMUL_OVF_I32: {
7980 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7981 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7982 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7984 AddFunc (module, name, ret_type, params, 2);
7987 case INTRINS_SADD_OVF_I64:
7988 case INTRINS_UADD_OVF_I64:
7989 case INTRINS_SSUB_OVF_I64:
7990 case INTRINS_USUB_OVF_I64:
7991 case INTRINS_SMUL_OVF_I64:
7992 case INTRINS_UMUL_OVF_I64: {
7993 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7994 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7995 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7997 AddFunc (module, name, ret_type, params, 2);
8003 case INTRINS_FABS: {
8004 LLVMTypeRef params [] = { LLVMDoubleType () };
8006 AddFunc (module, name, LLVMDoubleType (), params, 1);
8009 case INTRINS_EXPECT_I8:
8010 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8012 case INTRINS_EXPECT_I1:
8013 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8015 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8016 case INTRINS_SSE_PMOVMSKB:
8018 ret_type = LLVMInt32Type ();
8019 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8020 AddFunc (module, name, ret_type, arg_types, 1);
8022 case INTRINS_SSE_PSRLI_W:
8023 case INTRINS_SSE_PSRAI_W:
8024 case INTRINS_SSE_PSLLI_W:
8026 ret_type = type_to_simd_type (MONO_TYPE_I2);
8027 arg_types [0] = ret_type;
8028 arg_types [1] = LLVMInt32Type ();
8029 AddFunc (module, name, ret_type, arg_types, 2);
8031 case INTRINS_SSE_PSRLI_D:
8032 case INTRINS_SSE_PSRAI_D:
8033 case INTRINS_SSE_PSLLI_D:
8034 ret_type = type_to_simd_type (MONO_TYPE_I4);
8035 arg_types [0] = ret_type;
8036 arg_types [1] = LLVMInt32Type ();
8037 AddFunc (module, name, ret_type, arg_types, 2);
8039 case INTRINS_SSE_PSRLI_Q:
8040 case INTRINS_SSE_PSLLI_Q:
8041 ret_type = type_to_simd_type (MONO_TYPE_I8);
8042 arg_types [0] = ret_type;
8043 arg_types [1] = LLVMInt32Type ();
8044 AddFunc (module, name, ret_type, arg_types, 2);
8046 case INTRINS_SSE_SQRT_PD:
8048 ret_type = type_to_simd_type (MONO_TYPE_R8);
8049 arg_types [0] = ret_type;
8050 AddFunc (module, name, ret_type, arg_types, 1);
8052 case INTRINS_SSE_SQRT_PS:
8053 ret_type = type_to_simd_type (MONO_TYPE_R4);
8054 arg_types [0] = ret_type;
8055 AddFunc (module, name, ret_type, arg_types, 1);
8057 case INTRINS_SSE_RSQRT_PS:
8058 ret_type = type_to_simd_type (MONO_TYPE_R4);
8059 arg_types [0] = ret_type;
8060 AddFunc (module, name, ret_type, arg_types, 1);
8062 case INTRINS_SSE_RCP_PS:
8063 ret_type = type_to_simd_type (MONO_TYPE_R4);
8064 arg_types [0] = ret_type;
8065 AddFunc (module, name, ret_type, arg_types, 1);
8067 case INTRINS_SSE_CVTTPD2DQ:
8068 ret_type = type_to_simd_type (MONO_TYPE_I4);
8069 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8070 AddFunc (module, name, ret_type, arg_types, 1);
8072 case INTRINS_SSE_CVTTPS2DQ:
8073 ret_type = type_to_simd_type (MONO_TYPE_I4);
8074 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8075 AddFunc (module, name, ret_type, arg_types, 1);
8077 case INTRINS_SSE_CVTDQ2PD:
8078 /* Conversion ops */
8079 ret_type = type_to_simd_type (MONO_TYPE_R8);
8080 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8081 AddFunc (module, name, ret_type, arg_types, 1);
8083 case INTRINS_SSE_CVTDQ2PS:
8084 ret_type = type_to_simd_type (MONO_TYPE_R4);
8085 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8086 AddFunc (module, name, ret_type, arg_types, 1);
8088 case INTRINS_SSE_CVTPD2DQ:
8089 ret_type = type_to_simd_type (MONO_TYPE_I4);
8090 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8091 AddFunc (module, name, ret_type, arg_types, 1);
8093 case INTRINS_SSE_CVTPS2DQ:
8094 ret_type = type_to_simd_type (MONO_TYPE_I4);
8095 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8096 AddFunc (module, name, ret_type, arg_types, 1);
8098 case INTRINS_SSE_CVTPD2PS:
8099 ret_type = type_to_simd_type (MONO_TYPE_R4);
8100 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8101 AddFunc (module, name, ret_type, arg_types, 1);
8103 case INTRINS_SSE_CVTPS2PD:
8104 ret_type = type_to_simd_type (MONO_TYPE_R8);
8105 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8106 AddFunc (module, name, ret_type, arg_types, 1);
8108 case INTRINS_SSE_CMPPD:
8110 ret_type = type_to_simd_type (MONO_TYPE_R8);
8111 arg_types [0] = ret_type;
8112 arg_types [1] = ret_type;
8113 arg_types [2] = LLVMInt8Type ();
8114 AddFunc (module, name, ret_type, arg_types, 3);
8116 case INTRINS_SSE_CMPPS:
8117 ret_type = type_to_simd_type (MONO_TYPE_R4);
8118 arg_types [0] = ret_type;
8119 arg_types [1] = ret_type;
8120 arg_types [2] = LLVMInt8Type ();
8121 AddFunc (module, name, ret_type, arg_types, 3);
8123 case INTRINS_SSE_PACKSSWB:
8124 case INTRINS_SSE_PACKUSWB:
8125 case INTRINS_SSE_PACKSSDW:
8127 ret_type = type_to_simd_type (MONO_TYPE_I1);
8128 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8129 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8130 AddFunc (module, name, ret_type, arg_types, 2);
8132 case INTRINS_SSE_PACKUSDW:
8133 ret_type = type_to_simd_type (MONO_TYPE_I2);
8134 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8135 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8136 AddFunc (module, name, ret_type, arg_types, 2);
8138 /* SSE Binary ops */
8139 case INTRINS_SSE_PADDSW:
8140 case INTRINS_SSE_PSUBSW:
8141 case INTRINS_SSE_PADDUSW:
8142 case INTRINS_SSE_PSUBUSW:
8143 case INTRINS_SSE_PAVGW:
8144 case INTRINS_SSE_PMULHW:
8145 case INTRINS_SSE_PMULHU:
8146 add_sse_binary (module, name, MONO_TYPE_I2);
8148 case INTRINS_SSE_MINPS:
8149 case INTRINS_SSE_MAXPS:
8150 case INTRINS_SSE_HADDPS:
8151 case INTRINS_SSE_HSUBPS:
8152 case INTRINS_SSE_ADDSUBPS:
8153 add_sse_binary (module, name, MONO_TYPE_R4);
8155 case INTRINS_SSE_MINPD:
8156 case INTRINS_SSE_MAXPD:
8157 case INTRINS_SSE_HADDPD:
8158 case INTRINS_SSE_HSUBPD:
8159 case INTRINS_SSE_ADDSUBPD:
8160 add_sse_binary (module, name, MONO_TYPE_R8);
8162 case INTRINS_SE_PADDSB:
8163 case INTRINS_SSE_PSUBSB:
8164 case INTRINS_SSE_PADDUSB:
8165 case INTRINS_SSE_PSUBUSB:
8166 case INTRINS_SSE_PAVGB:
8167 add_sse_binary (module, name, MONO_TYPE_I1);
8169 case INTRINS_SSE_PAUSE:
8170 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8174 g_assert_not_reached ();
8180 get_intrinsic (EmitContext *ctx, const char *name)
8182 #if LLVM_API_VERSION > 100
8186 * Every method is emitted into its own module so
8187 * we can add intrinsics on demand.
8189 res = LLVMGetNamedFunction (ctx->lmodule, name);
8193 /* No locking needed */
8194 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8197 printf ("%s\n", name);
8198 g_assert (id != -1);
8199 add_intrinsic (ctx->lmodule, id);
8200 res = LLVMGetNamedFunction (ctx->lmodule, name);
8208 res = LLVMGetNamedFunction (ctx->lmodule, name);
8215 add_intrinsics (LLVMModuleRef module)
8219 /* Emit declarations of instrinsics */
8221 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8222 * type doesn't seem to do any locking.
8224 for (i = 0; i < INTRINS_NUM; ++i)
8225 add_intrinsic (module, i);
8229 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8231 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8234 /* Load/Store intrinsics */
8236 LLVMTypeRef arg_types [5];
8240 for (i = 1; i <= 8; i *= 2) {
8241 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8242 arg_types [1] = LLVMInt32Type ();
8243 arg_types [2] = LLVMInt1Type ();
8244 arg_types [3] = LLVMInt32Type ();
8245 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8246 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8248 arg_types [0] = LLVMIntType (i * 8);
8249 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8250 arg_types [2] = LLVMInt32Type ();
8251 arg_types [3] = LLVMInt1Type ();
8252 arg_types [4] = LLVMInt32Type ();
8253 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8254 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8260 add_types (MonoLLVMModule *module)
8262 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8266 mono_llvm_init (void)
8271 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8273 h = g_hash_table_new (NULL, NULL);
8274 for (i = 0; i < INTRINS_NUM; ++i)
8275 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8276 intrins_id_to_name = h;
8278 h = g_hash_table_new (g_str_hash, g_str_equal);
8279 for (i = 0; i < INTRINS_NUM; ++i)
8280 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8281 intrins_name_to_id = h;
8285 init_jit_module (MonoDomain *domain)
8287 MonoJitDomainInfo *dinfo;
8288 MonoLLVMModule *module;
8291 dinfo = domain_jit_info (domain);
8292 if (dinfo->llvm_module)
8295 mono_loader_lock ();
8297 if (dinfo->llvm_module) {
8298 mono_loader_unlock ();
8302 module = g_new0 (MonoLLVMModule, 1);
8304 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8305 module->lmodule = LLVMModuleCreateWithName (name);
8306 module->context = LLVMGetGlobalContext ();
8308 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8310 add_intrinsics (module->lmodule);
8313 module->llvm_types = g_hash_table_new (NULL, NULL);
8315 #if LLVM_API_VERSION < 100
8316 MonoJitICallInfo *info;
8318 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8320 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8323 mono_memory_barrier ();
8325 dinfo->llvm_module = module;
8327 mono_loader_unlock ();
8331 mono_llvm_cleanup (void)
8333 MonoLLVMModule *module = &aot_module;
8335 if (module->lmodule)
8336 LLVMDisposeModule (module->lmodule);
8338 if (module->context)
8339 LLVMContextDispose (module->context);
8343 mono_llvm_free_domain_info (MonoDomain *domain)
8345 MonoJitDomainInfo *info = domain_jit_info (domain);
8346 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8352 if (module->llvm_types)
8353 g_hash_table_destroy (module->llvm_types);
8355 mono_llvm_dispose_ee (module->mono_ee);
8357 if (module->bb_names) {
8358 for (i = 0; i < module->bb_names_len; ++i)
8359 g_free (module->bb_names [i]);
8360 g_free (module->bb_names);
8362 //LLVMDisposeModule (module->module);
8366 info->llvm_module = NULL;
8370 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8372 MonoLLVMModule *module = &aot_module;
8374 /* Delete previous module */
8375 if (module->plt_entries)
8376 g_hash_table_destroy (module->plt_entries);
8377 if (module->lmodule)
8378 LLVMDisposeModule (module->lmodule);
8380 memset (module, 0, sizeof (aot_module));
8382 module->lmodule = LLVMModuleCreateWithName ("aot");
8383 module->assembly = assembly;
8384 module->global_prefix = g_strdup (global_prefix);
8385 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8386 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8387 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8388 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8389 module->external_symbols = TRUE;
8390 module->emit_dwarf = emit_dwarf;
8391 module->static_link = static_link;
8392 module->llvm_only = llvm_only;
8393 /* The first few entries are reserved */
8394 module->max_got_offset = 16;
8395 module->context = LLVMGetGlobalContext ();
8398 /* clang ignores our debug info because it has an invalid version */
8399 module->emit_dwarf = FALSE;
8401 add_intrinsics (module->lmodule);
8404 #if LLVM_API_VERSION > 100
8405 if (module->emit_dwarf) {
8406 char *dir, *build_info, *s, *cu_name;
8408 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8411 dir = g_strdup (".");
8412 build_info = mono_get_runtime_build_info ();
8413 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8414 cu_name = g_path_get_basename (assembly->image->name);
8415 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8417 g_free (build_info);
8424 * We couldn't compute the type of the LLVM global representing the got because
8425 * its size is only known after all the methods have been emitted. So create
8426 * a dummy variable, and replace all uses it with the real got variable when
8427 * its size is known in mono_llvm_emit_aot_module ().
8430 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8432 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8433 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8436 /* Add initialization array */
8438 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8440 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8441 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8445 emit_init_icall_wrappers (module);
8447 emit_llvm_code_start (module);
8449 /* Add a dummy personality function */
8450 if (!use_debug_personality) {
8451 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8452 LLVMSetLinkage (personality, LLVMExternalLinkage);
8453 mark_as_used (module, personality);
8456 /* Add a reference to the c++ exception we throw/catch */
8458 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8459 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8460 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8461 mono_llvm_set_is_constant (module->sentinel_exception);
8464 module->llvm_types = g_hash_table_new (NULL, NULL);
8465 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8466 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8467 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8468 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8469 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8470 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8471 module->method_to_callers = g_hash_table_new (NULL, NULL);
8475 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8478 LLVMValueRef res, *vals;
8480 vals = g_new0 (LLVMValueRef, nvalues);
8481 for (i = 0; i < nvalues; ++i)
8482 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8483 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8489 llvm_array_from_bytes (guint8 *values, int nvalues)
8492 LLVMValueRef res, *vals;
8494 vals = g_new0 (LLVMValueRef, nvalues);
8495 for (i = 0; i < nvalues; ++i)
8496 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8497 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8502 * mono_llvm_emit_aot_file_info:
8504 * Emit the MonoAotFileInfo structure.
8505 * Same as emit_aot_file_info () in aot-compiler.c.
8508 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8510 MonoLLVMModule *module = &aot_module;
8512 /* Save these for later */
8513 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8514 module->has_jitted_code = has_jitted_code;
8518 * mono_llvm_emit_aot_data:
8520 * Emit the binary data DATA pointed to by symbol SYMBOL.
8523 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8525 MonoLLVMModule *module = &aot_module;
8529 type = LLVMArrayType (LLVMInt8Type (), data_len);
8530 d = LLVMAddGlobal (module->lmodule, type, symbol);
8531 LLVMSetVisibility (d, LLVMHiddenVisibility);
8532 LLVMSetLinkage (d, LLVMInternalLinkage);
8533 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8534 mono_llvm_set_is_constant (d);
8537 /* Add a reference to a global defined in JITted code */
8539 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8544 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8545 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8551 emit_aot_file_info (MonoLLVMModule *module)
8553 LLVMTypeRef file_info_type;
8554 LLVMTypeRef *eltypes, eltype;
8555 LLVMValueRef info_var;
8556 LLVMValueRef *fields;
8557 int i, nfields, tindex;
8558 MonoAotFileInfo *info;
8559 LLVMModuleRef lmodule = module->lmodule;
8561 info = &module->aot_info;
8563 /* Create an LLVM type to represent MonoAotFileInfo */
8564 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8565 eltypes = g_new (LLVMTypeRef, nfields);
8567 eltypes [tindex ++] = LLVMInt32Type ();
8568 eltypes [tindex ++] = LLVMInt32Type ();
8570 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8571 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8573 for (i = 0; i < 15; ++i)
8574 eltypes [tindex ++] = LLVMInt32Type ();
8576 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8577 for (i = 0; i < 4; ++i)
8578 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8579 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8580 g_assert (tindex == nfields);
8581 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8582 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8584 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8585 if (module->static_link) {
8586 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8587 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8589 fields = g_new (LLVMValueRef, nfields);
8591 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8592 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8596 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8597 * for symbols defined in the .s file emitted by the aot compiler.
8599 eltype = eltypes [tindex];
8600 if (module->llvm_only)
8601 fields [tindex ++] = LLVMConstNull (eltype);
8603 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8604 fields [tindex ++] = module->got_var;
8605 /* llc defines this directly */
8606 if (!module->llvm_only) {
8607 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8608 fields [tindex ++] = LLVMConstNull (eltype);
8609 fields [tindex ++] = LLVMConstNull (eltype);
8611 fields [tindex ++] = LLVMConstNull (eltype);
8612 fields [tindex ++] = module->get_method;
8613 fields [tindex ++] = module->get_unbox_tramp;
8615 if (module->has_jitted_code) {
8616 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8617 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8619 fields [tindex ++] = LLVMConstNull (eltype);
8620 fields [tindex ++] = LLVMConstNull (eltype);
8622 if (!module->llvm_only)
8623 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8625 fields [tindex ++] = LLVMConstNull (eltype);
8626 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8627 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8628 fields [tindex ++] = LLVMConstNull (eltype);
8630 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8631 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8632 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8633 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8634 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8635 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8636 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8637 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8638 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8639 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8641 /* Not needed (mem_end) */
8642 fields [tindex ++] = LLVMConstNull (eltype);
8643 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8644 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8645 if (info->trampoline_size [0]) {
8646 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8647 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8648 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8649 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8651 fields [tindex ++] = LLVMConstNull (eltype);
8652 fields [tindex ++] = LLVMConstNull (eltype);
8653 fields [tindex ++] = LLVMConstNull (eltype);
8654 fields [tindex ++] = LLVMConstNull (eltype);
8656 if (module->static_link && !module->llvm_only)
8657 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8659 fields [tindex ++] = LLVMConstNull (eltype);
8660 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8661 if (!module->llvm_only) {
8662 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8663 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8664 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8665 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8666 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8667 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8669 fields [tindex ++] = LLVMConstNull (eltype);
8670 fields [tindex ++] = LLVMConstNull (eltype);
8671 fields [tindex ++] = LLVMConstNull (eltype);
8672 fields [tindex ++] = LLVMConstNull (eltype);
8673 fields [tindex ++] = LLVMConstNull (eltype);
8674 fields [tindex ++] = LLVMConstNull (eltype);
8677 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8678 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8681 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8682 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8683 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8684 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8685 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8686 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8687 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8688 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8689 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8690 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8691 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8692 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8693 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8694 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8695 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8697 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8698 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8699 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8700 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8701 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8703 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8704 g_assert (tindex == nfields);
8706 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8708 if (module->static_link) {
8712 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8713 /* Get rid of characters which cannot occur in symbols */
8715 for (p = s; *p; ++p) {
8716 if (!(isalnum (*p) || *p == '_'))
8719 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8721 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8722 LLVMSetLinkage (var, LLVMExternalLinkage);
8727 * Emit the aot module into the LLVM bitcode file FILENAME.
8730 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8732 LLVMTypeRef got_type, inited_type;
8733 LLVMValueRef real_got, real_inited;
8734 MonoLLVMModule *module = &aot_module;
8736 emit_llvm_code_end (module);
8739 * Create the real got variable and replace all uses of the dummy variable with
8742 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8743 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8744 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8745 if (module->external_symbols) {
8746 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8747 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8749 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8751 mono_llvm_replace_uses_of (module->got_var, real_got);
8753 mark_as_used (&aot_module, real_got);
8755 /* Delete the dummy got so it doesn't become a global */
8756 LLVMDeleteGlobal (module->got_var);
8757 module->got_var = real_got;
8760 * Same for the init_var
8762 if (module->llvm_only) {
8763 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8764 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8765 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8766 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8767 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8768 LLVMDeleteGlobal (module->inited_var);
8771 if (module->llvm_only) {
8772 emit_get_method (&aot_module);
8773 emit_get_unbox_tramp (&aot_module);
8776 emit_llvm_used (&aot_module);
8777 emit_dbg_info (&aot_module, filename, cu_name);
8778 emit_aot_file_info (&aot_module);
8781 * Replace GOT entries for directly callable methods with the methods themselves.
8782 * It would be easier to implement this by predefining all methods before compiling
8783 * their bodies, but that couldn't handle the case when a method fails to compile
8786 if (module->llvm_only) {
8787 GHashTableIter iter;
8789 GSList *callers, *l;
8791 g_hash_table_iter_init (&iter, module->method_to_callers);
8792 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8793 LLVMValueRef lmethod;
8795 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8798 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8800 for (l = callers; l; l = l->next) {
8801 LLVMValueRef caller = (LLVMValueRef)l->data;
8803 mono_llvm_replace_uses_of (caller, lmethod);
8809 /* Replace PLT entries for directly callable methods with the methods themselves */
8811 GHashTableIter iter;
8813 LLVMValueRef callee;
8815 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8816 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8817 if (mono_aot_is_direct_callable (ji)) {
8818 LLVMValueRef lmethod;
8820 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8821 /* The types might not match because the caller might pass an rgctx */
8822 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8823 mono_llvm_replace_uses_of (callee, lmethod);
8824 mono_aot_mark_unused_llvm_plt_entry (ji);
8834 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8835 printf ("%s\n", verifier_err);
8836 g_assert_not_reached ();
8841 LLVMWriteBitcodeToFile (module->lmodule, filename);
8846 md_string (const char *s)
8848 return LLVMMDString (s, strlen (s));
8851 /* Debugging support */
8854 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8856 LLVMModuleRef lmodule = module->lmodule;
8857 LLVMValueRef args [16], ver;
8860 * This can only be enabled when LLVM code is emitted into a separate object
8861 * file, since the AOT compiler also emits dwarf info,
8862 * and the abbrev indexes will not be correct since llvm has added its own
8865 if (!module->emit_dwarf)
8868 #if LLVM_API_VERSION > 100
8869 mono_llvm_di_builder_finalize (module->di_builder);
8871 LLVMValueRef cu_args [16], cu;
8873 char *build_info, *s, *dir;
8876 * Emit dwarf info in the form of LLVM metadata. There is some
8877 * out-of-date documentation at:
8878 * http://llvm.org/docs/SourceLevelDebugging.html
8879 * but most of this was gathered from the llvm and
8884 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8885 /* CU name/compilation dir */
8886 dir = g_path_get_dirname (filename);
8887 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8888 args [1] = LLVMMDString (dir, strlen (dir));
8889 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8892 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8894 build_info = mono_get_runtime_build_info ();
8895 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8896 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8897 g_free (build_info);
8899 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8901 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8902 /* Runtime version */
8903 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8905 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8906 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8908 if (module->subprogram_mds) {
8912 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8913 for (i = 0; i < module->subprogram_mds->len; ++i)
8914 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8915 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8917 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8920 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8921 /* Imported modules */
8922 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8924 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8925 /* DebugEmissionKind = FullDebug */
8926 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8927 cu = LLVMMDNode (cu_args, n_cuargs);
8928 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8931 #if LLVM_API_VERSION > 100
8932 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8933 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8934 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8935 ver = LLVMMDNode (args, 3);
8936 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8938 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8939 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8940 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8941 ver = LLVMMDNode (args, 3);
8942 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8944 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8945 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8946 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8947 ver = LLVMMDNode (args, 3);
8948 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8950 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8951 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8952 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8953 ver = LLVMMDNode (args, 3);
8954 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8959 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8961 MonoLLVMModule *module = ctx->module;
8962 MonoDebugMethodInfo *minfo = ctx->minfo;
8963 char *source_file, *dir, *filename;
8964 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8965 MonoSymSeqPoint *sym_seq_points;
8971 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8973 source_file = g_strdup ("<unknown>");
8974 dir = g_path_get_dirname (source_file);
8975 filename = g_path_get_basename (source_file);
8977 #if LLVM_API_VERSION > 100
8978 return mono_llvm_di_create_function (module->di_builder, module->cu, method, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
8981 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8982 args [0] = md_string (filename);
8983 args [1] = md_string (dir);
8984 ctx_args [1] = LLVMMDNode (args, 2);
8985 ctx_md = LLVMMDNode (ctx_args, 2);
8987 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8988 type_args [1] = NULL;
8989 type_args [2] = NULL;
8990 type_args [3] = LLVMMDString ("", 0);
8991 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8992 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8993 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8994 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8995 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8996 type_args [9] = NULL;
8997 type_args [10] = NULL;
8998 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8999 type_args [12] = NULL;
9000 type_args [13] = NULL;
9001 type_args [14] = NULL;
9002 type_md = LLVMMDNode (type_args, 14);
9004 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9005 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9006 /* Source directory + file pair */
9007 args [0] = md_string (filename);
9008 args [1] = md_string (dir);
9009 md_args [1] = LLVMMDNode (args ,2);
9010 md_args [2] = ctx_md;
9011 md_args [3] = md_string (cfg->method->name);
9012 md_args [4] = md_string (name);
9013 md_args [5] = md_string (name);
9016 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9018 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9020 md_args [7] = type_md;
9022 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9024 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9026 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9027 /* Index into a virtual function */
9028 md_args [11] = NULL;
9029 md_args [12] = NULL;
9031 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9033 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9034 /* Pointer to LLVM function */
9035 md_args [15] = method;
9036 /* Function template parameter */
9037 md_args [16] = NULL;
9038 /* Function declaration descriptor */
9039 md_args [17] = NULL;
9040 /* List of function variables */
9041 md_args [18] = LLVMMDNode (args, 0);
9043 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9044 md = LLVMMDNode (md_args, 20);
9046 if (!module->subprogram_mds)
9047 module->subprogram_mds = g_ptr_array_new ();
9048 g_ptr_array_add (module->subprogram_mds, md);
9052 g_free (source_file);
9053 g_free (sym_seq_points);
9059 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9061 MonoCompile *cfg = ctx->cfg;
9063 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9064 MonoDebugSourceLocation *loc;
9065 LLVMValueRef loc_md;
9067 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9070 #if LLVM_API_VERSION > 100
9071 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9072 mono_llvm_di_set_location (builder, loc_md);
9074 LLVMValueRef md_args [16];
9078 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9079 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9080 md_args [nmd_args ++] = ctx->dbg_md;
9081 md_args [nmd_args ++] = NULL;
9082 loc_md = LLVMMDNode (md_args, nmd_args);
9083 LLVMSetCurrentDebugLocation (builder, loc_md);
9085 mono_debug_symfile_free_location (loc);
9091 default_mono_llvm_unhandled_exception (void)
9093 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9094 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9096 mono_unhandled_exception (target);
9097 mono_invoke_unhandled_exception_hook (target);
9098 g_assert_not_reached ();
9103 - Emit LLVM IR from the mono IR using the LLVM C API.
9104 - The original arch specific code remains, so we can fall back to it if we run
9105 into something we can't handle.
9109 A partial list of issues:
9110 - Handling of opcodes which can throw exceptions.
9112 In the mono JIT, these are implemented using code like this:
9119 push throw_pos - method
9120 call <exception trampoline>
9122 The problematic part is push throw_pos - method, which cannot be represented
9123 in the LLVM IR, since it does not support label values.
9124 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9125 be implemented in JIT mode ?
9126 -> a possible but slower implementation would use the normal exception
9127 throwing code but it would need to control the placement of the throw code
9128 (it needs to be exactly after the compare+branch).
9129 -> perhaps add a PC offset intrinsics ?
9131 - efficient implementation of .ovf opcodes.
9133 These are currently implemented as:
9134 <ins which sets the condition codes>
9137 Some overflow opcodes are now supported by LLVM SVN.
9139 - exception handling, unwinding.
9140 - SSA is disabled for methods with exception handlers
9141 - How to obtain unwind info for LLVM compiled methods ?
9142 -> this is now solved by converting the unwind info generated by LLVM
9144 - LLVM uses the c++ exception handling framework, while we use our home grown
9145 code, and couldn't use the c++ one:
9146 - its not supported under VC++, other exotic platforms.
9147 - it might be impossible to support filter clauses with it.
9151 The trampolines need a predictable call sequence, since they need to disasm
9152 the calling code to obtain register numbers / offsets.
9154 LLVM currently generates this code in non-JIT mode:
9155 mov -0x98(%rax),%eax
9157 Here, the vtable pointer is lost.
9158 -> solution: use one vtable trampoline per class.
9160 - passing/receiving the IMT pointer/RGCTX.
9161 -> solution: pass them as normal arguments ?
9165 LLVM does not allow the specification of argument registers etc. This means
9166 that all calls are made according to the platform ABI.
9168 - passing/receiving vtypes.
9170 Vtypes passed/received in registers are handled by the front end by using
9171 a signature with scalar arguments, and loading the parts of the vtype into those
9174 Vtypes passed on the stack are handled using the 'byval' attribute.
9178 Supported though alloca, we need to emit the load/store code.
9182 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9183 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9184 This is made easier because the IR is already in SSA form.
9185 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9186 types are frequently used incorrectly.
9191 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9192 it with the file containing the methods emitted by the JIT and the AOT data
9196 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9197 * - each bblock should end with a branch
9198 * - setting the return value, making cfg->ret non-volatile
9199 * - avoid some transformations in the JIT which make it harder for us to generate
9201 * - use pointer types to help optimizations.