2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11 #include <mono/metadata/debug-helpers.h>
12 #include <mono/metadata/debug-mono-symfile.h>
13 #include <mono/metadata/mempool-internals.h>
14 #include <mono/metadata/environment.h>
15 #include <mono/metadata/object-internals.h>
16 #include <mono/metadata/abi-details.h>
17 #include <mono/utils/mono-tls.h>
18 #include <mono/utils/mono-dl.h>
19 #include <mono/utils/mono-time.h>
20 #include <mono/utils/freebsd-dwarf.h>
22 #ifndef __STDC_LIMIT_MACROS
23 #define __STDC_LIMIT_MACROS
25 #ifndef __STDC_CONSTANT_MACROS
26 #define __STDC_CONSTANT_MACROS
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #include "mini-llvm-cpp.h"
34 #include "aot-compiler.h"
35 #include "mini-llvm.h"
42 extern void *memset(void *, int, size_t);
43 void bzero (void *to, size_t count) { memset (to, 0, count); }
47 #if LLVM_API_VERSION < 4
48 #error "The version of the mono llvm repository is too old."
51 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
54 * Information associated by mono with LLVM modules.
57 LLVMModuleRef lmodule;
58 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
59 GHashTable *llvm_types;
61 const char *got_symbol;
62 const char *get_method_symbol;
63 const char *get_unbox_tramp_symbol;
64 GHashTable *plt_entries;
65 GHashTable *plt_entries_ji;
66 GHashTable *method_to_lmethod;
67 GHashTable *direct_callables;
72 GPtrArray *subprogram_mds;
74 LLVMExecutionEngineRef ee;
75 gboolean external_symbols;
78 LLVMValueRef personality;
81 MonoAssembly *assembly;
83 MonoAotFileInfo aot_info;
84 const char *jit_got_symbol;
85 const char *eh_frame_symbol;
86 LLVMValueRef get_method, get_unbox_tramp;
87 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
88 LLVMValueRef code_start, code_end;
89 LLVMValueRef inited_var;
90 int max_inited_idx, max_method_idx;
91 gboolean has_jitted_code;
94 GHashTable *idx_to_lmethod;
95 GHashTable *idx_to_unbox_tramp;
96 /* Maps a MonoMethod to LLVM instructions representing it */
97 GHashTable *method_to_callers;
98 LLVMContextRef context;
99 LLVMValueRef sentinel_exception;
100 void *di_builder, *cu;
101 GHashTable *objc_selector_to_var;
105 * Information associated by the backend with mono basic blocks.
108 LLVMBasicBlockRef bblock, end_bblock;
109 LLVMValueRef finally_ind;
110 gboolean added, invoke_target;
112 * If this bblock is the start of a finally clause, this is a list of bblocks it
113 * needs to branch to in ENDFINALLY.
115 GSList *call_handler_return_bbs;
117 * If this bblock is the start of a finally clause, this is the bblock that
118 * CALL_HANDLER needs to branch to.
120 LLVMBasicBlockRef call_handler_target_bb;
121 /* The list of switch statements generated by ENDFINALLY instructions */
122 GSList *endfinally_switch_ins_list;
127 * Structure containing emit state
130 MonoMemPool *mempool;
132 /* Maps method names to the corresponding LLVMValueRef */
133 GHashTable *emitted_method_decls;
136 LLVMValueRef lmethod;
137 MonoLLVMModule *module;
138 LLVMModuleRef lmodule;
140 int sindex, default_index, ex_index;
141 LLVMBuilderRef builder;
142 LLVMValueRef *values, *addresses;
143 MonoType **vreg_cli_types;
145 MonoMethodSignature *sig;
147 GHashTable *region_to_handler;
148 GHashTable *clause_to_handler;
149 LLVMBuilderRef alloca_builder;
150 LLVMValueRef last_alloca;
151 LLVMValueRef rgctx_arg;
152 LLVMValueRef this_arg;
153 LLVMTypeRef *vreg_types;
155 LLVMTypeRef method_type;
156 LLVMBasicBlockRef init_bb, inited_bb;
158 gboolean *unreachable;
160 gboolean has_got_access;
161 gboolean is_linkonce;
162 int this_arg_pindex, rgctx_arg_pindex;
163 LLVMValueRef imt_rgctx_loc;
164 GHashTable *llvm_types;
166 MonoDebugMethodInfo *minfo;
168 /* For every clause, the clauses it is nested in */
171 GHashTable *exc_meta;
172 GHashTable *method_to_callers;
173 GPtrArray *phi_values;
174 GPtrArray *bblock_list;
176 GHashTable *jit_callees;
177 LLVMValueRef long_bb_break_var;
183 MonoBasicBlock *in_bb;
188 * Instruction metadata
189 * This is the same as ins_info, but LREG != IREG.
197 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
198 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
205 /* keep in sync with the enum in mini.h */
208 #include "mini-ops.h"
213 #if SIZEOF_VOID_P == 4
214 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
216 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
219 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
222 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
224 #define TRACE_FAILURE(msg)
228 #define IS_TARGET_X86 1
230 #define IS_TARGET_X86 0
234 #define IS_TARGET_AMD64 1
236 #define IS_TARGET_AMD64 0
239 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
241 static LLVMIntPredicate cond_to_llvm_cond [] = {
254 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
267 static MonoNativeTlsKey current_cfg_tls_id;
269 static MonoLLVMModule aot_module;
271 static GHashTable *intrins_id_to_name;
272 static GHashTable *intrins_name_to_id;
274 static void init_jit_module (MonoDomain *domain);
276 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
277 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
278 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
279 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
280 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
281 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
284 set_failure (EmitContext *ctx, const char *message)
286 TRACE_FAILURE (reason);
287 ctx->cfg->exception_message = g_strdup (message);
288 ctx->cfg->disable_llvm = TRUE;
294 * The LLVM type with width == sizeof (gpointer)
299 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
305 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
311 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
317 * Return the size of the LLVM representation of the vtype T.
320 get_vtype_size (MonoType *t)
324 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
326 /* LLVMArgAsIArgs depends on this since it stores whole words */
327 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
334 * simd_class_to_llvm_type:
336 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
339 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
341 if (!strcmp (klass->name, "Vector2d")) {
342 return LLVMVectorType (LLVMDoubleType (), 2);
343 } else if (!strcmp (klass->name, "Vector2l")) {
344 return LLVMVectorType (LLVMInt64Type (), 2);
345 } else if (!strcmp (klass->name, "Vector2ul")) {
346 return LLVMVectorType (LLVMInt64Type (), 2);
347 } else if (!strcmp (klass->name, "Vector4i")) {
348 return LLVMVectorType (LLVMInt32Type (), 4);
349 } else if (!strcmp (klass->name, "Vector4ui")) {
350 return LLVMVectorType (LLVMInt32Type (), 4);
351 } else if (!strcmp (klass->name, "Vector4f")) {
352 return LLVMVectorType (LLVMFloatType (), 4);
353 } else if (!strcmp (klass->name, "Vector8s")) {
354 return LLVMVectorType (LLVMInt16Type (), 8);
355 } else if (!strcmp (klass->name, "Vector8us")) {
356 return LLVMVectorType (LLVMInt16Type (), 8);
357 } else if (!strcmp (klass->name, "Vector16sb")) {
358 return LLVMVectorType (LLVMInt8Type (), 16);
359 } else if (!strcmp (klass->name, "Vector16b")) {
360 return LLVMVectorType (LLVMInt8Type (), 16);
361 } else if (!strcmp (klass->name, "Vector2")) {
362 /* System.Numerics */
363 return LLVMVectorType (LLVMFloatType (), 4);
364 } else if (!strcmp (klass->name, "Vector3")) {
365 return LLVMVectorType (LLVMFloatType (), 4);
366 } else if (!strcmp (klass->name, "Vector4")) {
367 return LLVMVectorType (LLVMFloatType (), 4);
368 } else if (!strcmp (klass->name, "Vector`1")) {
369 MonoType *etype = mono_class_get_generic_class (klass)->context.class_inst->type_argv [0];
370 switch (etype->type) {
373 return LLVMVectorType (LLVMInt8Type (), 16);
376 return LLVMVectorType (LLVMInt16Type (), 8);
379 return LLVMVectorType (LLVMInt32Type (), 4);
382 return LLVMVectorType (LLVMInt64Type (), 2);
384 return LLVMVectorType (LLVMFloatType (), 4);
386 return LLVMVectorType (LLVMDoubleType (), 2);
388 g_assert_not_reached ();
392 printf ("%s\n", klass->name);
398 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
399 static inline G_GNUC_UNUSED LLVMTypeRef
400 type_to_simd_type (int type)
404 return LLVMVectorType (LLVMInt8Type (), 16);
406 return LLVMVectorType (LLVMInt16Type (), 8);
408 return LLVMVectorType (LLVMInt32Type (), 4);
410 return LLVMVectorType (LLVMInt64Type (), 2);
412 return LLVMVectorType (LLVMDoubleType (), 2);
414 return LLVMVectorType (LLVMFloatType (), 4);
416 g_assert_not_reached ();
422 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
424 int i, size, nfields, esize;
425 LLVMTypeRef *eltypes;
430 t = &klass->byval_arg;
432 if (mini_type_is_hfa (t, &nfields, &esize)) {
434 * This is needed on arm64 where HFAs are returned in
438 eltypes = g_new (LLVMTypeRef, size);
439 for (i = 0; i < size; ++i)
440 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
442 size = get_vtype_size (t);
444 eltypes = g_new (LLVMTypeRef, size);
445 for (i = 0; i < size; ++i)
446 eltypes [i] = LLVMInt8Type ();
449 name = mono_type_full_name (&klass->byval_arg);
450 ltype = LLVMStructCreateNamed (module->context, name);
451 LLVMStructSetBody (ltype, eltypes, size, FALSE);
461 * Return the LLVM type corresponding to T.
464 type_to_llvm_type (EmitContext *ctx, MonoType *t)
466 t = mini_get_underlying_type (t);
470 return LLVMVoidType ();
472 return LLVMInt8Type ();
474 return LLVMInt16Type ();
476 return LLVMInt32Type ();
478 return LLVMInt8Type ();
480 return LLVMInt16Type ();
482 return LLVMInt32Type ();
483 case MONO_TYPE_BOOLEAN:
484 return LLVMInt8Type ();
487 return LLVMInt64Type ();
489 return LLVMInt16Type ();
491 return LLVMFloatType ();
493 return LLVMDoubleType ();
496 return IntPtrType ();
497 case MONO_TYPE_OBJECT:
498 case MONO_TYPE_CLASS:
499 case MONO_TYPE_ARRAY:
500 case MONO_TYPE_SZARRAY:
501 case MONO_TYPE_STRING:
503 return ObjRefType ();
506 /* Because of generic sharing */
507 return ObjRefType ();
508 case MONO_TYPE_GENERICINST:
509 if (!mono_type_generic_inst_is_valuetype (t))
510 return ObjRefType ();
512 case MONO_TYPE_VALUETYPE:
513 case MONO_TYPE_TYPEDBYREF: {
517 klass = mono_class_from_mono_type (t);
519 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
520 return simd_class_to_llvm_type (ctx, klass);
523 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
525 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
527 ltype = create_llvm_type_for_type (ctx->module, klass);
528 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
534 printf ("X: %d\n", t->type);
535 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
536 ctx->cfg->disable_llvm = TRUE;
544 * Return whenever T is an unsigned int type.
547 type_is_unsigned (EmitContext *ctx, MonoType *t)
549 t = mini_get_underlying_type (t);
565 * type_to_llvm_arg_type:
567 * Same as type_to_llvm_type, but treat i8/i16 as i32.
570 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
572 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
574 if (ctx->cfg->llvm_only)
578 * This works on all abis except arm64/ios which passes multiple
579 * arguments in one stack slot.
582 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
584 * LLVM generates code which only sets the lower bits, while JITted
585 * code expects all the bits to be set.
587 ptype = LLVMInt32Type ();
595 * llvm_type_to_stack_type:
597 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
600 static G_GNUC_UNUSED LLVMTypeRef
601 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
605 if (type == LLVMInt8Type ())
606 return LLVMInt32Type ();
607 else if (type == LLVMInt16Type ())
608 return LLVMInt32Type ();
609 else if (!cfg->r4fp && type == LLVMFloatType ())
610 return LLVMDoubleType ();
616 * regtype_to_llvm_type:
618 * Return the LLVM type corresponding to the regtype C used in instruction
622 regtype_to_llvm_type (char c)
626 return LLVMInt32Type ();
628 return LLVMInt64Type ();
630 return LLVMDoubleType ();
639 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
642 op_to_llvm_type (int opcode)
647 return LLVMInt8Type ();
650 return LLVMInt8Type ();
653 return LLVMInt16Type ();
656 return LLVMInt16Type ();
659 return LLVMInt32Type ();
662 return LLVMInt32Type ();
664 return LLVMInt64Type ();
666 return LLVMFloatType ();
668 return LLVMDoubleType ();
670 return LLVMInt64Type ();
672 return LLVMInt32Type ();
674 return LLVMInt64Type ();
679 return LLVMInt8Type ();
684 return LLVMInt16Type ();
686 return LLVMInt32Type ();
689 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
696 return LLVMInt32Type ();
703 return LLVMInt64Type ();
705 printf ("%s\n", mono_inst_name (opcode));
706 g_assert_not_reached ();
711 #define CLAUSE_START(clause) ((clause)->try_offset)
712 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
715 * load_store_to_llvm_type:
717 * Return the size/sign/zero extension corresponding to the load/store opcode
721 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
727 case OP_LOADI1_MEMBASE:
728 case OP_STOREI1_MEMBASE_REG:
729 case OP_STOREI1_MEMBASE_IMM:
730 case OP_ATOMIC_LOAD_I1:
731 case OP_ATOMIC_STORE_I1:
734 return LLVMInt8Type ();
735 case OP_LOADU1_MEMBASE:
737 case OP_ATOMIC_LOAD_U1:
738 case OP_ATOMIC_STORE_U1:
741 return LLVMInt8Type ();
742 case OP_LOADI2_MEMBASE:
743 case OP_STOREI2_MEMBASE_REG:
744 case OP_STOREI2_MEMBASE_IMM:
745 case OP_ATOMIC_LOAD_I2:
746 case OP_ATOMIC_STORE_I2:
749 return LLVMInt16Type ();
750 case OP_LOADU2_MEMBASE:
752 case OP_ATOMIC_LOAD_U2:
753 case OP_ATOMIC_STORE_U2:
756 return LLVMInt16Type ();
757 case OP_LOADI4_MEMBASE:
758 case OP_LOADU4_MEMBASE:
761 case OP_STOREI4_MEMBASE_REG:
762 case OP_STOREI4_MEMBASE_IMM:
763 case OP_ATOMIC_LOAD_I4:
764 case OP_ATOMIC_STORE_I4:
765 case OP_ATOMIC_LOAD_U4:
766 case OP_ATOMIC_STORE_U4:
768 return LLVMInt32Type ();
769 case OP_LOADI8_MEMBASE:
771 case OP_STOREI8_MEMBASE_REG:
772 case OP_STOREI8_MEMBASE_IMM:
773 case OP_ATOMIC_LOAD_I8:
774 case OP_ATOMIC_STORE_I8:
775 case OP_ATOMIC_LOAD_U8:
776 case OP_ATOMIC_STORE_U8:
778 return LLVMInt64Type ();
779 case OP_LOADR4_MEMBASE:
780 case OP_STORER4_MEMBASE_REG:
781 case OP_ATOMIC_LOAD_R4:
782 case OP_ATOMIC_STORE_R4:
784 return LLVMFloatType ();
785 case OP_LOADR8_MEMBASE:
786 case OP_STORER8_MEMBASE_REG:
787 case OP_ATOMIC_LOAD_R8:
788 case OP_ATOMIC_STORE_R8:
790 return LLVMDoubleType ();
791 case OP_LOAD_MEMBASE:
793 case OP_STORE_MEMBASE_REG:
794 case OP_STORE_MEMBASE_IMM:
795 *size = sizeof (gpointer);
796 return IntPtrType ();
798 g_assert_not_reached ();
806 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
809 ovf_op_to_intrins (int opcode)
813 return "llvm.sadd.with.overflow.i32";
815 return "llvm.uadd.with.overflow.i32";
817 return "llvm.ssub.with.overflow.i32";
819 return "llvm.usub.with.overflow.i32";
821 return "llvm.smul.with.overflow.i32";
823 return "llvm.umul.with.overflow.i32";
825 return "llvm.sadd.with.overflow.i64";
827 return "llvm.uadd.with.overflow.i64";
829 return "llvm.ssub.with.overflow.i64";
831 return "llvm.usub.with.overflow.i64";
833 return "llvm.smul.with.overflow.i64";
835 return "llvm.umul.with.overflow.i64";
837 g_assert_not_reached ();
843 simd_op_to_intrins (int opcode)
846 #if defined(TARGET_X86) || defined(TARGET_AMD64)
848 return "llvm.x86.sse2.min.pd";
850 return "llvm.x86.sse.min.ps";
852 return "llvm.x86.sse2.max.pd";
854 return "llvm.x86.sse.max.ps";
856 return "llvm.x86.sse3.hadd.pd";
858 return "llvm.x86.sse3.hadd.ps";
860 return "llvm.x86.sse3.hsub.pd";
862 return "llvm.x86.sse3.hsub.ps";
864 return "llvm.x86.sse3.addsub.ps";
866 return "llvm.x86.sse3.addsub.pd";
867 case OP_EXTRACT_MASK:
868 return "llvm.x86.sse2.pmovmskb.128";
871 return "llvm.x86.sse2.psrli.w";
874 return "llvm.x86.sse2.psrli.d";
877 return "llvm.x86.sse2.psrli.q";
880 return "llvm.x86.sse2.pslli.w";
883 return "llvm.x86.sse2.pslli.d";
886 return "llvm.x86.sse2.pslli.q";
889 return "llvm.x86.sse2.psrai.w";
892 return "llvm.x86.sse2.psrai.d";
894 return "llvm.x86.sse2.padds.b";
896 return "llvm.x86.sse2.padds.w";
898 return "llvm.x86.sse2.psubs.b";
900 return "llvm.x86.sse2.psubs.w";
901 case OP_PADDB_SAT_UN:
902 return "llvm.x86.sse2.paddus.b";
903 case OP_PADDW_SAT_UN:
904 return "llvm.x86.sse2.paddus.w";
905 case OP_PSUBB_SAT_UN:
906 return "llvm.x86.sse2.psubus.b";
907 case OP_PSUBW_SAT_UN:
908 return "llvm.x86.sse2.psubus.w";
910 return "llvm.x86.sse2.pavg.b";
912 return "llvm.x86.sse2.pavg.w";
914 return "llvm.x86.sse.sqrt.ps";
916 return "llvm.x86.sse2.sqrt.pd";
918 return "llvm.x86.sse.rsqrt.ps";
920 return "llvm.x86.sse.rcp.ps";
922 return "llvm.x86.sse2.cvtdq2pd";
924 return "llvm.x86.sse2.cvtdq2ps";
926 return "llvm.x86.sse2.cvtpd2dq";
928 return "llvm.x86.sse2.cvtps2dq";
930 return "llvm.x86.sse2.cvtpd2ps";
932 return "llvm.x86.sse2.cvtps2pd";
934 return "llvm.x86.sse2.cvttpd2dq";
936 return "llvm.x86.sse2.cvttps2dq";
938 return "llvm.x86.sse2.packsswb.128";
940 return "llvm.x86.sse2.packssdw.128";
942 return "llvm.x86.sse2.packuswb.128";
944 return "llvm.x86.sse41.packusdw";
946 return "llvm.x86.sse2.pmulh.w";
947 case OP_PMULW_HIGH_UN:
948 return "llvm.x86.sse2.pmulhu.w";
950 return "llvm.x86.sse41.dpps";
953 g_assert_not_reached ();
959 simd_op_to_llvm_type (int opcode)
961 #if defined(TARGET_X86) || defined(TARGET_AMD64)
965 return type_to_simd_type (MONO_TYPE_R8);
968 return type_to_simd_type (MONO_TYPE_I8);
971 return type_to_simd_type (MONO_TYPE_I4);
976 return type_to_simd_type (MONO_TYPE_I2);
980 return type_to_simd_type (MONO_TYPE_I1);
982 return type_to_simd_type (MONO_TYPE_R4);
985 return type_to_simd_type (MONO_TYPE_I4);
989 return type_to_simd_type (MONO_TYPE_R8);
993 return type_to_simd_type (MONO_TYPE_R4);
994 case OP_EXTRACT_MASK:
995 return type_to_simd_type (MONO_TYPE_I1);
1001 return type_to_simd_type (MONO_TYPE_R4);
1004 return type_to_simd_type (MONO_TYPE_R8);
1006 g_assert_not_reached ();
1017 * Return the LLVM basic block corresponding to BB.
1019 static LLVMBasicBlockRef
1020 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1022 char bb_name_buf [128];
1025 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1026 if (bb->flags & BB_EXCEPTION_HANDLER) {
1027 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1028 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1029 bb_name = bb_name_buf;
1030 } else if (bb->block_num < 256) {
1031 if (!ctx->module->bb_names) {
1032 ctx->module->bb_names_len = 256;
1033 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1035 if (!ctx->module->bb_names [bb->block_num]) {
1038 n = g_strdup_printf ("BB%d", bb->block_num);
1039 mono_memory_barrier ();
1040 ctx->module->bb_names [bb->block_num] = n;
1042 bb_name = ctx->module->bb_names [bb->block_num];
1044 sprintf (bb_name_buf, "BB%d", bb->block_num);
1045 bb_name = bb_name_buf;
1048 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1049 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1052 return ctx->bblocks [bb->block_num].bblock;
1058 * Return the last LLVM bblock corresponding to BB.
1059 * This might not be equal to the bb returned by get_bb () since we need to generate
1060 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1062 static LLVMBasicBlockRef
1063 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1066 return ctx->bblocks [bb->block_num].end_bblock;
1069 static LLVMBasicBlockRef
1070 gen_bb (EmitContext *ctx, const char *prefix)
1074 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1075 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1081 * Return the target of the patch identified by TYPE and TARGET.
1084 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1090 memset (&ji, 0, sizeof (ji));
1092 ji.data.target = target;
1094 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1095 mono_error_assert_ok (&error);
1103 * Emit code to convert the LLVM value V to DTYPE.
1106 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1108 LLVMTypeRef stype = LLVMTypeOf (v);
1110 if (stype != dtype) {
1111 gboolean ext = FALSE;
1114 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1116 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1118 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1122 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1124 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1125 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1128 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1129 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1130 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1131 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1132 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1133 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1134 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1135 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1137 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1138 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1139 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1140 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1141 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1142 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1144 if (mono_arch_is_soft_float ()) {
1145 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1146 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1147 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1148 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1151 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1152 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1155 LLVMDumpValue (LLVMConstNull (dtype));
1156 g_assert_not_reached ();
1164 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1166 return convert_full (ctx, v, dtype, FALSE);
1170 * emit_volatile_load:
1172 * If vreg is volatile, emit a load from its address.
1175 emit_volatile_load (EmitContext *ctx, int vreg)
1181 // FIXME: This hack is required because we pass the rgctx in a callee saved
1182 // register on arm64 (x15), and llvm might keep the value in that register
1183 // even through the register is marked as 'reserved' inside llvm.
1184 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1185 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1187 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1189 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1191 t = ctx->vreg_cli_types [vreg];
1192 if (t && !t->byref) {
1194 * Might have to zero extend since llvm doesn't have
1197 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1198 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1199 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1200 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1201 else if (t->type == MONO_TYPE_U8)
1202 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1209 * emit_volatile_store:
1211 * If VREG is volatile, emit a store from its value to its address.
1214 emit_volatile_store (EmitContext *ctx, int vreg)
1216 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1218 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1219 g_assert (ctx->addresses [vreg]);
1220 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1225 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1227 LLVMTypeRef ret_type;
1228 LLVMTypeRef *param_types = NULL;
1233 rtype = mini_get_underlying_type (sig->ret);
1234 ret_type = type_to_llvm_type (ctx, rtype);
1238 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1242 param_types [pindex ++] = ThisType ();
1243 for (i = 0; i < sig->param_count; ++i)
1244 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1246 if (!ctx_ok (ctx)) {
1247 g_free (param_types);
1251 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1252 g_free (param_types);
1258 * sig_to_llvm_sig_full:
1260 * Return the LLVM signature corresponding to the mono signature SIG using the
1261 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1264 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1266 LLVMTypeRef ret_type;
1267 LLVMTypeRef *param_types = NULL;
1269 int i, j, pindex, vret_arg_pindex = 0;
1270 gboolean vretaddr = FALSE;
1274 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1276 rtype = mini_get_underlying_type (sig->ret);
1277 ret_type = type_to_llvm_type (ctx, rtype);
1281 switch (cinfo->ret.storage) {
1282 case LLVMArgVtypeInReg:
1283 /* LLVM models this by returning an aggregate value */
1284 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1285 LLVMTypeRef members [2];
1287 members [0] = IntPtrType ();
1288 ret_type = LLVMStructType (members, 1, FALSE);
1289 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1291 ret_type = LLVMVoidType ();
1292 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1293 LLVMTypeRef members [2];
1295 members [0] = IntPtrType ();
1296 members [1] = IntPtrType ();
1297 ret_type = LLVMStructType (members, 2, FALSE);
1299 g_assert_not_reached ();
1302 case LLVMArgVtypeByVal:
1303 /* Vtype returned normally by val */
1305 case LLVMArgVtypeAsScalar: {
1306 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1307 /* LLVM models this by returning an int */
1308 if (size < SIZEOF_VOID_P) {
1309 g_assert (cinfo->ret.nslots == 1);
1310 ret_type = LLVMIntType (size * 8);
1312 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1313 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1317 case LLVMArgAsIArgs:
1318 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1320 case LLVMArgFpStruct: {
1321 /* Vtype returned as a fp struct */
1322 LLVMTypeRef members [16];
1324 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1325 for (i = 0; i < cinfo->ret.nslots; ++i)
1326 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1327 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1330 case LLVMArgVtypeByRef:
1331 /* Vtype returned using a hidden argument */
1332 ret_type = LLVMVoidType ();
1334 case LLVMArgVtypeRetAddr:
1335 case LLVMArgGsharedvtFixed:
1336 case LLVMArgGsharedvtFixedVtype:
1337 case LLVMArgGsharedvtVariable:
1339 ret_type = LLVMVoidType ();
1345 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1347 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1349 * Has to be the first argument because of the sret argument attribute
1350 * FIXME: This might conflict with passing 'this' as the first argument, but
1351 * this is only used on arm64 which has a dedicated struct return register.
1353 cinfo->vret_arg_pindex = pindex;
1354 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1355 if (!ctx_ok (ctx)) {
1356 g_free (param_types);
1359 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1362 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1363 cinfo->rgctx_arg_pindex = pindex;
1364 param_types [pindex] = ctx->module->ptr_type;
1367 if (cinfo->imt_arg) {
1368 cinfo->imt_arg_pindex = pindex;
1369 param_types [pindex] = ctx->module->ptr_type;
1373 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1374 vret_arg_pindex = pindex;
1375 if (cinfo->vret_arg_index == 1) {
1376 /* Add the slots consumed by the first argument */
1377 LLVMArgInfo *ainfo = &cinfo->args [0];
1378 switch (ainfo->storage) {
1379 case LLVMArgVtypeInReg:
1380 for (j = 0; j < 2; ++j) {
1381 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1390 cinfo->vret_arg_pindex = vret_arg_pindex;
1393 if (vretaddr && vret_arg_pindex == pindex)
1394 param_types [pindex ++] = IntPtrType ();
1396 cinfo->this_arg_pindex = pindex;
1397 param_types [pindex ++] = ThisType ();
1398 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1400 if (vretaddr && vret_arg_pindex == pindex)
1401 param_types [pindex ++] = IntPtrType ();
1402 for (i = 0; i < sig->param_count; ++i) {
1403 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1405 if (vretaddr && vret_arg_pindex == pindex)
1406 param_types [pindex ++] = IntPtrType ();
1407 ainfo->pindex = pindex;
1409 switch (ainfo->storage) {
1410 case LLVMArgVtypeInReg:
1411 for (j = 0; j < 2; ++j) {
1412 switch (ainfo->pair_storage [j]) {
1414 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1419 g_assert_not_reached ();
1423 case LLVMArgVtypeByVal:
1424 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1427 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1430 case LLVMArgAsIArgs:
1431 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1434 case LLVMArgVtypeByRef:
1435 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1438 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1441 case LLVMArgAsFpArgs: {
1444 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1445 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1446 param_types [pindex ++] = LLVMDoubleType ();
1447 for (j = 0; j < ainfo->nslots; ++j)
1448 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1451 case LLVMArgVtypeAsScalar:
1452 g_assert_not_reached ();
1454 case LLVMArgGsharedvtFixed:
1455 case LLVMArgGsharedvtFixedVtype:
1456 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1458 case LLVMArgGsharedvtVariable:
1459 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1462 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1466 if (!ctx_ok (ctx)) {
1467 g_free (param_types);
1470 if (vretaddr && vret_arg_pindex == pindex)
1471 param_types [pindex ++] = IntPtrType ();
1472 if (ctx->llvm_only && cinfo->rgctx_arg) {
1473 /* Pass the rgctx as the last argument */
1474 cinfo->rgctx_arg_pindex = pindex;
1475 param_types [pindex] = ctx->module->ptr_type;
1479 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1480 g_free (param_types);
1486 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1488 return sig_to_llvm_sig_full (ctx, sig, NULL);
1492 * LLVMFunctionType1:
1494 * Create an LLVM function type from the arguments.
1496 static G_GNUC_UNUSED LLVMTypeRef
1497 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1500 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1504 * LLVMFunctionType1:
1506 * Create an LLVM function type from the arguments.
1508 static G_GNUC_UNUSED LLVMTypeRef
1509 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1510 LLVMTypeRef ParamType1,
1513 LLVMTypeRef param_types [1];
1515 param_types [0] = ParamType1;
1517 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1521 * LLVMFunctionType2:
1523 * Create an LLVM function type from the arguments.
1525 static G_GNUC_UNUSED LLVMTypeRef
1526 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1527 LLVMTypeRef ParamType1,
1528 LLVMTypeRef ParamType2,
1531 LLVMTypeRef param_types [2];
1533 param_types [0] = ParamType1;
1534 param_types [1] = ParamType2;
1536 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1540 * LLVMFunctionType3:
1542 * Create an LLVM function type from the arguments.
1544 static G_GNUC_UNUSED LLVMTypeRef
1545 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1546 LLVMTypeRef ParamType1,
1547 LLVMTypeRef ParamType2,
1548 LLVMTypeRef ParamType3,
1551 LLVMTypeRef param_types [3];
1553 param_types [0] = ParamType1;
1554 param_types [1] = ParamType2;
1555 param_types [2] = ParamType3;
1557 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1560 static G_GNUC_UNUSED LLVMTypeRef
1561 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1562 LLVMTypeRef ParamType1,
1563 LLVMTypeRef ParamType2,
1564 LLVMTypeRef ParamType3,
1565 LLVMTypeRef ParamType4,
1566 LLVMTypeRef ParamType5,
1569 LLVMTypeRef param_types [5];
1571 param_types [0] = ParamType1;
1572 param_types [1] = ParamType2;
1573 param_types [2] = ParamType3;
1574 param_types [3] = ParamType4;
1575 param_types [4] = ParamType5;
1577 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1583 * Create an LLVM builder and remember it so it can be freed later.
1585 static LLVMBuilderRef
1586 create_builder (EmitContext *ctx)
1588 LLVMBuilderRef builder = LLVMCreateBuilder ();
1590 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1596 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1601 case MONO_PATCH_INFO_INTERNAL_METHOD:
1602 name = g_strdup_printf ("jit_icall_%s", data);
1604 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1605 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1606 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1610 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1618 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1622 LLVMValueRef indexes [2];
1623 LLVMValueRef got_entry_addr, load;
1624 LLVMBuilderRef builder = ctx->builder;
1629 MonoJumpInfo tmp_ji;
1631 tmp_ji.data.target = data;
1633 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1635 ji->next = cfg->patch_info;
1636 cfg->patch_info = ji;
1638 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1639 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1641 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1642 * explicitly initialize it.
1644 if (!mono_aot_is_shared_got_offset (got_offset)) {
1645 //mono_print_ji (ji);
1647 ctx->has_got_access = TRUE;
1650 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1651 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1652 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1654 name = get_aotconst_name (type, data, got_offset);
1656 load = LLVMBuildLoad (builder, got_entry_addr, "");
1657 load = convert (ctx, load, llvm_type);
1658 LLVMSetValueName (load, name ? name : "");
1660 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1663 //set_invariant_load_flag (load);
1669 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1671 return get_aotconst_typed (ctx, type, data, NULL);
1675 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1677 LLVMValueRef callee;
1679 if (ctx->llvm_only) {
1680 callee_name = mono_aot_get_direct_call_symbol (type, data);
1682 /* Directly callable */
1684 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1686 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1688 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1690 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1692 /* LLVMTypeRef's are uniqued */
1693 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1694 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1696 g_free (callee_name);
1702 * Calls are made through the GOT.
1704 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1706 MonoJumpInfo *ji = NULL;
1708 callee_name = mono_aot_get_plt_symbol (type, data);
1712 if (ctx->cfg->compile_aot)
1713 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1714 mono_add_patch_info (ctx->cfg, 0, type, data);
1717 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1719 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1721 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1723 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1726 if (ctx->cfg->compile_aot) {
1727 ji = g_new0 (MonoJumpInfo, 1);
1729 ji->data.target = data;
1731 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1739 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1741 #if LLVM_API_VERSION > 100
1742 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1743 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1744 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1745 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1748 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1749 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1755 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1757 MonoMethodHeader *header = cfg->header;
1758 MonoExceptionClause *clause;
1762 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1763 return (bb->region >> 8) - 1;
1766 for (i = 0; i < header->num_clauses; ++i) {
1767 clause = &header->clauses [i];
1769 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1776 static MonoExceptionClause *
1777 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1779 if (bb == cfg->bb_init)
1781 // Since they're sorted by nesting we just need
1782 // the first one that the bb is a member of
1783 for (int i = 0; i < cfg->header->num_clauses; i++) {
1784 MonoExceptionClause *curr = &cfg->header->clauses [i];
1786 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1794 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1796 LLVMValueRef md_arg;
1799 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1800 md_arg = LLVMMDString ("mono", 4);
1801 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1805 set_invariant_load_flag (LLVMValueRef v)
1807 LLVMValueRef md_arg;
1809 const char *flag_name;
1811 // FIXME: Cache this
1812 flag_name = "invariant.load";
1813 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1814 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1815 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1821 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1825 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1827 MonoCompile *cfg = ctx->cfg;
1828 LLVMValueRef lcall = NULL;
1829 LLVMBuilderRef builder = *builder_ref;
1830 MonoExceptionClause *clause;
1832 if (ctx->llvm_only) {
1833 clause = get_most_deep_clause (cfg, ctx, bb);
1836 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1839 * Have to use an invoke instead of a call, branching to the
1840 * handler bblock of the clause containing this bblock.
1842 intptr_t key = CLAUSE_END(clause);
1844 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1846 // FIXME: Find the one that has the lowest end bound for the right start address
1847 // FIXME: Finally + nesting
1850 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1853 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1855 builder = ctx->builder = create_builder (ctx);
1856 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1858 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1862 int clause_index = get_handler_clause (cfg, bb);
1864 if (clause_index != -1) {
1865 MonoMethodHeader *header = cfg->header;
1866 MonoExceptionClause *ec = &header->clauses [clause_index];
1867 MonoBasicBlock *tblock;
1868 LLVMBasicBlockRef ex_bb, noex_bb;
1871 * Have to use an invoke instead of a call, branching to the
1872 * handler bblock of the clause containing this bblock.
1875 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1877 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1880 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1882 ex_bb = get_bb (ctx, tblock);
1884 noex_bb = gen_bb (ctx, "NOEX_BB");
1887 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1889 builder = ctx->builder = create_builder (ctx);
1890 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1892 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1897 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1898 ctx->builder = builder;
1902 *builder_ref = ctx->builder;
1908 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1910 const char *intrins_name;
1911 LLVMValueRef args [16], res;
1912 LLVMTypeRef addr_type;
1913 gboolean use_intrinsics = TRUE;
1915 #if LLVM_API_VERSION > 100
1916 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1917 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1920 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1921 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1922 *builder_ref = ctx->builder;
1923 use_intrinsics = FALSE;
1927 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1928 LLVMAtomicOrdering ordering;
1931 case LLVM_BARRIER_NONE:
1932 ordering = LLVMAtomicOrderingNotAtomic;
1934 case LLVM_BARRIER_ACQ:
1935 ordering = LLVMAtomicOrderingAcquire;
1937 case LLVM_BARRIER_SEQ:
1938 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1941 g_assert_not_reached ();
1946 * We handle loads which can fault by calling a mono specific intrinsic
1947 * using an invoke, so they are handled properly inside try blocks.
1948 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1949 * are marked with IntrReadArgMem.
1953 intrins_name = "llvm.mono.load.i8.p0i8";
1956 intrins_name = "llvm.mono.load.i16.p0i16";
1959 intrins_name = "llvm.mono.load.i32.p0i32";
1962 intrins_name = "llvm.mono.load.i64.p0i64";
1965 g_assert_not_reached ();
1968 addr_type = LLVMTypeOf (addr);
1969 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1970 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1973 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1974 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1975 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1976 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1978 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1979 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1980 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1981 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1988 * We emit volatile loads for loads which can fault, because otherwise
1989 * LLVM will generate invalid code when encountering a load from a
1992 if (barrier != LLVM_BARRIER_NONE)
1993 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1995 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1997 /* Mark it with a custom metadata */
2000 set_metadata_flag (res, "mono.faulting.load");
2008 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
2010 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
2014 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
2016 const char *intrins_name;
2017 LLVMValueRef args [16];
2018 gboolean use_intrinsics = TRUE;
2020 #if LLVM_API_VERSION > 100
2021 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
2022 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2023 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
2024 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
2025 *builder_ref = ctx->builder;
2026 use_intrinsics = FALSE;
2030 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2031 LLVMAtomicOrdering ordering;
2034 case LLVM_BARRIER_NONE:
2035 ordering = LLVMAtomicOrderingNotAtomic;
2037 case LLVM_BARRIER_REL:
2038 ordering = LLVMAtomicOrderingRelease;
2040 case LLVM_BARRIER_SEQ:
2041 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2044 g_assert_not_reached ();
2050 intrins_name = "llvm.mono.store.i8.p0i8";
2053 intrins_name = "llvm.mono.store.i16.p0i16";
2056 intrins_name = "llvm.mono.store.i32.p0i32";
2059 intrins_name = "llvm.mono.store.i64.p0i64";
2062 g_assert_not_reached ();
2065 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2066 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2067 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2072 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2073 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2074 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2075 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2077 if (barrier != LLVM_BARRIER_NONE)
2078 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2080 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2085 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2087 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2091 * emit_cond_system_exception:
2093 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2094 * Might set the ctx exception.
2097 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2099 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2100 LLVMBuilderRef builder;
2101 MonoClass *exc_class;
2102 LLVMValueRef args [2];
2103 LLVMValueRef callee;
2104 gboolean no_pc = FALSE;
2106 if (IS_TARGET_AMD64)
2107 /* Some platforms don't require the pc argument */
2110 ex_bb = gen_bb (ctx, "EX_BB");
2112 ex2_bb = gen_bb (ctx, "EX2_BB");
2113 noex_bb = gen_bb (ctx, "NOEX_BB");
2115 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2117 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2119 /* Emit exception throwing code */
2120 ctx->builder = builder = create_builder (ctx);
2121 LLVMPositionBuilderAtEnd (builder, ex_bb);
2123 if (ctx->cfg->llvm_only) {
2124 static LLVMTypeRef sig;
2127 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2128 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2130 LLVMBuildBr (builder, ex2_bb);
2132 ctx->builder = builder = create_builder (ctx);
2133 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2135 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2136 emit_call (ctx, bb, &builder, callee, args, 1);
2137 LLVMBuildUnreachable (builder);
2139 ctx->builder = builder = create_builder (ctx);
2140 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2142 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2148 callee = ctx->module->throw_corlib_exception;
2151 const char *icall_name;
2154 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2156 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2157 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2159 if (ctx->cfg->compile_aot) {
2160 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2163 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2164 * - On x86, LLVM generated code doesn't push the arguments
2165 * - The trampoline takes the throw address as an arguments, not a pc offset.
2167 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2168 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2170 #if LLVM_API_VERSION > 100
2172 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2173 * added by emit_jit_callee ().
2175 ex2_bb = gen_bb (ctx, "EX2_BB");
2176 LLVMBuildBr (builder, ex2_bb);
2179 ctx->builder = builder = create_builder (ctx);
2180 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2182 mono_memory_barrier ();
2183 ctx->module->throw_corlib_exception = callee;
2188 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2191 * The LLVM mono branch contains changes so a block address can be passed as an
2192 * argument to a call.
2195 emit_call (ctx, bb, &builder, callee, args, 1);
2197 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2198 emit_call (ctx, bb, &builder, callee, args, 2);
2201 LLVMBuildUnreachable (builder);
2203 ctx->builder = builder = create_builder (ctx);
2204 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2206 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2213 * emit_args_to_vtype:
2215 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2218 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2220 int j, size, nslots;
2222 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2224 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2225 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2228 if (ainfo->storage == LLVMArgAsFpArgs)
2229 nslots = ainfo->nslots;
2233 for (j = 0; j < nslots; ++j) {
2234 LLVMValueRef index [2], addr, daddr;
2235 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2236 LLVMTypeRef part_type;
2238 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2241 if (ainfo->pair_storage [j] == LLVMArgNone)
2244 switch (ainfo->pair_storage [j]) {
2245 case LLVMArgInIReg: {
2246 part_type = LLVMIntType (part_size * 8);
2247 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2248 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2249 addr = LLVMBuildGEP (builder, address, index, 1, "");
2251 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2252 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2253 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2255 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2258 case LLVMArgInFPReg: {
2259 LLVMTypeRef arg_type;
2261 if (ainfo->esize == 8)
2262 arg_type = LLVMDoubleType ();
2264 arg_type = LLVMFloatType ();
2266 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2267 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2268 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2269 LLVMBuildStore (builder, args [j], addr);
2275 g_assert_not_reached ();
2278 size -= sizeof (gpointer);
2283 * emit_vtype_to_args:
2285 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2286 * into ARGS, and the number of arguments into NARGS.
2289 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2292 int j, size, nslots;
2293 LLVMTypeRef arg_type;
2295 size = get_vtype_size (t);
2297 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2298 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2300 if (ainfo->storage == LLVMArgAsFpArgs)
2301 nslots = ainfo->nslots;
2304 for (j = 0; j < nslots; ++j) {
2305 LLVMValueRef index [2], addr, daddr;
2306 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2308 if (ainfo->pair_storage [j] == LLVMArgNone)
2311 switch (ainfo->pair_storage [j]) {
2313 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2314 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2315 addr = LLVMBuildGEP (builder, address, index, 1, "");
2317 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2318 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2319 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2321 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2323 case LLVMArgInFPReg:
2324 if (ainfo->esize == 8)
2325 arg_type = LLVMDoubleType ();
2327 arg_type = LLVMFloatType ();
2328 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2329 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2330 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2331 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2336 g_assert_not_reached ();
2338 size -= sizeof (gpointer);
2345 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2348 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2349 * get executed every time control reaches them.
2351 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2353 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2354 return ctx->last_alloca;
2358 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2360 return build_alloca_llvm_type_name (ctx, t, align, "");
2364 build_alloca (EmitContext *ctx, MonoType *t)
2366 MonoClass *k = mono_class_from_mono_type (t);
2369 g_assert (!mini_is_gsharedvt_variable_type (t));
2371 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2374 align = mono_class_min_align (k);
2376 /* Sometimes align is not a power of 2 */
2377 while (mono_is_power_of_two (align) == -1)
2380 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2384 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2388 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2390 MonoCompile *cfg = ctx->cfg;
2391 LLVMBuilderRef builder = ctx->builder;
2392 LLVMValueRef offset, offset_var;
2393 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2394 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2398 g_assert (info_var);
2399 g_assert (locals_var);
2401 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2403 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2404 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2406 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2407 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2409 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2413 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2416 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2419 module->used = g_ptr_array_sized_new (16);
2420 g_ptr_array_add (module->used, global);
2424 emit_llvm_used (MonoLLVMModule *module)
2426 LLVMModuleRef lmodule = module->lmodule;
2427 LLVMTypeRef used_type;
2428 LLVMValueRef used, *used_elem;
2434 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2435 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2436 used_elem = g_new0 (LLVMValueRef, module->used->len);
2437 for (i = 0; i < module->used->len; ++i)
2438 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2439 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2440 LLVMSetLinkage (used, LLVMAppendingLinkage);
2441 LLVMSetSection (used, "llvm.metadata");
2447 * Emit a function mapping method indexes to their code
2450 emit_get_method (MonoLLVMModule *module)
2452 LLVMModuleRef lmodule = module->lmodule;
2453 LLVMValueRef func, switch_ins, m;
2454 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2455 LLVMBasicBlockRef *bbs;
2457 LLVMBuilderRef builder = LLVMCreateBuilder ();
2462 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2463 * but generating code seems safer.
2465 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2466 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2467 LLVMSetLinkage (func, LLVMExternalLinkage);
2468 LLVMSetVisibility (func, LLVMHiddenVisibility);
2469 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2470 module->get_method = func;
2472 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2475 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2476 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2477 * then we will have to find another solution.
2480 name = g_strdup_printf ("BB_CODE_START");
2481 code_start_bb = LLVMAppendBasicBlock (func, name);
2483 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2484 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2486 name = g_strdup_printf ("BB_CODE_END");
2487 code_end_bb = LLVMAppendBasicBlock (func, name);
2489 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2490 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2492 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2493 for (i = 0; i < module->max_method_idx + 1; ++i) {
2494 name = g_strdup_printf ("BB_%d", i);
2495 bb = LLVMAppendBasicBlock (func, name);
2499 LLVMPositionBuilderAtEnd (builder, bb);
2501 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2503 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2505 LLVMBuildRet (builder, LLVMConstNull (rtype));
2508 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2509 LLVMPositionBuilderAtEnd (builder, fail_bb);
2510 LLVMBuildRet (builder, LLVMConstNull (rtype));
2512 LLVMPositionBuilderAtEnd (builder, entry_bb);
2514 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2515 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2516 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2517 for (i = 0; i < module->max_method_idx + 1; ++i) {
2518 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2521 mark_as_used (module, func);
2523 LLVMDisposeBuilder (builder);
2527 * emit_get_unbox_tramp:
2529 * Emit a function mapping method indexes to their unbox trampoline
2532 emit_get_unbox_tramp (MonoLLVMModule *module)
2534 LLVMModuleRef lmodule = module->lmodule;
2535 LLVMValueRef func, switch_ins, m;
2536 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2537 LLVMBasicBlockRef *bbs;
2539 LLVMBuilderRef builder = LLVMCreateBuilder ();
2543 /* Similar to emit_get_method () */
2545 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2546 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2547 LLVMSetLinkage (func, LLVMExternalLinkage);
2548 LLVMSetVisibility (func, LLVMHiddenVisibility);
2549 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2550 module->get_unbox_tramp = func;
2552 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2554 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2555 for (i = 0; i < module->max_method_idx + 1; ++i) {
2556 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2560 name = g_strdup_printf ("BB_%d", i);
2561 bb = LLVMAppendBasicBlock (func, name);
2565 LLVMPositionBuilderAtEnd (builder, bb);
2567 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2570 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2571 LLVMPositionBuilderAtEnd (builder, fail_bb);
2572 LLVMBuildRet (builder, LLVMConstNull (rtype));
2574 LLVMPositionBuilderAtEnd (builder, entry_bb);
2576 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2577 for (i = 0; i < module->max_method_idx + 1; ++i) {
2578 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2582 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2585 mark_as_used (module, func);
2586 LLVMDisposeBuilder (builder);
2589 /* Add a function to mark the beginning of LLVM code */
2591 emit_llvm_code_start (MonoLLVMModule *module)
2593 LLVMModuleRef lmodule = module->lmodule;
2595 LLVMBasicBlockRef entry_bb;
2596 LLVMBuilderRef builder;
2598 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2599 LLVMSetLinkage (func, LLVMInternalLinkage);
2600 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2601 module->code_start = func;
2602 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2603 builder = LLVMCreateBuilder ();
2604 LLVMPositionBuilderAtEnd (builder, entry_bb);
2605 LLVMBuildRetVoid (builder);
2606 LLVMDisposeBuilder (builder);
2610 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2612 LLVMModuleRef lmodule = module->lmodule;
2613 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2614 LLVMBasicBlockRef entry_bb;
2615 LLVMBuilderRef builder;
2622 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2623 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2628 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2629 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2632 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2633 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2636 g_assert_not_reached ();
2638 LLVMSetLinkage (func, LLVMInternalLinkage);
2639 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2640 mono_llvm_set_preserveall_cc (func);
2641 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2642 builder = LLVMCreateBuilder ();
2643 LLVMPositionBuilderAtEnd (builder, entry_bb);
2646 ji = g_new0 (MonoJumpInfo, 1);
2647 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2648 ji = mono_aot_patch_info_dup (ji);
2649 got_offset = mono_aot_get_got_offset (ji);
2650 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2651 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2652 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2653 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2654 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2655 args [1] = LLVMGetParam (func, 0);
2657 args [2] = LLVMGetParam (func, 1);
2659 ji = g_new0 (MonoJumpInfo, 1);
2660 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2661 ji->data.name = icall_name;
2662 ji = mono_aot_patch_info_dup (ji);
2663 got_offset = mono_aot_get_got_offset (ji);
2664 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2665 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2666 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2667 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2668 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2669 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2670 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2672 // Set the inited flag
2673 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2674 indexes [1] = LLVMGetParam (func, 0);
2675 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2677 LLVMBuildRetVoid (builder);
2679 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2680 LLVMDisposeBuilder (builder);
2685 * Emit wrappers around the C icalls used to initialize llvm methods, to
2686 * make the calling code smaller and to enable usage of the llvm
2687 * PreserveAll calling convention.
2690 emit_init_icall_wrappers (MonoLLVMModule *module)
2692 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2693 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2694 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2695 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2699 emit_llvm_code_end (MonoLLVMModule *module)
2701 LLVMModuleRef lmodule = module->lmodule;
2703 LLVMBasicBlockRef entry_bb;
2704 LLVMBuilderRef builder;
2706 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2707 LLVMSetLinkage (func, LLVMInternalLinkage);
2708 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2709 module->code_end = func;
2710 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2711 builder = LLVMCreateBuilder ();
2712 LLVMPositionBuilderAtEnd (builder, entry_bb);
2713 LLVMBuildRetVoid (builder);
2714 LLVMDisposeBuilder (builder);
2718 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2720 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2723 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2724 need_div_check = TRUE;
2726 if (!need_div_check)
2729 switch (ins->opcode) {
2742 case OP_IDIV_UN_IMM:
2743 case OP_LDIV_UN_IMM:
2744 case OP_IREM_UN_IMM:
2745 case OP_LREM_UN_IMM: {
2747 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2748 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2750 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2751 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2754 builder = ctx->builder;
2756 /* b == -1 && a == 0x80000000 */
2758 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2759 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2760 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2762 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2763 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2766 builder = ctx->builder;
2778 * Emit code to initialize the GOT slots used by the method.
2781 emit_init_method (EmitContext *ctx)
2783 LLVMValueRef indexes [16], args [16], callee;
2784 LLVMValueRef inited_var, cmp, call;
2785 LLVMBasicBlockRef inited_bb, notinited_bb;
2786 LLVMBuilderRef builder = ctx->builder;
2787 MonoCompile *cfg = ctx->cfg;
2789 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2791 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2792 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2793 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2795 args [0] = inited_var;
2796 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2797 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2799 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2801 inited_bb = ctx->inited_bb;
2802 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2804 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2806 builder = ctx->builder = create_builder (ctx);
2807 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2810 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2811 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2812 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2813 callee = ctx->module->init_method_gshared_mrgctx;
2814 call = LLVMBuildCall (builder, callee, args, 2, "");
2815 } else if (ctx->rgctx_arg) {
2816 /* A vtable is passed as the rgctx argument */
2817 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2818 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2819 callee = ctx->module->init_method_gshared_vtable;
2820 call = LLVMBuildCall (builder, callee, args, 2, "");
2821 } else if (cfg->gshared) {
2822 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2823 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2824 callee = ctx->module->init_method_gshared_this;
2825 call = LLVMBuildCall (builder, callee, args, 2, "");
2827 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2828 callee = ctx->module->init_method;
2829 call = LLVMBuildCall (builder, callee, args, 1, "");
2833 * This enables llvm to keep arguments in their original registers/
2834 * scratch registers, since the call will not clobber them.
2836 mono_llvm_set_call_preserveall_cc (call);
2838 LLVMBuildBr (builder, inited_bb);
2839 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2841 builder = ctx->builder = create_builder (ctx);
2842 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2846 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2849 * Emit unbox trampoline using a tail call
2851 LLVMValueRef tramp, call, *args;
2852 LLVMBuilderRef builder;
2853 LLVMBasicBlockRef lbb;
2854 LLVMCallInfo *linfo;
2858 tramp_name = g_strdup_printf ("ut_%s", method_name);
2859 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2860 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2861 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2862 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2864 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2865 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2866 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2867 if (ctx->cfg->vret_addr) {
2868 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2869 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2870 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2871 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2875 lbb = LLVMAppendBasicBlock (tramp, "");
2876 builder = LLVMCreateBuilder ();
2877 LLVMPositionBuilderAtEnd (builder, lbb);
2879 nargs = LLVMCountParamTypes (method_type);
2880 args = g_new0 (LLVMValueRef, nargs);
2881 for (i = 0; i < nargs; ++i) {
2882 args [i] = LLVMGetParam (tramp, i);
2883 if (i == ctx->this_arg_pindex) {
2884 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2886 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2887 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2888 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2891 call = LLVMBuildCall (builder, method, args, nargs, "");
2892 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2893 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2894 if (linfo->ret.storage == LLVMArgVtypeByRef)
2895 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2897 // FIXME: This causes assertions in clang
2898 //mono_llvm_set_must_tail (call);
2899 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2900 LLVMBuildRetVoid (builder);
2902 LLVMBuildRet (builder, call);
2904 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2905 LLVMDisposeBuilder (builder);
2911 * Emit code to load/convert arguments.
2914 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2917 MonoCompile *cfg = ctx->cfg;
2918 MonoMethodSignature *sig = ctx->sig;
2919 LLVMCallInfo *linfo = ctx->linfo;
2923 LLVMBuilderRef old_builder = ctx->builder;
2924 ctx->builder = builder;
2926 ctx->alloca_builder = create_builder (ctx);
2929 * Handle indirect/volatile variables by allocating memory for them
2930 * using 'alloca', and storing their address in a temporary.
2932 for (i = 0; i < cfg->num_varinfo; ++i) {
2933 MonoInst *var = cfg->varinfo [i];
2936 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2937 } 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))) {
2938 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2941 /* Could be already created by an OP_VPHI */
2942 if (!ctx->addresses [var->dreg]) {
2943 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2944 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2946 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2950 names = g_new (char *, sig->param_count);
2951 mono_method_get_param_names (cfg->method, (const char **) names);
2953 for (i = 0; i < sig->param_count; ++i) {
2954 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2955 int reg = cfg->args [i + sig->hasthis]->dreg;
2958 pindex = ainfo->pindex;
2960 switch (ainfo->storage) {
2961 case LLVMArgVtypeInReg:
2962 case LLVMArgAsFpArgs: {
2963 LLVMValueRef args [8];
2966 pindex += ainfo->ndummy_fpargs;
2968 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2969 memset (args, 0, sizeof (args));
2970 if (ainfo->storage == LLVMArgVtypeInReg) {
2971 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2972 if (ainfo->pair_storage [1] != LLVMArgNone)
2973 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2975 g_assert (ainfo->nslots <= 8);
2976 for (j = 0; j < ainfo->nslots; ++j)
2977 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2979 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2981 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2983 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2984 /* Treat these as normal values */
2985 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2989 case LLVMArgVtypeByVal: {
2990 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2992 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2993 /* Treat these as normal values */
2994 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2998 case LLVMArgVtypeByRef: {
2999 /* The argument is passed by ref */
3000 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3003 case LLVMArgAsIArgs: {
3004 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3007 /* The argument is received as an array of ints, store it into the real argument */
3008 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
3010 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
3011 if (size < SIZEOF_VOID_P) {
3012 /* The upper bits of the registers might not be valid */
3013 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
3014 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
3015 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
3017 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
3021 case LLVMArgVtypeAsScalar:
3022 g_assert_not_reached ();
3024 case LLVMArgGsharedvtFixed: {
3025 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3026 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3029 name = g_strdup_printf ("arg_%s", names [i]);
3031 name = g_strdup_printf ("arg_%d", i);
3033 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3036 case LLVMArgGsharedvtFixedVtype: {
3037 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3040 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3042 name = g_strdup_printf ("vtype_arg_%d", i);
3044 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3045 g_assert (ctx->addresses [reg]);
3046 LLVMSetValueName (ctx->addresses [reg], name);
3047 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3050 case LLVMArgGsharedvtVariable:
3051 /* The IR treats these as variables with addresses */
3052 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3055 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));
3062 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3064 emit_volatile_store (ctx, cfg->args [0]->dreg);
3065 for (i = 0; i < sig->param_count; ++i)
3066 if (!mini_type_is_vtype (sig->params [i]))
3067 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3069 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3070 LLVMValueRef this_alloc;
3073 * The exception handling code needs the location where the this argument was
3074 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3075 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3076 * location into the LSDA.
3078 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3079 /* This volatile store will keep the alloca alive */
3080 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3082 set_metadata_flag (this_alloc, "mono.this");
3085 if (cfg->rgctx_var) {
3086 LLVMValueRef rgctx_alloc, store;
3089 * We handle the rgctx arg similarly to the this pointer.
3091 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3092 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3093 /* This volatile store will keep the alloca alive */
3094 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3096 set_metadata_flag (rgctx_alloc, "mono.this");
3099 /* Initialize the method if needed */
3100 if (cfg->compile_aot && ctx->llvm_only) {
3101 /* Emit a location for the initialization code */
3102 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3103 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3105 LLVMBuildBr (ctx->builder, ctx->init_bb);
3106 builder = ctx->builder = create_builder (ctx);
3107 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3108 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3111 /* Compute nesting between clauses */
3112 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3113 for (i = 0; i < cfg->header->num_clauses; ++i) {
3114 for (j = 0; j < cfg->header->num_clauses; ++j) {
3115 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3116 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3118 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3119 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3124 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3125 * it needs to continue normally, or return back to the exception handling system.
3127 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3131 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3134 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3135 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3136 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3138 if (bb->in_scount == 0) {
3141 sprintf (name, "finally_ind_bb%d", bb->block_num);
3142 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3143 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3145 ctx->bblocks [bb->block_num].finally_ind = val;
3147 /* Create a variable to hold the exception var */
3149 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3153 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3154 * LLVM bblock containing a landing pad causes problems for the
3155 * LLVM optimizer passes.
3157 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3158 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3160 ctx->builder = old_builder;
3164 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3166 MonoCompile *cfg = ctx->cfg;
3167 LLVMValueRef *values = ctx->values;
3168 LLVMValueRef *addresses = ctx->addresses;
3169 MonoCallInst *call = (MonoCallInst*)ins;
3170 MonoMethodSignature *sig = call->signature;
3171 LLVMValueRef callee = NULL, lcall;
3173 LLVMCallInfo *cinfo;
3177 LLVMTypeRef llvm_sig;
3179 gboolean is_virtual, calli, preserveall;
3180 LLVMBuilderRef builder = *builder_ref;
3182 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3183 set_failure (ctx, "non-default callconv");
3187 cinfo = call->cinfo;
3189 if (call->rgctx_arg_reg)
3190 cinfo->rgctx_arg = TRUE;
3191 if (call->imt_arg_reg)
3192 cinfo->imt_arg = TRUE;
3194 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3196 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3200 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);
3201 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);
3203 preserveall = FALSE;
3205 /* FIXME: Avoid creating duplicate methods */
3207 if (ins->flags & MONO_INST_HAS_METHOD) {
3211 if (cfg->compile_aot) {
3212 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3214 set_failure (ctx, "can't encode patch");
3217 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3219 * Collect instructions representing the callee into a hash so they can be replaced
3220 * by the llvm method for the callee if the callee turns out to be direct
3221 * callable. Currently this only requires it to not fail llvm compilation.
3223 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3224 l = g_slist_prepend (l, callee);
3225 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3229 static int tramp_index;
3232 name = g_strdup_printf ("tramp_%d", tramp_index);
3235 #if LLVM_API_VERSION > 100
3237 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3238 * Make all calls through a global. The address of the global will be saved in
3239 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3242 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3245 mono_create_jit_trampoline (mono_domain_get (),
3246 call->method, &error);
3247 if (!is_ok (&error)) {
3248 set_failure (ctx, mono_error_get_message (&error));
3249 mono_error_cleanup (&error);
3253 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3254 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3255 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3256 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3258 callee = LLVMBuildLoad (builder, tramp_var, "");
3261 mono_create_jit_trampoline (mono_domain_get (),
3262 call->method, &error);
3263 if (!is_ok (&error)) {
3265 set_failure (ctx, mono_error_get_message (&error));
3266 mono_error_cleanup (&error);
3270 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3273 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3278 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3279 /* LLVM miscompiles async methods */
3280 set_failure (ctx, "#13734");
3285 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3291 memset (&ji, 0, sizeof (ji));
3292 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3293 ji.data.target = info->name;
3295 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3297 if (cfg->compile_aot) {
3298 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3300 set_failure (ctx, "can't encode patch");
3304 target = (gpointer)mono_icall_get_wrapper (info);
3305 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3308 if (cfg->compile_aot) {
3310 if (cfg->abs_patches) {
3311 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3313 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3315 set_failure (ctx, "can't encode patch");
3321 set_failure (ctx, "aot");
3325 #if LLVM_API_VERSION > 100
3326 if (cfg->abs_patches) {
3327 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3331 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3332 mono_error_assert_ok (&error);
3333 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3335 g_assert_not_reached ();
3338 g_assert_not_reached ();
3341 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3343 if (cfg->abs_patches) {
3344 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3349 * FIXME: Some trampolines might have
3350 * their own calling convention on some platforms.
3352 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3353 mono_error_assert_ok (&error);
3354 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3358 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3365 int size = sizeof (gpointer);
3368 g_assert (ins->inst_offset % size == 0);
3369 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3371 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3373 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3375 if (ins->flags & MONO_INST_HAS_METHOD) {
3380 * Collect and convert arguments
3382 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3383 len = sizeof (LLVMValueRef) * nargs;
3384 args = (LLVMValueRef*)alloca (len);
3385 memset (args, 0, len);
3386 l = call->out_ireg_args;
3388 if (call->rgctx_arg_reg) {
3389 g_assert (values [call->rgctx_arg_reg]);
3390 g_assert (cinfo->rgctx_arg_pindex < nargs);
3392 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3393 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3394 * it using a volatile load.
3397 if (!ctx->imt_rgctx_loc)
3398 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3399 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3400 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3402 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3405 if (call->imt_arg_reg) {
3406 g_assert (!ctx->llvm_only);
3407 g_assert (values [call->imt_arg_reg]);
3408 g_assert (cinfo->imt_arg_pindex < nargs);
3410 if (!ctx->imt_rgctx_loc)
3411 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3412 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3413 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3415 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3418 switch (cinfo->ret.storage) {
3419 case LLVMArgGsharedvtVariable: {
3420 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3422 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3423 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3425 g_assert (addresses [call->inst.dreg]);
3426 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3432 if (!addresses [call->inst.dreg])
3433 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3434 g_assert (cinfo->vret_arg_pindex < nargs);
3435 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3436 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3438 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3444 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3445 * use the real callee for argument type conversion.
3447 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3448 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3449 LLVMGetParamTypes (callee_type, param_types);
3451 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3454 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3456 pindex = ainfo->pindex;
3458 regpair = (guint32)(gssize)(l->data);
3459 reg = regpair & 0xffffff;
3460 args [pindex] = values [reg];
3461 switch (ainfo->storage) {
3462 case LLVMArgVtypeInReg:
3463 case LLVMArgAsFpArgs: {
3467 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3468 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3469 pindex += ainfo->ndummy_fpargs;
3471 g_assert (addresses [reg]);
3472 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3476 // FIXME: Get rid of the VMOVE
3479 case LLVMArgVtypeByVal:
3480 g_assert (addresses [reg]);
3481 args [pindex] = addresses [reg];
3483 case LLVMArgVtypeByRef: {
3484 g_assert (addresses [reg]);
3485 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3488 case LLVMArgAsIArgs:
3489 g_assert (addresses [reg]);
3490 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3492 case LLVMArgVtypeAsScalar:
3493 g_assert_not_reached ();
3495 case LLVMArgGsharedvtFixed:
3496 case LLVMArgGsharedvtFixedVtype:
3497 g_assert (addresses [reg]);
3498 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3500 case LLVMArgGsharedvtVariable:
3501 g_assert (addresses [reg]);
3502 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3505 g_assert (args [pindex]);
3506 if (i == 0 && sig->hasthis)
3507 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3509 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3512 g_assert (pindex <= nargs);
3517 // FIXME: Align call sites
3523 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3525 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3526 mono_llvm_set_call_notail (lcall);
3529 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3531 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3532 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3534 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3535 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3536 if (!sig->pinvoke && !cfg->llvm_only)
3537 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3539 mono_llvm_set_call_preserveall_cc (lcall);
3541 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3542 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3543 if (!ctx->llvm_only && call->rgctx_arg_reg)
3544 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3545 if (call->imt_arg_reg)
3546 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3548 /* Add byval attributes if needed */
3549 for (i = 0; i < sig->param_count; ++i) {
3550 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3552 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3553 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3557 * Convert the result
3559 switch (cinfo->ret.storage) {
3560 case LLVMArgVtypeInReg: {
3561 LLVMValueRef regs [2];
3563 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3567 if (!addresses [ins->dreg])
3568 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3570 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3571 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3572 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3573 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3576 case LLVMArgVtypeByVal:
3577 if (!addresses [call->inst.dreg])
3578 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3579 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3581 case LLVMArgAsIArgs:
3582 case LLVMArgFpStruct:
3583 if (!addresses [call->inst.dreg])
3584 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3585 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3587 case LLVMArgVtypeAsScalar:
3588 if (!addresses [call->inst.dreg])
3589 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3590 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3592 case LLVMArgVtypeRetAddr:
3593 case LLVMArgVtypeByRef:
3594 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3595 /* Some opcodes like STOREX_MEMBASE access these by value */
3596 g_assert (addresses [call->inst.dreg]);
3597 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3600 case LLVMArgGsharedvtVariable:
3602 case LLVMArgGsharedvtFixed:
3603 case LLVMArgGsharedvtFixedVtype:
3604 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3607 if (sig->ret->type != MONO_TYPE_VOID)
3608 /* If the method returns an unsigned value, need to zext it */
3609 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));
3613 *builder_ref = ctx->builder;
3617 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3619 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3620 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3622 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3625 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3627 if (ctx->cfg->compile_aot) {
3628 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3630 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3631 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3632 mono_memory_barrier ();
3635 ctx->module->rethrow = callee;
3637 ctx->module->throw_icall = callee;
3641 LLVMValueRef args [2];
3643 args [0] = convert (ctx, exc, exc_type);
3644 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3646 LLVMBuildUnreachable (ctx->builder);
3648 ctx->builder = create_builder (ctx);
3652 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3654 MonoMethodSignature *throw_sig;
3655 LLVMValueRef callee, arg;
3656 const char *icall_name;
3658 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3659 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3662 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3663 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3664 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3665 if (ctx->cfg->compile_aot) {
3666 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3671 * LLVM doesn't push the exception argument, so we need a different
3674 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3676 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3678 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3681 mono_memory_barrier ();
3682 #if LLVM_API_VERSION < 100
3684 ctx->module->rethrow = callee;
3686 ctx->module->throw_icall = callee;
3689 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3690 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3694 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3696 const char *icall_name = "mono_llvm_resume_exception";
3697 LLVMValueRef callee = ctx->module->resume_eh;
3699 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3702 if (ctx->cfg->compile_aot) {
3703 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3705 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3706 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3707 mono_memory_barrier ();
3709 ctx->module->resume_eh = callee;
3713 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3715 LLVMBuildUnreachable (ctx->builder);
3717 ctx->builder = create_builder (ctx);
3721 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3723 const char *icall_name = "mono_llvm_clear_exception";
3725 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3726 LLVMValueRef callee = NULL;
3729 if (ctx->cfg->compile_aot) {
3730 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3732 // FIXME: This is broken.
3733 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3737 g_assert (builder && callee);
3739 return LLVMBuildCall (builder, callee, NULL, 0, "");
3743 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3745 const char *icall_name = "mono_llvm_load_exception";
3747 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3748 LLVMValueRef callee = NULL;
3751 if (ctx->cfg->compile_aot) {
3752 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3754 // FIXME: This is broken.
3755 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3759 g_assert (builder && callee);
3761 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3766 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3768 const char *icall_name = "mono_llvm_match_exception";
3770 ctx->builder = builder;
3772 const int num_args = 5;
3773 LLVMValueRef args [num_args];
3774 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3775 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3776 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3777 if (ctx->cfg->rgctx_var) {
3778 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3779 g_assert (rgctx_alloc);
3780 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3782 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3785 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3787 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3789 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3790 LLVMValueRef callee = ctx->module->match_exc;
3793 if (ctx->cfg->compile_aot) {
3794 ctx->builder = builder;
3795 // get_callee expects ctx->builder to be the emitting builder
3796 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3798 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3799 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3800 ctx->module->match_exc = callee;
3801 mono_memory_barrier ();
3805 g_assert (builder && callee);
3807 g_assert (ctx->ex_var);
3809 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3812 // FIXME: This won't work because the code-finding makes this
3814 /*#define MONO_PERSONALITY_DEBUG*/
3816 #ifdef MONO_PERSONALITY_DEBUG
3817 static const gboolean use_debug_personality = TRUE;
3818 static const char *default_personality_name = "mono_debug_personality";
3820 static const gboolean use_debug_personality = FALSE;
3821 static const char *default_personality_name = "__gxx_personality_v0";
3825 default_cpp_lpad_exc_signature (void)
3827 static gboolean inited = FALSE;
3828 static LLVMTypeRef sig;
3831 LLVMTypeRef signature [2];
3832 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3833 signature [1] = LLVMInt32Type ();
3834 sig = LLVMStructType (signature, 2, FALSE);
3842 get_mono_personality (EmitContext *ctx)
3844 LLVMValueRef personality = NULL;
3845 static gint32 mapping_inited = FALSE;
3846 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3848 if (!use_debug_personality) {
3849 if (ctx->cfg->compile_aot) {
3850 personality = get_intrinsic (ctx, default_personality_name);
3851 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3852 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3853 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3856 if (ctx->cfg->compile_aot) {
3857 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3859 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3860 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3861 mono_memory_barrier ();
3865 g_assert (personality);
3869 static LLVMBasicBlockRef
3870 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3872 MonoCompile *cfg = ctx->cfg;
3873 LLVMBuilderRef old_builder = ctx->builder;
3874 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3876 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3877 ctx->builder = lpadBuilder;
3879 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3880 g_assert (handler_bb);
3882 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3883 LLVMValueRef personality = get_mono_personality (ctx);
3884 g_assert (personality);
3886 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3887 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3889 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3890 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3891 g_assert (landing_pad);
3893 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3894 LLVMAddClause (landing_pad, cast);
3896 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3897 LLVMBuilderRef resume_builder = create_builder (ctx);
3898 ctx->builder = resume_builder;
3899 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3901 emit_resume_eh (ctx, handler_bb);
3904 ctx->builder = lpadBuilder;
3905 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3907 gboolean finally_only = TRUE;
3909 MonoExceptionClause *group_cursor = group_start;
3911 for (int i = 0; i < group_size; i ++) {
3912 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3913 finally_only = FALSE;
3919 // Handle landing pad inlining
3921 if (!finally_only) {
3922 // So at each level of the exception stack we will match the exception again.
3923 // During that match, we need to compare against the handler types for the current
3924 // protected region. We send the try start and end so that we can only check against
3925 // handlers for this lexical protected region.
3926 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3928 // if returns -1, resume
3929 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3931 // else move to that target bb
3932 for (int i = 0; i < group_size; i++) {
3933 MonoExceptionClause *clause = group_start + i;
3934 int clause_index = clause - cfg->header->clauses;
3935 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3936 g_assert (handler_bb);
3937 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3938 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3941 int clause_index = group_start - cfg->header->clauses;
3942 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3943 g_assert (finally_bb);
3945 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3948 ctx->builder = old_builder;
3955 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3957 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3958 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3960 // Make exception available to catch blocks
3961 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3962 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3964 g_assert (ctx->ex_var);
3965 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3967 if (bb->in_scount == 1) {
3968 MonoInst *exvar = bb->in_stack [0];
3969 g_assert (!ctx->values [exvar->dreg]);
3970 g_assert (ctx->ex_var);
3971 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3972 emit_volatile_store (ctx, exvar->dreg);
3975 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3978 LLVMBuilderRef handler_builder = create_builder (ctx);
3979 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3980 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3982 // Make the handler code end with a jump to cbb
3983 LLVMBuildBr (handler_builder, cbb);
3987 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3989 MonoCompile *cfg = ctx->cfg;
3990 LLVMValueRef *values = ctx->values;
3991 LLVMModuleRef lmodule = ctx->lmodule;
3992 BBInfo *bblocks = ctx->bblocks;
3994 LLVMValueRef personality;
3995 LLVMValueRef landing_pad;
3996 LLVMBasicBlockRef target_bb;
3998 static int ti_generator;
4000 LLVMValueRef type_info;
4004 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4006 if (cfg->compile_aot) {
4007 /* Use a dummy personality function */
4008 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4009 g_assert (personality);
4011 #if LLVM_API_VERSION > 100
4012 personality = ctx->module->personality;
4014 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
4015 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
4016 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
4017 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
4018 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
4019 LLVMPositionBuilderAtEnd (builder2, entry_bb);
4020 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
4021 ctx->module->personality = personality;
4022 LLVMDisposeBuilder (builder2);
4025 static gint32 mapping_inited;
4027 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4029 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
4030 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4034 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4036 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4039 * Create the type info
4041 sprintf (ti_name, "type_info_%d", ti_generator);
4044 if (cfg->compile_aot) {
4045 /* decode_eh_frame () in aot-runtime.c will decode this */
4046 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4047 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4050 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4052 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4054 #if LLVM_API_VERSION > 100
4055 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4056 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4061 * After the cfg mempool is freed, the type info will point to stale memory,
4062 * but this is not a problem, since we decode it once in exception_cb during
4065 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4066 *(gint32*)ti = clause_index;
4068 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4070 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4075 LLVMTypeRef members [2], ret_type;
4077 members [0] = i8ptr;
4078 members [1] = LLVMInt32Type ();
4079 ret_type = LLVMStructType (members, 2, FALSE);
4081 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4082 LLVMAddClause (landing_pad, type_info);
4084 /* Store the exception into the exvar */
4086 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4090 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4091 * code expects control to be transferred to this landing pad even in the
4092 * presence of nested clauses. The landing pad needs to branch to the landing
4093 * pads belonging to nested clauses based on the selector value returned by
4094 * the landing pad instruction, which is passed to the landing pad in a
4095 * register by the EH code.
4097 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4098 g_assert (target_bb);
4101 * Branch to the correct landing pad
4103 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4104 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4106 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4107 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4108 MonoBasicBlock *handler_bb;
4110 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4111 g_assert (handler_bb);
4113 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4114 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4117 /* Start a new bblock which CALL_HANDLER can branch to */
4118 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4120 ctx->builder = builder = create_builder (ctx);
4121 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4123 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4125 /* Store the exception into the IL level exvar */
4126 if (bb->in_scount == 1) {
4127 g_assert (bb->in_scount == 1);
4128 exvar = bb->in_stack [0];
4130 // FIXME: This is shared with filter clauses ?
4131 g_assert (!values [exvar->dreg]);
4133 g_assert (ctx->ex_var);
4134 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4135 emit_volatile_store (ctx, exvar->dreg);
4141 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4143 MonoCompile *cfg = ctx->cfg;
4144 MonoMethodSignature *sig = ctx->sig;
4145 LLVMValueRef method = ctx->lmethod;
4146 LLVMValueRef *values = ctx->values;
4147 LLVMValueRef *addresses = ctx->addresses;
4148 LLVMCallInfo *linfo = ctx->linfo;
4149 BBInfo *bblocks = ctx->bblocks;
4151 LLVMBasicBlockRef cbb;
4152 LLVMBuilderRef builder, starting_builder;
4153 gboolean has_terminator;
4155 LLVMValueRef lhs, rhs;
4158 cbb = get_end_bb (ctx, bb);
4160 builder = create_builder (ctx);
4161 ctx->builder = builder;
4162 LLVMPositionBuilderAtEnd (builder, cbb);
4167 if (bb->flags & BB_EXCEPTION_HANDLER) {
4168 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4169 set_failure (ctx, "handler without invokes");
4174 emit_llvmonly_handler_start (ctx, bb, cbb);
4176 emit_handler_start (ctx, bb, builder);
4179 builder = ctx->builder;
4182 has_terminator = FALSE;
4183 starting_builder = builder;
4184 for (ins = bb->code; ins; ins = ins->next) {
4185 const char *spec = LLVM_INS_INFO (ins->opcode);
4187 char dname_buf [128];
4189 emit_dbg_loc (ctx, builder, ins->cil_code);
4194 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4195 * Start a new bblock.
4196 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4197 * from localloc-ed memory.
4199 if (!cfg->llvm_only)
4200 ;//set_failure (ctx, "basic block too long");
4202 if (!ctx->long_bb_break_var) {
4203 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4204 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4207 cbb = gen_bb (ctx, "CONT_LONG_BB");
4208 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4210 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4212 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4213 * but llvm doesn't know that, so the branch is not going to be eliminated.
4215 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4217 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4219 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4220 ctx->builder = builder = create_builder (ctx);
4221 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4222 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4223 LLVMBuildBr (builder, cbb);
4225 ctx->builder = builder = create_builder (ctx);
4226 LLVMPositionBuilderAtEnd (builder, cbb);
4227 ctx->bblocks [bb->block_num].end_bblock = cbb;
4232 /* There could be instructions after a terminator, skip them */
4235 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4236 sprintf (dname_buf, "t%d", ins->dreg);
4240 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4241 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4243 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4244 lhs = emit_volatile_load (ctx, ins->sreg1);
4246 /* It is ok for SETRET to have an uninitialized argument */
4247 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4248 set_failure (ctx, "sreg1");
4251 lhs = values [ins->sreg1];
4257 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4258 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4259 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4260 rhs = emit_volatile_load (ctx, ins->sreg2);
4262 if (!values [ins->sreg2]) {
4263 set_failure (ctx, "sreg2");
4266 rhs = values [ins->sreg2];
4272 //mono_print_ins (ins);
4273 switch (ins->opcode) {
4276 case OP_LIVERANGE_START:
4277 case OP_LIVERANGE_END:
4280 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4283 #if SIZEOF_VOID_P == 4
4284 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4286 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4290 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4294 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4296 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4298 case OP_DUMMY_ICONST:
4299 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4301 case OP_DUMMY_I8CONST:
4302 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4304 case OP_DUMMY_R8CONST:
4305 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4308 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4309 LLVMBuildBr (builder, target_bb);
4310 has_terminator = TRUE;
4317 LLVMBasicBlockRef new_bb;
4318 LLVMBuilderRef new_builder;
4320 // The default branch is already handled
4321 // FIXME: Handle it here
4323 /* Start new bblock */
4324 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4325 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4327 lhs = convert (ctx, lhs, LLVMInt32Type ());
4328 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4329 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4330 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4332 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4335 new_builder = create_builder (ctx);
4336 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4337 LLVMBuildUnreachable (new_builder);
4339 has_terminator = TRUE;
4340 g_assert (!ins->next);
4346 switch (linfo->ret.storage) {
4347 case LLVMArgVtypeInReg: {
4348 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4349 LLVMValueRef val, addr, retval;
4352 retval = LLVMGetUndef (ret_type);
4354 if (!addresses [ins->sreg1]) {
4356 * The return type is an LLVM vector type, have to convert between it and the
4357 * real return type which is a struct type.
4359 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4360 /* Convert to 2xi64 first */
4361 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4363 for (i = 0; i < 2; ++i) {
4364 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4365 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4367 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4371 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4372 for (i = 0; i < 2; ++i) {
4373 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4374 LLVMValueRef indexes [2], part_addr;
4376 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4377 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4378 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4380 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4382 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4386 LLVMBuildRet (builder, retval);
4389 case LLVMArgVtypeAsScalar: {
4390 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4391 LLVMValueRef retval;
4393 g_assert (addresses [ins->sreg1]);
4395 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4396 LLVMBuildRet (builder, retval);
4399 case LLVMArgVtypeByVal: {
4400 LLVMValueRef retval;
4402 g_assert (addresses [ins->sreg1]);
4403 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4404 LLVMBuildRet (builder, retval);
4407 case LLVMArgVtypeByRef: {
4408 LLVMBuildRetVoid (builder);
4411 case LLVMArgGsharedvtFixed: {
4412 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4413 /* The return value is in lhs, need to store to the vret argument */
4414 /* sreg1 might not be set */
4416 g_assert (cfg->vret_addr);
4417 g_assert (values [cfg->vret_addr->dreg]);
4418 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4420 LLVMBuildRetVoid (builder);
4423 case LLVMArgGsharedvtFixedVtype: {
4425 LLVMBuildRetVoid (builder);
4428 case LLVMArgGsharedvtVariable: {
4430 LLVMBuildRetVoid (builder);
4433 case LLVMArgVtypeRetAddr: {
4434 LLVMBuildRetVoid (builder);
4437 case LLVMArgAsIArgs:
4438 case LLVMArgFpStruct: {
4439 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4440 LLVMValueRef retval;
4442 g_assert (addresses [ins->sreg1]);
4443 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4444 LLVMBuildRet (builder, retval);
4448 case LLVMArgNormal: {
4449 if (!lhs || ctx->is_dead [ins->sreg1]) {
4451 * The method did not set its return value, probably because it
4452 * ends with a throw.
4455 LLVMBuildRetVoid (builder);
4457 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4459 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4461 has_terminator = TRUE;
4465 g_assert_not_reached ();
4474 case OP_ICOMPARE_IMM:
4475 case OP_LCOMPARE_IMM:
4476 case OP_COMPARE_IMM: {
4478 LLVMValueRef cmp, args [16];
4479 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4481 if (ins->next->opcode == OP_NOP)
4484 if (ins->next->opcode == OP_BR)
4485 /* The comparison result is not needed */
4488 rel = mono_opcode_to_cond (ins->next->opcode);
4490 if (ins->opcode == OP_ICOMPARE_IMM) {
4491 lhs = convert (ctx, lhs, LLVMInt32Type ());
4492 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4494 if (ins->opcode == OP_LCOMPARE_IMM) {
4495 lhs = convert (ctx, lhs, LLVMInt64Type ());
4496 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4498 if (ins->opcode == OP_LCOMPARE) {
4499 lhs = convert (ctx, lhs, LLVMInt64Type ());
4500 rhs = convert (ctx, rhs, LLVMInt64Type ());
4502 if (ins->opcode == OP_ICOMPARE) {
4503 lhs = convert (ctx, lhs, LLVMInt32Type ());
4504 rhs = convert (ctx, rhs, LLVMInt32Type ());
4508 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4509 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4510 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4511 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4514 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4515 if (ins->opcode == OP_FCOMPARE) {
4516 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4517 } else if (ins->opcode == OP_RCOMPARE) {
4518 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4519 } else if (ins->opcode == OP_COMPARE_IMM) {
4520 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4521 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4523 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4524 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4525 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4526 /* The immediate is encoded in two fields */
4527 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4528 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4530 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4533 else if (ins->opcode == OP_COMPARE) {
4534 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4535 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4537 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4539 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4543 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4544 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4547 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4548 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4550 * If the target bb contains PHI instructions, LLVM requires
4551 * two PHI entries for this bblock, while we only generate one.
4552 * So convert this to an unconditional bblock. (bxc #171).
4554 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4556 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4558 has_terminator = TRUE;
4559 } else if (MONO_IS_SETCC (ins->next)) {
4560 sprintf (dname_buf, "t%d", ins->next->dreg);
4562 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4564 /* Add stores for volatile variables */
4565 emit_volatile_store (ctx, ins->next->dreg);
4566 } else if (MONO_IS_COND_EXC (ins->next)) {
4567 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4570 builder = ctx->builder;
4572 set_failure (ctx, "next");
4590 rel = mono_opcode_to_cond (ins->opcode);
4592 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4593 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4604 rel = mono_opcode_to_cond (ins->opcode);
4606 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4607 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4615 gboolean empty = TRUE;
4617 /* Check that all input bblocks really branch to us */
4618 for (i = 0; i < bb->in_count; ++i) {
4619 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4620 ins->inst_phi_args [i + 1] = -1;
4626 /* LLVM doesn't like phi instructions with zero operands */
4627 ctx->is_dead [ins->dreg] = TRUE;
4631 /* Created earlier, insert it now */
4632 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4634 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4635 int sreg1 = ins->inst_phi_args [i + 1];
4639 * Count the number of times the incoming bblock branches to us,
4640 * since llvm requires a separate entry for each.
4642 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4643 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4646 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4647 if (switch_ins->inst_many_bb [j] == bb)
4654 /* Remember for later */
4655 for (j = 0; j < count; ++j) {
4656 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4659 node->in_bb = bb->in_bb [i];
4661 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);
4671 values [ins->dreg] = lhs;
4675 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4678 values [ins->dreg] = lhs;
4680 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4682 * This is added by the spilling pass in case of the JIT,
4683 * but we have to do it ourselves.
4685 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4689 case OP_MOVE_F_TO_I4: {
4690 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4693 case OP_MOVE_I4_TO_F: {
4694 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4697 case OP_MOVE_F_TO_I8: {
4698 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4701 case OP_MOVE_I8_TO_F: {
4702 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4735 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4736 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4738 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4741 builder = ctx->builder;
4743 switch (ins->opcode) {
4746 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4750 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4754 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4758 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4762 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4766 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4770 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4774 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4778 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4782 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4786 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4790 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4794 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4798 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4802 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4805 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4808 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4812 g_assert_not_reached ();
4819 lhs = convert (ctx, lhs, LLVMFloatType ());
4820 rhs = convert (ctx, rhs, LLVMFloatType ());
4821 switch (ins->opcode) {
4823 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4826 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4829 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4832 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4835 g_assert_not_reached ();
4844 case OP_IREM_UN_IMM:
4846 case OP_IDIV_UN_IMM:
4852 case OP_ISHR_UN_IMM:
4862 case OP_LSHR_UN_IMM:
4868 case OP_SHR_UN_IMM: {
4871 if (spec [MONO_INST_SRC1] == 'l') {
4872 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4874 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4877 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4880 builder = ctx->builder;
4882 #if SIZEOF_VOID_P == 4
4883 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4884 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4887 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4888 lhs = convert (ctx, lhs, IntPtrType ());
4889 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4890 switch (ins->opcode) {
4894 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4898 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4903 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4907 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4909 case OP_IDIV_UN_IMM:
4910 case OP_LDIV_UN_IMM:
4911 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4915 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4917 case OP_IREM_UN_IMM:
4918 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4923 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4927 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4931 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4936 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4941 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4943 case OP_ISHR_UN_IMM:
4944 /* This is used to implement conv.u4, so the lhs could be an i8 */
4945 lhs = convert (ctx, lhs, LLVMInt32Type ());
4946 imm = convert (ctx, imm, LLVMInt32Type ());
4947 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4949 case OP_LSHR_UN_IMM:
4951 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4954 g_assert_not_reached ();
4959 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4962 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4965 lhs = convert (ctx, lhs, LLVMDoubleType ());
4966 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4969 lhs = convert (ctx, lhs, LLVMFloatType ());
4970 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4973 guint32 v = 0xffffffff;
4974 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4978 guint64 v = 0xffffffffffffffffLL;
4979 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4982 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4984 LLVMValueRef v1, v2;
4986 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4987 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4988 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4993 case OP_ICONV_TO_I1:
4994 case OP_ICONV_TO_I2:
4995 case OP_ICONV_TO_I4:
4996 case OP_ICONV_TO_U1:
4997 case OP_ICONV_TO_U2:
4998 case OP_ICONV_TO_U4:
4999 case OP_LCONV_TO_I1:
5000 case OP_LCONV_TO_I2:
5001 case OP_LCONV_TO_U1:
5002 case OP_LCONV_TO_U2:
5003 case OP_LCONV_TO_U4: {
5006 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);
5008 /* Have to do two casts since our vregs have type int */
5009 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
5011 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
5013 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
5016 case OP_ICONV_TO_I8:
5017 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
5019 case OP_ICONV_TO_U8:
5020 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
5022 case OP_FCONV_TO_I4:
5023 case OP_RCONV_TO_I4:
5024 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
5026 case OP_FCONV_TO_I1:
5027 case OP_RCONV_TO_I1:
5028 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
5030 case OP_FCONV_TO_U1:
5031 case OP_RCONV_TO_U1:
5032 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5034 case OP_FCONV_TO_I2:
5035 case OP_RCONV_TO_I2:
5036 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5038 case OP_FCONV_TO_U2:
5039 case OP_RCONV_TO_U2:
5040 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5042 case OP_RCONV_TO_U4:
5043 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5045 case OP_FCONV_TO_I8:
5046 case OP_RCONV_TO_I8:
5047 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5050 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5052 case OP_ICONV_TO_R8:
5053 case OP_LCONV_TO_R8:
5054 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5056 case OP_ICONV_TO_R_UN:
5057 case OP_LCONV_TO_R_UN:
5058 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5060 #if SIZEOF_VOID_P == 4
5063 case OP_LCONV_TO_I4:
5064 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5066 case OP_ICONV_TO_R4:
5067 case OP_LCONV_TO_R4:
5068 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5070 values [ins->dreg] = v;
5072 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5074 case OP_FCONV_TO_R4:
5075 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5077 values [ins->dreg] = v;
5079 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5081 case OP_RCONV_TO_R8:
5082 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5084 case OP_RCONV_TO_R4:
5085 values [ins->dreg] = lhs;
5088 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5091 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5094 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5096 case OP_LOCALLOC_IMM: {
5099 guint32 size = ins->inst_imm;
5100 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5102 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5104 if (ins->flags & MONO_INST_INIT) {
5105 LLVMValueRef args [5];
5108 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5109 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5110 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5111 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5112 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5115 values [ins->dreg] = v;
5119 LLVMValueRef v, size;
5121 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), "");
5123 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5125 if (ins->flags & MONO_INST_INIT) {
5126 LLVMValueRef args [5];
5129 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5131 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5132 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5133 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5135 values [ins->dreg] = v;
5139 case OP_LOADI1_MEMBASE:
5140 case OP_LOADU1_MEMBASE:
5141 case OP_LOADI2_MEMBASE:
5142 case OP_LOADU2_MEMBASE:
5143 case OP_LOADI4_MEMBASE:
5144 case OP_LOADU4_MEMBASE:
5145 case OP_LOADI8_MEMBASE:
5146 case OP_LOADR4_MEMBASE:
5147 case OP_LOADR8_MEMBASE:
5148 case OP_LOAD_MEMBASE:
5156 LLVMValueRef base, index, addr;
5158 gboolean sext = FALSE, zext = FALSE;
5159 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5161 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5166 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)) {
5167 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5173 if (ins->inst_offset == 0) {
5175 } else if (ins->inst_offset % size != 0) {
5176 /* Unaligned load */
5177 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5178 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5180 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5181 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5185 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5187 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5189 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5191 * These will signal LLVM that these loads do not alias any stores, and
5192 * they can't fail, allowing them to be hoisted out of loops.
5194 set_invariant_load_flag (values [ins->dreg]);
5195 #if LLVM_API_VERSION < 100
5196 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5201 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5203 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5204 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5205 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5209 case OP_STOREI1_MEMBASE_REG:
5210 case OP_STOREI2_MEMBASE_REG:
5211 case OP_STOREI4_MEMBASE_REG:
5212 case OP_STOREI8_MEMBASE_REG:
5213 case OP_STORER4_MEMBASE_REG:
5214 case OP_STORER8_MEMBASE_REG:
5215 case OP_STORE_MEMBASE_REG: {
5217 LLVMValueRef index, addr, base;
5219 gboolean sext = FALSE, zext = FALSE;
5220 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5222 if (!values [ins->inst_destbasereg]) {
5223 set_failure (ctx, "inst_destbasereg");
5227 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5229 base = values [ins->inst_destbasereg];
5230 if (ins->inst_offset % size != 0) {
5231 /* Unaligned store */
5232 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5233 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5235 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5236 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5238 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5242 case OP_STOREI1_MEMBASE_IMM:
5243 case OP_STOREI2_MEMBASE_IMM:
5244 case OP_STOREI4_MEMBASE_IMM:
5245 case OP_STOREI8_MEMBASE_IMM:
5246 case OP_STORE_MEMBASE_IMM: {
5248 LLVMValueRef index, addr, base;
5250 gboolean sext = FALSE, zext = FALSE;
5251 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5253 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5255 base = values [ins->inst_destbasereg];
5256 if (ins->inst_offset % size != 0) {
5257 /* Unaligned store */
5258 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5259 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5261 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5262 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5264 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5269 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5271 case OP_OUTARG_VTRETADDR:
5279 case OP_VOIDCALL_MEMBASE:
5280 case OP_CALL_MEMBASE:
5281 case OP_LCALL_MEMBASE:
5282 case OP_FCALL_MEMBASE:
5283 case OP_RCALL_MEMBASE:
5284 case OP_VCALL_MEMBASE:
5285 case OP_VOIDCALL_REG:
5290 case OP_VCALL_REG: {
5291 process_call (ctx, bb, &builder, ins);
5296 LLVMValueRef indexes [2];
5297 MonoJumpInfo *tmp_ji, *ji;
5298 LLVMValueRef got_entry_addr;
5302 * FIXME: Can't allocate from the cfg mempool since that is freed if
5303 * the LLVM compile fails.
5305 tmp_ji = g_new0 (MonoJumpInfo, 1);
5306 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5307 tmp_ji->data.target = ins->inst_p0;
5309 ji = mono_aot_patch_info_dup (tmp_ji);
5312 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5313 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5316 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5317 * resolvable at runtime using dlsym ().
5320 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5325 ji->next = cfg->patch_info;
5326 cfg->patch_info = ji;
5328 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5329 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5330 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5331 if (!mono_aot_is_shared_got_offset (got_offset)) {
5332 //mono_print_ji (ji);
5334 ctx->has_got_access = TRUE;
5337 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5338 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5339 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5341 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5342 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5344 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5345 if (!cfg->llvm_only)
5346 set_invariant_load_flag (values [ins->dreg]);
5349 case OP_NOT_REACHED:
5350 LLVMBuildUnreachable (builder);
5351 has_terminator = TRUE;
5352 g_assert (bb->block_num < cfg->max_block_num);
5353 ctx->unreachable [bb->block_num] = TRUE;
5354 /* Might have instructions after this */
5356 MonoInst *next = ins->next;
5358 * FIXME: If later code uses the regs defined by these instructions,
5359 * compilation will fail.
5361 MONO_DELETE_INS (bb, next);
5365 MonoInst *var = ins->inst_i0;
5367 if (var->opcode == OP_VTARG_ADDR) {
5368 /* The variable contains the vtype address */
5369 values [ins->dreg] = values [var->dreg];
5370 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5371 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5373 values [ins->dreg] = addresses [var->dreg];
5378 LLVMValueRef args [1];
5380 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5381 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5385 LLVMValueRef args [1];
5387 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5388 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5392 LLVMValueRef args [1];
5394 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5395 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5399 LLVMValueRef args [1];
5401 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5402 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5416 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5417 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5419 switch (ins->opcode) {
5422 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5426 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5430 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5434 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5437 g_assert_not_reached ();
5440 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5445 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5446 * hack is necessary (for now).
5449 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5451 #define ARM64_ATOMIC_FENCE_FIX
5454 case OP_ATOMIC_EXCHANGE_I4:
5455 case OP_ATOMIC_EXCHANGE_I8: {
5456 LLVMValueRef args [2];
5459 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5460 t = LLVMInt32Type ();
5462 t = LLVMInt64Type ();
5464 g_assert (ins->inst_offset == 0);
5466 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5467 args [1] = convert (ctx, rhs, t);
5469 ARM64_ATOMIC_FENCE_FIX;
5470 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5471 ARM64_ATOMIC_FENCE_FIX;
5474 case OP_ATOMIC_ADD_I4:
5475 case OP_ATOMIC_ADD_I8: {
5476 LLVMValueRef args [2];
5479 if (ins->opcode == OP_ATOMIC_ADD_I4)
5480 t = LLVMInt32Type ();
5482 t = LLVMInt64Type ();
5484 g_assert (ins->inst_offset == 0);
5486 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5487 args [1] = convert (ctx, rhs, t);
5488 ARM64_ATOMIC_FENCE_FIX;
5489 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5490 ARM64_ATOMIC_FENCE_FIX;
5493 case OP_ATOMIC_CAS_I4:
5494 case OP_ATOMIC_CAS_I8: {
5495 LLVMValueRef args [3], val;
5498 if (ins->opcode == OP_ATOMIC_CAS_I4)
5499 t = LLVMInt32Type ();
5501 t = LLVMInt64Type ();
5503 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5505 args [1] = convert (ctx, values [ins->sreg3], t);
5507 args [2] = convert (ctx, values [ins->sreg2], t);
5508 ARM64_ATOMIC_FENCE_FIX;
5509 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5510 ARM64_ATOMIC_FENCE_FIX;
5511 /* cmpxchg returns a pair */
5512 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5515 case OP_MEMORY_BARRIER: {
5516 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5519 case OP_ATOMIC_LOAD_I1:
5520 case OP_ATOMIC_LOAD_I2:
5521 case OP_ATOMIC_LOAD_I4:
5522 case OP_ATOMIC_LOAD_I8:
5523 case OP_ATOMIC_LOAD_U1:
5524 case OP_ATOMIC_LOAD_U2:
5525 case OP_ATOMIC_LOAD_U4:
5526 case OP_ATOMIC_LOAD_U8:
5527 case OP_ATOMIC_LOAD_R4:
5528 case OP_ATOMIC_LOAD_R8: {
5529 #if LLVM_API_VERSION > 100
5531 gboolean sext, zext;
5533 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5534 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5535 LLVMValueRef index, addr;
5537 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5542 if (ins->inst_offset != 0) {
5543 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5544 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5549 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5551 ARM64_ATOMIC_FENCE_FIX;
5552 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5553 ARM64_ATOMIC_FENCE_FIX;
5556 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5558 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5561 set_failure (ctx, "atomic mono.load intrinsic");
5565 case OP_ATOMIC_STORE_I1:
5566 case OP_ATOMIC_STORE_I2:
5567 case OP_ATOMIC_STORE_I4:
5568 case OP_ATOMIC_STORE_I8:
5569 case OP_ATOMIC_STORE_U1:
5570 case OP_ATOMIC_STORE_U2:
5571 case OP_ATOMIC_STORE_U4:
5572 case OP_ATOMIC_STORE_U8:
5573 case OP_ATOMIC_STORE_R4:
5574 case OP_ATOMIC_STORE_R8: {
5576 gboolean sext, zext;
5578 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5579 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5580 LLVMValueRef index, addr, value, base;
5582 #if LLVM_API_VERSION < 100
5583 if (!cfg->llvm_only) {
5584 set_failure (ctx, "atomic mono.store intrinsic");
5589 if (!values [ins->inst_destbasereg]) {
5590 set_failure (ctx, "inst_destbasereg");
5594 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5596 base = values [ins->inst_destbasereg];
5597 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5598 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5599 value = convert (ctx, values [ins->sreg1], t);
5601 ARM64_ATOMIC_FENCE_FIX;
5602 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5603 ARM64_ATOMIC_FENCE_FIX;
5606 case OP_RELAXED_NOP: {
5607 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5608 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5615 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5617 // 257 == FS segment register
5618 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5620 // 256 == GS segment register
5621 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5624 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5625 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5626 /* See mono_amd64_emit_tls_get () */
5627 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5629 // 256 == GS segment register
5630 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5631 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5633 set_failure (ctx, "opcode tls-get");
5639 case OP_GC_SAFE_POINT: {
5640 LLVMValueRef val, cmp, callee;
5641 LLVMBasicBlockRef poll_bb, cont_bb;
5642 static LLVMTypeRef sig;
5643 const char *icall_name = "mono_threads_state_poll";
5646 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5650 * mono_threads_state_poll ();
5651 * FIXME: Use a preserveall wrapper
5653 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5654 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5655 poll_bb = gen_bb (ctx, "POLL_BB");
5656 cont_bb = gen_bb (ctx, "CONT_BB");
5657 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5659 ctx->builder = builder = create_builder (ctx);
5660 LLVMPositionBuilderAtEnd (builder, poll_bb);
5662 if (ctx->cfg->compile_aot) {
5663 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5665 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5666 callee = emit_jit_callee (ctx, icall_name, sig, target);
5668 LLVMBuildCall (builder, callee, NULL, 0, "");
5669 LLVMBuildBr (builder, cont_bb);
5671 ctx->builder = builder = create_builder (ctx);
5672 LLVMPositionBuilderAtEnd (builder, cont_bb);
5673 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5681 case OP_IADD_OVF_UN:
5683 case OP_ISUB_OVF_UN:
5685 case OP_IMUL_OVF_UN:
5687 case OP_LADD_OVF_UN:
5689 case OP_LSUB_OVF_UN:
5691 case OP_LMUL_OVF_UN:
5693 LLVMValueRef args [2], val, ovf, func;
5695 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5696 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5697 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5699 val = LLVMBuildCall (builder, func, args, 2, "");
5700 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5701 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5702 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5705 builder = ctx->builder;
5711 * We currently model them using arrays. Promotion to local vregs is
5712 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5713 * so we always have an entry in cfg->varinfo for them.
5714 * FIXME: Is this needed ?
5717 MonoClass *klass = ins->klass;
5718 LLVMValueRef args [5];
5722 set_failure (ctx, "!klass");
5726 if (!addresses [ins->dreg])
5727 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5728 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5729 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5730 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5732 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5733 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5734 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5737 case OP_DUMMY_VZERO:
5740 case OP_STOREV_MEMBASE:
5741 case OP_LOADV_MEMBASE:
5743 MonoClass *klass = ins->klass;
5744 LLVMValueRef src = NULL, dst, args [5];
5745 gboolean done = FALSE;
5749 set_failure (ctx, "!klass");
5753 if (mini_is_gsharedvt_klass (klass)) {
5755 set_failure (ctx, "gsharedvt");
5759 switch (ins->opcode) {
5760 case OP_STOREV_MEMBASE:
5761 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5762 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5763 /* Decomposed earlier */
5764 g_assert_not_reached ();
5767 if (!addresses [ins->sreg1]) {
5769 g_assert (values [ins->sreg1]);
5770 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));
5771 LLVMBuildStore (builder, values [ins->sreg1], dst);
5774 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5775 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5778 case OP_LOADV_MEMBASE:
5779 if (!addresses [ins->dreg])
5780 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5781 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5782 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5785 if (!addresses [ins->sreg1])
5786 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5787 if (!addresses [ins->dreg])
5788 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5789 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5790 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5793 g_assert_not_reached ();
5803 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5804 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5806 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5807 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5808 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5811 case OP_LLVM_OUTARG_VT: {
5812 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5813 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5815 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5816 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5818 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5819 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5821 g_assert (addresses [ins->sreg1]);
5822 addresses [ins->dreg] = addresses [ins->sreg1];
5824 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5825 if (!addresses [ins->sreg1]) {
5826 addresses [ins->sreg1] = build_alloca (ctx, t);
5827 g_assert (values [ins->sreg1]);
5829 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5830 addresses [ins->dreg] = addresses [ins->sreg1];
5832 if (!addresses [ins->sreg1]) {
5833 addresses [ins->sreg1] = build_alloca (ctx, t);
5834 g_assert (values [ins->sreg1]);
5835 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5837 addresses [ins->dreg] = addresses [ins->sreg1];
5841 case OP_OBJC_GET_SELECTOR: {
5842 const char *name = (const char*)ins->inst_p0;
5845 if (!ctx->module->objc_selector_to_var) {
5846 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5848 LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
5849 int32_t objc_imageinfo [] = { 0, 16 };
5850 LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
5851 LLVMSetLinkage (info_var, LLVMPrivateLinkage);
5852 LLVMSetExternallyInitialized (info_var, TRUE);
5853 LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
5854 LLVMSetAlignment (info_var, sizeof (mgreg_t));
5855 mark_as_used (ctx->module, info_var);
5858 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5860 LLVMValueRef indexes [16];
5862 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5863 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5864 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5865 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5866 mark_as_used (ctx->module, name_var);
5868 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5870 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5871 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5872 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5873 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5874 LLVMSetExternallyInitialized (ref_var, TRUE);
5875 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5876 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5877 mark_as_used (ctx->module, ref_var);
5879 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5883 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5890 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5892 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5895 case OP_LOADX_MEMBASE: {
5896 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5899 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5900 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5903 case OP_STOREX_MEMBASE: {
5904 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5907 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5908 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5915 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5919 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5925 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5929 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5933 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5937 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5940 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5943 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5946 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5950 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5961 LLVMValueRef v = NULL;
5963 switch (ins->opcode) {
5968 t = LLVMVectorType (LLVMInt32Type (), 4);
5969 rt = LLVMVectorType (LLVMFloatType (), 4);
5975 t = LLVMVectorType (LLVMInt64Type (), 2);
5976 rt = LLVMVectorType (LLVMDoubleType (), 2);
5979 t = LLVMInt32Type ();
5980 rt = LLVMInt32Type ();
5981 g_assert_not_reached ();
5984 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5985 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5986 switch (ins->opcode) {
5989 v = LLVMBuildAnd (builder, lhs, rhs, "");
5993 v = LLVMBuildOr (builder, lhs, rhs, "");
5997 v = LLVMBuildXor (builder, lhs, rhs, "");
6001 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
6004 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
6010 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
6011 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6017 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6018 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6022 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6023 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6040 case OP_PADDB_SAT_UN:
6041 case OP_PADDW_SAT_UN:
6042 case OP_PSUBB_SAT_UN:
6043 case OP_PSUBW_SAT_UN:
6051 case OP_PMULW_HIGH_UN: {
6052 LLVMValueRef args [2];
6057 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6064 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6068 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6076 case OP_EXTRACTX_U2:
6078 case OP_EXTRACT_U1: {
6080 gboolean zext = FALSE;
6082 t = simd_op_to_llvm_type (ins->opcode);
6084 switch (ins->opcode) {
6092 case OP_EXTRACTX_U2:
6097 t = LLVMInt32Type ();
6098 g_assert_not_reached ();
6101 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6102 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6104 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6113 case OP_EXPAND_R8: {
6114 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6115 LLVMValueRef mask [16], v;
6118 for (i = 0; i < 16; ++i)
6119 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6121 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6123 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6124 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6129 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6132 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6135 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6138 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6141 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6144 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6148 // Requires a later llvm version
6150 LLVMValueRef indexes [16];
6152 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6153 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6154 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6155 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6156 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6160 LLVMValueRef indexes [16];
6162 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6163 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6164 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6165 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6166 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6170 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6182 case OP_EXTRACT_MASK:
6189 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6191 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6196 LLVMRealPredicate op;
6198 switch (ins->inst_c0) {
6208 case SIMD_COMP_UNORD:
6224 g_assert_not_reached ();
6227 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6228 if (ins->opcode == OP_COMPPD)
6229 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6231 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6235 /* This is only used for implementing shifts by non-immediate */
6236 values [ins->dreg] = lhs;
6247 LLVMValueRef args [3];
6250 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6252 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6263 case OP_PSHLQ_REG: {
6264 LLVMValueRef args [3];
6267 args [1] = values [ins->sreg2];
6269 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6276 case OP_PSHUFLEW_LOW:
6277 case OP_PSHUFLEW_HIGH: {
6279 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6280 int i, mask_size = 0;
6281 int imask = ins->inst_c0;
6283 /* Convert the x86 shuffle mask to LLVM's */
6284 switch (ins->opcode) {
6287 mask [0] = ((imask >> 0) & 3);
6288 mask [1] = ((imask >> 2) & 3);
6289 mask [2] = ((imask >> 4) & 3) + 4;
6290 mask [3] = ((imask >> 6) & 3) + 4;
6291 v1 = values [ins->sreg1];
6292 v2 = values [ins->sreg2];
6296 mask [0] = ((imask >> 0) & 1);
6297 mask [1] = ((imask >> 1) & 1) + 2;
6298 v1 = values [ins->sreg1];
6299 v2 = values [ins->sreg2];
6301 case OP_PSHUFLEW_LOW:
6303 mask [0] = ((imask >> 0) & 3);
6304 mask [1] = ((imask >> 2) & 3);
6305 mask [2] = ((imask >> 4) & 3);
6306 mask [3] = ((imask >> 6) & 3);
6311 v1 = values [ins->sreg1];
6312 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6314 case OP_PSHUFLEW_HIGH:
6320 mask [4] = 4 + ((imask >> 0) & 3);
6321 mask [5] = 4 + ((imask >> 2) & 3);
6322 mask [6] = 4 + ((imask >> 4) & 3);
6323 mask [7] = 4 + ((imask >> 6) & 3);
6324 v1 = values [ins->sreg1];
6325 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6329 mask [0] = ((imask >> 0) & 3);
6330 mask [1] = ((imask >> 2) & 3);
6331 mask [2] = ((imask >> 4) & 3);
6332 mask [3] = ((imask >> 6) & 3);
6333 v1 = values [ins->sreg1];
6334 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6337 g_assert_not_reached ();
6339 for (i = 0; i < mask_size; ++i)
6340 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6342 values [ins->dreg] =
6343 LLVMBuildShuffleVector (builder, v1, v2,
6344 LLVMConstVector (mask_values, mask_size), dname);
6348 case OP_UNPACK_LOWB:
6349 case OP_UNPACK_LOWW:
6350 case OP_UNPACK_LOWD:
6351 case OP_UNPACK_LOWQ:
6352 case OP_UNPACK_LOWPS:
6353 case OP_UNPACK_LOWPD:
6354 case OP_UNPACK_HIGHB:
6355 case OP_UNPACK_HIGHW:
6356 case OP_UNPACK_HIGHD:
6357 case OP_UNPACK_HIGHQ:
6358 case OP_UNPACK_HIGHPS:
6359 case OP_UNPACK_HIGHPD: {
6361 LLVMValueRef mask_values [16];
6362 int i, mask_size = 0;
6363 gboolean low = FALSE;
6365 switch (ins->opcode) {
6366 case OP_UNPACK_LOWB:
6370 case OP_UNPACK_LOWW:
6374 case OP_UNPACK_LOWD:
6375 case OP_UNPACK_LOWPS:
6379 case OP_UNPACK_LOWQ:
6380 case OP_UNPACK_LOWPD:
6384 case OP_UNPACK_HIGHB:
6387 case OP_UNPACK_HIGHW:
6390 case OP_UNPACK_HIGHD:
6391 case OP_UNPACK_HIGHPS:
6394 case OP_UNPACK_HIGHQ:
6395 case OP_UNPACK_HIGHPD:
6399 g_assert_not_reached ();
6403 for (i = 0; i < (mask_size / 2); ++i) {
6405 mask [(i * 2) + 1] = mask_size + i;
6408 for (i = 0; i < (mask_size / 2); ++i) {
6409 mask [(i * 2)] = (mask_size / 2) + i;
6410 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6414 for (i = 0; i < mask_size; ++i)
6415 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6417 values [ins->dreg] =
6418 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6419 LLVMConstVector (mask_values, mask_size), dname);
6424 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6425 LLVMValueRef v, val;
6427 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6428 val = LLVMConstNull (t);
6429 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6430 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6432 values [ins->dreg] = val;
6436 case OP_DUPPS_HIGH: {
6437 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6438 LLVMValueRef v1, v2, val;
6441 if (ins->opcode == OP_DUPPS_LOW) {
6442 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6443 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6445 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6446 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6448 val = LLVMConstNull (t);
6449 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6450 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6451 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6452 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6454 values [ins->dreg] = val;
6459 LLVMValueRef args [3];
6463 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6464 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6466 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6476 * EXCEPTION HANDLING
6478 case OP_IMPLICIT_EXCEPTION:
6479 /* This marks a place where an implicit exception can happen */
6480 if (bb->region != -1)
6481 set_failure (ctx, "implicit-exception");
6485 gboolean rethrow = (ins->opcode == OP_RETHROW);
6486 if (ctx->llvm_only) {
6487 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6488 has_terminator = TRUE;
6489 ctx->unreachable [bb->block_num] = TRUE;
6491 emit_throw (ctx, bb, rethrow, lhs);
6492 builder = ctx->builder;
6496 case OP_CALL_HANDLER: {
6498 * We don't 'call' handlers, but instead simply branch to them.
6499 * The code generated by ENDFINALLY will branch back to us.
6501 LLVMBasicBlockRef noex_bb;
6503 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6505 bb_list = info->call_handler_return_bbs;
6508 * Set the indicator variable for the finally clause.
6510 lhs = info->finally_ind;
6512 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6514 /* Branch to the finally clause */
6515 LLVMBuildBr (builder, info->call_handler_target_bb);
6517 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6518 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6520 builder = ctx->builder = create_builder (ctx);
6521 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6523 bblocks [bb->block_num].end_bblock = noex_bb;
6526 case OP_START_HANDLER: {
6529 case OP_ENDFINALLY: {
6530 LLVMBasicBlockRef resume_bb;
6531 MonoBasicBlock *handler_bb;
6532 LLVMValueRef val, switch_ins, callee;
6536 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6537 g_assert (handler_bb);
6538 info = &bblocks [handler_bb->block_num];
6539 lhs = info->finally_ind;
6542 bb_list = info->call_handler_return_bbs;
6544 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6546 /* Load the finally variable */
6547 val = LLVMBuildLoad (builder, lhs, "");
6549 /* Reset the variable */
6550 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6552 /* Branch to either resume_bb, or to the bblocks in bb_list */
6553 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6555 * The other targets are added at the end to handle OP_CALL_HANDLER
6556 * opcodes processed later.
6558 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6560 builder = ctx->builder = create_builder (ctx);
6561 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6563 if (ctx->llvm_only) {
6564 emit_resume_eh (ctx, bb);
6566 if (ctx->cfg->compile_aot) {
6567 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6569 #if LLVM_API_VERSION > 100
6570 MonoJitICallInfo *info;
6572 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6574 gpointer target = (void*)info->func;
6575 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6576 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6578 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6581 LLVMBuildCall (builder, callee, NULL, 0, "");
6582 LLVMBuildUnreachable (builder);
6585 has_terminator = TRUE;
6588 case OP_IL_SEQ_POINT:
6593 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6594 set_failure (ctx, reason);
6602 /* Convert the value to the type required by phi nodes */
6603 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6604 if (ctx->is_vphi [ins->dreg])
6606 values [ins->dreg] = addresses [ins->dreg];
6608 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6611 /* Add stores for volatile variables */
6612 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6613 emit_volatile_store (ctx, ins->dreg);
6619 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6620 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6623 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6624 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6625 LLVMBuildRetVoid (builder);
6628 if (bb == cfg->bb_entry)
6629 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6633 * mono_llvm_check_method_supported:
6635 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6636 * compiling a method twice.
6639 mono_llvm_check_method_supported (MonoCompile *cfg)
6646 if (cfg->method->save_lmf) {
6647 cfg->exception_message = g_strdup ("lmf");
6648 cfg->disable_llvm = TRUE;
6650 if (cfg->disable_llvm)
6654 * Nested clauses where one of the clauses is a finally clause is
6655 * not supported, because LLVM can't figure out the control flow,
6656 * probably because we resume exception handling by calling our
6657 * own function instead of using the 'resume' llvm instruction.
6659 for (i = 0; i < cfg->header->num_clauses; ++i) {
6660 for (j = 0; j < cfg->header->num_clauses; ++j) {
6661 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6662 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6664 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6665 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6666 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6667 cfg->exception_message = g_strdup ("nested clauses");
6668 cfg->disable_llvm = TRUE;
6673 if (cfg->disable_llvm)
6677 if (cfg->method->dynamic) {
6678 cfg->exception_message = g_strdup ("dynamic.");
6679 cfg->disable_llvm = TRUE;
6681 if (cfg->disable_llvm)
6685 static LLVMCallInfo*
6686 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6688 LLVMCallInfo *linfo;
6691 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6695 * Gsharedvt methods have the following calling convention:
6696 * - all arguments are passed by ref, even non generic ones
6697 * - the return value is returned by ref too, using a vret
6698 * argument passed after 'this'.
6700 n = sig->param_count + sig->hasthis;
6701 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6705 linfo->args [pindex ++].storage = LLVMArgNormal;
6707 if (sig->ret->type != MONO_TYPE_VOID) {
6708 if (mini_is_gsharedvt_variable_type (sig->ret))
6709 linfo->ret.storage = LLVMArgGsharedvtVariable;
6710 else if (mini_type_is_vtype (sig->ret))
6711 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6713 linfo->ret.storage = LLVMArgGsharedvtFixed;
6714 linfo->vret_arg_index = pindex;
6716 linfo->ret.storage = LLVMArgNone;
6719 for (i = 0; i < sig->param_count; ++i) {
6720 if (sig->params [i]->byref)
6721 linfo->args [pindex].storage = LLVMArgNormal;
6722 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6723 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6724 else if (mini_type_is_vtype (sig->params [i]))
6725 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6727 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6728 linfo->args [pindex].type = sig->params [i];
6735 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6736 for (i = 0; i < sig->param_count; ++i)
6737 linfo->args [i + sig->hasthis].type = sig->params [i];
6743 emit_method_inner (EmitContext *ctx);
6746 free_ctx (EmitContext *ctx)
6750 g_free (ctx->values);
6751 g_free (ctx->addresses);
6752 g_free (ctx->vreg_types);
6753 g_free (ctx->is_vphi);
6754 g_free (ctx->vreg_cli_types);
6755 g_free (ctx->is_dead);
6756 g_free (ctx->unreachable);
6757 g_ptr_array_free (ctx->phi_values, TRUE);
6758 g_free (ctx->bblocks);
6759 g_hash_table_destroy (ctx->region_to_handler);
6760 g_hash_table_destroy (ctx->clause_to_handler);
6761 g_hash_table_destroy (ctx->jit_callees);
6763 GHashTableIter iter;
6764 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6765 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6768 g_hash_table_destroy (ctx->method_to_callers);
6770 g_free (ctx->method_name);
6771 g_ptr_array_free (ctx->bblock_list, TRUE);
6773 for (l = ctx->builders; l; l = l->next) {
6774 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6775 LLVMDisposeBuilder (builder);
6782 * mono_llvm_emit_method:
6784 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6787 mono_llvm_emit_method (MonoCompile *cfg)
6791 gboolean is_linkonce = FALSE;
6794 /* The code below might acquire the loader lock, so use it for global locking */
6795 mono_loader_lock ();
6797 /* Used to communicate with the callbacks */
6798 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6800 ctx = g_new0 (EmitContext, 1);
6802 ctx->mempool = cfg->mempool;
6805 * This maps vregs to the LLVM instruction defining them
6807 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6809 * This maps vregs for volatile variables to the LLVM instruction defining their
6812 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6813 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6814 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6815 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6816 ctx->phi_values = g_ptr_array_sized_new (256);
6818 * This signals whenever the vreg was defined by a phi node with no input vars
6819 * (i.e. all its input bblocks end with NOT_REACHABLE).
6821 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6822 /* Whenever the bblock is unreachable */
6823 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6824 ctx->bblock_list = g_ptr_array_sized_new (256);
6826 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6827 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6828 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6829 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6830 if (cfg->compile_aot) {
6831 ctx->module = &aot_module;
6835 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6836 * linkage for them. This requires the following:
6837 * - the method needs to have a unique mangled name
6838 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6840 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6842 method_name = mono_aot_get_mangled_method_name (cfg->method);
6844 is_linkonce = FALSE;
6847 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6849 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6853 method_name = mono_aot_get_method_name (cfg);
6854 cfg->llvm_method_name = g_strdup (method_name);
6856 init_jit_module (cfg->domain);
6857 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6858 method_name = mono_method_full_name (cfg->method, TRUE);
6860 ctx->method_name = method_name;
6861 ctx->is_linkonce = is_linkonce;
6863 #if LLVM_API_VERSION > 100
6864 if (cfg->compile_aot)
6865 ctx->lmodule = ctx->module->lmodule;
6867 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6869 ctx->lmodule = ctx->module->lmodule;
6871 ctx->llvm_only = ctx->module->llvm_only;
6873 emit_method_inner (ctx);
6875 if (!ctx_ok (ctx)) {
6877 /* Need to add unused phi nodes as they can be referenced by other values */
6878 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6879 LLVMBuilderRef builder;
6881 builder = create_builder (ctx);
6882 LLVMPositionBuilderAtEnd (builder, phi_bb);
6884 for (i = 0; i < ctx->phi_values->len; ++i) {
6885 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6886 if (LLVMGetInstructionParent (v) == NULL)
6887 LLVMInsertIntoBuilder (builder, v);
6890 LLVMDeleteFunction (ctx->lmethod);
6896 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6898 mono_loader_unlock ();
6902 emit_method_inner (EmitContext *ctx)
6904 MonoCompile *cfg = ctx->cfg;
6905 MonoMethodSignature *sig;
6907 LLVMTypeRef method_type;
6908 LLVMValueRef method = NULL;
6909 LLVMValueRef *values = ctx->values;
6910 int i, max_block_num, bb_index;
6911 gboolean last = FALSE;
6912 LLVMCallInfo *linfo;
6913 LLVMModuleRef lmodule = ctx->lmodule;
6915 GPtrArray *bblock_list = ctx->bblock_list;
6916 MonoMethodHeader *header;
6917 MonoExceptionClause *clause;
6920 if (cfg->gsharedvt && !cfg->llvm_only) {
6921 set_failure (ctx, "gsharedvt");
6927 static int count = 0;
6930 if (g_getenv ("LLVM_COUNT")) {
6931 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6932 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6936 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6937 set_failure (ctx, "count");
6944 sig = mono_method_signature (cfg->method);
6947 linfo = get_llvm_call_info (cfg, sig);
6953 linfo->rgctx_arg = TRUE;
6954 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6958 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6959 ctx->lmethod = method;
6961 if (!cfg->llvm_only)
6962 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6963 LLVMSetLinkage (method, LLVMPrivateLinkage);
6965 LLVMAddFunctionAttr (method, LLVMUWTable);
6967 if (cfg->compile_aot) {
6968 LLVMSetLinkage (method, LLVMInternalLinkage);
6969 if (ctx->module->external_symbols) {
6970 LLVMSetLinkage (method, LLVMExternalLinkage);
6971 LLVMSetVisibility (method, LLVMHiddenVisibility);
6973 if (ctx->is_linkonce) {
6974 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6975 LLVMSetVisibility (method, LLVMDefaultVisibility);
6978 #if LLVM_API_VERSION > 100
6979 LLVMSetLinkage (method, LLVMExternalLinkage);
6981 LLVMSetLinkage (method, LLVMPrivateLinkage);
6985 if (cfg->method->save_lmf && !cfg->llvm_only) {
6986 set_failure (ctx, "lmf");
6990 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6991 set_failure (ctx, "pinvoke signature");
6995 header = cfg->header;
6996 for (i = 0; i < header->num_clauses; ++i) {
6997 clause = &header->clauses [i];
6998 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6999 set_failure (ctx, "non-finally/catch clause.");
7003 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7004 /* We can't handle inlined methods with clauses */
7005 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
7007 if (linfo->rgctx_arg) {
7008 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7009 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7011 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7012 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7013 * CC_X86_64_Mono in X86CallingConv.td.
7015 if (!ctx->llvm_only)
7016 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
7017 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7019 ctx->rgctx_arg_pindex = -1;
7021 if (cfg->vret_addr) {
7022 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7023 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7024 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7025 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7026 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7031 ctx->this_arg_pindex = linfo->this_arg_pindex;
7032 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7033 values [cfg->args [0]->dreg] = ctx->this_arg;
7034 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7037 names = g_new (char *, sig->param_count);
7038 mono_method_get_param_names (cfg->method, (const char **) names);
7040 /* Set parameter names/attributes */
7041 for (i = 0; i < sig->param_count; ++i) {
7042 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7044 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7047 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7048 name = g_strdup_printf ("dummy_%d_%d", i, j);
7049 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7053 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7056 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7057 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7058 if (names [i] && names [i][0] != '\0')
7059 name = g_strdup_printf ("p_arg_%s", names [i]);
7061 name = g_strdup_printf ("p_arg_%d", i);
7063 if (names [i] && names [i][0] != '\0')
7064 name = g_strdup_printf ("arg_%s", names [i]);
7066 name = g_strdup_printf ("arg_%d", i);
7068 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7070 if (ainfo->storage == LLVMArgVtypeByVal)
7071 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7073 if (ainfo->storage == LLVMArgVtypeByRef) {
7075 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7080 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7081 ctx->minfo = mono_debug_lookup_method (cfg->method);
7082 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7086 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7087 max_block_num = MAX (max_block_num, bb->block_num);
7088 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7090 /* Add branches between non-consecutive bblocks */
7091 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7092 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7093 bb->next_bb != bb->last_ins->inst_false_bb) {
7095 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7096 inst->opcode = OP_BR;
7097 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7098 mono_bblock_add_inst (bb, inst);
7103 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7104 * was later optimized away, so clear these flags, and add them back for the still
7105 * present OP_LDADDR instructions.
7107 for (i = 0; i < cfg->next_vreg; ++i) {
7110 ins = get_vreg_to_inst (cfg, i);
7111 if (ins && ins != cfg->rgctx_var)
7112 ins->flags &= ~MONO_INST_INDIRECT;
7116 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7118 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7120 LLVMBuilderRef builder;
7122 char dname_buf[128];
7124 builder = create_builder (ctx);
7126 for (ins = bb->code; ins; ins = ins->next) {
7127 switch (ins->opcode) {
7132 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7137 if (ins->opcode == OP_VPHI) {
7138 /* Treat valuetype PHI nodes as operating on the address itself */
7139 g_assert (ins->klass);
7140 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7144 * Have to precreate these, as they can be referenced by
7145 * earlier instructions.
7147 sprintf (dname_buf, "t%d", ins->dreg);
7149 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7151 if (ins->opcode == OP_VPHI)
7152 ctx->addresses [ins->dreg] = values [ins->dreg];
7154 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7157 * Set the expected type of the incoming arguments since these have
7158 * to have the same type.
7160 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7161 int sreg1 = ins->inst_phi_args [i + 1];
7164 if (ins->opcode == OP_VPHI)
7165 ctx->is_vphi [sreg1] = TRUE;
7166 ctx->vreg_types [sreg1] = phi_type;
7172 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7181 * Create an ordering for bblocks, use the depth first order first, then
7182 * put the exception handling bblocks last.
7184 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7185 bb = cfg->bblocks [bb_index];
7186 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7187 g_ptr_array_add (bblock_list, bb);
7188 bblocks [bb->block_num].added = TRUE;
7192 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7193 if (!bblocks [bb->block_num].added)
7194 g_ptr_array_add (bblock_list, bb);
7198 * Second pass: generate code.
7201 LLVMBuilderRef entry_builder = create_builder (ctx);
7202 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7203 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7204 emit_entry_bb (ctx, entry_builder);
7206 // Make landing pads first
7207 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7209 if (ctx->llvm_only) {
7210 size_t group_index = 0;
7211 while (group_index < cfg->header->num_clauses) {
7213 size_t cursor = group_index;
7214 while (cursor < cfg->header->num_clauses &&
7215 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7216 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7221 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7222 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7223 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7225 group_index = cursor;
7229 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7230 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7232 // Prune unreachable mono BBs.
7233 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7236 process_bb (ctx, bb);
7240 g_hash_table_destroy (ctx->exc_meta);
7242 mono_memory_barrier ();
7244 /* Add incoming phi values */
7245 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7246 GSList *l, *ins_list;
7248 ins_list = bblocks [bb->block_num].phi_nodes;
7250 for (l = ins_list; l; l = l->next) {
7251 PhiNode *node = (PhiNode*)l->data;
7252 MonoInst *phi = node->phi;
7253 int sreg1 = node->sreg;
7254 LLVMBasicBlockRef in_bb;
7259 in_bb = get_end_bb (ctx, node->in_bb);
7261 if (ctx->unreachable [node->in_bb->block_num])
7264 if (!values [sreg1]) {
7265 /* Can happen with values in EH clauses */
7266 set_failure (ctx, "incoming phi sreg1");
7270 if (phi->opcode == OP_VPHI) {
7271 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7272 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7274 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7275 set_failure (ctx, "incoming phi arg type mismatch");
7278 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7279 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7284 /* Nullify empty phi instructions */
7285 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7286 GSList *l, *ins_list;
7288 ins_list = bblocks [bb->block_num].phi_nodes;
7290 for (l = ins_list; l; l = l->next) {
7291 PhiNode *node = (PhiNode*)l->data;
7292 MonoInst *phi = node->phi;
7293 LLVMValueRef phi_ins = values [phi->dreg];
7296 /* Already removed */
7299 if (LLVMCountIncoming (phi_ins) == 0) {
7300 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7301 LLVMInstructionEraseFromParent (phi_ins);
7302 values [phi->dreg] = NULL;
7307 /* Create the SWITCH statements for ENDFINALLY instructions */
7308 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7309 BBInfo *info = &bblocks [bb->block_num];
7311 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7312 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7313 GSList *bb_list = info->call_handler_return_bbs;
7315 GSList *bb_list_iter;
7317 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7318 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7324 /* Initialize the method if needed */
7325 if (cfg->compile_aot && ctx->llvm_only) {
7326 // FIXME: Add more shared got entries
7327 ctx->builder = create_builder (ctx);
7328 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7330 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7332 // FIXME: beforefieldinit
7334 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7335 * in load_method ().
7337 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7339 * linkonce methods shouldn't have initialization,
7340 * because they might belong to assemblies which
7341 * haven't been loaded yet.
7343 g_assert (!ctx->is_linkonce);
7344 emit_init_method (ctx);
7346 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7350 if (cfg->llvm_only) {
7351 GHashTableIter iter;
7353 GSList *callers, *l, *l2;
7356 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7357 * We can't do this earlier, as it contains llvm instructions which can be
7358 * freed if compilation fails.
7359 * FIXME: Get rid of this when all methods can be llvm compiled.
7361 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7362 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7363 for (l = callers; l; l = l->next) {
7364 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7365 l2 = g_slist_prepend (l2, l->data);
7366 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7371 if (cfg->verbose_level > 1)
7372 mono_llvm_dump_value (method);
7374 if (cfg->compile_aot && !cfg->llvm_only)
7375 mark_as_used (ctx->module, method);
7377 if (!cfg->llvm_only) {
7378 LLVMValueRef md_args [16];
7379 LLVMValueRef md_node;
7382 if (cfg->compile_aot)
7383 method_index = mono_aot_get_method_index (cfg->orig_method);
7386 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7387 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7388 md_node = LLVMMDNode (md_args, 2);
7389 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7390 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7393 if (cfg->compile_aot) {
7394 /* Don't generate native code, keep the LLVM IR */
7395 if (cfg->verbose_level)
7396 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7398 #if LLVM_API_VERSION < 100
7399 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7400 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7401 g_assert (err == 0);
7404 //LLVMVerifyFunction(method, 0);
7405 #if LLVM_API_VERSION > 100
7406 MonoDomain *domain = mono_domain_get ();
7407 MonoJitDomainInfo *domain_info;
7408 int nvars = g_hash_table_size (ctx->jit_callees);
7409 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7410 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7411 GHashTableIter iter;
7417 * Compute the addresses of the LLVM globals pointing to the
7418 * methods called by the current method. Pass it to the trampoline
7419 * code so it can update them after their corresponding method was
7422 g_hash_table_iter_init (&iter, ctx->jit_callees);
7424 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7425 callee_vars [i ++] = var;
7427 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7429 decode_llvm_eh_info (ctx, eh_frame);
7431 mono_domain_lock (domain);
7432 domain_info = domain_jit_info (domain);
7433 if (!domain_info->llvm_jit_callees)
7434 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7435 g_hash_table_iter_init (&iter, ctx->jit_callees);
7437 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7438 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7439 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7440 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7443 mono_domain_unlock (domain);
7445 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7447 if (cfg->verbose_level > 1)
7448 mono_llvm_dump_value (ctx->lmethod);
7450 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7452 /* Set by emit_cb */
7453 g_assert (cfg->code_len);
7457 if (ctx->module->method_to_lmethod)
7458 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7459 if (ctx->module->idx_to_lmethod)
7460 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7462 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7463 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7467 * mono_llvm_create_vars:
7469 * Same as mono_arch_create_vars () for LLVM.
7472 mono_llvm_create_vars (MonoCompile *cfg)
7474 MonoMethodSignature *sig;
7476 sig = mono_method_signature (cfg->method);
7477 if (cfg->gsharedvt && cfg->llvm_only) {
7478 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7479 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7480 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7481 printf ("vret_addr = ");
7482 mono_print_ins (cfg->vret_addr);
7486 mono_arch_create_vars (cfg);
7491 * mono_llvm_emit_call:
7493 * Same as mono_arch_emit_call () for LLVM.
7496 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7499 MonoMethodSignature *sig;
7500 int i, n, stack_size;
7505 sig = call->signature;
7506 n = sig->param_count + sig->hasthis;
7508 call->cinfo = get_llvm_call_info (cfg, sig);
7510 if (cfg->disable_llvm)
7513 if (sig->call_convention == MONO_CALL_VARARG) {
7514 cfg->exception_message = g_strdup ("varargs");
7515 cfg->disable_llvm = TRUE;
7518 for (i = 0; i < n; ++i) {
7521 ainfo = call->cinfo->args + i;
7523 in = call->args [i];
7525 /* Simply remember the arguments */
7526 switch (ainfo->storage) {
7527 case LLVMArgNormal: {
7528 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7531 opcode = mono_type_to_regmove (cfg, t);
7532 if (opcode == OP_FMOVE) {
7533 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7534 ins->dreg = mono_alloc_freg (cfg);
7535 } else if (opcode == OP_LMOVE) {
7536 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7537 ins->dreg = mono_alloc_lreg (cfg);
7538 } else if (opcode == OP_RMOVE) {
7539 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7540 ins->dreg = mono_alloc_freg (cfg);
7542 MONO_INST_NEW (cfg, ins, OP_MOVE);
7543 ins->dreg = mono_alloc_ireg (cfg);
7545 ins->sreg1 = in->dreg;
7548 case LLVMArgVtypeByVal:
7549 case LLVMArgVtypeByRef:
7550 case LLVMArgVtypeInReg:
7551 case LLVMArgVtypeAsScalar:
7552 case LLVMArgAsIArgs:
7553 case LLVMArgAsFpArgs:
7554 case LLVMArgGsharedvtVariable:
7555 case LLVMArgGsharedvtFixed:
7556 case LLVMArgGsharedvtFixedVtype:
7557 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7558 ins->dreg = mono_alloc_ireg (cfg);
7559 ins->sreg1 = in->dreg;
7560 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7561 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7562 ins->inst_vtype = ainfo->type;
7563 ins->klass = mono_class_from_mono_type (ainfo->type);
7566 cfg->exception_message = g_strdup ("ainfo->storage");
7567 cfg->disable_llvm = TRUE;
7571 if (!cfg->disable_llvm) {
7572 MONO_ADD_INS (cfg->cbb, ins);
7573 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7578 static unsigned char*
7579 alloc_cb (LLVMValueRef function, int size)
7583 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7587 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7589 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7594 emitted_cb (LLVMValueRef function, void *start, void *end)
7598 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7600 cfg->code_len = (guint8*)end - (guint8*)start;
7604 exception_cb (void *data)
7607 MonoJitExceptionInfo *ei;
7608 guint32 ei_len, i, j, nested_len, nindex;
7609 gpointer *type_info;
7610 int this_reg, this_offset;
7612 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7616 * data points to a DWARF FDE structure, convert it to our unwind format and
7618 * An alternative would be to save it directly, and modify our unwinder to work
7621 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);
7622 if (cfg->verbose_level > 1)
7623 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7625 /* Count nested clauses */
7627 for (i = 0; i < ei_len; ++i) {
7628 gint32 cindex1 = *(gint32*)type_info [i];
7629 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7631 for (j = 0; j < cfg->header->num_clauses; ++j) {
7633 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7635 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7641 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7642 cfg->llvm_ex_info_len = ei_len + nested_len;
7643 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7644 /* Fill the rest of the information from the type info */
7645 for (i = 0; i < ei_len; ++i) {
7646 gint32 clause_index = *(gint32*)type_info [i];
7647 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7649 cfg->llvm_ex_info [i].flags = clause->flags;
7650 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7651 cfg->llvm_ex_info [i].clause_index = clause_index;
7655 * For nested clauses, the LLVM produced exception info associates the try interval with
7656 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7657 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7658 * and everything else from the nested clause.
7661 for (i = 0; i < ei_len; ++i) {
7662 gint32 cindex1 = *(gint32*)type_info [i];
7663 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7665 for (j = 0; j < cfg->header->num_clauses; ++j) {
7667 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7668 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7670 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7671 /* clause1 is the nested clause */
7672 nested_ei = &cfg->llvm_ex_info [i];
7673 nesting_ei = &cfg->llvm_ex_info [nindex];
7676 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7678 nesting_ei->flags = clause2->flags;
7679 nesting_ei->data.catch_class = clause2->data.catch_class;
7680 nesting_ei->clause_index = cindex2;
7684 g_assert (nindex == ei_len + nested_len);
7685 cfg->llvm_this_reg = this_reg;
7686 cfg->llvm_this_offset = this_offset;
7688 /* type_info [i] is cfg mempool allocated, no need to free it */
7694 #if LLVM_API_VERSION > 100
7696 * decode_llvm_eh_info:
7698 * Decode the EH table emitted by llvm in jit mode, and store
7699 * the result into cfg.
7702 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7704 MonoCompile *cfg = ctx->cfg;
7707 MonoLLVMFDEInfo info;
7708 MonoJitExceptionInfo *ei;
7709 guint8 *p = eh_frame;
7710 int version, fde_count, fde_offset;
7711 guint32 ei_len, i, nested_len;
7712 gpointer *type_info;
7716 * Decode the one element EH table emitted by the MonoException class
7720 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7723 g_assert (version == 3);
7726 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7728 fde_count = *(guint32*)p;
7732 g_assert (fde_count <= 2);
7734 /* The first entry is the real method */
7735 g_assert (table [0] == 1);
7736 fde_offset = table [1];
7737 table += fde_count * 2;
7739 cfg->code_len = table [0];
7740 fde_len = table [1] - fde_offset;
7743 fde = (guint8*)eh_frame + fde_offset;
7744 cie = (guint8*)table;
7746 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7748 cfg->encoded_unwind_ops = info.unw_info;
7749 cfg->encoded_unwind_ops_len = info.unw_info_len;
7750 if (cfg->verbose_level > 1)
7751 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7752 if (info.this_reg != -1) {
7753 cfg->llvm_this_reg = info.this_reg;
7754 cfg->llvm_this_offset = info.this_offset;
7758 ei_len = info.ex_info_len;
7759 type_info = info.type_info;
7761 // Nested clauses are currently disabled
7764 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7765 cfg->llvm_ex_info_len = ei_len + nested_len;
7766 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7767 /* Fill the rest of the information from the type info */
7768 for (i = 0; i < ei_len; ++i) {
7769 gint32 clause_index = *(gint32*)type_info [i];
7770 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7772 cfg->llvm_ex_info [i].flags = clause->flags;
7773 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7774 cfg->llvm_ex_info [i].clause_index = clause_index;
7780 dlsym_cb (const char *name, void **symbol)
7786 if (!strcmp (name, "__bzero")) {
7787 *symbol = (void*)bzero;
7789 current = mono_dl_open (NULL, 0, NULL);
7792 err = mono_dl_symbol (current, name, symbol);
7794 mono_dl_close (current);
7796 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7797 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7803 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7805 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7809 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7811 LLVMTypeRef param_types [4];
7813 param_types [0] = param_type1;
7814 param_types [1] = param_type2;
7816 AddFunc (module, name, ret_type, param_types, 2);
7822 INTRINS_SADD_OVF_I32,
7823 INTRINS_UADD_OVF_I32,
7824 INTRINS_SSUB_OVF_I32,
7825 INTRINS_USUB_OVF_I32,
7826 INTRINS_SMUL_OVF_I32,
7827 INTRINS_UMUL_OVF_I32,
7828 INTRINS_SADD_OVF_I64,
7829 INTRINS_UADD_OVF_I64,
7830 INTRINS_SSUB_OVF_I64,
7831 INTRINS_USUB_OVF_I64,
7832 INTRINS_SMUL_OVF_I64,
7833 INTRINS_UMUL_OVF_I64,
7840 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7841 INTRINS_SSE_PMOVMSKB,
7842 INTRINS_SSE_PSRLI_W,
7843 INTRINS_SSE_PSRAI_W,
7844 INTRINS_SSE_PSLLI_W,
7845 INTRINS_SSE_PSRLI_D,
7846 INTRINS_SSE_PSRAI_D,
7847 INTRINS_SSE_PSLLI_D,
7848 INTRINS_SSE_PSRLI_Q,
7849 INTRINS_SSE_PSLLI_Q,
7850 INTRINS_SSE_SQRT_PD,
7851 INTRINS_SSE_SQRT_PS,
7852 INTRINS_SSE_RSQRT_PS,
7854 INTRINS_SSE_CVTTPD2DQ,
7855 INTRINS_SSE_CVTTPS2DQ,
7856 INTRINS_SSE_CVTDQ2PD,
7857 INTRINS_SSE_CVTDQ2PS,
7858 INTRINS_SSE_CVTPD2DQ,
7859 INTRINS_SSE_CVTPS2DQ,
7860 INTRINS_SSE_CVTPD2PS,
7861 INTRINS_SSE_CVTPS2PD,
7864 INTRINS_SSE_PACKSSWB,
7865 INTRINS_SSE_PACKUSWB,
7866 INTRINS_SSE_PACKSSDW,
7867 INTRINS_SSE_PACKUSDW,
7872 INTRINS_SSE_ADDSUBPS,
7877 INTRINS_SSE_ADDSUBPD,
7880 INTRINS_SSE_PADDUSW,
7881 INTRINS_SSE_PSUBUSW,
7887 INTRINS_SSE_PADDUSB,
7888 INTRINS_SSE_PSUBUSB,
7901 static IntrinsicDesc intrinsics[] = {
7902 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7903 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7904 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7905 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7906 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7907 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7908 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7909 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7910 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7911 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7912 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7913 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7914 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7915 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7916 {INTRINS_SIN, "llvm.sin.f64"},
7917 {INTRINS_COS, "llvm.cos.f64"},
7918 {INTRINS_SQRT, "llvm.sqrt.f64"},
7919 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7920 {INTRINS_FABS, "fabs"},
7921 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7922 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7923 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7924 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7925 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7926 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7927 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7928 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7929 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7930 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7931 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7932 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7933 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7934 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7935 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7936 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7937 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7938 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7939 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7940 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7941 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7942 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7943 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7944 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7945 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7946 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7947 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7948 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7949 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7950 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7951 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7952 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7953 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7954 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7955 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7956 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7957 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7958 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7959 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7960 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7961 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7962 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7963 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7964 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7965 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7966 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7967 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7968 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7969 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7970 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7971 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7972 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7973 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7974 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7979 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7981 LLVMTypeRef ret_type = type_to_simd_type (type);
7982 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7986 add_intrinsic (LLVMModuleRef module, int id)
7989 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7990 LLVMTypeRef ret_type, arg_types [16];
7993 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7997 case INTRINS_MEMSET: {
7998 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8000 AddFunc (module, name, LLVMVoidType (), params, 5);
8003 case INTRINS_MEMCPY: {
8004 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8006 AddFunc (module, name, LLVMVoidType (), params, 5);
8009 case INTRINS_SADD_OVF_I32:
8010 case INTRINS_UADD_OVF_I32:
8011 case INTRINS_SSUB_OVF_I32:
8012 case INTRINS_USUB_OVF_I32:
8013 case INTRINS_SMUL_OVF_I32:
8014 case INTRINS_UMUL_OVF_I32: {
8015 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
8016 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
8017 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
8019 AddFunc (module, name, ret_type, params, 2);
8022 case INTRINS_SADD_OVF_I64:
8023 case INTRINS_UADD_OVF_I64:
8024 case INTRINS_SSUB_OVF_I64:
8025 case INTRINS_USUB_OVF_I64:
8026 case INTRINS_SMUL_OVF_I64:
8027 case INTRINS_UMUL_OVF_I64: {
8028 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8029 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8030 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8032 AddFunc (module, name, ret_type, params, 2);
8038 case INTRINS_FABS: {
8039 LLVMTypeRef params [] = { LLVMDoubleType () };
8041 AddFunc (module, name, LLVMDoubleType (), params, 1);
8044 case INTRINS_EXPECT_I8:
8045 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8047 case INTRINS_EXPECT_I1:
8048 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8050 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8051 case INTRINS_SSE_PMOVMSKB:
8053 ret_type = LLVMInt32Type ();
8054 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8055 AddFunc (module, name, ret_type, arg_types, 1);
8057 case INTRINS_SSE_PSRLI_W:
8058 case INTRINS_SSE_PSRAI_W:
8059 case INTRINS_SSE_PSLLI_W:
8061 ret_type = type_to_simd_type (MONO_TYPE_I2);
8062 arg_types [0] = ret_type;
8063 arg_types [1] = LLVMInt32Type ();
8064 AddFunc (module, name, ret_type, arg_types, 2);
8066 case INTRINS_SSE_PSRLI_D:
8067 case INTRINS_SSE_PSRAI_D:
8068 case INTRINS_SSE_PSLLI_D:
8069 ret_type = type_to_simd_type (MONO_TYPE_I4);
8070 arg_types [0] = ret_type;
8071 arg_types [1] = LLVMInt32Type ();
8072 AddFunc (module, name, ret_type, arg_types, 2);
8074 case INTRINS_SSE_PSRLI_Q:
8075 case INTRINS_SSE_PSLLI_Q:
8076 ret_type = type_to_simd_type (MONO_TYPE_I8);
8077 arg_types [0] = ret_type;
8078 arg_types [1] = LLVMInt32Type ();
8079 AddFunc (module, name, ret_type, arg_types, 2);
8081 case INTRINS_SSE_SQRT_PD:
8083 ret_type = type_to_simd_type (MONO_TYPE_R8);
8084 arg_types [0] = ret_type;
8085 AddFunc (module, name, ret_type, arg_types, 1);
8087 case INTRINS_SSE_SQRT_PS:
8088 ret_type = type_to_simd_type (MONO_TYPE_R4);
8089 arg_types [0] = ret_type;
8090 AddFunc (module, name, ret_type, arg_types, 1);
8092 case INTRINS_SSE_RSQRT_PS:
8093 ret_type = type_to_simd_type (MONO_TYPE_R4);
8094 arg_types [0] = ret_type;
8095 AddFunc (module, name, ret_type, arg_types, 1);
8097 case INTRINS_SSE_RCP_PS:
8098 ret_type = type_to_simd_type (MONO_TYPE_R4);
8099 arg_types [0] = ret_type;
8100 AddFunc (module, name, ret_type, arg_types, 1);
8102 case INTRINS_SSE_CVTTPD2DQ:
8103 ret_type = type_to_simd_type (MONO_TYPE_I4);
8104 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8105 AddFunc (module, name, ret_type, arg_types, 1);
8107 case INTRINS_SSE_CVTTPS2DQ:
8108 ret_type = type_to_simd_type (MONO_TYPE_I4);
8109 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8110 AddFunc (module, name, ret_type, arg_types, 1);
8112 case INTRINS_SSE_CVTDQ2PD:
8113 /* Conversion ops */
8114 ret_type = type_to_simd_type (MONO_TYPE_R8);
8115 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8116 AddFunc (module, name, ret_type, arg_types, 1);
8118 case INTRINS_SSE_CVTDQ2PS:
8119 ret_type = type_to_simd_type (MONO_TYPE_R4);
8120 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8121 AddFunc (module, name, ret_type, arg_types, 1);
8123 case INTRINS_SSE_CVTPD2DQ:
8124 ret_type = type_to_simd_type (MONO_TYPE_I4);
8125 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8126 AddFunc (module, name, ret_type, arg_types, 1);
8128 case INTRINS_SSE_CVTPS2DQ:
8129 ret_type = type_to_simd_type (MONO_TYPE_I4);
8130 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8131 AddFunc (module, name, ret_type, arg_types, 1);
8133 case INTRINS_SSE_CVTPD2PS:
8134 ret_type = type_to_simd_type (MONO_TYPE_R4);
8135 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8136 AddFunc (module, name, ret_type, arg_types, 1);
8138 case INTRINS_SSE_CVTPS2PD:
8139 ret_type = type_to_simd_type (MONO_TYPE_R8);
8140 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8141 AddFunc (module, name, ret_type, arg_types, 1);
8143 case INTRINS_SSE_CMPPD:
8145 ret_type = type_to_simd_type (MONO_TYPE_R8);
8146 arg_types [0] = ret_type;
8147 arg_types [1] = ret_type;
8148 arg_types [2] = LLVMInt8Type ();
8149 AddFunc (module, name, ret_type, arg_types, 3);
8151 case INTRINS_SSE_CMPPS:
8152 ret_type = type_to_simd_type (MONO_TYPE_R4);
8153 arg_types [0] = ret_type;
8154 arg_types [1] = ret_type;
8155 arg_types [2] = LLVMInt8Type ();
8156 AddFunc (module, name, ret_type, arg_types, 3);
8158 case INTRINS_SSE_PACKSSWB:
8159 case INTRINS_SSE_PACKUSWB:
8160 case INTRINS_SSE_PACKSSDW:
8162 ret_type = type_to_simd_type (MONO_TYPE_I1);
8163 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8164 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8165 AddFunc (module, name, ret_type, arg_types, 2);
8167 case INTRINS_SSE_PACKUSDW:
8168 ret_type = type_to_simd_type (MONO_TYPE_I2);
8169 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8170 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8171 AddFunc (module, name, ret_type, arg_types, 2);
8173 /* SSE Binary ops */
8174 case INTRINS_SSE_PADDSW:
8175 case INTRINS_SSE_PSUBSW:
8176 case INTRINS_SSE_PADDUSW:
8177 case INTRINS_SSE_PSUBUSW:
8178 case INTRINS_SSE_PAVGW:
8179 case INTRINS_SSE_PMULHW:
8180 case INTRINS_SSE_PMULHU:
8181 add_sse_binary (module, name, MONO_TYPE_I2);
8183 case INTRINS_SSE_MINPS:
8184 case INTRINS_SSE_MAXPS:
8185 case INTRINS_SSE_HADDPS:
8186 case INTRINS_SSE_HSUBPS:
8187 case INTRINS_SSE_ADDSUBPS:
8188 add_sse_binary (module, name, MONO_TYPE_R4);
8190 case INTRINS_SSE_MINPD:
8191 case INTRINS_SSE_MAXPD:
8192 case INTRINS_SSE_HADDPD:
8193 case INTRINS_SSE_HSUBPD:
8194 case INTRINS_SSE_ADDSUBPD:
8195 add_sse_binary (module, name, MONO_TYPE_R8);
8197 case INTRINS_SE_PADDSB:
8198 case INTRINS_SSE_PSUBSB:
8199 case INTRINS_SSE_PADDUSB:
8200 case INTRINS_SSE_PSUBUSB:
8201 case INTRINS_SSE_PAVGB:
8202 add_sse_binary (module, name, MONO_TYPE_I1);
8204 case INTRINS_SSE_PAUSE:
8205 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8207 case INTRINS_SSE_DPPS:
8208 ret_type = type_to_simd_type (MONO_TYPE_R4);
8209 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8210 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8211 arg_types [2] = LLVMInt32Type ();
8212 AddFunc (module, name, ret_type, arg_types, 3);
8216 g_assert_not_reached ();
8222 get_intrinsic (EmitContext *ctx, const char *name)
8224 #if LLVM_API_VERSION > 100
8228 * Every method is emitted into its own module so
8229 * we can add intrinsics on demand.
8231 res = LLVMGetNamedFunction (ctx->lmodule, name);
8235 /* No locking needed */
8236 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8239 printf ("%s\n", name);
8240 g_assert (id != -1);
8241 add_intrinsic (ctx->lmodule, id);
8242 res = LLVMGetNamedFunction (ctx->lmodule, name);
8250 res = LLVMGetNamedFunction (ctx->lmodule, name);
8257 add_intrinsics (LLVMModuleRef module)
8261 /* Emit declarations of instrinsics */
8263 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8264 * type doesn't seem to do any locking.
8266 for (i = 0; i < INTRINS_NUM; ++i)
8267 add_intrinsic (module, i);
8271 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8273 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8276 /* Load/Store intrinsics */
8278 LLVMTypeRef arg_types [5];
8282 for (i = 1; i <= 8; i *= 2) {
8283 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8284 arg_types [1] = LLVMInt32Type ();
8285 arg_types [2] = LLVMInt1Type ();
8286 arg_types [3] = LLVMInt32Type ();
8287 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8288 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8290 arg_types [0] = LLVMIntType (i * 8);
8291 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8292 arg_types [2] = LLVMInt32Type ();
8293 arg_types [3] = LLVMInt1Type ();
8294 arg_types [4] = LLVMInt32Type ();
8295 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8296 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8302 add_types (MonoLLVMModule *module)
8304 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8308 mono_llvm_init (void)
8313 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8315 h = g_hash_table_new (NULL, NULL);
8316 for (i = 0; i < INTRINS_NUM; ++i)
8317 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8318 intrins_id_to_name = h;
8320 h = g_hash_table_new (g_str_hash, g_str_equal);
8321 for (i = 0; i < INTRINS_NUM; ++i)
8322 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8323 intrins_name_to_id = h;
8327 init_jit_module (MonoDomain *domain)
8329 MonoJitDomainInfo *dinfo;
8330 MonoLLVMModule *module;
8333 dinfo = domain_jit_info (domain);
8334 if (dinfo->llvm_module)
8337 mono_loader_lock ();
8339 if (dinfo->llvm_module) {
8340 mono_loader_unlock ();
8344 module = g_new0 (MonoLLVMModule, 1);
8346 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8347 module->lmodule = LLVMModuleCreateWithName (name);
8348 module->context = LLVMGetGlobalContext ();
8350 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8352 add_intrinsics (module->lmodule);
8355 module->llvm_types = g_hash_table_new (NULL, NULL);
8357 #if LLVM_API_VERSION < 100
8358 MonoJitICallInfo *info;
8360 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8362 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8365 mono_memory_barrier ();
8367 dinfo->llvm_module = module;
8369 mono_loader_unlock ();
8373 mono_llvm_cleanup (void)
8375 MonoLLVMModule *module = &aot_module;
8377 if (module->lmodule)
8378 LLVMDisposeModule (module->lmodule);
8380 if (module->context)
8381 LLVMContextDispose (module->context);
8385 mono_llvm_free_domain_info (MonoDomain *domain)
8387 MonoJitDomainInfo *info = domain_jit_info (domain);
8388 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8394 if (module->llvm_types)
8395 g_hash_table_destroy (module->llvm_types);
8397 mono_llvm_dispose_ee (module->mono_ee);
8399 if (module->bb_names) {
8400 for (i = 0; i < module->bb_names_len; ++i)
8401 g_free (module->bb_names [i]);
8402 g_free (module->bb_names);
8404 //LLVMDisposeModule (module->module);
8408 info->llvm_module = NULL;
8412 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8414 MonoLLVMModule *module = &aot_module;
8416 /* Delete previous module */
8417 if (module->plt_entries)
8418 g_hash_table_destroy (module->plt_entries);
8419 if (module->lmodule)
8420 LLVMDisposeModule (module->lmodule);
8422 memset (module, 0, sizeof (aot_module));
8424 module->lmodule = LLVMModuleCreateWithName ("aot");
8425 module->assembly = assembly;
8426 module->global_prefix = g_strdup (global_prefix);
8427 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8428 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8429 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8430 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8431 module->external_symbols = TRUE;
8432 module->emit_dwarf = emit_dwarf;
8433 module->static_link = static_link;
8434 module->llvm_only = llvm_only;
8435 /* The first few entries are reserved */
8436 module->max_got_offset = 16;
8437 module->context = LLVMGetGlobalContext ();
8440 /* clang ignores our debug info because it has an invalid version */
8441 module->emit_dwarf = FALSE;
8443 add_intrinsics (module->lmodule);
8446 #if LLVM_API_VERSION > 100
8447 if (module->emit_dwarf) {
8448 char *dir, *build_info, *s, *cu_name;
8450 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8453 dir = g_strdup (".");
8454 build_info = mono_get_runtime_build_info ();
8455 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8456 cu_name = g_path_get_basename (assembly->image->name);
8457 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8459 g_free (build_info);
8466 * We couldn't compute the type of the LLVM global representing the got because
8467 * its size is only known after all the methods have been emitted. So create
8468 * a dummy variable, and replace all uses it with the real got variable when
8469 * its size is known in mono_llvm_emit_aot_module ().
8472 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8474 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8475 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8478 /* Add initialization array */
8480 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8482 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8483 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8487 emit_init_icall_wrappers (module);
8489 emit_llvm_code_start (module);
8491 /* Add a dummy personality function */
8492 if (!use_debug_personality) {
8493 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8494 LLVMSetLinkage (personality, LLVMExternalLinkage);
8495 mark_as_used (module, personality);
8498 /* Add a reference to the c++ exception we throw/catch */
8500 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8501 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8502 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8503 mono_llvm_set_is_constant (module->sentinel_exception);
8506 module->llvm_types = g_hash_table_new (NULL, NULL);
8507 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8508 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8509 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8510 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8511 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8512 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8513 module->method_to_callers = g_hash_table_new (NULL, NULL);
8517 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8520 LLVMValueRef res, *vals;
8522 vals = g_new0 (LLVMValueRef, nvalues);
8523 for (i = 0; i < nvalues; ++i)
8524 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8525 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8531 llvm_array_from_bytes (guint8 *values, int nvalues)
8534 LLVMValueRef res, *vals;
8536 vals = g_new0 (LLVMValueRef, nvalues);
8537 for (i = 0; i < nvalues; ++i)
8538 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8539 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8544 * mono_llvm_emit_aot_file_info:
8546 * Emit the MonoAotFileInfo structure.
8547 * Same as emit_aot_file_info () in aot-compiler.c.
8550 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8552 MonoLLVMModule *module = &aot_module;
8554 /* Save these for later */
8555 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8556 module->has_jitted_code = has_jitted_code;
8560 * mono_llvm_emit_aot_data:
8562 * Emit the binary data DATA pointed to by symbol SYMBOL.
8565 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8567 MonoLLVMModule *module = &aot_module;
8571 type = LLVMArrayType (LLVMInt8Type (), data_len);
8572 d = LLVMAddGlobal (module->lmodule, type, symbol);
8573 LLVMSetVisibility (d, LLVMHiddenVisibility);
8574 LLVMSetLinkage (d, LLVMInternalLinkage);
8575 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8576 mono_llvm_set_is_constant (d);
8579 /* Add a reference to a global defined in JITted code */
8581 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8586 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8587 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8593 emit_aot_file_info (MonoLLVMModule *module)
8595 LLVMTypeRef file_info_type;
8596 LLVMTypeRef *eltypes, eltype;
8597 LLVMValueRef info_var;
8598 LLVMValueRef *fields;
8599 int i, nfields, tindex;
8600 MonoAotFileInfo *info;
8601 LLVMModuleRef lmodule = module->lmodule;
8603 info = &module->aot_info;
8605 /* Create an LLVM type to represent MonoAotFileInfo */
8606 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8607 eltypes = g_new (LLVMTypeRef, nfields);
8609 eltypes [tindex ++] = LLVMInt32Type ();
8610 eltypes [tindex ++] = LLVMInt32Type ();
8612 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8613 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8615 for (i = 0; i < 15; ++i)
8616 eltypes [tindex ++] = LLVMInt32Type ();
8618 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8619 for (i = 0; i < 4; ++i)
8620 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8621 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8622 g_assert (tindex == nfields);
8623 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8624 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8626 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8627 if (module->static_link) {
8628 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8629 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8631 fields = g_new (LLVMValueRef, nfields);
8633 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8634 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8638 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8639 * for symbols defined in the .s file emitted by the aot compiler.
8641 eltype = eltypes [tindex];
8642 if (module->llvm_only)
8643 fields [tindex ++] = LLVMConstNull (eltype);
8645 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8646 fields [tindex ++] = module->got_var;
8647 /* llc defines this directly */
8648 if (!module->llvm_only) {
8649 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8650 fields [tindex ++] = LLVMConstNull (eltype);
8651 fields [tindex ++] = LLVMConstNull (eltype);
8653 fields [tindex ++] = LLVMConstNull (eltype);
8654 fields [tindex ++] = module->get_method;
8655 fields [tindex ++] = module->get_unbox_tramp;
8657 if (module->has_jitted_code) {
8658 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8659 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8661 fields [tindex ++] = LLVMConstNull (eltype);
8662 fields [tindex ++] = LLVMConstNull (eltype);
8664 if (!module->llvm_only)
8665 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8667 fields [tindex ++] = LLVMConstNull (eltype);
8668 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8669 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8670 fields [tindex ++] = LLVMConstNull (eltype);
8672 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8673 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8674 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8675 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8676 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8677 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8678 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8679 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8680 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8681 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8683 /* Not needed (mem_end) */
8684 fields [tindex ++] = LLVMConstNull (eltype);
8685 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8686 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8687 if (info->trampoline_size [0]) {
8688 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8689 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8690 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8691 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8693 fields [tindex ++] = LLVMConstNull (eltype);
8694 fields [tindex ++] = LLVMConstNull (eltype);
8695 fields [tindex ++] = LLVMConstNull (eltype);
8696 fields [tindex ++] = LLVMConstNull (eltype);
8698 if (module->static_link && !module->llvm_only)
8699 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8701 fields [tindex ++] = LLVMConstNull (eltype);
8702 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8703 if (!module->llvm_only) {
8704 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8705 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8706 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8707 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8708 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8709 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8711 fields [tindex ++] = LLVMConstNull (eltype);
8712 fields [tindex ++] = LLVMConstNull (eltype);
8713 fields [tindex ++] = LLVMConstNull (eltype);
8714 fields [tindex ++] = LLVMConstNull (eltype);
8715 fields [tindex ++] = LLVMConstNull (eltype);
8716 fields [tindex ++] = LLVMConstNull (eltype);
8719 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8720 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8723 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8724 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8725 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8726 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8727 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8728 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8729 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8730 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8731 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8732 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8733 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8734 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8735 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8736 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8737 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8739 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8740 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8741 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8742 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8743 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8745 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8746 g_assert (tindex == nfields);
8748 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8750 if (module->static_link) {
8754 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8755 /* Get rid of characters which cannot occur in symbols */
8757 for (p = s; *p; ++p) {
8758 if (!(isalnum (*p) || *p == '_'))
8761 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8763 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8764 LLVMSetLinkage (var, LLVMExternalLinkage);
8769 * Emit the aot module into the LLVM bitcode file FILENAME.
8772 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8774 LLVMTypeRef got_type, inited_type;
8775 LLVMValueRef real_got, real_inited;
8776 MonoLLVMModule *module = &aot_module;
8778 emit_llvm_code_end (module);
8781 * Create the real got variable and replace all uses of the dummy variable with
8784 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8785 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8786 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8787 if (module->external_symbols) {
8788 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8789 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8791 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8793 mono_llvm_replace_uses_of (module->got_var, real_got);
8795 mark_as_used (&aot_module, real_got);
8797 /* Delete the dummy got so it doesn't become a global */
8798 LLVMDeleteGlobal (module->got_var);
8799 module->got_var = real_got;
8802 * Same for the init_var
8804 if (module->llvm_only) {
8805 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8806 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8807 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8808 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8809 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8810 LLVMDeleteGlobal (module->inited_var);
8813 if (module->llvm_only) {
8814 emit_get_method (&aot_module);
8815 emit_get_unbox_tramp (&aot_module);
8818 emit_llvm_used (&aot_module);
8819 emit_dbg_info (&aot_module, filename, cu_name);
8820 emit_aot_file_info (&aot_module);
8823 * Replace GOT entries for directly callable methods with the methods themselves.
8824 * It would be easier to implement this by predefining all methods before compiling
8825 * their bodies, but that couldn't handle the case when a method fails to compile
8828 if (module->llvm_only) {
8829 GHashTableIter iter;
8831 GSList *callers, *l;
8833 g_hash_table_iter_init (&iter, module->method_to_callers);
8834 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8835 LLVMValueRef lmethod;
8837 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8840 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8842 for (l = callers; l; l = l->next) {
8843 LLVMValueRef caller = (LLVMValueRef)l->data;
8845 mono_llvm_replace_uses_of (caller, lmethod);
8851 /* Replace PLT entries for directly callable methods with the methods themselves */
8853 GHashTableIter iter;
8855 LLVMValueRef callee;
8857 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8858 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8859 if (mono_aot_is_direct_callable (ji)) {
8860 LLVMValueRef lmethod;
8862 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8863 /* The types might not match because the caller might pass an rgctx */
8864 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8865 mono_llvm_replace_uses_of (callee, lmethod);
8866 mono_aot_mark_unused_llvm_plt_entry (ji);
8876 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8877 printf ("%s\n", verifier_err);
8878 g_assert_not_reached ();
8883 LLVMWriteBitcodeToFile (module->lmodule, filename);
8888 md_string (const char *s)
8890 return LLVMMDString (s, strlen (s));
8893 /* Debugging support */
8896 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8898 LLVMModuleRef lmodule = module->lmodule;
8899 LLVMValueRef args [16], ver;
8902 * This can only be enabled when LLVM code is emitted into a separate object
8903 * file, since the AOT compiler also emits dwarf info,
8904 * and the abbrev indexes will not be correct since llvm has added its own
8907 if (!module->emit_dwarf)
8910 #if LLVM_API_VERSION > 100
8911 mono_llvm_di_builder_finalize (module->di_builder);
8913 LLVMValueRef cu_args [16], cu;
8915 char *build_info, *s, *dir;
8918 * Emit dwarf info in the form of LLVM metadata. There is some
8919 * out-of-date documentation at:
8920 * http://llvm.org/docs/SourceLevelDebugging.html
8921 * but most of this was gathered from the llvm and
8926 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8927 /* CU name/compilation dir */
8928 dir = g_path_get_dirname (filename);
8929 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8930 args [1] = LLVMMDString (dir, strlen (dir));
8931 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8934 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8936 build_info = mono_get_runtime_build_info ();
8937 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8938 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8939 g_free (build_info);
8941 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8943 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8944 /* Runtime version */
8945 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8947 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8948 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8950 if (module->subprogram_mds) {
8954 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8955 for (i = 0; i < module->subprogram_mds->len; ++i)
8956 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8957 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8959 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8962 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8963 /* Imported modules */
8964 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8966 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8967 /* DebugEmissionKind = FullDebug */
8968 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8969 cu = LLVMMDNode (cu_args, n_cuargs);
8970 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8973 #if LLVM_API_VERSION > 100
8974 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8975 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8976 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8977 ver = LLVMMDNode (args, 3);
8978 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8980 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8981 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8982 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8983 ver = LLVMMDNode (args, 3);
8984 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8986 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8987 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8988 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8989 ver = LLVMMDNode (args, 3);
8990 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8992 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8993 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8994 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8995 ver = LLVMMDNode (args, 3);
8996 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9001 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9003 MonoLLVMModule *module = ctx->module;
9004 MonoDebugMethodInfo *minfo = ctx->minfo;
9005 char *source_file, *dir, *filename;
9006 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9007 MonoSymSeqPoint *sym_seq_points;
9013 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9015 source_file = g_strdup ("<unknown>");
9016 dir = g_path_get_dirname (source_file);
9017 filename = g_path_get_basename (source_file);
9019 #if LLVM_API_VERSION > 100
9020 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);
9023 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9024 args [0] = md_string (filename);
9025 args [1] = md_string (dir);
9026 ctx_args [1] = LLVMMDNode (args, 2);
9027 ctx_md = LLVMMDNode (ctx_args, 2);
9029 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9030 type_args [1] = NULL;
9031 type_args [2] = NULL;
9032 type_args [3] = LLVMMDString ("", 0);
9033 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9034 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9035 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9036 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9037 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9038 type_args [9] = NULL;
9039 type_args [10] = NULL;
9040 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9041 type_args [12] = NULL;
9042 type_args [13] = NULL;
9043 type_args [14] = NULL;
9044 type_md = LLVMMDNode (type_args, 14);
9046 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9047 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9048 /* Source directory + file pair */
9049 args [0] = md_string (filename);
9050 args [1] = md_string (dir);
9051 md_args [1] = LLVMMDNode (args ,2);
9052 md_args [2] = ctx_md;
9053 md_args [3] = md_string (cfg->method->name);
9054 md_args [4] = md_string (name);
9055 md_args [5] = md_string (name);
9058 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9060 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9062 md_args [7] = type_md;
9064 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9066 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9068 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9069 /* Index into a virtual function */
9070 md_args [11] = NULL;
9071 md_args [12] = NULL;
9073 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9075 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9076 /* Pointer to LLVM function */
9077 md_args [15] = method;
9078 /* Function template parameter */
9079 md_args [16] = NULL;
9080 /* Function declaration descriptor */
9081 md_args [17] = NULL;
9082 /* List of function variables */
9083 md_args [18] = LLVMMDNode (args, 0);
9085 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9086 md = LLVMMDNode (md_args, 20);
9088 if (!module->subprogram_mds)
9089 module->subprogram_mds = g_ptr_array_new ();
9090 g_ptr_array_add (module->subprogram_mds, md);
9094 g_free (source_file);
9095 g_free (sym_seq_points);
9101 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9103 MonoCompile *cfg = ctx->cfg;
9105 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9106 MonoDebugSourceLocation *loc;
9107 LLVMValueRef loc_md;
9109 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9112 #if LLVM_API_VERSION > 100
9113 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9114 mono_llvm_di_set_location (builder, loc_md);
9116 LLVMValueRef md_args [16];
9120 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9121 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9122 md_args [nmd_args ++] = ctx->dbg_md;
9123 md_args [nmd_args ++] = NULL;
9124 loc_md = LLVMMDNode (md_args, nmd_args);
9125 LLVMSetCurrentDebugLocation (builder, loc_md);
9127 mono_debug_symfile_free_location (loc);
9133 default_mono_llvm_unhandled_exception (void)
9135 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9136 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9138 mono_unhandled_exception (target);
9139 mono_invoke_unhandled_exception_hook (target);
9140 g_assert_not_reached ();
9145 - Emit LLVM IR from the mono IR using the LLVM C API.
9146 - The original arch specific code remains, so we can fall back to it if we run
9147 into something we can't handle.
9151 A partial list of issues:
9152 - Handling of opcodes which can throw exceptions.
9154 In the mono JIT, these are implemented using code like this:
9161 push throw_pos - method
9162 call <exception trampoline>
9164 The problematic part is push throw_pos - method, which cannot be represented
9165 in the LLVM IR, since it does not support label values.
9166 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9167 be implemented in JIT mode ?
9168 -> a possible but slower implementation would use the normal exception
9169 throwing code but it would need to control the placement of the throw code
9170 (it needs to be exactly after the compare+branch).
9171 -> perhaps add a PC offset intrinsics ?
9173 - efficient implementation of .ovf opcodes.
9175 These are currently implemented as:
9176 <ins which sets the condition codes>
9179 Some overflow opcodes are now supported by LLVM SVN.
9181 - exception handling, unwinding.
9182 - SSA is disabled for methods with exception handlers
9183 - How to obtain unwind info for LLVM compiled methods ?
9184 -> this is now solved by converting the unwind info generated by LLVM
9186 - LLVM uses the c++ exception handling framework, while we use our home grown
9187 code, and couldn't use the c++ one:
9188 - its not supported under VC++, other exotic platforms.
9189 - it might be impossible to support filter clauses with it.
9193 The trampolines need a predictable call sequence, since they need to disasm
9194 the calling code to obtain register numbers / offsets.
9196 LLVM currently generates this code in non-JIT mode:
9197 mov -0x98(%rax),%eax
9199 Here, the vtable pointer is lost.
9200 -> solution: use one vtable trampoline per class.
9202 - passing/receiving the IMT pointer/RGCTX.
9203 -> solution: pass them as normal arguments ?
9207 LLVM does not allow the specification of argument registers etc. This means
9208 that all calls are made according to the platform ABI.
9210 - passing/receiving vtypes.
9212 Vtypes passed/received in registers are handled by the front end by using
9213 a signature with scalar arguments, and loading the parts of the vtype into those
9216 Vtypes passed on the stack are handled using the 'byval' attribute.
9220 Supported though alloca, we need to emit the load/store code.
9224 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9225 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9226 This is made easier because the IR is already in SSA form.
9227 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9228 types are frequently used incorrectly.
9233 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9234 it with the file containing the methods emitted by the JIT and the AOT data
9238 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9239 * - each bblock should end with a branch
9240 * - setting the return value, making cfg->ret non-volatile
9241 * - avoid some transformations in the JIT which make it harder for us to generate
9243 * - use pointer types to help optimizations.
9246 #else /* DISABLE_JIT */
9249 mono_llvm_cleanup (void)
9254 mono_llvm_free_domain_info (MonoDomain *domain)
9259 mono_llvm_init (void)
9264 default_mono_llvm_unhandled_exception (void)
9268 #endif /* DISABLE_JIT */