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);
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);
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))
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)) {
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 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4989 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4990 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4995 case OP_ICONV_TO_I1:
4996 case OP_ICONV_TO_I2:
4997 case OP_ICONV_TO_I4:
4998 case OP_ICONV_TO_U1:
4999 case OP_ICONV_TO_U2:
5000 case OP_ICONV_TO_U4:
5001 case OP_LCONV_TO_I1:
5002 case OP_LCONV_TO_I2:
5003 case OP_LCONV_TO_U1:
5004 case OP_LCONV_TO_U2:
5005 case OP_LCONV_TO_U4: {
5008 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);
5010 /* Have to do two casts since our vregs have type int */
5011 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
5013 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
5015 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
5018 case OP_ICONV_TO_I8:
5019 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
5021 case OP_ICONV_TO_U8:
5022 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
5024 case OP_FCONV_TO_I4:
5025 case OP_RCONV_TO_I4:
5026 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
5028 case OP_FCONV_TO_I1:
5029 case OP_RCONV_TO_I1:
5030 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
5032 case OP_FCONV_TO_U1:
5033 case OP_RCONV_TO_U1:
5034 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5036 case OP_FCONV_TO_I2:
5037 case OP_RCONV_TO_I2:
5038 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5040 case OP_FCONV_TO_U2:
5041 case OP_RCONV_TO_U2:
5042 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5044 case OP_RCONV_TO_U4:
5045 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5047 case OP_FCONV_TO_I8:
5048 case OP_RCONV_TO_I8:
5049 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5052 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5054 case OP_ICONV_TO_R8:
5055 case OP_LCONV_TO_R8:
5056 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5058 case OP_ICONV_TO_R_UN:
5059 case OP_LCONV_TO_R_UN:
5060 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5062 #if SIZEOF_VOID_P == 4
5065 case OP_LCONV_TO_I4:
5066 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5068 case OP_ICONV_TO_R4:
5069 case OP_LCONV_TO_R4:
5070 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5072 values [ins->dreg] = v;
5074 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5076 case OP_FCONV_TO_R4:
5077 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5079 values [ins->dreg] = v;
5081 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5083 case OP_RCONV_TO_R8:
5084 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5086 case OP_RCONV_TO_R4:
5087 values [ins->dreg] = lhs;
5090 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5093 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5096 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5098 case OP_LOCALLOC_IMM: {
5101 guint32 size = ins->inst_imm;
5102 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5104 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5106 if (ins->flags & MONO_INST_INIT) {
5107 LLVMValueRef args [5];
5110 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5111 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5112 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5113 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5114 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5117 values [ins->dreg] = v;
5121 LLVMValueRef v, size;
5123 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), "");
5125 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5127 if (ins->flags & MONO_INST_INIT) {
5128 LLVMValueRef args [5];
5131 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5133 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5134 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5135 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5137 values [ins->dreg] = v;
5141 case OP_LOADI1_MEMBASE:
5142 case OP_LOADU1_MEMBASE:
5143 case OP_LOADI2_MEMBASE:
5144 case OP_LOADU2_MEMBASE:
5145 case OP_LOADI4_MEMBASE:
5146 case OP_LOADU4_MEMBASE:
5147 case OP_LOADI8_MEMBASE:
5148 case OP_LOADR4_MEMBASE:
5149 case OP_LOADR8_MEMBASE:
5150 case OP_LOAD_MEMBASE:
5158 LLVMValueRef base, index, addr;
5160 gboolean sext = FALSE, zext = FALSE;
5161 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5163 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5168 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)) {
5169 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5175 if (ins->inst_offset == 0) {
5177 } else if (ins->inst_offset % size != 0) {
5178 /* Unaligned load */
5179 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5180 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5182 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5183 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5187 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5189 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5191 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5193 * These will signal LLVM that these loads do not alias any stores, and
5194 * they can't fail, allowing them to be hoisted out of loops.
5196 set_invariant_load_flag (values [ins->dreg]);
5197 #if LLVM_API_VERSION < 100
5198 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5203 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5205 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5206 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5207 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5211 case OP_STOREI1_MEMBASE_REG:
5212 case OP_STOREI2_MEMBASE_REG:
5213 case OP_STOREI4_MEMBASE_REG:
5214 case OP_STOREI8_MEMBASE_REG:
5215 case OP_STORER4_MEMBASE_REG:
5216 case OP_STORER8_MEMBASE_REG:
5217 case OP_STORE_MEMBASE_REG: {
5219 LLVMValueRef index, addr, base;
5221 gboolean sext = FALSE, zext = FALSE;
5222 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5224 if (!values [ins->inst_destbasereg]) {
5225 set_failure (ctx, "inst_destbasereg");
5229 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5231 base = values [ins->inst_destbasereg];
5232 if (ins->inst_offset % size != 0) {
5233 /* Unaligned store */
5234 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5235 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5237 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5238 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5240 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5244 case OP_STOREI1_MEMBASE_IMM:
5245 case OP_STOREI2_MEMBASE_IMM:
5246 case OP_STOREI4_MEMBASE_IMM:
5247 case OP_STOREI8_MEMBASE_IMM:
5248 case OP_STORE_MEMBASE_IMM: {
5250 LLVMValueRef index, addr, base;
5252 gboolean sext = FALSE, zext = FALSE;
5253 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5255 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5257 base = values [ins->inst_destbasereg];
5258 if (ins->inst_offset % size != 0) {
5259 /* Unaligned store */
5260 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5261 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5263 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5264 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5266 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5271 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5273 case OP_OUTARG_VTRETADDR:
5281 case OP_VOIDCALL_MEMBASE:
5282 case OP_CALL_MEMBASE:
5283 case OP_LCALL_MEMBASE:
5284 case OP_FCALL_MEMBASE:
5285 case OP_RCALL_MEMBASE:
5286 case OP_VCALL_MEMBASE:
5287 case OP_VOIDCALL_REG:
5292 case OP_VCALL_REG: {
5293 process_call (ctx, bb, &builder, ins);
5298 LLVMValueRef indexes [2];
5299 MonoJumpInfo *tmp_ji, *ji;
5300 LLVMValueRef got_entry_addr;
5304 * FIXME: Can't allocate from the cfg mempool since that is freed if
5305 * the LLVM compile fails.
5307 tmp_ji = g_new0 (MonoJumpInfo, 1);
5308 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5309 tmp_ji->data.target = ins->inst_p0;
5311 ji = mono_aot_patch_info_dup (tmp_ji);
5314 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5315 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5318 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5319 * resolvable at runtime using dlsym ().
5322 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5327 ji->next = cfg->patch_info;
5328 cfg->patch_info = ji;
5330 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5331 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5332 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5333 if (!mono_aot_is_shared_got_offset (got_offset)) {
5334 //mono_print_ji (ji);
5336 ctx->has_got_access = TRUE;
5339 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5340 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5341 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5343 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5344 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5346 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5347 if (!cfg->llvm_only)
5348 set_invariant_load_flag (values [ins->dreg]);
5351 case OP_NOT_REACHED:
5352 LLVMBuildUnreachable (builder);
5353 has_terminator = TRUE;
5354 g_assert (bb->block_num < cfg->max_block_num);
5355 ctx->unreachable [bb->block_num] = TRUE;
5356 /* Might have instructions after this */
5358 MonoInst *next = ins->next;
5360 * FIXME: If later code uses the regs defined by these instructions,
5361 * compilation will fail.
5363 MONO_DELETE_INS (bb, next);
5367 MonoInst *var = ins->inst_i0;
5369 if (var->opcode == OP_VTARG_ADDR) {
5370 /* The variable contains the vtype address */
5371 values [ins->dreg] = values [var->dreg];
5372 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5373 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5375 values [ins->dreg] = addresses [var->dreg];
5380 LLVMValueRef args [1];
5382 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5383 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5387 LLVMValueRef args [1];
5389 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5390 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5394 LLVMValueRef args [1];
5396 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5397 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5401 LLVMValueRef args [1];
5403 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5404 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5418 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5419 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5421 switch (ins->opcode) {
5424 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5428 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5432 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5436 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5439 g_assert_not_reached ();
5442 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5447 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5448 * hack is necessary (for now).
5451 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5453 #define ARM64_ATOMIC_FENCE_FIX
5456 case OP_ATOMIC_EXCHANGE_I4:
5457 case OP_ATOMIC_EXCHANGE_I8: {
5458 LLVMValueRef args [2];
5461 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5462 t = LLVMInt32Type ();
5464 t = LLVMInt64Type ();
5466 g_assert (ins->inst_offset == 0);
5468 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5469 args [1] = convert (ctx, rhs, t);
5471 ARM64_ATOMIC_FENCE_FIX;
5472 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5473 ARM64_ATOMIC_FENCE_FIX;
5476 case OP_ATOMIC_ADD_I4:
5477 case OP_ATOMIC_ADD_I8: {
5478 LLVMValueRef args [2];
5481 if (ins->opcode == OP_ATOMIC_ADD_I4)
5482 t = LLVMInt32Type ();
5484 t = LLVMInt64Type ();
5486 g_assert (ins->inst_offset == 0);
5488 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5489 args [1] = convert (ctx, rhs, t);
5490 ARM64_ATOMIC_FENCE_FIX;
5491 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5492 ARM64_ATOMIC_FENCE_FIX;
5495 case OP_ATOMIC_CAS_I4:
5496 case OP_ATOMIC_CAS_I8: {
5497 LLVMValueRef args [3], val;
5500 if (ins->opcode == OP_ATOMIC_CAS_I4)
5501 t = LLVMInt32Type ();
5503 t = LLVMInt64Type ();
5505 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5507 args [1] = convert (ctx, values [ins->sreg3], t);
5509 args [2] = convert (ctx, values [ins->sreg2], t);
5510 ARM64_ATOMIC_FENCE_FIX;
5511 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5512 ARM64_ATOMIC_FENCE_FIX;
5513 /* cmpxchg returns a pair */
5514 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5517 case OP_MEMORY_BARRIER: {
5518 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5521 case OP_ATOMIC_LOAD_I1:
5522 case OP_ATOMIC_LOAD_I2:
5523 case OP_ATOMIC_LOAD_I4:
5524 case OP_ATOMIC_LOAD_I8:
5525 case OP_ATOMIC_LOAD_U1:
5526 case OP_ATOMIC_LOAD_U2:
5527 case OP_ATOMIC_LOAD_U4:
5528 case OP_ATOMIC_LOAD_U8:
5529 case OP_ATOMIC_LOAD_R4:
5530 case OP_ATOMIC_LOAD_R8: {
5531 #if LLVM_API_VERSION > 100
5533 gboolean sext, zext;
5535 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5536 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5537 LLVMValueRef index, addr;
5539 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5544 if (ins->inst_offset != 0) {
5545 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5546 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5551 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5553 ARM64_ATOMIC_FENCE_FIX;
5554 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5555 ARM64_ATOMIC_FENCE_FIX;
5558 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5560 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5563 set_failure (ctx, "atomic mono.load intrinsic");
5567 case OP_ATOMIC_STORE_I1:
5568 case OP_ATOMIC_STORE_I2:
5569 case OP_ATOMIC_STORE_I4:
5570 case OP_ATOMIC_STORE_I8:
5571 case OP_ATOMIC_STORE_U1:
5572 case OP_ATOMIC_STORE_U2:
5573 case OP_ATOMIC_STORE_U4:
5574 case OP_ATOMIC_STORE_U8:
5575 case OP_ATOMIC_STORE_R4:
5576 case OP_ATOMIC_STORE_R8: {
5578 gboolean sext, zext;
5580 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5581 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5582 LLVMValueRef index, addr, value, base;
5584 #if LLVM_API_VERSION < 100
5585 if (!cfg->llvm_only) {
5586 set_failure (ctx, "atomic mono.store intrinsic");
5591 if (!values [ins->inst_destbasereg]) {
5592 set_failure (ctx, "inst_destbasereg");
5596 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5598 base = values [ins->inst_destbasereg];
5599 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5600 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5601 value = convert (ctx, values [ins->sreg1], t);
5603 ARM64_ATOMIC_FENCE_FIX;
5604 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5605 ARM64_ATOMIC_FENCE_FIX;
5608 case OP_RELAXED_NOP: {
5609 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5610 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5617 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5619 // 257 == FS segment register
5620 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5622 // 256 == GS segment register
5623 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5626 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5627 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5628 /* See mono_amd64_emit_tls_get () */
5629 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5631 // 256 == GS segment register
5632 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5633 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5635 set_failure (ctx, "opcode tls-get");
5641 case OP_GC_SAFE_POINT: {
5642 LLVMValueRef val, cmp, callee;
5643 LLVMBasicBlockRef poll_bb, cont_bb;
5644 static LLVMTypeRef sig;
5645 const char *icall_name = "mono_threads_state_poll";
5648 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5652 * mono_threads_state_poll ();
5653 * FIXME: Use a preserveall wrapper
5655 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5656 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5657 poll_bb = gen_bb (ctx, "POLL_BB");
5658 cont_bb = gen_bb (ctx, "CONT_BB");
5659 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5661 ctx->builder = builder = create_builder (ctx);
5662 LLVMPositionBuilderAtEnd (builder, poll_bb);
5664 if (ctx->cfg->compile_aot) {
5665 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5667 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5668 callee = emit_jit_callee (ctx, icall_name, sig, target);
5670 LLVMBuildCall (builder, callee, NULL, 0, "");
5671 LLVMBuildBr (builder, cont_bb);
5673 ctx->builder = builder = create_builder (ctx);
5674 LLVMPositionBuilderAtEnd (builder, cont_bb);
5675 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5683 case OP_IADD_OVF_UN:
5685 case OP_ISUB_OVF_UN:
5687 case OP_IMUL_OVF_UN:
5689 case OP_LADD_OVF_UN:
5691 case OP_LSUB_OVF_UN:
5693 case OP_LMUL_OVF_UN:
5695 LLVMValueRef args [2], val, ovf, func;
5697 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5698 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5699 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5701 val = LLVMBuildCall (builder, func, args, 2, "");
5702 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5703 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5704 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5707 builder = ctx->builder;
5713 * We currently model them using arrays. Promotion to local vregs is
5714 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5715 * so we always have an entry in cfg->varinfo for them.
5716 * FIXME: Is this needed ?
5719 MonoClass *klass = ins->klass;
5720 LLVMValueRef args [5];
5724 set_failure (ctx, "!klass");
5728 if (!addresses [ins->dreg])
5729 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5730 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5731 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5732 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5734 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5735 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5736 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5739 case OP_DUMMY_VZERO:
5742 case OP_STOREV_MEMBASE:
5743 case OP_LOADV_MEMBASE:
5745 MonoClass *klass = ins->klass;
5746 LLVMValueRef src = NULL, dst, args [5];
5747 gboolean done = FALSE;
5751 set_failure (ctx, "!klass");
5755 if (mini_is_gsharedvt_klass (klass)) {
5757 set_failure (ctx, "gsharedvt");
5761 switch (ins->opcode) {
5762 case OP_STOREV_MEMBASE:
5763 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5764 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5765 /* Decomposed earlier */
5766 g_assert_not_reached ();
5769 if (!addresses [ins->sreg1]) {
5771 g_assert (values [ins->sreg1]);
5772 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));
5773 LLVMBuildStore (builder, values [ins->sreg1], dst);
5776 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5777 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5780 case OP_LOADV_MEMBASE:
5781 if (!addresses [ins->dreg])
5782 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5783 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5784 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5787 if (!addresses [ins->sreg1])
5788 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5789 if (!addresses [ins->dreg])
5790 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5791 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5792 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5795 g_assert_not_reached ();
5805 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5806 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5808 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5809 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5810 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5813 case OP_LLVM_OUTARG_VT: {
5814 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5815 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5817 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5818 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5820 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5821 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5823 g_assert (addresses [ins->sreg1]);
5824 addresses [ins->dreg] = addresses [ins->sreg1];
5826 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5827 if (!addresses [ins->sreg1]) {
5828 addresses [ins->sreg1] = build_alloca (ctx, t);
5829 g_assert (values [ins->sreg1]);
5831 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5832 addresses [ins->dreg] = addresses [ins->sreg1];
5834 if (!addresses [ins->sreg1]) {
5835 addresses [ins->sreg1] = build_alloca (ctx, t);
5836 g_assert (values [ins->sreg1]);
5837 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5839 addresses [ins->dreg] = addresses [ins->sreg1];
5843 case OP_OBJC_GET_SELECTOR: {
5844 const char *name = (const char*)ins->inst_p0;
5847 if (!ctx->module->objc_selector_to_var) {
5848 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5850 LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
5851 int32_t objc_imageinfo [] = { 0, 16 };
5852 LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
5853 LLVMSetLinkage (info_var, LLVMPrivateLinkage);
5854 LLVMSetExternallyInitialized (info_var, TRUE);
5855 LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
5856 LLVMSetAlignment (info_var, sizeof (mgreg_t));
5857 mark_as_used (ctx->module, info_var);
5860 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5862 LLVMValueRef indexes [16];
5864 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5865 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5866 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5867 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5868 mark_as_used (ctx->module, name_var);
5870 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5872 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5873 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5874 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5875 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5876 LLVMSetExternallyInitialized (ref_var, TRUE);
5877 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5878 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5879 mark_as_used (ctx->module, ref_var);
5881 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5885 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5892 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5894 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5897 case OP_LOADX_MEMBASE: {
5898 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5901 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5902 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5905 case OP_STOREX_MEMBASE: {
5906 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5909 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5910 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5917 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5921 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5927 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5931 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5935 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5939 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5942 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5945 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5948 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5952 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5963 LLVMValueRef v = NULL;
5965 switch (ins->opcode) {
5970 t = LLVMVectorType (LLVMInt32Type (), 4);
5971 rt = LLVMVectorType (LLVMFloatType (), 4);
5977 t = LLVMVectorType (LLVMInt64Type (), 2);
5978 rt = LLVMVectorType (LLVMDoubleType (), 2);
5981 t = LLVMInt32Type ();
5982 rt = LLVMInt32Type ();
5983 g_assert_not_reached ();
5986 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5987 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5988 switch (ins->opcode) {
5991 v = LLVMBuildAnd (builder, lhs, rhs, "");
5995 v = LLVMBuildOr (builder, lhs, rhs, "");
5999 v = LLVMBuildXor (builder, lhs, rhs, "");
6003 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
6006 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
6012 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
6013 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6019 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6020 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6024 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6025 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6042 case OP_PADDB_SAT_UN:
6043 case OP_PADDW_SAT_UN:
6044 case OP_PSUBB_SAT_UN:
6045 case OP_PSUBW_SAT_UN:
6053 case OP_PMULW_HIGH_UN: {
6054 LLVMValueRef args [2];
6059 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6066 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6070 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6078 case OP_EXTRACTX_U2:
6080 case OP_EXTRACT_U1: {
6082 gboolean zext = FALSE;
6084 t = simd_op_to_llvm_type (ins->opcode);
6086 switch (ins->opcode) {
6094 case OP_EXTRACTX_U2:
6099 t = LLVMInt32Type ();
6100 g_assert_not_reached ();
6103 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6104 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6106 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6115 case OP_EXPAND_R8: {
6116 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6117 LLVMValueRef mask [16], v;
6120 for (i = 0; i < 16; ++i)
6121 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6123 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6125 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6126 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6131 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6134 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6137 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6140 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6143 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6146 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6149 #if LLVM_API_VERSION > 100
6151 LLVMValueRef indexes [16];
6153 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6154 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6155 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6156 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6157 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6161 LLVMValueRef indexes [16];
6163 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6164 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6165 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6166 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6167 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6171 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6175 #if LLVM_API_VERSION <= 100
6185 case OP_EXTRACT_MASK:
6192 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6194 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6199 LLVMRealPredicate op;
6201 switch (ins->inst_c0) {
6211 case SIMD_COMP_UNORD:
6227 g_assert_not_reached ();
6230 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6231 if (ins->opcode == OP_COMPPD)
6232 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6234 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6238 /* This is only used for implementing shifts by non-immediate */
6239 values [ins->dreg] = lhs;
6250 LLVMValueRef args [3];
6253 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6255 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6266 case OP_PSHLQ_REG: {
6267 LLVMValueRef args [3];
6270 args [1] = values [ins->sreg2];
6272 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6279 case OP_PSHUFLEW_LOW:
6280 case OP_PSHUFLEW_HIGH: {
6282 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6283 int i, mask_size = 0;
6284 int imask = ins->inst_c0;
6286 /* Convert the x86 shuffle mask to LLVM's */
6287 switch (ins->opcode) {
6290 mask [0] = ((imask >> 0) & 3);
6291 mask [1] = ((imask >> 2) & 3);
6292 mask [2] = ((imask >> 4) & 3) + 4;
6293 mask [3] = ((imask >> 6) & 3) + 4;
6294 v1 = values [ins->sreg1];
6295 v2 = values [ins->sreg2];
6299 mask [0] = ((imask >> 0) & 1);
6300 mask [1] = ((imask >> 1) & 1) + 2;
6301 v1 = values [ins->sreg1];
6302 v2 = values [ins->sreg2];
6304 case OP_PSHUFLEW_LOW:
6306 mask [0] = ((imask >> 0) & 3);
6307 mask [1] = ((imask >> 2) & 3);
6308 mask [2] = ((imask >> 4) & 3);
6309 mask [3] = ((imask >> 6) & 3);
6314 v1 = values [ins->sreg1];
6315 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6317 case OP_PSHUFLEW_HIGH:
6323 mask [4] = 4 + ((imask >> 0) & 3);
6324 mask [5] = 4 + ((imask >> 2) & 3);
6325 mask [6] = 4 + ((imask >> 4) & 3);
6326 mask [7] = 4 + ((imask >> 6) & 3);
6327 v1 = values [ins->sreg1];
6328 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6332 mask [0] = ((imask >> 0) & 3);
6333 mask [1] = ((imask >> 2) & 3);
6334 mask [2] = ((imask >> 4) & 3);
6335 mask [3] = ((imask >> 6) & 3);
6336 v1 = values [ins->sreg1];
6337 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6340 g_assert_not_reached ();
6342 for (i = 0; i < mask_size; ++i)
6343 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6345 values [ins->dreg] =
6346 LLVMBuildShuffleVector (builder, v1, v2,
6347 LLVMConstVector (mask_values, mask_size), dname);
6351 case OP_UNPACK_LOWB:
6352 case OP_UNPACK_LOWW:
6353 case OP_UNPACK_LOWD:
6354 case OP_UNPACK_LOWQ:
6355 case OP_UNPACK_LOWPS:
6356 case OP_UNPACK_LOWPD:
6357 case OP_UNPACK_HIGHB:
6358 case OP_UNPACK_HIGHW:
6359 case OP_UNPACK_HIGHD:
6360 case OP_UNPACK_HIGHQ:
6361 case OP_UNPACK_HIGHPS:
6362 case OP_UNPACK_HIGHPD: {
6364 LLVMValueRef mask_values [16];
6365 int i, mask_size = 0;
6366 gboolean low = FALSE;
6368 switch (ins->opcode) {
6369 case OP_UNPACK_LOWB:
6373 case OP_UNPACK_LOWW:
6377 case OP_UNPACK_LOWD:
6378 case OP_UNPACK_LOWPS:
6382 case OP_UNPACK_LOWQ:
6383 case OP_UNPACK_LOWPD:
6387 case OP_UNPACK_HIGHB:
6390 case OP_UNPACK_HIGHW:
6393 case OP_UNPACK_HIGHD:
6394 case OP_UNPACK_HIGHPS:
6397 case OP_UNPACK_HIGHQ:
6398 case OP_UNPACK_HIGHPD:
6402 g_assert_not_reached ();
6406 for (i = 0; i < (mask_size / 2); ++i) {
6408 mask [(i * 2) + 1] = mask_size + i;
6411 for (i = 0; i < (mask_size / 2); ++i) {
6412 mask [(i * 2)] = (mask_size / 2) + i;
6413 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6417 for (i = 0; i < mask_size; ++i)
6418 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6420 values [ins->dreg] =
6421 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6422 LLVMConstVector (mask_values, mask_size), dname);
6427 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6428 LLVMValueRef v, val;
6430 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6431 val = LLVMConstNull (t);
6432 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6433 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6435 values [ins->dreg] = val;
6439 case OP_DUPPS_HIGH: {
6440 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6441 LLVMValueRef v1, v2, val;
6444 if (ins->opcode == OP_DUPPS_LOW) {
6445 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6446 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6448 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6449 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6451 val = LLVMConstNull (t);
6452 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6453 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6454 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6455 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6457 values [ins->dreg] = val;
6462 LLVMValueRef args [3];
6466 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6467 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6469 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6479 * EXCEPTION HANDLING
6481 case OP_IMPLICIT_EXCEPTION:
6482 /* This marks a place where an implicit exception can happen */
6483 if (bb->region != -1)
6484 set_failure (ctx, "implicit-exception");
6488 gboolean rethrow = (ins->opcode == OP_RETHROW);
6489 if (ctx->llvm_only) {
6490 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6491 has_terminator = TRUE;
6492 ctx->unreachable [bb->block_num] = TRUE;
6494 emit_throw (ctx, bb, rethrow, lhs);
6495 builder = ctx->builder;
6499 case OP_CALL_HANDLER: {
6501 * We don't 'call' handlers, but instead simply branch to them.
6502 * The code generated by ENDFINALLY will branch back to us.
6504 LLVMBasicBlockRef noex_bb;
6506 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6508 bb_list = info->call_handler_return_bbs;
6511 * Set the indicator variable for the finally clause.
6513 lhs = info->finally_ind;
6515 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6517 /* Branch to the finally clause */
6518 LLVMBuildBr (builder, info->call_handler_target_bb);
6520 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6521 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6523 builder = ctx->builder = create_builder (ctx);
6524 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6526 bblocks [bb->block_num].end_bblock = noex_bb;
6529 case OP_START_HANDLER: {
6532 case OP_ENDFINALLY: {
6533 LLVMBasicBlockRef resume_bb;
6534 MonoBasicBlock *handler_bb;
6535 LLVMValueRef val, switch_ins, callee;
6539 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6540 g_assert (handler_bb);
6541 info = &bblocks [handler_bb->block_num];
6542 lhs = info->finally_ind;
6545 bb_list = info->call_handler_return_bbs;
6547 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6549 /* Load the finally variable */
6550 val = LLVMBuildLoad (builder, lhs, "");
6552 /* Reset the variable */
6553 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6555 /* Branch to either resume_bb, or to the bblocks in bb_list */
6556 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6558 * The other targets are added at the end to handle OP_CALL_HANDLER
6559 * opcodes processed later.
6561 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6563 builder = ctx->builder = create_builder (ctx);
6564 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6566 if (ctx->llvm_only) {
6567 emit_resume_eh (ctx, bb);
6569 if (ctx->cfg->compile_aot) {
6570 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6572 #if LLVM_API_VERSION > 100
6573 MonoJitICallInfo *info;
6575 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6577 gpointer target = (void*)info->func;
6578 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6579 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6581 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6584 LLVMBuildCall (builder, callee, NULL, 0, "");
6585 LLVMBuildUnreachable (builder);
6588 has_terminator = TRUE;
6591 case OP_IL_SEQ_POINT:
6596 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6597 set_failure (ctx, reason);
6605 /* Convert the value to the type required by phi nodes */
6606 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6607 if (ctx->is_vphi [ins->dreg])
6609 values [ins->dreg] = addresses [ins->dreg];
6611 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6614 /* Add stores for volatile variables */
6615 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6616 emit_volatile_store (ctx, ins->dreg);
6622 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6623 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6626 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6627 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6628 LLVMBuildRetVoid (builder);
6631 if (bb == cfg->bb_entry)
6632 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6636 * mono_llvm_check_method_supported:
6638 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6639 * compiling a method twice.
6642 mono_llvm_check_method_supported (MonoCompile *cfg)
6649 if (cfg->method->save_lmf) {
6650 cfg->exception_message = g_strdup ("lmf");
6651 cfg->disable_llvm = TRUE;
6653 if (cfg->disable_llvm)
6657 * Nested clauses where one of the clauses is a finally clause is
6658 * not supported, because LLVM can't figure out the control flow,
6659 * probably because we resume exception handling by calling our
6660 * own function instead of using the 'resume' llvm instruction.
6662 for (i = 0; i < cfg->header->num_clauses; ++i) {
6663 for (j = 0; j < cfg->header->num_clauses; ++j) {
6664 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6665 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6667 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6668 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6669 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6670 cfg->exception_message = g_strdup ("nested clauses");
6671 cfg->disable_llvm = TRUE;
6676 if (cfg->disable_llvm)
6680 if (cfg->method->dynamic) {
6681 cfg->exception_message = g_strdup ("dynamic.");
6682 cfg->disable_llvm = TRUE;
6684 if (cfg->disable_llvm)
6688 static LLVMCallInfo*
6689 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6691 LLVMCallInfo *linfo;
6694 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6698 * Gsharedvt methods have the following calling convention:
6699 * - all arguments are passed by ref, even non generic ones
6700 * - the return value is returned by ref too, using a vret
6701 * argument passed after 'this'.
6703 n = sig->param_count + sig->hasthis;
6704 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6708 linfo->args [pindex ++].storage = LLVMArgNormal;
6710 if (sig->ret->type != MONO_TYPE_VOID) {
6711 if (mini_is_gsharedvt_variable_type (sig->ret))
6712 linfo->ret.storage = LLVMArgGsharedvtVariable;
6713 else if (mini_type_is_vtype (sig->ret))
6714 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6716 linfo->ret.storage = LLVMArgGsharedvtFixed;
6717 linfo->vret_arg_index = pindex;
6719 linfo->ret.storage = LLVMArgNone;
6722 for (i = 0; i < sig->param_count; ++i) {
6723 if (sig->params [i]->byref)
6724 linfo->args [pindex].storage = LLVMArgNormal;
6725 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6726 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6727 else if (mini_type_is_vtype (sig->params [i]))
6728 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6730 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6731 linfo->args [pindex].type = sig->params [i];
6738 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6739 for (i = 0; i < sig->param_count; ++i)
6740 linfo->args [i + sig->hasthis].type = sig->params [i];
6746 emit_method_inner (EmitContext *ctx);
6749 free_ctx (EmitContext *ctx)
6753 g_free (ctx->values);
6754 g_free (ctx->addresses);
6755 g_free (ctx->vreg_types);
6756 g_free (ctx->is_vphi);
6757 g_free (ctx->vreg_cli_types);
6758 g_free (ctx->is_dead);
6759 g_free (ctx->unreachable);
6760 g_ptr_array_free (ctx->phi_values, TRUE);
6761 g_free (ctx->bblocks);
6762 g_hash_table_destroy (ctx->region_to_handler);
6763 g_hash_table_destroy (ctx->clause_to_handler);
6764 g_hash_table_destroy (ctx->jit_callees);
6766 GHashTableIter iter;
6767 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6768 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6771 g_hash_table_destroy (ctx->method_to_callers);
6773 g_free (ctx->method_name);
6774 g_ptr_array_free (ctx->bblock_list, TRUE);
6776 for (l = ctx->builders; l; l = l->next) {
6777 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6778 LLVMDisposeBuilder (builder);
6785 * mono_llvm_emit_method:
6787 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6790 mono_llvm_emit_method (MonoCompile *cfg)
6794 gboolean is_linkonce = FALSE;
6797 /* The code below might acquire the loader lock, so use it for global locking */
6798 mono_loader_lock ();
6800 /* Used to communicate with the callbacks */
6801 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6803 ctx = g_new0 (EmitContext, 1);
6805 ctx->mempool = cfg->mempool;
6808 * This maps vregs to the LLVM instruction defining them
6810 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6812 * This maps vregs for volatile variables to the LLVM instruction defining their
6815 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6816 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6817 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6818 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6819 ctx->phi_values = g_ptr_array_sized_new (256);
6821 * This signals whenever the vreg was defined by a phi node with no input vars
6822 * (i.e. all its input bblocks end with NOT_REACHABLE).
6824 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6825 /* Whenever the bblock is unreachable */
6826 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6827 ctx->bblock_list = g_ptr_array_sized_new (256);
6829 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6830 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6831 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6832 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6833 if (cfg->compile_aot) {
6834 ctx->module = &aot_module;
6838 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6839 * linkage for them. This requires the following:
6840 * - the method needs to have a unique mangled name
6841 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6843 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6845 method_name = mono_aot_get_mangled_method_name (cfg->method);
6847 is_linkonce = FALSE;
6850 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6852 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6856 method_name = mono_aot_get_method_name (cfg);
6857 cfg->llvm_method_name = g_strdup (method_name);
6859 init_jit_module (cfg->domain);
6860 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6861 method_name = mono_method_full_name (cfg->method, TRUE);
6863 ctx->method_name = method_name;
6864 ctx->is_linkonce = is_linkonce;
6866 #if LLVM_API_VERSION > 100
6867 if (cfg->compile_aot)
6868 ctx->lmodule = ctx->module->lmodule;
6870 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6872 ctx->lmodule = ctx->module->lmodule;
6874 ctx->llvm_only = ctx->module->llvm_only;
6876 emit_method_inner (ctx);
6878 if (!ctx_ok (ctx)) {
6880 /* Need to add unused phi nodes as they can be referenced by other values */
6881 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6882 LLVMBuilderRef builder;
6884 builder = create_builder (ctx);
6885 LLVMPositionBuilderAtEnd (builder, phi_bb);
6887 for (i = 0; i < ctx->phi_values->len; ++i) {
6888 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6889 if (LLVMGetInstructionParent (v) == NULL)
6890 LLVMInsertIntoBuilder (builder, v);
6893 LLVMDeleteFunction (ctx->lmethod);
6899 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6901 mono_loader_unlock ();
6905 emit_method_inner (EmitContext *ctx)
6907 MonoCompile *cfg = ctx->cfg;
6908 MonoMethodSignature *sig;
6910 LLVMTypeRef method_type;
6911 LLVMValueRef method = NULL;
6912 LLVMValueRef *values = ctx->values;
6913 int i, max_block_num, bb_index;
6914 gboolean last = FALSE;
6915 LLVMCallInfo *linfo;
6916 LLVMModuleRef lmodule = ctx->lmodule;
6918 GPtrArray *bblock_list = ctx->bblock_list;
6919 MonoMethodHeader *header;
6920 MonoExceptionClause *clause;
6923 if (cfg->gsharedvt && !cfg->llvm_only) {
6924 set_failure (ctx, "gsharedvt");
6930 static int count = 0;
6933 char *llvm_count_str = g_getenv ("LLVM_COUNT");
6934 if (llvm_count_str) {
6935 int lcount = atoi (llvm_count_str);
6936 g_free (llvm_count_str);
6937 if (count == lcount) {
6938 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6942 if (count > lcount) {
6943 set_failure (ctx, "count");
6950 sig = mono_method_signature (cfg->method);
6953 linfo = get_llvm_call_info (cfg, sig);
6959 linfo->rgctx_arg = TRUE;
6960 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6964 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6965 ctx->lmethod = method;
6967 if (!cfg->llvm_only)
6968 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6969 LLVMSetLinkage (method, LLVMPrivateLinkage);
6971 LLVMAddFunctionAttr (method, LLVMUWTable);
6973 if (cfg->compile_aot) {
6974 LLVMSetLinkage (method, LLVMInternalLinkage);
6975 if (ctx->module->external_symbols) {
6976 LLVMSetLinkage (method, LLVMExternalLinkage);
6977 LLVMSetVisibility (method, LLVMHiddenVisibility);
6979 if (ctx->is_linkonce) {
6980 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6981 LLVMSetVisibility (method, LLVMDefaultVisibility);
6984 #if LLVM_API_VERSION > 100
6985 LLVMSetLinkage (method, LLVMExternalLinkage);
6987 LLVMSetLinkage (method, LLVMPrivateLinkage);
6991 if (cfg->method->save_lmf && !cfg->llvm_only) {
6992 set_failure (ctx, "lmf");
6996 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6997 set_failure (ctx, "pinvoke signature");
7001 header = cfg->header;
7002 for (i = 0; i < header->num_clauses; ++i) {
7003 clause = &header->clauses [i];
7004 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
7005 set_failure (ctx, "non-finally/catch clause.");
7009 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7010 /* We can't handle inlined methods with clauses */
7011 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
7013 if (linfo->rgctx_arg) {
7014 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7015 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7017 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7018 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7019 * CC_X86_64_Mono in X86CallingConv.td.
7021 if (!ctx->llvm_only)
7022 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
7023 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7025 ctx->rgctx_arg_pindex = -1;
7027 if (cfg->vret_addr) {
7028 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7029 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7030 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7031 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7032 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7037 ctx->this_arg_pindex = linfo->this_arg_pindex;
7038 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7039 values [cfg->args [0]->dreg] = ctx->this_arg;
7040 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7043 names = g_new (char *, sig->param_count);
7044 mono_method_get_param_names (cfg->method, (const char **) names);
7046 /* Set parameter names/attributes */
7047 for (i = 0; i < sig->param_count; ++i) {
7048 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7050 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7053 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7054 name = g_strdup_printf ("dummy_%d_%d", i, j);
7055 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7059 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7062 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7063 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7064 if (names [i] && names [i][0] != '\0')
7065 name = g_strdup_printf ("p_arg_%s", names [i]);
7067 name = g_strdup_printf ("p_arg_%d", i);
7069 if (names [i] && names [i][0] != '\0')
7070 name = g_strdup_printf ("arg_%s", names [i]);
7072 name = g_strdup_printf ("arg_%d", i);
7074 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7076 if (ainfo->storage == LLVMArgVtypeByVal)
7077 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7079 if (ainfo->storage == LLVMArgVtypeByRef) {
7081 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7086 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7087 ctx->minfo = mono_debug_lookup_method (cfg->method);
7088 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7092 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7093 max_block_num = MAX (max_block_num, bb->block_num);
7094 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7096 /* Add branches between non-consecutive bblocks */
7097 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7098 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7099 bb->next_bb != bb->last_ins->inst_false_bb) {
7101 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7102 inst->opcode = OP_BR;
7103 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7104 mono_bblock_add_inst (bb, inst);
7109 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7110 * was later optimized away, so clear these flags, and add them back for the still
7111 * present OP_LDADDR instructions.
7113 for (i = 0; i < cfg->next_vreg; ++i) {
7116 ins = get_vreg_to_inst (cfg, i);
7117 if (ins && ins != cfg->rgctx_var)
7118 ins->flags &= ~MONO_INST_INDIRECT;
7122 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7124 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7126 LLVMBuilderRef builder;
7128 char dname_buf[128];
7130 builder = create_builder (ctx);
7132 for (ins = bb->code; ins; ins = ins->next) {
7133 switch (ins->opcode) {
7138 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7143 if (ins->opcode == OP_VPHI) {
7144 /* Treat valuetype PHI nodes as operating on the address itself */
7145 g_assert (ins->klass);
7146 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7150 * Have to precreate these, as they can be referenced by
7151 * earlier instructions.
7153 sprintf (dname_buf, "t%d", ins->dreg);
7155 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7157 if (ins->opcode == OP_VPHI)
7158 ctx->addresses [ins->dreg] = values [ins->dreg];
7160 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7163 * Set the expected type of the incoming arguments since these have
7164 * to have the same type.
7166 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7167 int sreg1 = ins->inst_phi_args [i + 1];
7170 if (ins->opcode == OP_VPHI)
7171 ctx->is_vphi [sreg1] = TRUE;
7172 ctx->vreg_types [sreg1] = phi_type;
7178 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7187 * Create an ordering for bblocks, use the depth first order first, then
7188 * put the exception handling bblocks last.
7190 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7191 bb = cfg->bblocks [bb_index];
7192 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7193 g_ptr_array_add (bblock_list, bb);
7194 bblocks [bb->block_num].added = TRUE;
7198 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7199 if (!bblocks [bb->block_num].added)
7200 g_ptr_array_add (bblock_list, bb);
7204 * Second pass: generate code.
7207 LLVMBuilderRef entry_builder = create_builder (ctx);
7208 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7209 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7210 emit_entry_bb (ctx, entry_builder);
7212 // Make landing pads first
7213 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7215 if (ctx->llvm_only) {
7216 size_t group_index = 0;
7217 while (group_index < cfg->header->num_clauses) {
7219 size_t cursor = group_index;
7220 while (cursor < cfg->header->num_clauses &&
7221 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7222 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7227 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7228 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7229 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7231 group_index = cursor;
7235 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7236 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7238 // Prune unreachable mono BBs.
7239 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7242 process_bb (ctx, bb);
7246 g_hash_table_destroy (ctx->exc_meta);
7248 mono_memory_barrier ();
7250 /* Add incoming phi values */
7251 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7252 GSList *l, *ins_list;
7254 ins_list = bblocks [bb->block_num].phi_nodes;
7256 for (l = ins_list; l; l = l->next) {
7257 PhiNode *node = (PhiNode*)l->data;
7258 MonoInst *phi = node->phi;
7259 int sreg1 = node->sreg;
7260 LLVMBasicBlockRef in_bb;
7265 in_bb = get_end_bb (ctx, node->in_bb);
7267 if (ctx->unreachable [node->in_bb->block_num])
7270 if (!values [sreg1]) {
7271 /* Can happen with values in EH clauses */
7272 set_failure (ctx, "incoming phi sreg1");
7276 if (phi->opcode == OP_VPHI) {
7277 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7278 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7280 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7281 set_failure (ctx, "incoming phi arg type mismatch");
7284 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7285 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7290 /* Nullify empty phi instructions */
7291 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7292 GSList *l, *ins_list;
7294 ins_list = bblocks [bb->block_num].phi_nodes;
7296 for (l = ins_list; l; l = l->next) {
7297 PhiNode *node = (PhiNode*)l->data;
7298 MonoInst *phi = node->phi;
7299 LLVMValueRef phi_ins = values [phi->dreg];
7302 /* Already removed */
7305 if (LLVMCountIncoming (phi_ins) == 0) {
7306 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7307 LLVMInstructionEraseFromParent (phi_ins);
7308 values [phi->dreg] = NULL;
7313 /* Create the SWITCH statements for ENDFINALLY instructions */
7314 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7315 BBInfo *info = &bblocks [bb->block_num];
7317 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7318 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7319 GSList *bb_list = info->call_handler_return_bbs;
7321 GSList *bb_list_iter;
7323 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7324 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7330 /* Initialize the method if needed */
7331 if (cfg->compile_aot && ctx->llvm_only) {
7332 // FIXME: Add more shared got entries
7333 ctx->builder = create_builder (ctx);
7334 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7336 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7338 // FIXME: beforefieldinit
7340 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7341 * in load_method ().
7343 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7345 * linkonce methods shouldn't have initialization,
7346 * because they might belong to assemblies which
7347 * haven't been loaded yet.
7349 g_assert (!ctx->is_linkonce);
7350 emit_init_method (ctx);
7352 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7356 if (cfg->llvm_only) {
7357 GHashTableIter iter;
7359 GSList *callers, *l, *l2;
7362 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7363 * We can't do this earlier, as it contains llvm instructions which can be
7364 * freed if compilation fails.
7365 * FIXME: Get rid of this when all methods can be llvm compiled.
7367 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7368 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7369 for (l = callers; l; l = l->next) {
7370 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7371 l2 = g_slist_prepend (l2, l->data);
7372 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7377 if (cfg->verbose_level > 1)
7378 mono_llvm_dump_value (method);
7380 if (cfg->compile_aot && !cfg->llvm_only)
7381 mark_as_used (ctx->module, method);
7383 if (!cfg->llvm_only) {
7384 LLVMValueRef md_args [16];
7385 LLVMValueRef md_node;
7388 if (cfg->compile_aot)
7389 method_index = mono_aot_get_method_index (cfg->orig_method);
7392 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7393 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7394 md_node = LLVMMDNode (md_args, 2);
7395 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7396 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7399 if (cfg->compile_aot) {
7400 /* Don't generate native code, keep the LLVM IR */
7401 if (cfg->verbose_level)
7402 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7404 #if LLVM_API_VERSION < 100
7405 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7406 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7407 g_assert (err == 0);
7410 //LLVMVerifyFunction(method, 0);
7411 #if LLVM_API_VERSION > 100
7412 MonoDomain *domain = mono_domain_get ();
7413 MonoJitDomainInfo *domain_info;
7414 int nvars = g_hash_table_size (ctx->jit_callees);
7415 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7416 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7417 GHashTableIter iter;
7423 * Compute the addresses of the LLVM globals pointing to the
7424 * methods called by the current method. Pass it to the trampoline
7425 * code so it can update them after their corresponding method was
7428 g_hash_table_iter_init (&iter, ctx->jit_callees);
7430 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7431 callee_vars [i ++] = var;
7433 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7435 decode_llvm_eh_info (ctx, eh_frame);
7437 mono_domain_lock (domain);
7438 domain_info = domain_jit_info (domain);
7439 if (!domain_info->llvm_jit_callees)
7440 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7441 g_hash_table_iter_init (&iter, ctx->jit_callees);
7443 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7444 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7445 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7446 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7449 mono_domain_unlock (domain);
7451 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7453 if (cfg->verbose_level > 1)
7454 mono_llvm_dump_value (ctx->lmethod);
7456 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7458 /* Set by emit_cb */
7459 g_assert (cfg->code_len);
7463 if (ctx->module->method_to_lmethod)
7464 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7465 if (ctx->module->idx_to_lmethod)
7466 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7468 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7469 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7473 * mono_llvm_create_vars:
7475 * Same as mono_arch_create_vars () for LLVM.
7478 mono_llvm_create_vars (MonoCompile *cfg)
7480 MonoMethodSignature *sig;
7482 sig = mono_method_signature (cfg->method);
7483 if (cfg->gsharedvt && cfg->llvm_only) {
7484 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7485 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7486 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7487 printf ("vret_addr = ");
7488 mono_print_ins (cfg->vret_addr);
7492 mono_arch_create_vars (cfg);
7497 * mono_llvm_emit_call:
7499 * Same as mono_arch_emit_call () for LLVM.
7502 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7505 MonoMethodSignature *sig;
7506 int i, n, stack_size;
7511 sig = call->signature;
7512 n = sig->param_count + sig->hasthis;
7514 call->cinfo = get_llvm_call_info (cfg, sig);
7516 if (cfg->disable_llvm)
7519 if (sig->call_convention == MONO_CALL_VARARG) {
7520 cfg->exception_message = g_strdup ("varargs");
7521 cfg->disable_llvm = TRUE;
7524 for (i = 0; i < n; ++i) {
7527 ainfo = call->cinfo->args + i;
7529 in = call->args [i];
7531 /* Simply remember the arguments */
7532 switch (ainfo->storage) {
7533 case LLVMArgNormal: {
7534 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7537 opcode = mono_type_to_regmove (cfg, t);
7538 if (opcode == OP_FMOVE) {
7539 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7540 ins->dreg = mono_alloc_freg (cfg);
7541 } else if (opcode == OP_LMOVE) {
7542 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7543 ins->dreg = mono_alloc_lreg (cfg);
7544 } else if (opcode == OP_RMOVE) {
7545 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7546 ins->dreg = mono_alloc_freg (cfg);
7548 MONO_INST_NEW (cfg, ins, OP_MOVE);
7549 ins->dreg = mono_alloc_ireg (cfg);
7551 ins->sreg1 = in->dreg;
7554 case LLVMArgVtypeByVal:
7555 case LLVMArgVtypeByRef:
7556 case LLVMArgVtypeInReg:
7557 case LLVMArgVtypeAsScalar:
7558 case LLVMArgAsIArgs:
7559 case LLVMArgAsFpArgs:
7560 case LLVMArgGsharedvtVariable:
7561 case LLVMArgGsharedvtFixed:
7562 case LLVMArgGsharedvtFixedVtype:
7563 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7564 ins->dreg = mono_alloc_ireg (cfg);
7565 ins->sreg1 = in->dreg;
7566 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7567 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7568 ins->inst_vtype = ainfo->type;
7569 ins->klass = mono_class_from_mono_type (ainfo->type);
7572 cfg->exception_message = g_strdup ("ainfo->storage");
7573 cfg->disable_llvm = TRUE;
7577 if (!cfg->disable_llvm) {
7578 MONO_ADD_INS (cfg->cbb, ins);
7579 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7584 static unsigned char*
7585 alloc_cb (LLVMValueRef function, int size)
7589 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7593 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7595 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7600 emitted_cb (LLVMValueRef function, void *start, void *end)
7604 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7606 cfg->code_len = (guint8*)end - (guint8*)start;
7610 exception_cb (void *data)
7613 MonoJitExceptionInfo *ei;
7614 guint32 ei_len, i, j, nested_len, nindex;
7615 gpointer *type_info;
7616 int this_reg, this_offset;
7618 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7622 * data points to a DWARF FDE structure, convert it to our unwind format and
7624 * An alternative would be to save it directly, and modify our unwinder to work
7627 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);
7628 if (cfg->verbose_level > 1)
7629 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7631 /* Count nested clauses */
7633 for (i = 0; i < ei_len; ++i) {
7634 gint32 cindex1 = *(gint32*)type_info [i];
7635 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7637 for (j = 0; j < cfg->header->num_clauses; ++j) {
7639 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7641 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7647 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7648 cfg->llvm_ex_info_len = ei_len + nested_len;
7649 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7650 /* Fill the rest of the information from the type info */
7651 for (i = 0; i < ei_len; ++i) {
7652 gint32 clause_index = *(gint32*)type_info [i];
7653 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7655 cfg->llvm_ex_info [i].flags = clause->flags;
7656 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7657 cfg->llvm_ex_info [i].clause_index = clause_index;
7661 * For nested clauses, the LLVM produced exception info associates the try interval with
7662 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7663 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7664 * and everything else from the nested clause.
7667 for (i = 0; i < ei_len; ++i) {
7668 gint32 cindex1 = *(gint32*)type_info [i];
7669 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7671 for (j = 0; j < cfg->header->num_clauses; ++j) {
7673 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7674 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7676 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7677 /* clause1 is the nested clause */
7678 nested_ei = &cfg->llvm_ex_info [i];
7679 nesting_ei = &cfg->llvm_ex_info [nindex];
7682 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7684 nesting_ei->flags = clause2->flags;
7685 nesting_ei->data.catch_class = clause2->data.catch_class;
7686 nesting_ei->clause_index = cindex2;
7690 g_assert (nindex == ei_len + nested_len);
7691 cfg->llvm_this_reg = this_reg;
7692 cfg->llvm_this_offset = this_offset;
7694 /* type_info [i] is cfg mempool allocated, no need to free it */
7700 #if LLVM_API_VERSION > 100
7702 * decode_llvm_eh_info:
7704 * Decode the EH table emitted by llvm in jit mode, and store
7705 * the result into cfg.
7708 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7710 MonoCompile *cfg = ctx->cfg;
7713 MonoLLVMFDEInfo info;
7714 MonoJitExceptionInfo *ei;
7715 guint8 *p = eh_frame;
7716 int version, fde_count, fde_offset;
7717 guint32 ei_len, i, nested_len;
7718 gpointer *type_info;
7722 * Decode the one element EH table emitted by the MonoException class
7726 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7729 g_assert (version == 3);
7732 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7734 fde_count = *(guint32*)p;
7738 g_assert (fde_count <= 2);
7740 /* The first entry is the real method */
7741 g_assert (table [0] == 1);
7742 fde_offset = table [1];
7743 table += fde_count * 2;
7745 cfg->code_len = table [0];
7746 fde_len = table [1] - fde_offset;
7749 fde = (guint8*)eh_frame + fde_offset;
7750 cie = (guint8*)table;
7752 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7754 cfg->encoded_unwind_ops = info.unw_info;
7755 cfg->encoded_unwind_ops_len = info.unw_info_len;
7756 if (cfg->verbose_level > 1)
7757 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7758 if (info.this_reg != -1) {
7759 cfg->llvm_this_reg = info.this_reg;
7760 cfg->llvm_this_offset = info.this_offset;
7764 ei_len = info.ex_info_len;
7765 type_info = info.type_info;
7767 // Nested clauses are currently disabled
7770 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7771 cfg->llvm_ex_info_len = ei_len + nested_len;
7772 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7773 /* Fill the rest of the information from the type info */
7774 for (i = 0; i < ei_len; ++i) {
7775 gint32 clause_index = *(gint32*)type_info [i];
7776 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7778 cfg->llvm_ex_info [i].flags = clause->flags;
7779 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7780 cfg->llvm_ex_info [i].clause_index = clause_index;
7786 dlsym_cb (const char *name, void **symbol)
7792 if (!strcmp (name, "__bzero")) {
7793 *symbol = (void*)bzero;
7795 current = mono_dl_open (NULL, 0, NULL);
7798 err = mono_dl_symbol (current, name, symbol);
7800 mono_dl_close (current);
7802 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7803 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7809 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7811 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7815 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7817 LLVMTypeRef param_types [4];
7819 param_types [0] = param_type1;
7820 param_types [1] = param_type2;
7822 AddFunc (module, name, ret_type, param_types, 2);
7828 INTRINS_SADD_OVF_I32,
7829 INTRINS_UADD_OVF_I32,
7830 INTRINS_SSUB_OVF_I32,
7831 INTRINS_USUB_OVF_I32,
7832 INTRINS_SMUL_OVF_I32,
7833 INTRINS_UMUL_OVF_I32,
7834 INTRINS_SADD_OVF_I64,
7835 INTRINS_UADD_OVF_I64,
7836 INTRINS_SSUB_OVF_I64,
7837 INTRINS_USUB_OVF_I64,
7838 INTRINS_SMUL_OVF_I64,
7839 INTRINS_UMUL_OVF_I64,
7846 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7847 INTRINS_SSE_PMOVMSKB,
7848 INTRINS_SSE_PSRLI_W,
7849 INTRINS_SSE_PSRAI_W,
7850 INTRINS_SSE_PSLLI_W,
7851 INTRINS_SSE_PSRLI_D,
7852 INTRINS_SSE_PSRAI_D,
7853 INTRINS_SSE_PSLLI_D,
7854 INTRINS_SSE_PSRLI_Q,
7855 INTRINS_SSE_PSLLI_Q,
7856 INTRINS_SSE_SQRT_PD,
7857 INTRINS_SSE_SQRT_PS,
7858 INTRINS_SSE_RSQRT_PS,
7860 INTRINS_SSE_CVTTPD2DQ,
7861 INTRINS_SSE_CVTTPS2DQ,
7862 INTRINS_SSE_CVTDQ2PD,
7863 INTRINS_SSE_CVTDQ2PS,
7864 INTRINS_SSE_CVTPD2DQ,
7865 INTRINS_SSE_CVTPS2DQ,
7866 INTRINS_SSE_CVTPD2PS,
7867 INTRINS_SSE_CVTPS2PD,
7870 INTRINS_SSE_PACKSSWB,
7871 INTRINS_SSE_PACKUSWB,
7872 INTRINS_SSE_PACKSSDW,
7873 INTRINS_SSE_PACKUSDW,
7878 INTRINS_SSE_ADDSUBPS,
7883 INTRINS_SSE_ADDSUBPD,
7886 INTRINS_SSE_PADDUSW,
7887 INTRINS_SSE_PSUBUSW,
7893 INTRINS_SSE_PADDUSB,
7894 INTRINS_SSE_PSUBUSB,
7907 static IntrinsicDesc intrinsics[] = {
7908 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7909 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7910 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7911 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7912 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7913 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7914 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7915 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7916 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7917 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7918 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7919 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7920 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7921 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7922 {INTRINS_SIN, "llvm.sin.f64"},
7923 {INTRINS_COS, "llvm.cos.f64"},
7924 {INTRINS_SQRT, "llvm.sqrt.f64"},
7925 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7926 {INTRINS_FABS, "fabs"},
7927 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7928 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7929 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7930 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7931 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7932 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7933 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7934 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7935 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7936 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7937 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7938 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7939 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7940 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7941 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7942 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7943 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7944 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7945 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7946 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7947 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7948 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7949 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7950 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7951 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7952 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7953 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7954 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7955 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7956 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7957 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7958 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7959 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7960 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7961 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7962 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7963 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7964 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7965 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7966 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7967 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7968 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7969 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7970 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7971 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7972 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7973 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7974 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7975 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7976 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7977 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7978 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7979 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7980 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7985 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7987 LLVMTypeRef ret_type = type_to_simd_type (type);
7988 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7992 add_intrinsic (LLVMModuleRef module, int id)
7995 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7996 LLVMTypeRef ret_type, arg_types [16];
7999 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
8003 case INTRINS_MEMSET: {
8004 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8006 AddFunc (module, name, LLVMVoidType (), params, 5);
8009 case INTRINS_MEMCPY: {
8010 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8012 AddFunc (module, name, LLVMVoidType (), params, 5);
8015 case INTRINS_SADD_OVF_I32:
8016 case INTRINS_UADD_OVF_I32:
8017 case INTRINS_SSUB_OVF_I32:
8018 case INTRINS_USUB_OVF_I32:
8019 case INTRINS_SMUL_OVF_I32:
8020 case INTRINS_UMUL_OVF_I32: {
8021 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
8022 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
8023 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
8025 AddFunc (module, name, ret_type, params, 2);
8028 case INTRINS_SADD_OVF_I64:
8029 case INTRINS_UADD_OVF_I64:
8030 case INTRINS_SSUB_OVF_I64:
8031 case INTRINS_USUB_OVF_I64:
8032 case INTRINS_SMUL_OVF_I64:
8033 case INTRINS_UMUL_OVF_I64: {
8034 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8035 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8036 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8038 AddFunc (module, name, ret_type, params, 2);
8044 case INTRINS_FABS: {
8045 LLVMTypeRef params [] = { LLVMDoubleType () };
8047 AddFunc (module, name, LLVMDoubleType (), params, 1);
8050 case INTRINS_EXPECT_I8:
8051 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8053 case INTRINS_EXPECT_I1:
8054 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8056 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8057 case INTRINS_SSE_PMOVMSKB:
8059 ret_type = LLVMInt32Type ();
8060 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8061 AddFunc (module, name, ret_type, arg_types, 1);
8063 case INTRINS_SSE_PSRLI_W:
8064 case INTRINS_SSE_PSRAI_W:
8065 case INTRINS_SSE_PSLLI_W:
8067 ret_type = type_to_simd_type (MONO_TYPE_I2);
8068 arg_types [0] = ret_type;
8069 arg_types [1] = LLVMInt32Type ();
8070 AddFunc (module, name, ret_type, arg_types, 2);
8072 case INTRINS_SSE_PSRLI_D:
8073 case INTRINS_SSE_PSRAI_D:
8074 case INTRINS_SSE_PSLLI_D:
8075 ret_type = type_to_simd_type (MONO_TYPE_I4);
8076 arg_types [0] = ret_type;
8077 arg_types [1] = LLVMInt32Type ();
8078 AddFunc (module, name, ret_type, arg_types, 2);
8080 case INTRINS_SSE_PSRLI_Q:
8081 case INTRINS_SSE_PSLLI_Q:
8082 ret_type = type_to_simd_type (MONO_TYPE_I8);
8083 arg_types [0] = ret_type;
8084 arg_types [1] = LLVMInt32Type ();
8085 AddFunc (module, name, ret_type, arg_types, 2);
8087 case INTRINS_SSE_SQRT_PD:
8089 ret_type = type_to_simd_type (MONO_TYPE_R8);
8090 arg_types [0] = ret_type;
8091 AddFunc (module, name, ret_type, arg_types, 1);
8093 case INTRINS_SSE_SQRT_PS:
8094 ret_type = type_to_simd_type (MONO_TYPE_R4);
8095 arg_types [0] = ret_type;
8096 AddFunc (module, name, ret_type, arg_types, 1);
8098 case INTRINS_SSE_RSQRT_PS:
8099 ret_type = type_to_simd_type (MONO_TYPE_R4);
8100 arg_types [0] = ret_type;
8101 AddFunc (module, name, ret_type, arg_types, 1);
8103 case INTRINS_SSE_RCP_PS:
8104 ret_type = type_to_simd_type (MONO_TYPE_R4);
8105 arg_types [0] = ret_type;
8106 AddFunc (module, name, ret_type, arg_types, 1);
8108 case INTRINS_SSE_CVTTPD2DQ:
8109 ret_type = type_to_simd_type (MONO_TYPE_I4);
8110 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8111 AddFunc (module, name, ret_type, arg_types, 1);
8113 case INTRINS_SSE_CVTTPS2DQ:
8114 ret_type = type_to_simd_type (MONO_TYPE_I4);
8115 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8116 AddFunc (module, name, ret_type, arg_types, 1);
8118 case INTRINS_SSE_CVTDQ2PD:
8119 /* Conversion ops */
8120 ret_type = type_to_simd_type (MONO_TYPE_R8);
8121 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8122 AddFunc (module, name, ret_type, arg_types, 1);
8124 case INTRINS_SSE_CVTDQ2PS:
8125 ret_type = type_to_simd_type (MONO_TYPE_R4);
8126 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8127 AddFunc (module, name, ret_type, arg_types, 1);
8129 case INTRINS_SSE_CVTPD2DQ:
8130 ret_type = type_to_simd_type (MONO_TYPE_I4);
8131 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8132 AddFunc (module, name, ret_type, arg_types, 1);
8134 case INTRINS_SSE_CVTPS2DQ:
8135 ret_type = type_to_simd_type (MONO_TYPE_I4);
8136 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8137 AddFunc (module, name, ret_type, arg_types, 1);
8139 case INTRINS_SSE_CVTPD2PS:
8140 ret_type = type_to_simd_type (MONO_TYPE_R4);
8141 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8142 AddFunc (module, name, ret_type, arg_types, 1);
8144 case INTRINS_SSE_CVTPS2PD:
8145 ret_type = type_to_simd_type (MONO_TYPE_R8);
8146 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8147 AddFunc (module, name, ret_type, arg_types, 1);
8149 case INTRINS_SSE_CMPPD:
8151 ret_type = type_to_simd_type (MONO_TYPE_R8);
8152 arg_types [0] = ret_type;
8153 arg_types [1] = ret_type;
8154 arg_types [2] = LLVMInt8Type ();
8155 AddFunc (module, name, ret_type, arg_types, 3);
8157 case INTRINS_SSE_CMPPS:
8158 ret_type = type_to_simd_type (MONO_TYPE_R4);
8159 arg_types [0] = ret_type;
8160 arg_types [1] = ret_type;
8161 arg_types [2] = LLVMInt8Type ();
8162 AddFunc (module, name, ret_type, arg_types, 3);
8164 case INTRINS_SSE_PACKSSWB:
8165 case INTRINS_SSE_PACKUSWB:
8166 case INTRINS_SSE_PACKSSDW:
8168 ret_type = type_to_simd_type (MONO_TYPE_I1);
8169 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8170 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8171 AddFunc (module, name, ret_type, arg_types, 2);
8173 case INTRINS_SSE_PACKUSDW:
8174 ret_type = type_to_simd_type (MONO_TYPE_I2);
8175 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8176 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8177 AddFunc (module, name, ret_type, arg_types, 2);
8179 /* SSE Binary ops */
8180 case INTRINS_SSE_PADDSW:
8181 case INTRINS_SSE_PSUBSW:
8182 case INTRINS_SSE_PADDUSW:
8183 case INTRINS_SSE_PSUBUSW:
8184 case INTRINS_SSE_PAVGW:
8185 case INTRINS_SSE_PMULHW:
8186 case INTRINS_SSE_PMULHU:
8187 add_sse_binary (module, name, MONO_TYPE_I2);
8189 case INTRINS_SSE_MINPS:
8190 case INTRINS_SSE_MAXPS:
8191 case INTRINS_SSE_HADDPS:
8192 case INTRINS_SSE_HSUBPS:
8193 case INTRINS_SSE_ADDSUBPS:
8194 add_sse_binary (module, name, MONO_TYPE_R4);
8196 case INTRINS_SSE_MINPD:
8197 case INTRINS_SSE_MAXPD:
8198 case INTRINS_SSE_HADDPD:
8199 case INTRINS_SSE_HSUBPD:
8200 case INTRINS_SSE_ADDSUBPD:
8201 add_sse_binary (module, name, MONO_TYPE_R8);
8203 case INTRINS_SE_PADDSB:
8204 case INTRINS_SSE_PSUBSB:
8205 case INTRINS_SSE_PADDUSB:
8206 case INTRINS_SSE_PSUBUSB:
8207 case INTRINS_SSE_PAVGB:
8208 add_sse_binary (module, name, MONO_TYPE_I1);
8210 case INTRINS_SSE_PAUSE:
8211 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8213 case INTRINS_SSE_DPPS:
8214 ret_type = type_to_simd_type (MONO_TYPE_R4);
8215 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8216 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8217 arg_types [2] = LLVMInt32Type ();
8218 AddFunc (module, name, ret_type, arg_types, 3);
8222 g_assert_not_reached ();
8228 get_intrinsic (EmitContext *ctx, const char *name)
8230 #if LLVM_API_VERSION > 100
8234 * Every method is emitted into its own module so
8235 * we can add intrinsics on demand.
8237 res = LLVMGetNamedFunction (ctx->lmodule, name);
8241 /* No locking needed */
8242 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8245 printf ("%s\n", name);
8246 g_assert (id != -1);
8247 add_intrinsic (ctx->lmodule, id);
8248 res = LLVMGetNamedFunction (ctx->lmodule, name);
8256 res = LLVMGetNamedFunction (ctx->lmodule, name);
8263 add_intrinsics (LLVMModuleRef module)
8267 /* Emit declarations of instrinsics */
8269 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8270 * type doesn't seem to do any locking.
8272 for (i = 0; i < INTRINS_NUM; ++i)
8273 add_intrinsic (module, i);
8277 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8279 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8282 /* Load/Store intrinsics */
8284 LLVMTypeRef arg_types [5];
8288 for (i = 1; i <= 8; i *= 2) {
8289 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8290 arg_types [1] = LLVMInt32Type ();
8291 arg_types [2] = LLVMInt1Type ();
8292 arg_types [3] = LLVMInt32Type ();
8293 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8294 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8296 arg_types [0] = LLVMIntType (i * 8);
8297 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8298 arg_types [2] = LLVMInt32Type ();
8299 arg_types [3] = LLVMInt1Type ();
8300 arg_types [4] = LLVMInt32Type ();
8301 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8302 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8308 add_types (MonoLLVMModule *module)
8310 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8314 mono_llvm_init (void)
8319 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8321 h = g_hash_table_new (NULL, NULL);
8322 for (i = 0; i < INTRINS_NUM; ++i)
8323 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8324 intrins_id_to_name = h;
8326 h = g_hash_table_new (g_str_hash, g_str_equal);
8327 for (i = 0; i < INTRINS_NUM; ++i)
8328 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8329 intrins_name_to_id = h;
8333 init_jit_module (MonoDomain *domain)
8335 MonoJitDomainInfo *dinfo;
8336 MonoLLVMModule *module;
8339 dinfo = domain_jit_info (domain);
8340 if (dinfo->llvm_module)
8343 mono_loader_lock ();
8345 if (dinfo->llvm_module) {
8346 mono_loader_unlock ();
8350 module = g_new0 (MonoLLVMModule, 1);
8352 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8353 module->lmodule = LLVMModuleCreateWithName (name);
8354 module->context = LLVMGetGlobalContext ();
8356 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8358 add_intrinsics (module->lmodule);
8361 module->llvm_types = g_hash_table_new (NULL, NULL);
8363 #if LLVM_API_VERSION < 100
8364 MonoJitICallInfo *info;
8366 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8368 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8371 mono_memory_barrier ();
8373 dinfo->llvm_module = module;
8375 mono_loader_unlock ();
8379 mono_llvm_cleanup (void)
8381 MonoLLVMModule *module = &aot_module;
8383 if (module->lmodule)
8384 LLVMDisposeModule (module->lmodule);
8386 if (module->context)
8387 LLVMContextDispose (module->context);
8391 mono_llvm_free_domain_info (MonoDomain *domain)
8393 MonoJitDomainInfo *info = domain_jit_info (domain);
8394 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8400 if (module->llvm_types)
8401 g_hash_table_destroy (module->llvm_types);
8403 mono_llvm_dispose_ee (module->mono_ee);
8405 if (module->bb_names) {
8406 for (i = 0; i < module->bb_names_len; ++i)
8407 g_free (module->bb_names [i]);
8408 g_free (module->bb_names);
8410 //LLVMDisposeModule (module->module);
8414 info->llvm_module = NULL;
8418 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8420 MonoLLVMModule *module = &aot_module;
8422 /* Delete previous module */
8423 if (module->plt_entries)
8424 g_hash_table_destroy (module->plt_entries);
8425 if (module->lmodule)
8426 LLVMDisposeModule (module->lmodule);
8428 memset (module, 0, sizeof (aot_module));
8430 module->lmodule = LLVMModuleCreateWithName ("aot");
8431 module->assembly = assembly;
8432 module->global_prefix = g_strdup (global_prefix);
8433 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8434 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8435 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8436 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8437 module->external_symbols = TRUE;
8438 module->emit_dwarf = emit_dwarf;
8439 module->static_link = static_link;
8440 module->llvm_only = llvm_only;
8441 /* The first few entries are reserved */
8442 module->max_got_offset = 16;
8443 module->context = LLVMGetGlobalContext ();
8446 /* clang ignores our debug info because it has an invalid version */
8447 module->emit_dwarf = FALSE;
8449 add_intrinsics (module->lmodule);
8452 #if LLVM_API_VERSION > 100
8453 if (module->emit_dwarf) {
8454 char *dir, *build_info, *s, *cu_name;
8456 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8459 dir = g_strdup (".");
8460 build_info = mono_get_runtime_build_info ();
8461 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8462 cu_name = g_path_get_basename (assembly->image->name);
8463 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8465 g_free (build_info);
8472 * We couldn't compute the type of the LLVM global representing the got because
8473 * its size is only known after all the methods have been emitted. So create
8474 * a dummy variable, and replace all uses it with the real got variable when
8475 * its size is known in mono_llvm_emit_aot_module ().
8478 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8480 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8481 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8484 /* Add initialization array */
8486 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8488 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8489 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8493 emit_init_icall_wrappers (module);
8495 emit_llvm_code_start (module);
8497 /* Add a dummy personality function */
8498 if (!use_debug_personality) {
8499 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8500 LLVMSetLinkage (personality, LLVMExternalLinkage);
8501 mark_as_used (module, personality);
8504 /* Add a reference to the c++ exception we throw/catch */
8506 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8507 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8508 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8509 mono_llvm_set_is_constant (module->sentinel_exception);
8512 module->llvm_types = g_hash_table_new (NULL, NULL);
8513 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8514 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8515 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8516 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8517 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8518 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8519 module->method_to_callers = g_hash_table_new (NULL, NULL);
8523 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8526 LLVMValueRef res, *vals;
8528 vals = g_new0 (LLVMValueRef, nvalues);
8529 for (i = 0; i < nvalues; ++i)
8530 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8531 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8537 llvm_array_from_bytes (guint8 *values, int nvalues)
8540 LLVMValueRef res, *vals;
8542 vals = g_new0 (LLVMValueRef, nvalues);
8543 for (i = 0; i < nvalues; ++i)
8544 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8545 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8550 * mono_llvm_emit_aot_file_info:
8552 * Emit the MonoAotFileInfo structure.
8553 * Same as emit_aot_file_info () in aot-compiler.c.
8556 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8558 MonoLLVMModule *module = &aot_module;
8560 /* Save these for later */
8561 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8562 module->has_jitted_code = has_jitted_code;
8566 * mono_llvm_emit_aot_data:
8568 * Emit the binary data DATA pointed to by symbol SYMBOL.
8571 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8573 MonoLLVMModule *module = &aot_module;
8577 type = LLVMArrayType (LLVMInt8Type (), data_len);
8578 d = LLVMAddGlobal (module->lmodule, type, symbol);
8579 LLVMSetVisibility (d, LLVMHiddenVisibility);
8580 LLVMSetLinkage (d, LLVMInternalLinkage);
8581 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8582 mono_llvm_set_is_constant (d);
8585 /* Add a reference to a global defined in JITted code */
8587 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8592 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8593 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8599 emit_aot_file_info (MonoLLVMModule *module)
8601 LLVMTypeRef file_info_type;
8602 LLVMTypeRef *eltypes, eltype;
8603 LLVMValueRef info_var;
8604 LLVMValueRef *fields;
8605 int i, nfields, tindex;
8606 MonoAotFileInfo *info;
8607 LLVMModuleRef lmodule = module->lmodule;
8609 info = &module->aot_info;
8611 /* Create an LLVM type to represent MonoAotFileInfo */
8612 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8613 eltypes = g_new (LLVMTypeRef, nfields);
8615 eltypes [tindex ++] = LLVMInt32Type ();
8616 eltypes [tindex ++] = LLVMInt32Type ();
8618 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8619 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8621 for (i = 0; i < 15; ++i)
8622 eltypes [tindex ++] = LLVMInt32Type ();
8624 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8625 for (i = 0; i < 4; ++i)
8626 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8627 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8628 g_assert (tindex == nfields);
8629 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8630 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8632 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8633 if (module->static_link) {
8634 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8635 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8637 fields = g_new (LLVMValueRef, nfields);
8639 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8640 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8644 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8645 * for symbols defined in the .s file emitted by the aot compiler.
8647 eltype = eltypes [tindex];
8648 if (module->llvm_only)
8649 fields [tindex ++] = LLVMConstNull (eltype);
8651 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8652 fields [tindex ++] = module->got_var;
8653 /* llc defines this directly */
8654 if (!module->llvm_only) {
8655 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8656 fields [tindex ++] = LLVMConstNull (eltype);
8657 fields [tindex ++] = LLVMConstNull (eltype);
8659 fields [tindex ++] = LLVMConstNull (eltype);
8660 fields [tindex ++] = module->get_method;
8661 fields [tindex ++] = module->get_unbox_tramp;
8663 if (module->has_jitted_code) {
8664 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8665 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8667 fields [tindex ++] = LLVMConstNull (eltype);
8668 fields [tindex ++] = LLVMConstNull (eltype);
8670 if (!module->llvm_only)
8671 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8673 fields [tindex ++] = LLVMConstNull (eltype);
8674 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8675 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8676 fields [tindex ++] = LLVMConstNull (eltype);
8678 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8679 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8680 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8681 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8682 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8683 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8684 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8685 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8686 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8687 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8689 /* Not needed (mem_end) */
8690 fields [tindex ++] = LLVMConstNull (eltype);
8691 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8692 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8693 if (info->trampoline_size [0]) {
8694 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8695 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8696 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8697 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8699 fields [tindex ++] = LLVMConstNull (eltype);
8700 fields [tindex ++] = LLVMConstNull (eltype);
8701 fields [tindex ++] = LLVMConstNull (eltype);
8702 fields [tindex ++] = LLVMConstNull (eltype);
8704 if (module->static_link && !module->llvm_only)
8705 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8707 fields [tindex ++] = LLVMConstNull (eltype);
8708 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8709 if (!module->llvm_only) {
8710 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8711 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8712 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8713 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8714 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8715 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8717 fields [tindex ++] = LLVMConstNull (eltype);
8718 fields [tindex ++] = LLVMConstNull (eltype);
8719 fields [tindex ++] = LLVMConstNull (eltype);
8720 fields [tindex ++] = LLVMConstNull (eltype);
8721 fields [tindex ++] = LLVMConstNull (eltype);
8722 fields [tindex ++] = LLVMConstNull (eltype);
8725 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8726 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8729 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8730 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8731 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8732 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8733 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8734 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8735 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8736 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8737 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8738 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8739 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8740 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8741 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8742 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8743 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8745 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8746 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8747 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8748 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8749 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8751 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8752 g_assert (tindex == nfields);
8754 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8756 if (module->static_link) {
8760 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8761 /* Get rid of characters which cannot occur in symbols */
8763 for (p = s; *p; ++p) {
8764 if (!(isalnum (*p) || *p == '_'))
8767 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8769 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8770 LLVMSetLinkage (var, LLVMExternalLinkage);
8775 * Emit the aot module into the LLVM bitcode file FILENAME.
8778 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8780 LLVMTypeRef got_type, inited_type;
8781 LLVMValueRef real_got, real_inited;
8782 MonoLLVMModule *module = &aot_module;
8784 emit_llvm_code_end (module);
8787 * Create the real got variable and replace all uses of the dummy variable with
8790 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8791 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8792 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8793 if (module->external_symbols) {
8794 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8795 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8797 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8799 mono_llvm_replace_uses_of (module->got_var, real_got);
8801 mark_as_used (&aot_module, real_got);
8803 /* Delete the dummy got so it doesn't become a global */
8804 LLVMDeleteGlobal (module->got_var);
8805 module->got_var = real_got;
8808 * Same for the init_var
8810 if (module->llvm_only) {
8811 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8812 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8813 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8814 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8815 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8816 LLVMDeleteGlobal (module->inited_var);
8819 if (module->llvm_only) {
8820 emit_get_method (&aot_module);
8821 emit_get_unbox_tramp (&aot_module);
8824 emit_llvm_used (&aot_module);
8825 emit_dbg_info (&aot_module, filename, cu_name);
8826 emit_aot_file_info (&aot_module);
8829 * Replace GOT entries for directly callable methods with the methods themselves.
8830 * It would be easier to implement this by predefining all methods before compiling
8831 * their bodies, but that couldn't handle the case when a method fails to compile
8834 if (module->llvm_only) {
8835 GHashTableIter iter;
8837 GSList *callers, *l;
8839 g_hash_table_iter_init (&iter, module->method_to_callers);
8840 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8841 LLVMValueRef lmethod;
8843 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8846 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8848 for (l = callers; l; l = l->next) {
8849 LLVMValueRef caller = (LLVMValueRef)l->data;
8851 mono_llvm_replace_uses_of (caller, lmethod);
8857 /* Replace PLT entries for directly callable methods with the methods themselves */
8859 GHashTableIter iter;
8861 LLVMValueRef callee;
8863 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8864 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8865 if (mono_aot_is_direct_callable (ji)) {
8866 LLVMValueRef lmethod;
8868 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8869 /* The types might not match because the caller might pass an rgctx */
8870 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8871 mono_llvm_replace_uses_of (callee, lmethod);
8872 mono_aot_mark_unused_llvm_plt_entry (ji);
8882 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8883 printf ("%s\n", verifier_err);
8884 g_assert_not_reached ();
8889 LLVMWriteBitcodeToFile (module->lmodule, filename);
8894 md_string (const char *s)
8896 return LLVMMDString (s, strlen (s));
8899 /* Debugging support */
8902 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8904 LLVMModuleRef lmodule = module->lmodule;
8905 LLVMValueRef args [16], ver;
8908 * This can only be enabled when LLVM code is emitted into a separate object
8909 * file, since the AOT compiler also emits dwarf info,
8910 * and the abbrev indexes will not be correct since llvm has added its own
8913 if (!module->emit_dwarf)
8916 #if LLVM_API_VERSION > 100
8917 mono_llvm_di_builder_finalize (module->di_builder);
8919 LLVMValueRef cu_args [16], cu;
8921 char *build_info, *s, *dir;
8924 * Emit dwarf info in the form of LLVM metadata. There is some
8925 * out-of-date documentation at:
8926 * http://llvm.org/docs/SourceLevelDebugging.html
8927 * but most of this was gathered from the llvm and
8932 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8933 /* CU name/compilation dir */
8934 dir = g_path_get_dirname (filename);
8935 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8936 args [1] = LLVMMDString (dir, strlen (dir));
8937 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8940 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8942 build_info = mono_get_runtime_build_info ();
8943 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8944 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8945 g_free (build_info);
8947 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8949 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8950 /* Runtime version */
8951 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8953 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8954 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8956 if (module->subprogram_mds) {
8960 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8961 for (i = 0; i < module->subprogram_mds->len; ++i)
8962 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8963 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8965 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8968 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8969 /* Imported modules */
8970 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8972 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8973 /* DebugEmissionKind = FullDebug */
8974 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8975 cu = LLVMMDNode (cu_args, n_cuargs);
8976 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8979 #if LLVM_API_VERSION > 100
8980 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8981 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8982 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8983 ver = LLVMMDNode (args, 3);
8984 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8986 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8987 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8988 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8989 ver = LLVMMDNode (args, 3);
8990 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8992 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8993 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8994 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8995 ver = LLVMMDNode (args, 3);
8996 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8998 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8999 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9000 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9001 ver = LLVMMDNode (args, 3);
9002 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9007 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9009 MonoLLVMModule *module = ctx->module;
9010 MonoDebugMethodInfo *minfo = ctx->minfo;
9011 char *source_file, *dir, *filename;
9012 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9013 MonoSymSeqPoint *sym_seq_points;
9019 mono_debug_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9021 source_file = g_strdup ("<unknown>");
9022 dir = g_path_get_dirname (source_file);
9023 filename = g_path_get_basename (source_file);
9025 #if LLVM_API_VERSION > 100
9026 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);
9029 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9030 args [0] = md_string (filename);
9031 args [1] = md_string (dir);
9032 ctx_args [1] = LLVMMDNode (args, 2);
9033 ctx_md = LLVMMDNode (ctx_args, 2);
9035 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9036 type_args [1] = NULL;
9037 type_args [2] = NULL;
9038 type_args [3] = LLVMMDString ("", 0);
9039 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9040 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9041 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9042 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9043 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9044 type_args [9] = NULL;
9045 type_args [10] = NULL;
9046 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9047 type_args [12] = NULL;
9048 type_args [13] = NULL;
9049 type_args [14] = NULL;
9050 type_md = LLVMMDNode (type_args, 14);
9052 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9053 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9054 /* Source directory + file pair */
9055 args [0] = md_string (filename);
9056 args [1] = md_string (dir);
9057 md_args [1] = LLVMMDNode (args ,2);
9058 md_args [2] = ctx_md;
9059 md_args [3] = md_string (cfg->method->name);
9060 md_args [4] = md_string (name);
9061 md_args [5] = md_string (name);
9064 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9066 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9068 md_args [7] = type_md;
9070 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9072 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9074 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9075 /* Index into a virtual function */
9076 md_args [11] = NULL;
9077 md_args [12] = NULL;
9079 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9081 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9082 /* Pointer to LLVM function */
9083 md_args [15] = method;
9084 /* Function template parameter */
9085 md_args [16] = NULL;
9086 /* Function declaration descriptor */
9087 md_args [17] = NULL;
9088 /* List of function variables */
9089 md_args [18] = LLVMMDNode (args, 0);
9091 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9092 md = LLVMMDNode (md_args, 20);
9094 if (!module->subprogram_mds)
9095 module->subprogram_mds = g_ptr_array_new ();
9096 g_ptr_array_add (module->subprogram_mds, md);
9100 g_free (source_file);
9101 g_free (sym_seq_points);
9107 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9109 MonoCompile *cfg = ctx->cfg;
9111 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9112 MonoDebugSourceLocation *loc;
9113 LLVMValueRef loc_md;
9115 loc = mono_debug_method_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9118 #if LLVM_API_VERSION > 100
9119 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9120 mono_llvm_di_set_location (builder, loc_md);
9122 LLVMValueRef md_args [16];
9126 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9127 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9128 md_args [nmd_args ++] = ctx->dbg_md;
9129 md_args [nmd_args ++] = NULL;
9130 loc_md = LLVMMDNode (md_args, nmd_args);
9131 LLVMSetCurrentDebugLocation (builder, loc_md);
9133 mono_debug_free_source_location (loc);
9139 default_mono_llvm_unhandled_exception (void)
9141 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9142 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9144 mono_unhandled_exception (target);
9145 mono_invoke_unhandled_exception_hook (target);
9146 g_assert_not_reached ();
9151 - Emit LLVM IR from the mono IR using the LLVM C API.
9152 - The original arch specific code remains, so we can fall back to it if we run
9153 into something we can't handle.
9157 A partial list of issues:
9158 - Handling of opcodes which can throw exceptions.
9160 In the mono JIT, these are implemented using code like this:
9167 push throw_pos - method
9168 call <exception trampoline>
9170 The problematic part is push throw_pos - method, which cannot be represented
9171 in the LLVM IR, since it does not support label values.
9172 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9173 be implemented in JIT mode ?
9174 -> a possible but slower implementation would use the normal exception
9175 throwing code but it would need to control the placement of the throw code
9176 (it needs to be exactly after the compare+branch).
9177 -> perhaps add a PC offset intrinsics ?
9179 - efficient implementation of .ovf opcodes.
9181 These are currently implemented as:
9182 <ins which sets the condition codes>
9185 Some overflow opcodes are now supported by LLVM SVN.
9187 - exception handling, unwinding.
9188 - SSA is disabled for methods with exception handlers
9189 - How to obtain unwind info for LLVM compiled methods ?
9190 -> this is now solved by converting the unwind info generated by LLVM
9192 - LLVM uses the c++ exception handling framework, while we use our home grown
9193 code, and couldn't use the c++ one:
9194 - its not supported under VC++, other exotic platforms.
9195 - it might be impossible to support filter clauses with it.
9199 The trampolines need a predictable call sequence, since they need to disasm
9200 the calling code to obtain register numbers / offsets.
9202 LLVM currently generates this code in non-JIT mode:
9203 mov -0x98(%rax),%eax
9205 Here, the vtable pointer is lost.
9206 -> solution: use one vtable trampoline per class.
9208 - passing/receiving the IMT pointer/RGCTX.
9209 -> solution: pass them as normal arguments ?
9213 LLVM does not allow the specification of argument registers etc. This means
9214 that all calls are made according to the platform ABI.
9216 - passing/receiving vtypes.
9218 Vtypes passed/received in registers are handled by the front end by using
9219 a signature with scalar arguments, and loading the parts of the vtype into those
9222 Vtypes passed on the stack are handled using the 'byval' attribute.
9226 Supported though alloca, we need to emit the load/store code.
9230 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9231 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9232 This is made easier because the IR is already in SSA form.
9233 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9234 types are frequently used incorrectly.
9239 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9240 it with the file containing the methods emitted by the JIT and the AOT data
9244 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9245 * - each bblock should end with a branch
9246 * - setting the return value, making cfg->ret non-volatile
9247 * - avoid some transformations in the JIT which make it harder for us to generate
9249 * - use pointer types to help optimizations.
9252 #else /* DISABLE_JIT */
9255 mono_llvm_cleanup (void)
9260 mono_llvm_free_domain_info (MonoDomain *domain)
9265 mono_llvm_init (void)
9270 default_mono_llvm_unhandled_exception (void)
9274 #endif /* DISABLE_JIT */