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)
470 t = mini_get_underlying_type (t);
474 return LLVMVoidType ();
476 return LLVMInt8Type ();
478 return LLVMInt16Type ();
480 return LLVMInt32Type ();
482 return LLVMInt8Type ();
484 return LLVMInt16Type ();
486 return LLVMInt32Type ();
489 return LLVMInt64Type ();
491 return LLVMFloatType ();
493 return LLVMDoubleType ();
496 return IntPtrType ();
497 case MONO_TYPE_OBJECT:
499 return ObjRefType ();
502 /* Because of generic sharing */
503 return ObjRefType ();
504 case MONO_TYPE_GENERICINST:
505 if (!mono_type_generic_inst_is_valuetype (t))
506 return ObjRefType ();
508 case MONO_TYPE_VALUETYPE:
509 case MONO_TYPE_TYPEDBYREF: {
513 klass = mono_class_from_mono_type (t);
515 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
516 return simd_class_to_llvm_type (ctx, klass);
519 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
521 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
523 ltype = create_llvm_type_for_type (ctx->module, klass);
524 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
530 printf ("X: %d\n", t->type);
531 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
532 ctx->cfg->disable_llvm = TRUE;
540 * Return whenever T is an unsigned int type.
543 type_is_unsigned (EmitContext *ctx, MonoType *t)
545 t = mini_get_underlying_type (t);
561 * type_to_llvm_arg_type:
563 * Same as type_to_llvm_type, but treat i8/i16 as i32.
566 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
568 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
570 if (ctx->cfg->llvm_only)
574 * This works on all abis except arm64/ios which passes multiple
575 * arguments in one stack slot.
578 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
580 * LLVM generates code which only sets the lower bits, while JITted
581 * code expects all the bits to be set.
583 ptype = LLVMInt32Type ();
591 * llvm_type_to_stack_type:
593 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
596 static G_GNUC_UNUSED LLVMTypeRef
597 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
601 if (type == LLVMInt8Type ())
602 return LLVMInt32Type ();
603 else if (type == LLVMInt16Type ())
604 return LLVMInt32Type ();
605 else if (!cfg->r4fp && type == LLVMFloatType ())
606 return LLVMDoubleType ();
612 * regtype_to_llvm_type:
614 * Return the LLVM type corresponding to the regtype C used in instruction
618 regtype_to_llvm_type (char c)
622 return LLVMInt32Type ();
624 return LLVMInt64Type ();
626 return LLVMDoubleType ();
635 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
638 op_to_llvm_type (int opcode)
643 return LLVMInt8Type ();
646 return LLVMInt8Type ();
649 return LLVMInt16Type ();
652 return LLVMInt16Type ();
655 return LLVMInt32Type ();
658 return LLVMInt32Type ();
660 return LLVMInt64Type ();
662 return LLVMFloatType ();
664 return LLVMDoubleType ();
666 return LLVMInt64Type ();
668 return LLVMInt32Type ();
670 return LLVMInt64Type ();
675 return LLVMInt8Type ();
680 return LLVMInt16Type ();
682 return LLVMInt32Type ();
685 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
692 return LLVMInt32Type ();
699 return LLVMInt64Type ();
701 printf ("%s\n", mono_inst_name (opcode));
702 g_assert_not_reached ();
707 #define CLAUSE_START(clause) ((clause)->try_offset)
708 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
711 * load_store_to_llvm_type:
713 * Return the size/sign/zero extension corresponding to the load/store opcode
717 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
723 case OP_LOADI1_MEMBASE:
724 case OP_STOREI1_MEMBASE_REG:
725 case OP_STOREI1_MEMBASE_IMM:
726 case OP_ATOMIC_LOAD_I1:
727 case OP_ATOMIC_STORE_I1:
730 return LLVMInt8Type ();
731 case OP_LOADU1_MEMBASE:
733 case OP_ATOMIC_LOAD_U1:
734 case OP_ATOMIC_STORE_U1:
737 return LLVMInt8Type ();
738 case OP_LOADI2_MEMBASE:
739 case OP_STOREI2_MEMBASE_REG:
740 case OP_STOREI2_MEMBASE_IMM:
741 case OP_ATOMIC_LOAD_I2:
742 case OP_ATOMIC_STORE_I2:
745 return LLVMInt16Type ();
746 case OP_LOADU2_MEMBASE:
748 case OP_ATOMIC_LOAD_U2:
749 case OP_ATOMIC_STORE_U2:
752 return LLVMInt16Type ();
753 case OP_LOADI4_MEMBASE:
754 case OP_LOADU4_MEMBASE:
757 case OP_STOREI4_MEMBASE_REG:
758 case OP_STOREI4_MEMBASE_IMM:
759 case OP_ATOMIC_LOAD_I4:
760 case OP_ATOMIC_STORE_I4:
761 case OP_ATOMIC_LOAD_U4:
762 case OP_ATOMIC_STORE_U4:
764 return LLVMInt32Type ();
765 case OP_LOADI8_MEMBASE:
767 case OP_STOREI8_MEMBASE_REG:
768 case OP_STOREI8_MEMBASE_IMM:
769 case OP_ATOMIC_LOAD_I8:
770 case OP_ATOMIC_STORE_I8:
771 case OP_ATOMIC_LOAD_U8:
772 case OP_ATOMIC_STORE_U8:
774 return LLVMInt64Type ();
775 case OP_LOADR4_MEMBASE:
776 case OP_STORER4_MEMBASE_REG:
777 case OP_ATOMIC_LOAD_R4:
778 case OP_ATOMIC_STORE_R4:
780 return LLVMFloatType ();
781 case OP_LOADR8_MEMBASE:
782 case OP_STORER8_MEMBASE_REG:
783 case OP_ATOMIC_LOAD_R8:
784 case OP_ATOMIC_STORE_R8:
786 return LLVMDoubleType ();
787 case OP_LOAD_MEMBASE:
789 case OP_STORE_MEMBASE_REG:
790 case OP_STORE_MEMBASE_IMM:
791 *size = sizeof (gpointer);
792 return IntPtrType ();
794 g_assert_not_reached ();
802 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
805 ovf_op_to_intrins (int opcode)
809 return "llvm.sadd.with.overflow.i32";
811 return "llvm.uadd.with.overflow.i32";
813 return "llvm.ssub.with.overflow.i32";
815 return "llvm.usub.with.overflow.i32";
817 return "llvm.smul.with.overflow.i32";
819 return "llvm.umul.with.overflow.i32";
821 return "llvm.sadd.with.overflow.i64";
823 return "llvm.uadd.with.overflow.i64";
825 return "llvm.ssub.with.overflow.i64";
827 return "llvm.usub.with.overflow.i64";
829 return "llvm.smul.with.overflow.i64";
831 return "llvm.umul.with.overflow.i64";
833 g_assert_not_reached ();
839 simd_op_to_intrins (int opcode)
842 #if defined(TARGET_X86) || defined(TARGET_AMD64)
844 return "llvm.x86.sse2.min.pd";
846 return "llvm.x86.sse.min.ps";
848 return "llvm.x86.sse2.max.pd";
850 return "llvm.x86.sse.max.ps";
852 return "llvm.x86.sse3.hadd.pd";
854 return "llvm.x86.sse3.hadd.ps";
856 return "llvm.x86.sse3.hsub.pd";
858 return "llvm.x86.sse3.hsub.ps";
860 return "llvm.x86.sse3.addsub.ps";
862 return "llvm.x86.sse3.addsub.pd";
863 case OP_EXTRACT_MASK:
864 return "llvm.x86.sse2.pmovmskb.128";
867 return "llvm.x86.sse2.psrli.w";
870 return "llvm.x86.sse2.psrli.d";
873 return "llvm.x86.sse2.psrli.q";
876 return "llvm.x86.sse2.pslli.w";
879 return "llvm.x86.sse2.pslli.d";
882 return "llvm.x86.sse2.pslli.q";
885 return "llvm.x86.sse2.psrai.w";
888 return "llvm.x86.sse2.psrai.d";
890 return "llvm.x86.sse2.padds.b";
892 return "llvm.x86.sse2.padds.w";
894 return "llvm.x86.sse2.psubs.b";
896 return "llvm.x86.sse2.psubs.w";
897 case OP_PADDB_SAT_UN:
898 return "llvm.x86.sse2.paddus.b";
899 case OP_PADDW_SAT_UN:
900 return "llvm.x86.sse2.paddus.w";
901 case OP_PSUBB_SAT_UN:
902 return "llvm.x86.sse2.psubus.b";
903 case OP_PSUBW_SAT_UN:
904 return "llvm.x86.sse2.psubus.w";
906 return "llvm.x86.sse2.pavg.b";
908 return "llvm.x86.sse2.pavg.w";
910 return "llvm.x86.sse.sqrt.ps";
912 return "llvm.x86.sse2.sqrt.pd";
914 return "llvm.x86.sse.rsqrt.ps";
916 return "llvm.x86.sse.rcp.ps";
918 return "llvm.x86.sse2.cvtdq2pd";
920 return "llvm.x86.sse2.cvtdq2ps";
922 return "llvm.x86.sse2.cvtpd2dq";
924 return "llvm.x86.sse2.cvtps2dq";
926 return "llvm.x86.sse2.cvtpd2ps";
928 return "llvm.x86.sse2.cvtps2pd";
930 return "llvm.x86.sse2.cvttpd2dq";
932 return "llvm.x86.sse2.cvttps2dq";
934 return "llvm.x86.sse2.packsswb.128";
936 return "llvm.x86.sse2.packssdw.128";
938 return "llvm.x86.sse2.packuswb.128";
940 return "llvm.x86.sse41.packusdw";
942 return "llvm.x86.sse2.pmulh.w";
943 case OP_PMULW_HIGH_UN:
944 return "llvm.x86.sse2.pmulhu.w";
946 return "llvm.x86.sse41.dpps";
949 g_assert_not_reached ();
955 simd_op_to_llvm_type (int opcode)
957 #if defined(TARGET_X86) || defined(TARGET_AMD64)
961 return type_to_simd_type (MONO_TYPE_R8);
964 return type_to_simd_type (MONO_TYPE_I8);
967 return type_to_simd_type (MONO_TYPE_I4);
972 return type_to_simd_type (MONO_TYPE_I2);
976 return type_to_simd_type (MONO_TYPE_I1);
978 return type_to_simd_type (MONO_TYPE_R4);
981 return type_to_simd_type (MONO_TYPE_I4);
985 return type_to_simd_type (MONO_TYPE_R8);
989 return type_to_simd_type (MONO_TYPE_R4);
990 case OP_EXTRACT_MASK:
991 return type_to_simd_type (MONO_TYPE_I1);
997 return type_to_simd_type (MONO_TYPE_R4);
1000 return type_to_simd_type (MONO_TYPE_R8);
1002 g_assert_not_reached ();
1013 * Return the LLVM basic block corresponding to BB.
1015 static LLVMBasicBlockRef
1016 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1018 char bb_name_buf [128];
1021 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1022 if (bb->flags & BB_EXCEPTION_HANDLER) {
1023 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1024 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1025 bb_name = bb_name_buf;
1026 } else if (bb->block_num < 256) {
1027 if (!ctx->module->bb_names) {
1028 ctx->module->bb_names_len = 256;
1029 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1031 if (!ctx->module->bb_names [bb->block_num]) {
1034 n = g_strdup_printf ("BB%d", bb->block_num);
1035 mono_memory_barrier ();
1036 ctx->module->bb_names [bb->block_num] = n;
1038 bb_name = ctx->module->bb_names [bb->block_num];
1040 sprintf (bb_name_buf, "BB%d", bb->block_num);
1041 bb_name = bb_name_buf;
1044 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1045 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1048 return ctx->bblocks [bb->block_num].bblock;
1054 * Return the last LLVM bblock corresponding to BB.
1055 * This might not be equal to the bb returned by get_bb () since we need to generate
1056 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1058 static LLVMBasicBlockRef
1059 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1062 return ctx->bblocks [bb->block_num].end_bblock;
1065 static LLVMBasicBlockRef
1066 gen_bb (EmitContext *ctx, const char *prefix)
1070 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1071 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1077 * Return the target of the patch identified by TYPE and TARGET.
1080 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1086 memset (&ji, 0, sizeof (ji));
1088 ji.data.target = target;
1090 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1091 mono_error_assert_ok (&error);
1099 * Emit code to convert the LLVM value V to DTYPE.
1102 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1104 LLVMTypeRef stype = LLVMTypeOf (v);
1106 if (stype != dtype) {
1107 gboolean ext = FALSE;
1110 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1112 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1114 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1118 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1120 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1121 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1124 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1125 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1126 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1127 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1128 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1129 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1130 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1131 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1133 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1134 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1135 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1136 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1137 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1138 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1140 if (mono_arch_is_soft_float ()) {
1141 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1142 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1143 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1144 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1147 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1148 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1151 LLVMDumpValue (LLVMConstNull (dtype));
1152 g_assert_not_reached ();
1160 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1162 return convert_full (ctx, v, dtype, FALSE);
1166 * emit_volatile_load:
1168 * If vreg is volatile, emit a load from its address.
1171 emit_volatile_load (EmitContext *ctx, int vreg)
1177 // FIXME: This hack is required because we pass the rgctx in a callee saved
1178 // register on arm64 (x15), and llvm might keep the value in that register
1179 // even through the register is marked as 'reserved' inside llvm.
1180 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1181 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1183 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1185 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1187 t = ctx->vreg_cli_types [vreg];
1188 if (t && !t->byref) {
1190 * Might have to zero extend since llvm doesn't have
1193 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1194 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1195 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1196 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1197 else if (t->type == MONO_TYPE_U8)
1198 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1205 * emit_volatile_store:
1207 * If VREG is volatile, emit a store from its value to its address.
1210 emit_volatile_store (EmitContext *ctx, int vreg)
1212 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1214 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1215 g_assert (ctx->addresses [vreg]);
1216 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1221 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1223 LLVMTypeRef ret_type;
1224 LLVMTypeRef *param_types = NULL;
1229 rtype = mini_get_underlying_type (sig->ret);
1230 ret_type = type_to_llvm_type (ctx, rtype);
1234 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1238 param_types [pindex ++] = ThisType ();
1239 for (i = 0; i < sig->param_count; ++i)
1240 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1242 if (!ctx_ok (ctx)) {
1243 g_free (param_types);
1247 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1248 g_free (param_types);
1254 * sig_to_llvm_sig_full:
1256 * Return the LLVM signature corresponding to the mono signature SIG using the
1257 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1260 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1262 LLVMTypeRef ret_type;
1263 LLVMTypeRef *param_types = NULL;
1265 int i, j, pindex, vret_arg_pindex = 0;
1266 gboolean vretaddr = FALSE;
1270 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1272 rtype = mini_get_underlying_type (sig->ret);
1273 ret_type = type_to_llvm_type (ctx, rtype);
1277 switch (cinfo->ret.storage) {
1278 case LLVMArgVtypeInReg:
1279 /* LLVM models this by returning an aggregate value */
1280 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1281 LLVMTypeRef members [2];
1283 members [0] = IntPtrType ();
1284 ret_type = LLVMStructType (members, 1, FALSE);
1285 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1287 ret_type = LLVMVoidType ();
1288 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1289 LLVMTypeRef members [2];
1291 members [0] = IntPtrType ();
1292 members [1] = IntPtrType ();
1293 ret_type = LLVMStructType (members, 2, FALSE);
1295 g_assert_not_reached ();
1298 case LLVMArgVtypeByVal:
1299 /* Vtype returned normally by val */
1301 case LLVMArgVtypeAsScalar: {
1302 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1303 /* LLVM models this by returning an int */
1304 if (size < SIZEOF_VOID_P) {
1305 g_assert (cinfo->ret.nslots == 1);
1306 ret_type = LLVMIntType (size * 8);
1308 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1309 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1313 case LLVMArgAsIArgs:
1314 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1316 case LLVMArgFpStruct: {
1317 /* Vtype returned as a fp struct */
1318 LLVMTypeRef members [16];
1320 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1321 for (i = 0; i < cinfo->ret.nslots; ++i)
1322 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1323 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1326 case LLVMArgVtypeByRef:
1327 /* Vtype returned using a hidden argument */
1328 ret_type = LLVMVoidType ();
1330 case LLVMArgVtypeRetAddr:
1331 case LLVMArgGsharedvtFixed:
1332 case LLVMArgGsharedvtFixedVtype:
1333 case LLVMArgGsharedvtVariable:
1335 ret_type = LLVMVoidType ();
1341 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1343 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1345 * Has to be the first argument because of the sret argument attribute
1346 * FIXME: This might conflict with passing 'this' as the first argument, but
1347 * this is only used on arm64 which has a dedicated struct return register.
1349 cinfo->vret_arg_pindex = pindex;
1350 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1351 if (!ctx_ok (ctx)) {
1352 g_free (param_types);
1355 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1358 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1359 cinfo->rgctx_arg_pindex = pindex;
1360 param_types [pindex] = ctx->module->ptr_type;
1363 if (cinfo->imt_arg) {
1364 cinfo->imt_arg_pindex = pindex;
1365 param_types [pindex] = ctx->module->ptr_type;
1369 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1370 vret_arg_pindex = pindex;
1371 if (cinfo->vret_arg_index == 1) {
1372 /* Add the slots consumed by the first argument */
1373 LLVMArgInfo *ainfo = &cinfo->args [0];
1374 switch (ainfo->storage) {
1375 case LLVMArgVtypeInReg:
1376 for (j = 0; j < 2; ++j) {
1377 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1386 cinfo->vret_arg_pindex = vret_arg_pindex;
1389 if (vretaddr && vret_arg_pindex == pindex)
1390 param_types [pindex ++] = IntPtrType ();
1392 cinfo->this_arg_pindex = pindex;
1393 param_types [pindex ++] = ThisType ();
1394 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1396 if (vretaddr && vret_arg_pindex == pindex)
1397 param_types [pindex ++] = IntPtrType ();
1398 for (i = 0; i < sig->param_count; ++i) {
1399 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1401 if (vretaddr && vret_arg_pindex == pindex)
1402 param_types [pindex ++] = IntPtrType ();
1403 ainfo->pindex = pindex;
1405 switch (ainfo->storage) {
1406 case LLVMArgVtypeInReg:
1407 for (j = 0; j < 2; ++j) {
1408 switch (ainfo->pair_storage [j]) {
1410 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1415 g_assert_not_reached ();
1419 case LLVMArgVtypeByVal:
1420 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1423 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1426 case LLVMArgAsIArgs:
1427 if (ainfo->esize == 8)
1428 param_types [pindex] = LLVMArrayType (LLVMInt64Type (), ainfo->nslots);
1430 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1433 case LLVMArgVtypeByRef:
1434 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1437 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1440 case LLVMArgAsFpArgs: {
1443 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1444 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1445 param_types [pindex ++] = LLVMDoubleType ();
1446 for (j = 0; j < ainfo->nslots; ++j)
1447 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1450 case LLVMArgVtypeAsScalar:
1451 g_assert_not_reached ();
1453 case LLVMArgGsharedvtFixed:
1454 case LLVMArgGsharedvtFixedVtype:
1455 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1457 case LLVMArgGsharedvtVariable:
1458 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1461 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1465 if (!ctx_ok (ctx)) {
1466 g_free (param_types);
1469 if (vretaddr && vret_arg_pindex == pindex)
1470 param_types [pindex ++] = IntPtrType ();
1471 if (ctx->llvm_only && cinfo->rgctx_arg) {
1472 /* Pass the rgctx as the last argument */
1473 cinfo->rgctx_arg_pindex = pindex;
1474 param_types [pindex] = ctx->module->ptr_type;
1478 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1479 g_free (param_types);
1485 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1487 return sig_to_llvm_sig_full (ctx, sig, NULL);
1491 * LLVMFunctionType1:
1493 * Create an LLVM function type from the arguments.
1495 static G_GNUC_UNUSED LLVMTypeRef
1496 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1499 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1503 * LLVMFunctionType1:
1505 * Create an LLVM function type from the arguments.
1507 static G_GNUC_UNUSED LLVMTypeRef
1508 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1509 LLVMTypeRef ParamType1,
1512 LLVMTypeRef param_types [1];
1514 param_types [0] = ParamType1;
1516 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1520 * LLVMFunctionType2:
1522 * Create an LLVM function type from the arguments.
1524 static G_GNUC_UNUSED LLVMTypeRef
1525 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1526 LLVMTypeRef ParamType1,
1527 LLVMTypeRef ParamType2,
1530 LLVMTypeRef param_types [2];
1532 param_types [0] = ParamType1;
1533 param_types [1] = ParamType2;
1535 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1539 * LLVMFunctionType3:
1541 * Create an LLVM function type from the arguments.
1543 static G_GNUC_UNUSED LLVMTypeRef
1544 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1545 LLVMTypeRef ParamType1,
1546 LLVMTypeRef ParamType2,
1547 LLVMTypeRef ParamType3,
1550 LLVMTypeRef param_types [3];
1552 param_types [0] = ParamType1;
1553 param_types [1] = ParamType2;
1554 param_types [2] = ParamType3;
1556 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1559 static G_GNUC_UNUSED LLVMTypeRef
1560 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1561 LLVMTypeRef ParamType1,
1562 LLVMTypeRef ParamType2,
1563 LLVMTypeRef ParamType3,
1564 LLVMTypeRef ParamType4,
1565 LLVMTypeRef ParamType5,
1568 LLVMTypeRef param_types [5];
1570 param_types [0] = ParamType1;
1571 param_types [1] = ParamType2;
1572 param_types [2] = ParamType3;
1573 param_types [3] = ParamType4;
1574 param_types [4] = ParamType5;
1576 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1582 * Create an LLVM builder and remember it so it can be freed later.
1584 static LLVMBuilderRef
1585 create_builder (EmitContext *ctx)
1587 LLVMBuilderRef builder = LLVMCreateBuilder ();
1589 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1595 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1600 case MONO_PATCH_INFO_INTERNAL_METHOD:
1601 name = g_strdup_printf ("jit_icall_%s", data);
1603 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1604 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1605 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1609 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1617 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1621 LLVMValueRef indexes [2];
1622 LLVMValueRef got_entry_addr, load;
1623 LLVMBuilderRef builder = ctx->builder;
1628 MonoJumpInfo tmp_ji;
1630 tmp_ji.data.target = data;
1632 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1634 ji->next = cfg->patch_info;
1635 cfg->patch_info = ji;
1637 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1638 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1640 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1641 * explicitly initialize it.
1643 if (!mono_aot_is_shared_got_offset (got_offset)) {
1644 //mono_print_ji (ji);
1646 ctx->has_got_access = TRUE;
1649 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1650 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1651 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1653 name = get_aotconst_name (type, data, got_offset);
1655 load = LLVMBuildLoad (builder, got_entry_addr, "");
1656 load = convert (ctx, load, llvm_type);
1657 LLVMSetValueName (load, name ? name : "");
1659 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1662 //set_invariant_load_flag (load);
1668 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1670 return get_aotconst_typed (ctx, type, data, NULL);
1674 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1676 LLVMValueRef callee;
1678 if (ctx->llvm_only) {
1679 callee_name = mono_aot_get_direct_call_symbol (type, data);
1681 /* Directly callable */
1683 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1685 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1687 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1689 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1691 /* LLVMTypeRef's are uniqued */
1692 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1693 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1695 g_free (callee_name);
1701 * Calls are made through the GOT.
1703 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1705 MonoJumpInfo *ji = NULL;
1707 callee_name = mono_aot_get_plt_symbol (type, data);
1711 if (ctx->cfg->compile_aot)
1712 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1713 mono_add_patch_info (ctx->cfg, 0, type, data);
1716 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1718 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1720 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1722 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1725 if (ctx->cfg->compile_aot) {
1726 ji = g_new0 (MonoJumpInfo, 1);
1728 ji->data.target = data;
1730 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1738 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1740 #if LLVM_API_VERSION > 100
1741 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1742 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1743 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1744 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1747 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1748 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1754 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1756 MonoMethodHeader *header = cfg->header;
1757 MonoExceptionClause *clause;
1761 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1762 return (bb->region >> 8) - 1;
1765 for (i = 0; i < header->num_clauses; ++i) {
1766 clause = &header->clauses [i];
1768 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1775 static MonoExceptionClause *
1776 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1778 if (bb == cfg->bb_init)
1780 // Since they're sorted by nesting we just need
1781 // the first one that the bb is a member of
1782 for (int i = 0; i < cfg->header->num_clauses; i++) {
1783 MonoExceptionClause *curr = &cfg->header->clauses [i];
1785 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1793 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1795 LLVMValueRef md_arg;
1798 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1799 md_arg = LLVMMDString ("mono", 4);
1800 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1804 set_invariant_load_flag (LLVMValueRef v)
1806 LLVMValueRef md_arg;
1808 const char *flag_name;
1810 // FIXME: Cache this
1811 flag_name = "invariant.load";
1812 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1813 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1814 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1820 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1824 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1826 MonoCompile *cfg = ctx->cfg;
1827 LLVMValueRef lcall = NULL;
1828 LLVMBuilderRef builder = *builder_ref;
1829 MonoExceptionClause *clause;
1831 if (ctx->llvm_only) {
1832 clause = get_most_deep_clause (cfg, ctx, bb);
1835 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause->flags == MONO_EXCEPTION_CLAUSE_FAULT);
1838 * Have to use an invoke instead of a call, branching to the
1839 * handler bblock of the clause containing this bblock.
1841 intptr_t key = CLAUSE_END(clause);
1843 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1845 // FIXME: Find the one that has the lowest end bound for the right start address
1846 // FIXME: Finally + nesting
1849 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1852 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1854 builder = ctx->builder = create_builder (ctx);
1855 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1857 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1861 int clause_index = get_handler_clause (cfg, bb);
1863 if (clause_index != -1) {
1864 MonoMethodHeader *header = cfg->header;
1865 MonoExceptionClause *ec = &header->clauses [clause_index];
1866 MonoBasicBlock *tblock;
1867 LLVMBasicBlockRef ex_bb, noex_bb;
1870 * Have to use an invoke instead of a call, branching to the
1871 * handler bblock of the clause containing this bblock.
1874 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY || ec->flags == MONO_EXCEPTION_CLAUSE_FAULT);
1876 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1879 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1881 ex_bb = get_bb (ctx, tblock);
1883 noex_bb = gen_bb (ctx, "NOEX_BB");
1886 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1888 builder = ctx->builder = create_builder (ctx);
1889 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1891 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1896 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1897 ctx->builder = builder;
1901 *builder_ref = ctx->builder;
1907 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1909 const char *intrins_name;
1910 LLVMValueRef args [16], res;
1911 LLVMTypeRef addr_type;
1912 gboolean use_intrinsics = TRUE;
1914 #if LLVM_API_VERSION > 100
1915 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1916 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1919 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1920 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1921 *builder_ref = ctx->builder;
1922 use_intrinsics = FALSE;
1926 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1927 LLVMAtomicOrdering ordering;
1930 case LLVM_BARRIER_NONE:
1931 ordering = LLVMAtomicOrderingNotAtomic;
1933 case LLVM_BARRIER_ACQ:
1934 ordering = LLVMAtomicOrderingAcquire;
1936 case LLVM_BARRIER_SEQ:
1937 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1940 g_assert_not_reached ();
1945 * We handle loads which can fault by calling a mono specific intrinsic
1946 * using an invoke, so they are handled properly inside try blocks.
1947 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1948 * are marked with IntrReadArgMem.
1952 intrins_name = "llvm.mono.load.i8.p0i8";
1955 intrins_name = "llvm.mono.load.i16.p0i16";
1958 intrins_name = "llvm.mono.load.i32.p0i32";
1961 intrins_name = "llvm.mono.load.i64.p0i64";
1964 g_assert_not_reached ();
1967 addr_type = LLVMTypeOf (addr);
1968 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1969 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1972 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1973 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1974 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1975 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1977 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1978 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1979 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1980 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1987 * We emit volatile loads for loads which can fault, because otherwise
1988 * LLVM will generate invalid code when encountering a load from a
1991 if (barrier != LLVM_BARRIER_NONE)
1992 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1994 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1996 /* Mark it with a custom metadata */
1999 set_metadata_flag (res, "mono.faulting.load");
2007 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
2009 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
2013 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
2015 const char *intrins_name;
2016 LLVMValueRef args [16];
2017 gboolean use_intrinsics = TRUE;
2019 #if LLVM_API_VERSION > 100
2020 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
2021 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2022 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
2023 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
2024 *builder_ref = ctx->builder;
2025 use_intrinsics = FALSE;
2029 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2030 LLVMAtomicOrdering ordering;
2033 case LLVM_BARRIER_NONE:
2034 ordering = LLVMAtomicOrderingNotAtomic;
2036 case LLVM_BARRIER_REL:
2037 ordering = LLVMAtomicOrderingRelease;
2039 case LLVM_BARRIER_SEQ:
2040 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2043 g_assert_not_reached ();
2049 intrins_name = "llvm.mono.store.i8.p0i8";
2052 intrins_name = "llvm.mono.store.i16.p0i16";
2055 intrins_name = "llvm.mono.store.i32.p0i32";
2058 intrins_name = "llvm.mono.store.i64.p0i64";
2061 g_assert_not_reached ();
2064 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2065 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2066 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2071 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2072 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2073 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2074 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2076 if (barrier != LLVM_BARRIER_NONE)
2077 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2079 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2084 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2086 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2090 * emit_cond_system_exception:
2092 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2093 * Might set the ctx exception.
2096 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2098 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2099 LLVMBuilderRef builder;
2100 MonoClass *exc_class;
2101 LLVMValueRef args [2];
2102 LLVMValueRef callee;
2103 gboolean no_pc = FALSE;
2105 if (IS_TARGET_AMD64)
2106 /* Some platforms don't require the pc argument */
2109 ex_bb = gen_bb (ctx, "EX_BB");
2111 ex2_bb = gen_bb (ctx, "EX2_BB");
2112 noex_bb = gen_bb (ctx, "NOEX_BB");
2114 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2116 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2118 /* Emit exception throwing code */
2119 ctx->builder = builder = create_builder (ctx);
2120 LLVMPositionBuilderAtEnd (builder, ex_bb);
2122 if (ctx->cfg->llvm_only) {
2123 static LLVMTypeRef sig;
2126 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2127 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2129 LLVMBuildBr (builder, ex2_bb);
2131 ctx->builder = builder = create_builder (ctx);
2132 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2134 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2135 emit_call (ctx, bb, &builder, callee, args, 1);
2136 LLVMBuildUnreachable (builder);
2138 ctx->builder = builder = create_builder (ctx);
2139 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2141 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2147 callee = ctx->module->throw_corlib_exception;
2150 const char *icall_name;
2153 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2155 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2156 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2158 if (ctx->cfg->compile_aot) {
2159 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2162 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2163 * - On x86, LLVM generated code doesn't push the arguments
2164 * - The trampoline takes the throw address as an arguments, not a pc offset.
2166 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2167 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2169 #if LLVM_API_VERSION > 100
2171 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2172 * added by emit_jit_callee ().
2174 ex2_bb = gen_bb (ctx, "EX2_BB");
2175 LLVMBuildBr (builder, ex2_bb);
2178 ctx->builder = builder = create_builder (ctx);
2179 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2181 mono_memory_barrier ();
2182 ctx->module->throw_corlib_exception = callee;
2187 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2190 * The LLVM mono branch contains changes so a block address can be passed as an
2191 * argument to a call.
2194 emit_call (ctx, bb, &builder, callee, args, 1);
2196 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2197 emit_call (ctx, bb, &builder, callee, args, 2);
2200 LLVMBuildUnreachable (builder);
2202 ctx->builder = builder = create_builder (ctx);
2203 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2205 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2212 * emit_args_to_vtype:
2214 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2217 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2219 int j, size, nslots;
2221 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2223 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2224 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2227 if (ainfo->storage == LLVMArgAsFpArgs)
2228 nslots = ainfo->nslots;
2232 for (j = 0; j < nslots; ++j) {
2233 LLVMValueRef index [2], addr, daddr;
2234 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2235 LLVMTypeRef part_type;
2237 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2240 if (ainfo->pair_storage [j] == LLVMArgNone)
2243 switch (ainfo->pair_storage [j]) {
2244 case LLVMArgInIReg: {
2245 part_type = LLVMIntType (part_size * 8);
2246 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2247 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2248 addr = LLVMBuildGEP (builder, address, index, 1, "");
2250 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2251 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2252 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2254 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2257 case LLVMArgInFPReg: {
2258 LLVMTypeRef arg_type;
2260 if (ainfo->esize == 8)
2261 arg_type = LLVMDoubleType ();
2263 arg_type = LLVMFloatType ();
2265 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2266 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2267 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2268 LLVMBuildStore (builder, args [j], addr);
2274 g_assert_not_reached ();
2277 size -= sizeof (gpointer);
2282 * emit_vtype_to_args:
2284 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2285 * into ARGS, and the number of arguments into NARGS.
2288 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2291 int j, size, nslots;
2292 LLVMTypeRef arg_type;
2294 size = get_vtype_size (t);
2296 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2297 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2299 if (ainfo->storage == LLVMArgAsFpArgs)
2300 nslots = ainfo->nslots;
2303 for (j = 0; j < nslots; ++j) {
2304 LLVMValueRef index [2], addr, daddr;
2305 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2307 if (ainfo->pair_storage [j] == LLVMArgNone)
2310 switch (ainfo->pair_storage [j]) {
2312 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2313 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2314 addr = LLVMBuildGEP (builder, address, index, 1, "");
2316 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2317 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2318 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2320 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2322 case LLVMArgInFPReg:
2323 if (ainfo->esize == 8)
2324 arg_type = LLVMDoubleType ();
2326 arg_type = LLVMFloatType ();
2327 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2328 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2329 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2330 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2335 g_assert_not_reached ();
2337 size -= sizeof (gpointer);
2344 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2347 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2348 * get executed every time control reaches them.
2350 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2352 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2353 return ctx->last_alloca;
2357 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2359 return build_alloca_llvm_type_name (ctx, t, align, "");
2363 build_alloca (EmitContext *ctx, MonoType *t)
2365 MonoClass *k = mono_class_from_mono_type (t);
2368 g_assert (!mini_is_gsharedvt_variable_type (t));
2370 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2373 align = mono_class_min_align (k);
2375 /* Sometimes align is not a power of 2 */
2376 while (mono_is_power_of_two (align) == -1)
2379 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2383 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2387 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2389 MonoCompile *cfg = ctx->cfg;
2390 LLVMBuilderRef builder = ctx->builder;
2391 LLVMValueRef offset, offset_var;
2392 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2393 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2397 g_assert (info_var);
2398 g_assert (locals_var);
2400 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2402 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2403 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2405 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2406 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2408 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2412 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2415 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2418 module->used = g_ptr_array_sized_new (16);
2419 g_ptr_array_add (module->used, global);
2423 emit_llvm_used (MonoLLVMModule *module)
2425 LLVMModuleRef lmodule = module->lmodule;
2426 LLVMTypeRef used_type;
2427 LLVMValueRef used, *used_elem;
2433 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2434 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2435 used_elem = g_new0 (LLVMValueRef, module->used->len);
2436 for (i = 0; i < module->used->len; ++i)
2437 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2438 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2439 LLVMSetLinkage (used, LLVMAppendingLinkage);
2440 LLVMSetSection (used, "llvm.metadata");
2446 * Emit a function mapping method indexes to their code
2449 emit_get_method (MonoLLVMModule *module)
2451 LLVMModuleRef lmodule = module->lmodule;
2452 LLVMValueRef func, switch_ins, m;
2453 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2454 LLVMBasicBlockRef *bbs;
2456 LLVMBuilderRef builder = LLVMCreateBuilder ();
2461 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2462 * but generating code seems safer.
2464 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2465 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2466 LLVMSetLinkage (func, LLVMExternalLinkage);
2467 LLVMSetVisibility (func, LLVMHiddenVisibility);
2468 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2469 module->get_method = func;
2471 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2474 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2475 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2476 * then we will have to find another solution.
2479 name = g_strdup_printf ("BB_CODE_START");
2480 code_start_bb = LLVMAppendBasicBlock (func, name);
2482 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2483 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2485 name = g_strdup_printf ("BB_CODE_END");
2486 code_end_bb = LLVMAppendBasicBlock (func, name);
2488 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2489 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2491 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2492 for (i = 0; i < module->max_method_idx + 1; ++i) {
2493 name = g_strdup_printf ("BB_%d", i);
2494 bb = LLVMAppendBasicBlock (func, name);
2498 LLVMPositionBuilderAtEnd (builder, bb);
2500 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2502 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2504 LLVMBuildRet (builder, LLVMConstNull (rtype));
2507 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2508 LLVMPositionBuilderAtEnd (builder, fail_bb);
2509 LLVMBuildRet (builder, LLVMConstNull (rtype));
2511 LLVMPositionBuilderAtEnd (builder, entry_bb);
2513 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2514 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2515 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2516 for (i = 0; i < module->max_method_idx + 1; ++i) {
2517 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2520 mark_as_used (module, func);
2522 LLVMDisposeBuilder (builder);
2526 * emit_get_unbox_tramp:
2528 * Emit a function mapping method indexes to their unbox trampoline
2531 emit_get_unbox_tramp (MonoLLVMModule *module)
2533 LLVMModuleRef lmodule = module->lmodule;
2534 LLVMValueRef func, switch_ins, m;
2535 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2536 LLVMBasicBlockRef *bbs;
2538 LLVMBuilderRef builder = LLVMCreateBuilder ();
2542 /* Similar to emit_get_method () */
2544 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2545 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2546 LLVMSetLinkage (func, LLVMExternalLinkage);
2547 LLVMSetVisibility (func, LLVMHiddenVisibility);
2548 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2549 module->get_unbox_tramp = func;
2551 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2553 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2554 for (i = 0; i < module->max_method_idx + 1; ++i) {
2555 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2559 name = g_strdup_printf ("BB_%d", i);
2560 bb = LLVMAppendBasicBlock (func, name);
2564 LLVMPositionBuilderAtEnd (builder, bb);
2566 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2569 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2570 LLVMPositionBuilderAtEnd (builder, fail_bb);
2571 LLVMBuildRet (builder, LLVMConstNull (rtype));
2573 LLVMPositionBuilderAtEnd (builder, entry_bb);
2575 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2576 for (i = 0; i < module->max_method_idx + 1; ++i) {
2577 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2581 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2584 mark_as_used (module, func);
2585 LLVMDisposeBuilder (builder);
2588 /* Add a function to mark the beginning of LLVM code */
2590 emit_llvm_code_start (MonoLLVMModule *module)
2592 LLVMModuleRef lmodule = module->lmodule;
2594 LLVMBasicBlockRef entry_bb;
2595 LLVMBuilderRef builder;
2597 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2598 LLVMSetLinkage (func, LLVMInternalLinkage);
2599 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2600 module->code_start = func;
2601 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2602 builder = LLVMCreateBuilder ();
2603 LLVMPositionBuilderAtEnd (builder, entry_bb);
2604 LLVMBuildRetVoid (builder);
2605 LLVMDisposeBuilder (builder);
2609 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2611 LLVMModuleRef lmodule = module->lmodule;
2612 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2613 LLVMBasicBlockRef entry_bb;
2614 LLVMBuilderRef builder;
2621 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2622 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2627 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2628 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2631 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2632 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2635 g_assert_not_reached ();
2637 LLVMSetLinkage (func, LLVMInternalLinkage);
2638 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2639 mono_llvm_set_preserveall_cc (func);
2640 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2641 builder = LLVMCreateBuilder ();
2642 LLVMPositionBuilderAtEnd (builder, entry_bb);
2645 ji = g_new0 (MonoJumpInfo, 1);
2646 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2647 ji = mono_aot_patch_info_dup (ji);
2648 got_offset = mono_aot_get_got_offset (ji);
2649 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2650 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2651 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2652 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2653 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2654 args [1] = LLVMGetParam (func, 0);
2656 args [2] = LLVMGetParam (func, 1);
2658 ji = g_new0 (MonoJumpInfo, 1);
2659 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2660 ji->data.name = icall_name;
2661 ji = mono_aot_patch_info_dup (ji);
2662 got_offset = mono_aot_get_got_offset (ji);
2663 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2664 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2665 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2666 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2667 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2668 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2669 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2671 // Set the inited flag
2672 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2673 indexes [1] = LLVMGetParam (func, 0);
2674 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2676 LLVMBuildRetVoid (builder);
2678 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2679 LLVMDisposeBuilder (builder);
2684 * Emit wrappers around the C icalls used to initialize llvm methods, to
2685 * make the calling code smaller and to enable usage of the llvm
2686 * PreserveAll calling convention.
2689 emit_init_icall_wrappers (MonoLLVMModule *module)
2691 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2692 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2693 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2694 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2698 emit_llvm_code_end (MonoLLVMModule *module)
2700 LLVMModuleRef lmodule = module->lmodule;
2702 LLVMBasicBlockRef entry_bb;
2703 LLVMBuilderRef builder;
2705 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2706 LLVMSetLinkage (func, LLVMInternalLinkage);
2707 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2708 module->code_end = func;
2709 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2710 builder = LLVMCreateBuilder ();
2711 LLVMPositionBuilderAtEnd (builder, entry_bb);
2712 LLVMBuildRetVoid (builder);
2713 LLVMDisposeBuilder (builder);
2717 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2719 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2722 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2723 need_div_check = TRUE;
2725 if (!need_div_check)
2728 switch (ins->opcode) {
2741 case OP_IDIV_UN_IMM:
2742 case OP_LDIV_UN_IMM:
2743 case OP_IREM_UN_IMM:
2744 case OP_LREM_UN_IMM: {
2746 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2747 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2749 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2750 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2753 builder = ctx->builder;
2755 /* b == -1 && a == 0x80000000 */
2757 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2758 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2759 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2761 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2762 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2765 builder = ctx->builder;
2777 * Emit code to initialize the GOT slots used by the method.
2780 emit_init_method (EmitContext *ctx)
2782 LLVMValueRef indexes [16], args [16], callee;
2783 LLVMValueRef inited_var, cmp, call;
2784 LLVMBasicBlockRef inited_bb, notinited_bb;
2785 LLVMBuilderRef builder = ctx->builder;
2786 MonoCompile *cfg = ctx->cfg;
2788 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2790 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2791 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2792 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2794 args [0] = inited_var;
2795 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2796 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2798 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2800 inited_bb = ctx->inited_bb;
2801 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2803 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2805 builder = ctx->builder = create_builder (ctx);
2806 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2809 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2810 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2811 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2812 callee = ctx->module->init_method_gshared_mrgctx;
2813 call = LLVMBuildCall (builder, callee, args, 2, "");
2814 } else if (ctx->rgctx_arg) {
2815 /* A vtable is passed as the rgctx argument */
2816 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2817 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2818 callee = ctx->module->init_method_gshared_vtable;
2819 call = LLVMBuildCall (builder, callee, args, 2, "");
2820 } else if (cfg->gshared) {
2821 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2822 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2823 callee = ctx->module->init_method_gshared_this;
2824 call = LLVMBuildCall (builder, callee, args, 2, "");
2826 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2827 callee = ctx->module->init_method;
2828 call = LLVMBuildCall (builder, callee, args, 1, "");
2832 * This enables llvm to keep arguments in their original registers/
2833 * scratch registers, since the call will not clobber them.
2835 mono_llvm_set_call_preserveall_cc (call);
2837 LLVMBuildBr (builder, inited_bb);
2838 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2840 builder = ctx->builder = create_builder (ctx);
2841 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2845 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2848 * Emit unbox trampoline using a tail call
2850 LLVMValueRef tramp, call, *args;
2851 LLVMBuilderRef builder;
2852 LLVMBasicBlockRef lbb;
2853 LLVMCallInfo *linfo;
2857 tramp_name = g_strdup_printf ("ut_%s", method_name);
2858 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2859 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2860 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2861 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2863 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2864 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2865 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2866 if (ctx->cfg->vret_addr) {
2867 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2868 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2869 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2870 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2874 lbb = LLVMAppendBasicBlock (tramp, "");
2875 builder = LLVMCreateBuilder ();
2876 LLVMPositionBuilderAtEnd (builder, lbb);
2878 nargs = LLVMCountParamTypes (method_type);
2879 args = g_new0 (LLVMValueRef, nargs);
2880 for (i = 0; i < nargs; ++i) {
2881 args [i] = LLVMGetParam (tramp, i);
2882 if (i == ctx->this_arg_pindex) {
2883 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2885 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2886 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2887 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2890 call = LLVMBuildCall (builder, method, args, nargs, "");
2891 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2892 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2893 if (linfo->ret.storage == LLVMArgVtypeByRef)
2894 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2896 // FIXME: This causes assertions in clang
2897 //mono_llvm_set_must_tail (call);
2898 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2899 LLVMBuildRetVoid (builder);
2901 LLVMBuildRet (builder, call);
2903 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2904 LLVMDisposeBuilder (builder);
2910 * Emit code to load/convert arguments.
2913 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2916 MonoCompile *cfg = ctx->cfg;
2917 MonoMethodSignature *sig = ctx->sig;
2918 LLVMCallInfo *linfo = ctx->linfo;
2922 LLVMBuilderRef old_builder = ctx->builder;
2923 ctx->builder = builder;
2925 ctx->alloca_builder = create_builder (ctx);
2928 * Handle indirect/volatile variables by allocating memory for them
2929 * using 'alloca', and storing their address in a temporary.
2931 for (i = 0; i < cfg->num_varinfo; ++i) {
2932 MonoInst *var = cfg->varinfo [i];
2935 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2936 } 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))) {
2937 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2940 /* Could be already created by an OP_VPHI */
2941 if (!ctx->addresses [var->dreg]) {
2942 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2943 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2945 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2949 names = g_new (char *, sig->param_count);
2950 mono_method_get_param_names (cfg->method, (const char **) names);
2952 for (i = 0; i < sig->param_count; ++i) {
2953 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2954 int reg = cfg->args [i + sig->hasthis]->dreg;
2957 pindex = ainfo->pindex;
2959 switch (ainfo->storage) {
2960 case LLVMArgVtypeInReg:
2961 case LLVMArgAsFpArgs: {
2962 LLVMValueRef args [8];
2965 pindex += ainfo->ndummy_fpargs;
2967 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2968 memset (args, 0, sizeof (args));
2969 if (ainfo->storage == LLVMArgVtypeInReg) {
2970 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2971 if (ainfo->pair_storage [1] != LLVMArgNone)
2972 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2974 g_assert (ainfo->nslots <= 8);
2975 for (j = 0; j < ainfo->nslots; ++j)
2976 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2978 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2980 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2982 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2983 /* Treat these as normal values */
2984 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2988 case LLVMArgVtypeByVal: {
2989 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2991 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2992 /* Treat these as normal values */
2993 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2997 case LLVMArgVtypeByRef: {
2998 /* The argument is passed by ref */
2999 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3002 case LLVMArgAsIArgs: {
3003 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3006 /* The argument is received as an array of ints, store it into the real argument */
3007 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
3009 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
3010 if (size < SIZEOF_VOID_P) {
3011 /* The upper bits of the registers might not be valid */
3012 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
3013 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
3014 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
3016 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
3020 case LLVMArgVtypeAsScalar:
3021 g_assert_not_reached ();
3023 case LLVMArgGsharedvtFixed: {
3024 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3025 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3028 name = g_strdup_printf ("arg_%s", names [i]);
3030 name = g_strdup_printf ("arg_%d", i);
3032 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3035 case LLVMArgGsharedvtFixedVtype: {
3036 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3039 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3041 name = g_strdup_printf ("vtype_arg_%d", i);
3043 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3044 g_assert (ctx->addresses [reg]);
3045 LLVMSetValueName (ctx->addresses [reg], name);
3046 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3049 case LLVMArgGsharedvtVariable:
3050 /* The IR treats these as variables with addresses */
3051 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3054 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));
3061 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3063 emit_volatile_store (ctx, cfg->args [0]->dreg);
3064 for (i = 0; i < sig->param_count; ++i)
3065 if (!mini_type_is_vtype (sig->params [i]))
3066 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3068 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3069 LLVMValueRef this_alloc;
3072 * The exception handling code needs the location where the this argument was
3073 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3074 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3075 * location into the LSDA.
3077 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3078 /* This volatile store will keep the alloca alive */
3079 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3081 set_metadata_flag (this_alloc, "mono.this");
3084 if (cfg->rgctx_var) {
3085 LLVMValueRef rgctx_alloc, store;
3088 * We handle the rgctx arg similarly to the this pointer.
3090 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3091 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3092 /* This volatile store will keep the alloca alive */
3093 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3095 set_metadata_flag (rgctx_alloc, "mono.this");
3098 /* Initialize the method if needed */
3099 if (cfg->compile_aot && ctx->llvm_only) {
3100 /* Emit a location for the initialization code */
3101 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3102 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3104 LLVMBuildBr (ctx->builder, ctx->init_bb);
3105 builder = ctx->builder = create_builder (ctx);
3106 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3107 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3110 /* Compute nesting between clauses */
3111 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3112 for (i = 0; i < cfg->header->num_clauses; ++i) {
3113 for (j = 0; j < cfg->header->num_clauses; ++j) {
3114 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3115 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3117 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3118 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3123 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3124 * it needs to continue normally, or return back to the exception handling system.
3126 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3130 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3133 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3134 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3135 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3137 if (bb->in_scount == 0) {
3140 sprintf (name, "finally_ind_bb%d", bb->block_num);
3141 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3142 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3144 ctx->bblocks [bb->block_num].finally_ind = val;
3146 /* Create a variable to hold the exception var */
3148 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3152 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3153 * LLVM bblock containing a landing pad causes problems for the
3154 * LLVM optimizer passes.
3156 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3157 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3159 ctx->builder = old_builder;
3163 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3165 MonoCompile *cfg = ctx->cfg;
3166 LLVMValueRef *values = ctx->values;
3167 LLVMValueRef *addresses = ctx->addresses;
3168 MonoCallInst *call = (MonoCallInst*)ins;
3169 MonoMethodSignature *sig = call->signature;
3170 LLVMValueRef callee = NULL, lcall;
3172 LLVMCallInfo *cinfo;
3176 LLVMTypeRef llvm_sig;
3178 gboolean is_virtual, calli, preserveall;
3179 LLVMBuilderRef builder = *builder_ref;
3181 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3182 set_failure (ctx, "non-default callconv");
3186 cinfo = call->cinfo;
3188 if (call->rgctx_arg_reg)
3189 cinfo->rgctx_arg = TRUE;
3190 if (call->imt_arg_reg)
3191 cinfo->imt_arg = TRUE;
3193 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3195 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3199 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);
3200 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);
3202 preserveall = FALSE;
3204 /* FIXME: Avoid creating duplicate methods */
3206 if (ins->flags & MONO_INST_HAS_METHOD) {
3210 if (cfg->compile_aot) {
3211 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3213 set_failure (ctx, "can't encode patch");
3216 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3218 * Collect instructions representing the callee into a hash so they can be replaced
3219 * by the llvm method for the callee if the callee turns out to be direct
3220 * callable. Currently this only requires it to not fail llvm compilation.
3222 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3223 l = g_slist_prepend (l, callee);
3224 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3228 static int tramp_index;
3231 name = g_strdup_printf ("tramp_%d", tramp_index);
3234 #if LLVM_API_VERSION > 100
3236 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3237 * Make all calls through a global. The address of the global will be saved in
3238 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3241 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3244 mono_create_jit_trampoline (mono_domain_get (),
3245 call->method, &error);
3246 if (!is_ok (&error)) {
3247 set_failure (ctx, mono_error_get_message (&error));
3248 mono_error_cleanup (&error);
3252 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3253 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3254 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3255 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3257 callee = LLVMBuildLoad (builder, tramp_var, "");
3260 mono_create_jit_trampoline (mono_domain_get (),
3261 call->method, &error);
3262 if (!is_ok (&error)) {
3264 set_failure (ctx, mono_error_get_message (&error));
3265 mono_error_cleanup (&error);
3269 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3272 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3277 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3278 /* LLVM miscompiles async methods */
3279 set_failure (ctx, "#13734");
3284 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3290 memset (&ji, 0, sizeof (ji));
3291 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3292 ji.data.target = info->name;
3294 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3296 if (cfg->compile_aot) {
3297 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3299 set_failure (ctx, "can't encode patch");
3303 target = (gpointer)mono_icall_get_wrapper (info);
3304 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3307 if (cfg->compile_aot) {
3309 if (cfg->abs_patches) {
3310 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3312 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3314 set_failure (ctx, "can't encode patch");
3320 set_failure (ctx, "aot");
3324 #if LLVM_API_VERSION > 100
3325 if (cfg->abs_patches) {
3326 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3330 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3331 mono_error_assert_ok (&error);
3332 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3334 g_assert_not_reached ();
3337 g_assert_not_reached ();
3340 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3342 if (cfg->abs_patches) {
3343 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3348 * FIXME: Some trampolines might have
3349 * their own calling convention on some platforms.
3351 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3352 mono_error_assert_ok (&error);
3353 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3357 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3364 int size = sizeof (gpointer);
3367 g_assert (ins->inst_offset % size == 0);
3368 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3370 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3372 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3374 if (ins->flags & MONO_INST_HAS_METHOD) {
3379 * Collect and convert arguments
3381 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3382 len = sizeof (LLVMValueRef) * nargs;
3383 args = (LLVMValueRef*)alloca (len);
3384 memset (args, 0, len);
3385 l = call->out_ireg_args;
3387 if (call->rgctx_arg_reg) {
3388 g_assert (values [call->rgctx_arg_reg]);
3389 g_assert (cinfo->rgctx_arg_pindex < nargs);
3391 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3392 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3393 * it using a volatile load.
3396 if (!ctx->imt_rgctx_loc)
3397 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3398 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3399 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3401 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3404 if (call->imt_arg_reg) {
3405 g_assert (!ctx->llvm_only);
3406 g_assert (values [call->imt_arg_reg]);
3407 g_assert (cinfo->imt_arg_pindex < nargs);
3409 if (!ctx->imt_rgctx_loc)
3410 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3411 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3412 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3414 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3417 switch (cinfo->ret.storage) {
3418 case LLVMArgGsharedvtVariable: {
3419 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3421 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3422 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3424 g_assert (addresses [call->inst.dreg]);
3425 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3431 if (!addresses [call->inst.dreg])
3432 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3433 g_assert (cinfo->vret_arg_pindex < nargs);
3434 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3435 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3437 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3443 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3444 * use the real callee for argument type conversion.
3446 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3447 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3448 LLVMGetParamTypes (callee_type, param_types);
3450 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3453 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3455 pindex = ainfo->pindex;
3457 regpair = (guint32)(gssize)(l->data);
3458 reg = regpair & 0xffffff;
3459 args [pindex] = values [reg];
3460 switch (ainfo->storage) {
3461 case LLVMArgVtypeInReg:
3462 case LLVMArgAsFpArgs: {
3466 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3467 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3468 pindex += ainfo->ndummy_fpargs;
3470 g_assert (addresses [reg]);
3471 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3475 // FIXME: Get rid of the VMOVE
3478 case LLVMArgVtypeByVal:
3479 g_assert (addresses [reg]);
3480 args [pindex] = addresses [reg];
3482 case LLVMArgVtypeByRef: {
3483 g_assert (addresses [reg]);
3484 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3487 case LLVMArgAsIArgs:
3488 g_assert (addresses [reg]);
3489 if (ainfo->esize == 8)
3490 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (LLVMInt64Type (), ainfo->nslots), 0)), "");
3492 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3494 case LLVMArgVtypeAsScalar:
3495 g_assert_not_reached ();
3497 case LLVMArgGsharedvtFixed:
3498 case LLVMArgGsharedvtFixedVtype:
3499 g_assert (addresses [reg]);
3500 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3502 case LLVMArgGsharedvtVariable:
3503 g_assert (addresses [reg]);
3504 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3507 g_assert (args [pindex]);
3508 if (i == 0 && sig->hasthis)
3509 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3511 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3514 g_assert (pindex <= nargs);
3519 // FIXME: Align call sites
3525 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3527 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3528 mono_llvm_set_call_notail (lcall);
3531 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3533 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3534 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3536 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3537 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3538 if (!sig->pinvoke && !cfg->llvm_only)
3539 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3541 mono_llvm_set_call_preserveall_cc (lcall);
3543 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3544 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3545 if (!ctx->llvm_only && call->rgctx_arg_reg)
3546 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3547 if (call->imt_arg_reg)
3548 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3550 /* Add byval attributes if needed */
3551 for (i = 0; i < sig->param_count; ++i) {
3552 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3554 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3555 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3559 * Convert the result
3561 switch (cinfo->ret.storage) {
3562 case LLVMArgVtypeInReg: {
3563 LLVMValueRef regs [2];
3565 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3569 if (!addresses [ins->dreg])
3570 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3572 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3573 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3574 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3575 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3578 case LLVMArgVtypeByVal:
3579 if (!addresses [call->inst.dreg])
3580 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3581 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3583 case LLVMArgAsIArgs:
3584 case LLVMArgFpStruct:
3585 if (!addresses [call->inst.dreg])
3586 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3587 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3589 case LLVMArgVtypeAsScalar:
3590 if (!addresses [call->inst.dreg])
3591 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3592 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3594 case LLVMArgVtypeRetAddr:
3595 case LLVMArgVtypeByRef:
3596 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3597 /* Some opcodes like STOREX_MEMBASE access these by value */
3598 g_assert (addresses [call->inst.dreg]);
3599 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3602 case LLVMArgGsharedvtVariable:
3604 case LLVMArgGsharedvtFixed:
3605 case LLVMArgGsharedvtFixedVtype:
3606 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3609 if (sig->ret->type != MONO_TYPE_VOID)
3610 /* If the method returns an unsigned value, need to zext it */
3611 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));
3615 *builder_ref = ctx->builder;
3619 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3621 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3622 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3624 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3627 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3629 if (ctx->cfg->compile_aot) {
3630 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3632 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3633 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3634 mono_memory_barrier ();
3637 ctx->module->rethrow = callee;
3639 ctx->module->throw_icall = callee;
3643 LLVMValueRef args [2];
3645 args [0] = convert (ctx, exc, exc_type);
3646 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3648 LLVMBuildUnreachable (ctx->builder);
3650 ctx->builder = create_builder (ctx);
3654 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3656 MonoMethodSignature *throw_sig;
3657 LLVMValueRef callee, arg;
3658 const char *icall_name;
3660 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3661 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3664 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3665 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3666 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3667 if (ctx->cfg->compile_aot) {
3668 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3673 * LLVM doesn't push the exception argument, so we need a different
3676 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3678 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3680 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3683 mono_memory_barrier ();
3684 #if LLVM_API_VERSION < 100
3686 ctx->module->rethrow = callee;
3688 ctx->module->throw_icall = callee;
3691 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3692 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3696 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3698 const char *icall_name = "mono_llvm_resume_exception";
3699 LLVMValueRef callee = ctx->module->resume_eh;
3701 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3704 if (ctx->cfg->compile_aot) {
3705 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3707 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3708 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3709 mono_memory_barrier ();
3711 ctx->module->resume_eh = callee;
3715 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3717 LLVMBuildUnreachable (ctx->builder);
3719 ctx->builder = create_builder (ctx);
3723 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3725 const char *icall_name = "mono_llvm_clear_exception";
3727 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3728 LLVMValueRef callee = NULL;
3731 if (ctx->cfg->compile_aot) {
3732 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3734 // FIXME: This is broken.
3735 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3739 g_assert (builder && callee);
3741 return LLVMBuildCall (builder, callee, NULL, 0, "");
3745 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3747 const char *icall_name = "mono_llvm_load_exception";
3749 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3750 LLVMValueRef callee = NULL;
3753 if (ctx->cfg->compile_aot) {
3754 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3756 // FIXME: This is broken.
3757 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3761 g_assert (builder && callee);
3763 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3768 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3770 const char *icall_name = "mono_llvm_match_exception";
3772 ctx->builder = builder;
3774 const int num_args = 5;
3775 LLVMValueRef args [num_args];
3776 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3777 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3778 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3779 if (ctx->cfg->rgctx_var) {
3780 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3781 g_assert (rgctx_alloc);
3782 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3784 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3787 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3789 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3791 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3792 LLVMValueRef callee = ctx->module->match_exc;
3795 if (ctx->cfg->compile_aot) {
3796 ctx->builder = builder;
3797 // get_callee expects ctx->builder to be the emitting builder
3798 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3800 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3801 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3802 ctx->module->match_exc = callee;
3803 mono_memory_barrier ();
3807 g_assert (builder && callee);
3809 g_assert (ctx->ex_var);
3811 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3814 // FIXME: This won't work because the code-finding makes this
3816 /*#define MONO_PERSONALITY_DEBUG*/
3818 #ifdef MONO_PERSONALITY_DEBUG
3819 static const gboolean use_debug_personality = TRUE;
3820 static const char *default_personality_name = "mono_debug_personality";
3822 static const gboolean use_debug_personality = FALSE;
3823 static const char *default_personality_name = "__gxx_personality_v0";
3827 default_cpp_lpad_exc_signature (void)
3829 static gboolean inited = FALSE;
3830 static LLVMTypeRef sig;
3833 LLVMTypeRef signature [2];
3834 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3835 signature [1] = LLVMInt32Type ();
3836 sig = LLVMStructType (signature, 2, FALSE);
3844 get_mono_personality (EmitContext *ctx)
3846 LLVMValueRef personality = NULL;
3847 static gint32 mapping_inited = FALSE;
3848 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3850 if (!use_debug_personality) {
3851 if (ctx->cfg->compile_aot) {
3852 personality = get_intrinsic (ctx, default_personality_name);
3853 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3854 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3855 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3858 if (ctx->cfg->compile_aot) {
3859 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3861 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3862 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3863 mono_memory_barrier ();
3867 g_assert (personality);
3871 static LLVMBasicBlockRef
3872 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3874 MonoCompile *cfg = ctx->cfg;
3875 LLVMBuilderRef old_builder = ctx->builder;
3876 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3878 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3879 ctx->builder = lpadBuilder;
3881 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3882 g_assert (handler_bb);
3884 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3885 LLVMValueRef personality = get_mono_personality (ctx);
3886 g_assert (personality);
3888 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3889 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3891 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3892 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3893 g_assert (landing_pad);
3895 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3896 LLVMAddClause (landing_pad, cast);
3898 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3899 LLVMBuilderRef resume_builder = create_builder (ctx);
3900 ctx->builder = resume_builder;
3901 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3903 emit_resume_eh (ctx, handler_bb);
3906 ctx->builder = lpadBuilder;
3907 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3909 gboolean finally_only = TRUE;
3911 MonoExceptionClause *group_cursor = group_start;
3913 for (int i = 0; i < group_size; i ++) {
3914 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY || group_cursor->flags & MONO_EXCEPTION_CLAUSE_FAULT))
3915 finally_only = FALSE;
3921 // Handle landing pad inlining
3923 if (!finally_only) {
3924 // So at each level of the exception stack we will match the exception again.
3925 // During that match, we need to compare against the handler types for the current
3926 // protected region. We send the try start and end so that we can only check against
3927 // handlers for this lexical protected region.
3928 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3930 // if returns -1, resume
3931 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3933 // else move to that target bb
3934 for (int i = 0; i < group_size; i++) {
3935 MonoExceptionClause *clause = group_start + i;
3936 int clause_index = clause - cfg->header->clauses;
3937 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3938 g_assert (handler_bb);
3939 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3940 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3943 int clause_index = group_start - cfg->header->clauses;
3944 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3945 g_assert (finally_bb);
3947 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3950 ctx->builder = old_builder;
3957 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3959 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3960 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3962 // Make exception available to catch blocks
3963 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY || clause->flags & MONO_EXCEPTION_CLAUSE_FAULT)) {
3964 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3966 g_assert (ctx->ex_var);
3967 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3969 if (bb->in_scount == 1) {
3970 MonoInst *exvar = bb->in_stack [0];
3971 g_assert (!ctx->values [exvar->dreg]);
3972 g_assert (ctx->ex_var);
3973 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3974 emit_volatile_store (ctx, exvar->dreg);
3977 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3980 LLVMBuilderRef handler_builder = create_builder (ctx);
3981 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3982 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3984 // Make the handler code end with a jump to cbb
3985 LLVMBuildBr (handler_builder, cbb);
3989 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3991 MonoCompile *cfg = ctx->cfg;
3992 LLVMValueRef *values = ctx->values;
3993 LLVMModuleRef lmodule = ctx->lmodule;
3994 BBInfo *bblocks = ctx->bblocks;
3996 LLVMValueRef personality;
3997 LLVMValueRef landing_pad;
3998 LLVMBasicBlockRef target_bb;
4000 static int ti_generator;
4002 LLVMValueRef type_info;
4006 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4008 if (cfg->compile_aot) {
4009 /* Use a dummy personality function */
4010 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4011 g_assert (personality);
4013 #if LLVM_API_VERSION > 100
4014 personality = ctx->module->personality;
4016 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
4017 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
4018 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
4019 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
4020 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
4021 LLVMPositionBuilderAtEnd (builder2, entry_bb);
4022 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
4023 ctx->module->personality = personality;
4024 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 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4122 ctx->builder = builder = create_builder (ctx);
4123 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4125 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4127 /* Store the exception into the IL level exvar */
4128 if (bb->in_scount == 1) {
4129 g_assert (bb->in_scount == 1);
4130 exvar = bb->in_stack [0];
4132 // FIXME: This is shared with filter clauses ?
4133 g_assert (!values [exvar->dreg]);
4135 g_assert (ctx->ex_var);
4136 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4137 emit_volatile_store (ctx, exvar->dreg);
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 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6471 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6481 * EXCEPTION HANDLING
6483 case OP_IMPLICIT_EXCEPTION:
6484 /* This marks a place where an implicit exception can happen */
6485 if (bb->region != -1)
6486 set_failure (ctx, "implicit-exception");
6490 gboolean rethrow = (ins->opcode == OP_RETHROW);
6491 if (ctx->llvm_only) {
6492 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6493 has_terminator = TRUE;
6494 ctx->unreachable [bb->block_num] = TRUE;
6496 emit_throw (ctx, bb, rethrow, lhs);
6497 builder = ctx->builder;
6501 case OP_CALL_HANDLER: {
6503 * We don't 'call' handlers, but instead simply branch to them.
6504 * The code generated by ENDFINALLY will branch back to us.
6506 LLVMBasicBlockRef noex_bb;
6508 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6510 bb_list = info->call_handler_return_bbs;
6513 * Set the indicator variable for the finally clause.
6515 lhs = info->finally_ind;
6517 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6519 /* Branch to the finally clause */
6520 LLVMBuildBr (builder, info->call_handler_target_bb);
6522 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6523 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6525 builder = ctx->builder = create_builder (ctx);
6526 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6528 bblocks [bb->block_num].end_bblock = noex_bb;
6531 case OP_START_HANDLER: {
6534 case OP_ENDFINALLY: {
6535 LLVMBasicBlockRef resume_bb;
6536 MonoBasicBlock *handler_bb;
6537 LLVMValueRef val, switch_ins, callee;
6540 gboolean is_fault = MONO_REGION_FLAGS (bb->region) == MONO_EXCEPTION_CLAUSE_FAULT;
6543 * Fault clauses are like finally clauses, but they are only called if an exception is thrown.
6546 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6547 g_assert (handler_bb);
6548 info = &bblocks [handler_bb->block_num];
6549 lhs = info->finally_ind;
6552 bb_list = info->call_handler_return_bbs;
6554 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6556 /* Load the finally variable */
6557 val = LLVMBuildLoad (builder, lhs, "");
6559 /* Reset the variable */
6560 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6562 /* Branch to either resume_bb, or to the bblocks in bb_list */
6563 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6565 * The other targets are added at the end to handle OP_CALL_HANDLER
6566 * opcodes processed later.
6568 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6570 builder = ctx->builder = create_builder (ctx);
6571 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6574 if (ctx->llvm_only) {
6575 emit_resume_eh (ctx, bb);
6577 if (ctx->cfg->compile_aot) {
6578 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6580 #if LLVM_API_VERSION > 100
6581 MonoJitICallInfo *info;
6583 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6585 gpointer target = (void*)info->func;
6586 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6587 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6589 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6592 LLVMBuildCall (builder, callee, NULL, 0, "");
6593 LLVMBuildUnreachable (builder);
6596 has_terminator = TRUE;
6599 case OP_IL_SEQ_POINT:
6604 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6605 set_failure (ctx, reason);
6613 /* Convert the value to the type required by phi nodes */
6614 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6615 if (ctx->is_vphi [ins->dreg])
6617 values [ins->dreg] = addresses [ins->dreg];
6619 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6622 /* Add stores for volatile variables */
6623 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6624 emit_volatile_store (ctx, ins->dreg);
6630 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6631 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6634 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6635 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6636 LLVMBuildRetVoid (builder);
6639 if (bb == cfg->bb_entry)
6640 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6644 * mono_llvm_check_method_supported:
6646 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6647 * compiling a method twice.
6650 mono_llvm_check_method_supported (MonoCompile *cfg)
6657 if (cfg->method->save_lmf) {
6658 cfg->exception_message = g_strdup ("lmf");
6659 cfg->disable_llvm = TRUE;
6661 if (cfg->disable_llvm)
6665 * Nested clauses where one of the clauses is a finally clause is
6666 * not supported, because LLVM can't figure out the control flow,
6667 * probably because we resume exception handling by calling our
6668 * own function instead of using the 'resume' llvm instruction.
6670 for (i = 0; i < cfg->header->num_clauses; ++i) {
6671 for (j = 0; j < cfg->header->num_clauses; ++j) {
6672 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6673 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6675 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6676 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6677 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6678 cfg->exception_message = g_strdup ("nested clauses");
6679 cfg->disable_llvm = TRUE;
6684 if (cfg->disable_llvm)
6688 if (cfg->method->dynamic) {
6689 cfg->exception_message = g_strdup ("dynamic.");
6690 cfg->disable_llvm = TRUE;
6692 if (cfg->disable_llvm)
6696 static LLVMCallInfo*
6697 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6699 LLVMCallInfo *linfo;
6702 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6706 * Gsharedvt methods have the following calling convention:
6707 * - all arguments are passed by ref, even non generic ones
6708 * - the return value is returned by ref too, using a vret
6709 * argument passed after 'this'.
6711 n = sig->param_count + sig->hasthis;
6712 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6716 linfo->args [pindex ++].storage = LLVMArgNormal;
6718 if (sig->ret->type != MONO_TYPE_VOID) {
6719 if (mini_is_gsharedvt_variable_type (sig->ret))
6720 linfo->ret.storage = LLVMArgGsharedvtVariable;
6721 else if (mini_type_is_vtype (sig->ret))
6722 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6724 linfo->ret.storage = LLVMArgGsharedvtFixed;
6725 linfo->vret_arg_index = pindex;
6727 linfo->ret.storage = LLVMArgNone;
6730 for (i = 0; i < sig->param_count; ++i) {
6731 if (sig->params [i]->byref)
6732 linfo->args [pindex].storage = LLVMArgNormal;
6733 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6734 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6735 else if (mini_type_is_vtype (sig->params [i]))
6736 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6738 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6739 linfo->args [pindex].type = sig->params [i];
6746 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6747 for (i = 0; i < sig->param_count; ++i)
6748 linfo->args [i + sig->hasthis].type = sig->params [i];
6754 emit_method_inner (EmitContext *ctx);
6757 free_ctx (EmitContext *ctx)
6761 g_free (ctx->values);
6762 g_free (ctx->addresses);
6763 g_free (ctx->vreg_types);
6764 g_free (ctx->is_vphi);
6765 g_free (ctx->vreg_cli_types);
6766 g_free (ctx->is_dead);
6767 g_free (ctx->unreachable);
6768 g_ptr_array_free (ctx->phi_values, TRUE);
6769 g_free (ctx->bblocks);
6770 g_hash_table_destroy (ctx->region_to_handler);
6771 g_hash_table_destroy (ctx->clause_to_handler);
6772 g_hash_table_destroy (ctx->jit_callees);
6774 GHashTableIter iter;
6775 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6776 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6779 g_hash_table_destroy (ctx->method_to_callers);
6781 g_free (ctx->method_name);
6782 g_ptr_array_free (ctx->bblock_list, TRUE);
6784 for (l = ctx->builders; l; l = l->next) {
6785 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6786 LLVMDisposeBuilder (builder);
6793 * mono_llvm_emit_method:
6795 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6798 mono_llvm_emit_method (MonoCompile *cfg)
6802 gboolean is_linkonce = FALSE;
6805 /* The code below might acquire the loader lock, so use it for global locking */
6806 mono_loader_lock ();
6808 /* Used to communicate with the callbacks */
6809 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6811 ctx = g_new0 (EmitContext, 1);
6813 ctx->mempool = cfg->mempool;
6816 * This maps vregs to the LLVM instruction defining them
6818 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6820 * This maps vregs for volatile variables to the LLVM instruction defining their
6823 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6824 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6825 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6826 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6827 ctx->phi_values = g_ptr_array_sized_new (256);
6829 * This signals whenever the vreg was defined by a phi node with no input vars
6830 * (i.e. all its input bblocks end with NOT_REACHABLE).
6832 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6833 /* Whenever the bblock is unreachable */
6834 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6835 ctx->bblock_list = g_ptr_array_sized_new (256);
6837 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6838 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6839 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6840 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6841 if (cfg->compile_aot) {
6842 ctx->module = &aot_module;
6846 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6847 * linkage for them. This requires the following:
6848 * - the method needs to have a unique mangled name
6849 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6851 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6853 method_name = mono_aot_get_mangled_method_name (cfg->method);
6855 is_linkonce = FALSE;
6858 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6860 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6864 method_name = mono_aot_get_method_name (cfg);
6865 cfg->llvm_method_name = g_strdup (method_name);
6867 init_jit_module (cfg->domain);
6868 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6869 method_name = mono_method_full_name (cfg->method, TRUE);
6871 ctx->method_name = method_name;
6872 ctx->is_linkonce = is_linkonce;
6874 #if LLVM_API_VERSION > 100
6875 if (cfg->compile_aot)
6876 ctx->lmodule = ctx->module->lmodule;
6878 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6880 ctx->lmodule = ctx->module->lmodule;
6882 ctx->llvm_only = ctx->module->llvm_only;
6884 emit_method_inner (ctx);
6886 if (!ctx_ok (ctx)) {
6888 /* Need to add unused phi nodes as they can be referenced by other values */
6889 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6890 LLVMBuilderRef builder;
6892 builder = create_builder (ctx);
6893 LLVMPositionBuilderAtEnd (builder, phi_bb);
6895 for (i = 0; i < ctx->phi_values->len; ++i) {
6896 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6897 if (LLVMGetInstructionParent (v) == NULL)
6898 LLVMInsertIntoBuilder (builder, v);
6901 LLVMDeleteFunction (ctx->lmethod);
6907 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6909 mono_loader_unlock ();
6913 emit_method_inner (EmitContext *ctx)
6915 MonoCompile *cfg = ctx->cfg;
6916 MonoMethodSignature *sig;
6918 LLVMTypeRef method_type;
6919 LLVMValueRef method = NULL;
6920 LLVMValueRef *values = ctx->values;
6921 int i, max_block_num, bb_index;
6922 gboolean last = FALSE;
6923 LLVMCallInfo *linfo;
6924 LLVMModuleRef lmodule = ctx->lmodule;
6926 GPtrArray *bblock_list = ctx->bblock_list;
6927 MonoMethodHeader *header;
6928 MonoExceptionClause *clause;
6931 if (cfg->gsharedvt && !cfg->llvm_only) {
6932 set_failure (ctx, "gsharedvt");
6938 static int count = 0;
6941 char *llvm_count_str = g_getenv ("LLVM_COUNT");
6942 if (llvm_count_str) {
6943 int lcount = atoi (llvm_count_str);
6944 g_free (llvm_count_str);
6945 if (count == lcount) {
6946 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6950 if (count > lcount) {
6951 set_failure (ctx, "count");
6958 sig = mono_method_signature (cfg->method);
6961 linfo = get_llvm_call_info (cfg, sig);
6967 linfo->rgctx_arg = TRUE;
6968 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6972 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6973 ctx->lmethod = method;
6975 if (!cfg->llvm_only)
6976 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6977 LLVMSetLinkage (method, LLVMPrivateLinkage);
6979 LLVMAddFunctionAttr (method, LLVMUWTable);
6981 if (cfg->compile_aot) {
6982 LLVMSetLinkage (method, LLVMInternalLinkage);
6983 if (ctx->module->external_symbols) {
6984 LLVMSetLinkage (method, LLVMExternalLinkage);
6985 LLVMSetVisibility (method, LLVMHiddenVisibility);
6987 if (ctx->is_linkonce) {
6988 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6989 LLVMSetVisibility (method, LLVMDefaultVisibility);
6992 #if LLVM_API_VERSION > 100
6993 LLVMSetLinkage (method, LLVMExternalLinkage);
6995 LLVMSetLinkage (method, LLVMPrivateLinkage);
6999 if (cfg->method->save_lmf && !cfg->llvm_only) {
7000 set_failure (ctx, "lmf");
7004 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
7005 set_failure (ctx, "pinvoke signature");
7009 header = cfg->header;
7010 for (i = 0; i < header->num_clauses; ++i) {
7011 clause = &header->clauses [i];
7012 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_FAULT && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
7013 set_failure (ctx, "non-finally/catch/fault clause.");
7017 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7018 /* We can't handle inlined methods with clauses */
7019 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
7021 if (linfo->rgctx_arg) {
7022 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7023 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7025 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7026 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7027 * CC_X86_64_Mono in X86CallingConv.td.
7029 if (!ctx->llvm_only)
7030 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
7031 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7033 ctx->rgctx_arg_pindex = -1;
7035 if (cfg->vret_addr) {
7036 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7037 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7038 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7039 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7040 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7045 ctx->this_arg_pindex = linfo->this_arg_pindex;
7046 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7047 values [cfg->args [0]->dreg] = ctx->this_arg;
7048 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7051 names = g_new (char *, sig->param_count);
7052 mono_method_get_param_names (cfg->method, (const char **) names);
7054 /* Set parameter names/attributes */
7055 for (i = 0; i < sig->param_count; ++i) {
7056 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7058 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7061 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7062 name = g_strdup_printf ("dummy_%d_%d", i, j);
7063 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7067 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7070 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7071 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7072 if (names [i] && names [i][0] != '\0')
7073 name = g_strdup_printf ("p_arg_%s", names [i]);
7075 name = g_strdup_printf ("p_arg_%d", i);
7077 if (names [i] && names [i][0] != '\0')
7078 name = g_strdup_printf ("arg_%s", names [i]);
7080 name = g_strdup_printf ("arg_%d", i);
7082 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7084 if (ainfo->storage == LLVMArgVtypeByVal)
7085 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7087 if (ainfo->storage == LLVMArgVtypeByRef) {
7089 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7094 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7095 ctx->minfo = mono_debug_lookup_method (cfg->method);
7096 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7100 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7101 max_block_num = MAX (max_block_num, bb->block_num);
7102 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7104 /* Add branches between non-consecutive bblocks */
7105 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7106 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7107 bb->next_bb != bb->last_ins->inst_false_bb) {
7109 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7110 inst->opcode = OP_BR;
7111 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7112 mono_bblock_add_inst (bb, inst);
7117 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7118 * was later optimized away, so clear these flags, and add them back for the still
7119 * present OP_LDADDR instructions.
7121 for (i = 0; i < cfg->next_vreg; ++i) {
7124 ins = get_vreg_to_inst (cfg, i);
7125 if (ins && ins != cfg->rgctx_var)
7126 ins->flags &= ~MONO_INST_INDIRECT;
7130 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7132 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7134 LLVMBuilderRef builder;
7136 char dname_buf[128];
7138 builder = create_builder (ctx);
7140 for (ins = bb->code; ins; ins = ins->next) {
7141 switch (ins->opcode) {
7146 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7151 if (ins->opcode == OP_VPHI) {
7152 /* Treat valuetype PHI nodes as operating on the address itself */
7153 g_assert (ins->klass);
7154 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7158 * Have to precreate these, as they can be referenced by
7159 * earlier instructions.
7161 sprintf (dname_buf, "t%d", ins->dreg);
7163 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7165 if (ins->opcode == OP_VPHI)
7166 ctx->addresses [ins->dreg] = values [ins->dreg];
7168 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7171 * Set the expected type of the incoming arguments since these have
7172 * to have the same type.
7174 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7175 int sreg1 = ins->inst_phi_args [i + 1];
7178 if (ins->opcode == OP_VPHI)
7179 ctx->is_vphi [sreg1] = TRUE;
7180 ctx->vreg_types [sreg1] = phi_type;
7186 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7195 * Create an ordering for bblocks, use the depth first order first, then
7196 * put the exception handling bblocks last.
7198 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7199 bb = cfg->bblocks [bb_index];
7200 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7201 g_ptr_array_add (bblock_list, bb);
7202 bblocks [bb->block_num].added = TRUE;
7206 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7207 if (!bblocks [bb->block_num].added)
7208 g_ptr_array_add (bblock_list, bb);
7212 * Second pass: generate code.
7215 LLVMBuilderRef entry_builder = create_builder (ctx);
7216 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7217 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7218 emit_entry_bb (ctx, entry_builder);
7220 // Make landing pads first
7221 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7223 if (ctx->llvm_only) {
7224 size_t group_index = 0;
7225 while (group_index < cfg->header->num_clauses) {
7227 size_t cursor = group_index;
7228 while (cursor < cfg->header->num_clauses &&
7229 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7230 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7235 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7236 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7237 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7239 group_index = cursor;
7243 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7244 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7246 // Prune unreachable mono BBs.
7247 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7250 process_bb (ctx, bb);
7254 g_hash_table_destroy (ctx->exc_meta);
7256 mono_memory_barrier ();
7258 /* Add incoming phi values */
7259 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7260 GSList *l, *ins_list;
7262 ins_list = bblocks [bb->block_num].phi_nodes;
7264 for (l = ins_list; l; l = l->next) {
7265 PhiNode *node = (PhiNode*)l->data;
7266 MonoInst *phi = node->phi;
7267 int sreg1 = node->sreg;
7268 LLVMBasicBlockRef in_bb;
7273 in_bb = get_end_bb (ctx, node->in_bb);
7275 if (ctx->unreachable [node->in_bb->block_num])
7278 if (!values [sreg1]) {
7279 /* Can happen with values in EH clauses */
7280 set_failure (ctx, "incoming phi sreg1");
7284 if (phi->opcode == OP_VPHI) {
7285 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7286 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7288 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7289 set_failure (ctx, "incoming phi arg type mismatch");
7292 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7293 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7298 /* Nullify empty phi instructions */
7299 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7300 GSList *l, *ins_list;
7302 ins_list = bblocks [bb->block_num].phi_nodes;
7304 for (l = ins_list; l; l = l->next) {
7305 PhiNode *node = (PhiNode*)l->data;
7306 MonoInst *phi = node->phi;
7307 LLVMValueRef phi_ins = values [phi->dreg];
7310 /* Already removed */
7313 if (LLVMCountIncoming (phi_ins) == 0) {
7314 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7315 LLVMInstructionEraseFromParent (phi_ins);
7316 values [phi->dreg] = NULL;
7321 /* Create the SWITCH statements for ENDFINALLY instructions */
7322 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7323 BBInfo *info = &bblocks [bb->block_num];
7325 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7326 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7327 GSList *bb_list = info->call_handler_return_bbs;
7329 GSList *bb_list_iter;
7331 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7332 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7338 /* Initialize the method if needed */
7339 if (cfg->compile_aot && ctx->llvm_only) {
7340 // FIXME: Add more shared got entries
7341 ctx->builder = create_builder (ctx);
7342 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7344 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7346 // FIXME: beforefieldinit
7348 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7349 * in load_method ().
7351 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7353 * linkonce methods shouldn't have initialization,
7354 * because they might belong to assemblies which
7355 * haven't been loaded yet.
7357 g_assert (!ctx->is_linkonce);
7358 emit_init_method (ctx);
7360 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7364 if (cfg->llvm_only) {
7365 GHashTableIter iter;
7367 GSList *callers, *l, *l2;
7370 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7371 * We can't do this earlier, as it contains llvm instructions which can be
7372 * freed if compilation fails.
7373 * FIXME: Get rid of this when all methods can be llvm compiled.
7375 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7376 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7377 for (l = callers; l; l = l->next) {
7378 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7379 l2 = g_slist_prepend (l2, l->data);
7380 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7385 if (cfg->verbose_level > 1)
7386 mono_llvm_dump_value (method);
7388 if (cfg->compile_aot && !cfg->llvm_only)
7389 mark_as_used (ctx->module, method);
7391 if (!cfg->llvm_only) {
7392 LLVMValueRef md_args [16];
7393 LLVMValueRef md_node;
7396 if (cfg->compile_aot)
7397 method_index = mono_aot_get_method_index (cfg->orig_method);
7400 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7401 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7402 md_node = LLVMMDNode (md_args, 2);
7403 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7404 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7407 if (cfg->compile_aot) {
7408 /* Don't generate native code, keep the LLVM IR */
7409 if (cfg->verbose_level)
7410 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7412 #if LLVM_API_VERSION < 100
7413 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7414 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7415 g_assert (err == 0);
7418 //LLVMVerifyFunction(method, 0);
7419 #if LLVM_API_VERSION > 100
7420 MonoDomain *domain = mono_domain_get ();
7421 MonoJitDomainInfo *domain_info;
7422 int nvars = g_hash_table_size (ctx->jit_callees);
7423 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7424 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7425 GHashTableIter iter;
7431 * Compute the addresses of the LLVM globals pointing to the
7432 * methods called by the current method. Pass it to the trampoline
7433 * code so it can update them after their corresponding method was
7436 g_hash_table_iter_init (&iter, ctx->jit_callees);
7438 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7439 callee_vars [i ++] = var;
7441 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7443 decode_llvm_eh_info (ctx, eh_frame);
7445 mono_domain_lock (domain);
7446 domain_info = domain_jit_info (domain);
7447 if (!domain_info->llvm_jit_callees)
7448 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7449 g_hash_table_iter_init (&iter, ctx->jit_callees);
7451 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7452 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7453 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7454 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7457 mono_domain_unlock (domain);
7459 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7461 if (cfg->verbose_level > 1)
7462 mono_llvm_dump_value (ctx->lmethod);
7464 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7466 /* Set by emit_cb */
7467 g_assert (cfg->code_len);
7471 if (ctx->module->method_to_lmethod)
7472 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7473 if (ctx->module->idx_to_lmethod)
7474 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7476 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7477 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7481 * mono_llvm_create_vars:
7483 * Same as mono_arch_create_vars () for LLVM.
7486 mono_llvm_create_vars (MonoCompile *cfg)
7488 MonoMethodSignature *sig;
7490 sig = mono_method_signature (cfg->method);
7491 if (cfg->gsharedvt && cfg->llvm_only) {
7492 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7493 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7494 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7495 printf ("vret_addr = ");
7496 mono_print_ins (cfg->vret_addr);
7500 mono_arch_create_vars (cfg);
7505 * mono_llvm_emit_call:
7507 * Same as mono_arch_emit_call () for LLVM.
7510 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7513 MonoMethodSignature *sig;
7514 int i, n, stack_size;
7519 sig = call->signature;
7520 n = sig->param_count + sig->hasthis;
7522 call->cinfo = get_llvm_call_info (cfg, sig);
7524 if (cfg->disable_llvm)
7527 if (sig->call_convention == MONO_CALL_VARARG) {
7528 cfg->exception_message = g_strdup ("varargs");
7529 cfg->disable_llvm = TRUE;
7532 for (i = 0; i < n; ++i) {
7535 ainfo = call->cinfo->args + i;
7537 in = call->args [i];
7539 /* Simply remember the arguments */
7540 switch (ainfo->storage) {
7541 case LLVMArgNormal: {
7542 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7545 opcode = mono_type_to_regmove (cfg, t);
7546 if (opcode == OP_FMOVE) {
7547 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7548 ins->dreg = mono_alloc_freg (cfg);
7549 } else if (opcode == OP_LMOVE) {
7550 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7551 ins->dreg = mono_alloc_lreg (cfg);
7552 } else if (opcode == OP_RMOVE) {
7553 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7554 ins->dreg = mono_alloc_freg (cfg);
7556 MONO_INST_NEW (cfg, ins, OP_MOVE);
7557 ins->dreg = mono_alloc_ireg (cfg);
7559 ins->sreg1 = in->dreg;
7562 case LLVMArgVtypeByVal:
7563 case LLVMArgVtypeByRef:
7564 case LLVMArgVtypeInReg:
7565 case LLVMArgVtypeAsScalar:
7566 case LLVMArgAsIArgs:
7567 case LLVMArgAsFpArgs:
7568 case LLVMArgGsharedvtVariable:
7569 case LLVMArgGsharedvtFixed:
7570 case LLVMArgGsharedvtFixedVtype:
7571 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7572 ins->dreg = mono_alloc_ireg (cfg);
7573 ins->sreg1 = in->dreg;
7574 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7575 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7576 ins->inst_vtype = ainfo->type;
7577 ins->klass = mono_class_from_mono_type (ainfo->type);
7580 cfg->exception_message = g_strdup ("ainfo->storage");
7581 cfg->disable_llvm = TRUE;
7585 if (!cfg->disable_llvm) {
7586 MONO_ADD_INS (cfg->cbb, ins);
7587 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7592 static unsigned char*
7593 alloc_cb (LLVMValueRef function, int size)
7597 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7601 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7603 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7608 emitted_cb (LLVMValueRef function, void *start, void *end)
7612 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7614 cfg->code_len = (guint8*)end - (guint8*)start;
7618 exception_cb (void *data)
7621 MonoJitExceptionInfo *ei;
7622 guint32 ei_len, i, j, nested_len, nindex;
7623 gpointer *type_info;
7624 int this_reg, this_offset;
7626 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7630 * data points to a DWARF FDE structure, convert it to our unwind format and
7632 * An alternative would be to save it directly, and modify our unwinder to work
7635 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);
7636 if (cfg->verbose_level > 1)
7637 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7639 /* Count nested clauses */
7641 for (i = 0; i < ei_len; ++i) {
7642 gint32 cindex1 = *(gint32*)type_info [i];
7643 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7645 for (j = 0; j < cfg->header->num_clauses; ++j) {
7647 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7649 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7655 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7656 cfg->llvm_ex_info_len = ei_len + nested_len;
7657 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7658 /* Fill the rest of the information from the type info */
7659 for (i = 0; i < ei_len; ++i) {
7660 gint32 clause_index = *(gint32*)type_info [i];
7661 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7663 cfg->llvm_ex_info [i].flags = clause->flags;
7664 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7665 cfg->llvm_ex_info [i].clause_index = clause_index;
7669 * For nested clauses, the LLVM produced exception info associates the try interval with
7670 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7671 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7672 * and everything else from the nested clause.
7675 for (i = 0; i < ei_len; ++i) {
7676 gint32 cindex1 = *(gint32*)type_info [i];
7677 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7679 for (j = 0; j < cfg->header->num_clauses; ++j) {
7681 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7682 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7684 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7685 /* clause1 is the nested clause */
7686 nested_ei = &cfg->llvm_ex_info [i];
7687 nesting_ei = &cfg->llvm_ex_info [nindex];
7690 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7692 nesting_ei->flags = clause2->flags;
7693 nesting_ei->data.catch_class = clause2->data.catch_class;
7694 nesting_ei->clause_index = cindex2;
7698 g_assert (nindex == ei_len + nested_len);
7699 cfg->llvm_this_reg = this_reg;
7700 cfg->llvm_this_offset = this_offset;
7702 /* type_info [i] is cfg mempool allocated, no need to free it */
7708 #if LLVM_API_VERSION > 100
7710 * decode_llvm_eh_info:
7712 * Decode the EH table emitted by llvm in jit mode, and store
7713 * the result into cfg.
7716 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7718 MonoCompile *cfg = ctx->cfg;
7721 MonoLLVMFDEInfo info;
7722 MonoJitExceptionInfo *ei;
7723 guint8 *p = eh_frame;
7724 int version, fde_count, fde_offset;
7725 guint32 ei_len, i, nested_len;
7726 gpointer *type_info;
7731 * Decode the one element EH table emitted by the MonoException class
7735 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7738 g_assert (version == 3);
7741 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7743 fde_count = *(guint32*)p;
7747 g_assert (fde_count <= 2);
7749 /* The first entry is the real method */
7750 g_assert (table [0] == 1);
7751 fde_offset = table [1];
7752 table += fde_count * 2;
7754 cfg->code_len = table [0];
7755 fde_len = table [1] - fde_offset;
7758 fde = (guint8*)eh_frame + fde_offset;
7759 cie = (guint8*)table;
7761 /* Compute lengths */
7762 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info, NULL, NULL, NULL);
7764 ei = (MonoJitExceptionInfo *)g_malloc0 (info.ex_info_len * sizeof (MonoJitExceptionInfo));
7765 type_info = (gpointer *)g_malloc0 (info.ex_info_len * sizeof (gpointer));
7766 unw_info = (guint8*)g_malloc0 (info.unw_info_len);
7768 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info, ei, type_info, unw_info);
7770 cfg->encoded_unwind_ops = unw_info;
7771 cfg->encoded_unwind_ops_len = info.unw_info_len;
7772 if (cfg->verbose_level > 1)
7773 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7774 if (info.this_reg != -1) {
7775 cfg->llvm_this_reg = info.this_reg;
7776 cfg->llvm_this_offset = info.this_offset;
7779 ei_len = info.ex_info_len;
7781 // Nested clauses are currently disabled
7784 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7785 cfg->llvm_ex_info_len = ei_len + nested_len;
7786 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7787 /* Fill the rest of the information from the type info */
7788 for (i = 0; i < ei_len; ++i) {
7789 gint32 clause_index = *(gint32*)type_info [i];
7790 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7792 cfg->llvm_ex_info [i].flags = clause->flags;
7793 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7794 cfg->llvm_ex_info [i].clause_index = clause_index;
7800 dlsym_cb (const char *name, void **symbol)
7806 if (!strcmp (name, "__bzero")) {
7807 *symbol = (void*)bzero;
7809 current = mono_dl_open (NULL, 0, NULL);
7812 err = mono_dl_symbol (current, name, symbol);
7814 mono_dl_close (current);
7816 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7817 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7823 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7825 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7829 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7831 LLVMTypeRef param_types [4];
7833 param_types [0] = param_type1;
7834 param_types [1] = param_type2;
7836 AddFunc (module, name, ret_type, param_types, 2);
7842 INTRINS_SADD_OVF_I32,
7843 INTRINS_UADD_OVF_I32,
7844 INTRINS_SSUB_OVF_I32,
7845 INTRINS_USUB_OVF_I32,
7846 INTRINS_SMUL_OVF_I32,
7847 INTRINS_UMUL_OVF_I32,
7848 INTRINS_SADD_OVF_I64,
7849 INTRINS_UADD_OVF_I64,
7850 INTRINS_SSUB_OVF_I64,
7851 INTRINS_USUB_OVF_I64,
7852 INTRINS_SMUL_OVF_I64,
7853 INTRINS_UMUL_OVF_I64,
7860 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7861 INTRINS_SSE_PMOVMSKB,
7862 INTRINS_SSE_PSRLI_W,
7863 INTRINS_SSE_PSRAI_W,
7864 INTRINS_SSE_PSLLI_W,
7865 INTRINS_SSE_PSRLI_D,
7866 INTRINS_SSE_PSRAI_D,
7867 INTRINS_SSE_PSLLI_D,
7868 INTRINS_SSE_PSRLI_Q,
7869 INTRINS_SSE_PSLLI_Q,
7870 INTRINS_SSE_SQRT_PD,
7871 INTRINS_SSE_SQRT_PS,
7872 INTRINS_SSE_RSQRT_PS,
7874 INTRINS_SSE_CVTTPD2DQ,
7875 INTRINS_SSE_CVTTPS2DQ,
7876 INTRINS_SSE_CVTDQ2PD,
7877 INTRINS_SSE_CVTDQ2PS,
7878 INTRINS_SSE_CVTPD2DQ,
7879 INTRINS_SSE_CVTPS2DQ,
7880 INTRINS_SSE_CVTPD2PS,
7881 INTRINS_SSE_CVTPS2PD,
7884 INTRINS_SSE_PACKSSWB,
7885 INTRINS_SSE_PACKUSWB,
7886 INTRINS_SSE_PACKSSDW,
7887 INTRINS_SSE_PACKUSDW,
7892 INTRINS_SSE_ADDSUBPS,
7897 INTRINS_SSE_ADDSUBPD,
7900 INTRINS_SSE_PADDUSW,
7901 INTRINS_SSE_PSUBUSW,
7907 INTRINS_SSE_PADDUSB,
7908 INTRINS_SSE_PSUBUSB,
7921 static IntrinsicDesc intrinsics[] = {
7922 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7923 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7924 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7925 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7926 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7927 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7928 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7929 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7930 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7931 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7932 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7933 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7934 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7935 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7936 {INTRINS_SIN, "llvm.sin.f64"},
7937 {INTRINS_COS, "llvm.cos.f64"},
7938 {INTRINS_SQRT, "llvm.sqrt.f64"},
7939 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7940 {INTRINS_FABS, "fabs"},
7941 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7942 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7943 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7944 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7945 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7946 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7947 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7948 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7949 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7950 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7951 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7952 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7953 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7954 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7955 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7956 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7957 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7958 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7959 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7960 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7961 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7962 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7963 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7964 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7965 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7966 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7967 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7968 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7969 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7970 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7971 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7972 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7973 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7974 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7975 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7976 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7977 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7978 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7979 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7980 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7981 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7982 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7983 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7984 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7985 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7986 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7987 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7988 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7989 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7990 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7991 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7992 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7993 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7994 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7999 add_sse_binary (LLVMModuleRef module, const char *name, int type)
8001 LLVMTypeRef ret_type = type_to_simd_type (type);
8002 AddFunc2 (module, name, ret_type, ret_type, ret_type);
8006 add_intrinsic (LLVMModuleRef module, int id)
8009 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8010 LLVMTypeRef ret_type, arg_types [16];
8013 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
8017 case INTRINS_MEMSET: {
8018 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8020 AddFunc (module, name, LLVMVoidType (), params, 5);
8023 case INTRINS_MEMCPY: {
8024 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8026 AddFunc (module, name, LLVMVoidType (), params, 5);
8029 case INTRINS_SADD_OVF_I32:
8030 case INTRINS_UADD_OVF_I32:
8031 case INTRINS_SSUB_OVF_I32:
8032 case INTRINS_USUB_OVF_I32:
8033 case INTRINS_SMUL_OVF_I32:
8034 case INTRINS_UMUL_OVF_I32: {
8035 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
8036 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
8037 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
8039 AddFunc (module, name, ret_type, params, 2);
8042 case INTRINS_SADD_OVF_I64:
8043 case INTRINS_UADD_OVF_I64:
8044 case INTRINS_SSUB_OVF_I64:
8045 case INTRINS_USUB_OVF_I64:
8046 case INTRINS_SMUL_OVF_I64:
8047 case INTRINS_UMUL_OVF_I64: {
8048 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8049 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8050 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8052 AddFunc (module, name, ret_type, params, 2);
8058 case INTRINS_FABS: {
8059 LLVMTypeRef params [] = { LLVMDoubleType () };
8061 AddFunc (module, name, LLVMDoubleType (), params, 1);
8064 case INTRINS_EXPECT_I8:
8065 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8067 case INTRINS_EXPECT_I1:
8068 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8070 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8071 case INTRINS_SSE_PMOVMSKB:
8073 ret_type = LLVMInt32Type ();
8074 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8075 AddFunc (module, name, ret_type, arg_types, 1);
8077 case INTRINS_SSE_PSRLI_W:
8078 case INTRINS_SSE_PSRAI_W:
8079 case INTRINS_SSE_PSLLI_W:
8081 ret_type = type_to_simd_type (MONO_TYPE_I2);
8082 arg_types [0] = ret_type;
8083 arg_types [1] = LLVMInt32Type ();
8084 AddFunc (module, name, ret_type, arg_types, 2);
8086 case INTRINS_SSE_PSRLI_D:
8087 case INTRINS_SSE_PSRAI_D:
8088 case INTRINS_SSE_PSLLI_D:
8089 ret_type = type_to_simd_type (MONO_TYPE_I4);
8090 arg_types [0] = ret_type;
8091 arg_types [1] = LLVMInt32Type ();
8092 AddFunc (module, name, ret_type, arg_types, 2);
8094 case INTRINS_SSE_PSRLI_Q:
8095 case INTRINS_SSE_PSLLI_Q:
8096 ret_type = type_to_simd_type (MONO_TYPE_I8);
8097 arg_types [0] = ret_type;
8098 arg_types [1] = LLVMInt32Type ();
8099 AddFunc (module, name, ret_type, arg_types, 2);
8101 case INTRINS_SSE_SQRT_PD:
8103 ret_type = type_to_simd_type (MONO_TYPE_R8);
8104 arg_types [0] = ret_type;
8105 AddFunc (module, name, ret_type, arg_types, 1);
8107 case INTRINS_SSE_SQRT_PS:
8108 ret_type = type_to_simd_type (MONO_TYPE_R4);
8109 arg_types [0] = ret_type;
8110 AddFunc (module, name, ret_type, arg_types, 1);
8112 case INTRINS_SSE_RSQRT_PS:
8113 ret_type = type_to_simd_type (MONO_TYPE_R4);
8114 arg_types [0] = ret_type;
8115 AddFunc (module, name, ret_type, arg_types, 1);
8117 case INTRINS_SSE_RCP_PS:
8118 ret_type = type_to_simd_type (MONO_TYPE_R4);
8119 arg_types [0] = ret_type;
8120 AddFunc (module, name, ret_type, arg_types, 1);
8122 case INTRINS_SSE_CVTTPD2DQ:
8123 ret_type = type_to_simd_type (MONO_TYPE_I4);
8124 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8125 AddFunc (module, name, ret_type, arg_types, 1);
8127 case INTRINS_SSE_CVTTPS2DQ:
8128 ret_type = type_to_simd_type (MONO_TYPE_I4);
8129 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8130 AddFunc (module, name, ret_type, arg_types, 1);
8132 case INTRINS_SSE_CVTDQ2PD:
8133 /* Conversion ops */
8134 ret_type = type_to_simd_type (MONO_TYPE_R8);
8135 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8136 AddFunc (module, name, ret_type, arg_types, 1);
8138 case INTRINS_SSE_CVTDQ2PS:
8139 ret_type = type_to_simd_type (MONO_TYPE_R4);
8140 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8141 AddFunc (module, name, ret_type, arg_types, 1);
8143 case INTRINS_SSE_CVTPD2DQ:
8144 ret_type = type_to_simd_type (MONO_TYPE_I4);
8145 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8146 AddFunc (module, name, ret_type, arg_types, 1);
8148 case INTRINS_SSE_CVTPS2DQ:
8149 ret_type = type_to_simd_type (MONO_TYPE_I4);
8150 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8151 AddFunc (module, name, ret_type, arg_types, 1);
8153 case INTRINS_SSE_CVTPD2PS:
8154 ret_type = type_to_simd_type (MONO_TYPE_R4);
8155 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8156 AddFunc (module, name, ret_type, arg_types, 1);
8158 case INTRINS_SSE_CVTPS2PD:
8159 ret_type = type_to_simd_type (MONO_TYPE_R8);
8160 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8161 AddFunc (module, name, ret_type, arg_types, 1);
8163 case INTRINS_SSE_CMPPD:
8165 ret_type = type_to_simd_type (MONO_TYPE_R8);
8166 arg_types [0] = ret_type;
8167 arg_types [1] = ret_type;
8168 arg_types [2] = LLVMInt8Type ();
8169 AddFunc (module, name, ret_type, arg_types, 3);
8171 case INTRINS_SSE_CMPPS:
8172 ret_type = type_to_simd_type (MONO_TYPE_R4);
8173 arg_types [0] = ret_type;
8174 arg_types [1] = ret_type;
8175 arg_types [2] = LLVMInt8Type ();
8176 AddFunc (module, name, ret_type, arg_types, 3);
8178 case INTRINS_SSE_PACKSSWB:
8179 case INTRINS_SSE_PACKUSWB:
8180 case INTRINS_SSE_PACKSSDW:
8182 ret_type = type_to_simd_type (MONO_TYPE_I1);
8183 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8184 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8185 AddFunc (module, name, ret_type, arg_types, 2);
8187 case INTRINS_SSE_PACKUSDW:
8188 ret_type = type_to_simd_type (MONO_TYPE_I2);
8189 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8190 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8191 AddFunc (module, name, ret_type, arg_types, 2);
8193 /* SSE Binary ops */
8194 case INTRINS_SSE_PADDSW:
8195 case INTRINS_SSE_PSUBSW:
8196 case INTRINS_SSE_PADDUSW:
8197 case INTRINS_SSE_PSUBUSW:
8198 case INTRINS_SSE_PAVGW:
8199 case INTRINS_SSE_PMULHW:
8200 case INTRINS_SSE_PMULHU:
8201 add_sse_binary (module, name, MONO_TYPE_I2);
8203 case INTRINS_SSE_MINPS:
8204 case INTRINS_SSE_MAXPS:
8205 case INTRINS_SSE_HADDPS:
8206 case INTRINS_SSE_HSUBPS:
8207 case INTRINS_SSE_ADDSUBPS:
8208 add_sse_binary (module, name, MONO_TYPE_R4);
8210 case INTRINS_SSE_MINPD:
8211 case INTRINS_SSE_MAXPD:
8212 case INTRINS_SSE_HADDPD:
8213 case INTRINS_SSE_HSUBPD:
8214 case INTRINS_SSE_ADDSUBPD:
8215 add_sse_binary (module, name, MONO_TYPE_R8);
8217 case INTRINS_SE_PADDSB:
8218 case INTRINS_SSE_PSUBSB:
8219 case INTRINS_SSE_PADDUSB:
8220 case INTRINS_SSE_PSUBUSB:
8221 case INTRINS_SSE_PAVGB:
8222 add_sse_binary (module, name, MONO_TYPE_I1);
8224 case INTRINS_SSE_PAUSE:
8225 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8227 case INTRINS_SSE_DPPS:
8228 ret_type = type_to_simd_type (MONO_TYPE_R4);
8229 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8230 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8231 arg_types [2] = LLVMInt32Type ();
8232 AddFunc (module, name, ret_type, arg_types, 3);
8236 g_assert_not_reached ();
8242 get_intrinsic (EmitContext *ctx, const char *name)
8244 #if LLVM_API_VERSION > 100
8248 * Every method is emitted into its own module so
8249 * we can add intrinsics on demand.
8251 res = LLVMGetNamedFunction (ctx->lmodule, name);
8255 /* No locking needed */
8256 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8259 printf ("%s\n", name);
8260 g_assert (id != -1);
8261 add_intrinsic (ctx->lmodule, id);
8262 res = LLVMGetNamedFunction (ctx->lmodule, name);
8270 res = LLVMGetNamedFunction (ctx->lmodule, name);
8277 add_intrinsics (LLVMModuleRef module)
8281 /* Emit declarations of instrinsics */
8283 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8284 * type doesn't seem to do any locking.
8286 for (i = 0; i < INTRINS_NUM; ++i)
8287 add_intrinsic (module, i);
8291 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8293 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8296 /* Load/Store intrinsics */
8298 LLVMTypeRef arg_types [5];
8302 for (i = 1; i <= 8; i *= 2) {
8303 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8304 arg_types [1] = LLVMInt32Type ();
8305 arg_types [2] = LLVMInt1Type ();
8306 arg_types [3] = LLVMInt32Type ();
8307 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8308 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8310 arg_types [0] = LLVMIntType (i * 8);
8311 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8312 arg_types [2] = LLVMInt32Type ();
8313 arg_types [3] = LLVMInt1Type ();
8314 arg_types [4] = LLVMInt32Type ();
8315 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8316 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8322 add_types (MonoLLVMModule *module)
8324 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8328 mono_llvm_init (void)
8333 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8335 h = g_hash_table_new (NULL, NULL);
8336 for (i = 0; i < INTRINS_NUM; ++i)
8337 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8338 intrins_id_to_name = h;
8340 h = g_hash_table_new (g_str_hash, g_str_equal);
8341 for (i = 0; i < INTRINS_NUM; ++i)
8342 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8343 intrins_name_to_id = h;
8347 init_jit_module (MonoDomain *domain)
8349 MonoJitDomainInfo *dinfo;
8350 MonoLLVMModule *module;
8353 dinfo = domain_jit_info (domain);
8354 if (dinfo->llvm_module)
8357 mono_loader_lock ();
8359 if (dinfo->llvm_module) {
8360 mono_loader_unlock ();
8364 module = g_new0 (MonoLLVMModule, 1);
8366 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8367 module->lmodule = LLVMModuleCreateWithName (name);
8368 module->context = LLVMGetGlobalContext ();
8370 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8372 add_intrinsics (module->lmodule);
8375 module->llvm_types = g_hash_table_new (NULL, NULL);
8377 #if LLVM_API_VERSION < 100
8378 MonoJitICallInfo *info;
8380 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8382 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8385 mono_memory_barrier ();
8387 dinfo->llvm_module = module;
8389 mono_loader_unlock ();
8393 mono_llvm_cleanup (void)
8395 MonoLLVMModule *module = &aot_module;
8397 if (module->lmodule)
8398 LLVMDisposeModule (module->lmodule);
8400 if (module->context)
8401 LLVMContextDispose (module->context);
8405 mono_llvm_free_domain_info (MonoDomain *domain)
8407 MonoJitDomainInfo *info = domain_jit_info (domain);
8408 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8414 if (module->llvm_types)
8415 g_hash_table_destroy (module->llvm_types);
8417 mono_llvm_dispose_ee (module->mono_ee);
8419 if (module->bb_names) {
8420 for (i = 0; i < module->bb_names_len; ++i)
8421 g_free (module->bb_names [i]);
8422 g_free (module->bb_names);
8424 //LLVMDisposeModule (module->module);
8428 info->llvm_module = NULL;
8432 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, int initial_got_size, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8434 MonoLLVMModule *module = &aot_module;
8436 /* Delete previous module */
8437 if (module->plt_entries)
8438 g_hash_table_destroy (module->plt_entries);
8439 if (module->lmodule)
8440 LLVMDisposeModule (module->lmodule);
8442 memset (module, 0, sizeof (aot_module));
8444 module->lmodule = LLVMModuleCreateWithName ("aot");
8445 module->assembly = assembly;
8446 module->global_prefix = g_strdup (global_prefix);
8447 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8448 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8449 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8450 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8451 module->external_symbols = TRUE;
8452 module->emit_dwarf = emit_dwarf;
8453 module->static_link = static_link;
8454 module->llvm_only = llvm_only;
8455 /* The first few entries are reserved */
8456 module->max_got_offset = initial_got_size;
8457 module->context = LLVMGetGlobalContext ();
8460 /* clang ignores our debug info because it has an invalid version */
8461 module->emit_dwarf = FALSE;
8463 add_intrinsics (module->lmodule);
8466 #if LLVM_API_VERSION > 100
8467 if (module->emit_dwarf) {
8468 char *dir, *build_info, *s, *cu_name;
8470 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8473 dir = g_strdup (".");
8474 build_info = mono_get_runtime_build_info ();
8475 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8476 cu_name = g_path_get_basename (assembly->image->name);
8477 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8479 g_free (build_info);
8486 * We couldn't compute the type of the LLVM global representing the got because
8487 * its size is only known after all the methods have been emitted. So create
8488 * a dummy variable, and replace all uses it with the real got variable when
8489 * its size is known in mono_llvm_emit_aot_module ().
8492 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8494 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8495 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8498 /* Add initialization array */
8500 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8502 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8503 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8507 emit_init_icall_wrappers (module);
8509 emit_llvm_code_start (module);
8511 /* Add a dummy personality function */
8512 if (!use_debug_personality) {
8513 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8514 LLVMSetLinkage (personality, LLVMExternalLinkage);
8515 mark_as_used (module, personality);
8518 /* Add a reference to the c++ exception we throw/catch */
8520 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8521 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8522 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8523 mono_llvm_set_is_constant (module->sentinel_exception);
8526 module->llvm_types = g_hash_table_new (NULL, NULL);
8527 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8528 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8529 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8530 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8531 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8532 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8533 module->method_to_callers = g_hash_table_new (NULL, NULL);
8537 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8540 LLVMValueRef res, *vals;
8542 vals = g_new0 (LLVMValueRef, nvalues);
8543 for (i = 0; i < nvalues; ++i)
8544 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8545 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8551 llvm_array_from_bytes (guint8 *values, int nvalues)
8554 LLVMValueRef res, *vals;
8556 vals = g_new0 (LLVMValueRef, nvalues);
8557 for (i = 0; i < nvalues; ++i)
8558 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8559 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8564 * mono_llvm_emit_aot_file_info:
8566 * Emit the MonoAotFileInfo structure.
8567 * Same as emit_aot_file_info () in aot-compiler.c.
8570 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8572 MonoLLVMModule *module = &aot_module;
8574 /* Save these for later */
8575 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8576 module->has_jitted_code = has_jitted_code;
8580 * mono_llvm_emit_aot_data:
8582 * Emit the binary data DATA pointed to by symbol SYMBOL.
8585 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8587 MonoLLVMModule *module = &aot_module;
8591 type = LLVMArrayType (LLVMInt8Type (), data_len);
8592 d = LLVMAddGlobal (module->lmodule, type, symbol);
8593 LLVMSetVisibility (d, LLVMHiddenVisibility);
8594 LLVMSetLinkage (d, LLVMInternalLinkage);
8595 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8596 LLVMSetAlignment (d, 8);
8597 mono_llvm_set_is_constant (d);
8600 /* Add a reference to a global defined in JITted code */
8602 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8607 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8608 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8614 emit_aot_file_info (MonoLLVMModule *module)
8616 LLVMTypeRef file_info_type;
8617 LLVMTypeRef *eltypes, eltype;
8618 LLVMValueRef info_var;
8619 LLVMValueRef *fields;
8620 int i, nfields, tindex;
8621 MonoAotFileInfo *info;
8622 LLVMModuleRef lmodule = module->lmodule;
8624 info = &module->aot_info;
8626 /* Create an LLVM type to represent MonoAotFileInfo */
8627 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8628 eltypes = g_new (LLVMTypeRef, nfields);
8630 eltypes [tindex ++] = LLVMInt32Type ();
8631 eltypes [tindex ++] = LLVMInt32Type ();
8633 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8634 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8636 for (i = 0; i < 15; ++i)
8637 eltypes [tindex ++] = LLVMInt32Type ();
8639 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8640 for (i = 0; i < 4; ++i)
8641 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8642 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8643 g_assert (tindex == nfields);
8644 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8645 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8647 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8648 if (module->static_link) {
8649 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8650 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8652 fields = g_new (LLVMValueRef, nfields);
8654 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8655 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8659 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8660 * for symbols defined in the .s file emitted by the aot compiler.
8662 eltype = eltypes [tindex];
8663 if (module->llvm_only)
8664 fields [tindex ++] = LLVMConstNull (eltype);
8666 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8667 fields [tindex ++] = module->got_var;
8668 /* llc defines this directly */
8669 if (!module->llvm_only) {
8670 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8671 fields [tindex ++] = LLVMConstNull (eltype);
8672 fields [tindex ++] = LLVMConstNull (eltype);
8674 fields [tindex ++] = LLVMConstNull (eltype);
8675 fields [tindex ++] = module->get_method;
8676 fields [tindex ++] = module->get_unbox_tramp;
8678 if (module->has_jitted_code) {
8679 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8680 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8682 fields [tindex ++] = LLVMConstNull (eltype);
8683 fields [tindex ++] = LLVMConstNull (eltype);
8685 if (!module->llvm_only)
8686 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8688 fields [tindex ++] = LLVMConstNull (eltype);
8689 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8690 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8691 fields [tindex ++] = LLVMConstNull (eltype);
8693 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8694 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8695 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8696 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8697 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8698 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8699 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8700 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8701 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8702 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8704 /* Not needed (mem_end) */
8705 fields [tindex ++] = LLVMConstNull (eltype);
8706 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8707 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8708 if (info->trampoline_size [0]) {
8709 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8710 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8711 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8712 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8714 fields [tindex ++] = LLVMConstNull (eltype);
8715 fields [tindex ++] = LLVMConstNull (eltype);
8716 fields [tindex ++] = LLVMConstNull (eltype);
8717 fields [tindex ++] = LLVMConstNull (eltype);
8719 if (module->static_link && !module->llvm_only)
8720 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8722 fields [tindex ++] = LLVMConstNull (eltype);
8723 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8724 if (!module->llvm_only) {
8725 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8726 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8727 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8728 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8729 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8730 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8732 fields [tindex ++] = LLVMConstNull (eltype);
8733 fields [tindex ++] = LLVMConstNull (eltype);
8734 fields [tindex ++] = LLVMConstNull (eltype);
8735 fields [tindex ++] = LLVMConstNull (eltype);
8736 fields [tindex ++] = LLVMConstNull (eltype);
8737 fields [tindex ++] = LLVMConstNull (eltype);
8740 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8741 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8744 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8745 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8746 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8747 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8748 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8749 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8750 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8751 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8752 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8753 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8754 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8755 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8756 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8757 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8758 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8760 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8761 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8762 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8763 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8764 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8766 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8767 g_assert (tindex == nfields);
8769 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8771 if (module->static_link) {
8775 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8776 /* Get rid of characters which cannot occur in symbols */
8778 for (p = s; *p; ++p) {
8779 if (!(isalnum (*p) || *p == '_'))
8782 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8784 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8785 LLVMSetLinkage (var, LLVMExternalLinkage);
8790 * Emit the aot module into the LLVM bitcode file FILENAME.
8793 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8795 LLVMTypeRef got_type, inited_type;
8796 LLVMValueRef real_got, real_inited;
8797 MonoLLVMModule *module = &aot_module;
8799 emit_llvm_code_end (module);
8802 * Create the real got variable and replace all uses of the dummy variable with
8805 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8806 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8807 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8808 if (module->external_symbols) {
8809 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8810 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8812 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8814 mono_llvm_replace_uses_of (module->got_var, real_got);
8816 mark_as_used (&aot_module, real_got);
8818 /* Delete the dummy got so it doesn't become a global */
8819 LLVMDeleteGlobal (module->got_var);
8820 module->got_var = real_got;
8823 * Same for the init_var
8825 if (module->llvm_only) {
8826 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8827 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8828 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8829 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8830 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8831 LLVMDeleteGlobal (module->inited_var);
8834 if (module->llvm_only) {
8835 emit_get_method (&aot_module);
8836 emit_get_unbox_tramp (&aot_module);
8839 emit_llvm_used (&aot_module);
8840 emit_dbg_info (&aot_module, filename, cu_name);
8841 emit_aot_file_info (&aot_module);
8844 * Replace GOT entries for directly callable methods with the methods themselves.
8845 * It would be easier to implement this by predefining all methods before compiling
8846 * their bodies, but that couldn't handle the case when a method fails to compile
8849 if (module->llvm_only) {
8850 GHashTableIter iter;
8852 GSList *callers, *l;
8854 g_hash_table_iter_init (&iter, module->method_to_callers);
8855 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8856 LLVMValueRef lmethod;
8858 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8861 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8863 for (l = callers; l; l = l->next) {
8864 LLVMValueRef caller = (LLVMValueRef)l->data;
8866 mono_llvm_replace_uses_of (caller, lmethod);
8872 /* Replace PLT entries for directly callable methods with the methods themselves */
8874 GHashTableIter iter;
8876 LLVMValueRef callee;
8878 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8879 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8880 if (mono_aot_is_direct_callable (ji)) {
8881 LLVMValueRef lmethod;
8883 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8884 /* The types might not match because the caller might pass an rgctx */
8885 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8886 mono_llvm_replace_uses_of (callee, lmethod);
8887 mono_aot_mark_unused_llvm_plt_entry (ji);
8897 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8898 printf ("%s\n", verifier_err);
8899 g_assert_not_reached ();
8904 LLVMWriteBitcodeToFile (module->lmodule, filename);
8909 md_string (const char *s)
8911 return LLVMMDString (s, strlen (s));
8914 /* Debugging support */
8917 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8919 LLVMModuleRef lmodule = module->lmodule;
8920 LLVMValueRef args [16], ver;
8923 * This can only be enabled when LLVM code is emitted into a separate object
8924 * file, since the AOT compiler also emits dwarf info,
8925 * and the abbrev indexes will not be correct since llvm has added its own
8928 if (!module->emit_dwarf)
8931 #if LLVM_API_VERSION > 100
8932 mono_llvm_di_builder_finalize (module->di_builder);
8934 LLVMValueRef cu_args [16], cu;
8936 char *build_info, *s, *dir;
8939 * Emit dwarf info in the form of LLVM metadata. There is some
8940 * out-of-date documentation at:
8941 * http://llvm.org/docs/SourceLevelDebugging.html
8942 * but most of this was gathered from the llvm and
8947 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8948 /* CU name/compilation dir */
8949 dir = g_path_get_dirname (filename);
8950 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8951 args [1] = LLVMMDString (dir, strlen (dir));
8952 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8955 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8957 build_info = mono_get_runtime_build_info ();
8958 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8959 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8960 g_free (build_info);
8962 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8964 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8965 /* Runtime version */
8966 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8968 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8969 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8971 if (module->subprogram_mds) {
8975 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8976 for (i = 0; i < module->subprogram_mds->len; ++i)
8977 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8978 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8980 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8983 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8984 /* Imported modules */
8985 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8987 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8988 /* DebugEmissionKind = FullDebug */
8989 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8990 cu = LLVMMDNode (cu_args, n_cuargs);
8991 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8994 #if LLVM_API_VERSION > 100
8995 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8996 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8997 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8998 ver = LLVMMDNode (args, 3);
8999 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9001 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
9002 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9003 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
9004 ver = LLVMMDNode (args, 3);
9005 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9007 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9008 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9009 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
9010 ver = LLVMMDNode (args, 3);
9011 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9013 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9014 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9015 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9016 ver = LLVMMDNode (args, 3);
9017 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9022 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9024 MonoLLVMModule *module = ctx->module;
9025 MonoDebugMethodInfo *minfo = ctx->minfo;
9026 char *source_file, *dir, *filename;
9027 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9028 MonoSymSeqPoint *sym_seq_points;
9034 mono_debug_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9036 source_file = g_strdup ("<unknown>");
9037 dir = g_path_get_dirname (source_file);
9038 filename = g_path_get_basename (source_file);
9040 #if LLVM_API_VERSION > 100
9041 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);
9044 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9045 args [0] = md_string (filename);
9046 args [1] = md_string (dir);
9047 ctx_args [1] = LLVMMDNode (args, 2);
9048 ctx_md = LLVMMDNode (ctx_args, 2);
9050 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9051 type_args [1] = NULL;
9052 type_args [2] = NULL;
9053 type_args [3] = LLVMMDString ("", 0);
9054 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9055 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9056 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9057 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9058 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9059 type_args [9] = NULL;
9060 type_args [10] = NULL;
9061 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9062 type_args [12] = NULL;
9063 type_args [13] = NULL;
9064 type_args [14] = NULL;
9065 type_md = LLVMMDNode (type_args, 14);
9067 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9068 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9069 /* Source directory + file pair */
9070 args [0] = md_string (filename);
9071 args [1] = md_string (dir);
9072 md_args [1] = LLVMMDNode (args ,2);
9073 md_args [2] = ctx_md;
9074 md_args [3] = md_string (cfg->method->name);
9075 md_args [4] = md_string (name);
9076 md_args [5] = md_string (name);
9079 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9081 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9083 md_args [7] = type_md;
9085 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9087 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9089 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9090 /* Index into a virtual function */
9091 md_args [11] = NULL;
9092 md_args [12] = NULL;
9094 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9096 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9097 /* Pointer to LLVM function */
9098 md_args [15] = method;
9099 /* Function template parameter */
9100 md_args [16] = NULL;
9101 /* Function declaration descriptor */
9102 md_args [17] = NULL;
9103 /* List of function variables */
9104 md_args [18] = LLVMMDNode (args, 0);
9106 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9107 md = LLVMMDNode (md_args, 20);
9109 if (!module->subprogram_mds)
9110 module->subprogram_mds = g_ptr_array_new ();
9111 g_ptr_array_add (module->subprogram_mds, md);
9115 g_free (source_file);
9116 g_free (sym_seq_points);
9122 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9124 MonoCompile *cfg = ctx->cfg;
9126 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9127 MonoDebugSourceLocation *loc;
9128 LLVMValueRef loc_md;
9130 loc = mono_debug_method_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9133 #if LLVM_API_VERSION > 100
9134 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9135 mono_llvm_di_set_location (builder, loc_md);
9137 LLVMValueRef md_args [16];
9141 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9142 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9143 md_args [nmd_args ++] = ctx->dbg_md;
9144 md_args [nmd_args ++] = NULL;
9145 loc_md = LLVMMDNode (md_args, nmd_args);
9146 LLVMSetCurrentDebugLocation (builder, loc_md);
9148 mono_debug_free_source_location (loc);
9154 default_mono_llvm_unhandled_exception (void)
9156 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9157 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9159 mono_unhandled_exception (target);
9160 mono_invoke_unhandled_exception_hook (target);
9161 g_assert_not_reached ();
9166 - Emit LLVM IR from the mono IR using the LLVM C API.
9167 - The original arch specific code remains, so we can fall back to it if we run
9168 into something we can't handle.
9172 A partial list of issues:
9173 - Handling of opcodes which can throw exceptions.
9175 In the mono JIT, these are implemented using code like this:
9182 push throw_pos - method
9183 call <exception trampoline>
9185 The problematic part is push throw_pos - method, which cannot be represented
9186 in the LLVM IR, since it does not support label values.
9187 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9188 be implemented in JIT mode ?
9189 -> a possible but slower implementation would use the normal exception
9190 throwing code but it would need to control the placement of the throw code
9191 (it needs to be exactly after the compare+branch).
9192 -> perhaps add a PC offset intrinsics ?
9194 - efficient implementation of .ovf opcodes.
9196 These are currently implemented as:
9197 <ins which sets the condition codes>
9200 Some overflow opcodes are now supported by LLVM SVN.
9202 - exception handling, unwinding.
9203 - SSA is disabled for methods with exception handlers
9204 - How to obtain unwind info for LLVM compiled methods ?
9205 -> this is now solved by converting the unwind info generated by LLVM
9207 - LLVM uses the c++ exception handling framework, while we use our home grown
9208 code, and couldn't use the c++ one:
9209 - its not supported under VC++, other exotic platforms.
9210 - it might be impossible to support filter clauses with it.
9214 The trampolines need a predictable call sequence, since they need to disasm
9215 the calling code to obtain register numbers / offsets.
9217 LLVM currently generates this code in non-JIT mode:
9218 mov -0x98(%rax),%eax
9220 Here, the vtable pointer is lost.
9221 -> solution: use one vtable trampoline per class.
9223 - passing/receiving the IMT pointer/RGCTX.
9224 -> solution: pass them as normal arguments ?
9228 LLVM does not allow the specification of argument registers etc. This means
9229 that all calls are made according to the platform ABI.
9231 - passing/receiving vtypes.
9233 Vtypes passed/received in registers are handled by the front end by using
9234 a signature with scalar arguments, and loading the parts of the vtype into those
9237 Vtypes passed on the stack are handled using the 'byval' attribute.
9241 Supported though alloca, we need to emit the load/store code.
9245 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9246 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9247 This is made easier because the IR is already in SSA form.
9248 An additional problem is that our IR is not consistent with types, i.e. i32/i64
9249 types are frequently used incorrectly.
9254 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9255 it with the file containing the methods emitted by the JIT and the AOT data
9259 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9260 * - each bblock should end with a branch
9261 * - setting the return value, making cfg->ret non-volatile
9262 * - avoid some transformations in the JIT which make it harder for us to generate
9264 * - use pointer types to help optimizations.
9267 #else /* DISABLE_JIT */
9270 mono_llvm_cleanup (void)
9275 mono_llvm_free_domain_info (MonoDomain *domain)
9280 mono_llvm_init (void)
9285 default_mono_llvm_unhandled_exception (void)
9289 #endif /* DISABLE_JIT */