3 * llvm "Backend" for the mono JIT
5 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
6 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
7 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #include <mono/metadata/debug-helpers.h>
13 #include <mono/metadata/debug-internals.h>
14 #include <mono/metadata/mempool-internals.h>
15 #include <mono/metadata/environment.h>
16 #include <mono/metadata/object-internals.h>
17 #include <mono/metadata/abi-details.h>
18 #include <mono/utils/mono-tls.h>
19 #include <mono/utils/mono-dl.h>
20 #include <mono/utils/mono-time.h>
21 #include <mono/utils/freebsd-dwarf.h>
23 #ifndef __STDC_LIMIT_MACROS
24 #define __STDC_LIMIT_MACROS
26 #ifndef __STDC_CONSTANT_MACROS
27 #define __STDC_CONSTANT_MACROS
30 #include "llvm-c/BitWriter.h"
31 #include "llvm-c/Analysis.h"
33 #include "mini-llvm-cpp.h"
35 #include "aot-compiler.h"
36 #include "mini-llvm.h"
43 extern void *memset(void *, int, size_t);
44 void bzero (void *to, size_t count) { memset (to, 0, count); }
48 #if LLVM_API_VERSION < 4
49 #error "The version of the mono llvm repository is too old."
52 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
55 * Information associated by mono with LLVM modules.
58 LLVMModuleRef lmodule;
59 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
60 GHashTable *llvm_types;
62 const char *got_symbol;
63 const char *get_method_symbol;
64 const char *get_unbox_tramp_symbol;
65 GHashTable *plt_entries;
66 GHashTable *plt_entries_ji;
67 GHashTable *method_to_lmethod;
68 GHashTable *direct_callables;
73 GPtrArray *subprogram_mds;
75 LLVMExecutionEngineRef ee;
76 gboolean external_symbols;
79 LLVMValueRef personality;
82 MonoAssembly *assembly;
84 MonoAotFileInfo aot_info;
85 const char *jit_got_symbol;
86 const char *eh_frame_symbol;
87 LLVMValueRef get_method, get_unbox_tramp;
88 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
89 LLVMValueRef code_start, code_end;
90 LLVMValueRef inited_var;
91 int max_inited_idx, max_method_idx;
92 gboolean has_jitted_code;
95 GHashTable *idx_to_lmethod;
96 GHashTable *idx_to_unbox_tramp;
97 /* Maps a MonoMethod to LLVM instructions representing it */
98 GHashTable *method_to_callers;
99 LLVMContextRef context;
100 LLVMValueRef sentinel_exception;
101 void *di_builder, *cu;
102 GHashTable *objc_selector_to_var;
106 * Information associated by the backend with mono basic blocks.
109 LLVMBasicBlockRef bblock, end_bblock;
110 LLVMValueRef finally_ind;
111 gboolean added, invoke_target;
113 * If this bblock is the start of a finally clause, this is a list of bblocks it
114 * needs to branch to in ENDFINALLY.
116 GSList *call_handler_return_bbs;
118 * If this bblock is the start of a finally clause, this is the bblock that
119 * CALL_HANDLER needs to branch to.
121 LLVMBasicBlockRef call_handler_target_bb;
122 /* The list of switch statements generated by ENDFINALLY instructions */
123 GSList *endfinally_switch_ins_list;
128 * Structure containing emit state
131 MonoMemPool *mempool;
133 /* Maps method names to the corresponding LLVMValueRef */
134 GHashTable *emitted_method_decls;
137 LLVMValueRef lmethod;
138 MonoLLVMModule *module;
139 LLVMModuleRef lmodule;
141 int sindex, default_index, ex_index;
142 LLVMBuilderRef builder;
143 LLVMValueRef *values, *addresses;
144 MonoType **vreg_cli_types;
146 MonoMethodSignature *sig;
148 GHashTable *region_to_handler;
149 GHashTable *clause_to_handler;
150 LLVMBuilderRef alloca_builder;
151 LLVMValueRef last_alloca;
152 LLVMValueRef rgctx_arg;
153 LLVMValueRef this_arg;
154 LLVMTypeRef *vreg_types;
156 LLVMTypeRef method_type;
157 LLVMBasicBlockRef init_bb, inited_bb;
159 gboolean *unreachable;
161 gboolean has_got_access;
162 gboolean is_linkonce;
163 int this_arg_pindex, rgctx_arg_pindex;
164 LLVMValueRef imt_rgctx_loc;
165 GHashTable *llvm_types;
167 MonoDebugMethodInfo *minfo;
169 /* For every clause, the clauses it is nested in */
172 GHashTable *exc_meta;
173 GHashTable *method_to_callers;
174 GPtrArray *phi_values;
175 GPtrArray *bblock_list;
177 GHashTable *jit_callees;
178 LLVMValueRef long_bb_break_var;
184 MonoBasicBlock *in_bb;
189 * Instruction metadata
190 * This is the same as ins_info, but LREG != IREG.
198 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
199 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
206 /* keep in sync with the enum in mini.h */
209 #include "mini-ops.h"
214 #if SIZEOF_VOID_P == 4
215 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
217 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
220 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
223 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
225 #define TRACE_FAILURE(msg)
229 #define IS_TARGET_X86 1
231 #define IS_TARGET_X86 0
235 #define IS_TARGET_AMD64 1
237 #define IS_TARGET_AMD64 0
240 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
242 static LLVMIntPredicate cond_to_llvm_cond [] = {
255 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
268 static MonoNativeTlsKey current_cfg_tls_id;
270 static MonoLLVMModule aot_module;
272 static GHashTable *intrins_id_to_name;
273 static GHashTable *intrins_name_to_id;
275 static void init_jit_module (MonoDomain *domain);
277 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
278 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
279 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
280 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
281 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
282 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
285 set_failure (EmitContext *ctx, const char *message)
287 TRACE_FAILURE (reason);
288 ctx->cfg->exception_message = g_strdup (message);
289 ctx->cfg->disable_llvm = TRUE;
295 * The LLVM type with width == sizeof (gpointer)
300 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
306 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
312 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
318 * Return the size of the LLVM representation of the vtype T.
321 get_vtype_size (MonoType *t)
325 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
327 /* LLVMArgAsIArgs depends on this since it stores whole words */
328 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
335 * simd_class_to_llvm_type:
337 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
340 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
342 if (!strcmp (klass->name, "Vector2d")) {
343 return LLVMVectorType (LLVMDoubleType (), 2);
344 } else if (!strcmp (klass->name, "Vector2l")) {
345 return LLVMVectorType (LLVMInt64Type (), 2);
346 } else if (!strcmp (klass->name, "Vector2ul")) {
347 return LLVMVectorType (LLVMInt64Type (), 2);
348 } else if (!strcmp (klass->name, "Vector4i")) {
349 return LLVMVectorType (LLVMInt32Type (), 4);
350 } else if (!strcmp (klass->name, "Vector4ui")) {
351 return LLVMVectorType (LLVMInt32Type (), 4);
352 } else if (!strcmp (klass->name, "Vector4f")) {
353 return LLVMVectorType (LLVMFloatType (), 4);
354 } else if (!strcmp (klass->name, "Vector8s")) {
355 return LLVMVectorType (LLVMInt16Type (), 8);
356 } else if (!strcmp (klass->name, "Vector8us")) {
357 return LLVMVectorType (LLVMInt16Type (), 8);
358 } else if (!strcmp (klass->name, "Vector16sb")) {
359 return LLVMVectorType (LLVMInt8Type (), 16);
360 } else if (!strcmp (klass->name, "Vector16b")) {
361 return LLVMVectorType (LLVMInt8Type (), 16);
362 } else if (!strcmp (klass->name, "Vector2")) {
363 /* System.Numerics */
364 return LLVMVectorType (LLVMFloatType (), 4);
365 } else if (!strcmp (klass->name, "Vector3")) {
366 return LLVMVectorType (LLVMFloatType (), 4);
367 } else if (!strcmp (klass->name, "Vector4")) {
368 return LLVMVectorType (LLVMFloatType (), 4);
369 } else if (!strcmp (klass->name, "Vector`1")) {
370 MonoType *etype = mono_class_get_generic_class (klass)->context.class_inst->type_argv [0];
371 switch (etype->type) {
374 return LLVMVectorType (LLVMInt8Type (), 16);
377 return LLVMVectorType (LLVMInt16Type (), 8);
380 return LLVMVectorType (LLVMInt32Type (), 4);
383 return LLVMVectorType (LLVMInt64Type (), 2);
385 return LLVMVectorType (LLVMFloatType (), 4);
387 return LLVMVectorType (LLVMDoubleType (), 2);
389 g_assert_not_reached ();
393 printf ("%s\n", klass->name);
399 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
400 static inline G_GNUC_UNUSED LLVMTypeRef
401 type_to_simd_type (int type)
405 return LLVMVectorType (LLVMInt8Type (), 16);
407 return LLVMVectorType (LLVMInt16Type (), 8);
409 return LLVMVectorType (LLVMInt32Type (), 4);
411 return LLVMVectorType (LLVMInt64Type (), 2);
413 return LLVMVectorType (LLVMDoubleType (), 2);
415 return LLVMVectorType (LLVMFloatType (), 4);
417 g_assert_not_reached ();
423 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
425 int i, size, nfields, esize;
426 LLVMTypeRef *eltypes;
431 t = &klass->byval_arg;
433 if (mini_type_is_hfa (t, &nfields, &esize)) {
435 * This is needed on arm64 where HFAs are returned in
438 /* SIMD types have size 16 in mono_class_value_size () */
439 if (klass->simd_type)
442 eltypes = g_new (LLVMTypeRef, size);
443 for (i = 0; i < size; ++i)
444 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
446 size = get_vtype_size (t);
448 eltypes = g_new (LLVMTypeRef, size);
449 for (i = 0; i < size; ++i)
450 eltypes [i] = LLVMInt8Type ();
453 name = mono_type_full_name (&klass->byval_arg);
454 ltype = LLVMStructCreateNamed (module->context, name);
455 LLVMStructSetBody (ltype, eltypes, size, FALSE);
465 * Return the LLVM type corresponding to T.
468 type_to_llvm_type (EmitContext *ctx, MonoType *t)
473 t = mini_get_underlying_type (t);
477 return LLVMVoidType ();
479 return LLVMInt8Type ();
481 return LLVMInt16Type ();
483 return LLVMInt32Type ();
485 return LLVMInt8Type ();
487 return LLVMInt16Type ();
489 return LLVMInt32Type ();
492 return LLVMInt64Type ();
494 return LLVMFloatType ();
496 return LLVMDoubleType ();
499 return IntPtrType ();
500 case MONO_TYPE_OBJECT:
502 return ObjRefType ();
505 /* Because of generic sharing */
506 return ObjRefType ();
507 case MONO_TYPE_GENERICINST:
508 if (!mono_type_generic_inst_is_valuetype (t))
509 return ObjRefType ();
511 case MONO_TYPE_VALUETYPE:
512 case MONO_TYPE_TYPEDBYREF: {
516 klass = mono_class_from_mono_type (t);
518 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
519 return simd_class_to_llvm_type (ctx, klass);
522 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
524 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
526 ltype = create_llvm_type_for_type (ctx->module, klass);
527 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
533 printf ("X: %d\n", t->type);
534 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
535 ctx->cfg->disable_llvm = TRUE;
543 * Return whenever T is an unsigned int type.
546 type_is_unsigned (EmitContext *ctx, MonoType *t)
548 t = mini_get_underlying_type (t);
564 * type_to_llvm_arg_type:
566 * Same as type_to_llvm_type, but treat i8/i16 as i32.
569 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
571 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
573 if (ctx->cfg->llvm_only)
577 * This works on all abis except arm64/ios which passes multiple
578 * arguments in one stack slot.
581 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
583 * LLVM generates code which only sets the lower bits, while JITted
584 * code expects all the bits to be set.
586 ptype = LLVMInt32Type ();
594 * llvm_type_to_stack_type:
596 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
599 static G_GNUC_UNUSED LLVMTypeRef
600 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
604 if (type == LLVMInt8Type ())
605 return LLVMInt32Type ();
606 else if (type == LLVMInt16Type ())
607 return LLVMInt32Type ();
608 else if (!cfg->r4fp && type == LLVMFloatType ())
609 return LLVMDoubleType ();
615 * regtype_to_llvm_type:
617 * Return the LLVM type corresponding to the regtype C used in instruction
621 regtype_to_llvm_type (char c)
625 return LLVMInt32Type ();
627 return LLVMInt64Type ();
629 return LLVMDoubleType ();
638 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
641 op_to_llvm_type (int opcode)
646 return LLVMInt8Type ();
649 return LLVMInt8Type ();
652 return LLVMInt16Type ();
655 return LLVMInt16Type ();
658 return LLVMInt32Type ();
661 return LLVMInt32Type ();
663 return LLVMInt64Type ();
665 return LLVMFloatType ();
667 return LLVMDoubleType ();
669 return LLVMInt64Type ();
671 return LLVMInt32Type ();
673 return LLVMInt64Type ();
678 return LLVMInt8Type ();
683 return LLVMInt16Type ();
685 return LLVMInt32Type ();
688 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
695 return LLVMInt32Type ();
702 return LLVMInt64Type ();
704 printf ("%s\n", mono_inst_name (opcode));
705 g_assert_not_reached ();
710 #define CLAUSE_START(clause) ((clause)->try_offset)
711 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
714 * load_store_to_llvm_type:
716 * Return the size/sign/zero extension corresponding to the load/store opcode
720 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
726 case OP_LOADI1_MEMBASE:
727 case OP_STOREI1_MEMBASE_REG:
728 case OP_STOREI1_MEMBASE_IMM:
729 case OP_ATOMIC_LOAD_I1:
730 case OP_ATOMIC_STORE_I1:
733 return LLVMInt8Type ();
734 case OP_LOADU1_MEMBASE:
736 case OP_ATOMIC_LOAD_U1:
737 case OP_ATOMIC_STORE_U1:
740 return LLVMInt8Type ();
741 case OP_LOADI2_MEMBASE:
742 case OP_STOREI2_MEMBASE_REG:
743 case OP_STOREI2_MEMBASE_IMM:
744 case OP_ATOMIC_LOAD_I2:
745 case OP_ATOMIC_STORE_I2:
748 return LLVMInt16Type ();
749 case OP_LOADU2_MEMBASE:
751 case OP_ATOMIC_LOAD_U2:
752 case OP_ATOMIC_STORE_U2:
755 return LLVMInt16Type ();
756 case OP_LOADI4_MEMBASE:
757 case OP_LOADU4_MEMBASE:
760 case OP_STOREI4_MEMBASE_REG:
761 case OP_STOREI4_MEMBASE_IMM:
762 case OP_ATOMIC_LOAD_I4:
763 case OP_ATOMIC_STORE_I4:
764 case OP_ATOMIC_LOAD_U4:
765 case OP_ATOMIC_STORE_U4:
767 return LLVMInt32Type ();
768 case OP_LOADI8_MEMBASE:
770 case OP_STOREI8_MEMBASE_REG:
771 case OP_STOREI8_MEMBASE_IMM:
772 case OP_ATOMIC_LOAD_I8:
773 case OP_ATOMIC_STORE_I8:
774 case OP_ATOMIC_LOAD_U8:
775 case OP_ATOMIC_STORE_U8:
777 return LLVMInt64Type ();
778 case OP_LOADR4_MEMBASE:
779 case OP_STORER4_MEMBASE_REG:
780 case OP_ATOMIC_LOAD_R4:
781 case OP_ATOMIC_STORE_R4:
783 return LLVMFloatType ();
784 case OP_LOADR8_MEMBASE:
785 case OP_STORER8_MEMBASE_REG:
786 case OP_ATOMIC_LOAD_R8:
787 case OP_ATOMIC_STORE_R8:
789 return LLVMDoubleType ();
790 case OP_LOAD_MEMBASE:
792 case OP_STORE_MEMBASE_REG:
793 case OP_STORE_MEMBASE_IMM:
794 *size = sizeof (gpointer);
795 return IntPtrType ();
797 g_assert_not_reached ();
805 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
808 ovf_op_to_intrins (int opcode)
812 return "llvm.sadd.with.overflow.i32";
814 return "llvm.uadd.with.overflow.i32";
816 return "llvm.ssub.with.overflow.i32";
818 return "llvm.usub.with.overflow.i32";
820 return "llvm.smul.with.overflow.i32";
822 return "llvm.umul.with.overflow.i32";
824 return "llvm.sadd.with.overflow.i64";
826 return "llvm.uadd.with.overflow.i64";
828 return "llvm.ssub.with.overflow.i64";
830 return "llvm.usub.with.overflow.i64";
832 return "llvm.smul.with.overflow.i64";
834 return "llvm.umul.with.overflow.i64";
836 g_assert_not_reached ();
842 simd_op_to_intrins (int opcode)
845 #if defined(TARGET_X86) || defined(TARGET_AMD64)
847 return "llvm.x86.sse2.min.pd";
849 return "llvm.x86.sse.min.ps";
851 return "llvm.x86.sse2.max.pd";
853 return "llvm.x86.sse.max.ps";
855 return "llvm.x86.sse3.hadd.pd";
857 return "llvm.x86.sse3.hadd.ps";
859 return "llvm.x86.sse3.hsub.pd";
861 return "llvm.x86.sse3.hsub.ps";
863 return "llvm.x86.sse3.addsub.ps";
865 return "llvm.x86.sse3.addsub.pd";
866 case OP_EXTRACT_MASK:
867 return "llvm.x86.sse2.pmovmskb.128";
870 return "llvm.x86.sse2.psrli.w";
873 return "llvm.x86.sse2.psrli.d";
876 return "llvm.x86.sse2.psrli.q";
879 return "llvm.x86.sse2.pslli.w";
882 return "llvm.x86.sse2.pslli.d";
885 return "llvm.x86.sse2.pslli.q";
888 return "llvm.x86.sse2.psrai.w";
891 return "llvm.x86.sse2.psrai.d";
893 return "llvm.x86.sse2.padds.b";
895 return "llvm.x86.sse2.padds.w";
897 return "llvm.x86.sse2.psubs.b";
899 return "llvm.x86.sse2.psubs.w";
900 case OP_PADDB_SAT_UN:
901 return "llvm.x86.sse2.paddus.b";
902 case OP_PADDW_SAT_UN:
903 return "llvm.x86.sse2.paddus.w";
904 case OP_PSUBB_SAT_UN:
905 return "llvm.x86.sse2.psubus.b";
906 case OP_PSUBW_SAT_UN:
907 return "llvm.x86.sse2.psubus.w";
909 return "llvm.x86.sse2.pavg.b";
911 return "llvm.x86.sse2.pavg.w";
913 return "llvm.x86.sse.sqrt.ps";
915 return "llvm.x86.sse2.sqrt.pd";
917 return "llvm.x86.sse.rsqrt.ps";
919 return "llvm.x86.sse.rcp.ps";
921 return "llvm.x86.sse2.cvtdq2pd";
923 return "llvm.x86.sse2.cvtdq2ps";
925 return "llvm.x86.sse2.cvtpd2dq";
927 return "llvm.x86.sse2.cvtps2dq";
929 return "llvm.x86.sse2.cvtpd2ps";
931 return "llvm.x86.sse2.cvtps2pd";
933 return "llvm.x86.sse2.cvttpd2dq";
935 return "llvm.x86.sse2.cvttps2dq";
937 return "llvm.x86.sse2.packsswb.128";
939 return "llvm.x86.sse2.packssdw.128";
941 return "llvm.x86.sse2.packuswb.128";
943 return "llvm.x86.sse41.packusdw";
945 return "llvm.x86.sse2.pmulh.w";
946 case OP_PMULW_HIGH_UN:
947 return "llvm.x86.sse2.pmulhu.w";
949 return "llvm.x86.sse41.dpps";
952 g_assert_not_reached ();
958 simd_op_to_llvm_type (int opcode)
960 #if defined(TARGET_X86) || defined(TARGET_AMD64)
964 return type_to_simd_type (MONO_TYPE_R8);
967 return type_to_simd_type (MONO_TYPE_I8);
970 return type_to_simd_type (MONO_TYPE_I4);
975 return type_to_simd_type (MONO_TYPE_I2);
979 return type_to_simd_type (MONO_TYPE_I1);
981 return type_to_simd_type (MONO_TYPE_R4);
984 return type_to_simd_type (MONO_TYPE_I4);
988 return type_to_simd_type (MONO_TYPE_R8);
992 return type_to_simd_type (MONO_TYPE_R4);
993 case OP_EXTRACT_MASK:
994 return type_to_simd_type (MONO_TYPE_I1);
1000 return type_to_simd_type (MONO_TYPE_R4);
1003 return type_to_simd_type (MONO_TYPE_R8);
1005 g_assert_not_reached ();
1016 * Return the LLVM basic block corresponding to BB.
1018 static LLVMBasicBlockRef
1019 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1021 char bb_name_buf [128];
1024 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1025 if (bb->flags & BB_EXCEPTION_HANDLER) {
1026 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1027 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1028 bb_name = bb_name_buf;
1029 } else if (bb->block_num < 256) {
1030 if (!ctx->module->bb_names) {
1031 ctx->module->bb_names_len = 256;
1032 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1034 if (!ctx->module->bb_names [bb->block_num]) {
1037 n = g_strdup_printf ("BB%d", bb->block_num);
1038 mono_memory_barrier ();
1039 ctx->module->bb_names [bb->block_num] = n;
1041 bb_name = ctx->module->bb_names [bb->block_num];
1043 sprintf (bb_name_buf, "BB%d", bb->block_num);
1044 bb_name = bb_name_buf;
1047 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1048 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1051 return ctx->bblocks [bb->block_num].bblock;
1057 * Return the last LLVM bblock corresponding to BB.
1058 * This might not be equal to the bb returned by get_bb () since we need to generate
1059 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1061 static LLVMBasicBlockRef
1062 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1065 return ctx->bblocks [bb->block_num].end_bblock;
1068 static LLVMBasicBlockRef
1069 gen_bb (EmitContext *ctx, const char *prefix)
1073 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1074 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1080 * Return the target of the patch identified by TYPE and TARGET.
1083 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1089 memset (&ji, 0, sizeof (ji));
1091 ji.data.target = target;
1093 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1094 mono_error_assert_ok (&error);
1102 * Emit code to convert the LLVM value V to DTYPE.
1105 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1107 LLVMTypeRef stype = LLVMTypeOf (v);
1109 if (stype != dtype) {
1110 gboolean ext = FALSE;
1113 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1115 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1117 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1121 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1123 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1124 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1127 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1128 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1129 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1130 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1131 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1132 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1133 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1134 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1136 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1137 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1138 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1139 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1140 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1141 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1143 if (mono_arch_is_soft_float ()) {
1144 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1145 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1146 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1147 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1150 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1151 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1154 LLVMDumpValue (LLVMConstNull (dtype));
1155 g_assert_not_reached ();
1163 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1165 return convert_full (ctx, v, dtype, FALSE);
1169 * emit_volatile_load:
1171 * If vreg is volatile, emit a load from its address.
1174 emit_volatile_load (EmitContext *ctx, int vreg)
1180 // FIXME: This hack is required because we pass the rgctx in a callee saved
1181 // register on arm64 (x15), and llvm might keep the value in that register
1182 // even through the register is marked as 'reserved' inside llvm.
1183 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1184 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1186 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1188 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1190 t = ctx->vreg_cli_types [vreg];
1191 if (t && !t->byref) {
1193 * Might have to zero extend since llvm doesn't have
1196 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1197 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1198 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1199 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1200 else if (t->type == MONO_TYPE_U8)
1201 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1208 * emit_volatile_store:
1210 * If VREG is volatile, emit a store from its value to its address.
1213 emit_volatile_store (EmitContext *ctx, int vreg)
1215 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1217 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1218 g_assert (ctx->addresses [vreg]);
1219 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1224 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1226 LLVMTypeRef ret_type;
1227 LLVMTypeRef *param_types = NULL;
1232 ret_type = type_to_llvm_type (ctx, sig->ret);
1235 rtype = mini_get_underlying_type (sig->ret);
1237 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1241 param_types [pindex ++] = ThisType ();
1242 for (i = 0; i < sig->param_count; ++i)
1243 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1245 if (!ctx_ok (ctx)) {
1246 g_free (param_types);
1250 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1251 g_free (param_types);
1257 * sig_to_llvm_sig_full:
1259 * Return the LLVM signature corresponding to the mono signature SIG using the
1260 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1263 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1265 LLVMTypeRef ret_type;
1266 LLVMTypeRef *param_types = NULL;
1268 int i, j, pindex, vret_arg_pindex = 0;
1269 gboolean vretaddr = FALSE;
1273 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1275 ret_type = type_to_llvm_type (ctx, sig->ret);
1278 rtype = mini_get_underlying_type (sig->ret);
1280 switch (cinfo->ret.storage) {
1281 case LLVMArgVtypeInReg:
1282 /* LLVM models this by returning an aggregate value */
1283 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1284 LLVMTypeRef members [2];
1286 members [0] = IntPtrType ();
1287 ret_type = LLVMStructType (members, 1, FALSE);
1288 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1290 ret_type = LLVMVoidType ();
1291 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1292 LLVMTypeRef members [2];
1294 members [0] = IntPtrType ();
1295 members [1] = IntPtrType ();
1296 ret_type = LLVMStructType (members, 2, FALSE);
1298 g_assert_not_reached ();
1301 case LLVMArgVtypeByVal:
1302 /* Vtype returned normally by val */
1304 case LLVMArgVtypeAsScalar: {
1305 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1306 /* LLVM models this by returning an int */
1307 if (size < SIZEOF_VOID_P) {
1308 g_assert (cinfo->ret.nslots == 1);
1309 ret_type = LLVMIntType (size * 8);
1311 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1312 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1316 case LLVMArgAsIArgs:
1317 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1319 case LLVMArgFpStruct: {
1320 /* Vtype returned as a fp struct */
1321 LLVMTypeRef members [16];
1323 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1324 for (i = 0; i < cinfo->ret.nslots; ++i)
1325 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1326 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1329 case LLVMArgVtypeByRef:
1330 /* Vtype returned using a hidden argument */
1331 ret_type = LLVMVoidType ();
1333 case LLVMArgVtypeRetAddr:
1334 case LLVMArgGsharedvtFixed:
1335 case LLVMArgGsharedvtFixedVtype:
1336 case LLVMArgGsharedvtVariable:
1338 ret_type = LLVMVoidType ();
1344 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1346 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1348 * Has to be the first argument because of the sret argument attribute
1349 * FIXME: This might conflict with passing 'this' as the first argument, but
1350 * this is only used on arm64 which has a dedicated struct return register.
1352 cinfo->vret_arg_pindex = pindex;
1353 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1354 if (!ctx_ok (ctx)) {
1355 g_free (param_types);
1358 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1361 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1362 cinfo->rgctx_arg_pindex = pindex;
1363 param_types [pindex] = ctx->module->ptr_type;
1366 if (cinfo->imt_arg) {
1367 cinfo->imt_arg_pindex = pindex;
1368 param_types [pindex] = ctx->module->ptr_type;
1372 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1373 vret_arg_pindex = pindex;
1374 if (cinfo->vret_arg_index == 1) {
1375 /* Add the slots consumed by the first argument */
1376 LLVMArgInfo *ainfo = &cinfo->args [0];
1377 switch (ainfo->storage) {
1378 case LLVMArgVtypeInReg:
1379 for (j = 0; j < 2; ++j) {
1380 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1389 cinfo->vret_arg_pindex = vret_arg_pindex;
1392 if (vretaddr && vret_arg_pindex == pindex)
1393 param_types [pindex ++] = IntPtrType ();
1395 cinfo->this_arg_pindex = pindex;
1396 param_types [pindex ++] = ThisType ();
1397 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1399 if (vretaddr && vret_arg_pindex == pindex)
1400 param_types [pindex ++] = IntPtrType ();
1401 for (i = 0; i < sig->param_count; ++i) {
1402 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1404 if (vretaddr && vret_arg_pindex == pindex)
1405 param_types [pindex ++] = IntPtrType ();
1406 ainfo->pindex = pindex;
1408 switch (ainfo->storage) {
1409 case LLVMArgVtypeInReg:
1410 for (j = 0; j < 2; ++j) {
1411 switch (ainfo->pair_storage [j]) {
1413 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1418 g_assert_not_reached ();
1422 case LLVMArgVtypeByVal:
1423 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1426 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1429 case LLVMArgAsIArgs:
1430 if (ainfo->esize == 8)
1431 param_types [pindex] = LLVMArrayType (LLVMInt64Type (), ainfo->nslots);
1433 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1436 case LLVMArgVtypeByRef:
1437 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1440 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1443 case LLVMArgAsFpArgs: {
1446 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1447 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1448 param_types [pindex ++] = LLVMDoubleType ();
1449 for (j = 0; j < ainfo->nslots; ++j)
1450 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1453 case LLVMArgVtypeAsScalar:
1454 g_assert_not_reached ();
1456 case LLVMArgGsharedvtFixed:
1457 case LLVMArgGsharedvtFixedVtype:
1458 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1460 case LLVMArgGsharedvtVariable:
1461 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1464 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1468 if (!ctx_ok (ctx)) {
1469 g_free (param_types);
1472 if (vretaddr && vret_arg_pindex == pindex)
1473 param_types [pindex ++] = IntPtrType ();
1474 if (ctx->llvm_only && cinfo->rgctx_arg) {
1475 /* Pass the rgctx as the last argument */
1476 cinfo->rgctx_arg_pindex = pindex;
1477 param_types [pindex] = ctx->module->ptr_type;
1481 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1482 g_free (param_types);
1488 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1490 return sig_to_llvm_sig_full (ctx, sig, NULL);
1494 * LLVMFunctionType1:
1496 * Create an LLVM function type from the arguments.
1498 static G_GNUC_UNUSED LLVMTypeRef
1499 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1502 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1506 * LLVMFunctionType1:
1508 * Create an LLVM function type from the arguments.
1510 static G_GNUC_UNUSED LLVMTypeRef
1511 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1512 LLVMTypeRef ParamType1,
1515 LLVMTypeRef param_types [1];
1517 param_types [0] = ParamType1;
1519 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1523 * LLVMFunctionType2:
1525 * Create an LLVM function type from the arguments.
1527 static G_GNUC_UNUSED LLVMTypeRef
1528 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1529 LLVMTypeRef ParamType1,
1530 LLVMTypeRef ParamType2,
1533 LLVMTypeRef param_types [2];
1535 param_types [0] = ParamType1;
1536 param_types [1] = ParamType2;
1538 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1542 * LLVMFunctionType3:
1544 * Create an LLVM function type from the arguments.
1546 static G_GNUC_UNUSED LLVMTypeRef
1547 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1548 LLVMTypeRef ParamType1,
1549 LLVMTypeRef ParamType2,
1550 LLVMTypeRef ParamType3,
1553 LLVMTypeRef param_types [3];
1555 param_types [0] = ParamType1;
1556 param_types [1] = ParamType2;
1557 param_types [2] = ParamType3;
1559 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1562 static G_GNUC_UNUSED LLVMTypeRef
1563 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1564 LLVMTypeRef ParamType1,
1565 LLVMTypeRef ParamType2,
1566 LLVMTypeRef ParamType3,
1567 LLVMTypeRef ParamType4,
1568 LLVMTypeRef ParamType5,
1571 LLVMTypeRef param_types [5];
1573 param_types [0] = ParamType1;
1574 param_types [1] = ParamType2;
1575 param_types [2] = ParamType3;
1576 param_types [3] = ParamType4;
1577 param_types [4] = ParamType5;
1579 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1585 * Create an LLVM builder and remember it so it can be freed later.
1587 static LLVMBuilderRef
1588 create_builder (EmitContext *ctx)
1590 LLVMBuilderRef builder = LLVMCreateBuilder ();
1592 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1598 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1603 case MONO_PATCH_INFO_INTERNAL_METHOD:
1604 name = g_strdup_printf ("jit_icall_%s", data);
1606 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1607 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1608 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1612 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1620 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1624 LLVMValueRef indexes [2];
1625 LLVMValueRef got_entry_addr, load;
1626 LLVMBuilderRef builder = ctx->builder;
1631 MonoJumpInfo tmp_ji;
1633 tmp_ji.data.target = data;
1635 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1637 ji->next = cfg->patch_info;
1638 cfg->patch_info = ji;
1640 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1641 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1643 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1644 * explicitly initialize it.
1646 if (!mono_aot_is_shared_got_offset (got_offset)) {
1647 //mono_print_ji (ji);
1649 ctx->has_got_access = TRUE;
1652 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1653 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1654 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1656 name = get_aotconst_name (type, data, got_offset);
1658 load = LLVMBuildLoad (builder, got_entry_addr, "");
1659 load = convert (ctx, load, llvm_type);
1660 LLVMSetValueName (load, name ? name : "");
1662 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1665 //set_invariant_load_flag (load);
1671 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1673 return get_aotconst_typed (ctx, type, data, NULL);
1677 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1679 LLVMValueRef callee;
1681 if (ctx->llvm_only) {
1682 callee_name = mono_aot_get_direct_call_symbol (type, data);
1684 /* Directly callable */
1686 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1688 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1690 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1692 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1694 /* LLVMTypeRef's are uniqued */
1695 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1696 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1698 g_free (callee_name);
1704 * Calls are made through the GOT.
1706 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1708 MonoJumpInfo *ji = NULL;
1710 callee_name = mono_aot_get_plt_symbol (type, data);
1714 if (ctx->cfg->compile_aot)
1715 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1716 mono_add_patch_info (ctx->cfg, 0, type, data);
1719 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1721 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1723 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1725 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1728 if (ctx->cfg->compile_aot) {
1729 ji = g_new0 (MonoJumpInfo, 1);
1731 ji->data.target = data;
1733 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1741 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1743 #if LLVM_API_VERSION > 100
1744 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1745 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1746 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1747 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1750 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1751 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1757 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1759 MonoMethodHeader *header = cfg->header;
1760 MonoExceptionClause *clause;
1764 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1765 return (bb->region >> 8) - 1;
1768 for (i = 0; i < header->num_clauses; ++i) {
1769 clause = &header->clauses [i];
1771 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1778 static MonoExceptionClause *
1779 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1781 if (bb == cfg->bb_init)
1783 // Since they're sorted by nesting we just need
1784 // the first one that the bb is a member of
1785 for (int i = 0; i < cfg->header->num_clauses; i++) {
1786 MonoExceptionClause *curr = &cfg->header->clauses [i];
1788 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1796 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1798 LLVMValueRef md_arg;
1801 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1802 md_arg = LLVMMDString ("mono", 4);
1803 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1807 set_invariant_load_flag (LLVMValueRef v)
1809 LLVMValueRef md_arg;
1811 const char *flag_name;
1813 // FIXME: Cache this
1814 flag_name = "invariant.load";
1815 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1816 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1817 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1823 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1827 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1829 MonoCompile *cfg = ctx->cfg;
1830 LLVMValueRef lcall = NULL;
1831 LLVMBuilderRef builder = *builder_ref;
1832 MonoExceptionClause *clause;
1834 if (ctx->llvm_only) {
1835 clause = get_most_deep_clause (cfg, ctx, bb);
1838 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause->flags == MONO_EXCEPTION_CLAUSE_FAULT);
1841 * Have to use an invoke instead of a call, branching to the
1842 * handler bblock of the clause containing this bblock.
1844 intptr_t key = CLAUSE_END(clause);
1846 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1848 // FIXME: Find the one that has the lowest end bound for the right start address
1849 // FIXME: Finally + nesting
1852 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1855 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1857 builder = ctx->builder = create_builder (ctx);
1858 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1860 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1864 int clause_index = get_handler_clause (cfg, bb);
1866 if (clause_index != -1) {
1867 MonoMethodHeader *header = cfg->header;
1868 MonoExceptionClause *ec = &header->clauses [clause_index];
1869 MonoBasicBlock *tblock;
1870 LLVMBasicBlockRef ex_bb, noex_bb;
1873 * Have to use an invoke instead of a call, branching to the
1874 * handler bblock of the clause containing this bblock.
1877 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY || ec->flags == MONO_EXCEPTION_CLAUSE_FAULT);
1879 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1882 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1884 ex_bb = get_bb (ctx, tblock);
1886 noex_bb = gen_bb (ctx, "NOEX_BB");
1889 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1891 builder = ctx->builder = create_builder (ctx);
1892 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1894 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1899 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1900 ctx->builder = builder;
1904 *builder_ref = ctx->builder;
1910 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1912 const char *intrins_name;
1913 LLVMValueRef args [16], res;
1914 LLVMTypeRef addr_type;
1915 gboolean use_intrinsics = TRUE;
1917 #if LLVM_API_VERSION > 100
1918 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1919 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1922 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1923 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1924 *builder_ref = ctx->builder;
1925 use_intrinsics = FALSE;
1929 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1930 LLVMAtomicOrdering ordering;
1933 case LLVM_BARRIER_NONE:
1934 ordering = LLVMAtomicOrderingNotAtomic;
1936 case LLVM_BARRIER_ACQ:
1937 ordering = LLVMAtomicOrderingAcquire;
1939 case LLVM_BARRIER_SEQ:
1940 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1943 g_assert_not_reached ();
1948 * We handle loads which can fault by calling a mono specific intrinsic
1949 * using an invoke, so they are handled properly inside try blocks.
1950 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1951 * are marked with IntrReadArgMem.
1955 intrins_name = "llvm.mono.load.i8.p0i8";
1958 intrins_name = "llvm.mono.load.i16.p0i16";
1961 intrins_name = "llvm.mono.load.i32.p0i32";
1964 intrins_name = "llvm.mono.load.i64.p0i64";
1967 g_assert_not_reached ();
1970 addr_type = LLVMTypeOf (addr);
1971 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1972 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1975 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1976 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1977 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1978 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1980 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1981 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1982 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1983 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1990 * We emit volatile loads for loads which can fault, because otherwise
1991 * LLVM will generate invalid code when encountering a load from a
1994 if (barrier != LLVM_BARRIER_NONE)
1995 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1997 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1999 /* Mark it with a custom metadata */
2002 set_metadata_flag (res, "mono.faulting.load");
2010 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
2012 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
2016 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
2018 const char *intrins_name;
2019 LLVMValueRef args [16];
2020 gboolean use_intrinsics = TRUE;
2022 #if LLVM_API_VERSION > 100
2023 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
2024 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2025 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
2026 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
2027 *builder_ref = ctx->builder;
2028 use_intrinsics = FALSE;
2032 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2033 LLVMAtomicOrdering ordering;
2036 case LLVM_BARRIER_NONE:
2037 ordering = LLVMAtomicOrderingNotAtomic;
2039 case LLVM_BARRIER_REL:
2040 ordering = LLVMAtomicOrderingRelease;
2042 case LLVM_BARRIER_SEQ:
2043 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2046 g_assert_not_reached ();
2052 intrins_name = "llvm.mono.store.i8.p0i8";
2055 intrins_name = "llvm.mono.store.i16.p0i16";
2058 intrins_name = "llvm.mono.store.i32.p0i32";
2061 intrins_name = "llvm.mono.store.i64.p0i64";
2064 g_assert_not_reached ();
2067 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2068 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2069 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2074 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2075 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2076 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2077 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2079 if (barrier != LLVM_BARRIER_NONE)
2080 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2082 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2087 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2089 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2093 * emit_cond_system_exception:
2095 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2096 * Might set the ctx exception.
2099 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2101 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2102 LLVMBuilderRef builder;
2103 MonoClass *exc_class;
2104 LLVMValueRef args [2];
2105 LLVMValueRef callee;
2106 gboolean no_pc = FALSE;
2108 if (IS_TARGET_AMD64)
2109 /* Some platforms don't require the pc argument */
2112 ex_bb = gen_bb (ctx, "EX_BB");
2114 ex2_bb = gen_bb (ctx, "EX2_BB");
2115 noex_bb = gen_bb (ctx, "NOEX_BB");
2117 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2119 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2121 /* Emit exception throwing code */
2122 ctx->builder = builder = create_builder (ctx);
2123 LLVMPositionBuilderAtEnd (builder, ex_bb);
2125 if (ctx->cfg->llvm_only) {
2126 static LLVMTypeRef sig;
2129 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2130 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2132 LLVMBuildBr (builder, ex2_bb);
2134 ctx->builder = builder = create_builder (ctx);
2135 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2137 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2138 emit_call (ctx, bb, &builder, callee, args, 1);
2139 LLVMBuildUnreachable (builder);
2141 ctx->builder = builder = create_builder (ctx);
2142 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2144 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2150 callee = ctx->module->throw_corlib_exception;
2153 const char *icall_name;
2156 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2158 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2159 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2161 if (ctx->cfg->compile_aot) {
2162 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2165 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2166 * - On x86, LLVM generated code doesn't push the arguments
2167 * - The trampoline takes the throw address as an arguments, not a pc offset.
2169 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2170 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2172 #if LLVM_API_VERSION > 100
2174 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2175 * added by emit_jit_callee ().
2177 ex2_bb = gen_bb (ctx, "EX2_BB");
2178 LLVMBuildBr (builder, ex2_bb);
2181 ctx->builder = builder = create_builder (ctx);
2182 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2184 mono_memory_barrier ();
2185 ctx->module->throw_corlib_exception = callee;
2190 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2193 * The LLVM mono branch contains changes so a block address can be passed as an
2194 * argument to a call.
2197 emit_call (ctx, bb, &builder, callee, args, 1);
2199 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2200 emit_call (ctx, bb, &builder, callee, args, 2);
2203 LLVMBuildUnreachable (builder);
2205 ctx->builder = builder = create_builder (ctx);
2206 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2208 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2215 * emit_args_to_vtype:
2217 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2220 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2222 int j, size, nslots;
2224 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2226 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2227 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2230 if (ainfo->storage == LLVMArgAsFpArgs)
2231 nslots = ainfo->nslots;
2235 for (j = 0; j < nslots; ++j) {
2236 LLVMValueRef index [2], addr, daddr;
2237 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2238 LLVMTypeRef part_type;
2240 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2243 if (ainfo->pair_storage [j] == LLVMArgNone)
2246 switch (ainfo->pair_storage [j]) {
2247 case LLVMArgInIReg: {
2248 part_type = LLVMIntType (part_size * 8);
2249 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2250 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2251 addr = LLVMBuildGEP (builder, address, index, 1, "");
2253 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2254 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2255 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2257 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2260 case LLVMArgInFPReg: {
2261 LLVMTypeRef arg_type;
2263 if (ainfo->esize == 8)
2264 arg_type = LLVMDoubleType ();
2266 arg_type = LLVMFloatType ();
2268 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2269 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2270 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2271 LLVMBuildStore (builder, args [j], addr);
2277 g_assert_not_reached ();
2280 size -= sizeof (gpointer);
2285 * emit_vtype_to_args:
2287 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2288 * into ARGS, and the number of arguments into NARGS.
2291 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2294 int j, size, nslots;
2295 LLVMTypeRef arg_type;
2297 size = get_vtype_size (t);
2299 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2300 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2302 if (ainfo->storage == LLVMArgAsFpArgs)
2303 nslots = ainfo->nslots;
2306 for (j = 0; j < nslots; ++j) {
2307 LLVMValueRef index [2], addr, daddr;
2308 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2310 if (ainfo->pair_storage [j] == LLVMArgNone)
2313 switch (ainfo->pair_storage [j]) {
2315 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2316 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2317 addr = LLVMBuildGEP (builder, address, index, 1, "");
2319 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2320 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2321 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2323 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2325 case LLVMArgInFPReg:
2326 if (ainfo->esize == 8)
2327 arg_type = LLVMDoubleType ();
2329 arg_type = LLVMFloatType ();
2330 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2331 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2332 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2333 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2338 g_assert_not_reached ();
2340 size -= sizeof (gpointer);
2347 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2350 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2351 * get executed every time control reaches them.
2353 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2355 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2356 return ctx->last_alloca;
2360 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2362 return build_alloca_llvm_type_name (ctx, t, align, "");
2366 build_alloca (EmitContext *ctx, MonoType *t)
2368 MonoClass *k = mono_class_from_mono_type (t);
2371 g_assert (!mini_is_gsharedvt_variable_type (t));
2373 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2376 align = mono_class_min_align (k);
2378 /* Sometimes align is not a power of 2 */
2379 while (mono_is_power_of_two (align) == -1)
2382 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2386 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2390 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2392 MonoCompile *cfg = ctx->cfg;
2393 LLVMBuilderRef builder = ctx->builder;
2394 LLVMValueRef offset, offset_var;
2395 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2396 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2400 g_assert (info_var);
2401 g_assert (locals_var);
2403 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2405 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2406 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2408 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2409 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2411 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2415 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2418 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2421 module->used = g_ptr_array_sized_new (16);
2422 g_ptr_array_add (module->used, global);
2426 emit_llvm_used (MonoLLVMModule *module)
2428 LLVMModuleRef lmodule = module->lmodule;
2429 LLVMTypeRef used_type;
2430 LLVMValueRef used, *used_elem;
2436 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2437 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2438 used_elem = g_new0 (LLVMValueRef, module->used->len);
2439 for (i = 0; i < module->used->len; ++i)
2440 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2441 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2442 LLVMSetLinkage (used, LLVMAppendingLinkage);
2443 LLVMSetSection (used, "llvm.metadata");
2449 * Emit a function mapping method indexes to their code
2452 emit_get_method (MonoLLVMModule *module)
2454 LLVMModuleRef lmodule = module->lmodule;
2455 LLVMValueRef func, switch_ins, m;
2456 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2457 LLVMBasicBlockRef *bbs;
2459 LLVMBuilderRef builder = LLVMCreateBuilder ();
2464 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2465 * but generating code seems safer.
2467 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2468 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2469 LLVMSetLinkage (func, LLVMExternalLinkage);
2470 LLVMSetVisibility (func, LLVMHiddenVisibility);
2471 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
2472 module->get_method = func;
2474 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2477 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2478 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2479 * then we will have to find another solution.
2482 name = g_strdup_printf ("BB_CODE_START");
2483 code_start_bb = LLVMAppendBasicBlock (func, name);
2485 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2486 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2488 name = g_strdup_printf ("BB_CODE_END");
2489 code_end_bb = LLVMAppendBasicBlock (func, name);
2491 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2492 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2494 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2495 for (i = 0; i < module->max_method_idx + 1; ++i) {
2496 name = g_strdup_printf ("BB_%d", i);
2497 bb = LLVMAppendBasicBlock (func, name);
2501 LLVMPositionBuilderAtEnd (builder, bb);
2503 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2505 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2507 LLVMBuildRet (builder, LLVMConstNull (rtype));
2510 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2511 LLVMPositionBuilderAtEnd (builder, fail_bb);
2512 LLVMBuildRet (builder, LLVMConstNull (rtype));
2514 LLVMPositionBuilderAtEnd (builder, entry_bb);
2516 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2517 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2518 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2519 for (i = 0; i < module->max_method_idx + 1; ++i) {
2520 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2523 mark_as_used (module, func);
2525 LLVMDisposeBuilder (builder);
2529 * emit_get_unbox_tramp:
2531 * Emit a function mapping method indexes to their unbox trampoline
2534 emit_get_unbox_tramp (MonoLLVMModule *module)
2536 LLVMModuleRef lmodule = module->lmodule;
2537 LLVMValueRef func, switch_ins, m;
2538 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2539 LLVMBasicBlockRef *bbs;
2541 LLVMBuilderRef builder = LLVMCreateBuilder ();
2545 /* Similar to emit_get_method () */
2547 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2548 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2549 LLVMSetLinkage (func, LLVMExternalLinkage);
2550 LLVMSetVisibility (func, LLVMHiddenVisibility);
2551 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
2552 module->get_unbox_tramp = func;
2554 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2556 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2557 for (i = 0; i < module->max_method_idx + 1; ++i) {
2558 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2562 name = g_strdup_printf ("BB_%d", i);
2563 bb = LLVMAppendBasicBlock (func, name);
2567 LLVMPositionBuilderAtEnd (builder, bb);
2569 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2572 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2573 LLVMPositionBuilderAtEnd (builder, fail_bb);
2574 LLVMBuildRet (builder, LLVMConstNull (rtype));
2576 LLVMPositionBuilderAtEnd (builder, entry_bb);
2578 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2579 for (i = 0; i < module->max_method_idx + 1; ++i) {
2580 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2584 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2587 mark_as_used (module, func);
2588 LLVMDisposeBuilder (builder);
2591 /* Add a function to mark the beginning of LLVM code */
2593 emit_llvm_code_start (MonoLLVMModule *module)
2595 LLVMModuleRef lmodule = module->lmodule;
2597 LLVMBasicBlockRef entry_bb;
2598 LLVMBuilderRef builder;
2600 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2601 LLVMSetLinkage (func, LLVMInternalLinkage);
2602 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
2603 module->code_start = func;
2604 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2605 builder = LLVMCreateBuilder ();
2606 LLVMPositionBuilderAtEnd (builder, entry_bb);
2607 LLVMBuildRetVoid (builder);
2608 LLVMDisposeBuilder (builder);
2612 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2614 LLVMModuleRef lmodule = module->lmodule;
2615 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2616 LLVMBasicBlockRef entry_bb;
2617 LLVMBuilderRef builder;
2624 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2625 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2630 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2631 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2634 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2635 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2638 g_assert_not_reached ();
2640 LLVMSetLinkage (func, LLVMInternalLinkage);
2641 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_INLINE);
2642 mono_llvm_set_preserveall_cc (func);
2643 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2644 builder = LLVMCreateBuilder ();
2645 LLVMPositionBuilderAtEnd (builder, entry_bb);
2648 ji = g_new0 (MonoJumpInfo, 1);
2649 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2650 ji = mono_aot_patch_info_dup (ji);
2651 got_offset = mono_aot_get_got_offset (ji);
2652 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2653 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2654 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2655 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2656 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2657 args [1] = LLVMGetParam (func, 0);
2659 args [2] = LLVMGetParam (func, 1);
2661 ji = g_new0 (MonoJumpInfo, 1);
2662 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2663 ji->data.name = icall_name;
2664 ji = mono_aot_patch_info_dup (ji);
2665 got_offset = mono_aot_get_got_offset (ji);
2666 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2667 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2668 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2669 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2670 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2671 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2672 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2674 // Set the inited flag
2675 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2676 indexes [1] = LLVMGetParam (func, 0);
2677 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2679 LLVMBuildRetVoid (builder);
2681 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2682 LLVMDisposeBuilder (builder);
2687 * Emit wrappers around the C icalls used to initialize llvm methods, to
2688 * make the calling code smaller and to enable usage of the llvm
2689 * PreserveAll calling convention.
2692 emit_init_icall_wrappers (MonoLLVMModule *module)
2694 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2695 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2696 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2697 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2701 emit_llvm_code_end (MonoLLVMModule *module)
2703 LLVMModuleRef lmodule = module->lmodule;
2705 LLVMBasicBlockRef entry_bb;
2706 LLVMBuilderRef builder;
2708 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2709 LLVMSetLinkage (func, LLVMInternalLinkage);
2710 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
2711 module->code_end = func;
2712 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2713 builder = LLVMCreateBuilder ();
2714 LLVMPositionBuilderAtEnd (builder, entry_bb);
2715 LLVMBuildRetVoid (builder);
2716 LLVMDisposeBuilder (builder);
2720 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2722 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2725 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2726 need_div_check = TRUE;
2728 if (!need_div_check)
2731 switch (ins->opcode) {
2744 case OP_IDIV_UN_IMM:
2745 case OP_LDIV_UN_IMM:
2746 case OP_IREM_UN_IMM:
2747 case OP_LREM_UN_IMM: {
2749 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2750 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2752 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2753 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2756 builder = ctx->builder;
2758 /* b == -1 && a == 0x80000000 */
2760 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2761 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2762 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2764 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2765 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2768 builder = ctx->builder;
2780 * Emit code to initialize the GOT slots used by the method.
2783 emit_init_method (EmitContext *ctx)
2785 LLVMValueRef indexes [16], args [16], callee;
2786 LLVMValueRef inited_var, cmp, call;
2787 LLVMBasicBlockRef inited_bb, notinited_bb;
2788 LLVMBuilderRef builder = ctx->builder;
2789 MonoCompile *cfg = ctx->cfg;
2791 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2793 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2794 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2795 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2797 args [0] = inited_var;
2798 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2799 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2801 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2803 inited_bb = ctx->inited_bb;
2804 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2806 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2808 builder = ctx->builder = create_builder (ctx);
2809 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2812 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2813 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2814 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2815 callee = ctx->module->init_method_gshared_mrgctx;
2816 call = LLVMBuildCall (builder, callee, args, 2, "");
2817 } else if (ctx->rgctx_arg) {
2818 /* A vtable is passed as the rgctx argument */
2819 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2820 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2821 callee = ctx->module->init_method_gshared_vtable;
2822 call = LLVMBuildCall (builder, callee, args, 2, "");
2823 } else if (cfg->gshared) {
2824 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2825 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2826 callee = ctx->module->init_method_gshared_this;
2827 call = LLVMBuildCall (builder, callee, args, 2, "");
2829 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2830 callee = ctx->module->init_method;
2831 call = LLVMBuildCall (builder, callee, args, 1, "");
2835 * This enables llvm to keep arguments in their original registers/
2836 * scratch registers, since the call will not clobber them.
2838 mono_llvm_set_call_preserveall_cc (call);
2840 LLVMBuildBr (builder, inited_bb);
2841 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2843 builder = ctx->builder = create_builder (ctx);
2844 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2848 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2851 * Emit unbox trampoline using a tail call
2853 LLVMValueRef tramp, call, *args;
2854 LLVMBuilderRef builder;
2855 LLVMBasicBlockRef lbb;
2856 LLVMCallInfo *linfo;
2860 tramp_name = g_strdup_printf ("ut_%s", method_name);
2861 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2862 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2863 mono_llvm_add_func_attr (tramp, LLVM_ATTR_OPTIMIZE_FOR_SIZE);
2864 //mono_llvm_add_func_attr (tramp, LLVM_ATTR_NO_UNWIND);
2866 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2867 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2868 mono_llvm_add_param_attr (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVM_ATTR_IN_REG);
2869 if (ctx->cfg->vret_addr) {
2870 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2871 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2872 mono_llvm_add_param_attr (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVM_ATTR_STRUCT_RET);
2873 mono_llvm_add_param_attr (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVM_ATTR_NO_ALIAS);
2877 lbb = LLVMAppendBasicBlock (tramp, "");
2878 builder = LLVMCreateBuilder ();
2879 LLVMPositionBuilderAtEnd (builder, lbb);
2881 nargs = LLVMCountParamTypes (method_type);
2882 args = g_new0 (LLVMValueRef, nargs);
2883 for (i = 0; i < nargs; ++i) {
2884 args [i] = LLVMGetParam (tramp, i);
2885 if (i == ctx->this_arg_pindex) {
2886 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2888 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2889 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2890 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2893 call = LLVMBuildCall (builder, method, args, nargs, "");
2894 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2895 mono_llvm_add_instr_attr (call, 1 + ctx->rgctx_arg_pindex, LLVM_ATTR_IN_REG);
2896 if (linfo->ret.storage == LLVMArgVtypeByRef)
2897 mono_llvm_add_instr_attr (call, 1 + linfo->vret_arg_pindex, LLVM_ATTR_STRUCT_RET);
2899 // FIXME: This causes assertions in clang
2900 //mono_llvm_set_must_tail (call);
2901 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2902 LLVMBuildRetVoid (builder);
2904 LLVMBuildRet (builder, call);
2906 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2907 LLVMDisposeBuilder (builder);
2913 * Emit code to load/convert arguments.
2916 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2919 MonoCompile *cfg = ctx->cfg;
2920 MonoMethodSignature *sig = ctx->sig;
2921 LLVMCallInfo *linfo = ctx->linfo;
2925 LLVMBuilderRef old_builder = ctx->builder;
2926 ctx->builder = builder;
2928 ctx->alloca_builder = create_builder (ctx);
2931 * Handle indirect/volatile variables by allocating memory for them
2932 * using 'alloca', and storing their address in a temporary.
2934 for (i = 0; i < cfg->num_varinfo; ++i) {
2935 MonoInst *var = cfg->varinfo [i];
2938 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2939 } 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))) {
2940 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2943 /* Could be already created by an OP_VPHI */
2944 if (!ctx->addresses [var->dreg]) {
2945 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2946 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2948 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2952 names = g_new (char *, sig->param_count);
2953 mono_method_get_param_names (cfg->method, (const char **) names);
2955 for (i = 0; i < sig->param_count; ++i) {
2956 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2957 int reg = cfg->args [i + sig->hasthis]->dreg;
2960 pindex = ainfo->pindex;
2962 switch (ainfo->storage) {
2963 case LLVMArgVtypeInReg:
2964 case LLVMArgAsFpArgs: {
2965 LLVMValueRef args [8];
2968 pindex += ainfo->ndummy_fpargs;
2970 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2971 memset (args, 0, sizeof (args));
2972 if (ainfo->storage == LLVMArgVtypeInReg) {
2973 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2974 if (ainfo->pair_storage [1] != LLVMArgNone)
2975 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2977 g_assert (ainfo->nslots <= 8);
2978 for (j = 0; j < ainfo->nslots; ++j)
2979 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2981 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2983 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2985 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2986 /* Treat these as normal values */
2987 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2991 case LLVMArgVtypeByVal: {
2992 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2994 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2995 /* Treat these as normal values */
2996 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
3000 case LLVMArgVtypeByRef: {
3001 /* The argument is passed by ref */
3002 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3005 case LLVMArgAsIArgs: {
3006 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3009 /* The argument is received as an array of ints, store it into the real argument */
3010 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
3012 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
3013 if (size < SIZEOF_VOID_P) {
3014 /* The upper bits of the registers might not be valid */
3015 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
3016 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
3017 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
3019 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
3023 case LLVMArgVtypeAsScalar:
3024 g_assert_not_reached ();
3026 case LLVMArgGsharedvtFixed: {
3027 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3028 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3031 name = g_strdup_printf ("arg_%s", names [i]);
3033 name = g_strdup_printf ("arg_%d", i);
3035 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3038 case LLVMArgGsharedvtFixedVtype: {
3039 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3042 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3044 name = g_strdup_printf ("vtype_arg_%d", i);
3046 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3047 g_assert (ctx->addresses [reg]);
3048 LLVMSetValueName (ctx->addresses [reg], name);
3049 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3052 case LLVMArgGsharedvtVariable:
3053 /* The IR treats these as variables with addresses */
3054 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3057 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));
3064 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3066 emit_volatile_store (ctx, cfg->args [0]->dreg);
3067 for (i = 0; i < sig->param_count; ++i)
3068 if (!mini_type_is_vtype (sig->params [i]))
3069 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3071 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3072 LLVMValueRef this_alloc;
3075 * The exception handling code needs the location where the this argument was
3076 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3077 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3078 * location into the LSDA.
3080 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3081 /* This volatile store will keep the alloca alive */
3082 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3084 set_metadata_flag (this_alloc, "mono.this");
3087 if (cfg->rgctx_var) {
3088 LLVMValueRef rgctx_alloc, store;
3091 * We handle the rgctx arg similarly to the this pointer.
3093 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3094 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3095 /* This volatile store will keep the alloca alive */
3096 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3098 set_metadata_flag (rgctx_alloc, "mono.this");
3101 /* Initialize the method if needed */
3102 if (cfg->compile_aot && ctx->llvm_only) {
3103 /* Emit a location for the initialization code */
3104 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3105 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3107 LLVMBuildBr (ctx->builder, ctx->init_bb);
3108 builder = ctx->builder = create_builder (ctx);
3109 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3110 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3113 /* Compute nesting between clauses */
3114 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3115 for (i = 0; i < cfg->header->num_clauses; ++i) {
3116 for (j = 0; j < cfg->header->num_clauses; ++j) {
3117 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3118 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3120 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3121 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3126 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3127 * it needs to continue normally, or return back to the exception handling system.
3129 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3133 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3136 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3137 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3138 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3140 if (bb->in_scount == 0) {
3143 sprintf (name, "finally_ind_bb%d", bb->block_num);
3144 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3145 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3147 ctx->bblocks [bb->block_num].finally_ind = val;
3149 /* Create a variable to hold the exception var */
3151 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3155 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3156 * LLVM bblock containing a landing pad causes problems for the
3157 * LLVM optimizer passes.
3159 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3160 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3162 ctx->builder = old_builder;
3166 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3168 MonoCompile *cfg = ctx->cfg;
3169 LLVMValueRef *values = ctx->values;
3170 LLVMValueRef *addresses = ctx->addresses;
3171 MonoCallInst *call = (MonoCallInst*)ins;
3172 MonoMethodSignature *sig = call->signature;
3173 LLVMValueRef callee = NULL, lcall;
3175 LLVMCallInfo *cinfo;
3179 LLVMTypeRef llvm_sig;
3181 gboolean is_virtual, calli, preserveall;
3182 LLVMBuilderRef builder = *builder_ref;
3184 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3185 set_failure (ctx, "non-default callconv");
3189 cinfo = call->cinfo;
3191 if (call->rgctx_arg_reg)
3192 cinfo->rgctx_arg = TRUE;
3193 if (call->imt_arg_reg)
3194 cinfo->imt_arg = TRUE;
3196 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3198 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3202 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);
3203 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);
3205 preserveall = FALSE;
3207 /* FIXME: Avoid creating duplicate methods */
3209 if (ins->flags & MONO_INST_HAS_METHOD) {
3213 if (cfg->compile_aot) {
3214 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3216 set_failure (ctx, "can't encode patch");
3219 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3221 * Collect instructions representing the callee into a hash so they can be replaced
3222 * by the llvm method for the callee if the callee turns out to be direct
3223 * callable. Currently this only requires it to not fail llvm compilation.
3225 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3226 l = g_slist_prepend (l, callee);
3227 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3231 static int tramp_index;
3234 name = g_strdup_printf ("tramp_%d", tramp_index);
3237 #if LLVM_API_VERSION > 100
3239 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3240 * Make all calls through a global. The address of the global will be saved in
3241 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3244 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3247 mono_create_jit_trampoline (mono_domain_get (),
3248 call->method, &error);
3249 if (!is_ok (&error)) {
3250 set_failure (ctx, mono_error_get_message (&error));
3251 mono_error_cleanup (&error);
3255 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3256 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3257 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3258 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3260 callee = LLVMBuildLoad (builder, tramp_var, "");
3263 mono_create_jit_trampoline (mono_domain_get (),
3264 call->method, &error);
3265 if (!is_ok (&error)) {
3267 set_failure (ctx, mono_error_get_message (&error));
3268 mono_error_cleanup (&error);
3272 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3275 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3280 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3281 /* LLVM miscompiles async methods */
3282 set_failure (ctx, "#13734");
3287 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3293 memset (&ji, 0, sizeof (ji));
3294 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3295 ji.data.target = info->name;
3297 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3299 if (cfg->compile_aot) {
3300 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3302 set_failure (ctx, "can't encode patch");
3306 target = (gpointer)mono_icall_get_wrapper (info);
3307 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3310 if (cfg->compile_aot) {
3312 if (cfg->abs_patches) {
3313 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3315 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3317 set_failure (ctx, "can't encode patch");
3323 set_failure (ctx, "aot");
3327 #if LLVM_API_VERSION > 100
3328 if (cfg->abs_patches) {
3329 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3333 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3334 mono_error_assert_ok (&error);
3335 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3337 g_assert_not_reached ();
3340 g_assert_not_reached ();
3343 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3345 if (cfg->abs_patches) {
3346 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3351 * FIXME: Some trampolines might have
3352 * their own calling convention on some platforms.
3354 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3355 mono_error_assert_ok (&error);
3356 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3360 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3367 int size = sizeof (gpointer);
3370 g_assert (ins->inst_offset % size == 0);
3371 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3373 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3375 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3377 if (ins->flags & MONO_INST_HAS_METHOD) {
3382 * Collect and convert arguments
3384 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3385 len = sizeof (LLVMValueRef) * nargs;
3386 args = (LLVMValueRef*)alloca (len);
3387 memset (args, 0, len);
3388 l = call->out_ireg_args;
3390 if (call->rgctx_arg_reg) {
3391 g_assert (values [call->rgctx_arg_reg]);
3392 g_assert (cinfo->rgctx_arg_pindex < nargs);
3394 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3395 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3396 * it using a volatile load.
3399 if (!ctx->imt_rgctx_loc)
3400 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3401 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3402 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3404 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3407 if (call->imt_arg_reg) {
3408 g_assert (!ctx->llvm_only);
3409 g_assert (values [call->imt_arg_reg]);
3410 g_assert (cinfo->imt_arg_pindex < nargs);
3412 if (!ctx->imt_rgctx_loc)
3413 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3414 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3415 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3417 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3420 switch (cinfo->ret.storage) {
3421 case LLVMArgGsharedvtVariable: {
3422 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3424 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3425 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3427 g_assert (addresses [call->inst.dreg]);
3428 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3434 if (!addresses [call->inst.dreg])
3435 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3436 g_assert (cinfo->vret_arg_pindex < nargs);
3437 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3438 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3440 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3446 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3447 * use the real callee for argument type conversion.
3449 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3450 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3451 LLVMGetParamTypes (callee_type, param_types);
3453 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3456 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3458 pindex = ainfo->pindex;
3460 regpair = (guint32)(gssize)(l->data);
3461 reg = regpair & 0xffffff;
3462 args [pindex] = values [reg];
3463 switch (ainfo->storage) {
3464 case LLVMArgVtypeInReg:
3465 case LLVMArgAsFpArgs: {
3469 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3470 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3471 pindex += ainfo->ndummy_fpargs;
3473 g_assert (addresses [reg]);
3474 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3478 // FIXME: Get rid of the VMOVE
3481 case LLVMArgVtypeByVal:
3482 g_assert (addresses [reg]);
3483 args [pindex] = addresses [reg];
3485 case LLVMArgVtypeByRef: {
3486 g_assert (addresses [reg]);
3487 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3490 case LLVMArgAsIArgs:
3491 g_assert (addresses [reg]);
3492 if (ainfo->esize == 8)
3493 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (LLVMInt64Type (), ainfo->nslots), 0)), "");
3495 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3497 case LLVMArgVtypeAsScalar:
3498 g_assert_not_reached ();
3500 case LLVMArgGsharedvtFixed:
3501 case LLVMArgGsharedvtFixedVtype:
3502 g_assert (addresses [reg]);
3503 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3505 case LLVMArgGsharedvtVariable:
3506 g_assert (addresses [reg]);
3507 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3510 g_assert (args [pindex]);
3511 if (i == 0 && sig->hasthis)
3512 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3514 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3517 g_assert (pindex <= nargs);
3522 // FIXME: Align call sites
3528 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3530 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3531 mono_llvm_set_call_notail (lcall);
3534 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3536 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3537 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3539 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3540 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3541 if (!sig->pinvoke && !cfg->llvm_only)
3542 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3544 mono_llvm_set_call_preserveall_cc (lcall);
3546 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3547 mono_llvm_add_instr_attr (lcall, 1 + cinfo->vret_arg_pindex, LLVM_ATTR_STRUCT_RET);
3548 if (!ctx->llvm_only && call->rgctx_arg_reg)
3549 mono_llvm_add_instr_attr (lcall, 1 + cinfo->rgctx_arg_pindex, LLVM_ATTR_IN_REG);
3550 if (call->imt_arg_reg)
3551 mono_llvm_add_instr_attr (lcall, 1 + cinfo->imt_arg_pindex, LLVM_ATTR_IN_REG);
3553 /* Add byval attributes if needed */
3554 for (i = 0; i < sig->param_count; ++i) {
3555 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3557 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3558 mono_llvm_add_instr_attr (lcall, 1 + ainfo->pindex, LLVM_ATTR_BY_VAL);
3562 * Convert the result
3564 switch (cinfo->ret.storage) {
3565 case LLVMArgVtypeInReg: {
3566 LLVMValueRef regs [2];
3568 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3572 if (!addresses [ins->dreg])
3573 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3575 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3576 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3577 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3578 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3581 case LLVMArgVtypeByVal:
3582 if (!addresses [call->inst.dreg])
3583 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3584 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3586 case LLVMArgAsIArgs:
3587 case LLVMArgFpStruct:
3588 if (!addresses [call->inst.dreg])
3589 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3590 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3592 case LLVMArgVtypeAsScalar:
3593 if (!addresses [call->inst.dreg])
3594 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3595 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3597 case LLVMArgVtypeRetAddr:
3598 case LLVMArgVtypeByRef:
3599 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3600 /* Some opcodes like STOREX_MEMBASE access these by value */
3601 g_assert (addresses [call->inst.dreg]);
3602 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3605 case LLVMArgGsharedvtVariable:
3607 case LLVMArgGsharedvtFixed:
3608 case LLVMArgGsharedvtFixedVtype:
3609 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3612 if (sig->ret->type != MONO_TYPE_VOID)
3613 /* If the method returns an unsigned value, need to zext it */
3614 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));
3618 *builder_ref = ctx->builder;
3622 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3624 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3625 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3627 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3630 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3632 if (ctx->cfg->compile_aot) {
3633 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3635 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3636 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3637 mono_memory_barrier ();
3640 ctx->module->rethrow = callee;
3642 ctx->module->throw_icall = callee;
3646 LLVMValueRef args [2];
3648 args [0] = convert (ctx, exc, exc_type);
3649 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3651 LLVMBuildUnreachable (ctx->builder);
3653 ctx->builder = create_builder (ctx);
3657 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3659 MonoMethodSignature *throw_sig;
3660 LLVMValueRef callee, arg;
3661 const char *icall_name;
3663 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3664 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3667 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3668 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3669 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3670 if (ctx->cfg->compile_aot) {
3671 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3676 * LLVM doesn't push the exception argument, so we need a different
3679 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3681 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3683 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3686 mono_memory_barrier ();
3687 #if LLVM_API_VERSION < 100
3689 ctx->module->rethrow = callee;
3691 ctx->module->throw_icall = callee;
3694 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3695 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3699 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3701 const char *icall_name = "mono_llvm_resume_exception";
3702 LLVMValueRef callee = ctx->module->resume_eh;
3704 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3707 if (ctx->cfg->compile_aot) {
3708 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3710 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3711 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3712 mono_memory_barrier ();
3714 ctx->module->resume_eh = callee;
3718 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3720 LLVMBuildUnreachable (ctx->builder);
3722 ctx->builder = create_builder (ctx);
3726 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3728 const char *icall_name = "mono_llvm_clear_exception";
3730 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3731 LLVMValueRef callee = NULL;
3734 if (ctx->cfg->compile_aot) {
3735 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3737 // FIXME: This is broken.
3738 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3742 g_assert (builder && callee);
3744 return LLVMBuildCall (builder, callee, NULL, 0, "");
3748 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3750 const char *icall_name = "mono_llvm_load_exception";
3752 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3753 LLVMValueRef callee = NULL;
3756 if (ctx->cfg->compile_aot) {
3757 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3759 // FIXME: This is broken.
3760 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3764 g_assert (builder && callee);
3766 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3771 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3773 const char *icall_name = "mono_llvm_match_exception";
3775 ctx->builder = builder;
3777 const int num_args = 5;
3778 LLVMValueRef args [num_args];
3779 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3780 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3781 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3782 if (ctx->cfg->rgctx_var) {
3783 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3784 g_assert (rgctx_alloc);
3785 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3787 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3790 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3792 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3794 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3795 LLVMValueRef callee = ctx->module->match_exc;
3798 if (ctx->cfg->compile_aot) {
3799 ctx->builder = builder;
3800 // get_callee expects ctx->builder to be the emitting builder
3801 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3803 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3804 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3805 ctx->module->match_exc = callee;
3806 mono_memory_barrier ();
3810 g_assert (builder && callee);
3812 g_assert (ctx->ex_var);
3814 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3817 // FIXME: This won't work because the code-finding makes this
3819 /*#define MONO_PERSONALITY_DEBUG*/
3821 #ifdef MONO_PERSONALITY_DEBUG
3822 static const gboolean use_debug_personality = TRUE;
3823 static const char *default_personality_name = "mono_debug_personality";
3825 static const gboolean use_debug_personality = FALSE;
3826 static const char *default_personality_name = "__gxx_personality_v0";
3830 default_cpp_lpad_exc_signature (void)
3832 static gboolean inited = FALSE;
3833 static LLVMTypeRef sig;
3836 LLVMTypeRef signature [2];
3837 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3838 signature [1] = LLVMInt32Type ();
3839 sig = LLVMStructType (signature, 2, FALSE);
3847 get_mono_personality (EmitContext *ctx)
3849 LLVMValueRef personality = NULL;
3850 static gint32 mapping_inited = FALSE;
3851 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3853 if (!use_debug_personality) {
3854 if (ctx->cfg->compile_aot) {
3855 personality = get_intrinsic (ctx, default_personality_name);
3856 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3857 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3858 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3861 if (ctx->cfg->compile_aot) {
3862 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3864 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3865 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3866 mono_memory_barrier ();
3870 g_assert (personality);
3874 static LLVMBasicBlockRef
3875 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3877 MonoCompile *cfg = ctx->cfg;
3878 LLVMBuilderRef old_builder = ctx->builder;
3879 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3881 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3882 ctx->builder = lpadBuilder;
3884 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3885 g_assert (handler_bb);
3887 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3888 LLVMValueRef personality = get_mono_personality (ctx);
3889 g_assert (personality);
3891 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3892 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3894 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3895 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3896 g_assert (landing_pad);
3898 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3899 LLVMAddClause (landing_pad, cast);
3901 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3902 LLVMBuilderRef resume_builder = create_builder (ctx);
3903 ctx->builder = resume_builder;
3904 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3906 emit_resume_eh (ctx, handler_bb);
3909 ctx->builder = lpadBuilder;
3910 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3912 gboolean finally_only = TRUE;
3914 MonoExceptionClause *group_cursor = group_start;
3916 for (int i = 0; i < group_size; i ++) {
3917 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY || group_cursor->flags & MONO_EXCEPTION_CLAUSE_FAULT))
3918 finally_only = FALSE;
3924 // Handle landing pad inlining
3926 if (!finally_only) {
3927 // So at each level of the exception stack we will match the exception again.
3928 // During that match, we need to compare against the handler types for the current
3929 // protected region. We send the try start and end so that we can only check against
3930 // handlers for this lexical protected region.
3931 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3933 // if returns -1, resume
3934 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3936 // else move to that target bb
3937 for (int i = 0; i < group_size; i++) {
3938 MonoExceptionClause *clause = group_start + i;
3939 int clause_index = clause - cfg->header->clauses;
3940 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3941 g_assert (handler_bb);
3942 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3943 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3946 int clause_index = group_start - cfg->header->clauses;
3947 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3948 g_assert (finally_bb);
3950 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3953 ctx->builder = old_builder;
3960 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3962 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3963 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3965 // Make exception available to catch blocks
3966 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY || clause->flags & MONO_EXCEPTION_CLAUSE_FAULT)) {
3967 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3969 g_assert (ctx->ex_var);
3970 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3972 if (bb->in_scount == 1) {
3973 MonoInst *exvar = bb->in_stack [0];
3974 g_assert (!ctx->values [exvar->dreg]);
3975 g_assert (ctx->ex_var);
3976 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3977 emit_volatile_store (ctx, exvar->dreg);
3980 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3983 LLVMBuilderRef handler_builder = create_builder (ctx);
3984 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3985 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3987 // Make the handler code end with a jump to cbb
3988 LLVMBuildBr (handler_builder, cbb);
3992 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3994 MonoCompile *cfg = ctx->cfg;
3995 LLVMValueRef *values = ctx->values;
3996 LLVMModuleRef lmodule = ctx->lmodule;
3997 BBInfo *bblocks = ctx->bblocks;
3999 LLVMValueRef personality;
4000 LLVMValueRef landing_pad;
4001 LLVMBasicBlockRef target_bb;
4003 static int ti_generator;
4005 LLVMValueRef type_info;
4009 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4011 if (cfg->compile_aot) {
4012 /* Use a dummy personality function */
4013 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4014 g_assert (personality);
4016 #if LLVM_API_VERSION > 100
4017 /* Can't cache this as each method is in its own llvm module */
4018 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
4019 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
4020 mono_llvm_add_func_attr (personality, LLVM_ATTR_NO_UNWIND);
4021 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
4022 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
4023 LLVMPositionBuilderAtEnd (builder2, entry_bb);
4024 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
4025 LLVMDisposeBuilder (builder2);
4027 static gint32 mapping_inited;
4029 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4031 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
4032 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4036 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4038 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4041 * Create the type info
4043 sprintf (ti_name, "type_info_%d", ti_generator);
4046 if (cfg->compile_aot) {
4047 /* decode_eh_frame () in aot-runtime.c will decode this */
4048 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4049 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4052 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4054 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4056 #if LLVM_API_VERSION > 100
4057 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4058 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4063 * After the cfg mempool is freed, the type info will point to stale memory,
4064 * but this is not a problem, since we decode it once in exception_cb during
4067 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4068 *(gint32*)ti = clause_index;
4070 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4072 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4077 LLVMTypeRef members [2], ret_type;
4079 members [0] = i8ptr;
4080 members [1] = LLVMInt32Type ();
4081 ret_type = LLVMStructType (members, 2, FALSE);
4083 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4084 LLVMAddClause (landing_pad, type_info);
4086 /* Store the exception into the exvar */
4088 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4092 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4093 * code expects control to be transferred to this landing pad even in the
4094 * presence of nested clauses. The landing pad needs to branch to the landing
4095 * pads belonging to nested clauses based on the selector value returned by
4096 * the landing pad instruction, which is passed to the landing pad in a
4097 * register by the EH code.
4099 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4100 g_assert (target_bb);
4103 * Branch to the correct landing pad
4105 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4106 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4108 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4109 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4110 MonoBasicBlock *handler_bb;
4112 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4113 g_assert (handler_bb);
4115 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4116 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4119 /* Start a new bblock which CALL_HANDLER can branch to */
4120 ctx->builder = builder = create_builder (ctx);
4121 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4123 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4125 /* Store the exception into the IL level exvar */
4126 if (bb->in_scount == 1) {
4127 g_assert (bb->in_scount == 1);
4128 exvar = bb->in_stack [0];
4130 // FIXME: This is shared with filter clauses ?
4131 g_assert (!values [exvar->dreg]);
4133 g_assert (ctx->ex_var);
4134 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4135 emit_volatile_store (ctx, exvar->dreg);
4138 /* Make normal branches to the start of the clause branch to the new bblock */
4139 bblocks [bb->block_num].bblock = target_bb;
4143 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4145 MonoCompile *cfg = ctx->cfg;
4146 MonoMethodSignature *sig = ctx->sig;
4147 LLVMValueRef method = ctx->lmethod;
4148 LLVMValueRef *values = ctx->values;
4149 LLVMValueRef *addresses = ctx->addresses;
4150 LLVMCallInfo *linfo = ctx->linfo;
4151 BBInfo *bblocks = ctx->bblocks;
4153 LLVMBasicBlockRef cbb;
4154 LLVMBuilderRef builder, starting_builder;
4155 gboolean has_terminator;
4157 LLVMValueRef lhs, rhs;
4160 cbb = get_end_bb (ctx, bb);
4162 builder = create_builder (ctx);
4163 ctx->builder = builder;
4164 LLVMPositionBuilderAtEnd (builder, cbb);
4169 if (bb->flags & BB_EXCEPTION_HANDLER) {
4170 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4171 set_failure (ctx, "handler without invokes");
4176 emit_llvmonly_handler_start (ctx, bb, cbb);
4178 emit_handler_start (ctx, bb, builder);
4181 builder = ctx->builder;
4184 has_terminator = FALSE;
4185 starting_builder = builder;
4186 for (ins = bb->code; ins; ins = ins->next) {
4187 const char *spec = LLVM_INS_INFO (ins->opcode);
4189 char dname_buf [128];
4191 emit_dbg_loc (ctx, builder, ins->cil_code);
4196 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4197 * Start a new bblock.
4198 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4199 * from localloc-ed memory.
4201 if (!cfg->llvm_only)
4202 ;//set_failure (ctx, "basic block too long");
4204 if (!ctx->long_bb_break_var) {
4205 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4206 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4209 cbb = gen_bb (ctx, "CONT_LONG_BB");
4210 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4212 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4214 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4215 * but llvm doesn't know that, so the branch is not going to be eliminated.
4217 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4219 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4221 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4222 ctx->builder = builder = create_builder (ctx);
4223 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4224 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4225 LLVMBuildBr (builder, cbb);
4227 ctx->builder = builder = create_builder (ctx);
4228 LLVMPositionBuilderAtEnd (builder, cbb);
4229 ctx->bblocks [bb->block_num].end_bblock = cbb;
4234 /* There could be instructions after a terminator, skip them */
4237 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4238 sprintf (dname_buf, "t%d", ins->dreg);
4242 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4243 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4245 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4246 lhs = emit_volatile_load (ctx, ins->sreg1);
4248 /* It is ok for SETRET to have an uninitialized argument */
4249 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4250 set_failure (ctx, "sreg1");
4253 lhs = values [ins->sreg1];
4259 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4260 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4261 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4262 rhs = emit_volatile_load (ctx, ins->sreg2);
4264 if (!values [ins->sreg2]) {
4265 set_failure (ctx, "sreg2");
4268 rhs = values [ins->sreg2];
4274 //mono_print_ins (ins);
4275 switch (ins->opcode) {
4278 case OP_LIVERANGE_START:
4279 case OP_LIVERANGE_END:
4282 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4285 #if SIZEOF_VOID_P == 4
4286 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4288 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4292 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4296 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4298 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4300 case OP_DUMMY_ICONST:
4301 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4303 case OP_DUMMY_I8CONST:
4304 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4306 case OP_DUMMY_R8CONST:
4307 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4310 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4311 LLVMBuildBr (builder, target_bb);
4312 has_terminator = TRUE;
4319 LLVMBasicBlockRef new_bb;
4320 LLVMBuilderRef new_builder;
4322 // The default branch is already handled
4323 // FIXME: Handle it here
4325 /* Start new bblock */
4326 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4327 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4329 lhs = convert (ctx, lhs, LLVMInt32Type ());
4330 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4331 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4332 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4334 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4337 new_builder = create_builder (ctx);
4338 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4339 LLVMBuildUnreachable (new_builder);
4341 has_terminator = TRUE;
4342 g_assert (!ins->next);
4348 switch (linfo->ret.storage) {
4349 case LLVMArgVtypeInReg: {
4350 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4351 LLVMValueRef val, addr, retval;
4354 retval = LLVMGetUndef (ret_type);
4356 if (!addresses [ins->sreg1]) {
4358 * The return type is an LLVM vector type, have to convert between it and the
4359 * real return type which is a struct type.
4361 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4362 /* Convert to 2xi64 first */
4363 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4365 for (i = 0; i < 2; ++i) {
4366 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4367 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4369 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4373 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4374 for (i = 0; i < 2; ++i) {
4375 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4376 LLVMValueRef indexes [2], part_addr;
4378 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4379 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4380 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4382 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4384 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4388 LLVMBuildRet (builder, retval);
4391 case LLVMArgVtypeAsScalar: {
4392 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4393 LLVMValueRef retval;
4395 g_assert (addresses [ins->sreg1]);
4397 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4398 LLVMBuildRet (builder, retval);
4401 case LLVMArgVtypeByVal: {
4402 LLVMValueRef retval;
4404 g_assert (addresses [ins->sreg1]);
4405 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4406 LLVMBuildRet (builder, retval);
4409 case LLVMArgVtypeByRef: {
4410 LLVMBuildRetVoid (builder);
4413 case LLVMArgGsharedvtFixed: {
4414 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4415 /* The return value is in lhs, need to store to the vret argument */
4416 /* sreg1 might not be set */
4418 g_assert (cfg->vret_addr);
4419 g_assert (values [cfg->vret_addr->dreg]);
4420 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4422 LLVMBuildRetVoid (builder);
4425 case LLVMArgGsharedvtFixedVtype: {
4427 LLVMBuildRetVoid (builder);
4430 case LLVMArgGsharedvtVariable: {
4432 LLVMBuildRetVoid (builder);
4435 case LLVMArgVtypeRetAddr: {
4436 LLVMBuildRetVoid (builder);
4439 case LLVMArgAsIArgs:
4440 case LLVMArgFpStruct: {
4441 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4442 LLVMValueRef retval;
4444 g_assert (addresses [ins->sreg1]);
4445 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4446 LLVMBuildRet (builder, retval);
4450 case LLVMArgNormal: {
4451 if (!lhs || ctx->is_dead [ins->sreg1]) {
4453 * The method did not set its return value, probably because it
4454 * ends with a throw.
4457 LLVMBuildRetVoid (builder);
4459 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4461 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4463 has_terminator = TRUE;
4467 g_assert_not_reached ();
4476 case OP_ICOMPARE_IMM:
4477 case OP_LCOMPARE_IMM:
4478 case OP_COMPARE_IMM: {
4480 LLVMValueRef cmp, args [16];
4481 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4483 if (ins->next->opcode == OP_NOP)
4486 if (ins->next->opcode == OP_BR)
4487 /* The comparison result is not needed */
4490 rel = mono_opcode_to_cond (ins->next->opcode);
4492 if (ins->opcode == OP_ICOMPARE_IMM) {
4493 lhs = convert (ctx, lhs, LLVMInt32Type ());
4494 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4496 if (ins->opcode == OP_LCOMPARE_IMM) {
4497 lhs = convert (ctx, lhs, LLVMInt64Type ());
4498 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4500 if (ins->opcode == OP_LCOMPARE) {
4501 lhs = convert (ctx, lhs, LLVMInt64Type ());
4502 rhs = convert (ctx, rhs, LLVMInt64Type ());
4504 if (ins->opcode == OP_ICOMPARE) {
4505 lhs = convert (ctx, lhs, LLVMInt32Type ());
4506 rhs = convert (ctx, rhs, LLVMInt32Type ());
4510 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4511 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4512 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4513 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4516 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4517 if (ins->opcode == OP_FCOMPARE) {
4518 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4519 } else if (ins->opcode == OP_RCOMPARE) {
4520 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4521 } else if (ins->opcode == OP_COMPARE_IMM) {
4522 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4523 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4525 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4526 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4527 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4528 /* The immediate is encoded in two fields */
4529 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4530 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4532 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4535 else if (ins->opcode == OP_COMPARE) {
4536 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4537 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4539 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4541 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4545 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4546 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4549 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4550 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4552 * If the target bb contains PHI instructions, LLVM requires
4553 * two PHI entries for this bblock, while we only generate one.
4554 * So convert this to an unconditional bblock. (bxc #171).
4556 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4558 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4560 has_terminator = TRUE;
4561 } else if (MONO_IS_SETCC (ins->next)) {
4562 sprintf (dname_buf, "t%d", ins->next->dreg);
4564 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4566 /* Add stores for volatile variables */
4567 emit_volatile_store (ctx, ins->next->dreg);
4568 } else if (MONO_IS_COND_EXC (ins->next)) {
4569 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4572 builder = ctx->builder;
4574 set_failure (ctx, "next");
4592 rel = mono_opcode_to_cond (ins->opcode);
4594 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4595 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4606 rel = mono_opcode_to_cond (ins->opcode);
4608 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4609 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4617 gboolean empty = TRUE;
4619 /* Check that all input bblocks really branch to us */
4620 for (i = 0; i < bb->in_count; ++i) {
4621 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4622 ins->inst_phi_args [i + 1] = -1;
4628 /* LLVM doesn't like phi instructions with zero operands */
4629 ctx->is_dead [ins->dreg] = TRUE;
4633 /* Created earlier, insert it now */
4634 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4636 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4637 int sreg1 = ins->inst_phi_args [i + 1];
4641 * Count the number of times the incoming bblock branches to us,
4642 * since llvm requires a separate entry for each.
4644 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4645 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4648 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4649 if (switch_ins->inst_many_bb [j] == bb)
4656 /* Remember for later */
4657 for (j = 0; j < count; ++j) {
4658 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4661 node->in_bb = bb->in_bb [i];
4663 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);
4673 values [ins->dreg] = lhs;
4677 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4680 values [ins->dreg] = lhs;
4682 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4684 * This is added by the spilling pass in case of the JIT,
4685 * but we have to do it ourselves.
4687 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4691 case OP_MOVE_F_TO_I4: {
4692 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4695 case OP_MOVE_I4_TO_F: {
4696 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4699 case OP_MOVE_F_TO_I8: {
4700 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4703 case OP_MOVE_I8_TO_F: {
4704 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4737 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4738 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4740 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4743 builder = ctx->builder;
4745 switch (ins->opcode) {
4748 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4752 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4756 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4760 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4764 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4768 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4772 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4776 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4780 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4784 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4788 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4792 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4796 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4800 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4804 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4807 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4810 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4814 g_assert_not_reached ();
4821 lhs = convert (ctx, lhs, LLVMFloatType ());
4822 rhs = convert (ctx, rhs, LLVMFloatType ());
4823 switch (ins->opcode) {
4825 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4828 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4831 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4834 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4837 g_assert_not_reached ();
4846 case OP_IREM_UN_IMM:
4848 case OP_IDIV_UN_IMM:
4854 case OP_ISHR_UN_IMM:
4864 case OP_LSHR_UN_IMM:
4870 case OP_SHR_UN_IMM: {
4873 if (spec [MONO_INST_SRC1] == 'l') {
4874 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4876 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4879 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4882 builder = ctx->builder;
4884 #if SIZEOF_VOID_P == 4
4885 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4886 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4889 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4890 lhs = convert (ctx, lhs, IntPtrType ());
4891 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4892 switch (ins->opcode) {
4896 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4900 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4905 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4909 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4911 case OP_IDIV_UN_IMM:
4912 case OP_LDIV_UN_IMM:
4913 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4917 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4919 case OP_IREM_UN_IMM:
4920 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4925 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4929 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4933 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4938 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4943 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4945 case OP_ISHR_UN_IMM:
4946 /* This is used to implement conv.u4, so the lhs could be an i8 */
4947 lhs = convert (ctx, lhs, LLVMInt32Type ());
4948 imm = convert (ctx, imm, LLVMInt32Type ());
4949 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4951 case OP_LSHR_UN_IMM:
4953 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4956 g_assert_not_reached ();
4961 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4964 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4967 lhs = convert (ctx, lhs, LLVMDoubleType ());
4968 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4971 lhs = convert (ctx, lhs, LLVMFloatType ());
4972 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4975 guint32 v = 0xffffffff;
4976 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4980 guint64 v = 0xffffffffffffffffLL;
4981 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4984 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4986 LLVMValueRef v1, v2;
4988 rhs = LLVMBuildSExt (builder, convert (ctx, rhs, LLVMInt32Type ()), LLVMInt64Type (), "");
4990 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4991 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4992 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4997 case OP_ICONV_TO_I1:
4998 case OP_ICONV_TO_I2:
4999 case OP_ICONV_TO_I4:
5000 case OP_ICONV_TO_U1:
5001 case OP_ICONV_TO_U2:
5002 case OP_ICONV_TO_U4:
5003 case OP_LCONV_TO_I1:
5004 case OP_LCONV_TO_I2:
5005 case OP_LCONV_TO_U1:
5006 case OP_LCONV_TO_U2:
5007 case OP_LCONV_TO_U4: {
5010 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);
5012 /* Have to do two casts since our vregs have type int */
5013 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
5015 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
5017 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
5020 case OP_ICONV_TO_I8:
5021 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
5023 case OP_ICONV_TO_U8:
5024 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
5026 case OP_FCONV_TO_I4:
5027 case OP_RCONV_TO_I4:
5028 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
5030 case OP_FCONV_TO_I1:
5031 case OP_RCONV_TO_I1:
5032 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
5034 case OP_FCONV_TO_U1:
5035 case OP_RCONV_TO_U1:
5036 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5038 case OP_FCONV_TO_I2:
5039 case OP_RCONV_TO_I2:
5040 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5042 case OP_FCONV_TO_U2:
5043 case OP_RCONV_TO_U2:
5044 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5046 case OP_RCONV_TO_U4:
5047 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5049 case OP_FCONV_TO_I8:
5050 case OP_RCONV_TO_I8:
5051 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5054 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5056 case OP_ICONV_TO_R8:
5057 case OP_LCONV_TO_R8:
5058 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5060 case OP_ICONV_TO_R_UN:
5061 case OP_LCONV_TO_R_UN:
5062 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5064 #if SIZEOF_VOID_P == 4
5067 case OP_LCONV_TO_I4:
5068 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5070 case OP_ICONV_TO_R4:
5071 case OP_LCONV_TO_R4:
5072 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5074 values [ins->dreg] = v;
5076 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5078 case OP_FCONV_TO_R4:
5079 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5081 values [ins->dreg] = v;
5083 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5085 case OP_RCONV_TO_R8:
5086 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5088 case OP_RCONV_TO_R4:
5089 values [ins->dreg] = lhs;
5092 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5095 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5098 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5100 case OP_LOCALLOC_IMM: {
5103 guint32 size = ins->inst_imm;
5104 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5106 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5108 if (ins->flags & MONO_INST_INIT) {
5109 LLVMValueRef args [5];
5112 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5113 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5114 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5115 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5116 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5119 values [ins->dreg] = v;
5123 LLVMValueRef v, size;
5125 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), "");
5127 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5129 if (ins->flags & MONO_INST_INIT) {
5130 LLVMValueRef args [5];
5133 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5135 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5136 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5137 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5139 values [ins->dreg] = v;
5143 case OP_LOADI1_MEMBASE:
5144 case OP_LOADU1_MEMBASE:
5145 case OP_LOADI2_MEMBASE:
5146 case OP_LOADU2_MEMBASE:
5147 case OP_LOADI4_MEMBASE:
5148 case OP_LOADU4_MEMBASE:
5149 case OP_LOADI8_MEMBASE:
5150 case OP_LOADR4_MEMBASE:
5151 case OP_LOADR8_MEMBASE:
5152 case OP_LOAD_MEMBASE:
5160 LLVMValueRef base, index, addr;
5162 gboolean sext = FALSE, zext = FALSE;
5163 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5165 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5170 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)) {
5171 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5177 if (ins->inst_offset == 0) {
5179 } else if (ins->inst_offset % size != 0) {
5180 /* Unaligned load */
5181 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5182 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5184 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5185 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5189 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5191 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5193 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5195 * These will signal LLVM that these loads do not alias any stores, and
5196 * they can't fail, allowing them to be hoisted out of loops.
5198 set_invariant_load_flag (values [ins->dreg]);
5199 #if LLVM_API_VERSION < 100
5200 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5205 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5207 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5208 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5209 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5213 case OP_STOREI1_MEMBASE_REG:
5214 case OP_STOREI2_MEMBASE_REG:
5215 case OP_STOREI4_MEMBASE_REG:
5216 case OP_STOREI8_MEMBASE_REG:
5217 case OP_STORER4_MEMBASE_REG:
5218 case OP_STORER8_MEMBASE_REG:
5219 case OP_STORE_MEMBASE_REG: {
5221 LLVMValueRef index, addr, base;
5223 gboolean sext = FALSE, zext = FALSE;
5224 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5226 if (!values [ins->inst_destbasereg]) {
5227 set_failure (ctx, "inst_destbasereg");
5231 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5233 base = values [ins->inst_destbasereg];
5234 if (ins->inst_offset % size != 0) {
5235 /* Unaligned store */
5236 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5237 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5239 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5240 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5242 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5246 case OP_STOREI1_MEMBASE_IMM:
5247 case OP_STOREI2_MEMBASE_IMM:
5248 case OP_STOREI4_MEMBASE_IMM:
5249 case OP_STOREI8_MEMBASE_IMM:
5250 case OP_STORE_MEMBASE_IMM: {
5252 LLVMValueRef index, addr, base;
5254 gboolean sext = FALSE, zext = FALSE;
5255 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5257 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5259 base = values [ins->inst_destbasereg];
5260 if (ins->inst_offset % size != 0) {
5261 /* Unaligned store */
5262 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5263 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5265 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5266 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5268 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5273 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5275 case OP_OUTARG_VTRETADDR:
5283 case OP_VOIDCALL_MEMBASE:
5284 case OP_CALL_MEMBASE:
5285 case OP_LCALL_MEMBASE:
5286 case OP_FCALL_MEMBASE:
5287 case OP_RCALL_MEMBASE:
5288 case OP_VCALL_MEMBASE:
5289 case OP_VOIDCALL_REG:
5294 case OP_VCALL_REG: {
5295 process_call (ctx, bb, &builder, ins);
5300 LLVMValueRef indexes [2];
5301 MonoJumpInfo *tmp_ji, *ji;
5302 LLVMValueRef got_entry_addr;
5306 * FIXME: Can't allocate from the cfg mempool since that is freed if
5307 * the LLVM compile fails.
5309 tmp_ji = g_new0 (MonoJumpInfo, 1);
5310 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5311 tmp_ji->data.target = ins->inst_p0;
5313 ji = mono_aot_patch_info_dup (tmp_ji);
5316 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5317 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5320 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5321 * resolvable at runtime using dlsym ().
5324 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5329 ji->next = cfg->patch_info;
5330 cfg->patch_info = ji;
5332 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5333 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5334 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5335 if (!mono_aot_is_shared_got_offset (got_offset)) {
5336 //mono_print_ji (ji);
5338 ctx->has_got_access = TRUE;
5341 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5342 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5343 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5345 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5346 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5348 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5349 if (!cfg->llvm_only)
5350 set_invariant_load_flag (values [ins->dreg]);
5353 case OP_NOT_REACHED:
5354 LLVMBuildUnreachable (builder);
5355 has_terminator = TRUE;
5356 g_assert (bb->block_num < cfg->max_block_num);
5357 ctx->unreachable [bb->block_num] = TRUE;
5358 /* Might have instructions after this */
5360 MonoInst *next = ins->next;
5362 * FIXME: If later code uses the regs defined by these instructions,
5363 * compilation will fail.
5365 MONO_DELETE_INS (bb, next);
5369 MonoInst *var = ins->inst_i0;
5371 if (var->opcode == OP_VTARG_ADDR) {
5372 /* The variable contains the vtype address */
5373 values [ins->dreg] = values [var->dreg];
5374 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5375 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5377 values [ins->dreg] = addresses [var->dreg];
5382 LLVMValueRef args [1];
5384 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5385 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5389 LLVMValueRef args [1];
5391 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5392 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5396 LLVMValueRef args [1];
5398 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5399 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5403 LLVMValueRef args [1];
5405 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5406 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5420 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5421 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5423 switch (ins->opcode) {
5426 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5430 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5434 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5438 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5441 g_assert_not_reached ();
5444 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5449 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5450 * hack is necessary (for now).
5453 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5455 #define ARM64_ATOMIC_FENCE_FIX
5458 case OP_ATOMIC_EXCHANGE_I4:
5459 case OP_ATOMIC_EXCHANGE_I8: {
5460 LLVMValueRef args [2];
5463 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5464 t = LLVMInt32Type ();
5466 t = LLVMInt64Type ();
5468 g_assert (ins->inst_offset == 0);
5470 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5471 args [1] = convert (ctx, rhs, t);
5473 ARM64_ATOMIC_FENCE_FIX;
5474 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5475 ARM64_ATOMIC_FENCE_FIX;
5478 case OP_ATOMIC_ADD_I4:
5479 case OP_ATOMIC_ADD_I8: {
5480 LLVMValueRef args [2];
5483 if (ins->opcode == OP_ATOMIC_ADD_I4)
5484 t = LLVMInt32Type ();
5486 t = LLVMInt64Type ();
5488 g_assert (ins->inst_offset == 0);
5490 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5491 args [1] = convert (ctx, rhs, t);
5492 ARM64_ATOMIC_FENCE_FIX;
5493 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5494 ARM64_ATOMIC_FENCE_FIX;
5497 case OP_ATOMIC_CAS_I4:
5498 case OP_ATOMIC_CAS_I8: {
5499 LLVMValueRef args [3], val;
5502 if (ins->opcode == OP_ATOMIC_CAS_I4)
5503 t = LLVMInt32Type ();
5505 t = LLVMInt64Type ();
5507 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5509 args [1] = convert (ctx, values [ins->sreg3], t);
5511 args [2] = convert (ctx, values [ins->sreg2], t);
5512 ARM64_ATOMIC_FENCE_FIX;
5513 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5514 ARM64_ATOMIC_FENCE_FIX;
5515 /* cmpxchg returns a pair */
5516 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5519 case OP_MEMORY_BARRIER: {
5520 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5523 case OP_ATOMIC_LOAD_I1:
5524 case OP_ATOMIC_LOAD_I2:
5525 case OP_ATOMIC_LOAD_I4:
5526 case OP_ATOMIC_LOAD_I8:
5527 case OP_ATOMIC_LOAD_U1:
5528 case OP_ATOMIC_LOAD_U2:
5529 case OP_ATOMIC_LOAD_U4:
5530 case OP_ATOMIC_LOAD_U8:
5531 case OP_ATOMIC_LOAD_R4:
5532 case OP_ATOMIC_LOAD_R8: {
5533 #if LLVM_API_VERSION > 100
5535 gboolean sext, zext;
5537 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5538 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5539 LLVMValueRef index, addr;
5541 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5546 if (ins->inst_offset != 0) {
5547 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5548 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5553 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5555 ARM64_ATOMIC_FENCE_FIX;
5556 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5557 ARM64_ATOMIC_FENCE_FIX;
5560 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5562 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5565 set_failure (ctx, "atomic mono.load intrinsic");
5569 case OP_ATOMIC_STORE_I1:
5570 case OP_ATOMIC_STORE_I2:
5571 case OP_ATOMIC_STORE_I4:
5572 case OP_ATOMIC_STORE_I8:
5573 case OP_ATOMIC_STORE_U1:
5574 case OP_ATOMIC_STORE_U2:
5575 case OP_ATOMIC_STORE_U4:
5576 case OP_ATOMIC_STORE_U8:
5577 case OP_ATOMIC_STORE_R4:
5578 case OP_ATOMIC_STORE_R8: {
5580 gboolean sext, zext;
5582 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5583 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5584 LLVMValueRef index, addr, value, base;
5586 #if LLVM_API_VERSION < 100
5587 if (!cfg->llvm_only) {
5588 set_failure (ctx, "atomic mono.store intrinsic");
5593 if (!values [ins->inst_destbasereg]) {
5594 set_failure (ctx, "inst_destbasereg");
5598 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5600 base = values [ins->inst_destbasereg];
5601 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5602 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5603 value = convert (ctx, values [ins->sreg1], t);
5605 ARM64_ATOMIC_FENCE_FIX;
5606 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5607 ARM64_ATOMIC_FENCE_FIX;
5610 case OP_RELAXED_NOP: {
5611 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5612 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5619 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5621 // 257 == FS segment register
5622 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5624 // 256 == GS segment register
5625 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5628 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5629 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5630 /* See mono_amd64_emit_tls_get () */
5631 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5633 // 256 == GS segment register
5634 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5635 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5637 set_failure (ctx, "opcode tls-get");
5643 case OP_GC_SAFE_POINT: {
5644 LLVMValueRef val, cmp, callee;
5645 LLVMBasicBlockRef poll_bb, cont_bb;
5646 static LLVMTypeRef sig;
5647 const char *icall_name = "mono_threads_state_poll";
5650 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5654 * mono_threads_state_poll ();
5655 * FIXME: Use a preserveall wrapper
5657 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5658 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5659 poll_bb = gen_bb (ctx, "POLL_BB");
5660 cont_bb = gen_bb (ctx, "CONT_BB");
5661 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5663 ctx->builder = builder = create_builder (ctx);
5664 LLVMPositionBuilderAtEnd (builder, poll_bb);
5666 if (ctx->cfg->compile_aot) {
5667 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5669 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5670 callee = emit_jit_callee (ctx, icall_name, sig, target);
5672 LLVMBuildCall (builder, callee, NULL, 0, "");
5673 LLVMBuildBr (builder, cont_bb);
5675 ctx->builder = builder = create_builder (ctx);
5676 LLVMPositionBuilderAtEnd (builder, cont_bb);
5677 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5685 case OP_IADD_OVF_UN:
5687 case OP_ISUB_OVF_UN:
5689 case OP_IMUL_OVF_UN:
5691 case OP_LADD_OVF_UN:
5693 case OP_LSUB_OVF_UN:
5695 case OP_LMUL_OVF_UN:
5697 LLVMValueRef args [2], val, ovf, func;
5699 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5700 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5701 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5703 val = LLVMBuildCall (builder, func, args, 2, "");
5704 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5705 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5706 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5709 builder = ctx->builder;
5715 * We currently model them using arrays. Promotion to local vregs is
5716 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5717 * so we always have an entry in cfg->varinfo for them.
5718 * FIXME: Is this needed ?
5721 MonoClass *klass = ins->klass;
5722 LLVMValueRef args [5];
5726 set_failure (ctx, "!klass");
5730 if (!addresses [ins->dreg])
5731 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5732 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5733 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5734 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5736 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5737 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5738 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5741 case OP_DUMMY_VZERO:
5744 case OP_STOREV_MEMBASE:
5745 case OP_LOADV_MEMBASE:
5747 MonoClass *klass = ins->klass;
5748 LLVMValueRef src = NULL, dst, args [5];
5749 gboolean done = FALSE;
5753 set_failure (ctx, "!klass");
5757 if (mini_is_gsharedvt_klass (klass)) {
5759 set_failure (ctx, "gsharedvt");
5763 switch (ins->opcode) {
5764 case OP_STOREV_MEMBASE:
5765 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5766 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5767 /* Decomposed earlier */
5768 g_assert_not_reached ();
5771 if (!addresses [ins->sreg1]) {
5773 g_assert (values [ins->sreg1]);
5774 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));
5775 LLVMBuildStore (builder, values [ins->sreg1], dst);
5778 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5779 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5782 case OP_LOADV_MEMBASE:
5783 if (!addresses [ins->dreg])
5784 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5785 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5786 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5789 if (!addresses [ins->sreg1])
5790 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5791 if (!addresses [ins->dreg])
5792 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5793 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5794 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5797 g_assert_not_reached ();
5807 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5808 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5810 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5811 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5812 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5815 case OP_LLVM_OUTARG_VT: {
5816 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5817 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5819 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5820 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5822 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5823 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5825 g_assert (addresses [ins->sreg1]);
5826 addresses [ins->dreg] = addresses [ins->sreg1];
5828 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5829 if (!addresses [ins->sreg1]) {
5830 addresses [ins->sreg1] = build_alloca (ctx, t);
5831 g_assert (values [ins->sreg1]);
5833 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5834 addresses [ins->dreg] = addresses [ins->sreg1];
5836 if (!addresses [ins->sreg1]) {
5837 addresses [ins->sreg1] = build_alloca (ctx, t);
5838 g_assert (values [ins->sreg1]);
5839 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5841 addresses [ins->dreg] = addresses [ins->sreg1];
5845 case OP_OBJC_GET_SELECTOR: {
5846 const char *name = (const char*)ins->inst_p0;
5849 if (!ctx->module->objc_selector_to_var) {
5850 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5852 LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
5853 int32_t objc_imageinfo [] = { 0, 16 };
5854 LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
5855 LLVMSetLinkage (info_var, LLVMPrivateLinkage);
5856 LLVMSetExternallyInitialized (info_var, TRUE);
5857 LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
5858 LLVMSetAlignment (info_var, sizeof (mgreg_t));
5859 mark_as_used (ctx->module, info_var);
5862 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5864 LLVMValueRef indexes [16];
5866 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5867 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5868 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5869 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5870 mark_as_used (ctx->module, name_var);
5872 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5874 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5875 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5876 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5877 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5878 LLVMSetExternallyInitialized (ref_var, TRUE);
5879 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5880 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5881 mark_as_used (ctx->module, ref_var);
5883 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5887 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5894 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5896 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5899 case OP_LOADX_MEMBASE: {
5900 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5903 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5904 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5907 case OP_STOREX_MEMBASE: {
5908 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5911 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5912 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5919 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5923 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5929 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5933 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5937 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5941 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5944 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5947 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5950 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5954 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5965 LLVMValueRef v = NULL;
5967 switch (ins->opcode) {
5972 t = LLVMVectorType (LLVMInt32Type (), 4);
5973 rt = LLVMVectorType (LLVMFloatType (), 4);
5979 t = LLVMVectorType (LLVMInt64Type (), 2);
5980 rt = LLVMVectorType (LLVMDoubleType (), 2);
5983 t = LLVMInt32Type ();
5984 rt = LLVMInt32Type ();
5985 g_assert_not_reached ();
5988 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5989 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5990 switch (ins->opcode) {
5993 v = LLVMBuildAnd (builder, lhs, rhs, "");
5997 v = LLVMBuildOr (builder, lhs, rhs, "");
6001 v = LLVMBuildXor (builder, lhs, rhs, "");
6005 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
6008 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
6014 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
6015 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6021 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6022 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6026 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6027 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6044 case OP_PADDB_SAT_UN:
6045 case OP_PADDW_SAT_UN:
6046 case OP_PSUBB_SAT_UN:
6047 case OP_PSUBW_SAT_UN:
6055 case OP_PMULW_HIGH_UN: {
6056 LLVMValueRef args [2];
6061 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6068 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6072 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6080 case OP_EXTRACTX_U2:
6082 case OP_EXTRACT_U1: {
6084 gboolean zext = FALSE;
6086 t = simd_op_to_llvm_type (ins->opcode);
6088 switch (ins->opcode) {
6096 case OP_EXTRACTX_U2:
6101 t = LLVMInt32Type ();
6102 g_assert_not_reached ();
6105 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6106 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6108 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6117 case OP_EXPAND_R8: {
6118 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6119 LLVMValueRef mask [16], v;
6122 for (i = 0; i < 16; ++i)
6123 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6125 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6127 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6128 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6133 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6136 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6139 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6142 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6145 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6148 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6151 #if LLVM_API_VERSION > 100
6153 LLVMValueRef indexes [16];
6155 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6156 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6157 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6158 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6159 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6163 LLVMValueRef indexes [16];
6165 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6166 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6167 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6168 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6169 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6173 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6177 #if LLVM_API_VERSION <= 100
6187 case OP_EXTRACT_MASK:
6194 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6196 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6201 LLVMRealPredicate op;
6203 switch (ins->inst_c0) {
6213 case SIMD_COMP_UNORD:
6229 g_assert_not_reached ();
6232 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6233 if (ins->opcode == OP_COMPPD)
6234 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6236 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6240 /* This is only used for implementing shifts by non-immediate */
6241 values [ins->dreg] = lhs;
6252 LLVMValueRef args [3];
6255 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6257 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6268 case OP_PSHLQ_REG: {
6269 LLVMValueRef args [3];
6272 args [1] = values [ins->sreg2];
6274 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6281 case OP_PSHUFLEW_LOW:
6282 case OP_PSHUFLEW_HIGH: {
6284 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6285 int i, mask_size = 0;
6286 int imask = ins->inst_c0;
6288 /* Convert the x86 shuffle mask to LLVM's */
6289 switch (ins->opcode) {
6292 mask [0] = ((imask >> 0) & 3);
6293 mask [1] = ((imask >> 2) & 3);
6294 mask [2] = ((imask >> 4) & 3) + 4;
6295 mask [3] = ((imask >> 6) & 3) + 4;
6296 v1 = values [ins->sreg1];
6297 v2 = values [ins->sreg2];
6301 mask [0] = ((imask >> 0) & 1);
6302 mask [1] = ((imask >> 1) & 1) + 2;
6303 v1 = values [ins->sreg1];
6304 v2 = values [ins->sreg2];
6306 case OP_PSHUFLEW_LOW:
6308 mask [0] = ((imask >> 0) & 3);
6309 mask [1] = ((imask >> 2) & 3);
6310 mask [2] = ((imask >> 4) & 3);
6311 mask [3] = ((imask >> 6) & 3);
6316 v1 = values [ins->sreg1];
6317 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6319 case OP_PSHUFLEW_HIGH:
6325 mask [4] = 4 + ((imask >> 0) & 3);
6326 mask [5] = 4 + ((imask >> 2) & 3);
6327 mask [6] = 4 + ((imask >> 4) & 3);
6328 mask [7] = 4 + ((imask >> 6) & 3);
6329 v1 = values [ins->sreg1];
6330 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6334 mask [0] = ((imask >> 0) & 3);
6335 mask [1] = ((imask >> 2) & 3);
6336 mask [2] = ((imask >> 4) & 3);
6337 mask [3] = ((imask >> 6) & 3);
6338 v1 = values [ins->sreg1];
6339 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6342 g_assert_not_reached ();
6344 for (i = 0; i < mask_size; ++i)
6345 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6347 values [ins->dreg] =
6348 LLVMBuildShuffleVector (builder, v1, v2,
6349 LLVMConstVector (mask_values, mask_size), dname);
6353 case OP_UNPACK_LOWB:
6354 case OP_UNPACK_LOWW:
6355 case OP_UNPACK_LOWD:
6356 case OP_UNPACK_LOWQ:
6357 case OP_UNPACK_LOWPS:
6358 case OP_UNPACK_LOWPD:
6359 case OP_UNPACK_HIGHB:
6360 case OP_UNPACK_HIGHW:
6361 case OP_UNPACK_HIGHD:
6362 case OP_UNPACK_HIGHQ:
6363 case OP_UNPACK_HIGHPS:
6364 case OP_UNPACK_HIGHPD: {
6366 LLVMValueRef mask_values [16];
6367 int i, mask_size = 0;
6368 gboolean low = FALSE;
6370 switch (ins->opcode) {
6371 case OP_UNPACK_LOWB:
6375 case OP_UNPACK_LOWW:
6379 case OP_UNPACK_LOWD:
6380 case OP_UNPACK_LOWPS:
6384 case OP_UNPACK_LOWQ:
6385 case OP_UNPACK_LOWPD:
6389 case OP_UNPACK_HIGHB:
6392 case OP_UNPACK_HIGHW:
6395 case OP_UNPACK_HIGHD:
6396 case OP_UNPACK_HIGHPS:
6399 case OP_UNPACK_HIGHQ:
6400 case OP_UNPACK_HIGHPD:
6404 g_assert_not_reached ();
6408 for (i = 0; i < (mask_size / 2); ++i) {
6410 mask [(i * 2) + 1] = mask_size + i;
6413 for (i = 0; i < (mask_size / 2); ++i) {
6414 mask [(i * 2)] = (mask_size / 2) + i;
6415 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6419 for (i = 0; i < mask_size; ++i)
6420 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6422 values [ins->dreg] =
6423 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6424 LLVMConstVector (mask_values, mask_size), dname);
6429 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6430 LLVMValueRef v, val;
6432 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6433 val = LLVMConstNull (t);
6434 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6435 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6437 values [ins->dreg] = val;
6441 case OP_DUPPS_HIGH: {
6442 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6443 LLVMValueRef v1, v2, val;
6446 if (ins->opcode == OP_DUPPS_LOW) {
6447 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6448 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6450 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6451 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6453 val = LLVMConstNull (t);
6454 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6455 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6456 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6457 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6459 values [ins->dreg] = val;
6464 LLVMValueRef args [3];
6468 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6469 #if LLVM_API_VERSION >= 500
6470 args [2] = LLVMConstInt (LLVMInt8Type (), 0xf1, FALSE);
6472 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6475 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6485 * EXCEPTION HANDLING
6487 case OP_IMPLICIT_EXCEPTION:
6488 /* This marks a place where an implicit exception can happen */
6489 if (bb->region != -1)
6490 set_failure (ctx, "implicit-exception");
6494 gboolean rethrow = (ins->opcode == OP_RETHROW);
6495 if (ctx->llvm_only) {
6496 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6497 has_terminator = TRUE;
6498 ctx->unreachable [bb->block_num] = TRUE;
6500 emit_throw (ctx, bb, rethrow, lhs);
6501 builder = ctx->builder;
6505 case OP_CALL_HANDLER: {
6507 * We don't 'call' handlers, but instead simply branch to them.
6508 * The code generated by ENDFINALLY will branch back to us.
6510 LLVMBasicBlockRef noex_bb;
6512 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6514 bb_list = info->call_handler_return_bbs;
6517 * Set the indicator variable for the finally clause.
6519 lhs = info->finally_ind;
6521 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6523 /* Branch to the finally clause */
6524 LLVMBuildBr (builder, info->call_handler_target_bb);
6526 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6527 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6529 builder = ctx->builder = create_builder (ctx);
6530 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6532 bblocks [bb->block_num].end_bblock = noex_bb;
6535 case OP_START_HANDLER: {
6538 case OP_ENDFINALLY: {
6539 LLVMBasicBlockRef resume_bb;
6540 MonoBasicBlock *handler_bb;
6541 LLVMValueRef val, switch_ins, callee;
6544 gboolean is_fault = MONO_REGION_FLAGS (bb->region) == MONO_EXCEPTION_CLAUSE_FAULT;
6547 * Fault clauses are like finally clauses, but they are only called if an exception is thrown.
6550 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6551 g_assert (handler_bb);
6552 info = &bblocks [handler_bb->block_num];
6553 lhs = info->finally_ind;
6556 bb_list = info->call_handler_return_bbs;
6558 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6560 /* Load the finally variable */
6561 val = LLVMBuildLoad (builder, lhs, "");
6563 /* Reset the variable */
6564 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6566 /* Branch to either resume_bb, or to the bblocks in bb_list */
6567 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6569 * The other targets are added at the end to handle OP_CALL_HANDLER
6570 * opcodes processed later.
6572 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6574 builder = ctx->builder = create_builder (ctx);
6575 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6578 if (ctx->llvm_only) {
6579 emit_resume_eh (ctx, bb);
6581 if (ctx->cfg->compile_aot) {
6582 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6584 #if LLVM_API_VERSION > 100
6585 MonoJitICallInfo *info;
6587 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6589 gpointer target = (void*)info->func;
6590 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6591 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6593 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6596 LLVMBuildCall (builder, callee, NULL, 0, "");
6597 LLVMBuildUnreachable (builder);
6600 has_terminator = TRUE;
6603 case OP_IL_SEQ_POINT:
6608 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6609 set_failure (ctx, reason);
6617 /* Convert the value to the type required by phi nodes */
6618 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6619 if (ctx->is_vphi [ins->dreg])
6621 values [ins->dreg] = addresses [ins->dreg];
6623 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6626 /* Add stores for volatile variables */
6627 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6628 emit_volatile_store (ctx, ins->dreg);
6634 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6635 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6638 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6639 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6640 LLVMBuildRetVoid (builder);
6643 if (bb == cfg->bb_entry)
6644 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6648 * mono_llvm_check_method_supported:
6650 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6651 * compiling a method twice.
6654 mono_llvm_check_method_supported (MonoCompile *cfg)
6661 if (cfg->method->save_lmf) {
6662 cfg->exception_message = g_strdup ("lmf");
6663 cfg->disable_llvm = TRUE;
6665 if (cfg->disable_llvm)
6669 * Nested clauses where one of the clauses is a finally clause is
6670 * not supported, because LLVM can't figure out the control flow,
6671 * probably because we resume exception handling by calling our
6672 * own function instead of using the 'resume' llvm instruction.
6674 for (i = 0; i < cfg->header->num_clauses; ++i) {
6675 for (j = 0; j < cfg->header->num_clauses; ++j) {
6676 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6677 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6679 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6680 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6681 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6682 cfg->exception_message = g_strdup ("nested clauses");
6683 cfg->disable_llvm = TRUE;
6688 if (cfg->disable_llvm)
6692 if (cfg->method->dynamic) {
6693 cfg->exception_message = g_strdup ("dynamic.");
6694 cfg->disable_llvm = TRUE;
6696 if (cfg->disable_llvm)
6700 static LLVMCallInfo*
6701 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6703 LLVMCallInfo *linfo;
6706 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6710 * Gsharedvt methods have the following calling convention:
6711 * - all arguments are passed by ref, even non generic ones
6712 * - the return value is returned by ref too, using a vret
6713 * argument passed after 'this'.
6715 n = sig->param_count + sig->hasthis;
6716 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6720 linfo->args [pindex ++].storage = LLVMArgNormal;
6722 if (sig->ret->type != MONO_TYPE_VOID) {
6723 if (mini_is_gsharedvt_variable_type (sig->ret))
6724 linfo->ret.storage = LLVMArgGsharedvtVariable;
6725 else if (mini_type_is_vtype (sig->ret))
6726 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6728 linfo->ret.storage = LLVMArgGsharedvtFixed;
6729 linfo->vret_arg_index = pindex;
6731 linfo->ret.storage = LLVMArgNone;
6734 for (i = 0; i < sig->param_count; ++i) {
6735 if (sig->params [i]->byref)
6736 linfo->args [pindex].storage = LLVMArgNormal;
6737 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6738 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6739 else if (mini_type_is_vtype (sig->params [i]))
6740 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6742 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6743 linfo->args [pindex].type = sig->params [i];
6750 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6751 for (i = 0; i < sig->param_count; ++i)
6752 linfo->args [i + sig->hasthis].type = sig->params [i];
6758 emit_method_inner (EmitContext *ctx);
6761 free_ctx (EmitContext *ctx)
6765 g_free (ctx->values);
6766 g_free (ctx->addresses);
6767 g_free (ctx->vreg_types);
6768 g_free (ctx->is_vphi);
6769 g_free (ctx->vreg_cli_types);
6770 g_free (ctx->is_dead);
6771 g_free (ctx->unreachable);
6772 g_ptr_array_free (ctx->phi_values, TRUE);
6773 g_free (ctx->bblocks);
6774 g_hash_table_destroy (ctx->region_to_handler);
6775 g_hash_table_destroy (ctx->clause_to_handler);
6776 g_hash_table_destroy (ctx->jit_callees);
6778 GHashTableIter iter;
6779 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6780 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6783 g_hash_table_destroy (ctx->method_to_callers);
6785 g_free (ctx->method_name);
6786 g_ptr_array_free (ctx->bblock_list, TRUE);
6788 for (l = ctx->builders; l; l = l->next) {
6789 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6790 LLVMDisposeBuilder (builder);
6797 * mono_llvm_emit_method:
6799 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6802 mono_llvm_emit_method (MonoCompile *cfg)
6806 gboolean is_linkonce = FALSE;
6809 /* The code below might acquire the loader lock, so use it for global locking */
6810 mono_loader_lock ();
6812 /* Used to communicate with the callbacks */
6813 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6815 ctx = g_new0 (EmitContext, 1);
6817 ctx->mempool = cfg->mempool;
6820 * This maps vregs to the LLVM instruction defining them
6822 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6824 * This maps vregs for volatile variables to the LLVM instruction defining their
6827 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6828 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6829 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6830 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6831 ctx->phi_values = g_ptr_array_sized_new (256);
6833 * This signals whenever the vreg was defined by a phi node with no input vars
6834 * (i.e. all its input bblocks end with NOT_REACHABLE).
6836 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6837 /* Whenever the bblock is unreachable */
6838 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6839 ctx->bblock_list = g_ptr_array_sized_new (256);
6841 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6842 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6843 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6844 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6845 if (cfg->compile_aot) {
6846 ctx->module = &aot_module;
6850 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6851 * linkage for them. This requires the following:
6852 * - the method needs to have a unique mangled name
6853 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6855 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6857 method_name = mono_aot_get_mangled_method_name (cfg->method);
6859 is_linkonce = FALSE;
6862 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6864 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6868 method_name = mono_aot_get_method_name (cfg);
6869 cfg->llvm_method_name = g_strdup (method_name);
6871 init_jit_module (cfg->domain);
6872 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6873 method_name = mono_method_full_name (cfg->method, TRUE);
6875 ctx->method_name = method_name;
6876 ctx->is_linkonce = is_linkonce;
6878 #if LLVM_API_VERSION > 100
6879 if (cfg->compile_aot)
6880 ctx->lmodule = ctx->module->lmodule;
6882 ctx->lmodule = LLVMModuleCreateWithName (g_strdup_printf ("jit-module-%s", cfg->method->name));
6884 ctx->lmodule = ctx->module->lmodule;
6886 ctx->llvm_only = ctx->module->llvm_only;
6888 emit_method_inner (ctx);
6890 if (!ctx_ok (ctx)) {
6892 /* Need to add unused phi nodes as they can be referenced by other values */
6893 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6894 LLVMBuilderRef builder;
6896 builder = create_builder (ctx);
6897 LLVMPositionBuilderAtEnd (builder, phi_bb);
6899 for (i = 0; i < ctx->phi_values->len; ++i) {
6900 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6901 if (LLVMGetInstructionParent (v) == NULL)
6902 LLVMInsertIntoBuilder (builder, v);
6905 LLVMDeleteFunction (ctx->lmethod);
6911 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6913 mono_loader_unlock ();
6917 emit_method_inner (EmitContext *ctx)
6919 MonoCompile *cfg = ctx->cfg;
6920 MonoMethodSignature *sig;
6922 LLVMTypeRef method_type;
6923 LLVMValueRef method = NULL;
6924 LLVMValueRef *values = ctx->values;
6925 int i, max_block_num, bb_index;
6926 gboolean last = FALSE;
6927 LLVMCallInfo *linfo;
6928 LLVMModuleRef lmodule = ctx->lmodule;
6930 GPtrArray *bblock_list = ctx->bblock_list;
6931 MonoMethodHeader *header;
6932 MonoExceptionClause *clause;
6935 if (cfg->gsharedvt && !cfg->llvm_only) {
6936 set_failure (ctx, "gsharedvt");
6942 static int count = 0;
6945 char *llvm_count_str = g_getenv ("LLVM_COUNT");
6946 if (llvm_count_str) {
6947 int lcount = atoi (llvm_count_str);
6948 g_free (llvm_count_str);
6949 if (count == lcount) {
6950 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6954 if (count > lcount) {
6955 set_failure (ctx, "count");
6962 sig = mono_method_signature (cfg->method);
6965 linfo = get_llvm_call_info (cfg, sig);
6971 linfo->rgctx_arg = TRUE;
6972 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6976 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6977 ctx->lmethod = method;
6979 if (!cfg->llvm_only)
6980 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6981 LLVMSetLinkage (method, LLVMPrivateLinkage);
6983 mono_llvm_add_func_attr (method, LLVM_ATTR_UW_TABLE);
6985 if (cfg->compile_aot) {
6986 LLVMSetLinkage (method, LLVMInternalLinkage);
6987 if (ctx->module->external_symbols) {
6988 LLVMSetLinkage (method, LLVMExternalLinkage);
6989 LLVMSetVisibility (method, LLVMHiddenVisibility);
6991 if (ctx->is_linkonce) {
6992 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6993 LLVMSetVisibility (method, LLVMDefaultVisibility);
6996 #if LLVM_API_VERSION > 100
6997 LLVMSetLinkage (method, LLVMExternalLinkage);
6999 LLVMSetLinkage (method, LLVMPrivateLinkage);
7003 if (cfg->method->save_lmf && !cfg->llvm_only) {
7004 set_failure (ctx, "lmf");
7008 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
7009 set_failure (ctx, "pinvoke signature");
7013 header = cfg->header;
7014 for (i = 0; i < header->num_clauses; ++i) {
7015 clause = &header->clauses [i];
7016 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_FAULT && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
7017 set_failure (ctx, "non-finally/catch/fault clause.");
7021 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7022 /* We can't handle inlined methods with clauses */
7023 mono_llvm_add_func_attr (method, LLVM_ATTR_NO_INLINE);
7025 if (linfo->rgctx_arg) {
7026 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7027 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7029 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7030 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7031 * CC_X86_64_Mono in X86CallingConv.td.
7033 if (!ctx->llvm_only)
7034 mono_llvm_add_param_attr (ctx->rgctx_arg, LLVM_ATTR_IN_REG);
7035 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7037 ctx->rgctx_arg_pindex = -1;
7039 if (cfg->vret_addr) {
7040 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7041 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7042 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7043 mono_llvm_add_param_attr (LLVMGetParam (method, linfo->vret_arg_pindex), LLVM_ATTR_STRUCT_RET);
7044 mono_llvm_add_param_attr (LLVMGetParam (method, linfo->vret_arg_pindex), LLVM_ATTR_NO_ALIAS);
7049 ctx->this_arg_pindex = linfo->this_arg_pindex;
7050 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7051 values [cfg->args [0]->dreg] = ctx->this_arg;
7052 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7055 names = g_new (char *, sig->param_count);
7056 mono_method_get_param_names (cfg->method, (const char **) names);
7058 /* Set parameter names/attributes */
7059 for (i = 0; i < sig->param_count; ++i) {
7060 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7062 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7065 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7066 name = g_strdup_printf ("dummy_%d_%d", i, j);
7067 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7071 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7074 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7075 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7076 if (names [i] && names [i][0] != '\0')
7077 name = g_strdup_printf ("p_arg_%s", names [i]);
7079 name = g_strdup_printf ("p_arg_%d", i);
7081 if (names [i] && names [i][0] != '\0')
7082 name = g_strdup_printf ("arg_%s", names [i]);
7084 name = g_strdup_printf ("arg_%d", i);
7086 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7088 if (ainfo->storage == LLVMArgVtypeByVal)
7089 mono_llvm_add_param_attr (LLVMGetParam (method, pindex), LLVM_ATTR_BY_VAL);
7091 if (ainfo->storage == LLVMArgVtypeByRef) {
7093 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7098 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7099 ctx->minfo = mono_debug_lookup_method (cfg->method);
7100 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7104 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7105 max_block_num = MAX (max_block_num, bb->block_num);
7106 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7108 /* Add branches between non-consecutive bblocks */
7109 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7110 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7111 bb->next_bb != bb->last_ins->inst_false_bb) {
7113 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7114 inst->opcode = OP_BR;
7115 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7116 mono_bblock_add_inst (bb, inst);
7121 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7123 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7125 LLVMBuilderRef builder;
7127 char dname_buf[128];
7129 builder = create_builder (ctx);
7131 for (ins = bb->code; ins; ins = ins->next) {
7132 switch (ins->opcode) {
7137 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7142 if (ins->opcode == OP_VPHI) {
7143 /* Treat valuetype PHI nodes as operating on the address itself */
7144 g_assert (ins->klass);
7145 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7149 * Have to precreate these, as they can be referenced by
7150 * earlier instructions.
7152 sprintf (dname_buf, "t%d", ins->dreg);
7154 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7156 if (ins->opcode == OP_VPHI)
7157 ctx->addresses [ins->dreg] = values [ins->dreg];
7159 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7162 * Set the expected type of the incoming arguments since these have
7163 * to have the same type.
7165 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7166 int sreg1 = ins->inst_phi_args [i + 1];
7169 if (ins->opcode == OP_VPHI)
7170 ctx->is_vphi [sreg1] = TRUE;
7171 ctx->vreg_types [sreg1] = phi_type;
7177 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7186 * Create an ordering for bblocks, use the depth first order first, then
7187 * put the exception handling bblocks last.
7189 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7190 bb = cfg->bblocks [bb_index];
7191 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7192 g_ptr_array_add (bblock_list, bb);
7193 bblocks [bb->block_num].added = TRUE;
7197 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7198 if (!bblocks [bb->block_num].added)
7199 g_ptr_array_add (bblock_list, bb);
7203 * Second pass: generate code.
7206 LLVMBuilderRef entry_builder = create_builder (ctx);
7207 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7208 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7209 emit_entry_bb (ctx, entry_builder);
7211 // Make landing pads first
7212 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7214 if (ctx->llvm_only) {
7215 size_t group_index = 0;
7216 while (group_index < cfg->header->num_clauses) {
7218 size_t cursor = group_index;
7219 while (cursor < cfg->header->num_clauses &&
7220 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7221 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7226 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7227 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7228 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7230 group_index = cursor;
7234 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7235 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7237 // Prune unreachable mono BBs.
7238 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7241 process_bb (ctx, bb);
7245 g_hash_table_destroy (ctx->exc_meta);
7247 mono_memory_barrier ();
7249 /* Add incoming phi values */
7250 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7251 GSList *l, *ins_list;
7253 ins_list = bblocks [bb->block_num].phi_nodes;
7255 for (l = ins_list; l; l = l->next) {
7256 PhiNode *node = (PhiNode*)l->data;
7257 MonoInst *phi = node->phi;
7258 int sreg1 = node->sreg;
7259 LLVMBasicBlockRef in_bb;
7264 in_bb = get_end_bb (ctx, node->in_bb);
7266 if (ctx->unreachable [node->in_bb->block_num])
7269 if (!values [sreg1]) {
7270 /* Can happen with values in EH clauses */
7271 set_failure (ctx, "incoming phi sreg1");
7275 if (phi->opcode == OP_VPHI) {
7276 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7277 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7279 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7280 set_failure (ctx, "incoming phi arg type mismatch");
7283 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7284 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7289 /* Nullify empty phi instructions */
7290 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7291 GSList *l, *ins_list;
7293 ins_list = bblocks [bb->block_num].phi_nodes;
7295 for (l = ins_list; l; l = l->next) {
7296 PhiNode *node = (PhiNode*)l->data;
7297 MonoInst *phi = node->phi;
7298 LLVMValueRef phi_ins = values [phi->dreg];
7301 /* Already removed */
7304 if (LLVMCountIncoming (phi_ins) == 0) {
7305 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7306 LLVMInstructionEraseFromParent (phi_ins);
7307 values [phi->dreg] = NULL;
7312 /* Create the SWITCH statements for ENDFINALLY instructions */
7313 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7314 BBInfo *info = &bblocks [bb->block_num];
7316 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7317 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7318 GSList *bb_list = info->call_handler_return_bbs;
7320 GSList *bb_list_iter;
7322 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7323 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7329 /* Initialize the method if needed */
7330 if (cfg->compile_aot && ctx->llvm_only) {
7331 // FIXME: Add more shared got entries
7332 ctx->builder = create_builder (ctx);
7333 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7335 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7337 // FIXME: beforefieldinit
7339 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7340 * in load_method ().
7342 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7344 * linkonce methods shouldn't have initialization,
7345 * because they might belong to assemblies which
7346 * haven't been loaded yet.
7348 g_assert (!ctx->is_linkonce);
7349 emit_init_method (ctx);
7351 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7355 if (cfg->llvm_only) {
7356 GHashTableIter iter;
7358 GSList *callers, *l, *l2;
7361 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7362 * We can't do this earlier, as it contains llvm instructions which can be
7363 * freed if compilation fails.
7364 * FIXME: Get rid of this when all methods can be llvm compiled.
7366 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7367 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7368 for (l = callers; l; l = l->next) {
7369 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7370 l2 = g_slist_prepend (l2, l->data);
7371 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7376 if (cfg->verbose_level > 1)
7377 mono_llvm_dump_value (method);
7379 if (cfg->compile_aot && !cfg->llvm_only)
7380 mark_as_used (ctx->module, method);
7382 if (!cfg->llvm_only) {
7383 LLVMValueRef md_args [16];
7384 LLVMValueRef md_node;
7387 if (cfg->compile_aot)
7388 method_index = mono_aot_get_method_index (cfg->orig_method);
7391 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7392 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7393 md_node = LLVMMDNode (md_args, 2);
7394 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7395 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7398 if (cfg->compile_aot) {
7399 /* Don't generate native code, keep the LLVM IR */
7400 if (cfg->verbose_level)
7401 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7403 #if LLVM_API_VERSION < 100
7404 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7405 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7406 g_assert (err == 0);
7409 //LLVMVerifyFunction(method, 0);
7410 #if LLVM_API_VERSION > 100
7411 MonoDomain *domain = mono_domain_get ();
7412 MonoJitDomainInfo *domain_info;
7413 int nvars = g_hash_table_size (ctx->jit_callees);
7414 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7415 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7416 GHashTableIter iter;
7422 * Compute the addresses of the LLVM globals pointing to the
7423 * methods called by the current method. Pass it to the trampoline
7424 * code so it can update them after their corresponding method was
7427 g_hash_table_iter_init (&iter, ctx->jit_callees);
7429 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7430 callee_vars [i ++] = var;
7432 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7434 decode_llvm_eh_info (ctx, eh_frame);
7436 mono_domain_lock (domain);
7437 domain_info = domain_jit_info (domain);
7438 if (!domain_info->llvm_jit_callees)
7439 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7440 g_hash_table_iter_init (&iter, ctx->jit_callees);
7442 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7443 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7444 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7445 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7448 mono_domain_unlock (domain);
7450 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7452 if (cfg->verbose_level > 1)
7453 mono_llvm_dump_value (ctx->lmethod);
7455 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7457 /* Set by emit_cb */
7458 g_assert (cfg->code_len);
7462 if (ctx->module->method_to_lmethod)
7463 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7464 if (ctx->module->idx_to_lmethod)
7465 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7467 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7468 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7472 * mono_llvm_create_vars:
7474 * Same as mono_arch_create_vars () for LLVM.
7477 mono_llvm_create_vars (MonoCompile *cfg)
7479 MonoMethodSignature *sig;
7481 sig = mono_method_signature (cfg->method);
7482 if (cfg->gsharedvt && cfg->llvm_only) {
7483 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7484 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7485 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7486 printf ("vret_addr = ");
7487 mono_print_ins (cfg->vret_addr);
7491 mono_arch_create_vars (cfg);
7496 * mono_llvm_emit_call:
7498 * Same as mono_arch_emit_call () for LLVM.
7501 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7504 MonoMethodSignature *sig;
7505 int i, n, stack_size;
7510 sig = call->signature;
7511 n = sig->param_count + sig->hasthis;
7513 call->cinfo = get_llvm_call_info (cfg, sig);
7515 if (cfg->disable_llvm)
7518 if (sig->call_convention == MONO_CALL_VARARG) {
7519 cfg->exception_message = g_strdup ("varargs");
7520 cfg->disable_llvm = TRUE;
7523 for (i = 0; i < n; ++i) {
7526 ainfo = call->cinfo->args + i;
7528 in = call->args [i];
7530 /* Simply remember the arguments */
7531 switch (ainfo->storage) {
7532 case LLVMArgNormal: {
7533 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7536 opcode = mono_type_to_regmove (cfg, t);
7537 if (opcode == OP_FMOVE) {
7538 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7539 ins->dreg = mono_alloc_freg (cfg);
7540 } else if (opcode == OP_LMOVE) {
7541 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7542 ins->dreg = mono_alloc_lreg (cfg);
7543 } else if (opcode == OP_RMOVE) {
7544 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7545 ins->dreg = mono_alloc_freg (cfg);
7547 MONO_INST_NEW (cfg, ins, OP_MOVE);
7548 ins->dreg = mono_alloc_ireg (cfg);
7550 ins->sreg1 = in->dreg;
7553 case LLVMArgVtypeByVal:
7554 case LLVMArgVtypeByRef:
7555 case LLVMArgVtypeInReg:
7556 case LLVMArgVtypeAsScalar:
7557 case LLVMArgAsIArgs:
7558 case LLVMArgAsFpArgs:
7559 case LLVMArgGsharedvtVariable:
7560 case LLVMArgGsharedvtFixed:
7561 case LLVMArgGsharedvtFixedVtype:
7562 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7563 ins->dreg = mono_alloc_ireg (cfg);
7564 ins->sreg1 = in->dreg;
7565 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7566 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7567 ins->inst_vtype = ainfo->type;
7568 ins->klass = mono_class_from_mono_type (ainfo->type);
7571 cfg->exception_message = g_strdup ("ainfo->storage");
7572 cfg->disable_llvm = TRUE;
7576 if (!cfg->disable_llvm) {
7577 MONO_ADD_INS (cfg->cbb, ins);
7578 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7583 static unsigned char*
7584 alloc_cb (LLVMValueRef function, int size)
7588 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7592 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7594 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7599 emitted_cb (LLVMValueRef function, void *start, void *end)
7603 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7605 cfg->code_len = (guint8*)end - (guint8*)start;
7609 exception_cb (void *data)
7612 MonoJitExceptionInfo *ei;
7613 guint32 ei_len, i, j, nested_len, nindex;
7614 gpointer *type_info;
7615 int this_reg, this_offset;
7617 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7621 * data points to a DWARF FDE structure, convert it to our unwind format and
7623 * An alternative would be to save it directly, and modify our unwinder to work
7626 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);
7627 if (cfg->verbose_level > 1)
7628 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7630 /* Count nested clauses */
7632 for (i = 0; i < ei_len; ++i) {
7633 gint32 cindex1 = *(gint32*)type_info [i];
7634 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7636 for (j = 0; j < cfg->header->num_clauses; ++j) {
7638 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7640 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7646 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7647 cfg->llvm_ex_info_len = ei_len + nested_len;
7648 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7649 /* Fill the rest of the information from the type info */
7650 for (i = 0; i < ei_len; ++i) {
7651 gint32 clause_index = *(gint32*)type_info [i];
7652 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7654 cfg->llvm_ex_info [i].flags = clause->flags;
7655 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7656 cfg->llvm_ex_info [i].clause_index = clause_index;
7660 * For nested clauses, the LLVM produced exception info associates the try interval with
7661 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7662 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7663 * and everything else from the nested clause.
7666 for (i = 0; i < ei_len; ++i) {
7667 gint32 cindex1 = *(gint32*)type_info [i];
7668 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7670 for (j = 0; j < cfg->header->num_clauses; ++j) {
7672 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7673 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7675 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7676 /* clause1 is the nested clause */
7677 nested_ei = &cfg->llvm_ex_info [i];
7678 nesting_ei = &cfg->llvm_ex_info [nindex];
7681 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7683 nesting_ei->flags = clause2->flags;
7684 nesting_ei->data.catch_class = clause2->data.catch_class;
7685 nesting_ei->clause_index = cindex2;
7689 g_assert (nindex == ei_len + nested_len);
7690 cfg->llvm_this_reg = this_reg;
7691 cfg->llvm_this_offset = this_offset;
7693 /* type_info [i] is cfg mempool allocated, no need to free it */
7699 #if LLVM_API_VERSION > 100
7701 * decode_llvm_eh_info:
7703 * Decode the EH table emitted by llvm in jit mode, and store
7704 * the result into cfg.
7707 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7709 MonoCompile *cfg = ctx->cfg;
7712 MonoLLVMFDEInfo info;
7713 MonoJitExceptionInfo *ei;
7714 guint8 *p = eh_frame;
7715 int version, fde_count, fde_offset;
7716 guint32 ei_len, i, nested_len;
7717 gpointer *type_info;
7722 * Decode the one element EH table emitted by the MonoException class
7726 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7729 g_assert (version == 3);
7732 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7734 fde_count = *(guint32*)p;
7738 g_assert (fde_count <= 2);
7740 /* The first entry is the real method */
7741 g_assert (table [0] == 1);
7742 fde_offset = table [1];
7743 table += fde_count * 2;
7745 cfg->code_len = table [0];
7746 fde_len = table [1] - fde_offset;
7749 fde = (guint8*)eh_frame + fde_offset;
7750 cie = (guint8*)table;
7752 /* Compute lengths */
7753 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info, NULL, NULL, NULL);
7755 ei = (MonoJitExceptionInfo *)g_malloc0 (info.ex_info_len * sizeof (MonoJitExceptionInfo));
7756 type_info = (gpointer *)g_malloc0 (info.ex_info_len * sizeof (gpointer));
7757 unw_info = (guint8*)g_malloc0 (info.unw_info_len);
7759 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info, ei, type_info, unw_info);
7761 cfg->encoded_unwind_ops = unw_info;
7762 cfg->encoded_unwind_ops_len = info.unw_info_len;
7763 if (cfg->verbose_level > 1)
7764 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7765 if (info.this_reg != -1) {
7766 cfg->llvm_this_reg = info.this_reg;
7767 cfg->llvm_this_offset = info.this_offset;
7770 ei_len = info.ex_info_len;
7772 // Nested clauses are currently disabled
7775 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7776 cfg->llvm_ex_info_len = ei_len + nested_len;
7777 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7778 /* Fill the rest of the information from the type info */
7779 for (i = 0; i < ei_len; ++i) {
7780 gint32 clause_index = *(gint32*)type_info [i];
7781 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7783 cfg->llvm_ex_info [i].flags = clause->flags;
7784 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7785 cfg->llvm_ex_info [i].clause_index = clause_index;
7791 dlsym_cb (const char *name, void **symbol)
7797 if (!strcmp (name, "__bzero")) {
7798 *symbol = (void*)bzero;
7800 current = mono_dl_open (NULL, 0, NULL);
7803 err = mono_dl_symbol (current, name, symbol);
7805 mono_dl_close (current);
7807 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7808 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7814 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7816 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7820 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7822 LLVMTypeRef param_types [4];
7824 param_types [0] = param_type1;
7825 param_types [1] = param_type2;
7827 AddFunc (module, name, ret_type, param_types, 2);
7833 INTRINS_SADD_OVF_I32,
7834 INTRINS_UADD_OVF_I32,
7835 INTRINS_SSUB_OVF_I32,
7836 INTRINS_USUB_OVF_I32,
7837 INTRINS_SMUL_OVF_I32,
7838 INTRINS_UMUL_OVF_I32,
7839 INTRINS_SADD_OVF_I64,
7840 INTRINS_UADD_OVF_I64,
7841 INTRINS_SSUB_OVF_I64,
7842 INTRINS_USUB_OVF_I64,
7843 INTRINS_SMUL_OVF_I64,
7844 INTRINS_UMUL_OVF_I64,
7851 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7852 INTRINS_SSE_PMOVMSKB,
7853 INTRINS_SSE_PSRLI_W,
7854 INTRINS_SSE_PSRAI_W,
7855 INTRINS_SSE_PSLLI_W,
7856 INTRINS_SSE_PSRLI_D,
7857 INTRINS_SSE_PSRAI_D,
7858 INTRINS_SSE_PSLLI_D,
7859 INTRINS_SSE_PSRLI_Q,
7860 INTRINS_SSE_PSLLI_Q,
7861 INTRINS_SSE_SQRT_PD,
7862 INTRINS_SSE_SQRT_PS,
7863 INTRINS_SSE_RSQRT_PS,
7865 INTRINS_SSE_CVTTPD2DQ,
7866 INTRINS_SSE_CVTTPS2DQ,
7867 INTRINS_SSE_CVTDQ2PD,
7868 INTRINS_SSE_CVTDQ2PS,
7869 INTRINS_SSE_CVTPD2DQ,
7870 INTRINS_SSE_CVTPS2DQ,
7871 INTRINS_SSE_CVTPD2PS,
7872 INTRINS_SSE_CVTPS2PD,
7875 INTRINS_SSE_PACKSSWB,
7876 INTRINS_SSE_PACKUSWB,
7877 INTRINS_SSE_PACKSSDW,
7878 INTRINS_SSE_PACKUSDW,
7883 INTRINS_SSE_ADDSUBPS,
7888 INTRINS_SSE_ADDSUBPD,
7891 INTRINS_SSE_PADDUSW,
7892 INTRINS_SSE_PSUBUSW,
7898 INTRINS_SSE_PADDUSB,
7899 INTRINS_SSE_PSUBUSB,
7912 static IntrinsicDesc intrinsics[] = {
7913 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7914 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7915 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7916 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7917 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7918 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7919 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7920 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7921 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7922 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7923 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7924 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7925 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7926 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7927 {INTRINS_SIN, "llvm.sin.f64"},
7928 {INTRINS_COS, "llvm.cos.f64"},
7929 {INTRINS_SQRT, "llvm.sqrt.f64"},
7930 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7931 {INTRINS_FABS, "fabs"},
7932 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7933 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7934 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7935 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7936 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7937 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7938 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7939 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7940 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7941 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7942 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7943 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7944 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7945 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7946 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7947 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7948 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7949 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7950 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7951 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7952 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7953 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7954 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7955 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7956 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7957 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7958 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7959 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7960 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7961 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7962 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7963 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7964 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7965 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7966 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7967 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7968 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7969 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7970 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7971 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7972 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7973 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7974 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7975 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7976 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7977 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7978 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7979 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7980 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7981 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7982 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7983 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7984 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7985 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7990 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7992 LLVMTypeRef ret_type = type_to_simd_type (type);
7993 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7997 add_intrinsic (LLVMModuleRef module, int id)
8000 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8001 LLVMTypeRef ret_type, arg_types [16];
8004 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
8008 case INTRINS_MEMSET: {
8009 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8011 AddFunc (module, name, LLVMVoidType (), params, 5);
8014 case INTRINS_MEMCPY: {
8015 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8017 AddFunc (module, name, LLVMVoidType (), params, 5);
8020 case INTRINS_SADD_OVF_I32:
8021 case INTRINS_UADD_OVF_I32:
8022 case INTRINS_SSUB_OVF_I32:
8023 case INTRINS_USUB_OVF_I32:
8024 case INTRINS_SMUL_OVF_I32:
8025 case INTRINS_UMUL_OVF_I32: {
8026 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
8027 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
8028 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
8030 AddFunc (module, name, ret_type, params, 2);
8033 case INTRINS_SADD_OVF_I64:
8034 case INTRINS_UADD_OVF_I64:
8035 case INTRINS_SSUB_OVF_I64:
8036 case INTRINS_USUB_OVF_I64:
8037 case INTRINS_SMUL_OVF_I64:
8038 case INTRINS_UMUL_OVF_I64: {
8039 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8040 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8041 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8043 AddFunc (module, name, ret_type, params, 2);
8049 case INTRINS_FABS: {
8050 LLVMTypeRef params [] = { LLVMDoubleType () };
8052 AddFunc (module, name, LLVMDoubleType (), params, 1);
8055 case INTRINS_EXPECT_I8:
8056 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8058 case INTRINS_EXPECT_I1:
8059 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8061 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8062 case INTRINS_SSE_PMOVMSKB:
8064 ret_type = LLVMInt32Type ();
8065 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8066 AddFunc (module, name, ret_type, arg_types, 1);
8068 case INTRINS_SSE_PSRLI_W:
8069 case INTRINS_SSE_PSRAI_W:
8070 case INTRINS_SSE_PSLLI_W:
8072 ret_type = type_to_simd_type (MONO_TYPE_I2);
8073 arg_types [0] = ret_type;
8074 arg_types [1] = LLVMInt32Type ();
8075 AddFunc (module, name, ret_type, arg_types, 2);
8077 case INTRINS_SSE_PSRLI_D:
8078 case INTRINS_SSE_PSRAI_D:
8079 case INTRINS_SSE_PSLLI_D:
8080 ret_type = type_to_simd_type (MONO_TYPE_I4);
8081 arg_types [0] = ret_type;
8082 arg_types [1] = LLVMInt32Type ();
8083 AddFunc (module, name, ret_type, arg_types, 2);
8085 case INTRINS_SSE_PSRLI_Q:
8086 case INTRINS_SSE_PSLLI_Q:
8087 ret_type = type_to_simd_type (MONO_TYPE_I8);
8088 arg_types [0] = ret_type;
8089 arg_types [1] = LLVMInt32Type ();
8090 AddFunc (module, name, ret_type, arg_types, 2);
8092 case INTRINS_SSE_SQRT_PD:
8094 ret_type = type_to_simd_type (MONO_TYPE_R8);
8095 arg_types [0] = ret_type;
8096 AddFunc (module, name, ret_type, arg_types, 1);
8098 case INTRINS_SSE_SQRT_PS:
8099 ret_type = type_to_simd_type (MONO_TYPE_R4);
8100 arg_types [0] = ret_type;
8101 AddFunc (module, name, ret_type, arg_types, 1);
8103 case INTRINS_SSE_RSQRT_PS:
8104 ret_type = type_to_simd_type (MONO_TYPE_R4);
8105 arg_types [0] = ret_type;
8106 AddFunc (module, name, ret_type, arg_types, 1);
8108 case INTRINS_SSE_RCP_PS:
8109 ret_type = type_to_simd_type (MONO_TYPE_R4);
8110 arg_types [0] = ret_type;
8111 AddFunc (module, name, ret_type, arg_types, 1);
8113 case INTRINS_SSE_CVTTPD2DQ:
8114 ret_type = type_to_simd_type (MONO_TYPE_I4);
8115 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8116 AddFunc (module, name, ret_type, arg_types, 1);
8118 case INTRINS_SSE_CVTTPS2DQ:
8119 ret_type = type_to_simd_type (MONO_TYPE_I4);
8120 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8121 AddFunc (module, name, ret_type, arg_types, 1);
8123 case INTRINS_SSE_CVTDQ2PD:
8124 /* Conversion ops */
8125 ret_type = type_to_simd_type (MONO_TYPE_R8);
8126 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8127 AddFunc (module, name, ret_type, arg_types, 1);
8129 case INTRINS_SSE_CVTDQ2PS:
8130 ret_type = type_to_simd_type (MONO_TYPE_R4);
8131 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8132 AddFunc (module, name, ret_type, arg_types, 1);
8134 case INTRINS_SSE_CVTPD2DQ:
8135 ret_type = type_to_simd_type (MONO_TYPE_I4);
8136 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8137 AddFunc (module, name, ret_type, arg_types, 1);
8139 case INTRINS_SSE_CVTPS2DQ:
8140 ret_type = type_to_simd_type (MONO_TYPE_I4);
8141 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8142 AddFunc (module, name, ret_type, arg_types, 1);
8144 case INTRINS_SSE_CVTPD2PS:
8145 ret_type = type_to_simd_type (MONO_TYPE_R4);
8146 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8147 AddFunc (module, name, ret_type, arg_types, 1);
8149 case INTRINS_SSE_CVTPS2PD:
8150 ret_type = type_to_simd_type (MONO_TYPE_R8);
8151 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8152 AddFunc (module, name, ret_type, arg_types, 1);
8154 case INTRINS_SSE_CMPPD:
8156 ret_type = type_to_simd_type (MONO_TYPE_R8);
8157 arg_types [0] = ret_type;
8158 arg_types [1] = ret_type;
8159 arg_types [2] = LLVMInt8Type ();
8160 AddFunc (module, name, ret_type, arg_types, 3);
8162 case INTRINS_SSE_CMPPS:
8163 ret_type = type_to_simd_type (MONO_TYPE_R4);
8164 arg_types [0] = ret_type;
8165 arg_types [1] = ret_type;
8166 arg_types [2] = LLVMInt8Type ();
8167 AddFunc (module, name, ret_type, arg_types, 3);
8169 case INTRINS_SSE_PACKSSWB:
8170 case INTRINS_SSE_PACKUSWB:
8171 case INTRINS_SSE_PACKSSDW:
8173 ret_type = type_to_simd_type (MONO_TYPE_I1);
8174 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8175 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8176 AddFunc (module, name, ret_type, arg_types, 2);
8178 case INTRINS_SSE_PACKUSDW:
8179 ret_type = type_to_simd_type (MONO_TYPE_I2);
8180 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8181 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8182 AddFunc (module, name, ret_type, arg_types, 2);
8184 /* SSE Binary ops */
8185 case INTRINS_SSE_PADDSW:
8186 case INTRINS_SSE_PSUBSW:
8187 case INTRINS_SSE_PADDUSW:
8188 case INTRINS_SSE_PSUBUSW:
8189 case INTRINS_SSE_PAVGW:
8190 case INTRINS_SSE_PMULHW:
8191 case INTRINS_SSE_PMULHU:
8192 add_sse_binary (module, name, MONO_TYPE_I2);
8194 case INTRINS_SSE_MINPS:
8195 case INTRINS_SSE_MAXPS:
8196 case INTRINS_SSE_HADDPS:
8197 case INTRINS_SSE_HSUBPS:
8198 case INTRINS_SSE_ADDSUBPS:
8199 add_sse_binary (module, name, MONO_TYPE_R4);
8201 case INTRINS_SSE_MINPD:
8202 case INTRINS_SSE_MAXPD:
8203 case INTRINS_SSE_HADDPD:
8204 case INTRINS_SSE_HSUBPD:
8205 case INTRINS_SSE_ADDSUBPD:
8206 add_sse_binary (module, name, MONO_TYPE_R8);
8208 case INTRINS_SE_PADDSB:
8209 case INTRINS_SSE_PSUBSB:
8210 case INTRINS_SSE_PADDUSB:
8211 case INTRINS_SSE_PSUBUSB:
8212 case INTRINS_SSE_PAVGB:
8213 add_sse_binary (module, name, MONO_TYPE_I1);
8215 case INTRINS_SSE_PAUSE:
8216 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8218 case INTRINS_SSE_DPPS:
8219 ret_type = type_to_simd_type (MONO_TYPE_R4);
8220 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8221 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8222 #if LLVM_API_VERSION >= 500
8223 arg_types [2] = LLVMInt8Type ();
8225 arg_types [2] = LLVMInt32Type ();
8227 AddFunc (module, name, ret_type, arg_types, 3);
8231 g_assert_not_reached ();
8237 get_intrinsic (EmitContext *ctx, const char *name)
8239 #if LLVM_API_VERSION > 100
8243 * Every method is emitted into its own module so
8244 * we can add intrinsics on demand.
8246 res = LLVMGetNamedFunction (ctx->lmodule, name);
8250 /* No locking needed */
8251 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8254 printf ("%s\n", name);
8255 g_assert (id != -1);
8256 add_intrinsic (ctx->lmodule, id);
8257 res = LLVMGetNamedFunction (ctx->lmodule, name);
8265 res = LLVMGetNamedFunction (ctx->lmodule, name);
8272 add_intrinsics (LLVMModuleRef module)
8276 /* Emit declarations of instrinsics */
8278 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8279 * type doesn't seem to do any locking.
8281 for (i = 0; i < INTRINS_NUM; ++i)
8282 add_intrinsic (module, i);
8286 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8288 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8291 /* Load/Store intrinsics */
8293 LLVMTypeRef arg_types [5];
8297 for (i = 1; i <= 8; i *= 2) {
8298 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8299 arg_types [1] = LLVMInt32Type ();
8300 arg_types [2] = LLVMInt1Type ();
8301 arg_types [3] = LLVMInt32Type ();
8302 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8303 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8305 arg_types [0] = LLVMIntType (i * 8);
8306 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8307 arg_types [2] = LLVMInt32Type ();
8308 arg_types [3] = LLVMInt1Type ();
8309 arg_types [4] = LLVMInt32Type ();
8310 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8311 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8317 add_types (MonoLLVMModule *module)
8319 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8323 mono_llvm_init (void)
8328 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8330 h = g_hash_table_new (NULL, NULL);
8331 for (i = 0; i < INTRINS_NUM; ++i)
8332 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8333 intrins_id_to_name = h;
8335 h = g_hash_table_new (g_str_hash, g_str_equal);
8336 for (i = 0; i < INTRINS_NUM; ++i)
8337 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8338 intrins_name_to_id = h;
8342 init_jit_module (MonoDomain *domain)
8344 MonoJitDomainInfo *dinfo;
8345 MonoLLVMModule *module;
8348 dinfo = domain_jit_info (domain);
8349 if (dinfo->llvm_module)
8352 mono_loader_lock ();
8354 if (dinfo->llvm_module) {
8355 mono_loader_unlock ();
8359 module = g_new0 (MonoLLVMModule, 1);
8361 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8362 module->lmodule = LLVMModuleCreateWithName (name);
8363 module->context = LLVMGetGlobalContext ();
8365 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8367 add_intrinsics (module->lmodule);
8370 module->llvm_types = g_hash_table_new (NULL, NULL);
8372 #if LLVM_API_VERSION < 100
8373 MonoJitICallInfo *info;
8375 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8377 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8380 mono_memory_barrier ();
8382 dinfo->llvm_module = module;
8384 mono_loader_unlock ();
8388 mono_llvm_cleanup (void)
8390 MonoLLVMModule *module = &aot_module;
8392 if (module->lmodule)
8393 LLVMDisposeModule (module->lmodule);
8395 if (module->context)
8396 LLVMContextDispose (module->context);
8400 mono_llvm_free_domain_info (MonoDomain *domain)
8402 MonoJitDomainInfo *info = domain_jit_info (domain);
8403 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8409 if (module->llvm_types)
8410 g_hash_table_destroy (module->llvm_types);
8412 mono_llvm_dispose_ee (module->mono_ee);
8414 if (module->bb_names) {
8415 for (i = 0; i < module->bb_names_len; ++i)
8416 g_free (module->bb_names [i]);
8417 g_free (module->bb_names);
8419 //LLVMDisposeModule (module->module);
8423 info->llvm_module = NULL;
8427 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, int initial_got_size, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8429 MonoLLVMModule *module = &aot_module;
8431 /* Delete previous module */
8432 if (module->plt_entries)
8433 g_hash_table_destroy (module->plt_entries);
8434 if (module->lmodule)
8435 LLVMDisposeModule (module->lmodule);
8437 memset (module, 0, sizeof (aot_module));
8439 module->lmodule = LLVMModuleCreateWithName ("aot");
8440 module->assembly = assembly;
8441 module->global_prefix = g_strdup (global_prefix);
8442 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8443 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8444 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8445 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8446 module->external_symbols = TRUE;
8447 module->emit_dwarf = emit_dwarf;
8448 module->static_link = static_link;
8449 module->llvm_only = llvm_only;
8450 /* The first few entries are reserved */
8451 module->max_got_offset = initial_got_size;
8452 module->context = LLVMGetGlobalContext ();
8455 /* clang ignores our debug info because it has an invalid version */
8456 module->emit_dwarf = FALSE;
8458 add_intrinsics (module->lmodule);
8461 #if LLVM_API_VERSION > 100
8462 if (module->emit_dwarf) {
8463 char *dir, *build_info, *s, *cu_name;
8465 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8468 dir = g_strdup (".");
8469 build_info = mono_get_runtime_build_info ();
8470 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8471 cu_name = g_path_get_basename (assembly->image->name);
8472 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8474 g_free (build_info);
8481 * We couldn't compute the type of the LLVM global representing the got because
8482 * its size is only known after all the methods have been emitted. So create
8483 * a dummy variable, and replace all uses it with the real got variable when
8484 * its size is known in mono_llvm_emit_aot_module ().
8487 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8489 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8490 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8493 /* Add initialization array */
8495 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8497 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8498 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8502 emit_init_icall_wrappers (module);
8504 emit_llvm_code_start (module);
8506 /* Add a dummy personality function */
8507 if (!use_debug_personality) {
8508 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8509 LLVMSetLinkage (personality, LLVMExternalLinkage);
8510 mark_as_used (module, personality);
8513 /* Add a reference to the c++ exception we throw/catch */
8515 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8516 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8517 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8518 mono_llvm_set_is_constant (module->sentinel_exception);
8521 module->llvm_types = g_hash_table_new (NULL, NULL);
8522 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8523 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8524 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8525 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8526 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8527 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8528 module->method_to_callers = g_hash_table_new (NULL, NULL);
8532 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8535 LLVMValueRef res, *vals;
8537 vals = g_new0 (LLVMValueRef, nvalues);
8538 for (i = 0; i < nvalues; ++i)
8539 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8540 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8546 llvm_array_from_bytes (guint8 *values, int nvalues)
8549 LLVMValueRef res, *vals;
8551 vals = g_new0 (LLVMValueRef, nvalues);
8552 for (i = 0; i < nvalues; ++i)
8553 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8554 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8559 * mono_llvm_emit_aot_file_info:
8561 * Emit the MonoAotFileInfo structure.
8562 * Same as emit_aot_file_info () in aot-compiler.c.
8565 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8567 MonoLLVMModule *module = &aot_module;
8569 /* Save these for later */
8570 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8571 module->has_jitted_code = has_jitted_code;
8575 * mono_llvm_emit_aot_data:
8577 * Emit the binary data DATA pointed to by symbol SYMBOL.
8580 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8582 MonoLLVMModule *module = &aot_module;
8586 type = LLVMArrayType (LLVMInt8Type (), data_len);
8587 d = LLVMAddGlobal (module->lmodule, type, symbol);
8588 LLVMSetVisibility (d, LLVMHiddenVisibility);
8589 LLVMSetLinkage (d, LLVMInternalLinkage);
8590 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8591 LLVMSetAlignment (d, 8);
8592 mono_llvm_set_is_constant (d);
8595 /* Add a reference to a global defined in JITted code */
8597 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8602 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8603 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8609 emit_aot_file_info (MonoLLVMModule *module)
8611 LLVMTypeRef file_info_type;
8612 LLVMTypeRef *eltypes, eltype;
8613 LLVMValueRef info_var;
8614 LLVMValueRef *fields;
8615 int i, nfields, tindex;
8616 MonoAotFileInfo *info;
8617 LLVMModuleRef lmodule = module->lmodule;
8619 info = &module->aot_info;
8621 /* Create an LLVM type to represent MonoAotFileInfo */
8622 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8623 eltypes = g_new (LLVMTypeRef, nfields);
8625 eltypes [tindex ++] = LLVMInt32Type ();
8626 eltypes [tindex ++] = LLVMInt32Type ();
8628 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8629 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8631 for (i = 0; i < 15; ++i)
8632 eltypes [tindex ++] = LLVMInt32Type ();
8634 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8635 for (i = 0; i < 4; ++i)
8636 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8637 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8638 g_assert (tindex == nfields);
8639 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8640 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8642 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8643 if (module->static_link) {
8644 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8645 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8647 fields = g_new (LLVMValueRef, nfields);
8649 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8650 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8654 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8655 * for symbols defined in the .s file emitted by the aot compiler.
8657 eltype = eltypes [tindex];
8658 if (module->llvm_only)
8659 fields [tindex ++] = LLVMConstNull (eltype);
8661 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8662 fields [tindex ++] = module->got_var;
8663 /* llc defines this directly */
8664 if (!module->llvm_only) {
8665 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8666 fields [tindex ++] = LLVMConstNull (eltype);
8667 fields [tindex ++] = LLVMConstNull (eltype);
8669 fields [tindex ++] = LLVMConstNull (eltype);
8670 fields [tindex ++] = module->get_method;
8671 fields [tindex ++] = module->get_unbox_tramp;
8673 if (module->has_jitted_code) {
8674 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8675 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8677 fields [tindex ++] = LLVMConstNull (eltype);
8678 fields [tindex ++] = LLVMConstNull (eltype);
8680 if (!module->llvm_only)
8681 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8683 fields [tindex ++] = LLVMConstNull (eltype);
8684 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8685 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8686 fields [tindex ++] = LLVMConstNull (eltype);
8688 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8689 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8690 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8691 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8692 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8693 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8694 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8695 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8696 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8697 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8699 /* Not needed (mem_end) */
8700 fields [tindex ++] = LLVMConstNull (eltype);
8701 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8702 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8703 if (info->trampoline_size [0]) {
8704 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8705 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8706 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8707 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8709 fields [tindex ++] = LLVMConstNull (eltype);
8710 fields [tindex ++] = LLVMConstNull (eltype);
8711 fields [tindex ++] = LLVMConstNull (eltype);
8712 fields [tindex ++] = LLVMConstNull (eltype);
8714 if (module->static_link && !module->llvm_only)
8715 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8717 fields [tindex ++] = LLVMConstNull (eltype);
8718 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8719 if (!module->llvm_only) {
8720 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8721 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8722 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8723 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8724 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8725 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8727 fields [tindex ++] = LLVMConstNull (eltype);
8728 fields [tindex ++] = LLVMConstNull (eltype);
8729 fields [tindex ++] = LLVMConstNull (eltype);
8730 fields [tindex ++] = LLVMConstNull (eltype);
8731 fields [tindex ++] = LLVMConstNull (eltype);
8732 fields [tindex ++] = LLVMConstNull (eltype);
8735 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8736 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8739 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8740 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8741 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8742 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8743 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8744 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8745 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8746 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8747 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8748 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8749 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8750 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8751 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8752 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8753 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8755 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8756 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8757 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8758 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8759 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8761 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8762 g_assert (tindex == nfields);
8764 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8766 if (module->static_link) {
8770 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8771 /* Get rid of characters which cannot occur in symbols */
8773 for (p = s; *p; ++p) {
8774 if (!(isalnum (*p) || *p == '_'))
8777 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8779 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8780 LLVMSetLinkage (var, LLVMExternalLinkage);
8785 * Emit the aot module into the LLVM bitcode file FILENAME.
8788 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8790 LLVMTypeRef got_type, inited_type;
8791 LLVMValueRef real_got, real_inited;
8792 MonoLLVMModule *module = &aot_module;
8794 emit_llvm_code_end (module);
8797 * Create the real got variable and replace all uses of the dummy variable with
8800 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8801 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8802 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8803 if (module->external_symbols) {
8804 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8805 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8807 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8809 mono_llvm_replace_uses_of (module->got_var, real_got);
8811 mark_as_used (&aot_module, real_got);
8813 /* Delete the dummy got so it doesn't become a global */
8814 LLVMDeleteGlobal (module->got_var);
8815 module->got_var = real_got;
8818 * Same for the init_var
8820 if (module->llvm_only) {
8821 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8822 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8823 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8824 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8825 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8826 LLVMDeleteGlobal (module->inited_var);
8829 if (module->llvm_only) {
8830 emit_get_method (&aot_module);
8831 emit_get_unbox_tramp (&aot_module);
8834 emit_llvm_used (&aot_module);
8835 emit_dbg_info (&aot_module, filename, cu_name);
8836 emit_aot_file_info (&aot_module);
8839 * Replace GOT entries for directly callable methods with the methods themselves.
8840 * It would be easier to implement this by predefining all methods before compiling
8841 * their bodies, but that couldn't handle the case when a method fails to compile
8844 if (module->llvm_only) {
8845 GHashTableIter iter;
8847 GSList *callers, *l;
8849 g_hash_table_iter_init (&iter, module->method_to_callers);
8850 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8851 LLVMValueRef lmethod;
8853 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8856 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8858 for (l = callers; l; l = l->next) {
8859 LLVMValueRef caller = (LLVMValueRef)l->data;
8861 mono_llvm_replace_uses_of (caller, lmethod);
8867 /* Replace PLT entries for directly callable methods with the methods themselves */
8869 GHashTableIter iter;
8871 LLVMValueRef callee;
8873 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8874 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8875 if (mono_aot_is_direct_callable (ji)) {
8876 LLVMValueRef lmethod;
8878 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8879 /* The types might not match because the caller might pass an rgctx */
8880 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8881 mono_llvm_replace_uses_of (callee, lmethod);
8882 mono_aot_mark_unused_llvm_plt_entry (ji);
8892 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8893 printf ("%s\n", verifier_err);
8894 g_assert_not_reached ();
8899 LLVMWriteBitcodeToFile (module->lmodule, filename);
8904 md_string (const char *s)
8906 return LLVMMDString (s, strlen (s));
8909 /* Debugging support */
8912 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8914 LLVMModuleRef lmodule = module->lmodule;
8915 LLVMValueRef args [16], ver;
8918 * This can only be enabled when LLVM code is emitted into a separate object
8919 * file, since the AOT compiler also emits dwarf info,
8920 * and the abbrev indexes will not be correct since llvm has added its own
8923 if (!module->emit_dwarf)
8926 #if LLVM_API_VERSION > 100
8927 mono_llvm_di_builder_finalize (module->di_builder);
8929 LLVMValueRef cu_args [16], cu;
8931 char *build_info, *s, *dir;
8934 * Emit dwarf info in the form of LLVM metadata. There is some
8935 * out-of-date documentation at:
8936 * http://llvm.org/docs/SourceLevelDebugging.html
8937 * but most of this was gathered from the llvm and
8942 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8943 /* CU name/compilation dir */
8944 dir = g_path_get_dirname (filename);
8945 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8946 args [1] = LLVMMDString (dir, strlen (dir));
8947 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8950 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8952 build_info = mono_get_runtime_build_info ();
8953 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8954 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8955 g_free (build_info);
8957 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8959 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8960 /* Runtime version */
8961 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8963 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8964 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8966 if (module->subprogram_mds) {
8970 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8971 for (i = 0; i < module->subprogram_mds->len; ++i)
8972 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8973 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8975 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8978 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8979 /* Imported modules */
8980 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8982 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8983 /* DebugEmissionKind = FullDebug */
8984 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8985 cu = LLVMMDNode (cu_args, n_cuargs);
8986 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8989 #if LLVM_API_VERSION > 100
8990 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8991 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8992 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8993 ver = LLVMMDNode (args, 3);
8994 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8996 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8997 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8998 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8999 ver = LLVMMDNode (args, 3);
9000 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9002 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9003 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9004 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
9005 ver = LLVMMDNode (args, 3);
9006 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9008 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9009 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9010 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9011 ver = LLVMMDNode (args, 3);
9012 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9017 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9019 MonoLLVMModule *module = ctx->module;
9020 MonoDebugMethodInfo *minfo = ctx->minfo;
9021 char *source_file, *dir, *filename;
9022 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9023 MonoSymSeqPoint *sym_seq_points;
9029 mono_debug_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9031 source_file = g_strdup ("<unknown>");
9032 dir = g_path_get_dirname (source_file);
9033 filename = g_path_get_basename (source_file);
9035 #if LLVM_API_VERSION > 100
9036 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);
9039 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9040 args [0] = md_string (filename);
9041 args [1] = md_string (dir);
9042 ctx_args [1] = LLVMMDNode (args, 2);
9043 ctx_md = LLVMMDNode (ctx_args, 2);
9045 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9046 type_args [1] = NULL;
9047 type_args [2] = NULL;
9048 type_args [3] = LLVMMDString ("", 0);
9049 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9050 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9051 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9052 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9053 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9054 type_args [9] = NULL;
9055 type_args [10] = NULL;
9056 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9057 type_args [12] = NULL;
9058 type_args [13] = NULL;
9059 type_args [14] = NULL;
9060 type_md = LLVMMDNode (type_args, 14);
9062 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9063 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9064 /* Source directory + file pair */
9065 args [0] = md_string (filename);
9066 args [1] = md_string (dir);
9067 md_args [1] = LLVMMDNode (args ,2);
9068 md_args [2] = ctx_md;
9069 md_args [3] = md_string (cfg->method->name);
9070 md_args [4] = md_string (name);
9071 md_args [5] = md_string (name);
9074 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9076 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9078 md_args [7] = type_md;
9080 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9082 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9084 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9085 /* Index into a virtual function */
9086 md_args [11] = NULL;
9087 md_args [12] = NULL;
9089 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9091 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9092 /* Pointer to LLVM function */
9093 md_args [15] = method;
9094 /* Function template parameter */
9095 md_args [16] = NULL;
9096 /* Function declaration descriptor */
9097 md_args [17] = NULL;
9098 /* List of function variables */
9099 md_args [18] = LLVMMDNode (args, 0);
9101 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9102 md = LLVMMDNode (md_args, 20);
9104 if (!module->subprogram_mds)
9105 module->subprogram_mds = g_ptr_array_new ();
9106 g_ptr_array_add (module->subprogram_mds, md);
9110 g_free (source_file);
9111 g_free (sym_seq_points);
9117 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9119 MonoCompile *cfg = ctx->cfg;
9121 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9122 MonoDebugSourceLocation *loc;
9123 LLVMValueRef loc_md;
9125 loc = mono_debug_method_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9128 #if LLVM_API_VERSION > 100
9129 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9130 mono_llvm_di_set_location (builder, loc_md);
9132 LLVMValueRef md_args [16];
9136 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9137 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9138 md_args [nmd_args ++] = ctx->dbg_md;
9139 md_args [nmd_args ++] = NULL;
9140 loc_md = LLVMMDNode (md_args, nmd_args);
9141 LLVMSetCurrentDebugLocation (builder, loc_md);
9143 mono_debug_free_source_location (loc);
9149 default_mono_llvm_unhandled_exception (void)
9151 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9152 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9154 mono_unhandled_exception (target);
9155 mono_invoke_unhandled_exception_hook (target);
9156 g_assert_not_reached ();
9161 - Emit LLVM IR from the mono IR using the LLVM C API.
9162 - The original arch specific code remains, so we can fall back to it if we run
9163 into something we can't handle.
9167 A partial list of issues:
9168 - Handling of opcodes which can throw exceptions.
9170 In the mono JIT, these are implemented using code like this:
9177 push throw_pos - method
9178 call <exception trampoline>
9180 The problematic part is push throw_pos - method, which cannot be represented
9181 in the LLVM IR, since it does not support label values.
9182 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9183 be implemented in JIT mode ?
9184 -> a possible but slower implementation would use the normal exception
9185 throwing code but it would need to control the placement of the throw code
9186 (it needs to be exactly after the compare+branch).
9187 -> perhaps add a PC offset intrinsics ?
9189 - efficient implementation of .ovf opcodes.
9191 These are currently implemented as:
9192 <ins which sets the condition codes>
9195 Some overflow opcodes are now supported by LLVM SVN.
9197 - exception handling, unwinding.
9198 - SSA is disabled for methods with exception handlers
9199 - How to obtain unwind info for LLVM compiled methods ?
9200 -> this is now solved by converting the unwind info generated by LLVM
9202 - LLVM uses the c++ exception handling framework, while we use our home grown
9203 code, and couldn't use the c++ one:
9204 - its not supported under VC++, other exotic platforms.
9205 - it might be impossible to support filter clauses with it.
9209 The trampolines need a predictable call sequence, since they need to disasm
9210 the calling code to obtain register numbers / offsets.
9212 LLVM currently generates this code in non-JIT mode:
9213 mov -0x98(%rax),%eax
9215 Here, the vtable pointer is lost.
9216 -> solution: use one vtable trampoline per class.
9218 - passing/receiving the IMT pointer/RGCTX.
9219 -> solution: pass them as normal arguments ?
9223 LLVM does not allow the specification of argument registers etc. This means
9224 that all calls are made according to the platform ABI.
9226 - passing/receiving vtypes.
9228 Vtypes passed/received in registers are handled by the front end by using
9229 a signature with scalar arguments, and loading the parts of the vtype into those
9232 Vtypes passed on the stack are handled using the 'byval' attribute.
9236 Supported though alloca, we need to emit the load/store code.
9240 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9241 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9242 This is made easier because the IR is already in SSA form.
9243 An additional problem is that our IR is not consistent with types, i.e. i32/i64
9244 types are frequently used incorrectly.
9249 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9250 it with the file containing the methods emitted by the JIT and the AOT data
9254 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9255 * - each bblock should end with a branch
9256 * - setting the return value, making cfg->ret non-volatile
9257 * - avoid some transformations in the JIT which make it harder for us to generate
9259 * - use pointer types to help optimizations.
9262 #else /* DISABLE_JIT */
9265 mono_llvm_cleanup (void)
9270 mono_llvm_free_domain_info (MonoDomain *domain)
9275 mono_llvm_init (void)
9280 default_mono_llvm_unhandled_exception (void)
9284 #endif /* DISABLE_JIT */