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)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/metadata/environment.h>
13 #include <mono/metadata/object-internals.h>
14 #include <mono/metadata/abi-details.h>
15 #include <mono/utils/mono-tls.h>
16 #include <mono/utils/mono-dl.h>
17 #include <mono/utils/mono-time.h>
18 #include <mono/utils/freebsd-dwarf.h>
20 #ifndef __STDC_LIMIT_MACROS
21 #define __STDC_LIMIT_MACROS
23 #ifndef __STDC_CONSTANT_MACROS
24 #define __STDC_CONSTANT_MACROS
27 #include "llvm-c/Core.h"
28 #include "llvm-c/ExecutionEngine.h"
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"
40 extern void *memset(void *, int, size_t);
41 void bzero (void *to, size_t count) { memset (to, 0, count); }
45 #if LLVM_API_VERSION < 4
46 #error "The version of the mono llvm repository is too old."
49 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
52 * Information associated by mono with LLVM modules.
55 LLVMModuleRef lmodule;
56 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
57 GHashTable *llvm_types;
59 const char *got_symbol;
60 const char *get_method_symbol;
61 const char *get_unbox_tramp_symbol;
62 GHashTable *plt_entries;
63 GHashTable *plt_entries_ji;
64 GHashTable *method_to_lmethod;
65 GHashTable *direct_callables;
70 GPtrArray *subprogram_mds;
72 LLVMExecutionEngineRef ee;
73 gboolean external_symbols;
78 MonoAssembly *assembly;
80 MonoAotFileInfo aot_info;
81 const char *jit_got_symbol;
82 const char *eh_frame_symbol;
83 LLVMValueRef get_method, get_unbox_tramp;
84 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
85 LLVMValueRef code_start, code_end;
86 LLVMValueRef inited_var;
87 int max_inited_idx, max_method_idx;
88 gboolean has_jitted_code;
91 GHashTable *idx_to_lmethod;
92 GHashTable *idx_to_unbox_tramp;
93 /* Maps a MonoMethod to LLVM instructions representing it */
94 GHashTable *method_to_callers;
95 LLVMContextRef context;
96 LLVMValueRef sentinel_exception;
97 void *di_builder, *cu;
101 * Information associated by the backend with mono basic blocks.
104 LLVMBasicBlockRef bblock, end_bblock;
105 LLVMValueRef finally_ind;
106 gboolean added, invoke_target;
108 * If this bblock is the start of a finally clause, this is a list of bblocks it
109 * needs to branch to in ENDFINALLY.
111 GSList *call_handler_return_bbs;
113 * If this bblock is the start of a finally clause, this is the bblock that
114 * CALL_HANDLER needs to branch to.
116 LLVMBasicBlockRef call_handler_target_bb;
117 /* The list of switch statements generated by ENDFINALLY instructions */
118 GSList *endfinally_switch_ins_list;
123 * Structure containing emit state
126 MonoMemPool *mempool;
128 /* Maps method names to the corresponding LLVMValueRef */
129 GHashTable *emitted_method_decls;
132 LLVMValueRef lmethod;
133 MonoLLVMModule *module;
134 LLVMModuleRef lmodule;
136 int sindex, default_index, ex_index;
137 LLVMBuilderRef builder;
138 LLVMValueRef *values, *addresses;
139 MonoType **vreg_cli_types;
141 MonoMethodSignature *sig;
143 GHashTable *region_to_handler;
144 GHashTable *clause_to_handler;
145 LLVMBuilderRef alloca_builder;
146 LLVMValueRef last_alloca;
147 LLVMValueRef rgctx_arg;
148 LLVMValueRef this_arg;
149 LLVMTypeRef *vreg_types;
150 LLVMTypeRef method_type;
151 LLVMBasicBlockRef init_bb, inited_bb;
153 gboolean *unreachable;
155 gboolean has_got_access;
156 gboolean is_linkonce;
157 int this_arg_pindex, rgctx_arg_pindex;
158 LLVMValueRef imt_rgctx_loc;
159 GHashTable *llvm_types;
161 MonoDebugMethodInfo *minfo;
163 /* For every clause, the clauses it is nested in */
166 GHashTable *exc_meta;
167 GHashTable *method_to_callers;
168 GPtrArray *phi_values;
169 GPtrArray *bblock_list;
171 GHashTable *jit_callees;
177 MonoBasicBlock *in_bb;
182 * Instruction metadata
183 * This is the same as ins_info, but LREG != IREG.
191 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
192 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
199 /* keep in sync with the enum in mini.h */
202 #include "mini-ops.h"
207 #if SIZEOF_VOID_P == 4
208 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
210 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
213 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
216 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
218 #define TRACE_FAILURE(msg)
222 #define IS_TARGET_X86 1
224 #define IS_TARGET_X86 0
228 #define IS_TARGET_AMD64 1
230 #define IS_TARGET_AMD64 0
233 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
235 static LLVMIntPredicate cond_to_llvm_cond [] = {
248 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
261 static MonoNativeTlsKey current_cfg_tls_id;
263 static MonoLLVMModule aot_module;
265 static GHashTable *intrins_id_to_name;
266 static GHashTable *intrins_name_to_id;
268 static void init_jit_module (MonoDomain *domain);
270 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
271 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
272 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
273 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
274 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
275 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
278 set_failure (EmitContext *ctx, const char *message)
280 TRACE_FAILURE (reason);
281 ctx->cfg->exception_message = g_strdup (message);
282 ctx->cfg->disable_llvm = TRUE;
288 * The LLVM type with width == sizeof (gpointer)
293 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
299 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
305 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
311 * Return the size of the LLVM representation of the vtype T.
314 get_vtype_size (MonoType *t)
318 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
320 /* LLVMArgAsIArgs depends on this since it stores whole words */
321 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
328 * simd_class_to_llvm_type:
330 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
333 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
335 if (!strcmp (klass->name, "Vector2d")) {
336 return LLVMVectorType (LLVMDoubleType (), 2);
337 } else if (!strcmp (klass->name, "Vector2l")) {
338 return LLVMVectorType (LLVMInt64Type (), 2);
339 } else if (!strcmp (klass->name, "Vector2ul")) {
340 return LLVMVectorType (LLVMInt64Type (), 2);
341 } else if (!strcmp (klass->name, "Vector4i")) {
342 return LLVMVectorType (LLVMInt32Type (), 4);
343 } else if (!strcmp (klass->name, "Vector4ui")) {
344 return LLVMVectorType (LLVMInt32Type (), 4);
345 } else if (!strcmp (klass->name, "Vector4f")) {
346 return LLVMVectorType (LLVMFloatType (), 4);
347 } else if (!strcmp (klass->name, "Vector8s")) {
348 return LLVMVectorType (LLVMInt16Type (), 8);
349 } else if (!strcmp (klass->name, "Vector8us")) {
350 return LLVMVectorType (LLVMInt16Type (), 8);
351 } else if (!strcmp (klass->name, "Vector16sb")) {
352 return LLVMVectorType (LLVMInt8Type (), 16);
353 } else if (!strcmp (klass->name, "Vector16b")) {
354 return LLVMVectorType (LLVMInt8Type (), 16);
356 printf ("%s\n", klass->name);
362 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
363 static inline G_GNUC_UNUSED LLVMTypeRef
364 type_to_simd_type (int type)
368 return LLVMVectorType (LLVMInt8Type (), 16);
370 return LLVMVectorType (LLVMInt16Type (), 8);
372 return LLVMVectorType (LLVMInt32Type (), 4);
374 return LLVMVectorType (LLVMInt64Type (), 2);
376 return LLVMVectorType (LLVMDoubleType (), 2);
378 return LLVMVectorType (LLVMFloatType (), 4);
380 g_assert_not_reached ();
386 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
388 int i, size, nfields, esize;
389 LLVMTypeRef *eltypes;
394 t = &klass->byval_arg;
396 if (mini_type_is_hfa (t, &nfields, &esize)) {
398 * This is needed on arm64 where HFAs are returned in
402 eltypes = g_new (LLVMTypeRef, size);
403 for (i = 0; i < size; ++i)
404 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
406 size = get_vtype_size (t);
408 eltypes = g_new (LLVMTypeRef, size);
409 for (i = 0; i < size; ++i)
410 eltypes [i] = LLVMInt8Type ();
413 name = mono_type_full_name (&klass->byval_arg);
414 ltype = LLVMStructCreateNamed (module->context, name);
415 LLVMStructSetBody (ltype, eltypes, size, FALSE);
425 * Return the LLVM type corresponding to T.
428 type_to_llvm_type (EmitContext *ctx, MonoType *t)
430 t = mini_get_underlying_type (t);
434 return LLVMVoidType ();
436 return LLVMInt8Type ();
438 return LLVMInt16Type ();
440 return LLVMInt32Type ();
442 return LLVMInt8Type ();
444 return LLVMInt16Type ();
446 return LLVMInt32Type ();
447 case MONO_TYPE_BOOLEAN:
448 return LLVMInt8Type ();
451 return LLVMInt64Type ();
453 return LLVMInt16Type ();
455 return LLVMFloatType ();
457 return LLVMDoubleType ();
460 return IntPtrType ();
461 case MONO_TYPE_OBJECT:
462 case MONO_TYPE_CLASS:
463 case MONO_TYPE_ARRAY:
464 case MONO_TYPE_SZARRAY:
465 case MONO_TYPE_STRING:
467 return ObjRefType ();
470 /* Because of generic sharing */
471 return ObjRefType ();
472 case MONO_TYPE_GENERICINST:
473 if (!mono_type_generic_inst_is_valuetype (t))
474 return ObjRefType ();
476 case MONO_TYPE_VALUETYPE:
477 case MONO_TYPE_TYPEDBYREF: {
481 klass = mono_class_from_mono_type (t);
483 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
484 return simd_class_to_llvm_type (ctx, klass);
487 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
489 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
491 ltype = create_llvm_type_for_type (ctx->module, klass);
492 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
498 printf ("X: %d\n", t->type);
499 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
500 ctx->cfg->disable_llvm = TRUE;
508 * Return whenever T is an unsigned int type.
511 type_is_unsigned (EmitContext *ctx, MonoType *t)
513 t = mini_get_underlying_type (t);
529 * type_to_llvm_arg_type:
531 * Same as type_to_llvm_type, but treat i8/i16 as i32.
534 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
536 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
538 if (ctx->cfg->llvm_only)
542 * This works on all abis except arm64/ios which passes multiple
543 * arguments in one stack slot.
546 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
548 * LLVM generates code which only sets the lower bits, while JITted
549 * code expects all the bits to be set.
551 ptype = LLVMInt32Type ();
559 * llvm_type_to_stack_type:
561 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
564 static G_GNUC_UNUSED LLVMTypeRef
565 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
569 if (type == LLVMInt8Type ())
570 return LLVMInt32Type ();
571 else if (type == LLVMInt16Type ())
572 return LLVMInt32Type ();
573 else if (!cfg->r4fp && type == LLVMFloatType ())
574 return LLVMDoubleType ();
580 * regtype_to_llvm_type:
582 * Return the LLVM type corresponding to the regtype C used in instruction
586 regtype_to_llvm_type (char c)
590 return LLVMInt32Type ();
592 return LLVMInt64Type ();
594 return LLVMDoubleType ();
603 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
606 op_to_llvm_type (int opcode)
611 return LLVMInt8Type ();
614 return LLVMInt8Type ();
617 return LLVMInt16Type ();
620 return LLVMInt16Type ();
623 return LLVMInt32Type ();
626 return LLVMInt32Type ();
628 return LLVMInt64Type ();
630 return LLVMFloatType ();
632 return LLVMDoubleType ();
634 return LLVMInt64Type ();
636 return LLVMInt32Type ();
638 return LLVMInt64Type ();
643 return LLVMInt8Type ();
648 return LLVMInt16Type ();
650 return LLVMInt32Type ();
653 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
660 return LLVMInt32Type ();
667 return LLVMInt64Type ();
669 printf ("%s\n", mono_inst_name (opcode));
670 g_assert_not_reached ();
675 #define CLAUSE_START(clause) ((clause)->try_offset)
676 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
679 * load_store_to_llvm_type:
681 * Return the size/sign/zero extension corresponding to the load/store opcode
685 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
691 case OP_LOADI1_MEMBASE:
692 case OP_STOREI1_MEMBASE_REG:
693 case OP_STOREI1_MEMBASE_IMM:
694 case OP_ATOMIC_LOAD_I1:
695 case OP_ATOMIC_STORE_I1:
698 return LLVMInt8Type ();
699 case OP_LOADU1_MEMBASE:
701 case OP_ATOMIC_LOAD_U1:
702 case OP_ATOMIC_STORE_U1:
705 return LLVMInt8Type ();
706 case OP_LOADI2_MEMBASE:
707 case OP_STOREI2_MEMBASE_REG:
708 case OP_STOREI2_MEMBASE_IMM:
709 case OP_ATOMIC_LOAD_I2:
710 case OP_ATOMIC_STORE_I2:
713 return LLVMInt16Type ();
714 case OP_LOADU2_MEMBASE:
716 case OP_ATOMIC_LOAD_U2:
717 case OP_ATOMIC_STORE_U2:
720 return LLVMInt16Type ();
721 case OP_LOADI4_MEMBASE:
722 case OP_LOADU4_MEMBASE:
725 case OP_STOREI4_MEMBASE_REG:
726 case OP_STOREI4_MEMBASE_IMM:
727 case OP_ATOMIC_LOAD_I4:
728 case OP_ATOMIC_STORE_I4:
729 case OP_ATOMIC_LOAD_U4:
730 case OP_ATOMIC_STORE_U4:
732 return LLVMInt32Type ();
733 case OP_LOADI8_MEMBASE:
735 case OP_STOREI8_MEMBASE_REG:
736 case OP_STOREI8_MEMBASE_IMM:
737 case OP_ATOMIC_LOAD_I8:
738 case OP_ATOMIC_STORE_I8:
739 case OP_ATOMIC_LOAD_U8:
740 case OP_ATOMIC_STORE_U8:
742 return LLVMInt64Type ();
743 case OP_LOADR4_MEMBASE:
744 case OP_STORER4_MEMBASE_REG:
745 case OP_ATOMIC_LOAD_R4:
746 case OP_ATOMIC_STORE_R4:
748 return LLVMFloatType ();
749 case OP_LOADR8_MEMBASE:
750 case OP_STORER8_MEMBASE_REG:
751 case OP_ATOMIC_LOAD_R8:
752 case OP_ATOMIC_STORE_R8:
754 return LLVMDoubleType ();
755 case OP_LOAD_MEMBASE:
757 case OP_STORE_MEMBASE_REG:
758 case OP_STORE_MEMBASE_IMM:
759 *size = sizeof (gpointer);
760 return IntPtrType ();
762 g_assert_not_reached ();
770 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
773 ovf_op_to_intrins (int opcode)
777 return "llvm.sadd.with.overflow.i32";
779 return "llvm.uadd.with.overflow.i32";
781 return "llvm.ssub.with.overflow.i32";
783 return "llvm.usub.with.overflow.i32";
785 return "llvm.smul.with.overflow.i32";
787 return "llvm.umul.with.overflow.i32";
789 return "llvm.sadd.with.overflow.i64";
791 return "llvm.uadd.with.overflow.i64";
793 return "llvm.ssub.with.overflow.i64";
795 return "llvm.usub.with.overflow.i64";
797 return "llvm.smul.with.overflow.i64";
799 return "llvm.umul.with.overflow.i64";
801 g_assert_not_reached ();
807 simd_op_to_intrins (int opcode)
810 #if defined(TARGET_X86) || defined(TARGET_AMD64)
812 return "llvm.x86.sse2.min.pd";
814 return "llvm.x86.sse.min.ps";
816 return "llvm.x86.sse41.pminud";
818 return "llvm.x86.sse41.pminuw";
820 return "llvm.x86.sse2.pminu.b";
822 return "llvm.x86.sse2.pmins.w";
824 return "llvm.x86.sse2.max.pd";
826 return "llvm.x86.sse.max.ps";
828 return "llvm.x86.sse3.hadd.pd";
830 return "llvm.x86.sse3.hadd.ps";
832 return "llvm.x86.sse3.hsub.pd";
834 return "llvm.x86.sse3.hsub.ps";
836 return "llvm.x86.sse41.pmaxud";
838 return "llvm.x86.sse41.pmaxuw";
840 return "llvm.x86.sse2.pmaxu.b";
842 return "llvm.x86.sse3.addsub.ps";
844 return "llvm.x86.sse3.addsub.pd";
845 case OP_EXTRACT_MASK:
846 return "llvm.x86.sse2.pmovmskb.128";
849 return "llvm.x86.sse2.psrli.w";
852 return "llvm.x86.sse2.psrli.d";
855 return "llvm.x86.sse2.psrli.q";
858 return "llvm.x86.sse2.pslli.w";
861 return "llvm.x86.sse2.pslli.d";
864 return "llvm.x86.sse2.pslli.q";
867 return "llvm.x86.sse2.psrai.w";
870 return "llvm.x86.sse2.psrai.d";
872 return "llvm.x86.sse2.padds.b";
874 return "llvm.x86.sse2.padds.w";
876 return "llvm.x86.sse2.psubs.b";
878 return "llvm.x86.sse2.psubs.w";
879 case OP_PADDB_SAT_UN:
880 return "llvm.x86.sse2.paddus.b";
881 case OP_PADDW_SAT_UN:
882 return "llvm.x86.sse2.paddus.w";
883 case OP_PSUBB_SAT_UN:
884 return "llvm.x86.sse2.psubus.b";
885 case OP_PSUBW_SAT_UN:
886 return "llvm.x86.sse2.psubus.w";
888 return "llvm.x86.sse2.pavg.b";
890 return "llvm.x86.sse2.pavg.w";
892 return "llvm.x86.sse.sqrt.ps";
894 return "llvm.x86.sse2.sqrt.pd";
896 return "llvm.x86.sse.rsqrt.ps";
898 return "llvm.x86.sse.rcp.ps";
900 return "llvm.x86.sse2.cvtdq2pd";
902 return "llvm.x86.sse2.cvtdq2ps";
904 return "llvm.x86.sse2.cvtpd2dq";
906 return "llvm.x86.sse2.cvtps2dq";
908 return "llvm.x86.sse2.cvtpd2ps";
910 return "llvm.x86.sse2.cvtps2pd";
912 return "llvm.x86.sse2.cvttpd2dq";
914 return "llvm.x86.sse2.cvttps2dq";
916 return "llvm.x86.sse.cmp.ps";
918 return "llvm.x86.sse2.cmp.pd";
920 return "llvm.x86.sse2.packsswb.128";
922 return "llvm.x86.sse2.packssdw.128";
924 return "llvm.x86.sse2.packuswb.128";
926 return "llvm.x86.sse41.packusdw";
928 return "llvm.x86.sse2.pmulh.w";
929 case OP_PMULW_HIGH_UN:
930 return "llvm.x86.sse2.pmulhu.w";
933 g_assert_not_reached ();
939 simd_op_to_llvm_type (int opcode)
941 #if defined(TARGET_X86) || defined(TARGET_AMD64)
945 return type_to_simd_type (MONO_TYPE_R8);
948 return type_to_simd_type (MONO_TYPE_I8);
951 return type_to_simd_type (MONO_TYPE_I4);
956 return type_to_simd_type (MONO_TYPE_I2);
960 return type_to_simd_type (MONO_TYPE_I1);
962 return type_to_simd_type (MONO_TYPE_R4);
965 return type_to_simd_type (MONO_TYPE_I4);
969 return type_to_simd_type (MONO_TYPE_R8);
973 return type_to_simd_type (MONO_TYPE_R4);
974 case OP_EXTRACT_MASK:
975 return type_to_simd_type (MONO_TYPE_I1);
981 return type_to_simd_type (MONO_TYPE_R4);
984 return type_to_simd_type (MONO_TYPE_R8);
986 g_assert_not_reached ();
997 * Return the LLVM basic block corresponding to BB.
999 static LLVMBasicBlockRef
1000 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1002 char bb_name_buf [128];
1005 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1006 if (bb->flags & BB_EXCEPTION_HANDLER) {
1007 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1008 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1009 bb_name = bb_name_buf;
1010 } else if (bb->block_num < 256) {
1011 if (!ctx->module->bb_names) {
1012 ctx->module->bb_names_len = 256;
1013 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1015 if (!ctx->module->bb_names [bb->block_num]) {
1018 n = g_strdup_printf ("BB%d", bb->block_num);
1019 mono_memory_barrier ();
1020 ctx->module->bb_names [bb->block_num] = n;
1022 bb_name = ctx->module->bb_names [bb->block_num];
1024 sprintf (bb_name_buf, "BB%d", bb->block_num);
1025 bb_name = bb_name_buf;
1028 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1029 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1032 return ctx->bblocks [bb->block_num].bblock;
1038 * Return the last LLVM bblock corresponding to BB.
1039 * This might not be equal to the bb returned by get_bb () since we need to generate
1040 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1042 static LLVMBasicBlockRef
1043 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1046 return ctx->bblocks [bb->block_num].end_bblock;
1049 static LLVMBasicBlockRef
1050 gen_bb (EmitContext *ctx, const char *prefix)
1054 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1055 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1061 * Return the target of the patch identified by TYPE and TARGET.
1064 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1070 memset (&ji, 0, sizeof (ji));
1072 ji.data.target = target;
1074 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1075 mono_error_assert_ok (&error);
1083 * Emit code to convert the LLVM value V to DTYPE.
1086 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1088 LLVMTypeRef stype = LLVMTypeOf (v);
1090 if (stype != dtype) {
1091 gboolean ext = FALSE;
1094 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1096 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1098 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1102 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1104 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1105 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1108 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1109 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1110 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1111 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1112 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1113 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1114 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1115 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1117 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1118 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1119 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1120 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1121 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1122 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1124 if (mono_arch_is_soft_float ()) {
1125 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1126 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1127 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1128 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1131 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1132 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1135 LLVMDumpValue (LLVMConstNull (dtype));
1136 g_assert_not_reached ();
1144 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1146 return convert_full (ctx, v, dtype, FALSE);
1150 * emit_volatile_load:
1152 * If vreg is volatile, emit a load from its address.
1155 emit_volatile_load (EmitContext *ctx, int vreg)
1159 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1160 t = ctx->vreg_cli_types [vreg];
1161 if (t && !t->byref) {
1163 * Might have to zero extend since llvm doesn't have
1166 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1167 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1168 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1169 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1170 else if (t->type == MONO_TYPE_U8)
1171 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1178 * emit_volatile_store:
1180 * If VREG is volatile, emit a store from its value to its address.
1183 emit_volatile_store (EmitContext *ctx, int vreg)
1185 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1187 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1188 g_assert (ctx->addresses [vreg]);
1189 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1194 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1196 LLVMTypeRef ret_type;
1197 LLVMTypeRef *param_types = NULL;
1202 rtype = mini_get_underlying_type (sig->ret);
1203 ret_type = type_to_llvm_type (ctx, rtype);
1207 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1211 param_types [pindex ++] = ThisType ();
1212 for (i = 0; i < sig->param_count; ++i)
1213 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1215 if (!ctx_ok (ctx)) {
1216 g_free (param_types);
1220 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1221 g_free (param_types);
1227 * sig_to_llvm_sig_full:
1229 * Return the LLVM signature corresponding to the mono signature SIG using the
1230 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1233 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1235 LLVMTypeRef ret_type;
1236 LLVMTypeRef *param_types = NULL;
1238 int i, j, pindex, vret_arg_pindex = 0;
1239 gboolean vretaddr = FALSE;
1243 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1245 rtype = mini_get_underlying_type (sig->ret);
1246 ret_type = type_to_llvm_type (ctx, rtype);
1250 switch (cinfo->ret.storage) {
1251 case LLVMArgVtypeInReg:
1252 /* LLVM models this by returning an aggregate value */
1253 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1254 LLVMTypeRef members [2];
1256 members [0] = IntPtrType ();
1257 ret_type = LLVMStructType (members, 1, FALSE);
1258 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1260 ret_type = LLVMVoidType ();
1261 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1262 LLVMTypeRef members [2];
1264 members [0] = IntPtrType ();
1265 members [1] = IntPtrType ();
1266 ret_type = LLVMStructType (members, 2, FALSE);
1268 g_assert_not_reached ();
1271 case LLVMArgVtypeByVal:
1272 /* Vtype returned normally by val */
1274 case LLVMArgVtypeAsScalar: {
1275 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1276 /* LLVM models this by returning an int */
1277 if (size < SIZEOF_VOID_P) {
1278 g_assert (cinfo->ret.nslots == 1);
1279 ret_type = LLVMIntType (size * 8);
1281 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1282 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1286 case LLVMArgFpStruct: {
1287 /* Vtype returned as a fp struct */
1288 LLVMTypeRef members [16];
1290 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1291 for (i = 0; i < cinfo->ret.nslots; ++i)
1292 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1293 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1296 case LLVMArgVtypeByRef:
1297 /* Vtype returned using a hidden argument */
1298 ret_type = LLVMVoidType ();
1300 case LLVMArgVtypeRetAddr:
1301 case LLVMArgGsharedvtFixed:
1302 case LLVMArgGsharedvtFixedVtype:
1303 case LLVMArgGsharedvtVariable:
1305 ret_type = LLVMVoidType ();
1311 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1313 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1315 * Has to be the first argument because of the sret argument attribute
1316 * FIXME: This might conflict with passing 'this' as the first argument, but
1317 * this is only used on arm64 which has a dedicated struct return register.
1319 cinfo->vret_arg_pindex = pindex;
1320 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1321 if (!ctx_ok (ctx)) {
1322 g_free (param_types);
1325 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1328 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1329 cinfo->rgctx_arg_pindex = pindex;
1330 param_types [pindex] = ctx->module->ptr_type;
1333 if (cinfo->imt_arg) {
1334 cinfo->imt_arg_pindex = pindex;
1335 param_types [pindex] = ctx->module->ptr_type;
1339 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1340 vret_arg_pindex = pindex;
1341 if (cinfo->vret_arg_index == 1) {
1342 /* Add the slots consumed by the first argument */
1343 LLVMArgInfo *ainfo = &cinfo->args [0];
1344 switch (ainfo->storage) {
1345 case LLVMArgVtypeInReg:
1346 for (j = 0; j < 2; ++j) {
1347 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1356 cinfo->vret_arg_pindex = vret_arg_pindex;
1359 if (vretaddr && vret_arg_pindex == pindex)
1360 param_types [pindex ++] = IntPtrType ();
1362 cinfo->this_arg_pindex = pindex;
1363 param_types [pindex ++] = ThisType ();
1364 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1366 if (vretaddr && vret_arg_pindex == pindex)
1367 param_types [pindex ++] = IntPtrType ();
1368 for (i = 0; i < sig->param_count; ++i) {
1369 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1371 if (vretaddr && vret_arg_pindex == pindex)
1372 param_types [pindex ++] = IntPtrType ();
1373 ainfo->pindex = pindex;
1375 switch (ainfo->storage) {
1376 case LLVMArgVtypeInReg:
1377 for (j = 0; j < 2; ++j) {
1378 switch (ainfo->pair_storage [j]) {
1380 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1385 g_assert_not_reached ();
1389 case LLVMArgVtypeByVal:
1390 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1393 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1396 case LLVMArgAsIArgs:
1397 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1400 case LLVMArgVtypeByRef:
1401 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1404 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1407 case LLVMArgAsFpArgs: {
1410 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1411 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1412 param_types [pindex ++] = LLVMDoubleType ();
1413 for (j = 0; j < ainfo->nslots; ++j)
1414 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1417 case LLVMArgVtypeAsScalar:
1418 g_assert_not_reached ();
1420 case LLVMArgGsharedvtFixed:
1421 case LLVMArgGsharedvtFixedVtype:
1422 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1424 case LLVMArgGsharedvtVariable:
1425 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1428 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1432 if (!ctx_ok (ctx)) {
1433 g_free (param_types);
1436 if (vretaddr && vret_arg_pindex == pindex)
1437 param_types [pindex ++] = IntPtrType ();
1438 if (ctx->llvm_only && cinfo->rgctx_arg) {
1439 /* Pass the rgctx as the last argument */
1440 cinfo->rgctx_arg_pindex = pindex;
1441 param_types [pindex] = ctx->module->ptr_type;
1445 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1446 g_free (param_types);
1452 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1454 return sig_to_llvm_sig_full (ctx, sig, NULL);
1458 * LLVMFunctionType1:
1460 * Create an LLVM function type from the arguments.
1462 static G_GNUC_UNUSED LLVMTypeRef
1463 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1466 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1470 * LLVMFunctionType1:
1472 * Create an LLVM function type from the arguments.
1474 static G_GNUC_UNUSED LLVMTypeRef
1475 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1476 LLVMTypeRef ParamType1,
1479 LLVMTypeRef param_types [1];
1481 param_types [0] = ParamType1;
1483 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1487 * LLVMFunctionType2:
1489 * Create an LLVM function type from the arguments.
1491 static G_GNUC_UNUSED LLVMTypeRef
1492 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1493 LLVMTypeRef ParamType1,
1494 LLVMTypeRef ParamType2,
1497 LLVMTypeRef param_types [2];
1499 param_types [0] = ParamType1;
1500 param_types [1] = ParamType2;
1502 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1506 * LLVMFunctionType3:
1508 * Create an LLVM function type from the arguments.
1510 static G_GNUC_UNUSED LLVMTypeRef
1511 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1512 LLVMTypeRef ParamType1,
1513 LLVMTypeRef ParamType2,
1514 LLVMTypeRef ParamType3,
1517 LLVMTypeRef param_types [3];
1519 param_types [0] = ParamType1;
1520 param_types [1] = ParamType2;
1521 param_types [2] = ParamType3;
1523 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1526 static G_GNUC_UNUSED LLVMTypeRef
1527 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1528 LLVMTypeRef ParamType1,
1529 LLVMTypeRef ParamType2,
1530 LLVMTypeRef ParamType3,
1531 LLVMTypeRef ParamType4,
1532 LLVMTypeRef ParamType5,
1535 LLVMTypeRef param_types [5];
1537 param_types [0] = ParamType1;
1538 param_types [1] = ParamType2;
1539 param_types [2] = ParamType3;
1540 param_types [3] = ParamType4;
1541 param_types [4] = ParamType5;
1543 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1549 * Create an LLVM builder and remember it so it can be freed later.
1551 static LLVMBuilderRef
1552 create_builder (EmitContext *ctx)
1554 LLVMBuilderRef builder = LLVMCreateBuilder ();
1556 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1562 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1567 case MONO_PATCH_INFO_INTERNAL_METHOD:
1568 name = g_strdup_printf ("jit_icall_%s", data);
1570 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1571 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1572 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1576 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1584 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1588 LLVMValueRef indexes [2];
1590 LLVMValueRef got_entry_addr, load;
1591 LLVMBuilderRef builder = ctx->builder;
1596 ji = g_new0 (MonoJumpInfo, 1);
1598 ji->data.target = data;
1600 ji = mono_aot_patch_info_dup (ji);
1602 ji->next = cfg->patch_info;
1603 cfg->patch_info = ji;
1605 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1606 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1608 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1609 * explicitly initialize it.
1611 if (!mono_aot_is_shared_got_offset (got_offset)) {
1612 //mono_print_ji (ji);
1614 ctx->has_got_access = TRUE;
1617 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1618 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1619 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1621 name = get_aotconst_name (type, data, got_offset);
1623 load = LLVMBuildLoad (builder, got_entry_addr, "");
1624 load = convert (ctx, load, llvm_type);
1625 LLVMSetValueName (load, name ? name : "");
1627 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1630 //set_invariant_load_flag (load);
1636 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1638 return get_aotconst_typed (ctx, type, data, NULL);
1642 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1644 LLVMValueRef callee;
1646 if (ctx->llvm_only) {
1647 callee_name = mono_aot_get_direct_call_symbol (type, data);
1649 /* Directly callable */
1651 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1653 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1655 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1657 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1659 /* LLVMTypeRef's are uniqued */
1660 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1661 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1663 g_free (callee_name);
1669 * Calls are made through the GOT.
1671 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1673 MonoJumpInfo *ji = NULL;
1675 callee_name = mono_aot_get_plt_symbol (type, data);
1679 if (ctx->cfg->compile_aot)
1680 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1681 mono_add_patch_info (ctx->cfg, 0, type, data);
1684 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1686 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1688 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1690 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1693 if (ctx->cfg->compile_aot) {
1694 ji = g_new0 (MonoJumpInfo, 1);
1696 ji->data.target = data;
1698 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1706 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1708 #if LLVM_API_VERSION > 100
1709 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1710 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1711 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1712 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1715 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1716 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1722 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1724 MonoMethodHeader *header = cfg->header;
1725 MonoExceptionClause *clause;
1729 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1730 return (bb->region >> 8) - 1;
1733 for (i = 0; i < header->num_clauses; ++i) {
1734 clause = &header->clauses [i];
1736 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1743 static MonoExceptionClause *
1744 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1746 // Since they're sorted by nesting we just need
1747 // the first one that the bb is a member of
1748 MonoExceptionClause *last = NULL;
1750 for (int i = 0; i < cfg->header->num_clauses; i++) {
1751 MonoExceptionClause *curr = &cfg->header->clauses [i];
1753 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1756 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1757 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1771 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1773 LLVMValueRef md_arg;
1776 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1777 md_arg = LLVMMDString ("mono", 4);
1778 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1782 set_invariant_load_flag (LLVMValueRef v)
1784 LLVMValueRef md_arg;
1786 const char *flag_name;
1788 // FIXME: Cache this
1789 flag_name = "invariant.load";
1790 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1791 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1792 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1798 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1802 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1804 MonoCompile *cfg = ctx->cfg;
1805 LLVMValueRef lcall = NULL;
1806 LLVMBuilderRef builder = *builder_ref;
1807 MonoExceptionClause *clause;
1809 if (ctx->llvm_only) {
1810 clause = get_most_deep_clause (cfg, ctx, bb);
1813 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1816 * Have to use an invoke instead of a call, branching to the
1817 * handler bblock of the clause containing this bblock.
1819 intptr_t key = CLAUSE_END(clause);
1821 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1823 // FIXME: Find the one that has the lowest end bound for the right start address
1824 // FIXME: Finally + nesting
1827 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1830 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1832 builder = ctx->builder = create_builder (ctx);
1833 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1835 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1839 int clause_index = get_handler_clause (cfg, bb);
1841 if (clause_index != -1) {
1842 MonoMethodHeader *header = cfg->header;
1843 MonoExceptionClause *ec = &header->clauses [clause_index];
1844 MonoBasicBlock *tblock;
1845 LLVMBasicBlockRef ex_bb, noex_bb;
1848 * Have to use an invoke instead of a call, branching to the
1849 * handler bblock of the clause containing this bblock.
1852 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1854 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1857 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1859 ex_bb = get_bb (ctx, tblock);
1861 noex_bb = gen_bb (ctx, "NOEX_BB");
1864 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1866 builder = ctx->builder = create_builder (ctx);
1867 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1869 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1874 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1875 ctx->builder = builder;
1879 *builder_ref = ctx->builder;
1885 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1887 const char *intrins_name;
1888 LLVMValueRef args [16], res;
1889 LLVMTypeRef addr_type;
1890 gboolean use_intrinsics = TRUE;
1892 #if LLVM_API_VERSION > 100
1893 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1894 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1895 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1896 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1897 *builder_ref = ctx->builder;
1898 use_intrinsics = FALSE;
1902 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1903 LLVMAtomicOrdering ordering;
1906 case LLVM_BARRIER_NONE:
1907 ordering = LLVMAtomicOrderingNotAtomic;
1909 case LLVM_BARRIER_ACQ:
1910 ordering = LLVMAtomicOrderingAcquire;
1912 case LLVM_BARRIER_SEQ:
1913 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1916 g_assert_not_reached ();
1921 * We handle loads which can fault by calling a mono specific intrinsic
1922 * using an invoke, so they are handled properly inside try blocks.
1923 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1924 * are marked with IntrReadArgMem.
1928 intrins_name = "llvm.mono.load.i8.p0i8";
1931 intrins_name = "llvm.mono.load.i16.p0i16";
1934 intrins_name = "llvm.mono.load.i32.p0i32";
1937 intrins_name = "llvm.mono.load.i64.p0i64";
1940 g_assert_not_reached ();
1943 addr_type = LLVMTypeOf (addr);
1944 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1945 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1948 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1949 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1950 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1951 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1953 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1954 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1955 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1956 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1963 * We emit volatile loads for loads which can fault, because otherwise
1964 * LLVM will generate invalid code when encountering a load from a
1967 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1969 /* Mark it with a custom metadata */
1972 set_metadata_flag (res, "mono.faulting.load");
1980 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1982 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1986 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1988 const char *intrins_name;
1989 LLVMValueRef args [16];
1990 gboolean use_intrinsics = TRUE;
1992 #if LLVM_API_VERSION > 100
1993 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1994 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1995 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1996 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1997 *builder_ref = ctx->builder;
1998 use_intrinsics = FALSE;
2002 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2003 LLVMAtomicOrdering ordering;
2006 case LLVM_BARRIER_NONE:
2007 ordering = LLVMAtomicOrderingNotAtomic;
2009 case LLVM_BARRIER_REL:
2010 ordering = LLVMAtomicOrderingRelease;
2012 case LLVM_BARRIER_SEQ:
2013 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2016 g_assert_not_reached ();
2022 intrins_name = "llvm.mono.store.i8.p0i8";
2025 intrins_name = "llvm.mono.store.i16.p0i16";
2028 intrins_name = "llvm.mono.store.i32.p0i32";
2031 intrins_name = "llvm.mono.store.i64.p0i64";
2034 g_assert_not_reached ();
2037 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2038 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2039 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2044 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2045 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2046 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2047 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2049 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2054 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2056 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2060 * emit_cond_system_exception:
2062 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2063 * Might set the ctx exception.
2066 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2068 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2069 LLVMBuilderRef builder;
2070 MonoClass *exc_class;
2071 LLVMValueRef args [2];
2072 LLVMValueRef callee;
2074 ex_bb = gen_bb (ctx, "EX_BB");
2076 ex2_bb = gen_bb (ctx, "EX2_BB");
2077 noex_bb = gen_bb (ctx, "NOEX_BB");
2079 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2081 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2083 /* Emit exception throwing code */
2084 ctx->builder = builder = create_builder (ctx);
2085 LLVMPositionBuilderAtEnd (builder, ex_bb);
2087 if (ctx->cfg->llvm_only) {
2088 static LLVMTypeRef sig;
2091 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2092 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2094 LLVMBuildBr (builder, ex2_bb);
2096 ctx->builder = builder = create_builder (ctx);
2097 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2099 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2100 emit_call (ctx, bb, &builder, callee, args, 1);
2101 LLVMBuildUnreachable (builder);
2103 ctx->builder = builder = create_builder (ctx);
2104 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2106 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2112 callee = ctx->module->throw_corlib_exception;
2115 const char *icall_name;
2117 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2118 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2120 if (ctx->cfg->compile_aot) {
2121 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2124 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2125 * - On x86, LLVM generated code doesn't push the arguments
2126 * - The trampoline takes the throw address as an arguments, not a pc offset.
2128 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2129 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2131 #if LLVM_API_VERSION > 100
2133 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2134 * added by emit_jit_callee ().
2136 ex2_bb = gen_bb (ctx, "EX2_BB");
2137 LLVMBuildBr (builder, ex2_bb);
2140 ctx->builder = builder = create_builder (ctx);
2141 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2143 mono_memory_barrier ();
2144 ctx->module->throw_corlib_exception = callee;
2149 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2150 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2152 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2155 * The LLVM mono branch contains changes so a block address can be passed as an
2156 * argument to a call.
2158 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2159 emit_call (ctx, bb, &builder, callee, args, 2);
2161 LLVMBuildUnreachable (builder);
2163 ctx->builder = builder = create_builder (ctx);
2164 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2166 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2173 * emit_args_to_vtype:
2175 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2178 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2180 int j, size, nslots;
2182 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2184 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2185 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2188 if (ainfo->storage == LLVMArgAsFpArgs)
2189 nslots = ainfo->nslots;
2193 for (j = 0; j < nslots; ++j) {
2194 LLVMValueRef index [2], addr, daddr;
2195 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2196 LLVMTypeRef part_type;
2198 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2201 if (ainfo->pair_storage [j] == LLVMArgNone)
2204 switch (ainfo->pair_storage [j]) {
2205 case LLVMArgInIReg: {
2206 part_type = LLVMIntType (part_size * 8);
2207 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2208 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2209 addr = LLVMBuildGEP (builder, address, index, 1, "");
2211 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2212 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2213 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2215 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2218 case LLVMArgInFPReg: {
2219 LLVMTypeRef arg_type;
2221 if (ainfo->esize == 8)
2222 arg_type = LLVMDoubleType ();
2224 arg_type = LLVMFloatType ();
2226 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2227 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2228 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2229 LLVMBuildStore (builder, args [j], addr);
2235 g_assert_not_reached ();
2238 size -= sizeof (gpointer);
2243 * emit_vtype_to_args:
2245 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2246 * into ARGS, and the number of arguments into NARGS.
2249 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2252 int j, size, nslots;
2253 LLVMTypeRef arg_type;
2255 size = get_vtype_size (t);
2257 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2258 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2260 if (ainfo->storage == LLVMArgAsFpArgs)
2261 nslots = ainfo->nslots;
2264 for (j = 0; j < nslots; ++j) {
2265 LLVMValueRef index [2], addr, daddr;
2266 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2268 if (ainfo->pair_storage [j] == LLVMArgNone)
2271 switch (ainfo->pair_storage [j]) {
2273 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2274 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2275 addr = LLVMBuildGEP (builder, address, index, 1, "");
2277 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2278 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2279 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2281 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2283 case LLVMArgInFPReg:
2284 if (ainfo->esize == 8)
2285 arg_type = LLVMDoubleType ();
2287 arg_type = LLVMFloatType ();
2288 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2289 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2290 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2291 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2296 g_assert_not_reached ();
2298 size -= sizeof (gpointer);
2305 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2308 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2309 * get executed every time control reaches them.
2311 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2313 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2314 return ctx->last_alloca;
2318 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2320 return build_alloca_llvm_type_name (ctx, t, align, "");
2324 build_alloca (EmitContext *ctx, MonoType *t)
2326 MonoClass *k = mono_class_from_mono_type (t);
2329 g_assert (!mini_is_gsharedvt_variable_type (t));
2331 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2334 align = mono_class_min_align (k);
2336 /* Sometimes align is not a power of 2 */
2337 while (mono_is_power_of_two (align) == -1)
2340 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2344 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2348 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2350 MonoCompile *cfg = ctx->cfg;
2351 LLVMBuilderRef builder = ctx->builder;
2352 LLVMValueRef offset, offset_var;
2353 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2354 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2358 g_assert (info_var);
2359 g_assert (locals_var);
2361 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2363 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2364 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2366 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2367 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2369 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2373 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2376 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2379 module->used = g_ptr_array_sized_new (16);
2380 g_ptr_array_add (module->used, global);
2384 emit_llvm_used (MonoLLVMModule *module)
2386 LLVMModuleRef lmodule = module->lmodule;
2387 LLVMTypeRef used_type;
2388 LLVMValueRef used, *used_elem;
2394 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2395 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2396 used_elem = g_new0 (LLVMValueRef, module->used->len);
2397 for (i = 0; i < module->used->len; ++i)
2398 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2399 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2400 LLVMSetLinkage (used, LLVMAppendingLinkage);
2401 LLVMSetSection (used, "llvm.metadata");
2407 * Emit a function mapping method indexes to their code
2410 emit_get_method (MonoLLVMModule *module)
2412 LLVMModuleRef lmodule = module->lmodule;
2413 LLVMValueRef func, switch_ins, m;
2414 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2415 LLVMBasicBlockRef *bbs;
2417 LLVMBuilderRef builder;
2422 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2423 * but generating code seems safer.
2425 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2426 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2427 LLVMSetLinkage (func, LLVMExternalLinkage);
2428 LLVMSetVisibility (func, LLVMHiddenVisibility);
2429 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2430 module->get_method = func;
2432 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2435 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2436 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2437 * then we will have to find another solution.
2440 name = g_strdup_printf ("BB_CODE_START");
2441 code_start_bb = LLVMAppendBasicBlock (func, name);
2443 builder = LLVMCreateBuilder ();
2444 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2445 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2447 name = g_strdup_printf ("BB_CODE_END");
2448 code_end_bb = LLVMAppendBasicBlock (func, name);
2450 builder = LLVMCreateBuilder ();
2451 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2452 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2454 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2455 for (i = 0; i < module->max_method_idx + 1; ++i) {
2456 name = g_strdup_printf ("BB_%d", i);
2457 bb = LLVMAppendBasicBlock (func, name);
2461 builder = LLVMCreateBuilder ();
2462 LLVMPositionBuilderAtEnd (builder, bb);
2464 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2466 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2468 LLVMBuildRet (builder, LLVMConstNull (rtype));
2471 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2472 builder = LLVMCreateBuilder ();
2473 LLVMPositionBuilderAtEnd (builder, fail_bb);
2474 LLVMBuildRet (builder, LLVMConstNull (rtype));
2476 builder = LLVMCreateBuilder ();
2477 LLVMPositionBuilderAtEnd (builder, entry_bb);
2479 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2480 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2481 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2482 for (i = 0; i < module->max_method_idx + 1; ++i) {
2483 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2486 mark_as_used (module, func);
2490 * emit_get_unbox_tramp:
2492 * Emit a function mapping method indexes to their unbox trampoline
2495 emit_get_unbox_tramp (MonoLLVMModule *module)
2497 LLVMModuleRef lmodule = module->lmodule;
2498 LLVMValueRef func, switch_ins, m;
2499 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2500 LLVMBasicBlockRef *bbs;
2502 LLVMBuilderRef builder;
2506 /* Similar to emit_get_method () */
2508 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2509 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2510 LLVMSetLinkage (func, LLVMExternalLinkage);
2511 LLVMSetVisibility (func, LLVMHiddenVisibility);
2512 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2513 module->get_unbox_tramp = func;
2515 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2517 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2518 for (i = 0; i < module->max_method_idx + 1; ++i) {
2519 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2523 name = g_strdup_printf ("BB_%d", i);
2524 bb = LLVMAppendBasicBlock (func, name);
2528 builder = LLVMCreateBuilder ();
2529 LLVMPositionBuilderAtEnd (builder, bb);
2531 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2534 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2535 builder = LLVMCreateBuilder ();
2536 LLVMPositionBuilderAtEnd (builder, fail_bb);
2537 LLVMBuildRet (builder, LLVMConstNull (rtype));
2539 builder = LLVMCreateBuilder ();
2540 LLVMPositionBuilderAtEnd (builder, entry_bb);
2542 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2543 for (i = 0; i < module->max_method_idx + 1; ++i) {
2544 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2548 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2551 mark_as_used (module, func);
2554 /* Add a function to mark the beginning of LLVM code */
2556 emit_llvm_code_start (MonoLLVMModule *module)
2558 LLVMModuleRef lmodule = module->lmodule;
2560 LLVMBasicBlockRef entry_bb;
2561 LLVMBuilderRef builder;
2563 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2564 LLVMSetLinkage (func, LLVMInternalLinkage);
2565 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2566 module->code_start = func;
2567 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2568 builder = LLVMCreateBuilder ();
2569 LLVMPositionBuilderAtEnd (builder, entry_bb);
2570 LLVMBuildRetVoid (builder);
2574 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2576 LLVMModuleRef lmodule = module->lmodule;
2577 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2578 LLVMBasicBlockRef entry_bb;
2579 LLVMBuilderRef builder;
2586 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2587 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2592 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2593 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2596 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2597 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2600 g_assert_not_reached ();
2602 LLVMSetLinkage (func, LLVMInternalLinkage);
2603 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2604 mono_llvm_set_preserveall_cc (func);
2605 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2606 builder = LLVMCreateBuilder ();
2607 LLVMPositionBuilderAtEnd (builder, entry_bb);
2610 ji = g_new0 (MonoJumpInfo, 1);
2611 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2612 ji = mono_aot_patch_info_dup (ji);
2613 got_offset = mono_aot_get_got_offset (ji);
2614 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2615 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2616 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2617 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2618 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2619 args [1] = LLVMGetParam (func, 0);
2621 args [2] = LLVMGetParam (func, 1);
2623 ji = g_new0 (MonoJumpInfo, 1);
2624 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2625 ji->data.name = icall_name;
2626 ji = mono_aot_patch_info_dup (ji);
2627 got_offset = mono_aot_get_got_offset (ji);
2628 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2629 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2630 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2631 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2632 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2633 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2634 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2636 // Set the inited flag
2637 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2638 indexes [1] = LLVMGetParam (func, 0);
2639 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2641 LLVMBuildRetVoid (builder);
2643 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2648 * Emit wrappers around the C icalls used to initialize llvm methods, to
2649 * make the calling code smaller and to enable usage of the llvm
2650 * PreserveAll calling convention.
2653 emit_init_icall_wrappers (MonoLLVMModule *module)
2655 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2656 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2657 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2658 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2662 emit_llvm_code_end (MonoLLVMModule *module)
2664 LLVMModuleRef lmodule = module->lmodule;
2666 LLVMBasicBlockRef entry_bb;
2667 LLVMBuilderRef builder;
2669 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2670 LLVMSetLinkage (func, LLVMInternalLinkage);
2671 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2672 module->code_end = func;
2673 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2674 builder = LLVMCreateBuilder ();
2675 LLVMPositionBuilderAtEnd (builder, entry_bb);
2676 LLVMBuildRetVoid (builder);
2680 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2682 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2685 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2686 need_div_check = TRUE;
2688 if (!need_div_check)
2691 switch (ins->opcode) {
2704 case OP_IDIV_UN_IMM:
2705 case OP_LDIV_UN_IMM:
2706 case OP_IREM_UN_IMM:
2707 case OP_LREM_UN_IMM: {
2709 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2710 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2712 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2713 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2716 builder = ctx->builder;
2718 /* b == -1 && a == 0x80000000 */
2720 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2721 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2722 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2724 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2725 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2728 builder = ctx->builder;
2740 * Emit code to initialize the GOT slots used by the method.
2743 emit_init_method (EmitContext *ctx)
2745 LLVMValueRef indexes [16], args [16], callee;
2746 LLVMValueRef inited_var, cmp, call;
2747 LLVMBasicBlockRef inited_bb, notinited_bb;
2748 LLVMBuilderRef builder = ctx->builder;
2749 MonoCompile *cfg = ctx->cfg;
2751 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2753 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2754 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2755 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2757 args [0] = inited_var;
2758 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2759 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2761 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2763 inited_bb = ctx->inited_bb;
2764 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2766 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2768 builder = ctx->builder = create_builder (ctx);
2769 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2772 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2773 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2774 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2775 callee = ctx->module->init_method_gshared_mrgctx;
2776 call = LLVMBuildCall (builder, callee, args, 2, "");
2777 } else if (ctx->rgctx_arg) {
2778 /* A vtable is passed as the rgctx argument */
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_vtable;
2782 call = LLVMBuildCall (builder, callee, args, 2, "");
2783 } else if (cfg->gshared) {
2784 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2785 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2786 callee = ctx->module->init_method_gshared_this;
2787 call = LLVMBuildCall (builder, callee, args, 2, "");
2789 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2790 callee = ctx->module->init_method;
2791 call = LLVMBuildCall (builder, callee, args, 1, "");
2795 * This enables llvm to keep arguments in their original registers/
2796 * scratch registers, since the call will not clobber them.
2798 mono_llvm_set_call_preserveall_cc (call);
2800 LLVMBuildBr (builder, inited_bb);
2801 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2803 builder = ctx->builder = create_builder (ctx);
2804 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2808 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2811 * Emit unbox trampoline using a tail call
2813 LLVMValueRef tramp, call, *args;
2814 LLVMBuilderRef builder;
2815 LLVMBasicBlockRef lbb;
2816 LLVMCallInfo *linfo;
2820 tramp_name = g_strdup_printf ("ut_%s", method_name);
2821 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2822 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2823 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2824 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2826 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2827 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2828 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2829 if (ctx->cfg->vret_addr) {
2830 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2831 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2832 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2833 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2837 lbb = LLVMAppendBasicBlock (tramp, "");
2838 builder = LLVMCreateBuilder ();
2839 LLVMPositionBuilderAtEnd (builder, lbb);
2841 nargs = LLVMCountParamTypes (method_type);
2842 args = g_new0 (LLVMValueRef, nargs);
2843 for (i = 0; i < nargs; ++i) {
2844 args [i] = LLVMGetParam (tramp, i);
2845 if (i == ctx->this_arg_pindex) {
2846 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2848 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2849 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2850 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2853 call = LLVMBuildCall (builder, method, args, nargs, "");
2854 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2855 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2856 if (linfo->ret.storage == LLVMArgVtypeByRef)
2857 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2859 // FIXME: This causes assertions in clang
2860 //mono_llvm_set_must_tail (call);
2861 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2862 LLVMBuildRetVoid (builder);
2864 LLVMBuildRet (builder, call);
2866 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2872 * Emit code to load/convert arguments.
2875 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2878 MonoCompile *cfg = ctx->cfg;
2879 MonoMethodSignature *sig = ctx->sig;
2880 LLVMCallInfo *linfo = ctx->linfo;
2884 LLVMBuilderRef old_builder = ctx->builder;
2885 ctx->builder = builder;
2887 ctx->alloca_builder = create_builder (ctx);
2890 * Handle indirect/volatile variables by allocating memory for them
2891 * using 'alloca', and storing their address in a temporary.
2893 for (i = 0; i < cfg->num_varinfo; ++i) {
2894 MonoInst *var = cfg->varinfo [i];
2897 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2898 } 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))) {
2899 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2902 /* Could be already created by an OP_VPHI */
2903 if (!ctx->addresses [var->dreg]) {
2904 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2905 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2907 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2911 names = g_new (char *, sig->param_count);
2912 mono_method_get_param_names (cfg->method, (const char **) names);
2914 for (i = 0; i < sig->param_count; ++i) {
2915 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2916 int reg = cfg->args [i + sig->hasthis]->dreg;
2919 pindex = ainfo->pindex;
2921 switch (ainfo->storage) {
2922 case LLVMArgVtypeInReg:
2923 case LLVMArgAsFpArgs: {
2924 LLVMValueRef args [8];
2927 pindex += ainfo->ndummy_fpargs;
2929 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2930 memset (args, 0, sizeof (args));
2931 if (ainfo->storage == LLVMArgVtypeInReg) {
2932 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2933 if (ainfo->pair_storage [1] != LLVMArgNone)
2934 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2936 g_assert (ainfo->nslots <= 8);
2937 for (j = 0; j < ainfo->nslots; ++j)
2938 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2940 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2942 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2944 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2945 /* Treat these as normal values */
2946 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2950 case LLVMArgVtypeByVal: {
2951 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2953 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2954 /* Treat these as normal values */
2955 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2959 case LLVMArgVtypeByRef: {
2960 /* The argument is passed by ref */
2961 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2964 case LLVMArgAsIArgs: {
2965 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2968 /* The argument is received as an array of ints, store it into the real argument */
2969 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2971 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2972 if (size < SIZEOF_VOID_P) {
2973 /* The upper bits of the registers might not be valid */
2974 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2975 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2976 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2978 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2982 case LLVMArgVtypeAsScalar:
2983 g_assert_not_reached ();
2985 case LLVMArgGsharedvtFixed: {
2986 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2987 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2990 name = g_strdup_printf ("arg_%s", names [i]);
2992 name = g_strdup_printf ("arg_%d", i);
2994 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2997 case LLVMArgGsharedvtFixedVtype: {
2998 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3001 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3003 name = g_strdup_printf ("vtype_arg_%d", i);
3005 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3006 g_assert (ctx->addresses [reg]);
3007 LLVMSetValueName (ctx->addresses [reg], name);
3008 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3011 case LLVMArgGsharedvtVariable:
3012 /* The IR treats these as variables with addresses */
3013 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3016 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));
3023 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3025 emit_volatile_store (ctx, cfg->args [0]->dreg);
3026 for (i = 0; i < sig->param_count; ++i)
3027 if (!mini_type_is_vtype (sig->params [i]))
3028 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3030 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3031 LLVMValueRef this_alloc;
3034 * The exception handling code needs the location where the this argument was
3035 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3036 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3037 * location into the LSDA.
3039 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3040 /* This volatile store will keep the alloca alive */
3041 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3043 set_metadata_flag (this_alloc, "mono.this");
3046 if (cfg->rgctx_var) {
3047 LLVMValueRef rgctx_alloc, store;
3050 * We handle the rgctx arg similarly to the this pointer.
3052 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3053 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3054 /* This volatile store will keep the alloca alive */
3055 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3057 set_metadata_flag (rgctx_alloc, "mono.this");
3060 /* Initialize the method if needed */
3061 if (cfg->compile_aot && ctx->llvm_only) {
3062 /* Emit a location for the initialization code */
3063 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3064 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3066 LLVMBuildBr (ctx->builder, ctx->init_bb);
3067 builder = ctx->builder = create_builder (ctx);
3068 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3069 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3072 /* Compute nesting between clauses */
3073 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3074 for (i = 0; i < cfg->header->num_clauses; ++i) {
3075 for (j = 0; j < cfg->header->num_clauses; ++j) {
3076 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3077 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3079 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3080 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3085 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3086 * it needs to continue normally, or return back to the exception handling system.
3088 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3092 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3095 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3096 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3097 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3099 if (bb->in_scount == 0) {
3102 sprintf (name, "finally_ind_bb%d", bb->block_num);
3103 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3104 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3106 ctx->bblocks [bb->block_num].finally_ind = val;
3108 /* Create a variable to hold the exception var */
3110 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3114 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3115 * LLVM bblock containing a landing pad causes problems for the
3116 * LLVM optimizer passes.
3118 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3119 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3121 ctx->builder = old_builder;
3125 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3127 MonoCompile *cfg = ctx->cfg;
3128 LLVMValueRef *values = ctx->values;
3129 LLVMValueRef *addresses = ctx->addresses;
3130 MonoCallInst *call = (MonoCallInst*)ins;
3131 MonoMethodSignature *sig = call->signature;
3132 LLVMValueRef callee = NULL, lcall;
3134 LLVMCallInfo *cinfo;
3138 LLVMTypeRef llvm_sig;
3140 gboolean is_virtual, calli, preserveall;
3141 LLVMBuilderRef builder = *builder_ref;
3143 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3144 set_failure (ctx, "non-default callconv");
3148 cinfo = call->cinfo;
3150 if (call->rgctx_arg_reg)
3151 cinfo->rgctx_arg = TRUE;
3152 if (call->imt_arg_reg)
3153 cinfo->imt_arg = TRUE;
3155 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3157 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3161 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);
3162 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);
3164 preserveall = FALSE;
3166 /* FIXME: Avoid creating duplicate methods */
3168 if (ins->flags & MONO_INST_HAS_METHOD) {
3172 if (cfg->compile_aot) {
3173 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3175 set_failure (ctx, "can't encode patch");
3178 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3180 * Collect instructions representing the callee into a hash so they can be replaced
3181 * by the llvm method for the callee if the callee turns out to be direct
3182 * callable. Currently this only requires it to not fail llvm compilation.
3184 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3185 l = g_slist_prepend (l, callee);
3186 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3190 static int tramp_index;
3193 name = g_strdup_printf ("tramp_%d", tramp_index);
3196 #if LLVM_API_VERSION > 100
3198 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3199 * Make all calls through a global. The address of the global will be saved in
3200 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3203 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3206 mono_create_jit_trampoline (mono_domain_get (),
3207 call->method, &error);
3208 if (!mono_error_ok (&error))
3209 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3210 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3211 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3212 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3213 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3215 callee = LLVMBuildLoad (builder, tramp_var, "");
3217 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3220 if (!mono_error_ok (&error))
3221 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3222 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3227 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3228 /* LLVM miscompiles async methods */
3229 set_failure (ctx, "#13734");
3234 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3240 memset (&ji, 0, sizeof (ji));
3241 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3242 ji.data.target = info->name;
3244 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3246 if (cfg->compile_aot) {
3247 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3249 set_failure (ctx, "can't encode patch");
3253 target = (gpointer)mono_icall_get_wrapper (info);
3254 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3257 if (cfg->compile_aot) {
3259 if (cfg->abs_patches) {
3260 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3262 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3264 set_failure (ctx, "can't encode patch");
3270 set_failure (ctx, "aot");
3274 #if LLVM_API_VERSION > 100
3275 if (cfg->abs_patches) {
3276 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3280 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3281 mono_error_assert_ok (&error);
3282 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3284 g_assert_not_reached ();
3287 g_assert_not_reached ();
3290 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3292 if (cfg->abs_patches) {
3293 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3298 * FIXME: Some trampolines might have
3299 * their own calling convention on some platforms.
3301 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3302 mono_error_assert_ok (&error);
3303 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3307 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3314 int size = sizeof (gpointer);
3317 g_assert (ins->inst_offset % size == 0);
3318 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3320 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3322 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3324 if (ins->flags & MONO_INST_HAS_METHOD) {
3329 * Collect and convert arguments
3331 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3332 len = sizeof (LLVMValueRef) * nargs;
3333 args = (LLVMValueRef*)alloca (len);
3334 memset (args, 0, len);
3335 l = call->out_ireg_args;
3337 if (call->rgctx_arg_reg) {
3338 g_assert (values [call->rgctx_arg_reg]);
3339 g_assert (cinfo->rgctx_arg_pindex < nargs);
3341 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3342 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3343 * it using a volatile load.
3346 if (!ctx->imt_rgctx_loc)
3347 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3348 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3349 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3351 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3354 if (call->imt_arg_reg) {
3355 g_assert (!ctx->llvm_only);
3356 g_assert (values [call->imt_arg_reg]);
3357 g_assert (cinfo->imt_arg_pindex < nargs);
3359 if (!ctx->imt_rgctx_loc)
3360 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3361 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3362 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3364 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3367 switch (cinfo->ret.storage) {
3368 case LLVMArgGsharedvtVariable: {
3369 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3371 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3372 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3374 g_assert (addresses [call->inst.dreg]);
3375 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3381 if (!addresses [call->inst.dreg])
3382 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3383 g_assert (cinfo->vret_arg_pindex < nargs);
3384 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3385 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3387 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3393 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3394 * use the real callee for argument type conversion.
3396 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3397 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3398 LLVMGetParamTypes (callee_type, param_types);
3400 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3403 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3405 pindex = ainfo->pindex;
3407 regpair = (guint32)(gssize)(l->data);
3408 reg = regpair & 0xffffff;
3409 args [pindex] = values [reg];
3410 switch (ainfo->storage) {
3411 case LLVMArgVtypeInReg:
3412 case LLVMArgAsFpArgs: {
3416 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3417 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3418 pindex += ainfo->ndummy_fpargs;
3420 g_assert (addresses [reg]);
3421 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3425 // FIXME: Get rid of the VMOVE
3428 case LLVMArgVtypeByVal:
3429 g_assert (addresses [reg]);
3430 args [pindex] = addresses [reg];
3432 case LLVMArgVtypeByRef: {
3433 g_assert (addresses [reg]);
3434 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3437 case LLVMArgAsIArgs:
3438 g_assert (addresses [reg]);
3439 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3441 case LLVMArgVtypeAsScalar:
3442 g_assert_not_reached ();
3444 case LLVMArgGsharedvtFixed:
3445 case LLVMArgGsharedvtFixedVtype:
3446 g_assert (addresses [reg]);
3447 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3449 case LLVMArgGsharedvtVariable:
3450 g_assert (addresses [reg]);
3451 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3454 g_assert (args [pindex]);
3455 if (i == 0 && sig->hasthis)
3456 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3458 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3461 g_assert (pindex <= nargs);
3466 // FIXME: Align call sites
3472 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3475 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3477 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3478 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3480 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3481 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3482 if (!sig->pinvoke && !cfg->llvm_only)
3483 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3485 mono_llvm_set_call_preserveall_cc (lcall);
3487 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3488 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3489 if (!ctx->llvm_only && call->rgctx_arg_reg)
3490 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3491 if (call->imt_arg_reg)
3492 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3494 /* Add byval attributes if needed */
3495 for (i = 0; i < sig->param_count; ++i) {
3496 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3498 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3499 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3503 * Convert the result
3505 switch (cinfo->ret.storage) {
3506 case LLVMArgVtypeInReg: {
3507 LLVMValueRef regs [2];
3509 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3513 if (!addresses [ins->dreg])
3514 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3516 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3517 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3518 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3519 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3522 case LLVMArgVtypeByVal:
3523 if (!addresses [call->inst.dreg])
3524 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3525 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3527 case LLVMArgFpStruct:
3528 if (!addresses [call->inst.dreg])
3529 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3530 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3532 case LLVMArgVtypeAsScalar:
3533 if (!addresses [call->inst.dreg])
3534 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3535 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3537 case LLVMArgVtypeRetAddr:
3538 case LLVMArgVtypeByRef:
3539 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3540 /* Some opcodes like STOREX_MEMBASE access these by value */
3541 g_assert (addresses [call->inst.dreg]);
3542 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3545 case LLVMArgGsharedvtVariable:
3547 case LLVMArgGsharedvtFixed:
3548 case LLVMArgGsharedvtFixedVtype:
3549 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3552 if (sig->ret->type != MONO_TYPE_VOID)
3553 /* If the method returns an unsigned value, need to zext it */
3554 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));
3558 *builder_ref = ctx->builder;
3562 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3564 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3565 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3567 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3570 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3572 if (ctx->cfg->compile_aot) {
3573 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3575 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3576 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3577 mono_memory_barrier ();
3580 ctx->module->rethrow = callee;
3582 ctx->module->throw_icall = callee;
3586 LLVMValueRef args [2];
3588 args [0] = convert (ctx, exc, exc_type);
3589 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3591 LLVMBuildUnreachable (ctx->builder);
3593 ctx->builder = create_builder (ctx);
3597 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3599 MonoMethodSignature *throw_sig;
3600 LLVMValueRef callee, arg;
3601 const char *icall_name;
3603 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3604 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3607 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3608 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3609 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3610 if (ctx->cfg->compile_aot) {
3611 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3616 * LLVM doesn't push the exception argument, so we need a different
3619 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3621 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3623 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3626 mono_memory_barrier ();
3627 #if LLVM_API_VERSION < 100
3629 ctx->module->rethrow = callee;
3631 ctx->module->throw_icall = callee;
3634 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3635 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3639 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3641 const char *icall_name = "mono_llvm_resume_exception";
3642 LLVMValueRef callee = ctx->module->resume_eh;
3644 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3647 if (ctx->cfg->compile_aot) {
3648 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3650 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3651 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3652 mono_memory_barrier ();
3654 ctx->module->resume_eh = callee;
3658 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3660 LLVMBuildUnreachable (ctx->builder);
3662 ctx->builder = create_builder (ctx);
3666 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3668 const char *icall_name = "mono_llvm_clear_exception";
3670 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3671 LLVMValueRef callee = NULL;
3674 if (ctx->cfg->compile_aot) {
3675 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3677 // FIXME: This is broken.
3678 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3682 g_assert (builder && callee);
3684 return LLVMBuildCall (builder, callee, NULL, 0, "");
3688 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3690 const char *icall_name = "mono_llvm_load_exception";
3692 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3693 LLVMValueRef callee = NULL;
3696 if (ctx->cfg->compile_aot) {
3697 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3699 // FIXME: This is broken.
3700 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3704 g_assert (builder && callee);
3706 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3711 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3713 const char *icall_name = "mono_llvm_match_exception";
3715 ctx->builder = builder;
3717 const int num_args = 5;
3718 LLVMValueRef args [num_args];
3719 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3720 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3721 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3722 if (ctx->cfg->rgctx_var) {
3723 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3724 g_assert (rgctx_alloc);
3725 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3727 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3730 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3732 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3734 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3735 LLVMValueRef callee = ctx->module->match_exc;
3738 if (ctx->cfg->compile_aot) {
3739 ctx->builder = builder;
3740 // get_callee expects ctx->builder to be the emitting builder
3741 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3743 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3744 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3745 ctx->module->match_exc = callee;
3746 mono_memory_barrier ();
3750 g_assert (builder && callee);
3752 g_assert (ctx->ex_var);
3754 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3757 // FIXME: This won't work because the code-finding makes this
3759 /*#define MONO_PERSONALITY_DEBUG*/
3761 #ifdef MONO_PERSONALITY_DEBUG
3762 static const gboolean use_debug_personality = TRUE;
3763 static const char *default_personality_name = "mono_debug_personality";
3765 static const gboolean use_debug_personality = FALSE;
3766 static const char *default_personality_name = "__gxx_personality_v0";
3770 default_cpp_lpad_exc_signature (void)
3772 static gboolean inited = FALSE;
3773 static LLVMTypeRef sig;
3776 LLVMTypeRef signature [2];
3777 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3778 signature [1] = LLVMInt32Type ();
3779 sig = LLVMStructType (signature, 2, FALSE);
3787 get_mono_personality (EmitContext *ctx)
3789 LLVMValueRef personality = NULL;
3790 static gint32 mapping_inited = FALSE;
3791 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3793 if (!use_debug_personality) {
3794 if (ctx->cfg->compile_aot) {
3795 personality = get_intrinsic (ctx, default_personality_name);
3796 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3797 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3798 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3801 if (ctx->cfg->compile_aot) {
3802 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3804 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3805 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3806 mono_memory_barrier ();
3810 g_assert (personality);
3814 static LLVMBasicBlockRef
3815 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3817 MonoCompile *cfg = ctx->cfg;
3818 LLVMBuilderRef old_builder = ctx->builder;
3819 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3821 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3822 ctx->builder = lpadBuilder;
3824 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3825 g_assert (handler_bb);
3827 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3828 LLVMValueRef personality = get_mono_personality (ctx);
3829 g_assert (personality);
3831 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3832 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3834 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3835 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3836 g_assert (landing_pad);
3838 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3839 LLVMAddClause (landing_pad, cast);
3841 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3842 LLVMBuilderRef resume_builder = create_builder (ctx);
3843 ctx->builder = resume_builder;
3844 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3846 emit_resume_eh (ctx, handler_bb);
3849 ctx->builder = lpadBuilder;
3850 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3852 gboolean finally_only = TRUE;
3854 MonoExceptionClause *group_cursor = group_start;
3856 for (int i = 0; i < group_size; i ++) {
3857 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3858 finally_only = FALSE;
3864 // Handle landing pad inlining
3866 if (!finally_only) {
3867 // So at each level of the exception stack we will match the exception again.
3868 // During that match, we need to compare against the handler types for the current
3869 // protected region. We send the try start and end so that we can only check against
3870 // handlers for this lexical protected region.
3871 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3873 // if returns -1, resume
3874 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3876 // else move to that target bb
3877 for (int i=0; i < group_size; i++) {
3878 MonoExceptionClause *clause = group_start + i;
3879 int clause_index = clause - cfg->header->clauses;
3880 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3881 g_assert (handler_bb);
3882 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3883 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3886 int clause_index = group_start - cfg->header->clauses;
3887 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3888 g_assert (finally_bb);
3890 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3893 ctx->builder = old_builder;
3900 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3902 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3903 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3905 // Make exception available to catch blocks
3906 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3907 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3909 g_assert (ctx->ex_var);
3910 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3912 if (bb->in_scount == 1) {
3913 MonoInst *exvar = bb->in_stack [0];
3914 g_assert (!ctx->values [exvar->dreg]);
3915 g_assert (ctx->ex_var);
3916 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3917 emit_volatile_store (ctx, exvar->dreg);
3920 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3923 LLVMBuilderRef handler_builder = create_builder (ctx);
3924 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3925 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3927 // Make the handler code end with a jump to cbb
3928 LLVMBuildBr (handler_builder, cbb);
3932 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3934 MonoCompile *cfg = ctx->cfg;
3935 LLVMValueRef *values = ctx->values;
3936 LLVMModuleRef lmodule = ctx->lmodule;
3937 BBInfo *bblocks = ctx->bblocks;
3939 LLVMValueRef personality;
3940 LLVMValueRef landing_pad;
3941 LLVMBasicBlockRef target_bb;
3943 static int ti_generator;
3945 LLVMValueRef type_info;
3949 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3951 if (cfg->compile_aot) {
3952 /* Use a dummy personality function */
3953 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3954 g_assert (personality);
3956 #if LLVM_API_VERSION > 100
3957 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3958 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3959 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3960 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3961 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3962 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3963 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3965 static gint32 mapping_inited;
3967 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3969 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3970 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3974 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3976 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3979 * Create the type info
3981 sprintf (ti_name, "type_info_%d", ti_generator);
3984 if (cfg->compile_aot) {
3985 /* decode_eh_frame () in aot-runtime.c will decode this */
3986 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3987 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3990 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3992 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3994 #if LLVM_API_VERSION > 100
3995 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3996 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4001 * After the cfg mempool is freed, the type info will point to stale memory,
4002 * but this is not a problem, since we decode it once in exception_cb during
4005 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4006 *(gint32*)ti = clause_index;
4008 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4010 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4015 LLVMTypeRef members [2], ret_type;
4017 members [0] = i8ptr;
4018 members [1] = LLVMInt32Type ();
4019 ret_type = LLVMStructType (members, 2, FALSE);
4021 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4022 LLVMAddClause (landing_pad, type_info);
4024 /* Store the exception into the exvar */
4026 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4030 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4031 * code expects control to be transferred to this landing pad even in the
4032 * presence of nested clauses. The landing pad needs to branch to the landing
4033 * pads belonging to nested clauses based on the selector value returned by
4034 * the landing pad instruction, which is passed to the landing pad in a
4035 * register by the EH code.
4037 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4038 g_assert (target_bb);
4041 * Branch to the correct landing pad
4043 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4044 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4046 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4047 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4048 MonoBasicBlock *handler_bb;
4050 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4051 g_assert (handler_bb);
4053 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4054 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4057 /* Start a new bblock which CALL_HANDLER can branch to */
4058 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4060 ctx->builder = builder = create_builder (ctx);
4061 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4063 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4065 /* Store the exception into the IL level exvar */
4066 if (bb->in_scount == 1) {
4067 g_assert (bb->in_scount == 1);
4068 exvar = bb->in_stack [0];
4070 // FIXME: This is shared with filter clauses ?
4071 g_assert (!values [exvar->dreg]);
4073 g_assert (ctx->ex_var);
4074 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4075 emit_volatile_store (ctx, exvar->dreg);
4081 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4083 MonoCompile *cfg = ctx->cfg;
4084 MonoMethodSignature *sig = ctx->sig;
4085 LLVMValueRef method = ctx->lmethod;
4086 LLVMValueRef *values = ctx->values;
4087 LLVMValueRef *addresses = ctx->addresses;
4088 LLVMCallInfo *linfo = ctx->linfo;
4089 BBInfo *bblocks = ctx->bblocks;
4091 LLVMBasicBlockRef cbb;
4092 LLVMBuilderRef builder, starting_builder;
4093 gboolean has_terminator;
4095 LLVMValueRef lhs, rhs;
4098 cbb = get_end_bb (ctx, bb);
4100 builder = create_builder (ctx);
4101 ctx->builder = builder;
4102 LLVMPositionBuilderAtEnd (builder, cbb);
4107 if (bb->flags & BB_EXCEPTION_HANDLER) {
4108 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4109 set_failure (ctx, "handler without invokes");
4114 emit_llvmonly_handler_start (ctx, bb, cbb);
4116 emit_handler_start (ctx, bb, builder);
4119 builder = ctx->builder;
4122 has_terminator = FALSE;
4123 starting_builder = builder;
4124 for (ins = bb->code; ins; ins = ins->next) {
4125 const char *spec = LLVM_INS_INFO (ins->opcode);
4127 char dname_buf [128];
4129 emit_dbg_loc (ctx, builder, ins->cil_code);
4134 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4135 * Start a new bblock. If the llvm optimization passes merge these, we
4136 * can work around that by doing a volatile load + cond branch from
4137 * localloc-ed memory.
4139 //set_failure (ctx, "basic block too long");
4140 cbb = gen_bb (ctx, "CONT_LONG_BB");
4141 LLVMBuildBr (ctx->builder, cbb);
4142 ctx->builder = builder = create_builder (ctx);
4143 LLVMPositionBuilderAtEnd (builder, cbb);
4144 ctx->bblocks [bb->block_num].end_bblock = cbb;
4149 /* There could be instructions after a terminator, skip them */
4152 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4153 sprintf (dname_buf, "t%d", ins->dreg);
4157 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4158 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4160 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4161 lhs = emit_volatile_load (ctx, ins->sreg1);
4163 /* It is ok for SETRET to have an uninitialized argument */
4164 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4165 set_failure (ctx, "sreg1");
4168 lhs = values [ins->sreg1];
4174 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4175 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4176 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4177 rhs = emit_volatile_load (ctx, ins->sreg2);
4179 if (!values [ins->sreg2]) {
4180 set_failure (ctx, "sreg2");
4183 rhs = values [ins->sreg2];
4189 //mono_print_ins (ins);
4190 switch (ins->opcode) {
4193 case OP_LIVERANGE_START:
4194 case OP_LIVERANGE_END:
4197 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4200 #if SIZEOF_VOID_P == 4
4201 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4203 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4207 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4211 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4213 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4215 case OP_DUMMY_ICONST:
4216 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4218 case OP_DUMMY_I8CONST:
4219 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4221 case OP_DUMMY_R8CONST:
4222 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4225 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4226 LLVMBuildBr (builder, target_bb);
4227 has_terminator = TRUE;
4234 LLVMBasicBlockRef new_bb;
4235 LLVMBuilderRef new_builder;
4237 // The default branch is already handled
4238 // FIXME: Handle it here
4240 /* Start new bblock */
4241 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4242 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4244 lhs = convert (ctx, lhs, LLVMInt32Type ());
4245 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4246 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4247 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4249 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4252 new_builder = create_builder (ctx);
4253 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4254 LLVMBuildUnreachable (new_builder);
4256 has_terminator = TRUE;
4257 g_assert (!ins->next);
4263 switch (linfo->ret.storage) {
4264 case LLVMArgVtypeInReg: {
4265 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4266 LLVMValueRef val, addr, retval;
4269 retval = LLVMGetUndef (ret_type);
4271 if (!addresses [ins->sreg1]) {
4273 * The return type is an LLVM vector type, have to convert between it and the
4274 * real return type which is a struct type.
4276 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4277 /* Convert to 2xi64 first */
4278 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4280 for (i = 0; i < 2; ++i) {
4281 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4282 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4284 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4288 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4289 for (i = 0; i < 2; ++i) {
4290 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4291 LLVMValueRef indexes [2], part_addr;
4293 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4294 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4295 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4297 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4299 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4303 LLVMBuildRet (builder, retval);
4306 case LLVMArgVtypeAsScalar: {
4307 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4308 LLVMValueRef retval;
4310 g_assert (addresses [ins->sreg1]);
4312 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4313 LLVMBuildRet (builder, retval);
4316 case LLVMArgVtypeByVal: {
4317 LLVMValueRef retval;
4319 g_assert (addresses [ins->sreg1]);
4320 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4321 LLVMBuildRet (builder, retval);
4324 case LLVMArgVtypeByRef: {
4325 LLVMBuildRetVoid (builder);
4328 case LLVMArgGsharedvtFixed: {
4329 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4330 /* The return value is in lhs, need to store to the vret argument */
4331 /* sreg1 might not be set */
4333 g_assert (cfg->vret_addr);
4334 g_assert (values [cfg->vret_addr->dreg]);
4335 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4337 LLVMBuildRetVoid (builder);
4340 case LLVMArgGsharedvtFixedVtype: {
4342 LLVMBuildRetVoid (builder);
4345 case LLVMArgGsharedvtVariable: {
4347 LLVMBuildRetVoid (builder);
4350 case LLVMArgVtypeRetAddr: {
4351 LLVMBuildRetVoid (builder);
4354 case LLVMArgFpStruct: {
4355 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4356 LLVMValueRef retval;
4358 g_assert (addresses [ins->sreg1]);
4359 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4360 LLVMBuildRet (builder, retval);
4364 case LLVMArgNormal: {
4365 if (!lhs || ctx->is_dead [ins->sreg1]) {
4367 * The method did not set its return value, probably because it
4368 * ends with a throw.
4371 LLVMBuildRetVoid (builder);
4373 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4375 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4377 has_terminator = TRUE;
4381 g_assert_not_reached ();
4390 case OP_ICOMPARE_IMM:
4391 case OP_LCOMPARE_IMM:
4392 case OP_COMPARE_IMM: {
4394 LLVMValueRef cmp, args [16];
4395 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4397 if (ins->next->opcode == OP_NOP)
4400 if (ins->next->opcode == OP_BR)
4401 /* The comparison result is not needed */
4404 rel = mono_opcode_to_cond (ins->next->opcode);
4406 if (ins->opcode == OP_ICOMPARE_IMM) {
4407 lhs = convert (ctx, lhs, LLVMInt32Type ());
4408 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4410 if (ins->opcode == OP_LCOMPARE_IMM) {
4411 lhs = convert (ctx, lhs, LLVMInt64Type ());
4412 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4414 if (ins->opcode == OP_LCOMPARE) {
4415 lhs = convert (ctx, lhs, LLVMInt64Type ());
4416 rhs = convert (ctx, rhs, LLVMInt64Type ());
4418 if (ins->opcode == OP_ICOMPARE) {
4419 lhs = convert (ctx, lhs, LLVMInt32Type ());
4420 rhs = convert (ctx, rhs, LLVMInt32Type ());
4424 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4425 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4426 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4427 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4430 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4431 if (ins->opcode == OP_FCOMPARE) {
4432 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4433 } else if (ins->opcode == OP_RCOMPARE) {
4434 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4435 } else if (ins->opcode == OP_COMPARE_IMM) {
4436 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4437 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4439 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4440 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4441 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4442 /* The immediate is encoded in two fields */
4443 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4444 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4446 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4449 else if (ins->opcode == OP_COMPARE) {
4450 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4451 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4453 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4455 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4459 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4460 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4463 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4464 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4466 * If the target bb contains PHI instructions, LLVM requires
4467 * two PHI entries for this bblock, while we only generate one.
4468 * So convert this to an unconditional bblock. (bxc #171).
4470 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4472 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4474 has_terminator = TRUE;
4475 } else if (MONO_IS_SETCC (ins->next)) {
4476 sprintf (dname_buf, "t%d", ins->next->dreg);
4478 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4480 /* Add stores for volatile variables */
4481 emit_volatile_store (ctx, ins->next->dreg);
4482 } else if (MONO_IS_COND_EXC (ins->next)) {
4483 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4486 builder = ctx->builder;
4488 set_failure (ctx, "next");
4506 rel = mono_opcode_to_cond (ins->opcode);
4508 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4509 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4520 rel = mono_opcode_to_cond (ins->opcode);
4522 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4523 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4531 gboolean empty = TRUE;
4533 /* Check that all input bblocks really branch to us */
4534 for (i = 0; i < bb->in_count; ++i) {
4535 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4536 ins->inst_phi_args [i + 1] = -1;
4542 /* LLVM doesn't like phi instructions with zero operands */
4543 ctx->is_dead [ins->dreg] = TRUE;
4547 /* Created earlier, insert it now */
4548 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4550 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4551 int sreg1 = ins->inst_phi_args [i + 1];
4555 * Count the number of times the incoming bblock branches to us,
4556 * since llvm requires a separate entry for each.
4558 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4559 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4562 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4563 if (switch_ins->inst_many_bb [j] == bb)
4570 /* Remember for later */
4571 for (j = 0; j < count; ++j) {
4572 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4575 node->in_bb = bb->in_bb [i];
4577 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);
4587 values [ins->dreg] = lhs;
4591 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4594 values [ins->dreg] = lhs;
4596 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4598 * This is added by the spilling pass in case of the JIT,
4599 * but we have to do it ourselves.
4601 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4605 case OP_MOVE_F_TO_I4: {
4606 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4609 case OP_MOVE_I4_TO_F: {
4610 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4613 case OP_MOVE_F_TO_I8: {
4614 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4617 case OP_MOVE_I8_TO_F: {
4618 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4651 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4652 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4654 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4657 builder = ctx->builder;
4659 switch (ins->opcode) {
4662 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4666 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4670 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4674 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4678 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4682 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4686 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4690 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4694 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4698 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4702 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4706 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4710 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4714 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4718 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4721 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4724 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4728 g_assert_not_reached ();
4735 lhs = convert (ctx, lhs, LLVMFloatType ());
4736 rhs = convert (ctx, rhs, LLVMFloatType ());
4737 switch (ins->opcode) {
4739 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4742 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4745 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4748 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4751 g_assert_not_reached ();
4760 case OP_IREM_UN_IMM:
4762 case OP_IDIV_UN_IMM:
4768 case OP_ISHR_UN_IMM:
4778 case OP_LSHR_UN_IMM:
4784 case OP_SHR_UN_IMM: {
4787 if (spec [MONO_INST_SRC1] == 'l') {
4788 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4790 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4793 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4796 builder = ctx->builder;
4798 #if SIZEOF_VOID_P == 4
4799 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4800 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4803 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4804 lhs = convert (ctx, lhs, IntPtrType ());
4805 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4806 switch (ins->opcode) {
4810 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4814 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4819 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4823 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4825 case OP_IDIV_UN_IMM:
4826 case OP_LDIV_UN_IMM:
4827 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4831 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4833 case OP_IREM_UN_IMM:
4834 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4839 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4843 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4847 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4852 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4857 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4859 case OP_ISHR_UN_IMM:
4860 /* This is used to implement conv.u4, so the lhs could be an i8 */
4861 lhs = convert (ctx, lhs, LLVMInt32Type ());
4862 imm = convert (ctx, imm, LLVMInt32Type ());
4863 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4865 case OP_LSHR_UN_IMM:
4867 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4870 g_assert_not_reached ();
4875 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4878 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4881 lhs = convert (ctx, lhs, LLVMDoubleType ());
4882 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4885 lhs = convert (ctx, lhs, LLVMFloatType ());
4886 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4889 guint32 v = 0xffffffff;
4890 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4894 guint64 v = 0xffffffffffffffffLL;
4895 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4898 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4900 LLVMValueRef v1, v2;
4902 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4903 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4904 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4909 case OP_ICONV_TO_I1:
4910 case OP_ICONV_TO_I2:
4911 case OP_ICONV_TO_I4:
4912 case OP_ICONV_TO_U1:
4913 case OP_ICONV_TO_U2:
4914 case OP_ICONV_TO_U4:
4915 case OP_LCONV_TO_I1:
4916 case OP_LCONV_TO_I2:
4917 case OP_LCONV_TO_U1:
4918 case OP_LCONV_TO_U2:
4919 case OP_LCONV_TO_U4: {
4922 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);
4924 /* Have to do two casts since our vregs have type int */
4925 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4927 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4929 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4932 case OP_ICONV_TO_I8:
4933 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4935 case OP_ICONV_TO_U8:
4936 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4938 case OP_FCONV_TO_I4:
4939 case OP_RCONV_TO_I4:
4940 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4942 case OP_FCONV_TO_I1:
4943 case OP_RCONV_TO_I1:
4944 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4946 case OP_FCONV_TO_U1:
4947 case OP_RCONV_TO_U1:
4948 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4950 case OP_FCONV_TO_I2:
4951 case OP_RCONV_TO_I2:
4952 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4954 case OP_FCONV_TO_U2:
4955 case OP_RCONV_TO_U2:
4956 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4958 case OP_RCONV_TO_U4:
4959 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4961 case OP_FCONV_TO_I8:
4962 case OP_RCONV_TO_I8:
4963 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4966 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4968 case OP_ICONV_TO_R8:
4969 case OP_LCONV_TO_R8:
4970 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4972 case OP_ICONV_TO_R_UN:
4973 case OP_LCONV_TO_R_UN:
4974 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4976 #if SIZEOF_VOID_P == 4
4979 case OP_LCONV_TO_I4:
4980 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4982 case OP_ICONV_TO_R4:
4983 case OP_LCONV_TO_R4:
4984 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4986 values [ins->dreg] = v;
4988 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4990 case OP_FCONV_TO_R4:
4991 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4993 values [ins->dreg] = v;
4995 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4997 case OP_RCONV_TO_R8:
4998 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5000 case OP_RCONV_TO_R4:
5001 values [ins->dreg] = lhs;
5004 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5007 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5010 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5012 case OP_LOCALLOC_IMM: {
5015 guint32 size = ins->inst_imm;
5016 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5018 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5020 if (ins->flags & MONO_INST_INIT) {
5021 LLVMValueRef args [5];
5024 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5025 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5026 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5027 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5028 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5031 values [ins->dreg] = v;
5035 LLVMValueRef v, size;
5037 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), "");
5039 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5041 if (ins->flags & MONO_INST_INIT) {
5042 LLVMValueRef args [5];
5045 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5047 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5048 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5049 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5051 values [ins->dreg] = v;
5055 case OP_LOADI1_MEMBASE:
5056 case OP_LOADU1_MEMBASE:
5057 case OP_LOADI2_MEMBASE:
5058 case OP_LOADU2_MEMBASE:
5059 case OP_LOADI4_MEMBASE:
5060 case OP_LOADU4_MEMBASE:
5061 case OP_LOADI8_MEMBASE:
5062 case OP_LOADR4_MEMBASE:
5063 case OP_LOADR8_MEMBASE:
5064 case OP_LOAD_MEMBASE:
5072 LLVMValueRef base, index, addr;
5074 gboolean sext = FALSE, zext = FALSE;
5075 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5077 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5082 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)) {
5083 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5088 if (ins->inst_offset == 0) {
5090 } else if (ins->inst_offset % size != 0) {
5091 /* Unaligned load */
5092 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5093 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5095 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5096 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5100 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5102 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5104 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5106 * These will signal LLVM that these loads do not alias any stores, and
5107 * they can't fail, allowing them to be hoisted out of loops.
5109 set_invariant_load_flag (values [ins->dreg]);
5110 #if LLVM_API_VERSION < 100
5111 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5116 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5118 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5119 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5120 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5124 case OP_STOREI1_MEMBASE_REG:
5125 case OP_STOREI2_MEMBASE_REG:
5126 case OP_STOREI4_MEMBASE_REG:
5127 case OP_STOREI8_MEMBASE_REG:
5128 case OP_STORER4_MEMBASE_REG:
5129 case OP_STORER8_MEMBASE_REG:
5130 case OP_STORE_MEMBASE_REG: {
5132 LLVMValueRef index, addr;
5134 gboolean sext = FALSE, zext = FALSE;
5135 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5137 if (!values [ins->inst_destbasereg]) {
5138 set_failure (ctx, "inst_destbasereg");
5142 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5144 if (ins->inst_offset % size != 0) {
5145 /* Unaligned store */
5146 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5147 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5149 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5150 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5152 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5156 case OP_STOREI1_MEMBASE_IMM:
5157 case OP_STOREI2_MEMBASE_IMM:
5158 case OP_STOREI4_MEMBASE_IMM:
5159 case OP_STOREI8_MEMBASE_IMM:
5160 case OP_STORE_MEMBASE_IMM: {
5162 LLVMValueRef index, addr;
5164 gboolean sext = FALSE, zext = FALSE;
5165 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5167 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5169 if (ins->inst_offset % size != 0) {
5170 /* Unaligned store */
5171 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5172 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5174 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5175 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5177 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5182 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5184 case OP_OUTARG_VTRETADDR:
5192 case OP_VOIDCALL_MEMBASE:
5193 case OP_CALL_MEMBASE:
5194 case OP_LCALL_MEMBASE:
5195 case OP_FCALL_MEMBASE:
5196 case OP_RCALL_MEMBASE:
5197 case OP_VCALL_MEMBASE:
5198 case OP_VOIDCALL_REG:
5203 case OP_VCALL_REG: {
5204 process_call (ctx, bb, &builder, ins);
5209 LLVMValueRef indexes [2];
5210 MonoJumpInfo *tmp_ji, *ji;
5211 LLVMValueRef got_entry_addr;
5215 * FIXME: Can't allocate from the cfg mempool since that is freed if
5216 * the LLVM compile fails.
5218 tmp_ji = g_new0 (MonoJumpInfo, 1);
5219 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5220 tmp_ji->data.target = ins->inst_p0;
5222 ji = mono_aot_patch_info_dup (tmp_ji);
5225 ji->next = cfg->patch_info;
5226 cfg->patch_info = ji;
5228 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5229 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5230 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5231 if (!mono_aot_is_shared_got_offset (got_offset)) {
5232 //mono_print_ji (ji);
5234 ctx->has_got_access = TRUE;
5237 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5238 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5239 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5241 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5242 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5244 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5245 if (!cfg->llvm_only)
5246 set_invariant_load_flag (values [ins->dreg]);
5249 case OP_NOT_REACHED:
5250 LLVMBuildUnreachable (builder);
5251 has_terminator = TRUE;
5252 g_assert (bb->block_num < cfg->max_block_num);
5253 ctx->unreachable [bb->block_num] = TRUE;
5254 /* Might have instructions after this */
5256 MonoInst *next = ins->next;
5258 * FIXME: If later code uses the regs defined by these instructions,
5259 * compilation will fail.
5261 MONO_DELETE_INS (bb, next);
5265 MonoInst *var = ins->inst_i0;
5267 if (var->opcode == OP_VTARG_ADDR) {
5268 /* The variable contains the vtype address */
5269 values [ins->dreg] = values [var->dreg];
5270 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5271 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5273 values [ins->dreg] = addresses [var->dreg];
5278 LLVMValueRef args [1];
5280 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5281 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5285 LLVMValueRef args [1];
5287 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5288 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5292 LLVMValueRef args [1];
5294 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5295 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5299 LLVMValueRef args [1];
5301 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5302 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5316 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5317 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5319 switch (ins->opcode) {
5322 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5326 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5330 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5334 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5337 g_assert_not_reached ();
5340 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5343 case OP_ATOMIC_EXCHANGE_I4:
5344 case OP_ATOMIC_EXCHANGE_I8: {
5345 LLVMValueRef args [2];
5348 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5349 t = LLVMInt32Type ();
5351 t = LLVMInt64Type ();
5353 g_assert (ins->inst_offset == 0);
5355 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5356 args [1] = convert (ctx, rhs, t);
5358 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5361 case OP_ATOMIC_ADD_I4:
5362 case OP_ATOMIC_ADD_I8: {
5363 LLVMValueRef args [2];
5366 if (ins->opcode == OP_ATOMIC_ADD_I4)
5367 t = LLVMInt32Type ();
5369 t = LLVMInt64Type ();
5371 g_assert (ins->inst_offset == 0);
5373 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5374 args [1] = convert (ctx, rhs, t);
5375 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5378 case OP_ATOMIC_CAS_I4:
5379 case OP_ATOMIC_CAS_I8: {
5380 LLVMValueRef args [3], val;
5383 if (ins->opcode == OP_ATOMIC_CAS_I4)
5384 t = LLVMInt32Type ();
5386 t = LLVMInt64Type ();
5388 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5390 args [1] = convert (ctx, values [ins->sreg3], t);
5392 args [2] = convert (ctx, values [ins->sreg2], t);
5393 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5394 /* cmpxchg returns a pair */
5395 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5398 case OP_MEMORY_BARRIER: {
5399 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5402 case OP_ATOMIC_LOAD_I1:
5403 case OP_ATOMIC_LOAD_I2:
5404 case OP_ATOMIC_LOAD_I4:
5405 case OP_ATOMIC_LOAD_I8:
5406 case OP_ATOMIC_LOAD_U1:
5407 case OP_ATOMIC_LOAD_U2:
5408 case OP_ATOMIC_LOAD_U4:
5409 case OP_ATOMIC_LOAD_U8:
5410 case OP_ATOMIC_LOAD_R4:
5411 case OP_ATOMIC_LOAD_R8: {
5412 set_failure (ctx, "atomic mono.load intrinsic");
5416 gboolean sext, zext;
5418 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5419 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5420 LLVMValueRef index, addr;
5422 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5427 if (ins->inst_offset != 0) {
5428 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5429 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5434 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5436 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5439 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5441 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5445 case OP_ATOMIC_STORE_I1:
5446 case OP_ATOMIC_STORE_I2:
5447 case OP_ATOMIC_STORE_I4:
5448 case OP_ATOMIC_STORE_I8:
5449 case OP_ATOMIC_STORE_U1:
5450 case OP_ATOMIC_STORE_U2:
5451 case OP_ATOMIC_STORE_U4:
5452 case OP_ATOMIC_STORE_U8:
5453 case OP_ATOMIC_STORE_R4:
5454 case OP_ATOMIC_STORE_R8: {
5455 set_failure (ctx, "atomic mono.store intrinsic");
5459 gboolean sext, zext;
5461 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5462 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5463 LLVMValueRef index, addr, value;
5465 if (!values [ins->inst_destbasereg]) {
5466 set_failure (ctx, "inst_destbasereg");
5470 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5472 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5473 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5474 value = convert (ctx, values [ins->sreg1], t);
5476 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5480 case OP_RELAXED_NOP: {
5481 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5482 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5489 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5491 // 257 == FS segment register
5492 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5494 // 256 == GS segment register
5495 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5498 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5499 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5500 /* See mono_amd64_emit_tls_get () */
5501 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5503 // 256 == GS segment register
5504 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5505 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5507 set_failure (ctx, "opcode tls-get");
5513 case OP_TLS_GET_REG: {
5514 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5515 /* See emit_tls_get_reg () */
5516 // 256 == GS segment register
5517 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5518 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5520 set_failure (ctx, "opcode tls-get");
5526 case OP_TLS_SET_REG: {
5527 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5528 /* See emit_tls_get_reg () */
5529 // 256 == GS segment register
5530 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5531 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5533 set_failure (ctx, "opcode tls-set-reg");
5543 case OP_IADD_OVF_UN:
5545 case OP_ISUB_OVF_UN:
5547 case OP_IMUL_OVF_UN:
5548 #if SIZEOF_VOID_P == 8
5550 case OP_LADD_OVF_UN:
5552 case OP_LSUB_OVF_UN:
5554 case OP_LMUL_OVF_UN:
5557 LLVMValueRef args [2], val, ovf, func;
5559 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5560 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5561 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5563 val = LLVMBuildCall (builder, func, args, 2, "");
5564 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5565 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5566 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5569 builder = ctx->builder;
5575 * We currently model them using arrays. Promotion to local vregs is
5576 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5577 * so we always have an entry in cfg->varinfo for them.
5578 * FIXME: Is this needed ?
5581 MonoClass *klass = ins->klass;
5582 LLVMValueRef args [5];
5586 set_failure (ctx, "!klass");
5590 if (!addresses [ins->dreg])
5591 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5592 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5593 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5594 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5596 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5597 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5598 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5601 case OP_DUMMY_VZERO:
5604 case OP_STOREV_MEMBASE:
5605 case OP_LOADV_MEMBASE:
5607 MonoClass *klass = ins->klass;
5608 LLVMValueRef src = NULL, dst, args [5];
5609 gboolean done = FALSE;
5613 set_failure (ctx, "!klass");
5617 if (mini_is_gsharedvt_klass (klass)) {
5619 set_failure (ctx, "gsharedvt");
5623 switch (ins->opcode) {
5624 case OP_STOREV_MEMBASE:
5625 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5626 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5627 /* Decomposed earlier */
5628 g_assert_not_reached ();
5631 if (!addresses [ins->sreg1]) {
5633 g_assert (values [ins->sreg1]);
5634 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));
5635 LLVMBuildStore (builder, values [ins->sreg1], dst);
5638 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5639 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5642 case OP_LOADV_MEMBASE:
5643 if (!addresses [ins->dreg])
5644 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5645 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5646 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5649 if (!addresses [ins->sreg1])
5650 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5651 if (!addresses [ins->dreg])
5652 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5653 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5654 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5657 g_assert_not_reached ();
5667 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5668 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5670 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5671 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5672 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5675 case OP_LLVM_OUTARG_VT: {
5676 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5677 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5679 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5680 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5682 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5683 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5685 g_assert (addresses [ins->sreg1]);
5686 addresses [ins->dreg] = addresses [ins->sreg1];
5688 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5689 if (!addresses [ins->sreg1]) {
5690 addresses [ins->sreg1] = build_alloca (ctx, t);
5691 g_assert (values [ins->sreg1]);
5693 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5694 addresses [ins->dreg] = addresses [ins->sreg1];
5696 if (!addresses [ins->sreg1]) {
5697 addresses [ins->sreg1] = build_alloca (ctx, t);
5698 g_assert (values [ins->sreg1]);
5699 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5701 addresses [ins->dreg] = addresses [ins->sreg1];
5709 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5711 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5714 case OP_LOADX_MEMBASE: {
5715 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5718 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5719 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5722 case OP_STOREX_MEMBASE: {
5723 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5726 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5727 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5734 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5738 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5744 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5748 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5752 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5756 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5759 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5762 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5765 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5769 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5780 LLVMValueRef v = NULL;
5782 switch (ins->opcode) {
5787 t = LLVMVectorType (LLVMInt32Type (), 4);
5788 rt = LLVMVectorType (LLVMFloatType (), 4);
5794 t = LLVMVectorType (LLVMInt64Type (), 2);
5795 rt = LLVMVectorType (LLVMDoubleType (), 2);
5798 t = LLVMInt32Type ();
5799 rt = LLVMInt32Type ();
5800 g_assert_not_reached ();
5803 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5804 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5805 switch (ins->opcode) {
5808 v = LLVMBuildAnd (builder, lhs, rhs, "");
5812 v = LLVMBuildOr (builder, lhs, rhs, "");
5816 v = LLVMBuildXor (builder, lhs, rhs, "");
5820 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5823 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5847 case OP_PADDB_SAT_UN:
5848 case OP_PADDW_SAT_UN:
5849 case OP_PSUBB_SAT_UN:
5850 case OP_PSUBW_SAT_UN:
5858 case OP_PMULW_HIGH_UN: {
5859 LLVMValueRef args [2];
5864 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5871 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5875 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5883 case OP_EXTRACTX_U2:
5885 case OP_EXTRACT_U1: {
5887 gboolean zext = FALSE;
5889 t = simd_op_to_llvm_type (ins->opcode);
5891 switch (ins->opcode) {
5899 case OP_EXTRACTX_U2:
5904 t = LLVMInt32Type ();
5905 g_assert_not_reached ();
5908 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5909 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5911 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5920 case OP_EXPAND_R8: {
5921 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5922 LLVMValueRef mask [16], v;
5925 for (i = 0; i < 16; ++i)
5926 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5928 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5930 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5931 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5936 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5939 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5942 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5945 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5948 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5951 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5962 case OP_EXTRACT_MASK:
5969 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5971 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5977 LLVMValueRef args [3];
5981 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5983 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5988 /* This is only used for implementing shifts by non-immediate */
5989 values [ins->dreg] = lhs;
6000 LLVMValueRef args [3];
6003 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6005 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6016 case OP_PSHLQ_REG: {
6017 LLVMValueRef args [3];
6020 args [1] = values [ins->sreg2];
6022 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6029 case OP_PSHUFLEW_LOW:
6030 case OP_PSHUFLEW_HIGH: {
6032 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6033 int i, mask_size = 0;
6034 int imask = ins->inst_c0;
6036 /* Convert the x86 shuffle mask to LLVM's */
6037 switch (ins->opcode) {
6040 mask [0] = ((imask >> 0) & 3);
6041 mask [1] = ((imask >> 2) & 3);
6042 mask [2] = ((imask >> 4) & 3) + 4;
6043 mask [3] = ((imask >> 6) & 3) + 4;
6044 v1 = values [ins->sreg1];
6045 v2 = values [ins->sreg2];
6049 mask [0] = ((imask >> 0) & 1);
6050 mask [1] = ((imask >> 1) & 1) + 2;
6051 v1 = values [ins->sreg1];
6052 v2 = values [ins->sreg2];
6054 case OP_PSHUFLEW_LOW:
6056 mask [0] = ((imask >> 0) & 3);
6057 mask [1] = ((imask >> 2) & 3);
6058 mask [2] = ((imask >> 4) & 3);
6059 mask [3] = ((imask >> 6) & 3);
6064 v1 = values [ins->sreg1];
6065 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6067 case OP_PSHUFLEW_HIGH:
6073 mask [4] = 4 + ((imask >> 0) & 3);
6074 mask [5] = 4 + ((imask >> 2) & 3);
6075 mask [6] = 4 + ((imask >> 4) & 3);
6076 mask [7] = 4 + ((imask >> 6) & 3);
6077 v1 = values [ins->sreg1];
6078 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6082 mask [0] = ((imask >> 0) & 3);
6083 mask [1] = ((imask >> 2) & 3);
6084 mask [2] = ((imask >> 4) & 3);
6085 mask [3] = ((imask >> 6) & 3);
6086 v1 = values [ins->sreg1];
6087 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6090 g_assert_not_reached ();
6092 for (i = 0; i < mask_size; ++i)
6093 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6095 values [ins->dreg] =
6096 LLVMBuildShuffleVector (builder, v1, v2,
6097 LLVMConstVector (mask_values, mask_size), dname);
6101 case OP_UNPACK_LOWB:
6102 case OP_UNPACK_LOWW:
6103 case OP_UNPACK_LOWD:
6104 case OP_UNPACK_LOWQ:
6105 case OP_UNPACK_LOWPS:
6106 case OP_UNPACK_LOWPD:
6107 case OP_UNPACK_HIGHB:
6108 case OP_UNPACK_HIGHW:
6109 case OP_UNPACK_HIGHD:
6110 case OP_UNPACK_HIGHQ:
6111 case OP_UNPACK_HIGHPS:
6112 case OP_UNPACK_HIGHPD: {
6114 LLVMValueRef mask_values [16];
6115 int i, mask_size = 0;
6116 gboolean low = FALSE;
6118 switch (ins->opcode) {
6119 case OP_UNPACK_LOWB:
6123 case OP_UNPACK_LOWW:
6127 case OP_UNPACK_LOWD:
6128 case OP_UNPACK_LOWPS:
6132 case OP_UNPACK_LOWQ:
6133 case OP_UNPACK_LOWPD:
6137 case OP_UNPACK_HIGHB:
6140 case OP_UNPACK_HIGHW:
6143 case OP_UNPACK_HIGHD:
6144 case OP_UNPACK_HIGHPS:
6147 case OP_UNPACK_HIGHQ:
6148 case OP_UNPACK_HIGHPD:
6152 g_assert_not_reached ();
6156 for (i = 0; i < (mask_size / 2); ++i) {
6158 mask [(i * 2) + 1] = mask_size + i;
6161 for (i = 0; i < (mask_size / 2); ++i) {
6162 mask [(i * 2)] = (mask_size / 2) + i;
6163 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6167 for (i = 0; i < mask_size; ++i)
6168 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6170 values [ins->dreg] =
6171 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6172 LLVMConstVector (mask_values, mask_size), dname);
6177 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6178 LLVMValueRef v, val;
6180 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6181 val = LLVMConstNull (t);
6182 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6183 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6185 values [ins->dreg] = val;
6189 case OP_DUPPS_HIGH: {
6190 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6191 LLVMValueRef v1, v2, val;
6194 if (ins->opcode == OP_DUPPS_LOW) {
6195 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6196 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6198 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6199 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6201 val = LLVMConstNull (t);
6202 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6203 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6204 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6205 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6207 values [ins->dreg] = val;
6217 * EXCEPTION HANDLING
6219 case OP_IMPLICIT_EXCEPTION:
6220 /* This marks a place where an implicit exception can happen */
6221 if (bb->region != -1)
6222 set_failure (ctx, "implicit-exception");
6226 gboolean rethrow = (ins->opcode == OP_RETHROW);
6227 if (ctx->llvm_only) {
6228 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6229 has_terminator = TRUE;
6230 ctx->unreachable [bb->block_num] = TRUE;
6232 emit_throw (ctx, bb, rethrow, lhs);
6233 builder = ctx->builder;
6237 case OP_CALL_HANDLER: {
6239 * We don't 'call' handlers, but instead simply branch to them.
6240 * The code generated by ENDFINALLY will branch back to us.
6242 LLVMBasicBlockRef noex_bb;
6244 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6246 bb_list = info->call_handler_return_bbs;
6249 * Set the indicator variable for the finally clause.
6251 lhs = info->finally_ind;
6253 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6255 /* Branch to the finally clause */
6256 LLVMBuildBr (builder, info->call_handler_target_bb);
6258 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6259 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6261 builder = ctx->builder = create_builder (ctx);
6262 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6264 bblocks [bb->block_num].end_bblock = noex_bb;
6267 case OP_START_HANDLER: {
6270 case OP_ENDFINALLY: {
6271 LLVMBasicBlockRef resume_bb;
6272 MonoBasicBlock *handler_bb;
6273 LLVMValueRef val, switch_ins, callee;
6277 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6278 g_assert (handler_bb);
6279 info = &bblocks [handler_bb->block_num];
6280 lhs = info->finally_ind;
6283 bb_list = info->call_handler_return_bbs;
6285 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6287 /* Load the finally variable */
6288 val = LLVMBuildLoad (builder, lhs, "");
6290 /* Reset the variable */
6291 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6293 /* Branch to either resume_bb, or to the bblocks in bb_list */
6294 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6296 * The other targets are added at the end to handle OP_CALL_HANDLER
6297 * opcodes processed later.
6299 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6301 builder = ctx->builder = create_builder (ctx);
6302 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6304 if (ctx->llvm_only) {
6305 emit_resume_eh (ctx, bb);
6307 if (ctx->cfg->compile_aot) {
6308 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6310 #if LLVM_API_VERSION > 100
6311 MonoJitICallInfo *info;
6313 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6315 gpointer target = (void*)info->func;
6316 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6317 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6319 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6322 LLVMBuildCall (builder, callee, NULL, 0, "");
6323 LLVMBuildUnreachable (builder);
6326 has_terminator = TRUE;
6329 case OP_IL_SEQ_POINT:
6334 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6335 set_failure (ctx, reason);
6343 /* Convert the value to the type required by phi nodes */
6344 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6345 if (!values [ins->dreg])
6347 values [ins->dreg] = addresses [ins->dreg];
6349 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6352 /* Add stores for volatile variables */
6353 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6354 emit_volatile_store (ctx, ins->dreg);
6360 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6361 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6364 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6365 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6366 LLVMBuildRetVoid (builder);
6369 if (bb == cfg->bb_entry)
6370 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6374 * mono_llvm_check_method_supported:
6376 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6377 * compiling a method twice.
6380 mono_llvm_check_method_supported (MonoCompile *cfg)
6387 if (cfg->method->save_lmf) {
6388 cfg->exception_message = g_strdup ("lmf");
6389 cfg->disable_llvm = TRUE;
6391 if (cfg->disable_llvm)
6395 * Nested clauses where one of the clauses is a finally clause is
6396 * not supported, because LLVM can't figure out the control flow,
6397 * probably because we resume exception handling by calling our
6398 * own function instead of using the 'resume' llvm instruction.
6400 for (i = 0; i < cfg->header->num_clauses; ++i) {
6401 for (j = 0; j < cfg->header->num_clauses; ++j) {
6402 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6403 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6405 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6406 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6407 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6408 cfg->exception_message = g_strdup ("nested clauses");
6409 cfg->disable_llvm = TRUE;
6414 if (cfg->disable_llvm)
6418 if (cfg->method->dynamic) {
6419 cfg->exception_message = g_strdup ("dynamic.");
6420 cfg->disable_llvm = TRUE;
6422 if (cfg->disable_llvm)
6426 static LLVMCallInfo*
6427 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6429 LLVMCallInfo *linfo;
6432 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6436 * Gsharedvt methods have the following calling convention:
6437 * - all arguments are passed by ref, even non generic ones
6438 * - the return value is returned by ref too, using a vret
6439 * argument passed after 'this'.
6441 n = sig->param_count + sig->hasthis;
6442 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6446 linfo->args [pindex ++].storage = LLVMArgNormal;
6448 if (sig->ret->type != MONO_TYPE_VOID) {
6449 if (mini_is_gsharedvt_variable_type (sig->ret))
6450 linfo->ret.storage = LLVMArgGsharedvtVariable;
6451 else if (mini_type_is_vtype (sig->ret))
6452 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6454 linfo->ret.storage = LLVMArgGsharedvtFixed;
6455 linfo->vret_arg_index = pindex;
6457 linfo->ret.storage = LLVMArgNone;
6460 for (i = 0; i < sig->param_count; ++i) {
6461 if (sig->params [i]->byref)
6462 linfo->args [pindex].storage = LLVMArgNormal;
6463 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6464 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6465 else if (mini_type_is_vtype (sig->params [i]))
6466 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6468 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6469 linfo->args [pindex].type = sig->params [i];
6476 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6477 for (i = 0; i < sig->param_count; ++i)
6478 linfo->args [i + sig->hasthis].type = sig->params [i];
6484 emit_method_inner (EmitContext *ctx);
6487 free_ctx (EmitContext *ctx)
6491 g_free (ctx->values);
6492 g_free (ctx->addresses);
6493 g_free (ctx->vreg_types);
6494 g_free (ctx->vreg_cli_types);
6495 g_free (ctx->is_dead);
6496 g_free (ctx->unreachable);
6497 g_ptr_array_free (ctx->phi_values, TRUE);
6498 g_free (ctx->bblocks);
6499 g_hash_table_destroy (ctx->region_to_handler);
6500 g_hash_table_destroy (ctx->clause_to_handler);
6501 g_hash_table_destroy (ctx->jit_callees);
6502 g_free (ctx->method_name);
6503 g_ptr_array_free (ctx->bblock_list, TRUE);
6505 for (l = ctx->builders; l; l = l->next) {
6506 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6507 LLVMDisposeBuilder (builder);
6514 * mono_llvm_emit_method:
6516 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6519 mono_llvm_emit_method (MonoCompile *cfg)
6523 gboolean is_linkonce = FALSE;
6526 /* The code below might acquire the loader lock, so use it for global locking */
6527 mono_loader_lock ();
6529 /* Used to communicate with the callbacks */
6530 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6532 ctx = g_new0 (EmitContext, 1);
6534 ctx->mempool = cfg->mempool;
6537 * This maps vregs to the LLVM instruction defining them
6539 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6541 * This maps vregs for volatile variables to the LLVM instruction defining their
6544 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6545 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6546 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6547 ctx->phi_values = g_ptr_array_sized_new (256);
6549 * This signals whenever the vreg was defined by a phi node with no input vars
6550 * (i.e. all its input bblocks end with NOT_REACHABLE).
6552 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6553 /* Whenever the bblock is unreachable */
6554 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6555 ctx->bblock_list = g_ptr_array_sized_new (256);
6557 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6558 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6559 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6560 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6561 if (cfg->compile_aot) {
6562 ctx->module = &aot_module;
6566 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6567 * linkage for them. This requires the following:
6568 * - the method needs to have a unique mangled name
6569 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6571 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6573 method_name = mono_aot_get_mangled_method_name (cfg->method);
6575 is_linkonce = FALSE;
6578 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6580 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6584 method_name = mono_aot_get_method_name (cfg);
6585 cfg->llvm_method_name = g_strdup (method_name);
6587 init_jit_module (cfg->domain);
6588 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6589 method_name = mono_method_full_name (cfg->method, TRUE);
6591 ctx->method_name = method_name;
6592 ctx->is_linkonce = is_linkonce;
6594 #if LLVM_API_VERSION > 100
6595 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6597 ctx->lmodule = ctx->module->lmodule;
6599 ctx->llvm_only = ctx->module->llvm_only;
6601 emit_method_inner (ctx);
6603 if (!ctx_ok (ctx)) {
6605 /* Need to add unused phi nodes as they can be referenced by other values */
6606 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6607 LLVMBuilderRef builder;
6609 builder = create_builder (ctx);
6610 LLVMPositionBuilderAtEnd (builder, phi_bb);
6612 for (i = 0; i < ctx->phi_values->len; ++i) {
6613 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6614 if (LLVMGetInstructionParent (v) == NULL)
6615 LLVMInsertIntoBuilder (builder, v);
6618 LLVMDeleteFunction (ctx->lmethod);
6624 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6626 mono_loader_unlock ();
6630 emit_method_inner (EmitContext *ctx)
6632 MonoCompile *cfg = ctx->cfg;
6633 MonoMethodSignature *sig;
6635 LLVMTypeRef method_type;
6636 LLVMValueRef method = NULL;
6637 LLVMValueRef *values = ctx->values;
6638 int i, max_block_num, bb_index;
6639 gboolean last = FALSE;
6640 LLVMCallInfo *linfo;
6641 LLVMModuleRef lmodule = ctx->lmodule;
6643 GPtrArray *bblock_list = ctx->bblock_list;
6644 MonoMethodHeader *header;
6645 MonoExceptionClause *clause;
6648 if (cfg->gsharedvt && !cfg->llvm_only) {
6649 set_failure (ctx, "gsharedvt");
6655 static int count = 0;
6658 if (g_getenv ("LLVM_COUNT")) {
6659 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6660 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6664 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6665 set_failure (ctx, "count");
6672 sig = mono_method_signature (cfg->method);
6675 linfo = get_llvm_call_info (cfg, sig);
6681 linfo->rgctx_arg = TRUE;
6682 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6686 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6687 ctx->lmethod = method;
6689 if (!cfg->llvm_only)
6690 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6691 LLVMSetLinkage (method, LLVMPrivateLinkage);
6693 LLVMAddFunctionAttr (method, LLVMUWTable);
6695 if (cfg->compile_aot) {
6696 LLVMSetLinkage (method, LLVMInternalLinkage);
6697 if (ctx->module->external_symbols) {
6698 LLVMSetLinkage (method, LLVMExternalLinkage);
6699 LLVMSetVisibility (method, LLVMHiddenVisibility);
6701 if (ctx->is_linkonce) {
6702 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6703 LLVMSetVisibility (method, LLVMDefaultVisibility);
6706 #if LLVM_API_VERSION > 100
6707 LLVMSetLinkage (method, LLVMExternalLinkage);
6709 LLVMSetLinkage (method, LLVMPrivateLinkage);
6713 if (cfg->method->save_lmf && !cfg->llvm_only) {
6714 set_failure (ctx, "lmf");
6718 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6719 set_failure (ctx, "pinvoke signature");
6723 header = cfg->header;
6724 for (i = 0; i < header->num_clauses; ++i) {
6725 clause = &header->clauses [i];
6726 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6727 set_failure (ctx, "non-finally/catch clause.");
6731 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6732 /* We can't handle inlined methods with clauses */
6733 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6735 if (linfo->rgctx_arg) {
6736 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6737 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6739 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6740 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6741 * CC_X86_64_Mono in X86CallingConv.td.
6743 if (!ctx->llvm_only)
6744 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6745 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6747 ctx->rgctx_arg_pindex = -1;
6749 if (cfg->vret_addr) {
6750 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6751 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6752 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6753 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6754 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6759 ctx->this_arg_pindex = linfo->this_arg_pindex;
6760 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6761 values [cfg->args [0]->dreg] = ctx->this_arg;
6762 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6765 names = g_new (char *, sig->param_count);
6766 mono_method_get_param_names (cfg->method, (const char **) names);
6768 for (i = 0; i < sig->param_count; ++i) {
6769 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6771 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6774 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6775 name = g_strdup_printf ("dummy_%d_%d", i, j);
6776 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6780 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6781 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6782 if (names [i] && names [i][0] != '\0')
6783 name = g_strdup_printf ("p_arg_%s", names [i]);
6785 name = g_strdup_printf ("p_arg_%d", i);
6787 if (names [i] && names [i][0] != '\0')
6788 name = g_strdup_printf ("arg_%s", names [i]);
6790 name = g_strdup_printf ("arg_%d", i);
6792 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6794 if (ainfo->storage == LLVMArgVtypeByVal)
6795 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6797 if (ainfo->storage == LLVMArgVtypeByRef) {
6799 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6804 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6805 ctx->minfo = mono_debug_lookup_method (cfg->method);
6806 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6810 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6811 max_block_num = MAX (max_block_num, bb->block_num);
6812 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6814 /* Add branches between non-consecutive bblocks */
6815 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6816 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6817 bb->next_bb != bb->last_ins->inst_false_bb) {
6819 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6820 inst->opcode = OP_BR;
6821 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6822 mono_bblock_add_inst (bb, inst);
6827 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6828 * was later optimized away, so clear these flags, and add them back for the still
6829 * present OP_LDADDR instructions.
6831 for (i = 0; i < cfg->next_vreg; ++i) {
6834 ins = get_vreg_to_inst (cfg, i);
6835 if (ins && ins != cfg->rgctx_var)
6836 ins->flags &= ~MONO_INST_INDIRECT;
6840 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6842 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6844 LLVMBuilderRef builder;
6846 char dname_buf[128];
6848 builder = create_builder (ctx);
6850 for (ins = bb->code; ins; ins = ins->next) {
6851 switch (ins->opcode) {
6856 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6861 if (ins->opcode == OP_VPHI) {
6862 /* Treat valuetype PHI nodes as operating on the address itself */
6863 g_assert (ins->klass);
6864 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6868 * Have to precreate these, as they can be referenced by
6869 * earlier instructions.
6871 sprintf (dname_buf, "t%d", ins->dreg);
6873 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6875 if (ins->opcode == OP_VPHI)
6876 ctx->addresses [ins->dreg] = values [ins->dreg];
6878 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6881 * Set the expected type of the incoming arguments since these have
6882 * to have the same type.
6884 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6885 int sreg1 = ins->inst_phi_args [i + 1];
6888 ctx->vreg_types [sreg1] = phi_type;
6893 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6902 * Create an ordering for bblocks, use the depth first order first, then
6903 * put the exception handling bblocks last.
6905 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6906 bb = cfg->bblocks [bb_index];
6907 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6908 g_ptr_array_add (bblock_list, bb);
6909 bblocks [bb->block_num].added = TRUE;
6913 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6914 if (!bblocks [bb->block_num].added)
6915 g_ptr_array_add (bblock_list, bb);
6919 * Second pass: generate code.
6922 LLVMBuilderRef entry_builder = create_builder (ctx);
6923 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6924 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6925 emit_entry_bb (ctx, entry_builder);
6927 // Make landing pads first
6928 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6930 if (ctx->llvm_only) {
6931 size_t group_index = 0;
6932 while (group_index < cfg->header->num_clauses) {
6934 size_t cursor = group_index;
6935 while (cursor < cfg->header->num_clauses &&
6936 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6937 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6942 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6943 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6944 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6946 group_index = cursor;
6950 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6951 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6953 // Prune unreachable mono BBs.
6954 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6957 process_bb (ctx, bb);
6961 g_hash_table_destroy (ctx->exc_meta);
6963 mono_memory_barrier ();
6965 /* Add incoming phi values */
6966 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6967 GSList *l, *ins_list;
6969 ins_list = bblocks [bb->block_num].phi_nodes;
6971 for (l = ins_list; l; l = l->next) {
6972 PhiNode *node = (PhiNode*)l->data;
6973 MonoInst *phi = node->phi;
6974 int sreg1 = node->sreg;
6975 LLVMBasicBlockRef in_bb;
6980 in_bb = get_end_bb (ctx, node->in_bb);
6982 if (ctx->unreachable [node->in_bb->block_num])
6985 if (!values [sreg1]) {
6986 /* Can happen with values in EH clauses */
6987 set_failure (ctx, "incoming phi sreg1");
6991 if (phi->opcode == OP_VPHI) {
6992 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6993 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6995 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6996 set_failure (ctx, "incoming phi arg type mismatch");
6999 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7000 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7005 /* Nullify empty phi instructions */
7006 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7007 GSList *l, *ins_list;
7009 ins_list = bblocks [bb->block_num].phi_nodes;
7011 for (l = ins_list; l; l = l->next) {
7012 PhiNode *node = (PhiNode*)l->data;
7013 MonoInst *phi = node->phi;
7014 LLVMValueRef phi_ins = values [phi->dreg];
7017 /* Already removed */
7020 if (LLVMCountIncoming (phi_ins) == 0) {
7021 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7022 LLVMInstructionEraseFromParent (phi_ins);
7023 values [phi->dreg] = NULL;
7028 /* Create the SWITCH statements for ENDFINALLY instructions */
7029 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7030 BBInfo *info = &bblocks [bb->block_num];
7032 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7033 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7034 GSList *bb_list = info->call_handler_return_bbs;
7036 for (i = 0; i < g_slist_length (bb_list); ++i)
7037 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7041 /* Initialize the method if needed */
7042 if (cfg->compile_aot && ctx->llvm_only) {
7043 // FIXME: Add more shared got entries
7044 ctx->builder = create_builder (ctx);
7045 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7047 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7049 // FIXME: beforefieldinit
7050 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7051 emit_init_method (ctx);
7053 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7057 if (cfg->llvm_only) {
7058 GHashTableIter iter;
7060 GSList *callers, *l, *l2;
7063 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7064 * We can't do this earlier, as it contains llvm instructions which can be
7065 * freed if compilation fails.
7066 * FIXME: Get rid of this when all methods can be llvm compiled.
7068 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7069 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7070 for (l = callers; l; l = l->next) {
7071 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7072 l2 = g_slist_prepend (l2, l->data);
7073 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7078 if (cfg->verbose_level > 1)
7079 mono_llvm_dump_value (method);
7081 if (cfg->compile_aot && !cfg->llvm_only)
7082 mark_as_used (ctx->module, method);
7084 if (cfg->compile_aot && !cfg->llvm_only) {
7085 LLVMValueRef md_args [16];
7086 LLVMValueRef md_node;
7089 method_index = mono_aot_get_method_index (cfg->orig_method);
7090 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7091 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7092 md_node = LLVMMDNode (md_args, 2);
7093 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7094 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7097 if (cfg->compile_aot) {
7098 /* Don't generate native code, keep the LLVM IR */
7099 if (cfg->verbose_level)
7100 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7102 #if LLVM_API_VERSION < 100
7103 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7104 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7105 g_assert (err == 0);
7108 //LLVMVerifyFunction(method, 0);
7109 #if LLVM_API_VERSION > 100
7110 MonoDomain *domain = mono_domain_get ();
7111 MonoJitDomainInfo *domain_info;
7112 int nvars = g_hash_table_size (ctx->jit_callees);
7113 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7114 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7115 GHashTableIter iter;
7121 * Compute the addresses of the LLVM globals pointing to the
7122 * methods called by the current method. Pass it to the trampoline
7123 * code so it can update them after their corresponding method was
7126 g_hash_table_iter_init (&iter, ctx->jit_callees);
7128 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7129 callee_vars [i ++] = var;
7131 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7133 decode_llvm_eh_info (ctx, eh_frame);
7135 mono_domain_lock (domain);
7136 domain_info = domain_jit_info (domain);
7137 if (!domain_info->llvm_jit_callees)
7138 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7139 g_hash_table_iter_init (&iter, ctx->jit_callees);
7141 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7142 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7143 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7144 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7147 mono_domain_unlock (domain);
7149 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7151 if (cfg->verbose_level > 1)
7152 mono_llvm_dump_value (ctx->lmethod);
7154 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7156 /* Set by emit_cb */
7157 g_assert (cfg->code_len);
7161 if (ctx->module->method_to_lmethod)
7162 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7163 if (ctx->module->idx_to_lmethod)
7164 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7166 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7167 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7171 * mono_llvm_create_vars:
7173 * Same as mono_arch_create_vars () for LLVM.
7176 mono_llvm_create_vars (MonoCompile *cfg)
7178 MonoMethodSignature *sig;
7180 sig = mono_method_signature (cfg->method);
7181 if (cfg->gsharedvt && cfg->llvm_only) {
7182 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7183 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7184 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7185 printf ("vret_addr = ");
7186 mono_print_ins (cfg->vret_addr);
7190 mono_arch_create_vars (cfg);
7195 * mono_llvm_emit_call:
7197 * Same as mono_arch_emit_call () for LLVM.
7200 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7203 MonoMethodSignature *sig;
7204 int i, n, stack_size;
7209 sig = call->signature;
7210 n = sig->param_count + sig->hasthis;
7212 call->cinfo = get_llvm_call_info (cfg, sig);
7214 if (cfg->disable_llvm)
7217 if (sig->call_convention == MONO_CALL_VARARG) {
7218 cfg->exception_message = g_strdup ("varargs");
7219 cfg->disable_llvm = TRUE;
7222 for (i = 0; i < n; ++i) {
7225 ainfo = call->cinfo->args + i;
7227 in = call->args [i];
7229 /* Simply remember the arguments */
7230 switch (ainfo->storage) {
7231 case LLVMArgNormal: {
7232 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7235 opcode = mono_type_to_regmove (cfg, t);
7236 if (opcode == OP_FMOVE) {
7237 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7238 ins->dreg = mono_alloc_freg (cfg);
7239 } else if (opcode == OP_LMOVE) {
7240 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7241 ins->dreg = mono_alloc_lreg (cfg);
7242 } else if (opcode == OP_RMOVE) {
7243 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7244 ins->dreg = mono_alloc_freg (cfg);
7246 MONO_INST_NEW (cfg, ins, OP_MOVE);
7247 ins->dreg = mono_alloc_ireg (cfg);
7249 ins->sreg1 = in->dreg;
7252 case LLVMArgVtypeByVal:
7253 case LLVMArgVtypeByRef:
7254 case LLVMArgVtypeInReg:
7255 case LLVMArgVtypeAsScalar:
7256 case LLVMArgAsIArgs:
7257 case LLVMArgAsFpArgs:
7258 case LLVMArgGsharedvtVariable:
7259 case LLVMArgGsharedvtFixed:
7260 case LLVMArgGsharedvtFixedVtype:
7261 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7262 ins->dreg = mono_alloc_ireg (cfg);
7263 ins->sreg1 = in->dreg;
7264 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7265 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7266 ins->inst_vtype = ainfo->type;
7267 ins->klass = mono_class_from_mono_type (ainfo->type);
7270 cfg->exception_message = g_strdup ("ainfo->storage");
7271 cfg->disable_llvm = TRUE;
7275 if (!cfg->disable_llvm) {
7276 MONO_ADD_INS (cfg->cbb, ins);
7277 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7282 static unsigned char*
7283 alloc_cb (LLVMValueRef function, int size)
7287 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7291 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7293 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7298 emitted_cb (LLVMValueRef function, void *start, void *end)
7302 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7304 cfg->code_len = (guint8*)end - (guint8*)start;
7308 exception_cb (void *data)
7311 MonoJitExceptionInfo *ei;
7312 guint32 ei_len, i, j, nested_len, nindex;
7313 gpointer *type_info;
7314 int this_reg, this_offset;
7316 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7320 * data points to a DWARF FDE structure, convert it to our unwind format and
7322 * An alternative would be to save it directly, and modify our unwinder to work
7325 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);
7326 if (cfg->verbose_level > 1)
7327 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7329 /* Count nested clauses */
7331 for (i = 0; i < ei_len; ++i) {
7332 gint32 cindex1 = *(gint32*)type_info [i];
7333 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7335 for (j = 0; j < cfg->header->num_clauses; ++j) {
7337 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7339 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7345 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7346 cfg->llvm_ex_info_len = ei_len + nested_len;
7347 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7348 /* Fill the rest of the information from the type info */
7349 for (i = 0; i < ei_len; ++i) {
7350 gint32 clause_index = *(gint32*)type_info [i];
7351 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7353 cfg->llvm_ex_info [i].flags = clause->flags;
7354 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7355 cfg->llvm_ex_info [i].clause_index = clause_index;
7359 * For nested clauses, the LLVM produced exception info associates the try interval with
7360 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7361 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7362 * and everything else from the nested clause.
7365 for (i = 0; i < ei_len; ++i) {
7366 gint32 cindex1 = *(gint32*)type_info [i];
7367 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7369 for (j = 0; j < cfg->header->num_clauses; ++j) {
7371 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7372 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7374 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7375 /* clause1 is the nested clause */
7376 nested_ei = &cfg->llvm_ex_info [i];
7377 nesting_ei = &cfg->llvm_ex_info [nindex];
7380 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7382 nesting_ei->flags = clause2->flags;
7383 nesting_ei->data.catch_class = clause2->data.catch_class;
7384 nesting_ei->clause_index = cindex2;
7388 g_assert (nindex == ei_len + nested_len);
7389 cfg->llvm_this_reg = this_reg;
7390 cfg->llvm_this_offset = this_offset;
7392 /* type_info [i] is cfg mempool allocated, no need to free it */
7398 #if LLVM_API_VERSION > 100
7400 * decode_llvm_eh_info:
7402 * Decode the EH table emitted by llvm in jit mode, and store
7403 * the result into cfg.
7406 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7408 MonoCompile *cfg = ctx->cfg;
7411 MonoLLVMFDEInfo info;
7412 MonoJitExceptionInfo *ei;
7413 guint8 *p = eh_frame;
7414 int version, fde_count, fde_offset;
7415 guint32 ei_len, i, nested_len;
7416 gpointer *type_info;
7420 * Decode the one element EH table emitted by the MonoException class
7424 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7427 g_assert (version == 3);
7430 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7432 fde_count = *(guint32*)p;
7436 g_assert (fde_count == 1);
7438 /* The only table entry */
7439 fde_offset = table [1];
7442 cfg->code_len = table [0];
7443 fde_len = table [1] - fde_offset;
7446 fde = (guint8*)eh_frame + fde_offset;
7447 cie = (guint8*)table;
7449 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7451 cfg->encoded_unwind_ops = info.unw_info;
7452 cfg->encoded_unwind_ops_len = info.unw_info_len;
7453 if (cfg->verbose_level > 1)
7454 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7455 if (info.this_reg != -1) {
7456 cfg->llvm_this_reg = info.this_reg;
7457 cfg->llvm_this_offset = info.this_offset;
7461 ei_len = info.ex_info_len;
7462 type_info = info.type_info;
7464 // Nested clauses are currently disabled
7467 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7468 cfg->llvm_ex_info_len = ei_len + nested_len;
7469 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7470 /* Fill the rest of the information from the type info */
7471 for (i = 0; i < ei_len; ++i) {
7472 gint32 clause_index = *(gint32*)type_info [i];
7473 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7475 cfg->llvm_ex_info [i].flags = clause->flags;
7476 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7477 cfg->llvm_ex_info [i].clause_index = clause_index;
7483 dlsym_cb (const char *name, void **symbol)
7489 if (!strcmp (name, "__bzero")) {
7490 *symbol = (void*)bzero;
7492 current = mono_dl_open (NULL, 0, NULL);
7495 err = mono_dl_symbol (current, name, symbol);
7497 mono_dl_close (current);
7499 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7500 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7506 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7508 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7512 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7514 LLVMTypeRef param_types [4];
7516 param_types [0] = param_type1;
7517 param_types [1] = param_type2;
7519 AddFunc (module, name, ret_type, param_types, 2);
7525 INTRINS_SADD_OVF_I32,
7526 INTRINS_UADD_OVF_I32,
7527 INTRINS_SSUB_OVF_I32,
7528 INTRINS_USUB_OVF_I32,
7529 INTRINS_SMUL_OVF_I32,
7530 INTRINS_UMUL_OVF_I32,
7531 INTRINS_SADD_OVF_I64,
7532 INTRINS_UADD_OVF_I64,
7533 INTRINS_SSUB_OVF_I64,
7534 INTRINS_USUB_OVF_I64,
7535 INTRINS_SMUL_OVF_I64,
7536 INTRINS_UMUL_OVF_I64,
7543 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7544 INTRINS_SSE_PMOVMSKB,
7545 INTRINS_SSE_PSRLI_W,
7546 INTRINS_SSE_PSRAI_W,
7547 INTRINS_SSE_PSLLI_W,
7548 INTRINS_SSE_PSRLI_D,
7549 INTRINS_SSE_PSRAI_D,
7550 INTRINS_SSE_PSLLI_D,
7551 INTRINS_SSE_PSRLI_Q,
7552 INTRINS_SSE_PSLLI_Q,
7553 INTRINS_SSE_SQRT_PD,
7554 INTRINS_SSE_SQRT_PS,
7555 INTRINS_SSE_RSQRT_PS,
7557 INTRINS_SSE_CVTTPD2DQ,
7558 INTRINS_SSE_CVTTPS2DQ,
7559 INTRINS_SSE_CVTDQ2PD,
7560 INTRINS_SSE_CVTDQ2PS,
7561 INTRINS_SSE_CVTPD2DQ,
7562 INTRINS_SSE_CVTPS2DQ,
7563 INTRINS_SSE_CVTPD2PS,
7564 INTRINS_SSE_CVTPS2PD,
7567 INTRINS_SSE_PACKSSWB,
7568 INTRINS_SSE_PACKUSWB,
7569 INTRINS_SSE_PACKSSDW,
7570 INTRINS_SSE_PACKUSDW,
7575 INTRINS_SSE_ADDSUBPS,
7580 INTRINS_SSE_ADDSUBPD,
7588 INTRINS_SSE_PADDUSW,
7589 INTRINS_SSE_PSUBUSW,
7597 INTRINS_SSE_PADDUSB,
7598 INTRINS_SSE_PSUBUSB,
7610 static IntrinsicDesc intrinsics[] = {
7611 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7612 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7613 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7614 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7615 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7616 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7617 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7618 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7619 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7620 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7621 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7622 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7623 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7624 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7625 {INTRINS_SIN, "llvm.sin.f64"},
7626 {INTRINS_COS, "llvm.cos.f64"},
7627 {INTRINS_SQRT, "llvm.sqrt.f64"},
7628 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7629 {INTRINS_FABS, "fabs"},
7630 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7631 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7632 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7633 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7634 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7635 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7636 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7637 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7638 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7639 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7640 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7641 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7642 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7643 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7644 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7645 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7646 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7647 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7648 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7649 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7650 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7651 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7652 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7653 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7654 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7655 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7656 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7657 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7658 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7659 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7660 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7661 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7662 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7663 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7664 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7665 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7666 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7667 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7668 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7669 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7670 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7671 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7672 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7673 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7674 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7675 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7676 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7677 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7678 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7679 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7680 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7681 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7682 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7683 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7684 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7685 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7686 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7687 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7688 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7689 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7694 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7696 LLVMTypeRef ret_type = type_to_simd_type (type);
7697 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7701 add_intrinsic (LLVMModuleRef module, int id)
7704 LLVMTypeRef ret_type, arg_types [16];
7706 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7710 case INTRINS_MEMSET: {
7711 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7713 AddFunc (module, name, LLVMVoidType (), params, 5);
7716 case INTRINS_MEMCPY: {
7717 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7719 AddFunc (module, name, LLVMVoidType (), params, 5);
7722 case INTRINS_SADD_OVF_I32:
7723 case INTRINS_UADD_OVF_I32:
7724 case INTRINS_SSUB_OVF_I32:
7725 case INTRINS_USUB_OVF_I32:
7726 case INTRINS_SMUL_OVF_I32:
7727 case INTRINS_UMUL_OVF_I32: {
7728 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7729 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7730 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7732 AddFunc (module, name, ret_type, params, 2);
7735 case INTRINS_SADD_OVF_I64:
7736 case INTRINS_UADD_OVF_I64:
7737 case INTRINS_SSUB_OVF_I64:
7738 case INTRINS_USUB_OVF_I64:
7739 case INTRINS_SMUL_OVF_I64:
7740 case INTRINS_UMUL_OVF_I64: {
7741 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7742 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7743 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7745 AddFunc (module, name, ret_type, params, 2);
7751 case INTRINS_FABS: {
7752 LLVMTypeRef params [] = { LLVMDoubleType () };
7754 AddFunc (module, name, LLVMDoubleType (), params, 1);
7757 case INTRINS_EXPECT_I8:
7758 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7760 case INTRINS_EXPECT_I1:
7761 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7763 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7764 case INTRINS_SSE_PMOVMSKB:
7766 ret_type = LLVMInt32Type ();
7767 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7768 AddFunc (module, name, ret_type, arg_types, 1);
7770 case INTRINS_SSE_PSRLI_W:
7771 case INTRINS_SSE_PSRAI_W:
7772 case INTRINS_SSE_PSLLI_W:
7774 ret_type = type_to_simd_type (MONO_TYPE_I2);
7775 arg_types [0] = ret_type;
7776 arg_types [1] = LLVMInt32Type ();
7777 AddFunc (module, name, ret_type, arg_types, 2);
7779 case INTRINS_SSE_PSRLI_D:
7780 case INTRINS_SSE_PSRAI_D:
7781 case INTRINS_SSE_PSLLI_D:
7782 ret_type = type_to_simd_type (MONO_TYPE_I4);
7783 arg_types [0] = ret_type;
7784 arg_types [1] = LLVMInt32Type ();
7785 AddFunc (module, name, ret_type, arg_types, 2);
7787 case INTRINS_SSE_PSRLI_Q:
7788 case INTRINS_SSE_PSLLI_Q:
7789 ret_type = type_to_simd_type (MONO_TYPE_I8);
7790 arg_types [0] = ret_type;
7791 arg_types [1] = LLVMInt32Type ();
7792 AddFunc (module, name, ret_type, arg_types, 2);
7794 case INTRINS_SSE_SQRT_PD:
7796 ret_type = type_to_simd_type (MONO_TYPE_R8);
7797 arg_types [0] = ret_type;
7798 AddFunc (module, name, ret_type, arg_types, 1);
7800 case INTRINS_SSE_SQRT_PS:
7801 ret_type = type_to_simd_type (MONO_TYPE_R4);
7802 arg_types [0] = ret_type;
7803 AddFunc (module, name, ret_type, arg_types, 1);
7805 case INTRINS_SSE_RSQRT_PS:
7806 ret_type = type_to_simd_type (MONO_TYPE_R4);
7807 arg_types [0] = ret_type;
7808 AddFunc (module, name, ret_type, arg_types, 1);
7810 case INTRINS_SSE_RCP_PS:
7811 ret_type = type_to_simd_type (MONO_TYPE_R4);
7812 arg_types [0] = ret_type;
7813 AddFunc (module, name, ret_type, arg_types, 1);
7815 case INTRINS_SSE_CVTTPD2DQ:
7816 ret_type = type_to_simd_type (MONO_TYPE_I4);
7817 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7818 AddFunc (module, name, ret_type, arg_types, 1);
7820 case INTRINS_SSE_CVTTPS2DQ:
7821 ret_type = type_to_simd_type (MONO_TYPE_I4);
7822 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7823 AddFunc (module, name, ret_type, arg_types, 1);
7825 case INTRINS_SSE_CVTDQ2PD:
7826 /* Conversion ops */
7827 ret_type = type_to_simd_type (MONO_TYPE_R8);
7828 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7829 AddFunc (module, name, ret_type, arg_types, 1);
7831 case INTRINS_SSE_CVTDQ2PS:
7832 ret_type = type_to_simd_type (MONO_TYPE_R4);
7833 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7834 AddFunc (module, name, ret_type, arg_types, 1);
7836 case INTRINS_SSE_CVTPD2DQ:
7837 ret_type = type_to_simd_type (MONO_TYPE_I4);
7838 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7839 AddFunc (module, name, ret_type, arg_types, 1);
7841 case INTRINS_SSE_CVTPS2DQ:
7842 ret_type = type_to_simd_type (MONO_TYPE_I4);
7843 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7844 AddFunc (module, name, ret_type, arg_types, 1);
7846 case INTRINS_SSE_CVTPD2PS:
7847 ret_type = type_to_simd_type (MONO_TYPE_R4);
7848 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7849 AddFunc (module, name, ret_type, arg_types, 1);
7851 case INTRINS_SSE_CVTPS2PD:
7852 ret_type = type_to_simd_type (MONO_TYPE_R8);
7853 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7854 AddFunc (module, name, ret_type, arg_types, 1);
7856 case INTRINS_SSE_CMPPD:
7858 ret_type = type_to_simd_type (MONO_TYPE_R8);
7859 arg_types [0] = ret_type;
7860 arg_types [1] = ret_type;
7861 arg_types [2] = LLVMInt8Type ();
7862 AddFunc (module, name, ret_type, arg_types, 3);
7864 case INTRINS_SSE_CMPPS:
7865 ret_type = type_to_simd_type (MONO_TYPE_R4);
7866 arg_types [0] = ret_type;
7867 arg_types [1] = ret_type;
7868 arg_types [2] = LLVMInt8Type ();
7869 AddFunc (module, name, ret_type, arg_types, 3);
7871 case INTRINS_SSE_PACKSSWB:
7872 case INTRINS_SSE_PACKUSWB:
7873 case INTRINS_SSE_PACKSSDW:
7875 ret_type = type_to_simd_type (MONO_TYPE_I1);
7876 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7877 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7878 AddFunc (module, name, ret_type, arg_types, 2);
7880 case INTRINS_SSE_PACKUSDW:
7881 ret_type = type_to_simd_type (MONO_TYPE_I2);
7882 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7883 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7884 AddFunc (module, name, ret_type, arg_types, 2);
7886 /* SSE Binary ops */
7887 case INTRINS_SSE_PMINUD:
7888 case INTRINS_SSE_PMAXUD:
7889 add_sse_binary (module, name, MONO_TYPE_I4);
7891 case INTRINS_SSE_PMINUW:
7892 case INTRINS_SSE_PMINSW:
7893 case INTRINS_SSE_PMAXUW:
7894 case INTRINS_SSE_PADDSW:
7895 case INTRINS_SSE_PSUBSW:
7896 case INTRINS_SSE_PADDUSW:
7897 case INTRINS_SSE_PSUBUSW:
7898 case INTRINS_SSE_PAVGW:
7899 case INTRINS_SSE_PMULHW:
7900 case INTRINS_SSE_PMULHU:
7901 add_sse_binary (module, name, MONO_TYPE_I2);
7903 case INTRINS_SSE_MINPS:
7904 case INTRINS_SSE_MAXPS:
7905 case INTRINS_SSE_HADDPS:
7906 case INTRINS_SSE_HSUBPS:
7907 case INTRINS_SSE_ADDSUBPS:
7908 add_sse_binary (module, name, MONO_TYPE_R4);
7910 case INTRINS_SSE_MINPD:
7911 case INTRINS_SSE_MAXPD:
7912 case INTRINS_SSE_HADDPD:
7913 case INTRINS_SSE_HSUBPD:
7914 case INTRINS_SSE_ADDSUBPD:
7915 add_sse_binary (module, name, MONO_TYPE_R8);
7917 case INTRINS_SSE_PMINUB:
7918 case INTRINS_SSE_PMAXUB:
7919 case INTRINS_SE_PADDSB:
7920 case INTRINS_SSE_PSUBSB:
7921 case INTRINS_SSE_PADDUSB:
7922 case INTRINS_SSE_PSUBUSB:
7923 case INTRINS_SSE_PAVGB:
7924 add_sse_binary (module, name, MONO_TYPE_I1);
7926 case INTRINS_SSE_PAUSE:
7927 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7931 g_assert_not_reached ();
7937 get_intrinsic (EmitContext *ctx, const char *name)
7939 #if LLVM_API_VERSION > 100
7943 * Every method is emitted into its own module so
7944 * we can add intrinsics on demand.
7946 res = LLVMGetNamedFunction (ctx->lmodule, name);
7950 /* No locking needed */
7951 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
7954 printf ("%s\n", name);
7955 g_assert (id != -1);
7956 add_intrinsic (ctx->lmodule, id);
7957 res = LLVMGetNamedFunction (ctx->lmodule, name);
7965 res = LLVMGetNamedFunction (ctx->lmodule, name);
7972 add_intrinsics (LLVMModuleRef module)
7976 /* Emit declarations of instrinsics */
7978 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7979 * type doesn't seem to do any locking.
7981 for (i = 0; i < INTRINS_NUM; ++i)
7982 add_intrinsic (module, i);
7986 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7988 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7991 /* SSE intrinsics */
7992 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7996 /* Load/Store intrinsics */
7998 LLVMTypeRef arg_types [5];
8002 for (i = 1; i <= 8; i *= 2) {
8003 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8004 arg_types [1] = LLVMInt32Type ();
8005 arg_types [2] = LLVMInt1Type ();
8006 arg_types [3] = LLVMInt32Type ();
8007 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8008 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8010 arg_types [0] = LLVMIntType (i * 8);
8011 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8012 arg_types [2] = LLVMInt32Type ();
8013 arg_types [3] = LLVMInt1Type ();
8014 arg_types [4] = LLVMInt32Type ();
8015 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8016 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8022 add_types (MonoLLVMModule *module)
8024 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8028 mono_llvm_init (void)
8033 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8035 h = g_hash_table_new (NULL, NULL);
8036 for (i = 0; i < INTRINS_NUM; ++i)
8037 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8038 intrins_id_to_name = h;
8040 h = g_hash_table_new (g_str_hash, g_str_equal);
8041 for (i = 0; i < INTRINS_NUM; ++i)
8042 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8043 intrins_name_to_id = h;
8047 init_jit_module (MonoDomain *domain)
8049 MonoJitDomainInfo *dinfo;
8050 MonoLLVMModule *module;
8053 dinfo = domain_jit_info (domain);
8054 if (dinfo->llvm_module)
8057 mono_loader_lock ();
8059 if (dinfo->llvm_module) {
8060 mono_loader_unlock ();
8064 module = g_new0 (MonoLLVMModule, 1);
8066 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8067 module->lmodule = LLVMModuleCreateWithName (name);
8068 module->context = LLVMGetGlobalContext ();
8070 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8072 add_intrinsics (module->lmodule);
8075 module->llvm_types = g_hash_table_new (NULL, NULL);
8077 #if LLVM_API_VERSION < 100
8078 MonoJitICallInfo *info;
8080 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8082 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8085 mono_memory_barrier ();
8087 dinfo->llvm_module = module;
8089 mono_loader_unlock ();
8093 mono_llvm_cleanup (void)
8095 MonoLLVMModule *module = &aot_module;
8097 if (module->lmodule)
8098 LLVMDisposeModule (module->lmodule);
8100 if (module->context)
8101 LLVMContextDispose (module->context);
8105 mono_llvm_free_domain_info (MonoDomain *domain)
8107 MonoJitDomainInfo *info = domain_jit_info (domain);
8108 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8114 if (module->llvm_types)
8115 g_hash_table_destroy (module->llvm_types);
8117 mono_llvm_dispose_ee (module->mono_ee);
8119 if (module->bb_names) {
8120 for (i = 0; i < module->bb_names_len; ++i)
8121 g_free (module->bb_names [i]);
8122 g_free (module->bb_names);
8124 //LLVMDisposeModule (module->module);
8128 info->llvm_module = NULL;
8132 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8134 MonoLLVMModule *module = &aot_module;
8136 /* Delete previous module */
8137 if (module->plt_entries)
8138 g_hash_table_destroy (module->plt_entries);
8139 if (module->lmodule)
8140 LLVMDisposeModule (module->lmodule);
8142 memset (module, 0, sizeof (aot_module));
8144 module->lmodule = LLVMModuleCreateWithName ("aot");
8145 module->assembly = assembly;
8146 module->global_prefix = g_strdup (global_prefix);
8147 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8148 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8149 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8150 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8151 module->external_symbols = TRUE;
8152 module->emit_dwarf = emit_dwarf;
8153 module->static_link = static_link;
8154 module->llvm_only = llvm_only;
8155 /* The first few entries are reserved */
8156 module->max_got_offset = 16;
8157 module->context = LLVMContextCreate ();
8160 /* clang ignores our debug info because it has an invalid version */
8161 module->emit_dwarf = FALSE;
8163 #if LLVM_API_VERSION > 100
8164 module->emit_dwarf = FALSE;
8167 add_intrinsics (module->lmodule);
8170 #if LLVM_API_VERSION > 100
8171 if (module->emit_dwarf) {
8172 char *dir, *build_info, *s, *cu_name;
8174 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8177 dir = g_strdup (".");
8178 build_info = mono_get_runtime_build_info ();
8179 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8180 cu_name = g_path_get_basename (assembly->image->name);
8181 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8183 g_free (build_info);
8190 * We couldn't compute the type of the LLVM global representing the got because
8191 * its size is only known after all the methods have been emitted. So create
8192 * a dummy variable, and replace all uses it with the real got variable when
8193 * its size is known in mono_llvm_emit_aot_module ().
8196 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8198 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8199 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8202 /* Add initialization array */
8204 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8206 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8207 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8211 emit_init_icall_wrappers (module);
8213 emit_llvm_code_start (module);
8215 /* Add a dummy personality function */
8216 if (!use_debug_personality) {
8217 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8218 LLVMSetLinkage (personality, LLVMExternalLinkage);
8219 mark_as_used (module, personality);
8222 /* Add a reference to the c++ exception we throw/catch */
8224 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8225 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8226 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8227 mono_llvm_set_is_constant (module->sentinel_exception);
8230 module->llvm_types = g_hash_table_new (NULL, NULL);
8231 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8232 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8233 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8234 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8235 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8236 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8237 module->method_to_callers = g_hash_table_new (NULL, NULL);
8241 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8244 LLVMValueRef res, *vals;
8246 vals = g_new0 (LLVMValueRef, nvalues);
8247 for (i = 0; i < nvalues; ++i)
8248 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8249 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8255 * mono_llvm_emit_aot_file_info:
8257 * Emit the MonoAotFileInfo structure.
8258 * Same as emit_aot_file_info () in aot-compiler.c.
8261 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8263 MonoLLVMModule *module = &aot_module;
8265 /* Save these for later */
8266 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8267 module->has_jitted_code = has_jitted_code;
8271 * mono_llvm_emit_aot_data:
8273 * Emit the binary data DATA pointed to by symbol SYMBOL.
8276 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8278 MonoLLVMModule *module = &aot_module;
8282 type = LLVMArrayType (LLVMInt8Type (), data_len);
8283 d = LLVMAddGlobal (module->lmodule, type, symbol);
8284 LLVMSetVisibility (d, LLVMHiddenVisibility);
8285 LLVMSetLinkage (d, LLVMInternalLinkage);
8286 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8287 mono_llvm_set_is_constant (d);
8290 /* Add a reference to a global defined in JITted code */
8292 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8297 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8298 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8304 emit_aot_file_info (MonoLLVMModule *module)
8306 LLVMTypeRef file_info_type;
8307 LLVMTypeRef *eltypes, eltype;
8308 LLVMValueRef info_var;
8309 LLVMValueRef *fields;
8310 int i, nfields, tindex;
8311 MonoAotFileInfo *info;
8312 LLVMModuleRef lmodule = module->lmodule;
8314 info = &module->aot_info;
8316 /* Create an LLVM type to represent MonoAotFileInfo */
8317 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8318 eltypes = g_new (LLVMTypeRef, nfields);
8320 eltypes [tindex ++] = LLVMInt32Type ();
8321 eltypes [tindex ++] = LLVMInt32Type ();
8323 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8324 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8326 for (i = 0; i < 15; ++i)
8327 eltypes [tindex ++] = LLVMInt32Type ();
8329 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8330 for (i = 0; i < 4; ++i)
8331 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8332 g_assert (tindex == nfields);
8333 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8334 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8336 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8337 if (module->static_link) {
8338 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8339 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8341 fields = g_new (LLVMValueRef, nfields);
8343 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8344 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8348 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8349 * for symbols defined in the .s file emitted by the aot compiler.
8351 eltype = eltypes [tindex];
8352 if (module->llvm_only)
8353 fields [tindex ++] = LLVMConstNull (eltype);
8355 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8356 fields [tindex ++] = module->got_var;
8357 /* llc defines this directly */
8358 if (!module->llvm_only) {
8359 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8360 fields [tindex ++] = LLVMConstNull (eltype);
8361 fields [tindex ++] = LLVMConstNull (eltype);
8363 fields [tindex ++] = LLVMConstNull (eltype);
8364 fields [tindex ++] = module->get_method;
8365 fields [tindex ++] = module->get_unbox_tramp;
8367 if (module->has_jitted_code) {
8368 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8369 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8371 fields [tindex ++] = LLVMConstNull (eltype);
8372 fields [tindex ++] = LLVMConstNull (eltype);
8374 if (!module->llvm_only)
8375 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8377 fields [tindex ++] = LLVMConstNull (eltype);
8378 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8379 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8380 fields [tindex ++] = LLVMConstNull (eltype);
8382 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8383 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8384 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8385 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8386 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8387 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8388 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8389 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8390 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8391 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8393 /* Not needed (mem_end) */
8394 fields [tindex ++] = LLVMConstNull (eltype);
8395 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8396 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8397 if (info->trampoline_size [0]) {
8398 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8399 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8400 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8401 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8403 fields [tindex ++] = LLVMConstNull (eltype);
8404 fields [tindex ++] = LLVMConstNull (eltype);
8405 fields [tindex ++] = LLVMConstNull (eltype);
8406 fields [tindex ++] = LLVMConstNull (eltype);
8408 if (module->static_link && !module->llvm_only)
8409 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8411 fields [tindex ++] = LLVMConstNull (eltype);
8412 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8413 if (!module->llvm_only) {
8414 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8415 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8416 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8417 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8418 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8419 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8421 fields [tindex ++] = LLVMConstNull (eltype);
8422 fields [tindex ++] = LLVMConstNull (eltype);
8423 fields [tindex ++] = LLVMConstNull (eltype);
8424 fields [tindex ++] = LLVMConstNull (eltype);
8425 fields [tindex ++] = LLVMConstNull (eltype);
8426 fields [tindex ++] = LLVMConstNull (eltype);
8429 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8430 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8433 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8434 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8435 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8436 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8437 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8438 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8439 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8440 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8441 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8442 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8443 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8444 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8445 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8446 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8447 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8449 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8450 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8451 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8452 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8453 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8454 g_assert (tindex == nfields);
8456 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8458 if (module->static_link) {
8462 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8463 /* Get rid of characters which cannot occur in symbols */
8465 for (p = s; *p; ++p) {
8466 if (!(isalnum (*p) || *p == '_'))
8469 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8471 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8472 LLVMSetLinkage (var, LLVMExternalLinkage);
8477 * Emit the aot module into the LLVM bitcode file FILENAME.
8480 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8482 LLVMTypeRef got_type, inited_type;
8483 LLVMValueRef real_got, real_inited;
8484 MonoLLVMModule *module = &aot_module;
8486 emit_llvm_code_end (module);
8489 * Create the real got variable and replace all uses of the dummy variable with
8492 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8493 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8494 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8495 if (module->external_symbols) {
8496 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8497 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8499 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8501 mono_llvm_replace_uses_of (module->got_var, real_got);
8503 mark_as_used (&aot_module, real_got);
8505 /* Delete the dummy got so it doesn't become a global */
8506 LLVMDeleteGlobal (module->got_var);
8507 module->got_var = real_got;
8510 * Same for the init_var
8512 if (module->llvm_only) {
8513 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8514 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8515 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8516 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8517 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8518 LLVMDeleteGlobal (module->inited_var);
8521 if (module->llvm_only) {
8522 emit_get_method (&aot_module);
8523 emit_get_unbox_tramp (&aot_module);
8526 emit_llvm_used (&aot_module);
8527 emit_dbg_info (&aot_module, filename, cu_name);
8528 emit_aot_file_info (&aot_module);
8531 * Replace GOT entries for directly callable methods with the methods themselves.
8532 * It would be easier to implement this by predefining all methods before compiling
8533 * their bodies, but that couldn't handle the case when a method fails to compile
8536 if (module->llvm_only) {
8537 GHashTableIter iter;
8539 GSList *callers, *l;
8541 g_hash_table_iter_init (&iter, module->method_to_callers);
8542 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8543 LLVMValueRef lmethod;
8545 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8547 for (l = callers; l; l = l->next) {
8548 LLVMValueRef caller = (LLVMValueRef)l->data;
8550 mono_llvm_replace_uses_of (caller, lmethod);
8556 /* Replace PLT entries for directly callable methods with the methods themselves */
8558 GHashTableIter iter;
8560 LLVMValueRef callee;
8562 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8563 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8564 if (mono_aot_is_direct_callable (ji)) {
8565 LLVMValueRef lmethod;
8567 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8568 /* The types might not match because the caller might pass an rgctx */
8569 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8570 mono_llvm_replace_uses_of (callee, lmethod);
8571 mono_aot_mark_unused_llvm_plt_entry (ji);
8581 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8582 g_assert_not_reached ();
8587 LLVMWriteBitcodeToFile (module->lmodule, filename);
8592 md_string (const char *s)
8594 return LLVMMDString (s, strlen (s));
8597 /* Debugging support */
8600 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8602 LLVMModuleRef lmodule = module->lmodule;
8603 LLVMValueRef args [16], ver;
8606 * This can only be enabled when LLVM code is emitted into a separate object
8607 * file, since the AOT compiler also emits dwarf info,
8608 * and the abbrev indexes will not be correct since llvm has added its own
8611 if (!module->emit_dwarf)
8614 #if LLVM_API_VERSION > 100
8615 mono_llvm_di_builder_finalize (module->di_builder);
8617 LLVMValueRef cu_args [16], cu;
8619 char *build_info, *s, *dir;
8622 * Emit dwarf info in the form of LLVM metadata. There is some
8623 * out-of-date documentation at:
8624 * http://llvm.org/docs/SourceLevelDebugging.html
8625 * but most of this was gathered from the llvm and
8630 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8631 /* CU name/compilation dir */
8632 dir = g_path_get_dirname (filename);
8633 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8634 args [1] = LLVMMDString (dir, strlen (dir));
8635 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8638 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8640 build_info = mono_get_runtime_build_info ();
8641 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8642 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8643 g_free (build_info);
8645 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8647 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8648 /* Runtime version */
8649 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8651 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8652 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8654 if (module->subprogram_mds) {
8658 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8659 for (i = 0; i < module->subprogram_mds->len; ++i)
8660 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8661 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8663 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8666 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8667 /* Imported modules */
8668 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8670 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8671 /* DebugEmissionKind = FullDebug */
8672 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8673 cu = LLVMMDNode (cu_args, n_cuargs);
8674 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8677 #if LLVM_API_VERSION > 100
8678 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8679 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8680 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8681 ver = LLVMMDNode (args, 3);
8682 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8684 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8685 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8686 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8687 ver = LLVMMDNode (args, 3);
8688 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8690 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8691 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8692 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8693 ver = LLVMMDNode (args, 3);
8694 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8696 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8697 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8698 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8699 ver = LLVMMDNode (args, 3);
8700 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8705 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8707 MonoLLVMModule *module = ctx->module;
8708 MonoDebugMethodInfo *minfo = ctx->minfo;
8709 char *source_file, *dir, *filename;
8710 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8711 MonoSymSeqPoint *sym_seq_points;
8717 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8719 source_file = g_strdup ("<unknown>");
8720 dir = g_path_get_dirname (source_file);
8721 filename = g_path_get_basename (source_file);
8723 #if LLVM_API_VERSION > 100
8724 return mono_llvm_di_create_function (module->di_builder, module->cu, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
8727 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8728 args [0] = md_string (filename);
8729 args [1] = md_string (dir);
8730 ctx_args [1] = LLVMMDNode (args, 2);
8731 ctx_md = LLVMMDNode (ctx_args, 2);
8733 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8734 type_args [1] = NULL;
8735 type_args [2] = NULL;
8736 type_args [3] = LLVMMDString ("", 0);
8737 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8738 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8739 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8740 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8741 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8742 type_args [9] = NULL;
8743 type_args [10] = NULL;
8744 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8745 type_args [12] = NULL;
8746 type_args [13] = NULL;
8747 type_args [14] = NULL;
8748 type_md = LLVMMDNode (type_args, 14);
8750 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8751 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8752 /* Source directory + file pair */
8753 args [0] = md_string (filename);
8754 args [1] = md_string (dir);
8755 md_args [1] = LLVMMDNode (args ,2);
8756 md_args [2] = ctx_md;
8757 md_args [3] = md_string (cfg->method->name);
8758 md_args [4] = md_string (name);
8759 md_args [5] = md_string (name);
8762 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8764 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8766 md_args [7] = type_md;
8768 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8770 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8772 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8773 /* Index into a virtual function */
8774 md_args [11] = NULL;
8775 md_args [12] = NULL;
8777 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8779 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8780 /* Pointer to LLVM function */
8781 md_args [15] = method;
8782 /* Function template parameter */
8783 md_args [16] = NULL;
8784 /* Function declaration descriptor */
8785 md_args [17] = NULL;
8786 /* List of function variables */
8787 md_args [18] = LLVMMDNode (args, 0);
8789 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8790 md = LLVMMDNode (md_args, 20);
8792 if (!module->subprogram_mds)
8793 module->subprogram_mds = g_ptr_array_new ();
8794 g_ptr_array_add (module->subprogram_mds, md);
8798 g_free (source_file);
8799 g_free (sym_seq_points);
8805 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8807 MonoCompile *cfg = ctx->cfg;
8809 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8810 MonoDebugSourceLocation *loc;
8811 LLVMValueRef loc_md;
8813 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8816 #if LLVM_API_VERSION > 100
8817 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8818 mono_llvm_di_set_location (builder, loc_md);
8820 LLVMValueRef md_args [16];
8824 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8825 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8826 md_args [nmd_args ++] = ctx->dbg_md;
8827 md_args [nmd_args ++] = NULL;
8828 loc_md = LLVMMDNode (md_args, nmd_args);
8829 LLVMSetCurrentDebugLocation (builder, loc_md);
8831 mono_debug_symfile_free_location (loc);
8837 default_mono_llvm_unhandled_exception (void)
8839 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8840 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8842 mono_unhandled_exception (target);
8843 exit (mono_environment_exitcode_get ());
8848 - Emit LLVM IR from the mono IR using the LLVM C API.
8849 - The original arch specific code remains, so we can fall back to it if we run
8850 into something we can't handle.
8854 A partial list of issues:
8855 - Handling of opcodes which can throw exceptions.
8857 In the mono JIT, these are implemented using code like this:
8864 push throw_pos - method
8865 call <exception trampoline>
8867 The problematic part is push throw_pos - method, which cannot be represented
8868 in the LLVM IR, since it does not support label values.
8869 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8870 be implemented in JIT mode ?
8871 -> a possible but slower implementation would use the normal exception
8872 throwing code but it would need to control the placement of the throw code
8873 (it needs to be exactly after the compare+branch).
8874 -> perhaps add a PC offset intrinsics ?
8876 - efficient implementation of .ovf opcodes.
8878 These are currently implemented as:
8879 <ins which sets the condition codes>
8882 Some overflow opcodes are now supported by LLVM SVN.
8884 - exception handling, unwinding.
8885 - SSA is disabled for methods with exception handlers
8886 - How to obtain unwind info for LLVM compiled methods ?
8887 -> this is now solved by converting the unwind info generated by LLVM
8889 - LLVM uses the c++ exception handling framework, while we use our home grown
8890 code, and couldn't use the c++ one:
8891 - its not supported under VC++, other exotic platforms.
8892 - it might be impossible to support filter clauses with it.
8896 The trampolines need a predictable call sequence, since they need to disasm
8897 the calling code to obtain register numbers / offsets.
8899 LLVM currently generates this code in non-JIT mode:
8900 mov -0x98(%rax),%eax
8902 Here, the vtable pointer is lost.
8903 -> solution: use one vtable trampoline per class.
8905 - passing/receiving the IMT pointer/RGCTX.
8906 -> solution: pass them as normal arguments ?
8910 LLVM does not allow the specification of argument registers etc. This means
8911 that all calls are made according to the platform ABI.
8913 - passing/receiving vtypes.
8915 Vtypes passed/received in registers are handled by the front end by using
8916 a signature with scalar arguments, and loading the parts of the vtype into those
8919 Vtypes passed on the stack are handled using the 'byval' attribute.
8923 Supported though alloca, we need to emit the load/store code.
8927 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8928 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8929 This is made easier because the IR is already in SSA form.
8930 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8931 types are frequently used incorrectly.
8936 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8937 it with the file containing the methods emitted by the JIT and the AOT data
8941 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8942 * - each bblock should end with a branch
8943 * - setting the return value, making cfg->ret non-volatile
8944 * - avoid some transformations in the JIT which make it harder for us to generate
8946 * - use pointer types to help optimizations.