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);
362 printf ("%s\n", klass->name);
368 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
369 static inline G_GNUC_UNUSED LLVMTypeRef
370 type_to_simd_type (int type)
374 return LLVMVectorType (LLVMInt8Type (), 16);
376 return LLVMVectorType (LLVMInt16Type (), 8);
378 return LLVMVectorType (LLVMInt32Type (), 4);
380 return LLVMVectorType (LLVMInt64Type (), 2);
382 return LLVMVectorType (LLVMDoubleType (), 2);
384 return LLVMVectorType (LLVMFloatType (), 4);
386 g_assert_not_reached ();
392 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
394 int i, size, nfields, esize;
395 LLVMTypeRef *eltypes;
400 t = &klass->byval_arg;
402 if (mini_type_is_hfa (t, &nfields, &esize)) {
404 * This is needed on arm64 where HFAs are returned in
408 eltypes = g_new (LLVMTypeRef, size);
409 for (i = 0; i < size; ++i)
410 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
412 size = get_vtype_size (t);
414 eltypes = g_new (LLVMTypeRef, size);
415 for (i = 0; i < size; ++i)
416 eltypes [i] = LLVMInt8Type ();
419 name = mono_type_full_name (&klass->byval_arg);
420 ltype = LLVMStructCreateNamed (module->context, name);
421 LLVMStructSetBody (ltype, eltypes, size, FALSE);
431 * Return the LLVM type corresponding to T.
434 type_to_llvm_type (EmitContext *ctx, MonoType *t)
436 t = mini_get_underlying_type (t);
440 return LLVMVoidType ();
442 return LLVMInt8Type ();
444 return LLVMInt16Type ();
446 return LLVMInt32Type ();
448 return LLVMInt8Type ();
450 return LLVMInt16Type ();
452 return LLVMInt32Type ();
453 case MONO_TYPE_BOOLEAN:
454 return LLVMInt8Type ();
457 return LLVMInt64Type ();
459 return LLVMInt16Type ();
461 return LLVMFloatType ();
463 return LLVMDoubleType ();
466 return IntPtrType ();
467 case MONO_TYPE_OBJECT:
468 case MONO_TYPE_CLASS:
469 case MONO_TYPE_ARRAY:
470 case MONO_TYPE_SZARRAY:
471 case MONO_TYPE_STRING:
473 return ObjRefType ();
476 /* Because of generic sharing */
477 return ObjRefType ();
478 case MONO_TYPE_GENERICINST:
479 if (!mono_type_generic_inst_is_valuetype (t))
480 return ObjRefType ();
482 case MONO_TYPE_VALUETYPE:
483 case MONO_TYPE_TYPEDBYREF: {
487 klass = mono_class_from_mono_type (t);
489 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
490 return simd_class_to_llvm_type (ctx, klass);
493 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
495 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
497 ltype = create_llvm_type_for_type (ctx->module, klass);
498 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
504 printf ("X: %d\n", t->type);
505 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
506 ctx->cfg->disable_llvm = TRUE;
514 * Return whenever T is an unsigned int type.
517 type_is_unsigned (EmitContext *ctx, MonoType *t)
519 t = mini_get_underlying_type (t);
535 * type_to_llvm_arg_type:
537 * Same as type_to_llvm_type, but treat i8/i16 as i32.
540 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
542 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
544 if (ctx->cfg->llvm_only)
548 * This works on all abis except arm64/ios which passes multiple
549 * arguments in one stack slot.
552 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
554 * LLVM generates code which only sets the lower bits, while JITted
555 * code expects all the bits to be set.
557 ptype = LLVMInt32Type ();
565 * llvm_type_to_stack_type:
567 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
570 static G_GNUC_UNUSED LLVMTypeRef
571 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
575 if (type == LLVMInt8Type ())
576 return LLVMInt32Type ();
577 else if (type == LLVMInt16Type ())
578 return LLVMInt32Type ();
579 else if (!cfg->r4fp && type == LLVMFloatType ())
580 return LLVMDoubleType ();
586 * regtype_to_llvm_type:
588 * Return the LLVM type corresponding to the regtype C used in instruction
592 regtype_to_llvm_type (char c)
596 return LLVMInt32Type ();
598 return LLVMInt64Type ();
600 return LLVMDoubleType ();
609 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
612 op_to_llvm_type (int opcode)
617 return LLVMInt8Type ();
620 return LLVMInt8Type ();
623 return LLVMInt16Type ();
626 return LLVMInt16Type ();
629 return LLVMInt32Type ();
632 return LLVMInt32Type ();
634 return LLVMInt64Type ();
636 return LLVMFloatType ();
638 return LLVMDoubleType ();
640 return LLVMInt64Type ();
642 return LLVMInt32Type ();
644 return LLVMInt64Type ();
649 return LLVMInt8Type ();
654 return LLVMInt16Type ();
656 return LLVMInt32Type ();
659 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
666 return LLVMInt32Type ();
673 return LLVMInt64Type ();
675 printf ("%s\n", mono_inst_name (opcode));
676 g_assert_not_reached ();
681 #define CLAUSE_START(clause) ((clause)->try_offset)
682 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
685 * load_store_to_llvm_type:
687 * Return the size/sign/zero extension corresponding to the load/store opcode
691 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
697 case OP_LOADI1_MEMBASE:
698 case OP_STOREI1_MEMBASE_REG:
699 case OP_STOREI1_MEMBASE_IMM:
700 case OP_ATOMIC_LOAD_I1:
701 case OP_ATOMIC_STORE_I1:
704 return LLVMInt8Type ();
705 case OP_LOADU1_MEMBASE:
707 case OP_ATOMIC_LOAD_U1:
708 case OP_ATOMIC_STORE_U1:
711 return LLVMInt8Type ();
712 case OP_LOADI2_MEMBASE:
713 case OP_STOREI2_MEMBASE_REG:
714 case OP_STOREI2_MEMBASE_IMM:
715 case OP_ATOMIC_LOAD_I2:
716 case OP_ATOMIC_STORE_I2:
719 return LLVMInt16Type ();
720 case OP_LOADU2_MEMBASE:
722 case OP_ATOMIC_LOAD_U2:
723 case OP_ATOMIC_STORE_U2:
726 return LLVMInt16Type ();
727 case OP_LOADI4_MEMBASE:
728 case OP_LOADU4_MEMBASE:
731 case OP_STOREI4_MEMBASE_REG:
732 case OP_STOREI4_MEMBASE_IMM:
733 case OP_ATOMIC_LOAD_I4:
734 case OP_ATOMIC_STORE_I4:
735 case OP_ATOMIC_LOAD_U4:
736 case OP_ATOMIC_STORE_U4:
738 return LLVMInt32Type ();
739 case OP_LOADI8_MEMBASE:
741 case OP_STOREI8_MEMBASE_REG:
742 case OP_STOREI8_MEMBASE_IMM:
743 case OP_ATOMIC_LOAD_I8:
744 case OP_ATOMIC_STORE_I8:
745 case OP_ATOMIC_LOAD_U8:
746 case OP_ATOMIC_STORE_U8:
748 return LLVMInt64Type ();
749 case OP_LOADR4_MEMBASE:
750 case OP_STORER4_MEMBASE_REG:
751 case OP_ATOMIC_LOAD_R4:
752 case OP_ATOMIC_STORE_R4:
754 return LLVMFloatType ();
755 case OP_LOADR8_MEMBASE:
756 case OP_STORER8_MEMBASE_REG:
757 case OP_ATOMIC_LOAD_R8:
758 case OP_ATOMIC_STORE_R8:
760 return LLVMDoubleType ();
761 case OP_LOAD_MEMBASE:
763 case OP_STORE_MEMBASE_REG:
764 case OP_STORE_MEMBASE_IMM:
765 *size = sizeof (gpointer);
766 return IntPtrType ();
768 g_assert_not_reached ();
776 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
779 ovf_op_to_intrins (int opcode)
783 return "llvm.sadd.with.overflow.i32";
785 return "llvm.uadd.with.overflow.i32";
787 return "llvm.ssub.with.overflow.i32";
789 return "llvm.usub.with.overflow.i32";
791 return "llvm.smul.with.overflow.i32";
793 return "llvm.umul.with.overflow.i32";
795 return "llvm.sadd.with.overflow.i64";
797 return "llvm.uadd.with.overflow.i64";
799 return "llvm.ssub.with.overflow.i64";
801 return "llvm.usub.with.overflow.i64";
803 return "llvm.smul.with.overflow.i64";
805 return "llvm.umul.with.overflow.i64";
807 g_assert_not_reached ();
813 simd_op_to_intrins (int opcode)
816 #if defined(TARGET_X86) || defined(TARGET_AMD64)
818 return "llvm.x86.sse2.min.pd";
820 return "llvm.x86.sse.min.ps";
822 return "llvm.x86.sse2.max.pd";
824 return "llvm.x86.sse.max.ps";
826 return "llvm.x86.sse3.hadd.pd";
828 return "llvm.x86.sse3.hadd.ps";
830 return "llvm.x86.sse3.hsub.pd";
832 return "llvm.x86.sse3.hsub.ps";
834 return "llvm.x86.sse3.addsub.ps";
836 return "llvm.x86.sse3.addsub.pd";
837 case OP_EXTRACT_MASK:
838 return "llvm.x86.sse2.pmovmskb.128";
841 return "llvm.x86.sse2.psrli.w";
844 return "llvm.x86.sse2.psrli.d";
847 return "llvm.x86.sse2.psrli.q";
850 return "llvm.x86.sse2.pslli.w";
853 return "llvm.x86.sse2.pslli.d";
856 return "llvm.x86.sse2.pslli.q";
859 return "llvm.x86.sse2.psrai.w";
862 return "llvm.x86.sse2.psrai.d";
864 return "llvm.x86.sse2.padds.b";
866 return "llvm.x86.sse2.padds.w";
868 return "llvm.x86.sse2.psubs.b";
870 return "llvm.x86.sse2.psubs.w";
871 case OP_PADDB_SAT_UN:
872 return "llvm.x86.sse2.paddus.b";
873 case OP_PADDW_SAT_UN:
874 return "llvm.x86.sse2.paddus.w";
875 case OP_PSUBB_SAT_UN:
876 return "llvm.x86.sse2.psubus.b";
877 case OP_PSUBW_SAT_UN:
878 return "llvm.x86.sse2.psubus.w";
880 return "llvm.x86.sse2.pavg.b";
882 return "llvm.x86.sse2.pavg.w";
884 return "llvm.x86.sse.sqrt.ps";
886 return "llvm.x86.sse2.sqrt.pd";
888 return "llvm.x86.sse.rsqrt.ps";
890 return "llvm.x86.sse.rcp.ps";
892 return "llvm.x86.sse2.cvtdq2pd";
894 return "llvm.x86.sse2.cvtdq2ps";
896 return "llvm.x86.sse2.cvtpd2dq";
898 return "llvm.x86.sse2.cvtps2dq";
900 return "llvm.x86.sse2.cvtpd2ps";
902 return "llvm.x86.sse2.cvtps2pd";
904 return "llvm.x86.sse2.cvttpd2dq";
906 return "llvm.x86.sse2.cvttps2dq";
908 return "llvm.x86.sse2.packsswb.128";
910 return "llvm.x86.sse2.packssdw.128";
912 return "llvm.x86.sse2.packuswb.128";
914 return "llvm.x86.sse41.packusdw";
916 return "llvm.x86.sse2.pmulh.w";
917 case OP_PMULW_HIGH_UN:
918 return "llvm.x86.sse2.pmulhu.w";
921 g_assert_not_reached ();
927 simd_op_to_llvm_type (int opcode)
929 #if defined(TARGET_X86) || defined(TARGET_AMD64)
933 return type_to_simd_type (MONO_TYPE_R8);
936 return type_to_simd_type (MONO_TYPE_I8);
939 return type_to_simd_type (MONO_TYPE_I4);
944 return type_to_simd_type (MONO_TYPE_I2);
948 return type_to_simd_type (MONO_TYPE_I1);
950 return type_to_simd_type (MONO_TYPE_R4);
953 return type_to_simd_type (MONO_TYPE_I4);
957 return type_to_simd_type (MONO_TYPE_R8);
961 return type_to_simd_type (MONO_TYPE_R4);
962 case OP_EXTRACT_MASK:
963 return type_to_simd_type (MONO_TYPE_I1);
969 return type_to_simd_type (MONO_TYPE_R4);
972 return type_to_simd_type (MONO_TYPE_R8);
974 g_assert_not_reached ();
985 * Return the LLVM basic block corresponding to BB.
987 static LLVMBasicBlockRef
988 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
990 char bb_name_buf [128];
993 if (ctx->bblocks [bb->block_num].bblock == NULL) {
994 if (bb->flags & BB_EXCEPTION_HANDLER) {
995 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
996 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
997 bb_name = bb_name_buf;
998 } else if (bb->block_num < 256) {
999 if (!ctx->module->bb_names) {
1000 ctx->module->bb_names_len = 256;
1001 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1003 if (!ctx->module->bb_names [bb->block_num]) {
1006 n = g_strdup_printf ("BB%d", bb->block_num);
1007 mono_memory_barrier ();
1008 ctx->module->bb_names [bb->block_num] = n;
1010 bb_name = ctx->module->bb_names [bb->block_num];
1012 sprintf (bb_name_buf, "BB%d", bb->block_num);
1013 bb_name = bb_name_buf;
1016 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1017 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1020 return ctx->bblocks [bb->block_num].bblock;
1026 * Return the last LLVM bblock corresponding to BB.
1027 * This might not be equal to the bb returned by get_bb () since we need to generate
1028 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1030 static LLVMBasicBlockRef
1031 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1034 return ctx->bblocks [bb->block_num].end_bblock;
1037 static LLVMBasicBlockRef
1038 gen_bb (EmitContext *ctx, const char *prefix)
1042 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1043 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1049 * Return the target of the patch identified by TYPE and TARGET.
1052 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1058 memset (&ji, 0, sizeof (ji));
1060 ji.data.target = target;
1062 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1063 mono_error_assert_ok (&error);
1071 * Emit code to convert the LLVM value V to DTYPE.
1074 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1076 LLVMTypeRef stype = LLVMTypeOf (v);
1078 if (stype != dtype) {
1079 gboolean ext = FALSE;
1082 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1084 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1086 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1090 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1092 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1093 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1096 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1097 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1098 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1099 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1100 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1101 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1102 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1103 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1105 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1106 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1107 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1108 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1109 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1110 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1112 if (mono_arch_is_soft_float ()) {
1113 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1114 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1115 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1116 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1119 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1120 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1123 LLVMDumpValue (LLVMConstNull (dtype));
1124 g_assert_not_reached ();
1132 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1134 return convert_full (ctx, v, dtype, FALSE);
1138 * emit_volatile_load:
1140 * If vreg is volatile, emit a load from its address.
1143 emit_volatile_load (EmitContext *ctx, int vreg)
1149 // FIXME: This hack is required because we pass the rgctx in a callee saved
1150 // register on arm64 (x15), and llvm might keep the value in that register
1151 // even through the register is marked as 'reserved' inside llvm.
1152 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1153 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1155 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1157 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1159 t = ctx->vreg_cli_types [vreg];
1160 if (t && !t->byref) {
1162 * Might have to zero extend since llvm doesn't have
1165 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1166 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1167 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1168 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1169 else if (t->type == MONO_TYPE_U8)
1170 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1177 * emit_volatile_store:
1179 * If VREG is volatile, emit a store from its value to its address.
1182 emit_volatile_store (EmitContext *ctx, int vreg)
1184 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1186 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1187 g_assert (ctx->addresses [vreg]);
1188 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1193 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1195 LLVMTypeRef ret_type;
1196 LLVMTypeRef *param_types = NULL;
1201 rtype = mini_get_underlying_type (sig->ret);
1202 ret_type = type_to_llvm_type (ctx, rtype);
1206 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1210 param_types [pindex ++] = ThisType ();
1211 for (i = 0; i < sig->param_count; ++i)
1212 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1214 if (!ctx_ok (ctx)) {
1215 g_free (param_types);
1219 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1220 g_free (param_types);
1226 * sig_to_llvm_sig_full:
1228 * Return the LLVM signature corresponding to the mono signature SIG using the
1229 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1232 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1234 LLVMTypeRef ret_type;
1235 LLVMTypeRef *param_types = NULL;
1237 int i, j, pindex, vret_arg_pindex = 0;
1238 gboolean vretaddr = FALSE;
1242 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1244 rtype = mini_get_underlying_type (sig->ret);
1245 ret_type = type_to_llvm_type (ctx, rtype);
1249 switch (cinfo->ret.storage) {
1250 case LLVMArgVtypeInReg:
1251 /* LLVM models this by returning an aggregate value */
1252 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1253 LLVMTypeRef members [2];
1255 members [0] = IntPtrType ();
1256 ret_type = LLVMStructType (members, 1, FALSE);
1257 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1259 ret_type = LLVMVoidType ();
1260 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1261 LLVMTypeRef members [2];
1263 members [0] = IntPtrType ();
1264 members [1] = IntPtrType ();
1265 ret_type = LLVMStructType (members, 2, FALSE);
1267 g_assert_not_reached ();
1270 case LLVMArgVtypeByVal:
1271 /* Vtype returned normally by val */
1273 case LLVMArgVtypeAsScalar: {
1274 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1275 /* LLVM models this by returning an int */
1276 if (size < SIZEOF_VOID_P) {
1277 g_assert (cinfo->ret.nslots == 1);
1278 ret_type = LLVMIntType (size * 8);
1280 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1281 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1285 case LLVMArgAsIArgs:
1286 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1288 case LLVMArgFpStruct: {
1289 /* Vtype returned as a fp struct */
1290 LLVMTypeRef members [16];
1292 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1293 for (i = 0; i < cinfo->ret.nslots; ++i)
1294 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1295 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1298 case LLVMArgVtypeByRef:
1299 /* Vtype returned using a hidden argument */
1300 ret_type = LLVMVoidType ();
1302 case LLVMArgVtypeRetAddr:
1303 case LLVMArgGsharedvtFixed:
1304 case LLVMArgGsharedvtFixedVtype:
1305 case LLVMArgGsharedvtVariable:
1307 ret_type = LLVMVoidType ();
1313 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1315 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1317 * Has to be the first argument because of the sret argument attribute
1318 * FIXME: This might conflict with passing 'this' as the first argument, but
1319 * this is only used on arm64 which has a dedicated struct return register.
1321 cinfo->vret_arg_pindex = pindex;
1322 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1323 if (!ctx_ok (ctx)) {
1324 g_free (param_types);
1327 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1330 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1331 cinfo->rgctx_arg_pindex = pindex;
1332 param_types [pindex] = ctx->module->ptr_type;
1335 if (cinfo->imt_arg) {
1336 cinfo->imt_arg_pindex = pindex;
1337 param_types [pindex] = ctx->module->ptr_type;
1341 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1342 vret_arg_pindex = pindex;
1343 if (cinfo->vret_arg_index == 1) {
1344 /* Add the slots consumed by the first argument */
1345 LLVMArgInfo *ainfo = &cinfo->args [0];
1346 switch (ainfo->storage) {
1347 case LLVMArgVtypeInReg:
1348 for (j = 0; j < 2; ++j) {
1349 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1358 cinfo->vret_arg_pindex = vret_arg_pindex;
1361 if (vretaddr && vret_arg_pindex == pindex)
1362 param_types [pindex ++] = IntPtrType ();
1364 cinfo->this_arg_pindex = pindex;
1365 param_types [pindex ++] = ThisType ();
1366 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1368 if (vretaddr && vret_arg_pindex == pindex)
1369 param_types [pindex ++] = IntPtrType ();
1370 for (i = 0; i < sig->param_count; ++i) {
1371 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1373 if (vretaddr && vret_arg_pindex == pindex)
1374 param_types [pindex ++] = IntPtrType ();
1375 ainfo->pindex = pindex;
1377 switch (ainfo->storage) {
1378 case LLVMArgVtypeInReg:
1379 for (j = 0; j < 2; ++j) {
1380 switch (ainfo->pair_storage [j]) {
1382 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1387 g_assert_not_reached ();
1391 case LLVMArgVtypeByVal:
1392 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1395 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1398 case LLVMArgAsIArgs:
1399 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1402 case LLVMArgVtypeByRef:
1403 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1406 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1409 case LLVMArgAsFpArgs: {
1412 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1413 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1414 param_types [pindex ++] = LLVMDoubleType ();
1415 for (j = 0; j < ainfo->nslots; ++j)
1416 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1419 case LLVMArgVtypeAsScalar:
1420 g_assert_not_reached ();
1422 case LLVMArgGsharedvtFixed:
1423 case LLVMArgGsharedvtFixedVtype:
1424 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1426 case LLVMArgGsharedvtVariable:
1427 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1430 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1434 if (!ctx_ok (ctx)) {
1435 g_free (param_types);
1438 if (vretaddr && vret_arg_pindex == pindex)
1439 param_types [pindex ++] = IntPtrType ();
1440 if (ctx->llvm_only && cinfo->rgctx_arg) {
1441 /* Pass the rgctx as the last argument */
1442 cinfo->rgctx_arg_pindex = pindex;
1443 param_types [pindex] = ctx->module->ptr_type;
1447 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1448 g_free (param_types);
1454 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1456 return sig_to_llvm_sig_full (ctx, sig, NULL);
1460 * LLVMFunctionType1:
1462 * Create an LLVM function type from the arguments.
1464 static G_GNUC_UNUSED LLVMTypeRef
1465 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1468 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1472 * LLVMFunctionType1:
1474 * Create an LLVM function type from the arguments.
1476 static G_GNUC_UNUSED LLVMTypeRef
1477 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1478 LLVMTypeRef ParamType1,
1481 LLVMTypeRef param_types [1];
1483 param_types [0] = ParamType1;
1485 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1489 * LLVMFunctionType2:
1491 * Create an LLVM function type from the arguments.
1493 static G_GNUC_UNUSED LLVMTypeRef
1494 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1495 LLVMTypeRef ParamType1,
1496 LLVMTypeRef ParamType2,
1499 LLVMTypeRef param_types [2];
1501 param_types [0] = ParamType1;
1502 param_types [1] = ParamType2;
1504 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1508 * LLVMFunctionType3:
1510 * Create an LLVM function type from the arguments.
1512 static G_GNUC_UNUSED LLVMTypeRef
1513 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1514 LLVMTypeRef ParamType1,
1515 LLVMTypeRef ParamType2,
1516 LLVMTypeRef ParamType3,
1519 LLVMTypeRef param_types [3];
1521 param_types [0] = ParamType1;
1522 param_types [1] = ParamType2;
1523 param_types [2] = ParamType3;
1525 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1528 static G_GNUC_UNUSED LLVMTypeRef
1529 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1530 LLVMTypeRef ParamType1,
1531 LLVMTypeRef ParamType2,
1532 LLVMTypeRef ParamType3,
1533 LLVMTypeRef ParamType4,
1534 LLVMTypeRef ParamType5,
1537 LLVMTypeRef param_types [5];
1539 param_types [0] = ParamType1;
1540 param_types [1] = ParamType2;
1541 param_types [2] = ParamType3;
1542 param_types [3] = ParamType4;
1543 param_types [4] = ParamType5;
1545 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1551 * Create an LLVM builder and remember it so it can be freed later.
1553 static LLVMBuilderRef
1554 create_builder (EmitContext *ctx)
1556 LLVMBuilderRef builder = LLVMCreateBuilder ();
1558 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1564 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1569 case MONO_PATCH_INFO_INTERNAL_METHOD:
1570 name = g_strdup_printf ("jit_icall_%s", data);
1572 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1573 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1574 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1578 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1586 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1590 LLVMValueRef indexes [2];
1591 LLVMValueRef got_entry_addr, load;
1592 LLVMBuilderRef builder = ctx->builder;
1597 MonoJumpInfo tmp_ji;
1599 tmp_ji.data.target = data;
1601 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1603 ji->next = cfg->patch_info;
1604 cfg->patch_info = ji;
1606 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1607 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1609 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1610 * explicitly initialize it.
1612 if (!mono_aot_is_shared_got_offset (got_offset)) {
1613 //mono_print_ji (ji);
1615 ctx->has_got_access = TRUE;
1618 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1619 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1620 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1622 name = get_aotconst_name (type, data, got_offset);
1624 load = LLVMBuildLoad (builder, got_entry_addr, "");
1625 load = convert (ctx, load, llvm_type);
1626 LLVMSetValueName (load, name ? name : "");
1628 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1631 //set_invariant_load_flag (load);
1637 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1639 return get_aotconst_typed (ctx, type, data, NULL);
1643 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1645 LLVMValueRef callee;
1647 if (ctx->llvm_only) {
1648 callee_name = mono_aot_get_direct_call_symbol (type, data);
1650 /* Directly callable */
1652 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1654 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1656 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1658 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1660 /* LLVMTypeRef's are uniqued */
1661 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1662 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1664 g_free (callee_name);
1670 * Calls are made through the GOT.
1672 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1674 MonoJumpInfo *ji = NULL;
1676 callee_name = mono_aot_get_plt_symbol (type, data);
1680 if (ctx->cfg->compile_aot)
1681 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1682 mono_add_patch_info (ctx->cfg, 0, type, data);
1685 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1687 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1689 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1691 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1694 if (ctx->cfg->compile_aot) {
1695 ji = g_new0 (MonoJumpInfo, 1);
1697 ji->data.target = data;
1699 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1707 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1709 #if LLVM_API_VERSION > 100
1710 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1711 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1712 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1713 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1716 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1717 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1723 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1725 MonoMethodHeader *header = cfg->header;
1726 MonoExceptionClause *clause;
1730 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1731 return (bb->region >> 8) - 1;
1734 for (i = 0; i < header->num_clauses; ++i) {
1735 clause = &header->clauses [i];
1737 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1744 static MonoExceptionClause *
1745 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1747 if (bb == cfg->bb_init)
1749 // Since they're sorted by nesting we just need
1750 // the first one that the bb is a member of
1751 for (int i = 0; i < cfg->header->num_clauses; i++) {
1752 MonoExceptionClause *curr = &cfg->header->clauses [i];
1754 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1762 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1764 LLVMValueRef md_arg;
1767 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1768 md_arg = LLVMMDString ("mono", 4);
1769 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1773 set_invariant_load_flag (LLVMValueRef v)
1775 LLVMValueRef md_arg;
1777 const char *flag_name;
1779 // FIXME: Cache this
1780 flag_name = "invariant.load";
1781 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1782 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1783 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1789 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1793 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1795 MonoCompile *cfg = ctx->cfg;
1796 LLVMValueRef lcall = NULL;
1797 LLVMBuilderRef builder = *builder_ref;
1798 MonoExceptionClause *clause;
1800 if (ctx->llvm_only) {
1801 clause = get_most_deep_clause (cfg, ctx, bb);
1804 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1807 * Have to use an invoke instead of a call, branching to the
1808 * handler bblock of the clause containing this bblock.
1810 intptr_t key = CLAUSE_END(clause);
1812 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1814 // FIXME: Find the one that has the lowest end bound for the right start address
1815 // FIXME: Finally + nesting
1818 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1821 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1823 builder = ctx->builder = create_builder (ctx);
1824 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1826 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1830 int clause_index = get_handler_clause (cfg, bb);
1832 if (clause_index != -1) {
1833 MonoMethodHeader *header = cfg->header;
1834 MonoExceptionClause *ec = &header->clauses [clause_index];
1835 MonoBasicBlock *tblock;
1836 LLVMBasicBlockRef ex_bb, noex_bb;
1839 * Have to use an invoke instead of a call, branching to the
1840 * handler bblock of the clause containing this bblock.
1843 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1845 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1848 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1850 ex_bb = get_bb (ctx, tblock);
1852 noex_bb = gen_bb (ctx, "NOEX_BB");
1855 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1857 builder = ctx->builder = create_builder (ctx);
1858 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1860 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1865 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1866 ctx->builder = builder;
1870 *builder_ref = ctx->builder;
1876 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1878 const char *intrins_name;
1879 LLVMValueRef args [16], res;
1880 LLVMTypeRef addr_type;
1881 gboolean use_intrinsics = TRUE;
1883 #if LLVM_API_VERSION > 100
1884 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1885 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1888 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1889 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1890 *builder_ref = ctx->builder;
1891 use_intrinsics = FALSE;
1895 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1896 LLVMAtomicOrdering ordering;
1899 case LLVM_BARRIER_NONE:
1900 ordering = LLVMAtomicOrderingNotAtomic;
1902 case LLVM_BARRIER_ACQ:
1903 ordering = LLVMAtomicOrderingAcquire;
1905 case LLVM_BARRIER_SEQ:
1906 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1909 g_assert_not_reached ();
1914 * We handle loads which can fault by calling a mono specific intrinsic
1915 * using an invoke, so they are handled properly inside try blocks.
1916 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1917 * are marked with IntrReadArgMem.
1921 intrins_name = "llvm.mono.load.i8.p0i8";
1924 intrins_name = "llvm.mono.load.i16.p0i16";
1927 intrins_name = "llvm.mono.load.i32.p0i32";
1930 intrins_name = "llvm.mono.load.i64.p0i64";
1933 g_assert_not_reached ();
1936 addr_type = LLVMTypeOf (addr);
1937 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1938 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1941 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1942 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1943 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1944 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1946 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1947 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1948 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1949 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1956 * We emit volatile loads for loads which can fault, because otherwise
1957 * LLVM will generate invalid code when encountering a load from a
1960 if (barrier != LLVM_BARRIER_NONE)
1961 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1963 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1965 /* Mark it with a custom metadata */
1968 set_metadata_flag (res, "mono.faulting.load");
1976 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1978 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
1982 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
1984 const char *intrins_name;
1985 LLVMValueRef args [16];
1986 gboolean use_intrinsics = TRUE;
1988 #if LLVM_API_VERSION > 100
1989 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1990 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1991 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1992 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1993 *builder_ref = ctx->builder;
1994 use_intrinsics = FALSE;
1998 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1999 LLVMAtomicOrdering ordering;
2002 case LLVM_BARRIER_NONE:
2003 ordering = LLVMAtomicOrderingNotAtomic;
2005 case LLVM_BARRIER_REL:
2006 ordering = LLVMAtomicOrderingRelease;
2008 case LLVM_BARRIER_SEQ:
2009 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2012 g_assert_not_reached ();
2018 intrins_name = "llvm.mono.store.i8.p0i8";
2021 intrins_name = "llvm.mono.store.i16.p0i16";
2024 intrins_name = "llvm.mono.store.i32.p0i32";
2027 intrins_name = "llvm.mono.store.i64.p0i64";
2030 g_assert_not_reached ();
2033 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2034 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2035 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2040 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2041 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2042 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2043 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2045 if (barrier != LLVM_BARRIER_NONE)
2046 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2048 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2053 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2055 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2059 * emit_cond_system_exception:
2061 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2062 * Might set the ctx exception.
2065 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2067 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2068 LLVMBuilderRef builder;
2069 MonoClass *exc_class;
2070 LLVMValueRef args [2];
2071 LLVMValueRef callee;
2072 gboolean no_pc = FALSE;
2074 if (IS_TARGET_AMD64)
2075 /* Some platforms don't require the pc argument */
2078 ex_bb = gen_bb (ctx, "EX_BB");
2080 ex2_bb = gen_bb (ctx, "EX2_BB");
2081 noex_bb = gen_bb (ctx, "NOEX_BB");
2083 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2085 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2087 /* Emit exception throwing code */
2088 ctx->builder = builder = create_builder (ctx);
2089 LLVMPositionBuilderAtEnd (builder, ex_bb);
2091 if (ctx->cfg->llvm_only) {
2092 static LLVMTypeRef sig;
2095 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2096 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2098 LLVMBuildBr (builder, ex2_bb);
2100 ctx->builder = builder = create_builder (ctx);
2101 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2103 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2104 emit_call (ctx, bb, &builder, callee, args, 1);
2105 LLVMBuildUnreachable (builder);
2107 ctx->builder = builder = create_builder (ctx);
2108 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2110 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2116 callee = ctx->module->throw_corlib_exception;
2119 const char *icall_name;
2122 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2124 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2125 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2127 if (ctx->cfg->compile_aot) {
2128 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2131 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2132 * - On x86, LLVM generated code doesn't push the arguments
2133 * - The trampoline takes the throw address as an arguments, not a pc offset.
2135 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2136 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2138 #if LLVM_API_VERSION > 100
2140 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2141 * added by emit_jit_callee ().
2143 ex2_bb = gen_bb (ctx, "EX2_BB");
2144 LLVMBuildBr (builder, ex2_bb);
2147 ctx->builder = builder = create_builder (ctx);
2148 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2150 mono_memory_barrier ();
2151 ctx->module->throw_corlib_exception = callee;
2156 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2159 * The LLVM mono branch contains changes so a block address can be passed as an
2160 * argument to a call.
2163 emit_call (ctx, bb, &builder, callee, args, 1);
2165 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2166 emit_call (ctx, bb, &builder, callee, args, 2);
2169 LLVMBuildUnreachable (builder);
2171 ctx->builder = builder = create_builder (ctx);
2172 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2174 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2181 * emit_args_to_vtype:
2183 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2186 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2188 int j, size, nslots;
2190 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2192 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2193 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2196 if (ainfo->storage == LLVMArgAsFpArgs)
2197 nslots = ainfo->nslots;
2201 for (j = 0; j < nslots; ++j) {
2202 LLVMValueRef index [2], addr, daddr;
2203 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2204 LLVMTypeRef part_type;
2206 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2209 if (ainfo->pair_storage [j] == LLVMArgNone)
2212 switch (ainfo->pair_storage [j]) {
2213 case LLVMArgInIReg: {
2214 part_type = LLVMIntType (part_size * 8);
2215 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2216 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2217 addr = LLVMBuildGEP (builder, address, index, 1, "");
2219 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2220 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2221 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2223 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2226 case LLVMArgInFPReg: {
2227 LLVMTypeRef arg_type;
2229 if (ainfo->esize == 8)
2230 arg_type = LLVMDoubleType ();
2232 arg_type = LLVMFloatType ();
2234 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2235 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2236 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2237 LLVMBuildStore (builder, args [j], addr);
2243 g_assert_not_reached ();
2246 size -= sizeof (gpointer);
2251 * emit_vtype_to_args:
2253 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2254 * into ARGS, and the number of arguments into NARGS.
2257 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2260 int j, size, nslots;
2261 LLVMTypeRef arg_type;
2263 size = get_vtype_size (t);
2265 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2266 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2268 if (ainfo->storage == LLVMArgAsFpArgs)
2269 nslots = ainfo->nslots;
2272 for (j = 0; j < nslots; ++j) {
2273 LLVMValueRef index [2], addr, daddr;
2274 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2276 if (ainfo->pair_storage [j] == LLVMArgNone)
2279 switch (ainfo->pair_storage [j]) {
2281 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2282 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2283 addr = LLVMBuildGEP (builder, address, index, 1, "");
2285 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2286 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2287 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2289 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2291 case LLVMArgInFPReg:
2292 if (ainfo->esize == 8)
2293 arg_type = LLVMDoubleType ();
2295 arg_type = LLVMFloatType ();
2296 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2297 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2298 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2299 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2304 g_assert_not_reached ();
2306 size -= sizeof (gpointer);
2313 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2316 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2317 * get executed every time control reaches them.
2319 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2321 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2322 return ctx->last_alloca;
2326 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2328 return build_alloca_llvm_type_name (ctx, t, align, "");
2332 build_alloca (EmitContext *ctx, MonoType *t)
2334 MonoClass *k = mono_class_from_mono_type (t);
2337 g_assert (!mini_is_gsharedvt_variable_type (t));
2339 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2342 align = mono_class_min_align (k);
2344 /* Sometimes align is not a power of 2 */
2345 while (mono_is_power_of_two (align) == -1)
2348 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2352 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2356 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2358 MonoCompile *cfg = ctx->cfg;
2359 LLVMBuilderRef builder = ctx->builder;
2360 LLVMValueRef offset, offset_var;
2361 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2362 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2366 g_assert (info_var);
2367 g_assert (locals_var);
2369 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2371 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2372 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2374 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2375 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2377 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2381 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2384 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2387 module->used = g_ptr_array_sized_new (16);
2388 g_ptr_array_add (module->used, global);
2392 emit_llvm_used (MonoLLVMModule *module)
2394 LLVMModuleRef lmodule = module->lmodule;
2395 LLVMTypeRef used_type;
2396 LLVMValueRef used, *used_elem;
2402 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2403 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2404 used_elem = g_new0 (LLVMValueRef, module->used->len);
2405 for (i = 0; i < module->used->len; ++i)
2406 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2407 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2408 LLVMSetLinkage (used, LLVMAppendingLinkage);
2409 LLVMSetSection (used, "llvm.metadata");
2415 * Emit a function mapping method indexes to their code
2418 emit_get_method (MonoLLVMModule *module)
2420 LLVMModuleRef lmodule = module->lmodule;
2421 LLVMValueRef func, switch_ins, m;
2422 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2423 LLVMBasicBlockRef *bbs;
2425 LLVMBuilderRef builder = LLVMCreateBuilder ();
2430 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2431 * but generating code seems safer.
2433 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2434 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2435 LLVMSetLinkage (func, LLVMExternalLinkage);
2436 LLVMSetVisibility (func, LLVMHiddenVisibility);
2437 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2438 module->get_method = func;
2440 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2443 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2444 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2445 * then we will have to find another solution.
2448 name = g_strdup_printf ("BB_CODE_START");
2449 code_start_bb = LLVMAppendBasicBlock (func, name);
2451 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2452 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2454 name = g_strdup_printf ("BB_CODE_END");
2455 code_end_bb = LLVMAppendBasicBlock (func, name);
2457 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2458 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2460 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2461 for (i = 0; i < module->max_method_idx + 1; ++i) {
2462 name = g_strdup_printf ("BB_%d", i);
2463 bb = LLVMAppendBasicBlock (func, name);
2467 LLVMPositionBuilderAtEnd (builder, bb);
2469 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2471 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2473 LLVMBuildRet (builder, LLVMConstNull (rtype));
2476 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2477 LLVMPositionBuilderAtEnd (builder, fail_bb);
2478 LLVMBuildRet (builder, LLVMConstNull (rtype));
2480 LLVMPositionBuilderAtEnd (builder, entry_bb);
2482 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2483 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2484 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2485 for (i = 0; i < module->max_method_idx + 1; ++i) {
2486 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2489 mark_as_used (module, func);
2491 LLVMDisposeBuilder (builder);
2495 * emit_get_unbox_tramp:
2497 * Emit a function mapping method indexes to their unbox trampoline
2500 emit_get_unbox_tramp (MonoLLVMModule *module)
2502 LLVMModuleRef lmodule = module->lmodule;
2503 LLVMValueRef func, switch_ins, m;
2504 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2505 LLVMBasicBlockRef *bbs;
2507 LLVMBuilderRef builder = LLVMCreateBuilder ();
2511 /* Similar to emit_get_method () */
2513 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2514 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2515 LLVMSetLinkage (func, LLVMExternalLinkage);
2516 LLVMSetVisibility (func, LLVMHiddenVisibility);
2517 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2518 module->get_unbox_tramp = func;
2520 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2522 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2523 for (i = 0; i < module->max_method_idx + 1; ++i) {
2524 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2528 name = g_strdup_printf ("BB_%d", i);
2529 bb = LLVMAppendBasicBlock (func, name);
2533 LLVMPositionBuilderAtEnd (builder, bb);
2535 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2538 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2539 LLVMPositionBuilderAtEnd (builder, fail_bb);
2540 LLVMBuildRet (builder, LLVMConstNull (rtype));
2542 LLVMPositionBuilderAtEnd (builder, entry_bb);
2544 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2545 for (i = 0; i < module->max_method_idx + 1; ++i) {
2546 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2550 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2553 mark_as_used (module, func);
2554 LLVMDisposeBuilder (builder);
2557 /* Add a function to mark the beginning of LLVM code */
2559 emit_llvm_code_start (MonoLLVMModule *module)
2561 LLVMModuleRef lmodule = module->lmodule;
2563 LLVMBasicBlockRef entry_bb;
2564 LLVMBuilderRef builder;
2566 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2567 LLVMSetLinkage (func, LLVMInternalLinkage);
2568 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2569 module->code_start = func;
2570 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2571 builder = LLVMCreateBuilder ();
2572 LLVMPositionBuilderAtEnd (builder, entry_bb);
2573 LLVMBuildRetVoid (builder);
2574 LLVMDisposeBuilder (builder);
2578 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2580 LLVMModuleRef lmodule = module->lmodule;
2581 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2582 LLVMBasicBlockRef entry_bb;
2583 LLVMBuilderRef builder;
2590 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2591 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2596 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2597 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2600 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2601 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2604 g_assert_not_reached ();
2606 LLVMSetLinkage (func, LLVMInternalLinkage);
2607 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2608 mono_llvm_set_preserveall_cc (func);
2609 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2610 builder = LLVMCreateBuilder ();
2611 LLVMPositionBuilderAtEnd (builder, entry_bb);
2614 ji = g_new0 (MonoJumpInfo, 1);
2615 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2616 ji = mono_aot_patch_info_dup (ji);
2617 got_offset = mono_aot_get_got_offset (ji);
2618 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2619 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2620 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2621 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2622 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2623 args [1] = LLVMGetParam (func, 0);
2625 args [2] = LLVMGetParam (func, 1);
2627 ji = g_new0 (MonoJumpInfo, 1);
2628 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2629 ji->data.name = icall_name;
2630 ji = mono_aot_patch_info_dup (ji);
2631 got_offset = mono_aot_get_got_offset (ji);
2632 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2633 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2634 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2635 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2636 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2637 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2638 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2640 // Set the inited flag
2641 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2642 indexes [1] = LLVMGetParam (func, 0);
2643 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2645 LLVMBuildRetVoid (builder);
2647 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2648 LLVMDisposeBuilder (builder);
2653 * Emit wrappers around the C icalls used to initialize llvm methods, to
2654 * make the calling code smaller and to enable usage of the llvm
2655 * PreserveAll calling convention.
2658 emit_init_icall_wrappers (MonoLLVMModule *module)
2660 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2661 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2662 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2663 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2667 emit_llvm_code_end (MonoLLVMModule *module)
2669 LLVMModuleRef lmodule = module->lmodule;
2671 LLVMBasicBlockRef entry_bb;
2672 LLVMBuilderRef builder;
2674 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2675 LLVMSetLinkage (func, LLVMInternalLinkage);
2676 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2677 module->code_end = func;
2678 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2679 builder = LLVMCreateBuilder ();
2680 LLVMPositionBuilderAtEnd (builder, entry_bb);
2681 LLVMBuildRetVoid (builder);
2682 LLVMDisposeBuilder (builder);
2686 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2688 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2691 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2692 need_div_check = TRUE;
2694 if (!need_div_check)
2697 switch (ins->opcode) {
2710 case OP_IDIV_UN_IMM:
2711 case OP_LDIV_UN_IMM:
2712 case OP_IREM_UN_IMM:
2713 case OP_LREM_UN_IMM: {
2715 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2716 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2718 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2719 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2722 builder = ctx->builder;
2724 /* b == -1 && a == 0x80000000 */
2726 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2727 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2728 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2730 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2731 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2734 builder = ctx->builder;
2746 * Emit code to initialize the GOT slots used by the method.
2749 emit_init_method (EmitContext *ctx)
2751 LLVMValueRef indexes [16], args [16], callee;
2752 LLVMValueRef inited_var, cmp, call;
2753 LLVMBasicBlockRef inited_bb, notinited_bb;
2754 LLVMBuilderRef builder = ctx->builder;
2755 MonoCompile *cfg = ctx->cfg;
2757 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2759 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2760 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2761 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2763 args [0] = inited_var;
2764 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2765 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2767 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2769 inited_bb = ctx->inited_bb;
2770 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2772 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2774 builder = ctx->builder = create_builder (ctx);
2775 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2778 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2779 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2780 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2781 callee = ctx->module->init_method_gshared_mrgctx;
2782 call = LLVMBuildCall (builder, callee, args, 2, "");
2783 } else if (ctx->rgctx_arg) {
2784 /* A vtable is passed as the rgctx argument */
2785 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2786 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2787 callee = ctx->module->init_method_gshared_vtable;
2788 call = LLVMBuildCall (builder, callee, args, 2, "");
2789 } else if (cfg->gshared) {
2790 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2791 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2792 callee = ctx->module->init_method_gshared_this;
2793 call = LLVMBuildCall (builder, callee, args, 2, "");
2795 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2796 callee = ctx->module->init_method;
2797 call = LLVMBuildCall (builder, callee, args, 1, "");
2801 * This enables llvm to keep arguments in their original registers/
2802 * scratch registers, since the call will not clobber them.
2804 mono_llvm_set_call_preserveall_cc (call);
2806 LLVMBuildBr (builder, inited_bb);
2807 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2809 builder = ctx->builder = create_builder (ctx);
2810 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2814 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2817 * Emit unbox trampoline using a tail call
2819 LLVMValueRef tramp, call, *args;
2820 LLVMBuilderRef builder;
2821 LLVMBasicBlockRef lbb;
2822 LLVMCallInfo *linfo;
2826 tramp_name = g_strdup_printf ("ut_%s", method_name);
2827 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2828 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2829 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2830 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2832 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2833 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2834 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2835 if (ctx->cfg->vret_addr) {
2836 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2837 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2838 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2839 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2843 lbb = LLVMAppendBasicBlock (tramp, "");
2844 builder = LLVMCreateBuilder ();
2845 LLVMPositionBuilderAtEnd (builder, lbb);
2847 nargs = LLVMCountParamTypes (method_type);
2848 args = g_new0 (LLVMValueRef, nargs);
2849 for (i = 0; i < nargs; ++i) {
2850 args [i] = LLVMGetParam (tramp, i);
2851 if (i == ctx->this_arg_pindex) {
2852 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2854 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2855 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2856 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2859 call = LLVMBuildCall (builder, method, args, nargs, "");
2860 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2861 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2862 if (linfo->ret.storage == LLVMArgVtypeByRef)
2863 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2865 // FIXME: This causes assertions in clang
2866 //mono_llvm_set_must_tail (call);
2867 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2868 LLVMBuildRetVoid (builder);
2870 LLVMBuildRet (builder, call);
2872 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2873 LLVMDisposeBuilder (builder);
2879 * Emit code to load/convert arguments.
2882 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2885 MonoCompile *cfg = ctx->cfg;
2886 MonoMethodSignature *sig = ctx->sig;
2887 LLVMCallInfo *linfo = ctx->linfo;
2891 LLVMBuilderRef old_builder = ctx->builder;
2892 ctx->builder = builder;
2894 ctx->alloca_builder = create_builder (ctx);
2897 * Handle indirect/volatile variables by allocating memory for them
2898 * using 'alloca', and storing their address in a temporary.
2900 for (i = 0; i < cfg->num_varinfo; ++i) {
2901 MonoInst *var = cfg->varinfo [i];
2904 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2905 } 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))) {
2906 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2909 /* Could be already created by an OP_VPHI */
2910 if (!ctx->addresses [var->dreg]) {
2911 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2912 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2914 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2918 names = g_new (char *, sig->param_count);
2919 mono_method_get_param_names (cfg->method, (const char **) names);
2921 for (i = 0; i < sig->param_count; ++i) {
2922 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2923 int reg = cfg->args [i + sig->hasthis]->dreg;
2926 pindex = ainfo->pindex;
2928 switch (ainfo->storage) {
2929 case LLVMArgVtypeInReg:
2930 case LLVMArgAsFpArgs: {
2931 LLVMValueRef args [8];
2934 pindex += ainfo->ndummy_fpargs;
2936 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2937 memset (args, 0, sizeof (args));
2938 if (ainfo->storage == LLVMArgVtypeInReg) {
2939 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2940 if (ainfo->pair_storage [1] != LLVMArgNone)
2941 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2943 g_assert (ainfo->nslots <= 8);
2944 for (j = 0; j < ainfo->nslots; ++j)
2945 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2947 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2949 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2951 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2952 /* Treat these as normal values */
2953 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2957 case LLVMArgVtypeByVal: {
2958 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2960 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2961 /* Treat these as normal values */
2962 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2966 case LLVMArgVtypeByRef: {
2967 /* The argument is passed by ref */
2968 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2971 case LLVMArgAsIArgs: {
2972 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2975 /* The argument is received as an array of ints, store it into the real argument */
2976 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2978 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2979 if (size < SIZEOF_VOID_P) {
2980 /* The upper bits of the registers might not be valid */
2981 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2982 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2983 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2985 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2989 case LLVMArgVtypeAsScalar:
2990 g_assert_not_reached ();
2992 case LLVMArgGsharedvtFixed: {
2993 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2994 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2997 name = g_strdup_printf ("arg_%s", names [i]);
2999 name = g_strdup_printf ("arg_%d", i);
3001 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3004 case LLVMArgGsharedvtFixedVtype: {
3005 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3008 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3010 name = g_strdup_printf ("vtype_arg_%d", i);
3012 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3013 g_assert (ctx->addresses [reg]);
3014 LLVMSetValueName (ctx->addresses [reg], name);
3015 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3018 case LLVMArgGsharedvtVariable:
3019 /* The IR treats these as variables with addresses */
3020 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3023 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));
3030 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3032 emit_volatile_store (ctx, cfg->args [0]->dreg);
3033 for (i = 0; i < sig->param_count; ++i)
3034 if (!mini_type_is_vtype (sig->params [i]))
3035 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3037 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3038 LLVMValueRef this_alloc;
3041 * The exception handling code needs the location where the this argument was
3042 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3043 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3044 * location into the LSDA.
3046 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3047 /* This volatile store will keep the alloca alive */
3048 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3050 set_metadata_flag (this_alloc, "mono.this");
3053 if (cfg->rgctx_var) {
3054 LLVMValueRef rgctx_alloc, store;
3057 * We handle the rgctx arg similarly to the this pointer.
3059 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3060 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3061 /* This volatile store will keep the alloca alive */
3062 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3064 set_metadata_flag (rgctx_alloc, "mono.this");
3067 /* Initialize the method if needed */
3068 if (cfg->compile_aot && ctx->llvm_only) {
3069 /* Emit a location for the initialization code */
3070 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3071 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3073 LLVMBuildBr (ctx->builder, ctx->init_bb);
3074 builder = ctx->builder = create_builder (ctx);
3075 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3076 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3079 /* Compute nesting between clauses */
3080 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3081 for (i = 0; i < cfg->header->num_clauses; ++i) {
3082 for (j = 0; j < cfg->header->num_clauses; ++j) {
3083 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3084 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3086 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3087 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3092 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3093 * it needs to continue normally, or return back to the exception handling system.
3095 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3099 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3102 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3103 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3104 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3106 if (bb->in_scount == 0) {
3109 sprintf (name, "finally_ind_bb%d", bb->block_num);
3110 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3111 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3113 ctx->bblocks [bb->block_num].finally_ind = val;
3115 /* Create a variable to hold the exception var */
3117 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3121 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3122 * LLVM bblock containing a landing pad causes problems for the
3123 * LLVM optimizer passes.
3125 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3126 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3128 ctx->builder = old_builder;
3132 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3134 MonoCompile *cfg = ctx->cfg;
3135 LLVMValueRef *values = ctx->values;
3136 LLVMValueRef *addresses = ctx->addresses;
3137 MonoCallInst *call = (MonoCallInst*)ins;
3138 MonoMethodSignature *sig = call->signature;
3139 LLVMValueRef callee = NULL, lcall;
3141 LLVMCallInfo *cinfo;
3145 LLVMTypeRef llvm_sig;
3147 gboolean is_virtual, calli, preserveall;
3148 LLVMBuilderRef builder = *builder_ref;
3150 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3151 set_failure (ctx, "non-default callconv");
3155 cinfo = call->cinfo;
3157 if (call->rgctx_arg_reg)
3158 cinfo->rgctx_arg = TRUE;
3159 if (call->imt_arg_reg)
3160 cinfo->imt_arg = TRUE;
3162 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3164 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3168 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);
3169 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);
3171 preserveall = FALSE;
3173 /* FIXME: Avoid creating duplicate methods */
3175 if (ins->flags & MONO_INST_HAS_METHOD) {
3179 if (cfg->compile_aot) {
3180 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3182 set_failure (ctx, "can't encode patch");
3185 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3187 * Collect instructions representing the callee into a hash so they can be replaced
3188 * by the llvm method for the callee if the callee turns out to be direct
3189 * callable. Currently this only requires it to not fail llvm compilation.
3191 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3192 l = g_slist_prepend (l, callee);
3193 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3197 static int tramp_index;
3200 name = g_strdup_printf ("tramp_%d", tramp_index);
3203 #if LLVM_API_VERSION > 100
3205 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3206 * Make all calls through a global. The address of the global will be saved in
3207 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3210 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3213 mono_create_jit_trampoline (mono_domain_get (),
3214 call->method, &error);
3215 if (!is_ok (&error)) {
3216 set_failure (ctx, mono_error_get_message (&error));
3217 mono_error_cleanup (&error);
3221 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3222 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3223 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3224 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3226 callee = LLVMBuildLoad (builder, tramp_var, "");
3229 mono_create_jit_trampoline (mono_domain_get (),
3230 call->method, &error);
3231 if (!is_ok (&error)) {
3233 set_failure (ctx, mono_error_get_message (&error));
3234 mono_error_cleanup (&error);
3238 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3241 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3246 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3247 /* LLVM miscompiles async methods */
3248 set_failure (ctx, "#13734");
3253 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3259 memset (&ji, 0, sizeof (ji));
3260 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3261 ji.data.target = info->name;
3263 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3265 if (cfg->compile_aot) {
3266 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3268 set_failure (ctx, "can't encode patch");
3272 target = (gpointer)mono_icall_get_wrapper (info);
3273 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3276 if (cfg->compile_aot) {
3278 if (cfg->abs_patches) {
3279 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3281 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3283 set_failure (ctx, "can't encode patch");
3289 set_failure (ctx, "aot");
3293 #if LLVM_API_VERSION > 100
3294 if (cfg->abs_patches) {
3295 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3299 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3300 mono_error_assert_ok (&error);
3301 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3303 g_assert_not_reached ();
3306 g_assert_not_reached ();
3309 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3311 if (cfg->abs_patches) {
3312 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3317 * FIXME: Some trampolines might have
3318 * their own calling convention on some platforms.
3320 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3321 mono_error_assert_ok (&error);
3322 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3326 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3333 int size = sizeof (gpointer);
3336 g_assert (ins->inst_offset % size == 0);
3337 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3339 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3341 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3343 if (ins->flags & MONO_INST_HAS_METHOD) {
3348 * Collect and convert arguments
3350 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3351 len = sizeof (LLVMValueRef) * nargs;
3352 args = (LLVMValueRef*)alloca (len);
3353 memset (args, 0, len);
3354 l = call->out_ireg_args;
3356 if (call->rgctx_arg_reg) {
3357 g_assert (values [call->rgctx_arg_reg]);
3358 g_assert (cinfo->rgctx_arg_pindex < nargs);
3360 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3361 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3362 * it using a volatile load.
3365 if (!ctx->imt_rgctx_loc)
3366 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3367 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3368 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3370 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3373 if (call->imt_arg_reg) {
3374 g_assert (!ctx->llvm_only);
3375 g_assert (values [call->imt_arg_reg]);
3376 g_assert (cinfo->imt_arg_pindex < nargs);
3378 if (!ctx->imt_rgctx_loc)
3379 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3380 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3381 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3383 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3386 switch (cinfo->ret.storage) {
3387 case LLVMArgGsharedvtVariable: {
3388 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3390 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3391 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3393 g_assert (addresses [call->inst.dreg]);
3394 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3400 if (!addresses [call->inst.dreg])
3401 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3402 g_assert (cinfo->vret_arg_pindex < nargs);
3403 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3404 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3406 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3412 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3413 * use the real callee for argument type conversion.
3415 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3416 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3417 LLVMGetParamTypes (callee_type, param_types);
3419 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3422 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3424 pindex = ainfo->pindex;
3426 regpair = (guint32)(gssize)(l->data);
3427 reg = regpair & 0xffffff;
3428 args [pindex] = values [reg];
3429 switch (ainfo->storage) {
3430 case LLVMArgVtypeInReg:
3431 case LLVMArgAsFpArgs: {
3435 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3436 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3437 pindex += ainfo->ndummy_fpargs;
3439 g_assert (addresses [reg]);
3440 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3444 // FIXME: Get rid of the VMOVE
3447 case LLVMArgVtypeByVal:
3448 g_assert (addresses [reg]);
3449 args [pindex] = addresses [reg];
3451 case LLVMArgVtypeByRef: {
3452 g_assert (addresses [reg]);
3453 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3456 case LLVMArgAsIArgs:
3457 g_assert (addresses [reg]);
3458 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3460 case LLVMArgVtypeAsScalar:
3461 g_assert_not_reached ();
3463 case LLVMArgGsharedvtFixed:
3464 case LLVMArgGsharedvtFixedVtype:
3465 g_assert (addresses [reg]);
3466 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3468 case LLVMArgGsharedvtVariable:
3469 g_assert (addresses [reg]);
3470 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3473 g_assert (args [pindex]);
3474 if (i == 0 && sig->hasthis)
3475 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3477 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3480 g_assert (pindex <= nargs);
3485 // FIXME: Align call sites
3491 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3493 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3494 mono_llvm_set_call_notail (lcall);
3497 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3499 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3500 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3502 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3503 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3504 if (!sig->pinvoke && !cfg->llvm_only)
3505 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3507 mono_llvm_set_call_preserveall_cc (lcall);
3509 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3510 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3511 if (!ctx->llvm_only && call->rgctx_arg_reg)
3512 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3513 if (call->imt_arg_reg)
3514 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3516 /* Add byval attributes if needed */
3517 for (i = 0; i < sig->param_count; ++i) {
3518 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3520 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3521 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3525 * Convert the result
3527 switch (cinfo->ret.storage) {
3528 case LLVMArgVtypeInReg: {
3529 LLVMValueRef regs [2];
3531 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3535 if (!addresses [ins->dreg])
3536 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3538 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3539 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3540 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3541 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3544 case LLVMArgVtypeByVal:
3545 if (!addresses [call->inst.dreg])
3546 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3547 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3549 case LLVMArgAsIArgs:
3550 case LLVMArgFpStruct:
3551 if (!addresses [call->inst.dreg])
3552 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3553 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3555 case LLVMArgVtypeAsScalar:
3556 if (!addresses [call->inst.dreg])
3557 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3558 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3560 case LLVMArgVtypeRetAddr:
3561 case LLVMArgVtypeByRef:
3562 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3563 /* Some opcodes like STOREX_MEMBASE access these by value */
3564 g_assert (addresses [call->inst.dreg]);
3565 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3568 case LLVMArgGsharedvtVariable:
3570 case LLVMArgGsharedvtFixed:
3571 case LLVMArgGsharedvtFixedVtype:
3572 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3575 if (sig->ret->type != MONO_TYPE_VOID)
3576 /* If the method returns an unsigned value, need to zext it */
3577 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));
3581 *builder_ref = ctx->builder;
3585 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3587 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3588 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3590 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3593 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3595 if (ctx->cfg->compile_aot) {
3596 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3598 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3599 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3600 mono_memory_barrier ();
3603 ctx->module->rethrow = callee;
3605 ctx->module->throw_icall = callee;
3609 LLVMValueRef args [2];
3611 args [0] = convert (ctx, exc, exc_type);
3612 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3614 LLVMBuildUnreachable (ctx->builder);
3616 ctx->builder = create_builder (ctx);
3620 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3622 MonoMethodSignature *throw_sig;
3623 LLVMValueRef callee, arg;
3624 const char *icall_name;
3626 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3627 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3630 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3631 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3632 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3633 if (ctx->cfg->compile_aot) {
3634 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3639 * LLVM doesn't push the exception argument, so we need a different
3642 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3644 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3646 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3649 mono_memory_barrier ();
3650 #if LLVM_API_VERSION < 100
3652 ctx->module->rethrow = callee;
3654 ctx->module->throw_icall = callee;
3657 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3658 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3662 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3664 const char *icall_name = "mono_llvm_resume_exception";
3665 LLVMValueRef callee = ctx->module->resume_eh;
3667 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3670 if (ctx->cfg->compile_aot) {
3671 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3673 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3674 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3675 mono_memory_barrier ();
3677 ctx->module->resume_eh = callee;
3681 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3683 LLVMBuildUnreachable (ctx->builder);
3685 ctx->builder = create_builder (ctx);
3689 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3691 const char *icall_name = "mono_llvm_clear_exception";
3693 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3694 LLVMValueRef callee = NULL;
3697 if (ctx->cfg->compile_aot) {
3698 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3700 // FIXME: This is broken.
3701 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3705 g_assert (builder && callee);
3707 return LLVMBuildCall (builder, callee, NULL, 0, "");
3711 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3713 const char *icall_name = "mono_llvm_load_exception";
3715 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3716 LLVMValueRef callee = NULL;
3719 if (ctx->cfg->compile_aot) {
3720 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3722 // FIXME: This is broken.
3723 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3727 g_assert (builder && callee);
3729 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3734 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3736 const char *icall_name = "mono_llvm_match_exception";
3738 ctx->builder = builder;
3740 const int num_args = 5;
3741 LLVMValueRef args [num_args];
3742 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3743 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3744 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3745 if (ctx->cfg->rgctx_var) {
3746 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3747 g_assert (rgctx_alloc);
3748 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3750 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3753 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3755 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3757 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3758 LLVMValueRef callee = ctx->module->match_exc;
3761 if (ctx->cfg->compile_aot) {
3762 ctx->builder = builder;
3763 // get_callee expects ctx->builder to be the emitting builder
3764 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3766 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3767 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3768 ctx->module->match_exc = callee;
3769 mono_memory_barrier ();
3773 g_assert (builder && callee);
3775 g_assert (ctx->ex_var);
3777 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3780 // FIXME: This won't work because the code-finding makes this
3782 /*#define MONO_PERSONALITY_DEBUG*/
3784 #ifdef MONO_PERSONALITY_DEBUG
3785 static const gboolean use_debug_personality = TRUE;
3786 static const char *default_personality_name = "mono_debug_personality";
3788 static const gboolean use_debug_personality = FALSE;
3789 static const char *default_personality_name = "__gxx_personality_v0";
3793 default_cpp_lpad_exc_signature (void)
3795 static gboolean inited = FALSE;
3796 static LLVMTypeRef sig;
3799 LLVMTypeRef signature [2];
3800 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3801 signature [1] = LLVMInt32Type ();
3802 sig = LLVMStructType (signature, 2, FALSE);
3810 get_mono_personality (EmitContext *ctx)
3812 LLVMValueRef personality = NULL;
3813 static gint32 mapping_inited = FALSE;
3814 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3816 if (!use_debug_personality) {
3817 if (ctx->cfg->compile_aot) {
3818 personality = get_intrinsic (ctx, default_personality_name);
3819 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3820 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3821 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3824 if (ctx->cfg->compile_aot) {
3825 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3827 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3828 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3829 mono_memory_barrier ();
3833 g_assert (personality);
3837 static LLVMBasicBlockRef
3838 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3840 MonoCompile *cfg = ctx->cfg;
3841 LLVMBuilderRef old_builder = ctx->builder;
3842 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3844 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3845 ctx->builder = lpadBuilder;
3847 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3848 g_assert (handler_bb);
3850 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3851 LLVMValueRef personality = get_mono_personality (ctx);
3852 g_assert (personality);
3854 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3855 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3857 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3858 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3859 g_assert (landing_pad);
3861 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3862 LLVMAddClause (landing_pad, cast);
3864 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3865 LLVMBuilderRef resume_builder = create_builder (ctx);
3866 ctx->builder = resume_builder;
3867 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3869 emit_resume_eh (ctx, handler_bb);
3872 ctx->builder = lpadBuilder;
3873 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3875 gboolean finally_only = TRUE;
3877 MonoExceptionClause *group_cursor = group_start;
3879 for (int i = 0; i < group_size; i ++) {
3880 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3881 finally_only = FALSE;
3887 // Handle landing pad inlining
3889 if (!finally_only) {
3890 // So at each level of the exception stack we will match the exception again.
3891 // During that match, we need to compare against the handler types for the current
3892 // protected region. We send the try start and end so that we can only check against
3893 // handlers for this lexical protected region.
3894 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3896 // if returns -1, resume
3897 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3899 // else move to that target bb
3900 for (int i=0; i < group_size; i++) {
3901 MonoExceptionClause *clause = group_start + i;
3902 int clause_index = clause - cfg->header->clauses;
3903 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3904 g_assert (handler_bb);
3905 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3906 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3909 int clause_index = group_start - cfg->header->clauses;
3910 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3911 g_assert (finally_bb);
3913 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3916 ctx->builder = old_builder;
3923 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3925 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3926 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3928 // Make exception available to catch blocks
3929 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3930 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3932 g_assert (ctx->ex_var);
3933 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3935 if (bb->in_scount == 1) {
3936 MonoInst *exvar = bb->in_stack [0];
3937 g_assert (!ctx->values [exvar->dreg]);
3938 g_assert (ctx->ex_var);
3939 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3940 emit_volatile_store (ctx, exvar->dreg);
3943 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3946 LLVMBuilderRef handler_builder = create_builder (ctx);
3947 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3948 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3950 // Make the handler code end with a jump to cbb
3951 LLVMBuildBr (handler_builder, cbb);
3955 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3957 MonoCompile *cfg = ctx->cfg;
3958 LLVMValueRef *values = ctx->values;
3959 LLVMModuleRef lmodule = ctx->lmodule;
3960 BBInfo *bblocks = ctx->bblocks;
3962 LLVMValueRef personality;
3963 LLVMValueRef landing_pad;
3964 LLVMBasicBlockRef target_bb;
3966 static int ti_generator;
3968 LLVMValueRef type_info;
3972 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3974 if (cfg->compile_aot) {
3975 /* Use a dummy personality function */
3976 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3977 g_assert (personality);
3979 #if LLVM_API_VERSION > 100
3980 personality = ctx->module->personality;
3982 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3983 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3984 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3985 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3986 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3987 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3988 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3989 ctx->module->personality = personality;
3990 LLVMDisposeBuilder (builder2);
3993 static gint32 mapping_inited;
3995 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3997 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3998 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4002 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4004 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4007 * Create the type info
4009 sprintf (ti_name, "type_info_%d", ti_generator);
4012 if (cfg->compile_aot) {
4013 /* decode_eh_frame () in aot-runtime.c will decode this */
4014 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4015 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4018 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4020 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4022 #if LLVM_API_VERSION > 100
4023 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4024 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4029 * After the cfg mempool is freed, the type info will point to stale memory,
4030 * but this is not a problem, since we decode it once in exception_cb during
4033 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4034 *(gint32*)ti = clause_index;
4036 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4038 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4043 LLVMTypeRef members [2], ret_type;
4045 members [0] = i8ptr;
4046 members [1] = LLVMInt32Type ();
4047 ret_type = LLVMStructType (members, 2, FALSE);
4049 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4050 LLVMAddClause (landing_pad, type_info);
4052 /* Store the exception into the exvar */
4054 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4058 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4059 * code expects control to be transferred to this landing pad even in the
4060 * presence of nested clauses. The landing pad needs to branch to the landing
4061 * pads belonging to nested clauses based on the selector value returned by
4062 * the landing pad instruction, which is passed to the landing pad in a
4063 * register by the EH code.
4065 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4066 g_assert (target_bb);
4069 * Branch to the correct landing pad
4071 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4072 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4074 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4075 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4076 MonoBasicBlock *handler_bb;
4078 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4079 g_assert (handler_bb);
4081 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4082 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4085 /* Start a new bblock which CALL_HANDLER can branch to */
4086 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4088 ctx->builder = builder = create_builder (ctx);
4089 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4091 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4093 /* Store the exception into the IL level exvar */
4094 if (bb->in_scount == 1) {
4095 g_assert (bb->in_scount == 1);
4096 exvar = bb->in_stack [0];
4098 // FIXME: This is shared with filter clauses ?
4099 g_assert (!values [exvar->dreg]);
4101 g_assert (ctx->ex_var);
4102 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4103 emit_volatile_store (ctx, exvar->dreg);
4109 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4111 MonoCompile *cfg = ctx->cfg;
4112 MonoMethodSignature *sig = ctx->sig;
4113 LLVMValueRef method = ctx->lmethod;
4114 LLVMValueRef *values = ctx->values;
4115 LLVMValueRef *addresses = ctx->addresses;
4116 LLVMCallInfo *linfo = ctx->linfo;
4117 BBInfo *bblocks = ctx->bblocks;
4119 LLVMBasicBlockRef cbb;
4120 LLVMBuilderRef builder, starting_builder;
4121 gboolean has_terminator;
4123 LLVMValueRef lhs, rhs;
4126 cbb = get_end_bb (ctx, bb);
4128 builder = create_builder (ctx);
4129 ctx->builder = builder;
4130 LLVMPositionBuilderAtEnd (builder, cbb);
4135 if (bb->flags & BB_EXCEPTION_HANDLER) {
4136 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4137 set_failure (ctx, "handler without invokes");
4142 emit_llvmonly_handler_start (ctx, bb, cbb);
4144 emit_handler_start (ctx, bb, builder);
4147 builder = ctx->builder;
4150 has_terminator = FALSE;
4151 starting_builder = builder;
4152 for (ins = bb->code; ins; ins = ins->next) {
4153 const char *spec = LLVM_INS_INFO (ins->opcode);
4155 char dname_buf [128];
4157 emit_dbg_loc (ctx, builder, ins->cil_code);
4162 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4163 * Start a new bblock.
4164 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4165 * from localloc-ed memory.
4167 if (!cfg->llvm_only)
4168 ;//set_failure (ctx, "basic block too long");
4170 if (!ctx->long_bb_break_var) {
4171 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4172 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4175 cbb = gen_bb (ctx, "CONT_LONG_BB");
4176 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4178 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4180 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4181 * but llvm doesn't know that, so the branch is not going to be eliminated.
4183 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4185 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4187 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4188 ctx->builder = builder = create_builder (ctx);
4189 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4190 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4191 LLVMBuildBr (builder, cbb);
4193 ctx->builder = builder = create_builder (ctx);
4194 LLVMPositionBuilderAtEnd (builder, cbb);
4195 ctx->bblocks [bb->block_num].end_bblock = cbb;
4200 /* There could be instructions after a terminator, skip them */
4203 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4204 sprintf (dname_buf, "t%d", ins->dreg);
4208 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4209 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4211 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4212 lhs = emit_volatile_load (ctx, ins->sreg1);
4214 /* It is ok for SETRET to have an uninitialized argument */
4215 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4216 set_failure (ctx, "sreg1");
4219 lhs = values [ins->sreg1];
4225 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4226 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4227 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4228 rhs = emit_volatile_load (ctx, ins->sreg2);
4230 if (!values [ins->sreg2]) {
4231 set_failure (ctx, "sreg2");
4234 rhs = values [ins->sreg2];
4240 //mono_print_ins (ins);
4241 switch (ins->opcode) {
4244 case OP_LIVERANGE_START:
4245 case OP_LIVERANGE_END:
4248 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4251 #if SIZEOF_VOID_P == 4
4252 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4254 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4258 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4262 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4264 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4266 case OP_DUMMY_ICONST:
4267 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4269 case OP_DUMMY_I8CONST:
4270 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4272 case OP_DUMMY_R8CONST:
4273 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4276 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4277 LLVMBuildBr (builder, target_bb);
4278 has_terminator = TRUE;
4285 LLVMBasicBlockRef new_bb;
4286 LLVMBuilderRef new_builder;
4288 // The default branch is already handled
4289 // FIXME: Handle it here
4291 /* Start new bblock */
4292 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4293 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4295 lhs = convert (ctx, lhs, LLVMInt32Type ());
4296 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4297 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4298 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4300 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4303 new_builder = create_builder (ctx);
4304 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4305 LLVMBuildUnreachable (new_builder);
4307 has_terminator = TRUE;
4308 g_assert (!ins->next);
4314 switch (linfo->ret.storage) {
4315 case LLVMArgVtypeInReg: {
4316 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4317 LLVMValueRef val, addr, retval;
4320 retval = LLVMGetUndef (ret_type);
4322 if (!addresses [ins->sreg1]) {
4324 * The return type is an LLVM vector type, have to convert between it and the
4325 * real return type which is a struct type.
4327 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4328 /* Convert to 2xi64 first */
4329 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4331 for (i = 0; i < 2; ++i) {
4332 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4333 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4335 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4339 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4340 for (i = 0; i < 2; ++i) {
4341 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4342 LLVMValueRef indexes [2], part_addr;
4344 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4345 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4346 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4348 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4350 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4354 LLVMBuildRet (builder, retval);
4357 case LLVMArgVtypeAsScalar: {
4358 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4359 LLVMValueRef retval;
4361 g_assert (addresses [ins->sreg1]);
4363 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4364 LLVMBuildRet (builder, retval);
4367 case LLVMArgVtypeByVal: {
4368 LLVMValueRef retval;
4370 g_assert (addresses [ins->sreg1]);
4371 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4372 LLVMBuildRet (builder, retval);
4375 case LLVMArgVtypeByRef: {
4376 LLVMBuildRetVoid (builder);
4379 case LLVMArgGsharedvtFixed: {
4380 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4381 /* The return value is in lhs, need to store to the vret argument */
4382 /* sreg1 might not be set */
4384 g_assert (cfg->vret_addr);
4385 g_assert (values [cfg->vret_addr->dreg]);
4386 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4388 LLVMBuildRetVoid (builder);
4391 case LLVMArgGsharedvtFixedVtype: {
4393 LLVMBuildRetVoid (builder);
4396 case LLVMArgGsharedvtVariable: {
4398 LLVMBuildRetVoid (builder);
4401 case LLVMArgVtypeRetAddr: {
4402 LLVMBuildRetVoid (builder);
4405 case LLVMArgAsIArgs:
4406 case LLVMArgFpStruct: {
4407 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4408 LLVMValueRef retval;
4410 g_assert (addresses [ins->sreg1]);
4411 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4412 LLVMBuildRet (builder, retval);
4416 case LLVMArgNormal: {
4417 if (!lhs || ctx->is_dead [ins->sreg1]) {
4419 * The method did not set its return value, probably because it
4420 * ends with a throw.
4423 LLVMBuildRetVoid (builder);
4425 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4427 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4429 has_terminator = TRUE;
4433 g_assert_not_reached ();
4442 case OP_ICOMPARE_IMM:
4443 case OP_LCOMPARE_IMM:
4444 case OP_COMPARE_IMM: {
4446 LLVMValueRef cmp, args [16];
4447 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4449 if (ins->next->opcode == OP_NOP)
4452 if (ins->next->opcode == OP_BR)
4453 /* The comparison result is not needed */
4456 rel = mono_opcode_to_cond (ins->next->opcode);
4458 if (ins->opcode == OP_ICOMPARE_IMM) {
4459 lhs = convert (ctx, lhs, LLVMInt32Type ());
4460 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4462 if (ins->opcode == OP_LCOMPARE_IMM) {
4463 lhs = convert (ctx, lhs, LLVMInt64Type ());
4464 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4466 if (ins->opcode == OP_LCOMPARE) {
4467 lhs = convert (ctx, lhs, LLVMInt64Type ());
4468 rhs = convert (ctx, rhs, LLVMInt64Type ());
4470 if (ins->opcode == OP_ICOMPARE) {
4471 lhs = convert (ctx, lhs, LLVMInt32Type ());
4472 rhs = convert (ctx, rhs, LLVMInt32Type ());
4476 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4477 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4478 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4479 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4482 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4483 if (ins->opcode == OP_FCOMPARE) {
4484 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4485 } else if (ins->opcode == OP_RCOMPARE) {
4486 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4487 } else if (ins->opcode == OP_COMPARE_IMM) {
4488 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4489 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4491 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4492 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4493 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4494 /* The immediate is encoded in two fields */
4495 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4496 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4498 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4501 else if (ins->opcode == OP_COMPARE) {
4502 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4503 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4505 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4507 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4511 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4512 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4515 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4516 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4518 * If the target bb contains PHI instructions, LLVM requires
4519 * two PHI entries for this bblock, while we only generate one.
4520 * So convert this to an unconditional bblock. (bxc #171).
4522 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4524 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4526 has_terminator = TRUE;
4527 } else if (MONO_IS_SETCC (ins->next)) {
4528 sprintf (dname_buf, "t%d", ins->next->dreg);
4530 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4532 /* Add stores for volatile variables */
4533 emit_volatile_store (ctx, ins->next->dreg);
4534 } else if (MONO_IS_COND_EXC (ins->next)) {
4535 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4538 builder = ctx->builder;
4540 set_failure (ctx, "next");
4558 rel = mono_opcode_to_cond (ins->opcode);
4560 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4561 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4572 rel = mono_opcode_to_cond (ins->opcode);
4574 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4575 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4583 gboolean empty = TRUE;
4585 /* Check that all input bblocks really branch to us */
4586 for (i = 0; i < bb->in_count; ++i) {
4587 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4588 ins->inst_phi_args [i + 1] = -1;
4594 /* LLVM doesn't like phi instructions with zero operands */
4595 ctx->is_dead [ins->dreg] = TRUE;
4599 /* Created earlier, insert it now */
4600 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4602 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4603 int sreg1 = ins->inst_phi_args [i + 1];
4607 * Count the number of times the incoming bblock branches to us,
4608 * since llvm requires a separate entry for each.
4610 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4611 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4614 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4615 if (switch_ins->inst_many_bb [j] == bb)
4622 /* Remember for later */
4623 for (j = 0; j < count; ++j) {
4624 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4627 node->in_bb = bb->in_bb [i];
4629 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);
4639 values [ins->dreg] = lhs;
4643 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4646 values [ins->dreg] = lhs;
4648 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4650 * This is added by the spilling pass in case of the JIT,
4651 * but we have to do it ourselves.
4653 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4657 case OP_MOVE_F_TO_I4: {
4658 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4661 case OP_MOVE_I4_TO_F: {
4662 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4665 case OP_MOVE_F_TO_I8: {
4666 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4669 case OP_MOVE_I8_TO_F: {
4670 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4703 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4704 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4706 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4709 builder = ctx->builder;
4711 switch (ins->opcode) {
4714 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4718 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4722 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4726 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4730 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4734 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4738 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4742 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4746 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4750 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4754 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4758 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4762 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4766 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4770 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4773 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4776 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4780 g_assert_not_reached ();
4787 lhs = convert (ctx, lhs, LLVMFloatType ());
4788 rhs = convert (ctx, rhs, LLVMFloatType ());
4789 switch (ins->opcode) {
4791 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4794 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4797 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4800 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4803 g_assert_not_reached ();
4812 case OP_IREM_UN_IMM:
4814 case OP_IDIV_UN_IMM:
4820 case OP_ISHR_UN_IMM:
4830 case OP_LSHR_UN_IMM:
4836 case OP_SHR_UN_IMM: {
4839 if (spec [MONO_INST_SRC1] == 'l') {
4840 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4842 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4845 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4848 builder = ctx->builder;
4850 #if SIZEOF_VOID_P == 4
4851 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4852 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4855 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4856 lhs = convert (ctx, lhs, IntPtrType ());
4857 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4858 switch (ins->opcode) {
4862 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4866 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4871 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4875 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4877 case OP_IDIV_UN_IMM:
4878 case OP_LDIV_UN_IMM:
4879 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4883 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4885 case OP_IREM_UN_IMM:
4886 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4891 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4895 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4899 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4904 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4909 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4911 case OP_ISHR_UN_IMM:
4912 /* This is used to implement conv.u4, so the lhs could be an i8 */
4913 lhs = convert (ctx, lhs, LLVMInt32Type ());
4914 imm = convert (ctx, imm, LLVMInt32Type ());
4915 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4917 case OP_LSHR_UN_IMM:
4919 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4922 g_assert_not_reached ();
4927 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4930 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4933 lhs = convert (ctx, lhs, LLVMDoubleType ());
4934 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4937 lhs = convert (ctx, lhs, LLVMFloatType ());
4938 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4941 guint32 v = 0xffffffff;
4942 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4946 guint64 v = 0xffffffffffffffffLL;
4947 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4950 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4952 LLVMValueRef v1, v2;
4954 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4955 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4956 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4961 case OP_ICONV_TO_I1:
4962 case OP_ICONV_TO_I2:
4963 case OP_ICONV_TO_I4:
4964 case OP_ICONV_TO_U1:
4965 case OP_ICONV_TO_U2:
4966 case OP_ICONV_TO_U4:
4967 case OP_LCONV_TO_I1:
4968 case OP_LCONV_TO_I2:
4969 case OP_LCONV_TO_U1:
4970 case OP_LCONV_TO_U2:
4971 case OP_LCONV_TO_U4: {
4974 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);
4976 /* Have to do two casts since our vregs have type int */
4977 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4979 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4981 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4984 case OP_ICONV_TO_I8:
4985 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4987 case OP_ICONV_TO_U8:
4988 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4990 case OP_FCONV_TO_I4:
4991 case OP_RCONV_TO_I4:
4992 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4994 case OP_FCONV_TO_I1:
4995 case OP_RCONV_TO_I1:
4996 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4998 case OP_FCONV_TO_U1:
4999 case OP_RCONV_TO_U1:
5000 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5002 case OP_FCONV_TO_I2:
5003 case OP_RCONV_TO_I2:
5004 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5006 case OP_FCONV_TO_U2:
5007 case OP_RCONV_TO_U2:
5008 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5010 case OP_RCONV_TO_U4:
5011 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5013 case OP_FCONV_TO_I8:
5014 case OP_RCONV_TO_I8:
5015 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5018 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5020 case OP_ICONV_TO_R8:
5021 case OP_LCONV_TO_R8:
5022 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5024 case OP_ICONV_TO_R_UN:
5025 case OP_LCONV_TO_R_UN:
5026 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5028 #if SIZEOF_VOID_P == 4
5031 case OP_LCONV_TO_I4:
5032 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5034 case OP_ICONV_TO_R4:
5035 case OP_LCONV_TO_R4:
5036 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5038 values [ins->dreg] = v;
5040 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5042 case OP_FCONV_TO_R4:
5043 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5045 values [ins->dreg] = v;
5047 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5049 case OP_RCONV_TO_R8:
5050 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5052 case OP_RCONV_TO_R4:
5053 values [ins->dreg] = lhs;
5056 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5059 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5062 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5064 case OP_LOCALLOC_IMM: {
5067 guint32 size = ins->inst_imm;
5068 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5070 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5072 if (ins->flags & MONO_INST_INIT) {
5073 LLVMValueRef args [5];
5076 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5077 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5078 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5079 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5080 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5083 values [ins->dreg] = v;
5087 LLVMValueRef v, size;
5089 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), "");
5091 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5093 if (ins->flags & MONO_INST_INIT) {
5094 LLVMValueRef args [5];
5097 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5099 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5100 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5101 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5103 values [ins->dreg] = v;
5107 case OP_LOADI1_MEMBASE:
5108 case OP_LOADU1_MEMBASE:
5109 case OP_LOADI2_MEMBASE:
5110 case OP_LOADU2_MEMBASE:
5111 case OP_LOADI4_MEMBASE:
5112 case OP_LOADU4_MEMBASE:
5113 case OP_LOADI8_MEMBASE:
5114 case OP_LOADR4_MEMBASE:
5115 case OP_LOADR8_MEMBASE:
5116 case OP_LOAD_MEMBASE:
5124 LLVMValueRef base, index, addr;
5126 gboolean sext = FALSE, zext = FALSE;
5127 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5129 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5134 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)) {
5135 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5141 if (ins->inst_offset == 0) {
5143 } else if (ins->inst_offset % size != 0) {
5144 /* Unaligned load */
5145 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5146 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5148 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5149 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5153 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5155 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5157 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5159 * These will signal LLVM that these loads do not alias any stores, and
5160 * they can't fail, allowing them to be hoisted out of loops.
5162 set_invariant_load_flag (values [ins->dreg]);
5163 #if LLVM_API_VERSION < 100
5164 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5169 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5171 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5172 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5173 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5177 case OP_STOREI1_MEMBASE_REG:
5178 case OP_STOREI2_MEMBASE_REG:
5179 case OP_STOREI4_MEMBASE_REG:
5180 case OP_STOREI8_MEMBASE_REG:
5181 case OP_STORER4_MEMBASE_REG:
5182 case OP_STORER8_MEMBASE_REG:
5183 case OP_STORE_MEMBASE_REG: {
5185 LLVMValueRef index, addr, base;
5187 gboolean sext = FALSE, zext = FALSE;
5188 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5190 if (!values [ins->inst_destbasereg]) {
5191 set_failure (ctx, "inst_destbasereg");
5195 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5197 base = values [ins->inst_destbasereg];
5198 if (ins->inst_offset % size != 0) {
5199 /* Unaligned store */
5200 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5201 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5203 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5204 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5206 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5210 case OP_STOREI1_MEMBASE_IMM:
5211 case OP_STOREI2_MEMBASE_IMM:
5212 case OP_STOREI4_MEMBASE_IMM:
5213 case OP_STOREI8_MEMBASE_IMM:
5214 case OP_STORE_MEMBASE_IMM: {
5216 LLVMValueRef index, addr, base;
5218 gboolean sext = FALSE, zext = FALSE;
5219 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5221 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5223 base = values [ins->inst_destbasereg];
5224 if (ins->inst_offset % size != 0) {
5225 /* Unaligned store */
5226 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5227 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5229 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5230 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5232 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5237 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5239 case OP_OUTARG_VTRETADDR:
5247 case OP_VOIDCALL_MEMBASE:
5248 case OP_CALL_MEMBASE:
5249 case OP_LCALL_MEMBASE:
5250 case OP_FCALL_MEMBASE:
5251 case OP_RCALL_MEMBASE:
5252 case OP_VCALL_MEMBASE:
5253 case OP_VOIDCALL_REG:
5258 case OP_VCALL_REG: {
5259 process_call (ctx, bb, &builder, ins);
5264 LLVMValueRef indexes [2];
5265 MonoJumpInfo *tmp_ji, *ji;
5266 LLVMValueRef got_entry_addr;
5270 * FIXME: Can't allocate from the cfg mempool since that is freed if
5271 * the LLVM compile fails.
5273 tmp_ji = g_new0 (MonoJumpInfo, 1);
5274 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5275 tmp_ji->data.target = ins->inst_p0;
5277 ji = mono_aot_patch_info_dup (tmp_ji);
5280 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5281 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5284 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5285 * resolvable at runtime using dlsym ().
5288 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5293 ji->next = cfg->patch_info;
5294 cfg->patch_info = ji;
5296 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5297 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5298 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5299 if (!mono_aot_is_shared_got_offset (got_offset)) {
5300 //mono_print_ji (ji);
5302 ctx->has_got_access = TRUE;
5305 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5306 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5307 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5309 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5310 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5312 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5313 if (!cfg->llvm_only)
5314 set_invariant_load_flag (values [ins->dreg]);
5317 case OP_NOT_REACHED:
5318 LLVMBuildUnreachable (builder);
5319 has_terminator = TRUE;
5320 g_assert (bb->block_num < cfg->max_block_num);
5321 ctx->unreachable [bb->block_num] = TRUE;
5322 /* Might have instructions after this */
5324 MonoInst *next = ins->next;
5326 * FIXME: If later code uses the regs defined by these instructions,
5327 * compilation will fail.
5329 MONO_DELETE_INS (bb, next);
5333 MonoInst *var = ins->inst_i0;
5335 if (var->opcode == OP_VTARG_ADDR) {
5336 /* The variable contains the vtype address */
5337 values [ins->dreg] = values [var->dreg];
5338 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5339 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5341 values [ins->dreg] = addresses [var->dreg];
5346 LLVMValueRef args [1];
5348 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5349 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5353 LLVMValueRef args [1];
5355 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5356 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5360 LLVMValueRef args [1];
5362 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5363 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5367 LLVMValueRef args [1];
5369 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5370 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5384 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5385 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5387 switch (ins->opcode) {
5390 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5394 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5398 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5402 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5405 g_assert_not_reached ();
5408 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5413 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5414 * hack is necessary (for now).
5417 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5419 #define ARM64_ATOMIC_FENCE_FIX
5422 case OP_ATOMIC_EXCHANGE_I4:
5423 case OP_ATOMIC_EXCHANGE_I8: {
5424 LLVMValueRef args [2];
5427 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5428 t = LLVMInt32Type ();
5430 t = LLVMInt64Type ();
5432 g_assert (ins->inst_offset == 0);
5434 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5435 args [1] = convert (ctx, rhs, t);
5437 ARM64_ATOMIC_FENCE_FIX;
5438 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5439 ARM64_ATOMIC_FENCE_FIX;
5442 case OP_ATOMIC_ADD_I4:
5443 case OP_ATOMIC_ADD_I8: {
5444 LLVMValueRef args [2];
5447 if (ins->opcode == OP_ATOMIC_ADD_I4)
5448 t = LLVMInt32Type ();
5450 t = LLVMInt64Type ();
5452 g_assert (ins->inst_offset == 0);
5454 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5455 args [1] = convert (ctx, rhs, t);
5456 ARM64_ATOMIC_FENCE_FIX;
5457 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5458 ARM64_ATOMIC_FENCE_FIX;
5461 case OP_ATOMIC_CAS_I4:
5462 case OP_ATOMIC_CAS_I8: {
5463 LLVMValueRef args [3], val;
5466 if (ins->opcode == OP_ATOMIC_CAS_I4)
5467 t = LLVMInt32Type ();
5469 t = LLVMInt64Type ();
5471 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5473 args [1] = convert (ctx, values [ins->sreg3], t);
5475 args [2] = convert (ctx, values [ins->sreg2], t);
5476 ARM64_ATOMIC_FENCE_FIX;
5477 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5478 ARM64_ATOMIC_FENCE_FIX;
5479 /* cmpxchg returns a pair */
5480 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5483 case OP_MEMORY_BARRIER: {
5484 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5487 case OP_ATOMIC_LOAD_I1:
5488 case OP_ATOMIC_LOAD_I2:
5489 case OP_ATOMIC_LOAD_I4:
5490 case OP_ATOMIC_LOAD_I8:
5491 case OP_ATOMIC_LOAD_U1:
5492 case OP_ATOMIC_LOAD_U2:
5493 case OP_ATOMIC_LOAD_U4:
5494 case OP_ATOMIC_LOAD_U8:
5495 case OP_ATOMIC_LOAD_R4:
5496 case OP_ATOMIC_LOAD_R8: {
5497 #if LLVM_API_VERSION > 100
5499 gboolean sext, zext;
5501 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5502 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5503 LLVMValueRef index, addr;
5505 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5510 if (ins->inst_offset != 0) {
5511 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5512 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5517 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5519 ARM64_ATOMIC_FENCE_FIX;
5520 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5521 ARM64_ATOMIC_FENCE_FIX;
5524 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5526 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5529 set_failure (ctx, "atomic mono.load intrinsic");
5533 case OP_ATOMIC_STORE_I1:
5534 case OP_ATOMIC_STORE_I2:
5535 case OP_ATOMIC_STORE_I4:
5536 case OP_ATOMIC_STORE_I8:
5537 case OP_ATOMIC_STORE_U1:
5538 case OP_ATOMIC_STORE_U2:
5539 case OP_ATOMIC_STORE_U4:
5540 case OP_ATOMIC_STORE_U8:
5541 case OP_ATOMIC_STORE_R4:
5542 case OP_ATOMIC_STORE_R8: {
5544 gboolean sext, zext;
5546 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5547 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5548 LLVMValueRef index, addr, value, base;
5550 #if LLVM_API_VERSION < 100
5551 if (!cfg->llvm_only) {
5552 set_failure (ctx, "atomic mono.store intrinsic");
5557 if (!values [ins->inst_destbasereg]) {
5558 set_failure (ctx, "inst_destbasereg");
5562 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5564 base = values [ins->inst_destbasereg];
5565 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5566 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5567 value = convert (ctx, values [ins->sreg1], t);
5569 ARM64_ATOMIC_FENCE_FIX;
5570 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5571 ARM64_ATOMIC_FENCE_FIX;
5574 case OP_RELAXED_NOP: {
5575 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5576 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5583 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5585 // 257 == FS segment register
5586 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5588 // 256 == GS segment register
5589 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5592 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5593 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5594 /* See mono_amd64_emit_tls_get () */
5595 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5597 // 256 == GS segment register
5598 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5599 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5601 set_failure (ctx, "opcode tls-get");
5607 case OP_TLS_GET_REG: {
5608 #if defined(TARGET_AMD64) && defined(__linux__)
5609 // 257 == FS segment register
5610 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5611 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt64Type ()), ptrtype, ""), "");
5612 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5613 /* See emit_tls_get_reg () */
5614 // 256 == GS segment register
5615 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5616 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5618 set_failure (ctx, "opcode tls-get");
5624 case OP_TLS_SET_REG: {
5625 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5626 /* See emit_tls_get_reg () */
5627 // 256 == GS segment register
5628 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5629 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5631 set_failure (ctx, "opcode tls-set-reg");
5636 case OP_GC_SAFE_POINT: {
5637 LLVMValueRef val, cmp, callee;
5638 LLVMBasicBlockRef poll_bb, cont_bb;
5639 static LLVMTypeRef sig;
5640 const char *icall_name = "mono_threads_state_poll";
5643 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5647 * mono_threads_state_poll ();
5648 * FIXME: Use a preserveall wrapper
5650 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5651 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5652 poll_bb = gen_bb (ctx, "POLL_BB");
5653 cont_bb = gen_bb (ctx, "CONT_BB");
5654 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5656 ctx->builder = builder = create_builder (ctx);
5657 LLVMPositionBuilderAtEnd (builder, poll_bb);
5659 if (ctx->cfg->compile_aot) {
5660 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5662 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5663 callee = emit_jit_callee (ctx, icall_name, sig, target);
5665 LLVMBuildCall (builder, callee, NULL, 0, "");
5666 LLVMBuildBr (builder, cont_bb);
5668 ctx->builder = builder = create_builder (ctx);
5669 LLVMPositionBuilderAtEnd (builder, cont_bb);
5670 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5678 case OP_IADD_OVF_UN:
5680 case OP_ISUB_OVF_UN:
5682 case OP_IMUL_OVF_UN:
5684 case OP_LADD_OVF_UN:
5686 case OP_LSUB_OVF_UN:
5688 case OP_LMUL_OVF_UN:
5690 LLVMValueRef args [2], val, ovf, func;
5692 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5693 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5694 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5696 val = LLVMBuildCall (builder, func, args, 2, "");
5697 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5698 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5699 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5702 builder = ctx->builder;
5708 * We currently model them using arrays. Promotion to local vregs is
5709 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5710 * so we always have an entry in cfg->varinfo for them.
5711 * FIXME: Is this needed ?
5714 MonoClass *klass = ins->klass;
5715 LLVMValueRef args [5];
5719 set_failure (ctx, "!klass");
5723 if (!addresses [ins->dreg])
5724 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5725 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5726 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5727 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5729 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5730 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5731 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5734 case OP_DUMMY_VZERO:
5737 case OP_STOREV_MEMBASE:
5738 case OP_LOADV_MEMBASE:
5740 MonoClass *klass = ins->klass;
5741 LLVMValueRef src = NULL, dst, args [5];
5742 gboolean done = FALSE;
5746 set_failure (ctx, "!klass");
5750 if (mini_is_gsharedvt_klass (klass)) {
5752 set_failure (ctx, "gsharedvt");
5756 switch (ins->opcode) {
5757 case OP_STOREV_MEMBASE:
5758 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5759 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5760 /* Decomposed earlier */
5761 g_assert_not_reached ();
5764 if (!addresses [ins->sreg1]) {
5766 g_assert (values [ins->sreg1]);
5767 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));
5768 LLVMBuildStore (builder, values [ins->sreg1], dst);
5771 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5772 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5775 case OP_LOADV_MEMBASE:
5776 if (!addresses [ins->dreg])
5777 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5778 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5779 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5782 if (!addresses [ins->sreg1])
5783 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5784 if (!addresses [ins->dreg])
5785 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5786 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5787 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5790 g_assert_not_reached ();
5800 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5801 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5803 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5804 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5805 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5808 case OP_LLVM_OUTARG_VT: {
5809 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5810 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5812 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5813 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5815 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5816 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5818 g_assert (addresses [ins->sreg1]);
5819 addresses [ins->dreg] = addresses [ins->sreg1];
5821 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5822 if (!addresses [ins->sreg1]) {
5823 addresses [ins->sreg1] = build_alloca (ctx, t);
5824 g_assert (values [ins->sreg1]);
5826 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5827 addresses [ins->dreg] = addresses [ins->sreg1];
5829 if (!addresses [ins->sreg1]) {
5830 addresses [ins->sreg1] = build_alloca (ctx, t);
5831 g_assert (values [ins->sreg1]);
5832 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5834 addresses [ins->dreg] = addresses [ins->sreg1];
5838 case OP_OBJC_GET_SELECTOR: {
5839 const char *name = (const char*)ins->inst_p0;
5842 if (!ctx->module->objc_selector_to_var)
5843 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5844 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5846 LLVMValueRef indexes [16];
5848 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5849 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5850 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5851 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5852 mark_as_used (ctx->module, name_var);
5854 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5856 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5857 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5858 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5859 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5860 LLVMSetExternallyInitialized (ref_var, TRUE);
5861 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5862 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5863 mark_as_used (ctx->module, ref_var);
5865 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5869 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5876 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5878 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5881 case OP_LOADX_MEMBASE: {
5882 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5885 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5886 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5889 case OP_STOREX_MEMBASE: {
5890 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5893 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5894 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5901 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5905 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5911 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5915 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5919 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5923 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5926 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5929 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5932 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5936 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5947 LLVMValueRef v = NULL;
5949 switch (ins->opcode) {
5954 t = LLVMVectorType (LLVMInt32Type (), 4);
5955 rt = LLVMVectorType (LLVMFloatType (), 4);
5961 t = LLVMVectorType (LLVMInt64Type (), 2);
5962 rt = LLVMVectorType (LLVMDoubleType (), 2);
5965 t = LLVMInt32Type ();
5966 rt = LLVMInt32Type ();
5967 g_assert_not_reached ();
5970 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5971 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5972 switch (ins->opcode) {
5975 v = LLVMBuildAnd (builder, lhs, rhs, "");
5979 v = LLVMBuildOr (builder, lhs, rhs, "");
5983 v = LLVMBuildXor (builder, lhs, rhs, "");
5987 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5990 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5996 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
5997 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6003 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6004 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6008 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6009 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6026 case OP_PADDB_SAT_UN:
6027 case OP_PADDW_SAT_UN:
6028 case OP_PSUBB_SAT_UN:
6029 case OP_PSUBW_SAT_UN:
6037 case OP_PMULW_HIGH_UN: {
6038 LLVMValueRef args [2];
6043 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6050 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6054 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6062 case OP_EXTRACTX_U2:
6064 case OP_EXTRACT_U1: {
6066 gboolean zext = FALSE;
6068 t = simd_op_to_llvm_type (ins->opcode);
6070 switch (ins->opcode) {
6078 case OP_EXTRACTX_U2:
6083 t = LLVMInt32Type ();
6084 g_assert_not_reached ();
6087 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6088 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6090 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6099 case OP_EXPAND_R8: {
6100 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6101 LLVMValueRef mask [16], v;
6104 for (i = 0; i < 16; ++i)
6105 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6107 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6109 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6110 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6115 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6118 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6121 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6124 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6127 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6130 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6134 // Requires a later llvm version
6136 LLVMValueRef indexes [16];
6138 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6139 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6140 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6141 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6142 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6146 LLVMValueRef indexes [16];
6148 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6149 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6150 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6151 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6152 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6156 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6168 case OP_EXTRACT_MASK:
6175 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6177 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6182 LLVMRealPredicate op;
6184 switch (ins->inst_c0) {
6194 case SIMD_COMP_UNORD:
6210 g_assert_not_reached ();
6213 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6214 if (ins->opcode == OP_COMPPD)
6215 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6217 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6221 /* This is only used for implementing shifts by non-immediate */
6222 values [ins->dreg] = lhs;
6233 LLVMValueRef args [3];
6236 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6238 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6249 case OP_PSHLQ_REG: {
6250 LLVMValueRef args [3];
6253 args [1] = values [ins->sreg2];
6255 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6262 case OP_PSHUFLEW_LOW:
6263 case OP_PSHUFLEW_HIGH: {
6265 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6266 int i, mask_size = 0;
6267 int imask = ins->inst_c0;
6269 /* Convert the x86 shuffle mask to LLVM's */
6270 switch (ins->opcode) {
6273 mask [0] = ((imask >> 0) & 3);
6274 mask [1] = ((imask >> 2) & 3);
6275 mask [2] = ((imask >> 4) & 3) + 4;
6276 mask [3] = ((imask >> 6) & 3) + 4;
6277 v1 = values [ins->sreg1];
6278 v2 = values [ins->sreg2];
6282 mask [0] = ((imask >> 0) & 1);
6283 mask [1] = ((imask >> 1) & 1) + 2;
6284 v1 = values [ins->sreg1];
6285 v2 = values [ins->sreg2];
6287 case OP_PSHUFLEW_LOW:
6289 mask [0] = ((imask >> 0) & 3);
6290 mask [1] = ((imask >> 2) & 3);
6291 mask [2] = ((imask >> 4) & 3);
6292 mask [3] = ((imask >> 6) & 3);
6297 v1 = values [ins->sreg1];
6298 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6300 case OP_PSHUFLEW_HIGH:
6306 mask [4] = 4 + ((imask >> 0) & 3);
6307 mask [5] = 4 + ((imask >> 2) & 3);
6308 mask [6] = 4 + ((imask >> 4) & 3);
6309 mask [7] = 4 + ((imask >> 6) & 3);
6310 v1 = values [ins->sreg1];
6311 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6315 mask [0] = ((imask >> 0) & 3);
6316 mask [1] = ((imask >> 2) & 3);
6317 mask [2] = ((imask >> 4) & 3);
6318 mask [3] = ((imask >> 6) & 3);
6319 v1 = values [ins->sreg1];
6320 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6323 g_assert_not_reached ();
6325 for (i = 0; i < mask_size; ++i)
6326 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6328 values [ins->dreg] =
6329 LLVMBuildShuffleVector (builder, v1, v2,
6330 LLVMConstVector (mask_values, mask_size), dname);
6334 case OP_UNPACK_LOWB:
6335 case OP_UNPACK_LOWW:
6336 case OP_UNPACK_LOWD:
6337 case OP_UNPACK_LOWQ:
6338 case OP_UNPACK_LOWPS:
6339 case OP_UNPACK_LOWPD:
6340 case OP_UNPACK_HIGHB:
6341 case OP_UNPACK_HIGHW:
6342 case OP_UNPACK_HIGHD:
6343 case OP_UNPACK_HIGHQ:
6344 case OP_UNPACK_HIGHPS:
6345 case OP_UNPACK_HIGHPD: {
6347 LLVMValueRef mask_values [16];
6348 int i, mask_size = 0;
6349 gboolean low = FALSE;
6351 switch (ins->opcode) {
6352 case OP_UNPACK_LOWB:
6356 case OP_UNPACK_LOWW:
6360 case OP_UNPACK_LOWD:
6361 case OP_UNPACK_LOWPS:
6365 case OP_UNPACK_LOWQ:
6366 case OP_UNPACK_LOWPD:
6370 case OP_UNPACK_HIGHB:
6373 case OP_UNPACK_HIGHW:
6376 case OP_UNPACK_HIGHD:
6377 case OP_UNPACK_HIGHPS:
6380 case OP_UNPACK_HIGHQ:
6381 case OP_UNPACK_HIGHPD:
6385 g_assert_not_reached ();
6389 for (i = 0; i < (mask_size / 2); ++i) {
6391 mask [(i * 2) + 1] = mask_size + i;
6394 for (i = 0; i < (mask_size / 2); ++i) {
6395 mask [(i * 2)] = (mask_size / 2) + i;
6396 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6400 for (i = 0; i < mask_size; ++i)
6401 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6403 values [ins->dreg] =
6404 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6405 LLVMConstVector (mask_values, mask_size), dname);
6410 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6411 LLVMValueRef v, val;
6413 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6414 val = LLVMConstNull (t);
6415 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6416 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6418 values [ins->dreg] = val;
6422 case OP_DUPPS_HIGH: {
6423 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6424 LLVMValueRef v1, v2, val;
6427 if (ins->opcode == OP_DUPPS_LOW) {
6428 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6429 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6431 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6432 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6434 val = LLVMConstNull (t);
6435 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6436 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6437 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6438 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6440 values [ins->dreg] = val;
6450 * EXCEPTION HANDLING
6452 case OP_IMPLICIT_EXCEPTION:
6453 /* This marks a place where an implicit exception can happen */
6454 if (bb->region != -1)
6455 set_failure (ctx, "implicit-exception");
6459 gboolean rethrow = (ins->opcode == OP_RETHROW);
6460 if (ctx->llvm_only) {
6461 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6462 has_terminator = TRUE;
6463 ctx->unreachable [bb->block_num] = TRUE;
6465 emit_throw (ctx, bb, rethrow, lhs);
6466 builder = ctx->builder;
6470 case OP_CALL_HANDLER: {
6472 * We don't 'call' handlers, but instead simply branch to them.
6473 * The code generated by ENDFINALLY will branch back to us.
6475 LLVMBasicBlockRef noex_bb;
6477 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6479 bb_list = info->call_handler_return_bbs;
6482 * Set the indicator variable for the finally clause.
6484 lhs = info->finally_ind;
6486 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6488 /* Branch to the finally clause */
6489 LLVMBuildBr (builder, info->call_handler_target_bb);
6491 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6492 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6494 builder = ctx->builder = create_builder (ctx);
6495 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6497 bblocks [bb->block_num].end_bblock = noex_bb;
6500 case OP_START_HANDLER: {
6503 case OP_ENDFINALLY: {
6504 LLVMBasicBlockRef resume_bb;
6505 MonoBasicBlock *handler_bb;
6506 LLVMValueRef val, switch_ins, callee;
6510 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6511 g_assert (handler_bb);
6512 info = &bblocks [handler_bb->block_num];
6513 lhs = info->finally_ind;
6516 bb_list = info->call_handler_return_bbs;
6518 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6520 /* Load the finally variable */
6521 val = LLVMBuildLoad (builder, lhs, "");
6523 /* Reset the variable */
6524 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6526 /* Branch to either resume_bb, or to the bblocks in bb_list */
6527 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6529 * The other targets are added at the end to handle OP_CALL_HANDLER
6530 * opcodes processed later.
6532 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6534 builder = ctx->builder = create_builder (ctx);
6535 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6537 if (ctx->llvm_only) {
6538 emit_resume_eh (ctx, bb);
6540 if (ctx->cfg->compile_aot) {
6541 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6543 #if LLVM_API_VERSION > 100
6544 MonoJitICallInfo *info;
6546 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6548 gpointer target = (void*)info->func;
6549 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6550 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6552 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6555 LLVMBuildCall (builder, callee, NULL, 0, "");
6556 LLVMBuildUnreachable (builder);
6559 has_terminator = TRUE;
6562 case OP_IL_SEQ_POINT:
6567 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6568 set_failure (ctx, reason);
6576 /* Convert the value to the type required by phi nodes */
6577 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6578 if (ctx->is_vphi [ins->dreg])
6580 values [ins->dreg] = addresses [ins->dreg];
6582 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6585 /* Add stores for volatile variables */
6586 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6587 emit_volatile_store (ctx, ins->dreg);
6593 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6594 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6597 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6598 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6599 LLVMBuildRetVoid (builder);
6602 if (bb == cfg->bb_entry)
6603 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6607 * mono_llvm_check_method_supported:
6609 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6610 * compiling a method twice.
6613 mono_llvm_check_method_supported (MonoCompile *cfg)
6620 if (cfg->method->save_lmf) {
6621 cfg->exception_message = g_strdup ("lmf");
6622 cfg->disable_llvm = TRUE;
6624 if (cfg->disable_llvm)
6628 * Nested clauses where one of the clauses is a finally clause is
6629 * not supported, because LLVM can't figure out the control flow,
6630 * probably because we resume exception handling by calling our
6631 * own function instead of using the 'resume' llvm instruction.
6633 for (i = 0; i < cfg->header->num_clauses; ++i) {
6634 for (j = 0; j < cfg->header->num_clauses; ++j) {
6635 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6636 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6638 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6639 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6640 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6641 cfg->exception_message = g_strdup ("nested clauses");
6642 cfg->disable_llvm = TRUE;
6647 if (cfg->disable_llvm)
6651 if (cfg->method->dynamic) {
6652 cfg->exception_message = g_strdup ("dynamic.");
6653 cfg->disable_llvm = TRUE;
6655 if (cfg->disable_llvm)
6659 static LLVMCallInfo*
6660 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6662 LLVMCallInfo *linfo;
6665 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6669 * Gsharedvt methods have the following calling convention:
6670 * - all arguments are passed by ref, even non generic ones
6671 * - the return value is returned by ref too, using a vret
6672 * argument passed after 'this'.
6674 n = sig->param_count + sig->hasthis;
6675 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6679 linfo->args [pindex ++].storage = LLVMArgNormal;
6681 if (sig->ret->type != MONO_TYPE_VOID) {
6682 if (mini_is_gsharedvt_variable_type (sig->ret))
6683 linfo->ret.storage = LLVMArgGsharedvtVariable;
6684 else if (mini_type_is_vtype (sig->ret))
6685 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6687 linfo->ret.storage = LLVMArgGsharedvtFixed;
6688 linfo->vret_arg_index = pindex;
6690 linfo->ret.storage = LLVMArgNone;
6693 for (i = 0; i < sig->param_count; ++i) {
6694 if (sig->params [i]->byref)
6695 linfo->args [pindex].storage = LLVMArgNormal;
6696 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6697 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6698 else if (mini_type_is_vtype (sig->params [i]))
6699 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6701 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6702 linfo->args [pindex].type = sig->params [i];
6709 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6710 for (i = 0; i < sig->param_count; ++i)
6711 linfo->args [i + sig->hasthis].type = sig->params [i];
6717 emit_method_inner (EmitContext *ctx);
6720 free_ctx (EmitContext *ctx)
6724 g_free (ctx->values);
6725 g_free (ctx->addresses);
6726 g_free (ctx->vreg_types);
6727 g_free (ctx->is_vphi);
6728 g_free (ctx->vreg_cli_types);
6729 g_free (ctx->is_dead);
6730 g_free (ctx->unreachable);
6731 g_ptr_array_free (ctx->phi_values, TRUE);
6732 g_free (ctx->bblocks);
6733 g_hash_table_destroy (ctx->region_to_handler);
6734 g_hash_table_destroy (ctx->clause_to_handler);
6735 g_hash_table_destroy (ctx->jit_callees);
6737 GHashTableIter iter;
6738 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6739 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6742 g_hash_table_destroy (ctx->method_to_callers);
6744 g_free (ctx->method_name);
6745 g_ptr_array_free (ctx->bblock_list, TRUE);
6747 for (l = ctx->builders; l; l = l->next) {
6748 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6749 LLVMDisposeBuilder (builder);
6756 * mono_llvm_emit_method:
6758 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6761 mono_llvm_emit_method (MonoCompile *cfg)
6765 gboolean is_linkonce = FALSE;
6768 /* The code below might acquire the loader lock, so use it for global locking */
6769 mono_loader_lock ();
6771 /* Used to communicate with the callbacks */
6772 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6774 ctx = g_new0 (EmitContext, 1);
6776 ctx->mempool = cfg->mempool;
6779 * This maps vregs to the LLVM instruction defining them
6781 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6783 * This maps vregs for volatile variables to the LLVM instruction defining their
6786 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6787 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6788 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6789 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6790 ctx->phi_values = g_ptr_array_sized_new (256);
6792 * This signals whenever the vreg was defined by a phi node with no input vars
6793 * (i.e. all its input bblocks end with NOT_REACHABLE).
6795 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6796 /* Whenever the bblock is unreachable */
6797 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6798 ctx->bblock_list = g_ptr_array_sized_new (256);
6800 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6801 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6802 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6803 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6804 if (cfg->compile_aot) {
6805 ctx->module = &aot_module;
6809 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6810 * linkage for them. This requires the following:
6811 * - the method needs to have a unique mangled name
6812 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6814 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6816 method_name = mono_aot_get_mangled_method_name (cfg->method);
6818 is_linkonce = FALSE;
6821 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6823 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6827 method_name = mono_aot_get_method_name (cfg);
6828 cfg->llvm_method_name = g_strdup (method_name);
6830 init_jit_module (cfg->domain);
6831 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6832 method_name = mono_method_full_name (cfg->method, TRUE);
6834 ctx->method_name = method_name;
6835 ctx->is_linkonce = is_linkonce;
6837 #if LLVM_API_VERSION > 100
6838 if (cfg->compile_aot)
6839 ctx->lmodule = ctx->module->lmodule;
6841 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6843 ctx->lmodule = ctx->module->lmodule;
6845 ctx->llvm_only = ctx->module->llvm_only;
6847 emit_method_inner (ctx);
6849 if (!ctx_ok (ctx)) {
6851 /* Need to add unused phi nodes as they can be referenced by other values */
6852 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6853 LLVMBuilderRef builder;
6855 builder = create_builder (ctx);
6856 LLVMPositionBuilderAtEnd (builder, phi_bb);
6858 for (i = 0; i < ctx->phi_values->len; ++i) {
6859 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6860 if (LLVMGetInstructionParent (v) == NULL)
6861 LLVMInsertIntoBuilder (builder, v);
6864 LLVMDeleteFunction (ctx->lmethod);
6870 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6872 mono_loader_unlock ();
6876 emit_method_inner (EmitContext *ctx)
6878 MonoCompile *cfg = ctx->cfg;
6879 MonoMethodSignature *sig;
6881 LLVMTypeRef method_type;
6882 LLVMValueRef method = NULL;
6883 LLVMValueRef *values = ctx->values;
6884 int i, max_block_num, bb_index;
6885 gboolean last = FALSE;
6886 LLVMCallInfo *linfo;
6887 LLVMModuleRef lmodule = ctx->lmodule;
6889 GPtrArray *bblock_list = ctx->bblock_list;
6890 MonoMethodHeader *header;
6891 MonoExceptionClause *clause;
6894 if (cfg->gsharedvt && !cfg->llvm_only) {
6895 set_failure (ctx, "gsharedvt");
6901 static int count = 0;
6904 if (g_getenv ("LLVM_COUNT")) {
6905 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6906 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6910 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6911 set_failure (ctx, "count");
6918 sig = mono_method_signature (cfg->method);
6921 linfo = get_llvm_call_info (cfg, sig);
6927 linfo->rgctx_arg = TRUE;
6928 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6932 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6933 ctx->lmethod = method;
6935 if (!cfg->llvm_only)
6936 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6937 LLVMSetLinkage (method, LLVMPrivateLinkage);
6939 LLVMAddFunctionAttr (method, LLVMUWTable);
6941 if (cfg->compile_aot) {
6942 LLVMSetLinkage (method, LLVMInternalLinkage);
6943 if (ctx->module->external_symbols) {
6944 LLVMSetLinkage (method, LLVMExternalLinkage);
6945 LLVMSetVisibility (method, LLVMHiddenVisibility);
6947 if (ctx->is_linkonce) {
6948 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6949 LLVMSetVisibility (method, LLVMDefaultVisibility);
6952 #if LLVM_API_VERSION > 100
6953 LLVMSetLinkage (method, LLVMExternalLinkage);
6955 LLVMSetLinkage (method, LLVMPrivateLinkage);
6959 if (cfg->method->save_lmf && !cfg->llvm_only) {
6960 set_failure (ctx, "lmf");
6964 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6965 set_failure (ctx, "pinvoke signature");
6969 header = cfg->header;
6970 for (i = 0; i < header->num_clauses; ++i) {
6971 clause = &header->clauses [i];
6972 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6973 set_failure (ctx, "non-finally/catch clause.");
6977 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6978 /* We can't handle inlined methods with clauses */
6979 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6981 if (linfo->rgctx_arg) {
6982 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6983 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6985 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6986 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6987 * CC_X86_64_Mono in X86CallingConv.td.
6989 if (!ctx->llvm_only)
6990 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6991 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6993 ctx->rgctx_arg_pindex = -1;
6995 if (cfg->vret_addr) {
6996 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6997 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6998 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6999 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7000 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7005 ctx->this_arg_pindex = linfo->this_arg_pindex;
7006 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7007 values [cfg->args [0]->dreg] = ctx->this_arg;
7008 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7011 names = g_new (char *, sig->param_count);
7012 mono_method_get_param_names (cfg->method, (const char **) names);
7014 /* Set parameter names/attributes */
7015 for (i = 0; i < sig->param_count; ++i) {
7016 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7018 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7021 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7022 name = g_strdup_printf ("dummy_%d_%d", i, j);
7023 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7027 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7030 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7031 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7032 if (names [i] && names [i][0] != '\0')
7033 name = g_strdup_printf ("p_arg_%s", names [i]);
7035 name = g_strdup_printf ("p_arg_%d", i);
7037 if (names [i] && names [i][0] != '\0')
7038 name = g_strdup_printf ("arg_%s", names [i]);
7040 name = g_strdup_printf ("arg_%d", i);
7042 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7044 if (ainfo->storage == LLVMArgVtypeByVal)
7045 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7047 if (ainfo->storage == LLVMArgVtypeByRef) {
7049 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7054 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7055 ctx->minfo = mono_debug_lookup_method (cfg->method);
7056 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7060 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7061 max_block_num = MAX (max_block_num, bb->block_num);
7062 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7064 /* Add branches between non-consecutive bblocks */
7065 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7066 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7067 bb->next_bb != bb->last_ins->inst_false_bb) {
7069 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7070 inst->opcode = OP_BR;
7071 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7072 mono_bblock_add_inst (bb, inst);
7077 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7078 * was later optimized away, so clear these flags, and add them back for the still
7079 * present OP_LDADDR instructions.
7081 for (i = 0; i < cfg->next_vreg; ++i) {
7084 ins = get_vreg_to_inst (cfg, i);
7085 if (ins && ins != cfg->rgctx_var)
7086 ins->flags &= ~MONO_INST_INDIRECT;
7090 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7092 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7094 LLVMBuilderRef builder;
7096 char dname_buf[128];
7098 builder = create_builder (ctx);
7100 for (ins = bb->code; ins; ins = ins->next) {
7101 switch (ins->opcode) {
7106 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7111 if (ins->opcode == OP_VPHI) {
7112 /* Treat valuetype PHI nodes as operating on the address itself */
7113 g_assert (ins->klass);
7114 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7118 * Have to precreate these, as they can be referenced by
7119 * earlier instructions.
7121 sprintf (dname_buf, "t%d", ins->dreg);
7123 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7125 if (ins->opcode == OP_VPHI)
7126 ctx->addresses [ins->dreg] = values [ins->dreg];
7128 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7131 * Set the expected type of the incoming arguments since these have
7132 * to have the same type.
7134 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7135 int sreg1 = ins->inst_phi_args [i + 1];
7138 if (ins->opcode == OP_VPHI)
7139 ctx->is_vphi [sreg1] = TRUE;
7140 ctx->vreg_types [sreg1] = phi_type;
7146 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7155 * Create an ordering for bblocks, use the depth first order first, then
7156 * put the exception handling bblocks last.
7158 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7159 bb = cfg->bblocks [bb_index];
7160 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7161 g_ptr_array_add (bblock_list, bb);
7162 bblocks [bb->block_num].added = TRUE;
7166 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7167 if (!bblocks [bb->block_num].added)
7168 g_ptr_array_add (bblock_list, bb);
7172 * Second pass: generate code.
7175 LLVMBuilderRef entry_builder = create_builder (ctx);
7176 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7177 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7178 emit_entry_bb (ctx, entry_builder);
7180 // Make landing pads first
7181 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7183 if (ctx->llvm_only) {
7184 size_t group_index = 0;
7185 while (group_index < cfg->header->num_clauses) {
7187 size_t cursor = group_index;
7188 while (cursor < cfg->header->num_clauses &&
7189 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7190 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7195 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7196 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7197 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7199 group_index = cursor;
7203 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7204 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7206 // Prune unreachable mono BBs.
7207 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7210 process_bb (ctx, bb);
7214 g_hash_table_destroy (ctx->exc_meta);
7216 mono_memory_barrier ();
7218 /* Add incoming phi values */
7219 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7220 GSList *l, *ins_list;
7222 ins_list = bblocks [bb->block_num].phi_nodes;
7224 for (l = ins_list; l; l = l->next) {
7225 PhiNode *node = (PhiNode*)l->data;
7226 MonoInst *phi = node->phi;
7227 int sreg1 = node->sreg;
7228 LLVMBasicBlockRef in_bb;
7233 in_bb = get_end_bb (ctx, node->in_bb);
7235 if (ctx->unreachable [node->in_bb->block_num])
7238 if (!values [sreg1]) {
7239 /* Can happen with values in EH clauses */
7240 set_failure (ctx, "incoming phi sreg1");
7244 if (phi->opcode == OP_VPHI) {
7245 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7246 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7248 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7249 set_failure (ctx, "incoming phi arg type mismatch");
7252 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7253 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7258 /* Nullify empty phi instructions */
7259 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7260 GSList *l, *ins_list;
7262 ins_list = bblocks [bb->block_num].phi_nodes;
7264 for (l = ins_list; l; l = l->next) {
7265 PhiNode *node = (PhiNode*)l->data;
7266 MonoInst *phi = node->phi;
7267 LLVMValueRef phi_ins = values [phi->dreg];
7270 /* Already removed */
7273 if (LLVMCountIncoming (phi_ins) == 0) {
7274 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7275 LLVMInstructionEraseFromParent (phi_ins);
7276 values [phi->dreg] = NULL;
7281 /* Create the SWITCH statements for ENDFINALLY instructions */
7282 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7283 BBInfo *info = &bblocks [bb->block_num];
7285 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7286 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7287 GSList *bb_list = info->call_handler_return_bbs;
7289 for (i = 0; i < g_slist_length (bb_list); ++i)
7290 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7294 /* Initialize the method if needed */
7295 if (cfg->compile_aot && ctx->llvm_only) {
7296 // FIXME: Add more shared got entries
7297 ctx->builder = create_builder (ctx);
7298 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7300 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7302 // FIXME: beforefieldinit
7304 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7305 * in load_method ().
7307 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7309 * linkonce methods shouldn't have initialization,
7310 * because they might belong to assemblies which
7311 * haven't been loaded yet.
7313 g_assert (!ctx->is_linkonce);
7314 emit_init_method (ctx);
7316 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7320 if (cfg->llvm_only) {
7321 GHashTableIter iter;
7323 GSList *callers, *l, *l2;
7326 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7327 * We can't do this earlier, as it contains llvm instructions which can be
7328 * freed if compilation fails.
7329 * FIXME: Get rid of this when all methods can be llvm compiled.
7331 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7332 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7333 for (l = callers; l; l = l->next) {
7334 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7335 l2 = g_slist_prepend (l2, l->data);
7336 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7341 if (cfg->verbose_level > 1)
7342 mono_llvm_dump_value (method);
7344 if (cfg->compile_aot && !cfg->llvm_only)
7345 mark_as_used (ctx->module, method);
7347 if (!cfg->llvm_only) {
7348 LLVMValueRef md_args [16];
7349 LLVMValueRef md_node;
7352 if (cfg->compile_aot)
7353 method_index = mono_aot_get_method_index (cfg->orig_method);
7356 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7357 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7358 md_node = LLVMMDNode (md_args, 2);
7359 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7360 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7363 if (cfg->compile_aot) {
7364 /* Don't generate native code, keep the LLVM IR */
7365 if (cfg->verbose_level)
7366 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7368 #if LLVM_API_VERSION < 100
7369 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7370 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7371 g_assert (err == 0);
7374 //LLVMVerifyFunction(method, 0);
7375 #if LLVM_API_VERSION > 100
7376 MonoDomain *domain = mono_domain_get ();
7377 MonoJitDomainInfo *domain_info;
7378 int nvars = g_hash_table_size (ctx->jit_callees);
7379 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7380 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7381 GHashTableIter iter;
7387 * Compute the addresses of the LLVM globals pointing to the
7388 * methods called by the current method. Pass it to the trampoline
7389 * code so it can update them after their corresponding method was
7392 g_hash_table_iter_init (&iter, ctx->jit_callees);
7394 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7395 callee_vars [i ++] = var;
7397 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7399 decode_llvm_eh_info (ctx, eh_frame);
7401 mono_domain_lock (domain);
7402 domain_info = domain_jit_info (domain);
7403 if (!domain_info->llvm_jit_callees)
7404 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7405 g_hash_table_iter_init (&iter, ctx->jit_callees);
7407 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7408 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7409 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7410 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7413 mono_domain_unlock (domain);
7415 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7417 if (cfg->verbose_level > 1)
7418 mono_llvm_dump_value (ctx->lmethod);
7420 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7422 /* Set by emit_cb */
7423 g_assert (cfg->code_len);
7427 if (ctx->module->method_to_lmethod)
7428 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7429 if (ctx->module->idx_to_lmethod)
7430 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7432 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7433 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7437 * mono_llvm_create_vars:
7439 * Same as mono_arch_create_vars () for LLVM.
7442 mono_llvm_create_vars (MonoCompile *cfg)
7444 MonoMethodSignature *sig;
7446 sig = mono_method_signature (cfg->method);
7447 if (cfg->gsharedvt && cfg->llvm_only) {
7448 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7449 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7450 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7451 printf ("vret_addr = ");
7452 mono_print_ins (cfg->vret_addr);
7456 mono_arch_create_vars (cfg);
7461 * mono_llvm_emit_call:
7463 * Same as mono_arch_emit_call () for LLVM.
7466 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7469 MonoMethodSignature *sig;
7470 int i, n, stack_size;
7475 sig = call->signature;
7476 n = sig->param_count + sig->hasthis;
7478 call->cinfo = get_llvm_call_info (cfg, sig);
7480 if (cfg->disable_llvm)
7483 if (sig->call_convention == MONO_CALL_VARARG) {
7484 cfg->exception_message = g_strdup ("varargs");
7485 cfg->disable_llvm = TRUE;
7488 for (i = 0; i < n; ++i) {
7491 ainfo = call->cinfo->args + i;
7493 in = call->args [i];
7495 /* Simply remember the arguments */
7496 switch (ainfo->storage) {
7497 case LLVMArgNormal: {
7498 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7501 opcode = mono_type_to_regmove (cfg, t);
7502 if (opcode == OP_FMOVE) {
7503 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7504 ins->dreg = mono_alloc_freg (cfg);
7505 } else if (opcode == OP_LMOVE) {
7506 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7507 ins->dreg = mono_alloc_lreg (cfg);
7508 } else if (opcode == OP_RMOVE) {
7509 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7510 ins->dreg = mono_alloc_freg (cfg);
7512 MONO_INST_NEW (cfg, ins, OP_MOVE);
7513 ins->dreg = mono_alloc_ireg (cfg);
7515 ins->sreg1 = in->dreg;
7518 case LLVMArgVtypeByVal:
7519 case LLVMArgVtypeByRef:
7520 case LLVMArgVtypeInReg:
7521 case LLVMArgVtypeAsScalar:
7522 case LLVMArgAsIArgs:
7523 case LLVMArgAsFpArgs:
7524 case LLVMArgGsharedvtVariable:
7525 case LLVMArgGsharedvtFixed:
7526 case LLVMArgGsharedvtFixedVtype:
7527 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7528 ins->dreg = mono_alloc_ireg (cfg);
7529 ins->sreg1 = in->dreg;
7530 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7531 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7532 ins->inst_vtype = ainfo->type;
7533 ins->klass = mono_class_from_mono_type (ainfo->type);
7536 cfg->exception_message = g_strdup ("ainfo->storage");
7537 cfg->disable_llvm = TRUE;
7541 if (!cfg->disable_llvm) {
7542 MONO_ADD_INS (cfg->cbb, ins);
7543 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7548 static unsigned char*
7549 alloc_cb (LLVMValueRef function, int size)
7553 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7557 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7559 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7564 emitted_cb (LLVMValueRef function, void *start, void *end)
7568 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7570 cfg->code_len = (guint8*)end - (guint8*)start;
7574 exception_cb (void *data)
7577 MonoJitExceptionInfo *ei;
7578 guint32 ei_len, i, j, nested_len, nindex;
7579 gpointer *type_info;
7580 int this_reg, this_offset;
7582 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7586 * data points to a DWARF FDE structure, convert it to our unwind format and
7588 * An alternative would be to save it directly, and modify our unwinder to work
7591 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);
7592 if (cfg->verbose_level > 1)
7593 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7595 /* Count nested clauses */
7597 for (i = 0; i < ei_len; ++i) {
7598 gint32 cindex1 = *(gint32*)type_info [i];
7599 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7601 for (j = 0; j < cfg->header->num_clauses; ++j) {
7603 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7605 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7611 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7612 cfg->llvm_ex_info_len = ei_len + nested_len;
7613 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7614 /* Fill the rest of the information from the type info */
7615 for (i = 0; i < ei_len; ++i) {
7616 gint32 clause_index = *(gint32*)type_info [i];
7617 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7619 cfg->llvm_ex_info [i].flags = clause->flags;
7620 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7621 cfg->llvm_ex_info [i].clause_index = clause_index;
7625 * For nested clauses, the LLVM produced exception info associates the try interval with
7626 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7627 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7628 * and everything else from the nested clause.
7631 for (i = 0; i < ei_len; ++i) {
7632 gint32 cindex1 = *(gint32*)type_info [i];
7633 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7635 for (j = 0; j < cfg->header->num_clauses; ++j) {
7637 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7638 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7640 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7641 /* clause1 is the nested clause */
7642 nested_ei = &cfg->llvm_ex_info [i];
7643 nesting_ei = &cfg->llvm_ex_info [nindex];
7646 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7648 nesting_ei->flags = clause2->flags;
7649 nesting_ei->data.catch_class = clause2->data.catch_class;
7650 nesting_ei->clause_index = cindex2;
7654 g_assert (nindex == ei_len + nested_len);
7655 cfg->llvm_this_reg = this_reg;
7656 cfg->llvm_this_offset = this_offset;
7658 /* type_info [i] is cfg mempool allocated, no need to free it */
7664 #if LLVM_API_VERSION > 100
7666 * decode_llvm_eh_info:
7668 * Decode the EH table emitted by llvm in jit mode, and store
7669 * the result into cfg.
7672 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7674 MonoCompile *cfg = ctx->cfg;
7677 MonoLLVMFDEInfo info;
7678 MonoJitExceptionInfo *ei;
7679 guint8 *p = eh_frame;
7680 int version, fde_count, fde_offset;
7681 guint32 ei_len, i, nested_len;
7682 gpointer *type_info;
7686 * Decode the one element EH table emitted by the MonoException class
7690 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7693 g_assert (version == 3);
7696 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7698 fde_count = *(guint32*)p;
7702 g_assert (fde_count <= 2);
7704 /* The first entry is the real method */
7705 g_assert (table [0] == 1);
7706 fde_offset = table [1];
7707 table += fde_count * 2;
7709 cfg->code_len = table [0];
7710 fde_len = table [1] - fde_offset;
7713 fde = (guint8*)eh_frame + fde_offset;
7714 cie = (guint8*)table;
7716 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7718 cfg->encoded_unwind_ops = info.unw_info;
7719 cfg->encoded_unwind_ops_len = info.unw_info_len;
7720 if (cfg->verbose_level > 1)
7721 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7722 if (info.this_reg != -1) {
7723 cfg->llvm_this_reg = info.this_reg;
7724 cfg->llvm_this_offset = info.this_offset;
7728 ei_len = info.ex_info_len;
7729 type_info = info.type_info;
7731 // Nested clauses are currently disabled
7734 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7735 cfg->llvm_ex_info_len = ei_len + nested_len;
7736 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7737 /* Fill the rest of the information from the type info */
7738 for (i = 0; i < ei_len; ++i) {
7739 gint32 clause_index = *(gint32*)type_info [i];
7740 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7742 cfg->llvm_ex_info [i].flags = clause->flags;
7743 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7744 cfg->llvm_ex_info [i].clause_index = clause_index;
7750 dlsym_cb (const char *name, void **symbol)
7756 if (!strcmp (name, "__bzero")) {
7757 *symbol = (void*)bzero;
7759 current = mono_dl_open (NULL, 0, NULL);
7762 err = mono_dl_symbol (current, name, symbol);
7764 mono_dl_close (current);
7766 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7767 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7773 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7775 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7779 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7781 LLVMTypeRef param_types [4];
7783 param_types [0] = param_type1;
7784 param_types [1] = param_type2;
7786 AddFunc (module, name, ret_type, param_types, 2);
7792 INTRINS_SADD_OVF_I32,
7793 INTRINS_UADD_OVF_I32,
7794 INTRINS_SSUB_OVF_I32,
7795 INTRINS_USUB_OVF_I32,
7796 INTRINS_SMUL_OVF_I32,
7797 INTRINS_UMUL_OVF_I32,
7798 INTRINS_SADD_OVF_I64,
7799 INTRINS_UADD_OVF_I64,
7800 INTRINS_SSUB_OVF_I64,
7801 INTRINS_USUB_OVF_I64,
7802 INTRINS_SMUL_OVF_I64,
7803 INTRINS_UMUL_OVF_I64,
7810 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7811 INTRINS_SSE_PMOVMSKB,
7812 INTRINS_SSE_PSRLI_W,
7813 INTRINS_SSE_PSRAI_W,
7814 INTRINS_SSE_PSLLI_W,
7815 INTRINS_SSE_PSRLI_D,
7816 INTRINS_SSE_PSRAI_D,
7817 INTRINS_SSE_PSLLI_D,
7818 INTRINS_SSE_PSRLI_Q,
7819 INTRINS_SSE_PSLLI_Q,
7820 INTRINS_SSE_SQRT_PD,
7821 INTRINS_SSE_SQRT_PS,
7822 INTRINS_SSE_RSQRT_PS,
7824 INTRINS_SSE_CVTTPD2DQ,
7825 INTRINS_SSE_CVTTPS2DQ,
7826 INTRINS_SSE_CVTDQ2PD,
7827 INTRINS_SSE_CVTDQ2PS,
7828 INTRINS_SSE_CVTPD2DQ,
7829 INTRINS_SSE_CVTPS2DQ,
7830 INTRINS_SSE_CVTPD2PS,
7831 INTRINS_SSE_CVTPS2PD,
7834 INTRINS_SSE_PACKSSWB,
7835 INTRINS_SSE_PACKUSWB,
7836 INTRINS_SSE_PACKSSDW,
7837 INTRINS_SSE_PACKUSDW,
7842 INTRINS_SSE_ADDSUBPS,
7847 INTRINS_SSE_ADDSUBPD,
7850 INTRINS_SSE_PADDUSW,
7851 INTRINS_SSE_PSUBUSW,
7857 INTRINS_SSE_PADDUSB,
7858 INTRINS_SSE_PSUBUSB,
7870 static IntrinsicDesc intrinsics[] = {
7871 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7872 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7873 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7874 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7875 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7876 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7877 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7878 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7879 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7880 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7881 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7882 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7883 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7884 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7885 {INTRINS_SIN, "llvm.sin.f64"},
7886 {INTRINS_COS, "llvm.cos.f64"},
7887 {INTRINS_SQRT, "llvm.sqrt.f64"},
7888 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7889 {INTRINS_FABS, "fabs"},
7890 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7891 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7892 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7893 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7894 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7895 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7896 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7897 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7898 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7899 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7900 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7901 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7902 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7903 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7904 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7905 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7906 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7907 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7908 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7909 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7910 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7911 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7912 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7913 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7914 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7915 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7916 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7917 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7918 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7919 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7920 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7921 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7922 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7923 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7924 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7925 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7926 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7927 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7928 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7929 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7930 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7931 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7932 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7933 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7934 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7935 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7936 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7937 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7938 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7939 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7940 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7941 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7942 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7947 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7949 LLVMTypeRef ret_type = type_to_simd_type (type);
7950 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7954 add_intrinsic (LLVMModuleRef module, int id)
7957 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7958 LLVMTypeRef ret_type, arg_types [16];
7961 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7965 case INTRINS_MEMSET: {
7966 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7968 AddFunc (module, name, LLVMVoidType (), params, 5);
7971 case INTRINS_MEMCPY: {
7972 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7974 AddFunc (module, name, LLVMVoidType (), params, 5);
7977 case INTRINS_SADD_OVF_I32:
7978 case INTRINS_UADD_OVF_I32:
7979 case INTRINS_SSUB_OVF_I32:
7980 case INTRINS_USUB_OVF_I32:
7981 case INTRINS_SMUL_OVF_I32:
7982 case INTRINS_UMUL_OVF_I32: {
7983 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7984 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7985 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7987 AddFunc (module, name, ret_type, params, 2);
7990 case INTRINS_SADD_OVF_I64:
7991 case INTRINS_UADD_OVF_I64:
7992 case INTRINS_SSUB_OVF_I64:
7993 case INTRINS_USUB_OVF_I64:
7994 case INTRINS_SMUL_OVF_I64:
7995 case INTRINS_UMUL_OVF_I64: {
7996 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7997 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7998 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8000 AddFunc (module, name, ret_type, params, 2);
8006 case INTRINS_FABS: {
8007 LLVMTypeRef params [] = { LLVMDoubleType () };
8009 AddFunc (module, name, LLVMDoubleType (), params, 1);
8012 case INTRINS_EXPECT_I8:
8013 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8015 case INTRINS_EXPECT_I1:
8016 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8018 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8019 case INTRINS_SSE_PMOVMSKB:
8021 ret_type = LLVMInt32Type ();
8022 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8023 AddFunc (module, name, ret_type, arg_types, 1);
8025 case INTRINS_SSE_PSRLI_W:
8026 case INTRINS_SSE_PSRAI_W:
8027 case INTRINS_SSE_PSLLI_W:
8029 ret_type = type_to_simd_type (MONO_TYPE_I2);
8030 arg_types [0] = ret_type;
8031 arg_types [1] = LLVMInt32Type ();
8032 AddFunc (module, name, ret_type, arg_types, 2);
8034 case INTRINS_SSE_PSRLI_D:
8035 case INTRINS_SSE_PSRAI_D:
8036 case INTRINS_SSE_PSLLI_D:
8037 ret_type = type_to_simd_type (MONO_TYPE_I4);
8038 arg_types [0] = ret_type;
8039 arg_types [1] = LLVMInt32Type ();
8040 AddFunc (module, name, ret_type, arg_types, 2);
8042 case INTRINS_SSE_PSRLI_Q:
8043 case INTRINS_SSE_PSLLI_Q:
8044 ret_type = type_to_simd_type (MONO_TYPE_I8);
8045 arg_types [0] = ret_type;
8046 arg_types [1] = LLVMInt32Type ();
8047 AddFunc (module, name, ret_type, arg_types, 2);
8049 case INTRINS_SSE_SQRT_PD:
8051 ret_type = type_to_simd_type (MONO_TYPE_R8);
8052 arg_types [0] = ret_type;
8053 AddFunc (module, name, ret_type, arg_types, 1);
8055 case INTRINS_SSE_SQRT_PS:
8056 ret_type = type_to_simd_type (MONO_TYPE_R4);
8057 arg_types [0] = ret_type;
8058 AddFunc (module, name, ret_type, arg_types, 1);
8060 case INTRINS_SSE_RSQRT_PS:
8061 ret_type = type_to_simd_type (MONO_TYPE_R4);
8062 arg_types [0] = ret_type;
8063 AddFunc (module, name, ret_type, arg_types, 1);
8065 case INTRINS_SSE_RCP_PS:
8066 ret_type = type_to_simd_type (MONO_TYPE_R4);
8067 arg_types [0] = ret_type;
8068 AddFunc (module, name, ret_type, arg_types, 1);
8070 case INTRINS_SSE_CVTTPD2DQ:
8071 ret_type = type_to_simd_type (MONO_TYPE_I4);
8072 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8073 AddFunc (module, name, ret_type, arg_types, 1);
8075 case INTRINS_SSE_CVTTPS2DQ:
8076 ret_type = type_to_simd_type (MONO_TYPE_I4);
8077 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8078 AddFunc (module, name, ret_type, arg_types, 1);
8080 case INTRINS_SSE_CVTDQ2PD:
8081 /* Conversion ops */
8082 ret_type = type_to_simd_type (MONO_TYPE_R8);
8083 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8084 AddFunc (module, name, ret_type, arg_types, 1);
8086 case INTRINS_SSE_CVTDQ2PS:
8087 ret_type = type_to_simd_type (MONO_TYPE_R4);
8088 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8089 AddFunc (module, name, ret_type, arg_types, 1);
8091 case INTRINS_SSE_CVTPD2DQ:
8092 ret_type = type_to_simd_type (MONO_TYPE_I4);
8093 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8094 AddFunc (module, name, ret_type, arg_types, 1);
8096 case INTRINS_SSE_CVTPS2DQ:
8097 ret_type = type_to_simd_type (MONO_TYPE_I4);
8098 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8099 AddFunc (module, name, ret_type, arg_types, 1);
8101 case INTRINS_SSE_CVTPD2PS:
8102 ret_type = type_to_simd_type (MONO_TYPE_R4);
8103 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8104 AddFunc (module, name, ret_type, arg_types, 1);
8106 case INTRINS_SSE_CVTPS2PD:
8107 ret_type = type_to_simd_type (MONO_TYPE_R8);
8108 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8109 AddFunc (module, name, ret_type, arg_types, 1);
8111 case INTRINS_SSE_CMPPD:
8113 ret_type = type_to_simd_type (MONO_TYPE_R8);
8114 arg_types [0] = ret_type;
8115 arg_types [1] = ret_type;
8116 arg_types [2] = LLVMInt8Type ();
8117 AddFunc (module, name, ret_type, arg_types, 3);
8119 case INTRINS_SSE_CMPPS:
8120 ret_type = type_to_simd_type (MONO_TYPE_R4);
8121 arg_types [0] = ret_type;
8122 arg_types [1] = ret_type;
8123 arg_types [2] = LLVMInt8Type ();
8124 AddFunc (module, name, ret_type, arg_types, 3);
8126 case INTRINS_SSE_PACKSSWB:
8127 case INTRINS_SSE_PACKUSWB:
8128 case INTRINS_SSE_PACKSSDW:
8130 ret_type = type_to_simd_type (MONO_TYPE_I1);
8131 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8132 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8133 AddFunc (module, name, ret_type, arg_types, 2);
8135 case INTRINS_SSE_PACKUSDW:
8136 ret_type = type_to_simd_type (MONO_TYPE_I2);
8137 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8138 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8139 AddFunc (module, name, ret_type, arg_types, 2);
8141 /* SSE Binary ops */
8142 case INTRINS_SSE_PADDSW:
8143 case INTRINS_SSE_PSUBSW:
8144 case INTRINS_SSE_PADDUSW:
8145 case INTRINS_SSE_PSUBUSW:
8146 case INTRINS_SSE_PAVGW:
8147 case INTRINS_SSE_PMULHW:
8148 case INTRINS_SSE_PMULHU:
8149 add_sse_binary (module, name, MONO_TYPE_I2);
8151 case INTRINS_SSE_MINPS:
8152 case INTRINS_SSE_MAXPS:
8153 case INTRINS_SSE_HADDPS:
8154 case INTRINS_SSE_HSUBPS:
8155 case INTRINS_SSE_ADDSUBPS:
8156 add_sse_binary (module, name, MONO_TYPE_R4);
8158 case INTRINS_SSE_MINPD:
8159 case INTRINS_SSE_MAXPD:
8160 case INTRINS_SSE_HADDPD:
8161 case INTRINS_SSE_HSUBPD:
8162 case INTRINS_SSE_ADDSUBPD:
8163 add_sse_binary (module, name, MONO_TYPE_R8);
8165 case INTRINS_SE_PADDSB:
8166 case INTRINS_SSE_PSUBSB:
8167 case INTRINS_SSE_PADDUSB:
8168 case INTRINS_SSE_PSUBUSB:
8169 case INTRINS_SSE_PAVGB:
8170 add_sse_binary (module, name, MONO_TYPE_I1);
8172 case INTRINS_SSE_PAUSE:
8173 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8177 g_assert_not_reached ();
8183 get_intrinsic (EmitContext *ctx, const char *name)
8185 #if LLVM_API_VERSION > 100
8189 * Every method is emitted into its own module so
8190 * we can add intrinsics on demand.
8192 res = LLVMGetNamedFunction (ctx->lmodule, name);
8196 /* No locking needed */
8197 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8200 printf ("%s\n", name);
8201 g_assert (id != -1);
8202 add_intrinsic (ctx->lmodule, id);
8203 res = LLVMGetNamedFunction (ctx->lmodule, name);
8211 res = LLVMGetNamedFunction (ctx->lmodule, name);
8218 add_intrinsics (LLVMModuleRef module)
8222 /* Emit declarations of instrinsics */
8224 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8225 * type doesn't seem to do any locking.
8227 for (i = 0; i < INTRINS_NUM; ++i)
8228 add_intrinsic (module, i);
8232 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8234 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8237 /* Load/Store intrinsics */
8239 LLVMTypeRef arg_types [5];
8243 for (i = 1; i <= 8; i *= 2) {
8244 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8245 arg_types [1] = LLVMInt32Type ();
8246 arg_types [2] = LLVMInt1Type ();
8247 arg_types [3] = LLVMInt32Type ();
8248 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8249 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8251 arg_types [0] = LLVMIntType (i * 8);
8252 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8253 arg_types [2] = LLVMInt32Type ();
8254 arg_types [3] = LLVMInt1Type ();
8255 arg_types [4] = LLVMInt32Type ();
8256 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8257 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8263 add_types (MonoLLVMModule *module)
8265 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8269 mono_llvm_init (void)
8274 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8276 h = g_hash_table_new (NULL, NULL);
8277 for (i = 0; i < INTRINS_NUM; ++i)
8278 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8279 intrins_id_to_name = h;
8281 h = g_hash_table_new (g_str_hash, g_str_equal);
8282 for (i = 0; i < INTRINS_NUM; ++i)
8283 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8284 intrins_name_to_id = h;
8288 init_jit_module (MonoDomain *domain)
8290 MonoJitDomainInfo *dinfo;
8291 MonoLLVMModule *module;
8294 dinfo = domain_jit_info (domain);
8295 if (dinfo->llvm_module)
8298 mono_loader_lock ();
8300 if (dinfo->llvm_module) {
8301 mono_loader_unlock ();
8305 module = g_new0 (MonoLLVMModule, 1);
8307 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8308 module->lmodule = LLVMModuleCreateWithName (name);
8309 module->context = LLVMGetGlobalContext ();
8311 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8313 add_intrinsics (module->lmodule);
8316 module->llvm_types = g_hash_table_new (NULL, NULL);
8318 #if LLVM_API_VERSION < 100
8319 MonoJitICallInfo *info;
8321 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8323 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8326 mono_memory_barrier ();
8328 dinfo->llvm_module = module;
8330 mono_loader_unlock ();
8334 mono_llvm_cleanup (void)
8336 MonoLLVMModule *module = &aot_module;
8338 if (module->lmodule)
8339 LLVMDisposeModule (module->lmodule);
8341 if (module->context)
8342 LLVMContextDispose (module->context);
8346 mono_llvm_free_domain_info (MonoDomain *domain)
8348 MonoJitDomainInfo *info = domain_jit_info (domain);
8349 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8355 if (module->llvm_types)
8356 g_hash_table_destroy (module->llvm_types);
8358 mono_llvm_dispose_ee (module->mono_ee);
8360 if (module->bb_names) {
8361 for (i = 0; i < module->bb_names_len; ++i)
8362 g_free (module->bb_names [i]);
8363 g_free (module->bb_names);
8365 //LLVMDisposeModule (module->module);
8369 info->llvm_module = NULL;
8373 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8375 MonoLLVMModule *module = &aot_module;
8377 /* Delete previous module */
8378 if (module->plt_entries)
8379 g_hash_table_destroy (module->plt_entries);
8380 if (module->lmodule)
8381 LLVMDisposeModule (module->lmodule);
8383 memset (module, 0, sizeof (aot_module));
8385 module->lmodule = LLVMModuleCreateWithName ("aot");
8386 module->assembly = assembly;
8387 module->global_prefix = g_strdup (global_prefix);
8388 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8389 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8390 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8391 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8392 module->external_symbols = TRUE;
8393 module->emit_dwarf = emit_dwarf;
8394 module->static_link = static_link;
8395 module->llvm_only = llvm_only;
8396 /* The first few entries are reserved */
8397 module->max_got_offset = 16;
8398 module->context = LLVMGetGlobalContext ();
8401 /* clang ignores our debug info because it has an invalid version */
8402 module->emit_dwarf = FALSE;
8404 add_intrinsics (module->lmodule);
8407 #if LLVM_API_VERSION > 100
8408 if (module->emit_dwarf) {
8409 char *dir, *build_info, *s, *cu_name;
8411 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8414 dir = g_strdup (".");
8415 build_info = mono_get_runtime_build_info ();
8416 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8417 cu_name = g_path_get_basename (assembly->image->name);
8418 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8420 g_free (build_info);
8427 * We couldn't compute the type of the LLVM global representing the got because
8428 * its size is only known after all the methods have been emitted. So create
8429 * a dummy variable, and replace all uses it with the real got variable when
8430 * its size is known in mono_llvm_emit_aot_module ().
8433 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8435 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8436 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8439 /* Add initialization array */
8441 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8443 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8444 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8448 emit_init_icall_wrappers (module);
8450 emit_llvm_code_start (module);
8452 /* Add a dummy personality function */
8453 if (!use_debug_personality) {
8454 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8455 LLVMSetLinkage (personality, LLVMExternalLinkage);
8456 mark_as_used (module, personality);
8459 /* Add a reference to the c++ exception we throw/catch */
8461 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8462 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8463 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8464 mono_llvm_set_is_constant (module->sentinel_exception);
8467 module->llvm_types = g_hash_table_new (NULL, NULL);
8468 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8469 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8470 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8471 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8472 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8473 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8474 module->method_to_callers = g_hash_table_new (NULL, NULL);
8478 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8481 LLVMValueRef res, *vals;
8483 vals = g_new0 (LLVMValueRef, nvalues);
8484 for (i = 0; i < nvalues; ++i)
8485 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8486 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8492 llvm_array_from_bytes (guint8 *values, int nvalues)
8495 LLVMValueRef res, *vals;
8497 vals = g_new0 (LLVMValueRef, nvalues);
8498 for (i = 0; i < nvalues; ++i)
8499 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8500 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8505 * mono_llvm_emit_aot_file_info:
8507 * Emit the MonoAotFileInfo structure.
8508 * Same as emit_aot_file_info () in aot-compiler.c.
8511 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8513 MonoLLVMModule *module = &aot_module;
8515 /* Save these for later */
8516 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8517 module->has_jitted_code = has_jitted_code;
8521 * mono_llvm_emit_aot_data:
8523 * Emit the binary data DATA pointed to by symbol SYMBOL.
8526 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8528 MonoLLVMModule *module = &aot_module;
8532 type = LLVMArrayType (LLVMInt8Type (), data_len);
8533 d = LLVMAddGlobal (module->lmodule, type, symbol);
8534 LLVMSetVisibility (d, LLVMHiddenVisibility);
8535 LLVMSetLinkage (d, LLVMInternalLinkage);
8536 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8537 mono_llvm_set_is_constant (d);
8540 /* Add a reference to a global defined in JITted code */
8542 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8547 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8548 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8554 emit_aot_file_info (MonoLLVMModule *module)
8556 LLVMTypeRef file_info_type;
8557 LLVMTypeRef *eltypes, eltype;
8558 LLVMValueRef info_var;
8559 LLVMValueRef *fields;
8560 int i, nfields, tindex;
8561 MonoAotFileInfo *info;
8562 LLVMModuleRef lmodule = module->lmodule;
8564 info = &module->aot_info;
8566 /* Create an LLVM type to represent MonoAotFileInfo */
8567 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8568 eltypes = g_new (LLVMTypeRef, nfields);
8570 eltypes [tindex ++] = LLVMInt32Type ();
8571 eltypes [tindex ++] = LLVMInt32Type ();
8573 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8574 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8576 for (i = 0; i < 15; ++i)
8577 eltypes [tindex ++] = LLVMInt32Type ();
8579 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8580 for (i = 0; i < 4; ++i)
8581 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8582 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8583 g_assert (tindex == nfields);
8584 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8585 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8587 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8588 if (module->static_link) {
8589 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8590 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8592 fields = g_new (LLVMValueRef, nfields);
8594 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8595 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8599 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8600 * for symbols defined in the .s file emitted by the aot compiler.
8602 eltype = eltypes [tindex];
8603 if (module->llvm_only)
8604 fields [tindex ++] = LLVMConstNull (eltype);
8606 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8607 fields [tindex ++] = module->got_var;
8608 /* llc defines this directly */
8609 if (!module->llvm_only) {
8610 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8611 fields [tindex ++] = LLVMConstNull (eltype);
8612 fields [tindex ++] = LLVMConstNull (eltype);
8614 fields [tindex ++] = LLVMConstNull (eltype);
8615 fields [tindex ++] = module->get_method;
8616 fields [tindex ++] = module->get_unbox_tramp;
8618 if (module->has_jitted_code) {
8619 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8620 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8622 fields [tindex ++] = LLVMConstNull (eltype);
8623 fields [tindex ++] = LLVMConstNull (eltype);
8625 if (!module->llvm_only)
8626 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8628 fields [tindex ++] = LLVMConstNull (eltype);
8629 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8630 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8631 fields [tindex ++] = LLVMConstNull (eltype);
8633 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8634 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8635 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8636 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8637 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8638 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8639 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8640 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8641 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8642 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8644 /* Not needed (mem_end) */
8645 fields [tindex ++] = LLVMConstNull (eltype);
8646 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8647 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8648 if (info->trampoline_size [0]) {
8649 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8650 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8651 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8652 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8654 fields [tindex ++] = LLVMConstNull (eltype);
8655 fields [tindex ++] = LLVMConstNull (eltype);
8656 fields [tindex ++] = LLVMConstNull (eltype);
8657 fields [tindex ++] = LLVMConstNull (eltype);
8659 if (module->static_link && !module->llvm_only)
8660 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8662 fields [tindex ++] = LLVMConstNull (eltype);
8663 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8664 if (!module->llvm_only) {
8665 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8666 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8667 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8668 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8669 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8670 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8672 fields [tindex ++] = LLVMConstNull (eltype);
8673 fields [tindex ++] = LLVMConstNull (eltype);
8674 fields [tindex ++] = LLVMConstNull (eltype);
8675 fields [tindex ++] = LLVMConstNull (eltype);
8676 fields [tindex ++] = LLVMConstNull (eltype);
8677 fields [tindex ++] = LLVMConstNull (eltype);
8680 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8681 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8684 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8685 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8686 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8687 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8688 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8689 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8690 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8691 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8692 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8693 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8694 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8695 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8696 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8697 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8698 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8700 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8701 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8702 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8703 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8704 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8706 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8707 g_assert (tindex == nfields);
8709 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8711 if (module->static_link) {
8715 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8716 /* Get rid of characters which cannot occur in symbols */
8718 for (p = s; *p; ++p) {
8719 if (!(isalnum (*p) || *p == '_'))
8722 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8724 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8725 LLVMSetLinkage (var, LLVMExternalLinkage);
8730 * Emit the aot module into the LLVM bitcode file FILENAME.
8733 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8735 LLVMTypeRef got_type, inited_type;
8736 LLVMValueRef real_got, real_inited;
8737 MonoLLVMModule *module = &aot_module;
8739 emit_llvm_code_end (module);
8742 * Create the real got variable and replace all uses of the dummy variable with
8745 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8746 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8747 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8748 if (module->external_symbols) {
8749 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8750 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8752 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8754 mono_llvm_replace_uses_of (module->got_var, real_got);
8756 mark_as_used (&aot_module, real_got);
8758 /* Delete the dummy got so it doesn't become a global */
8759 LLVMDeleteGlobal (module->got_var);
8760 module->got_var = real_got;
8763 * Same for the init_var
8765 if (module->llvm_only) {
8766 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8767 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8768 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8769 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8770 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8771 LLVMDeleteGlobal (module->inited_var);
8774 if (module->llvm_only) {
8775 emit_get_method (&aot_module);
8776 emit_get_unbox_tramp (&aot_module);
8779 emit_llvm_used (&aot_module);
8780 emit_dbg_info (&aot_module, filename, cu_name);
8781 emit_aot_file_info (&aot_module);
8784 * Replace GOT entries for directly callable methods with the methods themselves.
8785 * It would be easier to implement this by predefining all methods before compiling
8786 * their bodies, but that couldn't handle the case when a method fails to compile
8789 if (module->llvm_only) {
8790 GHashTableIter iter;
8792 GSList *callers, *l;
8794 g_hash_table_iter_init (&iter, module->method_to_callers);
8795 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8796 LLVMValueRef lmethod;
8798 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8801 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8803 for (l = callers; l; l = l->next) {
8804 LLVMValueRef caller = (LLVMValueRef)l->data;
8806 mono_llvm_replace_uses_of (caller, lmethod);
8812 /* Replace PLT entries for directly callable methods with the methods themselves */
8814 GHashTableIter iter;
8816 LLVMValueRef callee;
8818 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8819 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8820 if (mono_aot_is_direct_callable (ji)) {
8821 LLVMValueRef lmethod;
8823 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8824 /* The types might not match because the caller might pass an rgctx */
8825 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8826 mono_llvm_replace_uses_of (callee, lmethod);
8827 mono_aot_mark_unused_llvm_plt_entry (ji);
8837 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8838 printf ("%s\n", verifier_err);
8839 g_assert_not_reached ();
8844 LLVMWriteBitcodeToFile (module->lmodule, filename);
8849 md_string (const char *s)
8851 return LLVMMDString (s, strlen (s));
8854 /* Debugging support */
8857 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8859 LLVMModuleRef lmodule = module->lmodule;
8860 LLVMValueRef args [16], ver;
8863 * This can only be enabled when LLVM code is emitted into a separate object
8864 * file, since the AOT compiler also emits dwarf info,
8865 * and the abbrev indexes will not be correct since llvm has added its own
8868 if (!module->emit_dwarf)
8871 #if LLVM_API_VERSION > 100
8872 mono_llvm_di_builder_finalize (module->di_builder);
8874 LLVMValueRef cu_args [16], cu;
8876 char *build_info, *s, *dir;
8879 * Emit dwarf info in the form of LLVM metadata. There is some
8880 * out-of-date documentation at:
8881 * http://llvm.org/docs/SourceLevelDebugging.html
8882 * but most of this was gathered from the llvm and
8887 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8888 /* CU name/compilation dir */
8889 dir = g_path_get_dirname (filename);
8890 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8891 args [1] = LLVMMDString (dir, strlen (dir));
8892 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8895 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8897 build_info = mono_get_runtime_build_info ();
8898 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8899 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8900 g_free (build_info);
8902 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8904 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8905 /* Runtime version */
8906 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8908 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8909 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8911 if (module->subprogram_mds) {
8915 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8916 for (i = 0; i < module->subprogram_mds->len; ++i)
8917 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8918 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8920 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8923 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8924 /* Imported modules */
8925 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8927 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8928 /* DebugEmissionKind = FullDebug */
8929 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8930 cu = LLVMMDNode (cu_args, n_cuargs);
8931 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8934 #if LLVM_API_VERSION > 100
8935 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8936 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8937 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8938 ver = LLVMMDNode (args, 3);
8939 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8941 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8942 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8943 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8944 ver = LLVMMDNode (args, 3);
8945 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8947 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8948 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8949 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8950 ver = LLVMMDNode (args, 3);
8951 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8953 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8954 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8955 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8956 ver = LLVMMDNode (args, 3);
8957 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8962 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8964 MonoLLVMModule *module = ctx->module;
8965 MonoDebugMethodInfo *minfo = ctx->minfo;
8966 char *source_file, *dir, *filename;
8967 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8968 MonoSymSeqPoint *sym_seq_points;
8974 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8976 source_file = g_strdup ("<unknown>");
8977 dir = g_path_get_dirname (source_file);
8978 filename = g_path_get_basename (source_file);
8980 #if LLVM_API_VERSION > 100
8981 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);
8984 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8985 args [0] = md_string (filename);
8986 args [1] = md_string (dir);
8987 ctx_args [1] = LLVMMDNode (args, 2);
8988 ctx_md = LLVMMDNode (ctx_args, 2);
8990 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8991 type_args [1] = NULL;
8992 type_args [2] = NULL;
8993 type_args [3] = LLVMMDString ("", 0);
8994 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8995 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8996 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8997 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8998 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8999 type_args [9] = NULL;
9000 type_args [10] = NULL;
9001 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9002 type_args [12] = NULL;
9003 type_args [13] = NULL;
9004 type_args [14] = NULL;
9005 type_md = LLVMMDNode (type_args, 14);
9007 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9008 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9009 /* Source directory + file pair */
9010 args [0] = md_string (filename);
9011 args [1] = md_string (dir);
9012 md_args [1] = LLVMMDNode (args ,2);
9013 md_args [2] = ctx_md;
9014 md_args [3] = md_string (cfg->method->name);
9015 md_args [4] = md_string (name);
9016 md_args [5] = md_string (name);
9019 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9021 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9023 md_args [7] = type_md;
9025 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9027 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9029 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9030 /* Index into a virtual function */
9031 md_args [11] = NULL;
9032 md_args [12] = NULL;
9034 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9036 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9037 /* Pointer to LLVM function */
9038 md_args [15] = method;
9039 /* Function template parameter */
9040 md_args [16] = NULL;
9041 /* Function declaration descriptor */
9042 md_args [17] = NULL;
9043 /* List of function variables */
9044 md_args [18] = LLVMMDNode (args, 0);
9046 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9047 md = LLVMMDNode (md_args, 20);
9049 if (!module->subprogram_mds)
9050 module->subprogram_mds = g_ptr_array_new ();
9051 g_ptr_array_add (module->subprogram_mds, md);
9055 g_free (source_file);
9056 g_free (sym_seq_points);
9062 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9064 MonoCompile *cfg = ctx->cfg;
9066 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9067 MonoDebugSourceLocation *loc;
9068 LLVMValueRef loc_md;
9070 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9073 #if LLVM_API_VERSION > 100
9074 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9075 mono_llvm_di_set_location (builder, loc_md);
9077 LLVMValueRef md_args [16];
9081 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9082 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9083 md_args [nmd_args ++] = ctx->dbg_md;
9084 md_args [nmd_args ++] = NULL;
9085 loc_md = LLVMMDNode (md_args, nmd_args);
9086 LLVMSetCurrentDebugLocation (builder, loc_md);
9088 mono_debug_symfile_free_location (loc);
9094 default_mono_llvm_unhandled_exception (void)
9096 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9097 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9099 mono_unhandled_exception (target);
9100 mono_invoke_unhandled_exception_hook (target);
9101 g_assert_not_reached ();
9106 - Emit LLVM IR from the mono IR using the LLVM C API.
9107 - The original arch specific code remains, so we can fall back to it if we run
9108 into something we can't handle.
9112 A partial list of issues:
9113 - Handling of opcodes which can throw exceptions.
9115 In the mono JIT, these are implemented using code like this:
9122 push throw_pos - method
9123 call <exception trampoline>
9125 The problematic part is push throw_pos - method, which cannot be represented
9126 in the LLVM IR, since it does not support label values.
9127 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9128 be implemented in JIT mode ?
9129 -> a possible but slower implementation would use the normal exception
9130 throwing code but it would need to control the placement of the throw code
9131 (it needs to be exactly after the compare+branch).
9132 -> perhaps add a PC offset intrinsics ?
9134 - efficient implementation of .ovf opcodes.
9136 These are currently implemented as:
9137 <ins which sets the condition codes>
9140 Some overflow opcodes are now supported by LLVM SVN.
9142 - exception handling, unwinding.
9143 - SSA is disabled for methods with exception handlers
9144 - How to obtain unwind info for LLVM compiled methods ?
9145 -> this is now solved by converting the unwind info generated by LLVM
9147 - LLVM uses the c++ exception handling framework, while we use our home grown
9148 code, and couldn't use the c++ one:
9149 - its not supported under VC++, other exotic platforms.
9150 - it might be impossible to support filter clauses with it.
9154 The trampolines need a predictable call sequence, since they need to disasm
9155 the calling code to obtain register numbers / offsets.
9157 LLVM currently generates this code in non-JIT mode:
9158 mov -0x98(%rax),%eax
9160 Here, the vtable pointer is lost.
9161 -> solution: use one vtable trampoline per class.
9163 - passing/receiving the IMT pointer/RGCTX.
9164 -> solution: pass them as normal arguments ?
9168 LLVM does not allow the specification of argument registers etc. This means
9169 that all calls are made according to the platform ABI.
9171 - passing/receiving vtypes.
9173 Vtypes passed/received in registers are handled by the front end by using
9174 a signature with scalar arguments, and loading the parts of the vtype into those
9177 Vtypes passed on the stack are handled using the 'byval' attribute.
9181 Supported though alloca, we need to emit the load/store code.
9185 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9186 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9187 This is made easier because the IR is already in SSA form.
9188 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9189 types are frequently used incorrectly.
9194 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9195 it with the file containing the methods emitted by the JIT and the AOT data
9199 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9200 * - each bblock should end with a branch
9201 * - setting the return value, making cfg->ret non-volatile
9202 * - avoid some transformations in the JIT which make it harder for us to generate
9204 * - use pointer types to help optimizations.
9207 #else /* DISABLE_JIT */
9210 mono_llvm_cleanup (void)
9215 mono_llvm_free_domain_info (MonoDomain *domain)
9220 mono_llvm_init (void)
9225 default_mono_llvm_unhandled_exception (void)
9229 #endif /* DISABLE_JIT */