3 * llvm "Backend" for the mono JIT
5 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
6 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
7 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #include <mono/metadata/debug-helpers.h>
13 #include <mono/metadata/debug-internals.h>
14 #include <mono/metadata/mempool-internals.h>
15 #include <mono/metadata/environment.h>
16 #include <mono/metadata/object-internals.h>
17 #include <mono/metadata/abi-details.h>
18 #include <mono/utils/mono-tls.h>
19 #include <mono/utils/mono-dl.h>
20 #include <mono/utils/mono-time.h>
21 #include <mono/utils/freebsd-dwarf.h>
23 #ifndef __STDC_LIMIT_MACROS
24 #define __STDC_LIMIT_MACROS
26 #ifndef __STDC_CONSTANT_MACROS
27 #define __STDC_CONSTANT_MACROS
30 #include "llvm-c/BitWriter.h"
31 #include "llvm-c/Analysis.h"
33 #include "mini-llvm-cpp.h"
35 #include "aot-compiler.h"
36 #include "mini-llvm.h"
43 extern void *memset(void *, int, size_t);
44 void bzero (void *to, size_t count) { memset (to, 0, count); }
48 #if LLVM_API_VERSION < 4
49 #error "The version of the mono llvm repository is too old."
52 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
55 * Information associated by mono with LLVM modules.
58 LLVMModuleRef lmodule;
59 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
60 GHashTable *llvm_types;
62 const char *got_symbol;
63 const char *get_method_symbol;
64 const char *get_unbox_tramp_symbol;
65 GHashTable *plt_entries;
66 GHashTable *plt_entries_ji;
67 GHashTable *method_to_lmethod;
68 GHashTable *direct_callables;
73 GPtrArray *subprogram_mds;
75 LLVMExecutionEngineRef ee;
76 gboolean external_symbols;
79 LLVMValueRef personality;
82 MonoAssembly *assembly;
84 MonoAotFileInfo aot_info;
85 const char *jit_got_symbol;
86 const char *eh_frame_symbol;
87 LLVMValueRef get_method, get_unbox_tramp;
88 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
89 LLVMValueRef code_start, code_end;
90 LLVMValueRef inited_var;
91 int max_inited_idx, max_method_idx;
92 gboolean has_jitted_code;
95 GHashTable *idx_to_lmethod;
96 GHashTable *idx_to_unbox_tramp;
97 /* Maps a MonoMethod to LLVM instructions representing it */
98 GHashTable *method_to_callers;
99 LLVMContextRef context;
100 LLVMValueRef sentinel_exception;
101 void *di_builder, *cu;
102 GHashTable *objc_selector_to_var;
106 * Information associated by the backend with mono basic blocks.
109 LLVMBasicBlockRef bblock, end_bblock;
110 LLVMValueRef finally_ind;
111 gboolean added, invoke_target;
113 * If this bblock is the start of a finally clause, this is a list of bblocks it
114 * needs to branch to in ENDFINALLY.
116 GSList *call_handler_return_bbs;
118 * If this bblock is the start of a finally clause, this is the bblock that
119 * CALL_HANDLER needs to branch to.
121 LLVMBasicBlockRef call_handler_target_bb;
122 /* The list of switch statements generated by ENDFINALLY instructions */
123 GSList *endfinally_switch_ins_list;
128 * Structure containing emit state
131 MonoMemPool *mempool;
133 /* Maps method names to the corresponding LLVMValueRef */
134 GHashTable *emitted_method_decls;
137 LLVMValueRef lmethod;
138 MonoLLVMModule *module;
139 LLVMModuleRef lmodule;
141 int sindex, default_index, ex_index;
142 LLVMBuilderRef builder;
143 LLVMValueRef *values, *addresses;
144 MonoType **vreg_cli_types;
146 MonoMethodSignature *sig;
148 GHashTable *region_to_handler;
149 GHashTable *clause_to_handler;
150 LLVMBuilderRef alloca_builder;
151 LLVMValueRef last_alloca;
152 LLVMValueRef rgctx_arg;
153 LLVMValueRef this_arg;
154 LLVMTypeRef *vreg_types;
156 LLVMTypeRef method_type;
157 LLVMBasicBlockRef init_bb, inited_bb;
159 gboolean *unreachable;
161 gboolean has_got_access;
162 gboolean is_linkonce;
163 int this_arg_pindex, rgctx_arg_pindex;
164 LLVMValueRef imt_rgctx_loc;
165 GHashTable *llvm_types;
167 MonoDebugMethodInfo *minfo;
169 /* For every clause, the clauses it is nested in */
172 GHashTable *exc_meta;
173 GHashTable *method_to_callers;
174 GPtrArray *phi_values;
175 GPtrArray *bblock_list;
177 GHashTable *jit_callees;
178 LLVMValueRef long_bb_break_var;
184 MonoBasicBlock *in_bb;
189 * Instruction metadata
190 * This is the same as ins_info, but LREG != IREG.
198 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
199 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
206 /* keep in sync with the enum in mini.h */
209 #include "mini-ops.h"
214 #if SIZEOF_VOID_P == 4
215 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
217 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
220 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
223 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
225 #define TRACE_FAILURE(msg)
229 #define IS_TARGET_X86 1
231 #define IS_TARGET_X86 0
235 #define IS_TARGET_AMD64 1
237 #define IS_TARGET_AMD64 0
240 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
242 static LLVMIntPredicate cond_to_llvm_cond [] = {
255 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
268 static MonoNativeTlsKey current_cfg_tls_id;
270 static MonoLLVMModule aot_module;
272 static GHashTable *intrins_id_to_name;
273 static GHashTable *intrins_name_to_id;
275 static void init_jit_module (MonoDomain *domain);
277 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
278 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
279 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
280 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
281 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
282 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
285 set_failure (EmitContext *ctx, const char *message)
287 TRACE_FAILURE (reason);
288 ctx->cfg->exception_message = g_strdup (message);
289 ctx->cfg->disable_llvm = TRUE;
295 * The LLVM type with width == sizeof (gpointer)
300 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
306 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
312 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
318 * Return the size of the LLVM representation of the vtype T.
321 get_vtype_size (MonoType *t)
325 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
327 /* LLVMArgAsIArgs depends on this since it stores whole words */
328 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
335 * simd_class_to_llvm_type:
337 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
340 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
342 if (!strcmp (klass->name, "Vector2d")) {
343 return LLVMVectorType (LLVMDoubleType (), 2);
344 } else if (!strcmp (klass->name, "Vector2l")) {
345 return LLVMVectorType (LLVMInt64Type (), 2);
346 } else if (!strcmp (klass->name, "Vector2ul")) {
347 return LLVMVectorType (LLVMInt64Type (), 2);
348 } else if (!strcmp (klass->name, "Vector4i")) {
349 return LLVMVectorType (LLVMInt32Type (), 4);
350 } else if (!strcmp (klass->name, "Vector4ui")) {
351 return LLVMVectorType (LLVMInt32Type (), 4);
352 } else if (!strcmp (klass->name, "Vector4f")) {
353 return LLVMVectorType (LLVMFloatType (), 4);
354 } else if (!strcmp (klass->name, "Vector8s")) {
355 return LLVMVectorType (LLVMInt16Type (), 8);
356 } else if (!strcmp (klass->name, "Vector8us")) {
357 return LLVMVectorType (LLVMInt16Type (), 8);
358 } else if (!strcmp (klass->name, "Vector16sb")) {
359 return LLVMVectorType (LLVMInt8Type (), 16);
360 } else if (!strcmp (klass->name, "Vector16b")) {
361 return LLVMVectorType (LLVMInt8Type (), 16);
362 } else if (!strcmp (klass->name, "Vector2")) {
363 /* System.Numerics */
364 return LLVMVectorType (LLVMFloatType (), 4);
365 } else if (!strcmp (klass->name, "Vector3")) {
366 return LLVMVectorType (LLVMFloatType (), 4);
367 } else if (!strcmp (klass->name, "Vector4")) {
368 return LLVMVectorType (LLVMFloatType (), 4);
369 } else if (!strcmp (klass->name, "Vector`1")) {
370 MonoType *etype = mono_class_get_generic_class (klass)->context.class_inst->type_argv [0];
371 switch (etype->type) {
374 return LLVMVectorType (LLVMInt8Type (), 16);
377 return LLVMVectorType (LLVMInt16Type (), 8);
380 return LLVMVectorType (LLVMInt32Type (), 4);
383 return LLVMVectorType (LLVMInt64Type (), 2);
385 return LLVMVectorType (LLVMFloatType (), 4);
387 return LLVMVectorType (LLVMDoubleType (), 2);
389 g_assert_not_reached ();
393 printf ("%s\n", klass->name);
399 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
400 static inline G_GNUC_UNUSED LLVMTypeRef
401 type_to_simd_type (int type)
405 return LLVMVectorType (LLVMInt8Type (), 16);
407 return LLVMVectorType (LLVMInt16Type (), 8);
409 return LLVMVectorType (LLVMInt32Type (), 4);
411 return LLVMVectorType (LLVMInt64Type (), 2);
413 return LLVMVectorType (LLVMDoubleType (), 2);
415 return LLVMVectorType (LLVMFloatType (), 4);
417 g_assert_not_reached ();
423 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
425 int i, size, nfields, esize;
426 LLVMTypeRef *eltypes;
431 t = &klass->byval_arg;
433 if (mini_type_is_hfa (t, &nfields, &esize)) {
435 * This is needed on arm64 where HFAs are returned in
438 /* SIMD types have size 16 in mono_class_value_size () */
439 if (klass->simd_type)
442 eltypes = g_new (LLVMTypeRef, size);
443 for (i = 0; i < size; ++i)
444 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
446 size = get_vtype_size (t);
448 eltypes = g_new (LLVMTypeRef, size);
449 for (i = 0; i < size; ++i)
450 eltypes [i] = LLVMInt8Type ();
453 name = mono_type_full_name (&klass->byval_arg);
454 ltype = LLVMStructCreateNamed (module->context, name);
455 LLVMStructSetBody (ltype, eltypes, size, FALSE);
465 * Return the LLVM type corresponding to T.
468 type_to_llvm_type (EmitContext *ctx, MonoType *t)
470 t = mini_get_underlying_type (t);
474 return LLVMVoidType ();
476 return LLVMInt8Type ();
478 return LLVMInt16Type ();
480 return LLVMInt32Type ();
482 return LLVMInt8Type ();
484 return LLVMInt16Type ();
486 return LLVMInt32Type ();
489 return LLVMInt64Type ();
491 return LLVMFloatType ();
493 return LLVMDoubleType ();
496 return IntPtrType ();
497 case MONO_TYPE_OBJECT:
499 return ObjRefType ();
502 /* Because of generic sharing */
503 return ObjRefType ();
504 case MONO_TYPE_GENERICINST:
505 if (!mono_type_generic_inst_is_valuetype (t))
506 return ObjRefType ();
508 case MONO_TYPE_VALUETYPE:
509 case MONO_TYPE_TYPEDBYREF: {
513 klass = mono_class_from_mono_type (t);
515 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
516 return simd_class_to_llvm_type (ctx, klass);
519 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
521 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
523 ltype = create_llvm_type_for_type (ctx->module, klass);
524 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
530 printf ("X: %d\n", t->type);
531 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
532 ctx->cfg->disable_llvm = TRUE;
540 * Return whenever T is an unsigned int type.
543 type_is_unsigned (EmitContext *ctx, MonoType *t)
545 t = mini_get_underlying_type (t);
561 * type_to_llvm_arg_type:
563 * Same as type_to_llvm_type, but treat i8/i16 as i32.
566 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
568 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
570 if (ctx->cfg->llvm_only)
574 * This works on all abis except arm64/ios which passes multiple
575 * arguments in one stack slot.
578 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
580 * LLVM generates code which only sets the lower bits, while JITted
581 * code expects all the bits to be set.
583 ptype = LLVMInt32Type ();
591 * llvm_type_to_stack_type:
593 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
596 static G_GNUC_UNUSED LLVMTypeRef
597 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
601 if (type == LLVMInt8Type ())
602 return LLVMInt32Type ();
603 else if (type == LLVMInt16Type ())
604 return LLVMInt32Type ();
605 else if (!cfg->r4fp && type == LLVMFloatType ())
606 return LLVMDoubleType ();
612 * regtype_to_llvm_type:
614 * Return the LLVM type corresponding to the regtype C used in instruction
618 regtype_to_llvm_type (char c)
622 return LLVMInt32Type ();
624 return LLVMInt64Type ();
626 return LLVMDoubleType ();
635 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
638 op_to_llvm_type (int opcode)
643 return LLVMInt8Type ();
646 return LLVMInt8Type ();
649 return LLVMInt16Type ();
652 return LLVMInt16Type ();
655 return LLVMInt32Type ();
658 return LLVMInt32Type ();
660 return LLVMInt64Type ();
662 return LLVMFloatType ();
664 return LLVMDoubleType ();
666 return LLVMInt64Type ();
668 return LLVMInt32Type ();
670 return LLVMInt64Type ();
675 return LLVMInt8Type ();
680 return LLVMInt16Type ();
682 return LLVMInt32Type ();
685 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
692 return LLVMInt32Type ();
699 return LLVMInt64Type ();
701 printf ("%s\n", mono_inst_name (opcode));
702 g_assert_not_reached ();
707 #define CLAUSE_START(clause) ((clause)->try_offset)
708 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
711 * load_store_to_llvm_type:
713 * Return the size/sign/zero extension corresponding to the load/store opcode
717 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
723 case OP_LOADI1_MEMBASE:
724 case OP_STOREI1_MEMBASE_REG:
725 case OP_STOREI1_MEMBASE_IMM:
726 case OP_ATOMIC_LOAD_I1:
727 case OP_ATOMIC_STORE_I1:
730 return LLVMInt8Type ();
731 case OP_LOADU1_MEMBASE:
733 case OP_ATOMIC_LOAD_U1:
734 case OP_ATOMIC_STORE_U1:
737 return LLVMInt8Type ();
738 case OP_LOADI2_MEMBASE:
739 case OP_STOREI2_MEMBASE_REG:
740 case OP_STOREI2_MEMBASE_IMM:
741 case OP_ATOMIC_LOAD_I2:
742 case OP_ATOMIC_STORE_I2:
745 return LLVMInt16Type ();
746 case OP_LOADU2_MEMBASE:
748 case OP_ATOMIC_LOAD_U2:
749 case OP_ATOMIC_STORE_U2:
752 return LLVMInt16Type ();
753 case OP_LOADI4_MEMBASE:
754 case OP_LOADU4_MEMBASE:
757 case OP_STOREI4_MEMBASE_REG:
758 case OP_STOREI4_MEMBASE_IMM:
759 case OP_ATOMIC_LOAD_I4:
760 case OP_ATOMIC_STORE_I4:
761 case OP_ATOMIC_LOAD_U4:
762 case OP_ATOMIC_STORE_U4:
764 return LLVMInt32Type ();
765 case OP_LOADI8_MEMBASE:
767 case OP_STOREI8_MEMBASE_REG:
768 case OP_STOREI8_MEMBASE_IMM:
769 case OP_ATOMIC_LOAD_I8:
770 case OP_ATOMIC_STORE_I8:
771 case OP_ATOMIC_LOAD_U8:
772 case OP_ATOMIC_STORE_U8:
774 return LLVMInt64Type ();
775 case OP_LOADR4_MEMBASE:
776 case OP_STORER4_MEMBASE_REG:
777 case OP_ATOMIC_LOAD_R4:
778 case OP_ATOMIC_STORE_R4:
780 return LLVMFloatType ();
781 case OP_LOADR8_MEMBASE:
782 case OP_STORER8_MEMBASE_REG:
783 case OP_ATOMIC_LOAD_R8:
784 case OP_ATOMIC_STORE_R8:
786 return LLVMDoubleType ();
787 case OP_LOAD_MEMBASE:
789 case OP_STORE_MEMBASE_REG:
790 case OP_STORE_MEMBASE_IMM:
791 *size = sizeof (gpointer);
792 return IntPtrType ();
794 g_assert_not_reached ();
802 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
805 ovf_op_to_intrins (int opcode)
809 return "llvm.sadd.with.overflow.i32";
811 return "llvm.uadd.with.overflow.i32";
813 return "llvm.ssub.with.overflow.i32";
815 return "llvm.usub.with.overflow.i32";
817 return "llvm.smul.with.overflow.i32";
819 return "llvm.umul.with.overflow.i32";
821 return "llvm.sadd.with.overflow.i64";
823 return "llvm.uadd.with.overflow.i64";
825 return "llvm.ssub.with.overflow.i64";
827 return "llvm.usub.with.overflow.i64";
829 return "llvm.smul.with.overflow.i64";
831 return "llvm.umul.with.overflow.i64";
833 g_assert_not_reached ();
839 simd_op_to_intrins (int opcode)
842 #if defined(TARGET_X86) || defined(TARGET_AMD64)
844 return "llvm.x86.sse2.min.pd";
846 return "llvm.x86.sse.min.ps";
848 return "llvm.x86.sse2.max.pd";
850 return "llvm.x86.sse.max.ps";
852 return "llvm.x86.sse3.hadd.pd";
854 return "llvm.x86.sse3.hadd.ps";
856 return "llvm.x86.sse3.hsub.pd";
858 return "llvm.x86.sse3.hsub.ps";
860 return "llvm.x86.sse3.addsub.ps";
862 return "llvm.x86.sse3.addsub.pd";
863 case OP_EXTRACT_MASK:
864 return "llvm.x86.sse2.pmovmskb.128";
867 return "llvm.x86.sse2.psrli.w";
870 return "llvm.x86.sse2.psrli.d";
873 return "llvm.x86.sse2.psrli.q";
876 return "llvm.x86.sse2.pslli.w";
879 return "llvm.x86.sse2.pslli.d";
882 return "llvm.x86.sse2.pslli.q";
885 return "llvm.x86.sse2.psrai.w";
888 return "llvm.x86.sse2.psrai.d";
890 return "llvm.x86.sse2.padds.b";
892 return "llvm.x86.sse2.padds.w";
894 return "llvm.x86.sse2.psubs.b";
896 return "llvm.x86.sse2.psubs.w";
897 case OP_PADDB_SAT_UN:
898 return "llvm.x86.sse2.paddus.b";
899 case OP_PADDW_SAT_UN:
900 return "llvm.x86.sse2.paddus.w";
901 case OP_PSUBB_SAT_UN:
902 return "llvm.x86.sse2.psubus.b";
903 case OP_PSUBW_SAT_UN:
904 return "llvm.x86.sse2.psubus.w";
906 return "llvm.x86.sse2.pavg.b";
908 return "llvm.x86.sse2.pavg.w";
910 return "llvm.x86.sse.sqrt.ps";
912 return "llvm.x86.sse2.sqrt.pd";
914 return "llvm.x86.sse.rsqrt.ps";
916 return "llvm.x86.sse.rcp.ps";
918 return "llvm.x86.sse2.cvtdq2pd";
920 return "llvm.x86.sse2.cvtdq2ps";
922 return "llvm.x86.sse2.cvtpd2dq";
924 return "llvm.x86.sse2.cvtps2dq";
926 return "llvm.x86.sse2.cvtpd2ps";
928 return "llvm.x86.sse2.cvtps2pd";
930 return "llvm.x86.sse2.cvttpd2dq";
932 return "llvm.x86.sse2.cvttps2dq";
934 return "llvm.x86.sse2.packsswb.128";
936 return "llvm.x86.sse2.packssdw.128";
938 return "llvm.x86.sse2.packuswb.128";
940 return "llvm.x86.sse41.packusdw";
942 return "llvm.x86.sse2.pmulh.w";
943 case OP_PMULW_HIGH_UN:
944 return "llvm.x86.sse2.pmulhu.w";
946 return "llvm.x86.sse41.dpps";
949 g_assert_not_reached ();
955 simd_op_to_llvm_type (int opcode)
957 #if defined(TARGET_X86) || defined(TARGET_AMD64)
961 return type_to_simd_type (MONO_TYPE_R8);
964 return type_to_simd_type (MONO_TYPE_I8);
967 return type_to_simd_type (MONO_TYPE_I4);
972 return type_to_simd_type (MONO_TYPE_I2);
976 return type_to_simd_type (MONO_TYPE_I1);
978 return type_to_simd_type (MONO_TYPE_R4);
981 return type_to_simd_type (MONO_TYPE_I4);
985 return type_to_simd_type (MONO_TYPE_R8);
989 return type_to_simd_type (MONO_TYPE_R4);
990 case OP_EXTRACT_MASK:
991 return type_to_simd_type (MONO_TYPE_I1);
997 return type_to_simd_type (MONO_TYPE_R4);
1000 return type_to_simd_type (MONO_TYPE_R8);
1002 g_assert_not_reached ();
1013 * Return the LLVM basic block corresponding to BB.
1015 static LLVMBasicBlockRef
1016 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1018 char bb_name_buf [128];
1021 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1022 if (bb->flags & BB_EXCEPTION_HANDLER) {
1023 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1024 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1025 bb_name = bb_name_buf;
1026 } else if (bb->block_num < 256) {
1027 if (!ctx->module->bb_names) {
1028 ctx->module->bb_names_len = 256;
1029 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1031 if (!ctx->module->bb_names [bb->block_num]) {
1034 n = g_strdup_printf ("BB%d", bb->block_num);
1035 mono_memory_barrier ();
1036 ctx->module->bb_names [bb->block_num] = n;
1038 bb_name = ctx->module->bb_names [bb->block_num];
1040 sprintf (bb_name_buf, "BB%d", bb->block_num);
1041 bb_name = bb_name_buf;
1044 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1045 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1048 return ctx->bblocks [bb->block_num].bblock;
1054 * Return the last LLVM bblock corresponding to BB.
1055 * This might not be equal to the bb returned by get_bb () since we need to generate
1056 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1058 static LLVMBasicBlockRef
1059 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1062 return ctx->bblocks [bb->block_num].end_bblock;
1065 static LLVMBasicBlockRef
1066 gen_bb (EmitContext *ctx, const char *prefix)
1070 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1071 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1077 * Return the target of the patch identified by TYPE and TARGET.
1080 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1086 memset (&ji, 0, sizeof (ji));
1088 ji.data.target = target;
1090 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1091 mono_error_assert_ok (&error);
1099 * Emit code to convert the LLVM value V to DTYPE.
1102 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1104 LLVMTypeRef stype = LLVMTypeOf (v);
1106 if (stype != dtype) {
1107 gboolean ext = FALSE;
1110 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1112 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1114 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1118 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1120 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1121 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1124 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1125 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1126 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1127 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1128 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1129 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1130 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1131 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1133 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1134 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1135 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1136 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1137 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1138 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1140 if (mono_arch_is_soft_float ()) {
1141 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1142 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1143 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1144 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1147 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1148 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1151 LLVMDumpValue (LLVMConstNull (dtype));
1152 g_assert_not_reached ();
1160 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1162 return convert_full (ctx, v, dtype, FALSE);
1166 * emit_volatile_load:
1168 * If vreg is volatile, emit a load from its address.
1171 emit_volatile_load (EmitContext *ctx, int vreg)
1177 // FIXME: This hack is required because we pass the rgctx in a callee saved
1178 // register on arm64 (x15), and llvm might keep the value in that register
1179 // even through the register is marked as 'reserved' inside llvm.
1180 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1181 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1183 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1185 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1187 t = ctx->vreg_cli_types [vreg];
1188 if (t && !t->byref) {
1190 * Might have to zero extend since llvm doesn't have
1193 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1194 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1195 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1196 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1197 else if (t->type == MONO_TYPE_U8)
1198 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1205 * emit_volatile_store:
1207 * If VREG is volatile, emit a store from its value to its address.
1210 emit_volatile_store (EmitContext *ctx, int vreg)
1212 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1214 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1215 g_assert (ctx->addresses [vreg]);
1216 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1221 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1223 LLVMTypeRef ret_type;
1224 LLVMTypeRef *param_types = NULL;
1229 rtype = mini_get_underlying_type (sig->ret);
1230 ret_type = type_to_llvm_type (ctx, rtype);
1234 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1238 param_types [pindex ++] = ThisType ();
1239 for (i = 0; i < sig->param_count; ++i)
1240 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1242 if (!ctx_ok (ctx)) {
1243 g_free (param_types);
1247 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1248 g_free (param_types);
1254 * sig_to_llvm_sig_full:
1256 * Return the LLVM signature corresponding to the mono signature SIG using the
1257 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1260 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1262 LLVMTypeRef ret_type;
1263 LLVMTypeRef *param_types = NULL;
1265 int i, j, pindex, vret_arg_pindex = 0;
1266 gboolean vretaddr = FALSE;
1270 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1272 rtype = mini_get_underlying_type (sig->ret);
1273 ret_type = type_to_llvm_type (ctx, rtype);
1277 switch (cinfo->ret.storage) {
1278 case LLVMArgVtypeInReg:
1279 /* LLVM models this by returning an aggregate value */
1280 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1281 LLVMTypeRef members [2];
1283 members [0] = IntPtrType ();
1284 ret_type = LLVMStructType (members, 1, FALSE);
1285 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1287 ret_type = LLVMVoidType ();
1288 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1289 LLVMTypeRef members [2];
1291 members [0] = IntPtrType ();
1292 members [1] = IntPtrType ();
1293 ret_type = LLVMStructType (members, 2, FALSE);
1295 g_assert_not_reached ();
1298 case LLVMArgVtypeByVal:
1299 /* Vtype returned normally by val */
1301 case LLVMArgVtypeAsScalar: {
1302 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1303 /* LLVM models this by returning an int */
1304 if (size < SIZEOF_VOID_P) {
1305 g_assert (cinfo->ret.nslots == 1);
1306 ret_type = LLVMIntType (size * 8);
1308 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1309 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1313 case LLVMArgAsIArgs:
1314 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1316 case LLVMArgFpStruct: {
1317 /* Vtype returned as a fp struct */
1318 LLVMTypeRef members [16];
1320 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1321 for (i = 0; i < cinfo->ret.nslots; ++i)
1322 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1323 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1326 case LLVMArgVtypeByRef:
1327 /* Vtype returned using a hidden argument */
1328 ret_type = LLVMVoidType ();
1330 case LLVMArgVtypeRetAddr:
1331 case LLVMArgGsharedvtFixed:
1332 case LLVMArgGsharedvtFixedVtype:
1333 case LLVMArgGsharedvtVariable:
1335 ret_type = LLVMVoidType ();
1341 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1343 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1345 * Has to be the first argument because of the sret argument attribute
1346 * FIXME: This might conflict with passing 'this' as the first argument, but
1347 * this is only used on arm64 which has a dedicated struct return register.
1349 cinfo->vret_arg_pindex = pindex;
1350 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1351 if (!ctx_ok (ctx)) {
1352 g_free (param_types);
1355 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1358 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1359 cinfo->rgctx_arg_pindex = pindex;
1360 param_types [pindex] = ctx->module->ptr_type;
1363 if (cinfo->imt_arg) {
1364 cinfo->imt_arg_pindex = pindex;
1365 param_types [pindex] = ctx->module->ptr_type;
1369 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1370 vret_arg_pindex = pindex;
1371 if (cinfo->vret_arg_index == 1) {
1372 /* Add the slots consumed by the first argument */
1373 LLVMArgInfo *ainfo = &cinfo->args [0];
1374 switch (ainfo->storage) {
1375 case LLVMArgVtypeInReg:
1376 for (j = 0; j < 2; ++j) {
1377 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1386 cinfo->vret_arg_pindex = vret_arg_pindex;
1389 if (vretaddr && vret_arg_pindex == pindex)
1390 param_types [pindex ++] = IntPtrType ();
1392 cinfo->this_arg_pindex = pindex;
1393 param_types [pindex ++] = ThisType ();
1394 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1396 if (vretaddr && vret_arg_pindex == pindex)
1397 param_types [pindex ++] = IntPtrType ();
1398 for (i = 0; i < sig->param_count; ++i) {
1399 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1401 if (vretaddr && vret_arg_pindex == pindex)
1402 param_types [pindex ++] = IntPtrType ();
1403 ainfo->pindex = pindex;
1405 switch (ainfo->storage) {
1406 case LLVMArgVtypeInReg:
1407 for (j = 0; j < 2; ++j) {
1408 switch (ainfo->pair_storage [j]) {
1410 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1415 g_assert_not_reached ();
1419 case LLVMArgVtypeByVal:
1420 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1423 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1426 case LLVMArgAsIArgs:
1427 if (ainfo->esize == 8)
1428 param_types [pindex] = LLVMArrayType (LLVMInt64Type (), ainfo->nslots);
1430 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1433 case LLVMArgVtypeByRef:
1434 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1437 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1440 case LLVMArgAsFpArgs: {
1443 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1444 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1445 param_types [pindex ++] = LLVMDoubleType ();
1446 for (j = 0; j < ainfo->nslots; ++j)
1447 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1450 case LLVMArgVtypeAsScalar:
1451 g_assert_not_reached ();
1453 case LLVMArgGsharedvtFixed:
1454 case LLVMArgGsharedvtFixedVtype:
1455 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1457 case LLVMArgGsharedvtVariable:
1458 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1461 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1465 if (!ctx_ok (ctx)) {
1466 g_free (param_types);
1469 if (vretaddr && vret_arg_pindex == pindex)
1470 param_types [pindex ++] = IntPtrType ();
1471 if (ctx->llvm_only && cinfo->rgctx_arg) {
1472 /* Pass the rgctx as the last argument */
1473 cinfo->rgctx_arg_pindex = pindex;
1474 param_types [pindex] = ctx->module->ptr_type;
1478 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1479 g_free (param_types);
1485 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1487 return sig_to_llvm_sig_full (ctx, sig, NULL);
1491 * LLVMFunctionType1:
1493 * Create an LLVM function type from the arguments.
1495 static G_GNUC_UNUSED LLVMTypeRef
1496 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1499 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1503 * LLVMFunctionType1:
1505 * Create an LLVM function type from the arguments.
1507 static G_GNUC_UNUSED LLVMTypeRef
1508 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1509 LLVMTypeRef ParamType1,
1512 LLVMTypeRef param_types [1];
1514 param_types [0] = ParamType1;
1516 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1520 * LLVMFunctionType2:
1522 * Create an LLVM function type from the arguments.
1524 static G_GNUC_UNUSED LLVMTypeRef
1525 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1526 LLVMTypeRef ParamType1,
1527 LLVMTypeRef ParamType2,
1530 LLVMTypeRef param_types [2];
1532 param_types [0] = ParamType1;
1533 param_types [1] = ParamType2;
1535 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1539 * LLVMFunctionType3:
1541 * Create an LLVM function type from the arguments.
1543 static G_GNUC_UNUSED LLVMTypeRef
1544 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1545 LLVMTypeRef ParamType1,
1546 LLVMTypeRef ParamType2,
1547 LLVMTypeRef ParamType3,
1550 LLVMTypeRef param_types [3];
1552 param_types [0] = ParamType1;
1553 param_types [1] = ParamType2;
1554 param_types [2] = ParamType3;
1556 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1559 static G_GNUC_UNUSED LLVMTypeRef
1560 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1561 LLVMTypeRef ParamType1,
1562 LLVMTypeRef ParamType2,
1563 LLVMTypeRef ParamType3,
1564 LLVMTypeRef ParamType4,
1565 LLVMTypeRef ParamType5,
1568 LLVMTypeRef param_types [5];
1570 param_types [0] = ParamType1;
1571 param_types [1] = ParamType2;
1572 param_types [2] = ParamType3;
1573 param_types [3] = ParamType4;
1574 param_types [4] = ParamType5;
1576 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1582 * Create an LLVM builder and remember it so it can be freed later.
1584 static LLVMBuilderRef
1585 create_builder (EmitContext *ctx)
1587 LLVMBuilderRef builder = LLVMCreateBuilder ();
1589 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1595 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1600 case MONO_PATCH_INFO_INTERNAL_METHOD:
1601 name = g_strdup_printf ("jit_icall_%s", data);
1603 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1604 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1605 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1609 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1617 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1621 LLVMValueRef indexes [2];
1622 LLVMValueRef got_entry_addr, load;
1623 LLVMBuilderRef builder = ctx->builder;
1628 MonoJumpInfo tmp_ji;
1630 tmp_ji.data.target = data;
1632 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1634 ji->next = cfg->patch_info;
1635 cfg->patch_info = ji;
1637 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1638 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1640 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1641 * explicitly initialize it.
1643 if (!mono_aot_is_shared_got_offset (got_offset)) {
1644 //mono_print_ji (ji);
1646 ctx->has_got_access = TRUE;
1649 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1650 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1651 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1653 name = get_aotconst_name (type, data, got_offset);
1655 load = LLVMBuildLoad (builder, got_entry_addr, "");
1656 load = convert (ctx, load, llvm_type);
1657 LLVMSetValueName (load, name ? name : "");
1659 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1662 //set_invariant_load_flag (load);
1668 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1670 return get_aotconst_typed (ctx, type, data, NULL);
1674 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1676 LLVMValueRef callee;
1678 if (ctx->llvm_only) {
1679 callee_name = mono_aot_get_direct_call_symbol (type, data);
1681 /* Directly callable */
1683 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1685 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1687 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1689 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1691 /* LLVMTypeRef's are uniqued */
1692 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1693 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1695 g_free (callee_name);
1701 * Calls are made through the GOT.
1703 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1705 MonoJumpInfo *ji = NULL;
1707 callee_name = mono_aot_get_plt_symbol (type, data);
1711 if (ctx->cfg->compile_aot)
1712 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1713 mono_add_patch_info (ctx->cfg, 0, type, data);
1716 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1718 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1720 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1722 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1725 if (ctx->cfg->compile_aot) {
1726 ji = g_new0 (MonoJumpInfo, 1);
1728 ji->data.target = data;
1730 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1738 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1740 #if LLVM_API_VERSION > 100
1741 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1742 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1743 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1744 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1747 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1748 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1754 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1756 MonoMethodHeader *header = cfg->header;
1757 MonoExceptionClause *clause;
1761 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1762 return (bb->region >> 8) - 1;
1765 for (i = 0; i < header->num_clauses; ++i) {
1766 clause = &header->clauses [i];
1768 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1775 static MonoExceptionClause *
1776 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1778 if (bb == cfg->bb_init)
1780 // Since they're sorted by nesting we just need
1781 // the first one that the bb is a member of
1782 for (int i = 0; i < cfg->header->num_clauses; i++) {
1783 MonoExceptionClause *curr = &cfg->header->clauses [i];
1785 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1793 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1795 LLVMValueRef md_arg;
1798 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1799 md_arg = LLVMMDString ("mono", 4);
1800 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1804 set_invariant_load_flag (LLVMValueRef v)
1806 LLVMValueRef md_arg;
1808 const char *flag_name;
1810 // FIXME: Cache this
1811 flag_name = "invariant.load";
1812 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1813 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1814 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1820 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1824 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1826 MonoCompile *cfg = ctx->cfg;
1827 LLVMValueRef lcall = NULL;
1828 LLVMBuilderRef builder = *builder_ref;
1829 MonoExceptionClause *clause;
1831 if (ctx->llvm_only) {
1832 clause = get_most_deep_clause (cfg, ctx, bb);
1835 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause->flags == MONO_EXCEPTION_CLAUSE_FAULT);
1838 * Have to use an invoke instead of a call, branching to the
1839 * handler bblock of the clause containing this bblock.
1841 intptr_t key = CLAUSE_END(clause);
1843 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1845 // FIXME: Find the one that has the lowest end bound for the right start address
1846 // FIXME: Finally + nesting
1849 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1852 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1854 builder = ctx->builder = create_builder (ctx);
1855 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1857 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1861 int clause_index = get_handler_clause (cfg, bb);
1863 if (clause_index != -1) {
1864 MonoMethodHeader *header = cfg->header;
1865 MonoExceptionClause *ec = &header->clauses [clause_index];
1866 MonoBasicBlock *tblock;
1867 LLVMBasicBlockRef ex_bb, noex_bb;
1870 * Have to use an invoke instead of a call, branching to the
1871 * handler bblock of the clause containing this bblock.
1874 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY || ec->flags == MONO_EXCEPTION_CLAUSE_FAULT);
1876 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1879 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1881 ex_bb = get_bb (ctx, tblock);
1883 noex_bb = gen_bb (ctx, "NOEX_BB");
1886 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1888 builder = ctx->builder = create_builder (ctx);
1889 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1891 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1896 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1897 ctx->builder = builder;
1901 *builder_ref = ctx->builder;
1907 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1909 const char *intrins_name;
1910 LLVMValueRef args [16], res;
1911 LLVMTypeRef addr_type;
1912 gboolean use_intrinsics = TRUE;
1914 #if LLVM_API_VERSION > 100
1915 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1916 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1919 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1920 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1921 *builder_ref = ctx->builder;
1922 use_intrinsics = FALSE;
1926 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1927 LLVMAtomicOrdering ordering;
1930 case LLVM_BARRIER_NONE:
1931 ordering = LLVMAtomicOrderingNotAtomic;
1933 case LLVM_BARRIER_ACQ:
1934 ordering = LLVMAtomicOrderingAcquire;
1936 case LLVM_BARRIER_SEQ:
1937 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1940 g_assert_not_reached ();
1945 * We handle loads which can fault by calling a mono specific intrinsic
1946 * using an invoke, so they are handled properly inside try blocks.
1947 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1948 * are marked with IntrReadArgMem.
1952 intrins_name = "llvm.mono.load.i8.p0i8";
1955 intrins_name = "llvm.mono.load.i16.p0i16";
1958 intrins_name = "llvm.mono.load.i32.p0i32";
1961 intrins_name = "llvm.mono.load.i64.p0i64";
1964 g_assert_not_reached ();
1967 addr_type = LLVMTypeOf (addr);
1968 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1969 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1972 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1973 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1974 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1975 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1977 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1978 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1979 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1980 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1987 * We emit volatile loads for loads which can fault, because otherwise
1988 * LLVM will generate invalid code when encountering a load from a
1991 if (barrier != LLVM_BARRIER_NONE)
1992 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1994 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1996 /* Mark it with a custom metadata */
1999 set_metadata_flag (res, "mono.faulting.load");
2007 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
2009 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
2013 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
2015 const char *intrins_name;
2016 LLVMValueRef args [16];
2017 gboolean use_intrinsics = TRUE;
2019 #if LLVM_API_VERSION > 100
2020 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
2021 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2022 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
2023 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
2024 *builder_ref = ctx->builder;
2025 use_intrinsics = FALSE;
2029 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2030 LLVMAtomicOrdering ordering;
2033 case LLVM_BARRIER_NONE:
2034 ordering = LLVMAtomicOrderingNotAtomic;
2036 case LLVM_BARRIER_REL:
2037 ordering = LLVMAtomicOrderingRelease;
2039 case LLVM_BARRIER_SEQ:
2040 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2043 g_assert_not_reached ();
2049 intrins_name = "llvm.mono.store.i8.p0i8";
2052 intrins_name = "llvm.mono.store.i16.p0i16";
2055 intrins_name = "llvm.mono.store.i32.p0i32";
2058 intrins_name = "llvm.mono.store.i64.p0i64";
2061 g_assert_not_reached ();
2064 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2065 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2066 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2071 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2072 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2073 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2074 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2076 if (barrier != LLVM_BARRIER_NONE)
2077 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2079 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2084 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2086 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2090 * emit_cond_system_exception:
2092 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2093 * Might set the ctx exception.
2096 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2098 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2099 LLVMBuilderRef builder;
2100 MonoClass *exc_class;
2101 LLVMValueRef args [2];
2102 LLVMValueRef callee;
2103 gboolean no_pc = FALSE;
2105 if (IS_TARGET_AMD64)
2106 /* Some platforms don't require the pc argument */
2109 ex_bb = gen_bb (ctx, "EX_BB");
2111 ex2_bb = gen_bb (ctx, "EX2_BB");
2112 noex_bb = gen_bb (ctx, "NOEX_BB");
2114 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2116 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2118 /* Emit exception throwing code */
2119 ctx->builder = builder = create_builder (ctx);
2120 LLVMPositionBuilderAtEnd (builder, ex_bb);
2122 if (ctx->cfg->llvm_only) {
2123 static LLVMTypeRef sig;
2126 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2127 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2129 LLVMBuildBr (builder, ex2_bb);
2131 ctx->builder = builder = create_builder (ctx);
2132 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2134 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2135 emit_call (ctx, bb, &builder, callee, args, 1);
2136 LLVMBuildUnreachable (builder);
2138 ctx->builder = builder = create_builder (ctx);
2139 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2141 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2147 callee = ctx->module->throw_corlib_exception;
2150 const char *icall_name;
2153 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2155 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2156 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2158 if (ctx->cfg->compile_aot) {
2159 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2162 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2163 * - On x86, LLVM generated code doesn't push the arguments
2164 * - The trampoline takes the throw address as an arguments, not a pc offset.
2166 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2167 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2169 #if LLVM_API_VERSION > 100
2171 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2172 * added by emit_jit_callee ().
2174 ex2_bb = gen_bb (ctx, "EX2_BB");
2175 LLVMBuildBr (builder, ex2_bb);
2178 ctx->builder = builder = create_builder (ctx);
2179 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2181 mono_memory_barrier ();
2182 ctx->module->throw_corlib_exception = callee;
2187 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2190 * The LLVM mono branch contains changes so a block address can be passed as an
2191 * argument to a call.
2194 emit_call (ctx, bb, &builder, callee, args, 1);
2196 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2197 emit_call (ctx, bb, &builder, callee, args, 2);
2200 LLVMBuildUnreachable (builder);
2202 ctx->builder = builder = create_builder (ctx);
2203 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2205 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2212 * emit_args_to_vtype:
2214 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2217 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2219 int j, size, nslots;
2221 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2223 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2224 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2227 if (ainfo->storage == LLVMArgAsFpArgs)
2228 nslots = ainfo->nslots;
2232 for (j = 0; j < nslots; ++j) {
2233 LLVMValueRef index [2], addr, daddr;
2234 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2235 LLVMTypeRef part_type;
2237 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2240 if (ainfo->pair_storage [j] == LLVMArgNone)
2243 switch (ainfo->pair_storage [j]) {
2244 case LLVMArgInIReg: {
2245 part_type = LLVMIntType (part_size * 8);
2246 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2247 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2248 addr = LLVMBuildGEP (builder, address, index, 1, "");
2250 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2251 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2252 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2254 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2257 case LLVMArgInFPReg: {
2258 LLVMTypeRef arg_type;
2260 if (ainfo->esize == 8)
2261 arg_type = LLVMDoubleType ();
2263 arg_type = LLVMFloatType ();
2265 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2266 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2267 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2268 LLVMBuildStore (builder, args [j], addr);
2274 g_assert_not_reached ();
2277 size -= sizeof (gpointer);
2282 * emit_vtype_to_args:
2284 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2285 * into ARGS, and the number of arguments into NARGS.
2288 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2291 int j, size, nslots;
2292 LLVMTypeRef arg_type;
2294 size = get_vtype_size (t);
2296 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2297 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2299 if (ainfo->storage == LLVMArgAsFpArgs)
2300 nslots = ainfo->nslots;
2303 for (j = 0; j < nslots; ++j) {
2304 LLVMValueRef index [2], addr, daddr;
2305 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2307 if (ainfo->pair_storage [j] == LLVMArgNone)
2310 switch (ainfo->pair_storage [j]) {
2312 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2313 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2314 addr = LLVMBuildGEP (builder, address, index, 1, "");
2316 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2317 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2318 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2320 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2322 case LLVMArgInFPReg:
2323 if (ainfo->esize == 8)
2324 arg_type = LLVMDoubleType ();
2326 arg_type = LLVMFloatType ();
2327 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2328 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2329 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2330 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2335 g_assert_not_reached ();
2337 size -= sizeof (gpointer);
2344 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2347 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2348 * get executed every time control reaches them.
2350 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2352 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2353 return ctx->last_alloca;
2357 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2359 return build_alloca_llvm_type_name (ctx, t, align, "");
2363 build_alloca (EmitContext *ctx, MonoType *t)
2365 MonoClass *k = mono_class_from_mono_type (t);
2368 g_assert (!mini_is_gsharedvt_variable_type (t));
2370 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2373 align = mono_class_min_align (k);
2375 /* Sometimes align is not a power of 2 */
2376 while (mono_is_power_of_two (align) == -1)
2379 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2383 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2387 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2389 MonoCompile *cfg = ctx->cfg;
2390 LLVMBuilderRef builder = ctx->builder;
2391 LLVMValueRef offset, offset_var;
2392 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2393 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2397 g_assert (info_var);
2398 g_assert (locals_var);
2400 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2402 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2403 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2405 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2406 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2408 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2412 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2415 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2418 module->used = g_ptr_array_sized_new (16);
2419 g_ptr_array_add (module->used, global);
2423 emit_llvm_used (MonoLLVMModule *module)
2425 LLVMModuleRef lmodule = module->lmodule;
2426 LLVMTypeRef used_type;
2427 LLVMValueRef used, *used_elem;
2433 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2434 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2435 used_elem = g_new0 (LLVMValueRef, module->used->len);
2436 for (i = 0; i < module->used->len; ++i)
2437 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2438 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2439 LLVMSetLinkage (used, LLVMAppendingLinkage);
2440 LLVMSetSection (used, "llvm.metadata");
2446 * Emit a function mapping method indexes to their code
2449 emit_get_method (MonoLLVMModule *module)
2451 LLVMModuleRef lmodule = module->lmodule;
2452 LLVMValueRef func, switch_ins, m;
2453 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2454 LLVMBasicBlockRef *bbs;
2456 LLVMBuilderRef builder = LLVMCreateBuilder ();
2461 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2462 * but generating code seems safer.
2464 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2465 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2466 LLVMSetLinkage (func, LLVMExternalLinkage);
2467 LLVMSetVisibility (func, LLVMHiddenVisibility);
2468 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
2469 module->get_method = func;
2471 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2474 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2475 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2476 * then we will have to find another solution.
2479 name = g_strdup_printf ("BB_CODE_START");
2480 code_start_bb = LLVMAppendBasicBlock (func, name);
2482 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2483 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2485 name = g_strdup_printf ("BB_CODE_END");
2486 code_end_bb = LLVMAppendBasicBlock (func, name);
2488 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2489 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2491 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2492 for (i = 0; i < module->max_method_idx + 1; ++i) {
2493 name = g_strdup_printf ("BB_%d", i);
2494 bb = LLVMAppendBasicBlock (func, name);
2498 LLVMPositionBuilderAtEnd (builder, bb);
2500 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2502 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2504 LLVMBuildRet (builder, LLVMConstNull (rtype));
2507 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2508 LLVMPositionBuilderAtEnd (builder, fail_bb);
2509 LLVMBuildRet (builder, LLVMConstNull (rtype));
2511 LLVMPositionBuilderAtEnd (builder, entry_bb);
2513 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2514 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2515 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2516 for (i = 0; i < module->max_method_idx + 1; ++i) {
2517 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2520 mark_as_used (module, func);
2522 LLVMDisposeBuilder (builder);
2526 * emit_get_unbox_tramp:
2528 * Emit a function mapping method indexes to their unbox trampoline
2531 emit_get_unbox_tramp (MonoLLVMModule *module)
2533 LLVMModuleRef lmodule = module->lmodule;
2534 LLVMValueRef func, switch_ins, m;
2535 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2536 LLVMBasicBlockRef *bbs;
2538 LLVMBuilderRef builder = LLVMCreateBuilder ();
2542 /* Similar to emit_get_method () */
2544 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2545 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2546 LLVMSetLinkage (func, LLVMExternalLinkage);
2547 LLVMSetVisibility (func, LLVMHiddenVisibility);
2548 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
2549 module->get_unbox_tramp = func;
2551 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2553 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2554 for (i = 0; i < module->max_method_idx + 1; ++i) {
2555 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2559 name = g_strdup_printf ("BB_%d", i);
2560 bb = LLVMAppendBasicBlock (func, name);
2564 LLVMPositionBuilderAtEnd (builder, bb);
2566 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2569 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2570 LLVMPositionBuilderAtEnd (builder, fail_bb);
2571 LLVMBuildRet (builder, LLVMConstNull (rtype));
2573 LLVMPositionBuilderAtEnd (builder, entry_bb);
2575 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2576 for (i = 0; i < module->max_method_idx + 1; ++i) {
2577 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2581 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2584 mark_as_used (module, func);
2585 LLVMDisposeBuilder (builder);
2588 /* Add a function to mark the beginning of LLVM code */
2590 emit_llvm_code_start (MonoLLVMModule *module)
2592 LLVMModuleRef lmodule = module->lmodule;
2594 LLVMBasicBlockRef entry_bb;
2595 LLVMBuilderRef builder;
2597 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2598 LLVMSetLinkage (func, LLVMInternalLinkage);
2599 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
2600 module->code_start = func;
2601 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2602 builder = LLVMCreateBuilder ();
2603 LLVMPositionBuilderAtEnd (builder, entry_bb);
2604 LLVMBuildRetVoid (builder);
2605 LLVMDisposeBuilder (builder);
2609 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2611 LLVMModuleRef lmodule = module->lmodule;
2612 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2613 LLVMBasicBlockRef entry_bb;
2614 LLVMBuilderRef builder;
2621 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2622 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2627 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2628 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2631 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2632 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2635 g_assert_not_reached ();
2637 LLVMSetLinkage (func, LLVMInternalLinkage);
2638 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_INLINE);
2639 mono_llvm_set_preserveall_cc (func);
2640 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2641 builder = LLVMCreateBuilder ();
2642 LLVMPositionBuilderAtEnd (builder, entry_bb);
2645 ji = g_new0 (MonoJumpInfo, 1);
2646 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2647 ji = mono_aot_patch_info_dup (ji);
2648 got_offset = mono_aot_get_got_offset (ji);
2649 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2650 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2651 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2652 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2653 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2654 args [1] = LLVMGetParam (func, 0);
2656 args [2] = LLVMGetParam (func, 1);
2658 ji = g_new0 (MonoJumpInfo, 1);
2659 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2660 ji->data.name = icall_name;
2661 ji = mono_aot_patch_info_dup (ji);
2662 got_offset = mono_aot_get_got_offset (ji);
2663 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2664 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2665 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2666 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2667 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2668 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2669 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2671 // Set the inited flag
2672 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2673 indexes [1] = LLVMGetParam (func, 0);
2674 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2676 LLVMBuildRetVoid (builder);
2678 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2679 LLVMDisposeBuilder (builder);
2684 * Emit wrappers around the C icalls used to initialize llvm methods, to
2685 * make the calling code smaller and to enable usage of the llvm
2686 * PreserveAll calling convention.
2689 emit_init_icall_wrappers (MonoLLVMModule *module)
2691 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2692 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2693 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2694 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2698 emit_llvm_code_end (MonoLLVMModule *module)
2700 LLVMModuleRef lmodule = module->lmodule;
2702 LLVMBasicBlockRef entry_bb;
2703 LLVMBuilderRef builder;
2705 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2706 LLVMSetLinkage (func, LLVMInternalLinkage);
2707 mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
2708 module->code_end = func;
2709 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2710 builder = LLVMCreateBuilder ();
2711 LLVMPositionBuilderAtEnd (builder, entry_bb);
2712 LLVMBuildRetVoid (builder);
2713 LLVMDisposeBuilder (builder);
2717 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2719 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2722 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2723 need_div_check = TRUE;
2725 if (!need_div_check)
2728 switch (ins->opcode) {
2741 case OP_IDIV_UN_IMM:
2742 case OP_LDIV_UN_IMM:
2743 case OP_IREM_UN_IMM:
2744 case OP_LREM_UN_IMM: {
2746 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2747 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2749 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2750 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2753 builder = ctx->builder;
2755 /* b == -1 && a == 0x80000000 */
2757 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2758 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2759 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2761 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2762 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2765 builder = ctx->builder;
2777 * Emit code to initialize the GOT slots used by the method.
2780 emit_init_method (EmitContext *ctx)
2782 LLVMValueRef indexes [16], args [16], callee;
2783 LLVMValueRef inited_var, cmp, call;
2784 LLVMBasicBlockRef inited_bb, notinited_bb;
2785 LLVMBuilderRef builder = ctx->builder;
2786 MonoCompile *cfg = ctx->cfg;
2788 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2790 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2791 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2792 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2794 args [0] = inited_var;
2795 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2796 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2798 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2800 inited_bb = ctx->inited_bb;
2801 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2803 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2805 builder = ctx->builder = create_builder (ctx);
2806 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2809 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2810 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2811 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2812 callee = ctx->module->init_method_gshared_mrgctx;
2813 call = LLVMBuildCall (builder, callee, args, 2, "");
2814 } else if (ctx->rgctx_arg) {
2815 /* A vtable is passed as the rgctx argument */
2816 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2817 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2818 callee = ctx->module->init_method_gshared_vtable;
2819 call = LLVMBuildCall (builder, callee, args, 2, "");
2820 } else if (cfg->gshared) {
2821 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2822 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2823 callee = ctx->module->init_method_gshared_this;
2824 call = LLVMBuildCall (builder, callee, args, 2, "");
2826 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2827 callee = ctx->module->init_method;
2828 call = LLVMBuildCall (builder, callee, args, 1, "");
2832 * This enables llvm to keep arguments in their original registers/
2833 * scratch registers, since the call will not clobber them.
2835 mono_llvm_set_call_preserveall_cc (call);
2837 LLVMBuildBr (builder, inited_bb);
2838 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2840 builder = ctx->builder = create_builder (ctx);
2841 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2845 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2848 * Emit unbox trampoline using a tail call
2850 LLVMValueRef tramp, call, *args;
2851 LLVMBuilderRef builder;
2852 LLVMBasicBlockRef lbb;
2853 LLVMCallInfo *linfo;
2857 tramp_name = g_strdup_printf ("ut_%s", method_name);
2858 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2859 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2860 mono_llvm_add_func_attr (tramp, LLVM_ATTR_OPTIMIZE_FOR_SIZE);
2861 //mono_llvm_add_func_attr (tramp, LLVM_ATTR_NO_UNWIND);
2863 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2864 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2865 mono_llvm_add_param_attr (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVM_ATTR_IN_REG);
2866 if (ctx->cfg->vret_addr) {
2867 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2868 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2869 mono_llvm_add_param_attr (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVM_ATTR_STRUCT_RET);
2870 mono_llvm_add_param_attr (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVM_ATTR_NO_ALIAS);
2874 lbb = LLVMAppendBasicBlock (tramp, "");
2875 builder = LLVMCreateBuilder ();
2876 LLVMPositionBuilderAtEnd (builder, lbb);
2878 nargs = LLVMCountParamTypes (method_type);
2879 args = g_new0 (LLVMValueRef, nargs);
2880 for (i = 0; i < nargs; ++i) {
2881 args [i] = LLVMGetParam (tramp, i);
2882 if (i == ctx->this_arg_pindex) {
2883 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2885 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2886 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2887 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2890 call = LLVMBuildCall (builder, method, args, nargs, "");
2891 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2892 mono_llvm_add_instr_attr (call, 1 + ctx->rgctx_arg_pindex, LLVM_ATTR_IN_REG);
2893 if (linfo->ret.storage == LLVMArgVtypeByRef)
2894 mono_llvm_add_instr_attr (call, 1 + linfo->vret_arg_pindex, LLVM_ATTR_STRUCT_RET);
2896 // FIXME: This causes assertions in clang
2897 //mono_llvm_set_must_tail (call);
2898 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2899 LLVMBuildRetVoid (builder);
2901 LLVMBuildRet (builder, call);
2903 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2904 LLVMDisposeBuilder (builder);
2910 * Emit code to load/convert arguments.
2913 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2916 MonoCompile *cfg = ctx->cfg;
2917 MonoMethodSignature *sig = ctx->sig;
2918 LLVMCallInfo *linfo = ctx->linfo;
2922 LLVMBuilderRef old_builder = ctx->builder;
2923 ctx->builder = builder;
2925 ctx->alloca_builder = create_builder (ctx);
2928 * Handle indirect/volatile variables by allocating memory for them
2929 * using 'alloca', and storing their address in a temporary.
2931 for (i = 0; i < cfg->num_varinfo; ++i) {
2932 MonoInst *var = cfg->varinfo [i];
2935 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2936 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2937 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2940 /* Could be already created by an OP_VPHI */
2941 if (!ctx->addresses [var->dreg]) {
2942 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2943 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2945 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2949 names = g_new (char *, sig->param_count);
2950 mono_method_get_param_names (cfg->method, (const char **) names);
2952 for (i = 0; i < sig->param_count; ++i) {
2953 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2954 int reg = cfg->args [i + sig->hasthis]->dreg;
2957 pindex = ainfo->pindex;
2959 switch (ainfo->storage) {
2960 case LLVMArgVtypeInReg:
2961 case LLVMArgAsFpArgs: {
2962 LLVMValueRef args [8];
2965 pindex += ainfo->ndummy_fpargs;
2967 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2968 memset (args, 0, sizeof (args));
2969 if (ainfo->storage == LLVMArgVtypeInReg) {
2970 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2971 if (ainfo->pair_storage [1] != LLVMArgNone)
2972 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2974 g_assert (ainfo->nslots <= 8);
2975 for (j = 0; j < ainfo->nslots; ++j)
2976 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2978 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2980 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2982 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2983 /* Treat these as normal values */
2984 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2988 case LLVMArgVtypeByVal: {
2989 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2991 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2992 /* Treat these as normal values */
2993 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2997 case LLVMArgVtypeByRef: {
2998 /* The argument is passed by ref */
2999 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3002 case LLVMArgAsIArgs: {
3003 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3006 /* The argument is received as an array of ints, store it into the real argument */
3007 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
3009 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
3010 if (size < SIZEOF_VOID_P) {
3011 /* The upper bits of the registers might not be valid */
3012 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
3013 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
3014 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
3016 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
3020 case LLVMArgVtypeAsScalar:
3021 g_assert_not_reached ();
3023 case LLVMArgGsharedvtFixed: {
3024 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3025 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3028 name = g_strdup_printf ("arg_%s", names [i]);
3030 name = g_strdup_printf ("arg_%d", i);
3032 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3035 case LLVMArgGsharedvtFixedVtype: {
3036 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3039 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3041 name = g_strdup_printf ("vtype_arg_%d", i);
3043 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3044 g_assert (ctx->addresses [reg]);
3045 LLVMSetValueName (ctx->addresses [reg], name);
3046 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3049 case LLVMArgGsharedvtVariable:
3050 /* The IR treats these as variables with addresses */
3051 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3054 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
3061 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3063 emit_volatile_store (ctx, cfg->args [0]->dreg);
3064 for (i = 0; i < sig->param_count; ++i)
3065 if (!mini_type_is_vtype (sig->params [i]))
3066 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3068 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3069 LLVMValueRef this_alloc;
3072 * The exception handling code needs the location where the this argument was
3073 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3074 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3075 * location into the LSDA.
3077 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3078 /* This volatile store will keep the alloca alive */
3079 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3081 set_metadata_flag (this_alloc, "mono.this");
3084 if (cfg->rgctx_var) {
3085 LLVMValueRef rgctx_alloc, store;
3088 * We handle the rgctx arg similarly to the this pointer.
3090 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3091 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3092 /* This volatile store will keep the alloca alive */
3093 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3095 set_metadata_flag (rgctx_alloc, "mono.this");
3098 /* Initialize the method if needed */
3099 if (cfg->compile_aot && ctx->llvm_only) {
3100 /* Emit a location for the initialization code */
3101 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3102 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3104 LLVMBuildBr (ctx->builder, ctx->init_bb);
3105 builder = ctx->builder = create_builder (ctx);
3106 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3107 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3110 /* Compute nesting between clauses */
3111 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3112 for (i = 0; i < cfg->header->num_clauses; ++i) {
3113 for (j = 0; j < cfg->header->num_clauses; ++j) {
3114 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3115 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3117 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3118 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3123 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3124 * it needs to continue normally, or return back to the exception handling system.
3126 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3130 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3133 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3134 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3135 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3137 if (bb->in_scount == 0) {
3140 sprintf (name, "finally_ind_bb%d", bb->block_num);
3141 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3142 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3144 ctx->bblocks [bb->block_num].finally_ind = val;
3146 /* Create a variable to hold the exception var */
3148 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3152 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3153 * LLVM bblock containing a landing pad causes problems for the
3154 * LLVM optimizer passes.
3156 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3157 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3159 ctx->builder = old_builder;
3163 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3165 MonoCompile *cfg = ctx->cfg;
3166 LLVMValueRef *values = ctx->values;
3167 LLVMValueRef *addresses = ctx->addresses;
3168 MonoCallInst *call = (MonoCallInst*)ins;
3169 MonoMethodSignature *sig = call->signature;
3170 LLVMValueRef callee = NULL, lcall;
3172 LLVMCallInfo *cinfo;
3176 LLVMTypeRef llvm_sig;
3178 gboolean is_virtual, calli, preserveall;
3179 LLVMBuilderRef builder = *builder_ref;
3181 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3182 set_failure (ctx, "non-default callconv");
3186 cinfo = call->cinfo;
3188 if (call->rgctx_arg_reg)
3189 cinfo->rgctx_arg = TRUE;
3190 if (call->imt_arg_reg)
3191 cinfo->imt_arg = TRUE;
3193 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3195 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3199 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3200 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3202 preserveall = FALSE;
3204 /* FIXME: Avoid creating duplicate methods */
3206 if (ins->flags & MONO_INST_HAS_METHOD) {
3210 if (cfg->compile_aot) {
3211 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3213 set_failure (ctx, "can't encode patch");
3216 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3218 * Collect instructions representing the callee into a hash so they can be replaced
3219 * by the llvm method for the callee if the callee turns out to be direct
3220 * callable. Currently this only requires it to not fail llvm compilation.
3222 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3223 l = g_slist_prepend (l, callee);
3224 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3228 static int tramp_index;
3231 name = g_strdup_printf ("tramp_%d", tramp_index);
3234 #if LLVM_API_VERSION > 100
3236 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3237 * Make all calls through a global. The address of the global will be saved in
3238 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3241 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3244 mono_create_jit_trampoline (mono_domain_get (),
3245 call->method, &error);
3246 if (!is_ok (&error)) {
3247 set_failure (ctx, mono_error_get_message (&error));
3248 mono_error_cleanup (&error);
3252 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3253 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3254 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3255 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3257 callee = LLVMBuildLoad (builder, tramp_var, "");
3260 mono_create_jit_trampoline (mono_domain_get (),
3261 call->method, &error);
3262 if (!is_ok (&error)) {
3264 set_failure (ctx, mono_error_get_message (&error));
3265 mono_error_cleanup (&error);
3269 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3272 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3277 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3278 /* LLVM miscompiles async methods */
3279 set_failure (ctx, "#13734");
3284 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3290 memset (&ji, 0, sizeof (ji));
3291 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3292 ji.data.target = info->name;
3294 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3296 if (cfg->compile_aot) {
3297 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3299 set_failure (ctx, "can't encode patch");
3303 target = (gpointer)mono_icall_get_wrapper (info);
3304 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3307 if (cfg->compile_aot) {
3309 if (cfg->abs_patches) {
3310 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3312 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3314 set_failure (ctx, "can't encode patch");
3320 set_failure (ctx, "aot");
3324 #if LLVM_API_VERSION > 100
3325 if (cfg->abs_patches) {
3326 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3330 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3331 mono_error_assert_ok (&error);
3332 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3334 g_assert_not_reached ();
3337 g_assert_not_reached ();
3340 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3342 if (cfg->abs_patches) {
3343 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3348 * FIXME: Some trampolines might have
3349 * their own calling convention on some platforms.
3351 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3352 mono_error_assert_ok (&error);
3353 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3357 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3364 int size = sizeof (gpointer);
3367 g_assert (ins->inst_offset % size == 0);
3368 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3370 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3372 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3374 if (ins->flags & MONO_INST_HAS_METHOD) {
3379 * Collect and convert arguments
3381 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3382 len = sizeof (LLVMValueRef) * nargs;
3383 args = (LLVMValueRef*)alloca (len);
3384 memset (args, 0, len);
3385 l = call->out_ireg_args;
3387 if (call->rgctx_arg_reg) {
3388 g_assert (values [call->rgctx_arg_reg]);
3389 g_assert (cinfo->rgctx_arg_pindex < nargs);
3391 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3392 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3393 * it using a volatile load.
3396 if (!ctx->imt_rgctx_loc)
3397 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3398 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3399 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3401 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3404 if (call->imt_arg_reg) {
3405 g_assert (!ctx->llvm_only);
3406 g_assert (values [call->imt_arg_reg]);
3407 g_assert (cinfo->imt_arg_pindex < nargs);
3409 if (!ctx->imt_rgctx_loc)
3410 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3411 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3412 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3414 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3417 switch (cinfo->ret.storage) {
3418 case LLVMArgGsharedvtVariable: {
3419 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3421 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3422 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3424 g_assert (addresses [call->inst.dreg]);
3425 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3431 if (!addresses [call->inst.dreg])
3432 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3433 g_assert (cinfo->vret_arg_pindex < nargs);
3434 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3435 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3437 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3443 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3444 * use the real callee for argument type conversion.
3446 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3447 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3448 LLVMGetParamTypes (callee_type, param_types);
3450 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3453 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3455 pindex = ainfo->pindex;
3457 regpair = (guint32)(gssize)(l->data);
3458 reg = regpair & 0xffffff;
3459 args [pindex] = values [reg];
3460 switch (ainfo->storage) {
3461 case LLVMArgVtypeInReg:
3462 case LLVMArgAsFpArgs: {
3466 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3467 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3468 pindex += ainfo->ndummy_fpargs;
3470 g_assert (addresses [reg]);
3471 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3475 // FIXME: Get rid of the VMOVE
3478 case LLVMArgVtypeByVal:
3479 g_assert (addresses [reg]);
3480 args [pindex] = addresses [reg];
3482 case LLVMArgVtypeByRef: {
3483 g_assert (addresses [reg]);
3484 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3487 case LLVMArgAsIArgs:
3488 g_assert (addresses [reg]);
3489 if (ainfo->esize == 8)
3490 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (LLVMInt64Type (), ainfo->nslots), 0)), "");
3492 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3494 case LLVMArgVtypeAsScalar:
3495 g_assert_not_reached ();
3497 case LLVMArgGsharedvtFixed:
3498 case LLVMArgGsharedvtFixedVtype:
3499 g_assert (addresses [reg]);
3500 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3502 case LLVMArgGsharedvtVariable:
3503 g_assert (addresses [reg]);
3504 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3507 g_assert (args [pindex]);
3508 if (i == 0 && sig->hasthis)
3509 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3511 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3514 g_assert (pindex <= nargs);
3519 // FIXME: Align call sites
3525 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3527 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3528 mono_llvm_set_call_notail (lcall);
3531 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3533 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3534 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3536 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3537 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3538 if (!sig->pinvoke && !cfg->llvm_only)
3539 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3541 mono_llvm_set_call_preserveall_cc (lcall);
3543 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3544 mono_llvm_add_instr_attr (lcall, 1 + cinfo->vret_arg_pindex, LLVM_ATTR_STRUCT_RET);
3545 if (!ctx->llvm_only && call->rgctx_arg_reg)
3546 mono_llvm_add_instr_attr (lcall, 1 + cinfo->rgctx_arg_pindex, LLVM_ATTR_IN_REG);
3547 if (call->imt_arg_reg)
3548 mono_llvm_add_instr_attr (lcall, 1 + cinfo->imt_arg_pindex, LLVM_ATTR_IN_REG);
3550 /* Add byval attributes if needed */
3551 for (i = 0; i < sig->param_count; ++i) {
3552 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3554 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3555 mono_llvm_add_instr_attr (lcall, 1 + ainfo->pindex, LLVM_ATTR_BY_VAL);
3559 * Convert the result
3561 switch (cinfo->ret.storage) {
3562 case LLVMArgVtypeInReg: {
3563 LLVMValueRef regs [2];
3565 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3569 if (!addresses [ins->dreg])
3570 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3572 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3573 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3574 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3575 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3578 case LLVMArgVtypeByVal:
3579 if (!addresses [call->inst.dreg])
3580 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3581 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3583 case LLVMArgAsIArgs:
3584 case LLVMArgFpStruct:
3585 if (!addresses [call->inst.dreg])
3586 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3587 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3589 case LLVMArgVtypeAsScalar:
3590 if (!addresses [call->inst.dreg])
3591 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3592 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3594 case LLVMArgVtypeRetAddr:
3595 case LLVMArgVtypeByRef:
3596 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3597 /* Some opcodes like STOREX_MEMBASE access these by value */
3598 g_assert (addresses [call->inst.dreg]);
3599 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3602 case LLVMArgGsharedvtVariable:
3604 case LLVMArgGsharedvtFixed:
3605 case LLVMArgGsharedvtFixedVtype:
3606 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3609 if (sig->ret->type != MONO_TYPE_VOID)
3610 /* If the method returns an unsigned value, need to zext it */
3611 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
3615 *builder_ref = ctx->builder;
3619 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3621 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3622 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3624 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3627 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3629 if (ctx->cfg->compile_aot) {
3630 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3632 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3633 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3634 mono_memory_barrier ();
3637 ctx->module->rethrow = callee;
3639 ctx->module->throw_icall = callee;
3643 LLVMValueRef args [2];
3645 args [0] = convert (ctx, exc, exc_type);
3646 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3648 LLVMBuildUnreachable (ctx->builder);
3650 ctx->builder = create_builder (ctx);
3654 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3656 MonoMethodSignature *throw_sig;
3657 LLVMValueRef callee, arg;
3658 const char *icall_name;
3660 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3661 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3664 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3665 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3666 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3667 if (ctx->cfg->compile_aot) {
3668 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3673 * LLVM doesn't push the exception argument, so we need a different
3676 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3678 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3680 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3683 mono_memory_barrier ();
3684 #if LLVM_API_VERSION < 100
3686 ctx->module->rethrow = callee;
3688 ctx->module->throw_icall = callee;
3691 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3692 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3696 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3698 const char *icall_name = "mono_llvm_resume_exception";
3699 LLVMValueRef callee = ctx->module->resume_eh;
3701 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3704 if (ctx->cfg->compile_aot) {
3705 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3707 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3708 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3709 mono_memory_barrier ();
3711 ctx->module->resume_eh = callee;
3715 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3717 LLVMBuildUnreachable (ctx->builder);
3719 ctx->builder = create_builder (ctx);
3723 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3725 const char *icall_name = "mono_llvm_clear_exception";
3727 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3728 LLVMValueRef callee = NULL;
3731 if (ctx->cfg->compile_aot) {
3732 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3734 // FIXME: This is broken.
3735 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3739 g_assert (builder && callee);
3741 return LLVMBuildCall (builder, callee, NULL, 0, "");
3745 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3747 const char *icall_name = "mono_llvm_load_exception";
3749 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3750 LLVMValueRef callee = NULL;
3753 if (ctx->cfg->compile_aot) {
3754 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3756 // FIXME: This is broken.
3757 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3761 g_assert (builder && callee);
3763 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3768 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3770 const char *icall_name = "mono_llvm_match_exception";
3772 ctx->builder = builder;
3774 const int num_args = 5;
3775 LLVMValueRef args [num_args];
3776 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3777 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3778 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3779 if (ctx->cfg->rgctx_var) {
3780 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3781 g_assert (rgctx_alloc);
3782 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3784 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3787 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3789 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3791 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3792 LLVMValueRef callee = ctx->module->match_exc;
3795 if (ctx->cfg->compile_aot) {
3796 ctx->builder = builder;
3797 // get_callee expects ctx->builder to be the emitting builder
3798 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3800 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3801 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3802 ctx->module->match_exc = callee;
3803 mono_memory_barrier ();
3807 g_assert (builder && callee);
3809 g_assert (ctx->ex_var);
3811 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3814 // FIXME: This won't work because the code-finding makes this
3816 /*#define MONO_PERSONALITY_DEBUG*/
3818 #ifdef MONO_PERSONALITY_DEBUG
3819 static const gboolean use_debug_personality = TRUE;
3820 static const char *default_personality_name = "mono_debug_personality";
3822 static const gboolean use_debug_personality = FALSE;
3823 static const char *default_personality_name = "__gxx_personality_v0";
3827 default_cpp_lpad_exc_signature (void)
3829 static gboolean inited = FALSE;
3830 static LLVMTypeRef sig;
3833 LLVMTypeRef signature [2];
3834 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3835 signature [1] = LLVMInt32Type ();
3836 sig = LLVMStructType (signature, 2, FALSE);
3844 get_mono_personality (EmitContext *ctx)
3846 LLVMValueRef personality = NULL;
3847 static gint32 mapping_inited = FALSE;
3848 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3850 if (!use_debug_personality) {
3851 if (ctx->cfg->compile_aot) {
3852 personality = get_intrinsic (ctx, default_personality_name);
3853 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3854 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3855 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3858 if (ctx->cfg->compile_aot) {
3859 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3861 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3862 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3863 mono_memory_barrier ();
3867 g_assert (personality);
3871 static LLVMBasicBlockRef
3872 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3874 MonoCompile *cfg = ctx->cfg;
3875 LLVMBuilderRef old_builder = ctx->builder;
3876 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3878 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3879 ctx->builder = lpadBuilder;
3881 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3882 g_assert (handler_bb);
3884 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3885 LLVMValueRef personality = get_mono_personality (ctx);
3886 g_assert (personality);
3888 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3889 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3891 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3892 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3893 g_assert (landing_pad);
3895 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3896 LLVMAddClause (landing_pad, cast);
3898 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3899 LLVMBuilderRef resume_builder = create_builder (ctx);
3900 ctx->builder = resume_builder;
3901 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3903 emit_resume_eh (ctx, handler_bb);
3906 ctx->builder = lpadBuilder;
3907 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3909 gboolean finally_only = TRUE;
3911 MonoExceptionClause *group_cursor = group_start;
3913 for (int i = 0; i < group_size; i ++) {
3914 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY || group_cursor->flags & MONO_EXCEPTION_CLAUSE_FAULT))
3915 finally_only = FALSE;
3921 // Handle landing pad inlining
3923 if (!finally_only) {
3924 // So at each level of the exception stack we will match the exception again.
3925 // During that match, we need to compare against the handler types for the current
3926 // protected region. We send the try start and end so that we can only check against
3927 // handlers for this lexical protected region.
3928 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3930 // if returns -1, resume
3931 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3933 // else move to that target bb
3934 for (int i = 0; i < group_size; i++) {
3935 MonoExceptionClause *clause = group_start + i;
3936 int clause_index = clause - cfg->header->clauses;
3937 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3938 g_assert (handler_bb);
3939 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3940 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3943 int clause_index = group_start - cfg->header->clauses;
3944 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3945 g_assert (finally_bb);
3947 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3950 ctx->builder = old_builder;
3957 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3959 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3960 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3962 // Make exception available to catch blocks
3963 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY || clause->flags & MONO_EXCEPTION_CLAUSE_FAULT)) {
3964 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3966 g_assert (ctx->ex_var);
3967 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3969 if (bb->in_scount == 1) {
3970 MonoInst *exvar = bb->in_stack [0];
3971 g_assert (!ctx->values [exvar->dreg]);
3972 g_assert (ctx->ex_var);
3973 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3974 emit_volatile_store (ctx, exvar->dreg);
3977 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3980 LLVMBuilderRef handler_builder = create_builder (ctx);
3981 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3982 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3984 // Make the handler code end with a jump to cbb
3985 LLVMBuildBr (handler_builder, cbb);
3989 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3991 MonoCompile *cfg = ctx->cfg;
3992 LLVMValueRef *values = ctx->values;
3993 LLVMModuleRef lmodule = ctx->lmodule;
3994 BBInfo *bblocks = ctx->bblocks;
3996 LLVMValueRef personality;
3997 LLVMValueRef landing_pad;
3998 LLVMBasicBlockRef target_bb;
4000 static int ti_generator;
4002 LLVMValueRef type_info;
4006 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4008 if (cfg->compile_aot) {
4009 /* Use a dummy personality function */
4010 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4011 g_assert (personality);
4013 #if LLVM_API_VERSION > 100
4014 /* Can't cache this as each method is in its own llvm module */
4015 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
4016 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
4017 mono_llvm_add_func_attr (personality, LLVM_ATTR_NO_UNWIND);
4018 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
4019 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
4020 LLVMPositionBuilderAtEnd (builder2, entry_bb);
4021 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
4022 LLVMDisposeBuilder (builder2);
4024 static gint32 mapping_inited;
4026 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4028 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
4029 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4033 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4035 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4038 * Create the type info
4040 sprintf (ti_name, "type_info_%d", ti_generator);
4043 if (cfg->compile_aot) {
4044 /* decode_eh_frame () in aot-runtime.c will decode this */
4045 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4046 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4049 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4051 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4053 #if LLVM_API_VERSION > 100
4054 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4055 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4060 * After the cfg mempool is freed, the type info will point to stale memory,
4061 * but this is not a problem, since we decode it once in exception_cb during
4064 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4065 *(gint32*)ti = clause_index;
4067 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4069 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4074 LLVMTypeRef members [2], ret_type;
4076 members [0] = i8ptr;
4077 members [1] = LLVMInt32Type ();
4078 ret_type = LLVMStructType (members, 2, FALSE);
4080 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4081 LLVMAddClause (landing_pad, type_info);
4083 /* Store the exception into the exvar */
4085 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4089 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4090 * code expects control to be transferred to this landing pad even in the
4091 * presence of nested clauses. The landing pad needs to branch to the landing
4092 * pads belonging to nested clauses based on the selector value returned by
4093 * the landing pad instruction, which is passed to the landing pad in a
4094 * register by the EH code.
4096 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4097 g_assert (target_bb);
4100 * Branch to the correct landing pad
4102 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4103 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4105 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4106 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4107 MonoBasicBlock *handler_bb;
4109 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4110 g_assert (handler_bb);
4112 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4113 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4116 /* Start a new bblock which CALL_HANDLER can branch to */
4117 ctx->builder = builder = create_builder (ctx);
4118 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4120 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4122 /* Store the exception into the IL level exvar */
4123 if (bb->in_scount == 1) {
4124 g_assert (bb->in_scount == 1);
4125 exvar = bb->in_stack [0];
4127 // FIXME: This is shared with filter clauses ?
4128 g_assert (!values [exvar->dreg]);
4130 g_assert (ctx->ex_var);
4131 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4132 emit_volatile_store (ctx, exvar->dreg);
4135 /* Make normal branches to the start of the clause branch to the new bblock */
4136 bblocks [bb->block_num].bblock = target_bb;
4140 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4142 MonoCompile *cfg = ctx->cfg;
4143 MonoMethodSignature *sig = ctx->sig;
4144 LLVMValueRef method = ctx->lmethod;
4145 LLVMValueRef *values = ctx->values;
4146 LLVMValueRef *addresses = ctx->addresses;
4147 LLVMCallInfo *linfo = ctx->linfo;
4148 BBInfo *bblocks = ctx->bblocks;
4150 LLVMBasicBlockRef cbb;
4151 LLVMBuilderRef builder, starting_builder;
4152 gboolean has_terminator;
4154 LLVMValueRef lhs, rhs;
4157 cbb = get_end_bb (ctx, bb);
4159 builder = create_builder (ctx);
4160 ctx->builder = builder;
4161 LLVMPositionBuilderAtEnd (builder, cbb);
4166 if (bb->flags & BB_EXCEPTION_HANDLER) {
4167 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4168 set_failure (ctx, "handler without invokes");
4173 emit_llvmonly_handler_start (ctx, bb, cbb);
4175 emit_handler_start (ctx, bb, builder);
4178 builder = ctx->builder;
4181 has_terminator = FALSE;
4182 starting_builder = builder;
4183 for (ins = bb->code; ins; ins = ins->next) {
4184 const char *spec = LLVM_INS_INFO (ins->opcode);
4186 char dname_buf [128];
4188 emit_dbg_loc (ctx, builder, ins->cil_code);
4193 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4194 * Start a new bblock.
4195 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4196 * from localloc-ed memory.
4198 if (!cfg->llvm_only)
4199 ;//set_failure (ctx, "basic block too long");
4201 if (!ctx->long_bb_break_var) {
4202 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4203 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4206 cbb = gen_bb (ctx, "CONT_LONG_BB");
4207 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4209 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4211 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4212 * but llvm doesn't know that, so the branch is not going to be eliminated.
4214 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4216 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4218 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4219 ctx->builder = builder = create_builder (ctx);
4220 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4221 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4222 LLVMBuildBr (builder, cbb);
4224 ctx->builder = builder = create_builder (ctx);
4225 LLVMPositionBuilderAtEnd (builder, cbb);
4226 ctx->bblocks [bb->block_num].end_bblock = cbb;
4231 /* There could be instructions after a terminator, skip them */
4234 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4235 sprintf (dname_buf, "t%d", ins->dreg);
4239 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4240 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4242 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4243 lhs = emit_volatile_load (ctx, ins->sreg1);
4245 /* It is ok for SETRET to have an uninitialized argument */
4246 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4247 set_failure (ctx, "sreg1");
4250 lhs = values [ins->sreg1];
4256 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4257 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4258 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4259 rhs = emit_volatile_load (ctx, ins->sreg2);
4261 if (!values [ins->sreg2]) {
4262 set_failure (ctx, "sreg2");
4265 rhs = values [ins->sreg2];
4271 //mono_print_ins (ins);
4272 switch (ins->opcode) {
4275 case OP_LIVERANGE_START:
4276 case OP_LIVERANGE_END:
4279 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4282 #if SIZEOF_VOID_P == 4
4283 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4285 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4289 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4293 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4295 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4297 case OP_DUMMY_ICONST:
4298 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4300 case OP_DUMMY_I8CONST:
4301 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4303 case OP_DUMMY_R8CONST:
4304 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4307 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4308 LLVMBuildBr (builder, target_bb);
4309 has_terminator = TRUE;
4316 LLVMBasicBlockRef new_bb;
4317 LLVMBuilderRef new_builder;
4319 // The default branch is already handled
4320 // FIXME: Handle it here
4322 /* Start new bblock */
4323 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4324 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4326 lhs = convert (ctx, lhs, LLVMInt32Type ());
4327 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4328 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4329 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4331 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4334 new_builder = create_builder (ctx);
4335 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4336 LLVMBuildUnreachable (new_builder);
4338 has_terminator = TRUE;
4339 g_assert (!ins->next);
4345 switch (linfo->ret.storage) {
4346 case LLVMArgVtypeInReg: {
4347 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4348 LLVMValueRef val, addr, retval;
4351 retval = LLVMGetUndef (ret_type);
4353 if (!addresses [ins->sreg1]) {
4355 * The return type is an LLVM vector type, have to convert between it and the
4356 * real return type which is a struct type.
4358 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4359 /* Convert to 2xi64 first */
4360 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4362 for (i = 0; i < 2; ++i) {
4363 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4364 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4366 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4370 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4371 for (i = 0; i < 2; ++i) {
4372 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4373 LLVMValueRef indexes [2], part_addr;
4375 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4376 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4377 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4379 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4381 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4385 LLVMBuildRet (builder, retval);
4388 case LLVMArgVtypeAsScalar: {
4389 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4390 LLVMValueRef retval;
4392 g_assert (addresses [ins->sreg1]);
4394 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4395 LLVMBuildRet (builder, retval);
4398 case LLVMArgVtypeByVal: {
4399 LLVMValueRef retval;
4401 g_assert (addresses [ins->sreg1]);
4402 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4403 LLVMBuildRet (builder, retval);
4406 case LLVMArgVtypeByRef: {
4407 LLVMBuildRetVoid (builder);
4410 case LLVMArgGsharedvtFixed: {
4411 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4412 /* The return value is in lhs, need to store to the vret argument */
4413 /* sreg1 might not be set */
4415 g_assert (cfg->vret_addr);
4416 g_assert (values [cfg->vret_addr->dreg]);
4417 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4419 LLVMBuildRetVoid (builder);
4422 case LLVMArgGsharedvtFixedVtype: {
4424 LLVMBuildRetVoid (builder);
4427 case LLVMArgGsharedvtVariable: {
4429 LLVMBuildRetVoid (builder);
4432 case LLVMArgVtypeRetAddr: {
4433 LLVMBuildRetVoid (builder);
4436 case LLVMArgAsIArgs:
4437 case LLVMArgFpStruct: {
4438 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4439 LLVMValueRef retval;
4441 g_assert (addresses [ins->sreg1]);
4442 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4443 LLVMBuildRet (builder, retval);
4447 case LLVMArgNormal: {
4448 if (!lhs || ctx->is_dead [ins->sreg1]) {
4450 * The method did not set its return value, probably because it
4451 * ends with a throw.
4454 LLVMBuildRetVoid (builder);
4456 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4458 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4460 has_terminator = TRUE;
4464 g_assert_not_reached ();
4473 case OP_ICOMPARE_IMM:
4474 case OP_LCOMPARE_IMM:
4475 case OP_COMPARE_IMM: {
4477 LLVMValueRef cmp, args [16];
4478 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4480 if (ins->next->opcode == OP_NOP)
4483 if (ins->next->opcode == OP_BR)
4484 /* The comparison result is not needed */
4487 rel = mono_opcode_to_cond (ins->next->opcode);
4489 if (ins->opcode == OP_ICOMPARE_IMM) {
4490 lhs = convert (ctx, lhs, LLVMInt32Type ());
4491 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4493 if (ins->opcode == OP_LCOMPARE_IMM) {
4494 lhs = convert (ctx, lhs, LLVMInt64Type ());
4495 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4497 if (ins->opcode == OP_LCOMPARE) {
4498 lhs = convert (ctx, lhs, LLVMInt64Type ());
4499 rhs = convert (ctx, rhs, LLVMInt64Type ());
4501 if (ins->opcode == OP_ICOMPARE) {
4502 lhs = convert (ctx, lhs, LLVMInt32Type ());
4503 rhs = convert (ctx, rhs, LLVMInt32Type ());
4507 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4508 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4509 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4510 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4513 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4514 if (ins->opcode == OP_FCOMPARE) {
4515 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4516 } else if (ins->opcode == OP_RCOMPARE) {
4517 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4518 } else if (ins->opcode == OP_COMPARE_IMM) {
4519 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4520 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4522 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4523 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4524 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4525 /* The immediate is encoded in two fields */
4526 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4527 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4529 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4532 else if (ins->opcode == OP_COMPARE) {
4533 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4534 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4536 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4538 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4542 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4543 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4546 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4547 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4549 * If the target bb contains PHI instructions, LLVM requires
4550 * two PHI entries for this bblock, while we only generate one.
4551 * So convert this to an unconditional bblock. (bxc #171).
4553 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4555 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4557 has_terminator = TRUE;
4558 } else if (MONO_IS_SETCC (ins->next)) {
4559 sprintf (dname_buf, "t%d", ins->next->dreg);
4561 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4563 /* Add stores for volatile variables */
4564 emit_volatile_store (ctx, ins->next->dreg);
4565 } else if (MONO_IS_COND_EXC (ins->next)) {
4566 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4569 builder = ctx->builder;
4571 set_failure (ctx, "next");
4589 rel = mono_opcode_to_cond (ins->opcode);
4591 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4592 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4603 rel = mono_opcode_to_cond (ins->opcode);
4605 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4606 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4614 gboolean empty = TRUE;
4616 /* Check that all input bblocks really branch to us */
4617 for (i = 0; i < bb->in_count; ++i) {
4618 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4619 ins->inst_phi_args [i + 1] = -1;
4625 /* LLVM doesn't like phi instructions with zero operands */
4626 ctx->is_dead [ins->dreg] = TRUE;
4630 /* Created earlier, insert it now */
4631 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4633 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4634 int sreg1 = ins->inst_phi_args [i + 1];
4638 * Count the number of times the incoming bblock branches to us,
4639 * since llvm requires a separate entry for each.
4641 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4642 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4645 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4646 if (switch_ins->inst_many_bb [j] == bb)
4653 /* Remember for later */
4654 for (j = 0; j < count; ++j) {
4655 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4658 node->in_bb = bb->in_bb [i];
4660 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);
4670 values [ins->dreg] = lhs;
4674 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4677 values [ins->dreg] = lhs;
4679 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4681 * This is added by the spilling pass in case of the JIT,
4682 * but we have to do it ourselves.
4684 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4688 case OP_MOVE_F_TO_I4: {
4689 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4692 case OP_MOVE_I4_TO_F: {
4693 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4696 case OP_MOVE_F_TO_I8: {
4697 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4700 case OP_MOVE_I8_TO_F: {
4701 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4734 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4735 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4737 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4740 builder = ctx->builder;
4742 switch (ins->opcode) {
4745 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4749 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4753 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4757 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4761 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4765 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4769 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4773 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4777 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4781 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4785 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4789 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4793 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4797 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4801 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4804 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4807 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4811 g_assert_not_reached ();
4818 lhs = convert (ctx, lhs, LLVMFloatType ());
4819 rhs = convert (ctx, rhs, LLVMFloatType ());
4820 switch (ins->opcode) {
4822 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4825 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4828 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4831 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4834 g_assert_not_reached ();
4843 case OP_IREM_UN_IMM:
4845 case OP_IDIV_UN_IMM:
4851 case OP_ISHR_UN_IMM:
4861 case OP_LSHR_UN_IMM:
4867 case OP_SHR_UN_IMM: {
4870 if (spec [MONO_INST_SRC1] == 'l') {
4871 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4873 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4876 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4879 builder = ctx->builder;
4881 #if SIZEOF_VOID_P == 4
4882 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4883 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4886 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4887 lhs = convert (ctx, lhs, IntPtrType ());
4888 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4889 switch (ins->opcode) {
4893 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4897 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4902 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4906 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4908 case OP_IDIV_UN_IMM:
4909 case OP_LDIV_UN_IMM:
4910 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4914 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4916 case OP_IREM_UN_IMM:
4917 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4922 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4926 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4930 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4935 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4940 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4942 case OP_ISHR_UN_IMM:
4943 /* This is used to implement conv.u4, so the lhs could be an i8 */
4944 lhs = convert (ctx, lhs, LLVMInt32Type ());
4945 imm = convert (ctx, imm, LLVMInt32Type ());
4946 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4948 case OP_LSHR_UN_IMM:
4950 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4953 g_assert_not_reached ();
4958 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4961 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4964 lhs = convert (ctx, lhs, LLVMDoubleType ());
4965 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4968 lhs = convert (ctx, lhs, LLVMFloatType ());
4969 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4972 guint32 v = 0xffffffff;
4973 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4977 guint64 v = 0xffffffffffffffffLL;
4978 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4981 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4983 LLVMValueRef v1, v2;
4985 rhs = LLVMBuildSExt (builder, convert (ctx, rhs, LLVMInt32Type ()), LLVMInt64Type (), "");
4987 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4988 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4989 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4994 case OP_ICONV_TO_I1:
4995 case OP_ICONV_TO_I2:
4996 case OP_ICONV_TO_I4:
4997 case OP_ICONV_TO_U1:
4998 case OP_ICONV_TO_U2:
4999 case OP_ICONV_TO_U4:
5000 case OP_LCONV_TO_I1:
5001 case OP_LCONV_TO_I2:
5002 case OP_LCONV_TO_U1:
5003 case OP_LCONV_TO_U2:
5004 case OP_LCONV_TO_U4: {
5007 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);
5009 /* Have to do two casts since our vregs have type int */
5010 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
5012 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
5014 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
5017 case OP_ICONV_TO_I8:
5018 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
5020 case OP_ICONV_TO_U8:
5021 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
5023 case OP_FCONV_TO_I4:
5024 case OP_RCONV_TO_I4:
5025 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
5027 case OP_FCONV_TO_I1:
5028 case OP_RCONV_TO_I1:
5029 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
5031 case OP_FCONV_TO_U1:
5032 case OP_RCONV_TO_U1:
5033 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5035 case OP_FCONV_TO_I2:
5036 case OP_RCONV_TO_I2:
5037 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5039 case OP_FCONV_TO_U2:
5040 case OP_RCONV_TO_U2:
5041 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5043 case OP_RCONV_TO_U4:
5044 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5046 case OP_FCONV_TO_I8:
5047 case OP_RCONV_TO_I8:
5048 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5051 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5053 case OP_ICONV_TO_R8:
5054 case OP_LCONV_TO_R8:
5055 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5057 case OP_ICONV_TO_R_UN:
5058 case OP_LCONV_TO_R_UN:
5059 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5061 #if SIZEOF_VOID_P == 4
5064 case OP_LCONV_TO_I4:
5065 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5067 case OP_ICONV_TO_R4:
5068 case OP_LCONV_TO_R4:
5069 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5071 values [ins->dreg] = v;
5073 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5075 case OP_FCONV_TO_R4:
5076 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5078 values [ins->dreg] = v;
5080 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5082 case OP_RCONV_TO_R8:
5083 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5085 case OP_RCONV_TO_R4:
5086 values [ins->dreg] = lhs;
5089 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5092 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5095 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5097 case OP_LOCALLOC_IMM: {
5100 guint32 size = ins->inst_imm;
5101 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5103 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5105 if (ins->flags & MONO_INST_INIT) {
5106 LLVMValueRef args [5];
5109 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5110 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5111 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5112 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5113 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5116 values [ins->dreg] = v;
5120 LLVMValueRef v, size;
5122 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), "");
5124 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5126 if (ins->flags & MONO_INST_INIT) {
5127 LLVMValueRef args [5];
5130 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5132 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5133 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5134 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5136 values [ins->dreg] = v;
5140 case OP_LOADI1_MEMBASE:
5141 case OP_LOADU1_MEMBASE:
5142 case OP_LOADI2_MEMBASE:
5143 case OP_LOADU2_MEMBASE:
5144 case OP_LOADI4_MEMBASE:
5145 case OP_LOADU4_MEMBASE:
5146 case OP_LOADI8_MEMBASE:
5147 case OP_LOADR4_MEMBASE:
5148 case OP_LOADR8_MEMBASE:
5149 case OP_LOAD_MEMBASE:
5157 LLVMValueRef base, index, addr;
5159 gboolean sext = FALSE, zext = FALSE;
5160 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5162 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5167 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)) {
5168 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5174 if (ins->inst_offset == 0) {
5176 } else if (ins->inst_offset % size != 0) {
5177 /* Unaligned load */
5178 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5179 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5181 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5182 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5186 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5188 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5190 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5192 * These will signal LLVM that these loads do not alias any stores, and
5193 * they can't fail, allowing them to be hoisted out of loops.
5195 set_invariant_load_flag (values [ins->dreg]);
5196 #if LLVM_API_VERSION < 100
5197 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5202 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5204 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5205 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5206 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5210 case OP_STOREI1_MEMBASE_REG:
5211 case OP_STOREI2_MEMBASE_REG:
5212 case OP_STOREI4_MEMBASE_REG:
5213 case OP_STOREI8_MEMBASE_REG:
5214 case OP_STORER4_MEMBASE_REG:
5215 case OP_STORER8_MEMBASE_REG:
5216 case OP_STORE_MEMBASE_REG: {
5218 LLVMValueRef index, addr, base;
5220 gboolean sext = FALSE, zext = FALSE;
5221 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5223 if (!values [ins->inst_destbasereg]) {
5224 set_failure (ctx, "inst_destbasereg");
5228 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5230 base = values [ins->inst_destbasereg];
5231 if (ins->inst_offset % size != 0) {
5232 /* Unaligned store */
5233 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5234 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5236 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5237 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5239 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5243 case OP_STOREI1_MEMBASE_IMM:
5244 case OP_STOREI2_MEMBASE_IMM:
5245 case OP_STOREI4_MEMBASE_IMM:
5246 case OP_STOREI8_MEMBASE_IMM:
5247 case OP_STORE_MEMBASE_IMM: {
5249 LLVMValueRef index, addr, base;
5251 gboolean sext = FALSE, zext = FALSE;
5252 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5254 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5256 base = values [ins->inst_destbasereg];
5257 if (ins->inst_offset % size != 0) {
5258 /* Unaligned store */
5259 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5260 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5262 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5263 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5265 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5270 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5272 case OP_OUTARG_VTRETADDR:
5280 case OP_VOIDCALL_MEMBASE:
5281 case OP_CALL_MEMBASE:
5282 case OP_LCALL_MEMBASE:
5283 case OP_FCALL_MEMBASE:
5284 case OP_RCALL_MEMBASE:
5285 case OP_VCALL_MEMBASE:
5286 case OP_VOIDCALL_REG:
5291 case OP_VCALL_REG: {
5292 process_call (ctx, bb, &builder, ins);
5297 LLVMValueRef indexes [2];
5298 MonoJumpInfo *tmp_ji, *ji;
5299 LLVMValueRef got_entry_addr;
5303 * FIXME: Can't allocate from the cfg mempool since that is freed if
5304 * the LLVM compile fails.
5306 tmp_ji = g_new0 (MonoJumpInfo, 1);
5307 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5308 tmp_ji->data.target = ins->inst_p0;
5310 ji = mono_aot_patch_info_dup (tmp_ji);
5313 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5314 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5317 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5318 * resolvable at runtime using dlsym ().
5321 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5326 ji->next = cfg->patch_info;
5327 cfg->patch_info = ji;
5329 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5330 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5331 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5332 if (!mono_aot_is_shared_got_offset (got_offset)) {
5333 //mono_print_ji (ji);
5335 ctx->has_got_access = TRUE;
5338 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5339 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5340 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5342 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5343 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5345 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5346 if (!cfg->llvm_only)
5347 set_invariant_load_flag (values [ins->dreg]);
5350 case OP_NOT_REACHED:
5351 LLVMBuildUnreachable (builder);
5352 has_terminator = TRUE;
5353 g_assert (bb->block_num < cfg->max_block_num);
5354 ctx->unreachable [bb->block_num] = TRUE;
5355 /* Might have instructions after this */
5357 MonoInst *next = ins->next;
5359 * FIXME: If later code uses the regs defined by these instructions,
5360 * compilation will fail.
5362 MONO_DELETE_INS (bb, next);
5366 MonoInst *var = ins->inst_i0;
5368 if (var->opcode == OP_VTARG_ADDR) {
5369 /* The variable contains the vtype address */
5370 values [ins->dreg] = values [var->dreg];
5371 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5372 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5374 values [ins->dreg] = addresses [var->dreg];
5379 LLVMValueRef args [1];
5381 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5382 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5386 LLVMValueRef args [1];
5388 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5389 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5393 LLVMValueRef args [1];
5395 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5396 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5400 LLVMValueRef args [1];
5402 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5403 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5417 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5418 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5420 switch (ins->opcode) {
5423 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5427 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5431 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5435 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5438 g_assert_not_reached ();
5441 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5446 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5447 * hack is necessary (for now).
5450 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5452 #define ARM64_ATOMIC_FENCE_FIX
5455 case OP_ATOMIC_EXCHANGE_I4:
5456 case OP_ATOMIC_EXCHANGE_I8: {
5457 LLVMValueRef args [2];
5460 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5461 t = LLVMInt32Type ();
5463 t = LLVMInt64Type ();
5465 g_assert (ins->inst_offset == 0);
5467 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5468 args [1] = convert (ctx, rhs, t);
5470 ARM64_ATOMIC_FENCE_FIX;
5471 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5472 ARM64_ATOMIC_FENCE_FIX;
5475 case OP_ATOMIC_ADD_I4:
5476 case OP_ATOMIC_ADD_I8: {
5477 LLVMValueRef args [2];
5480 if (ins->opcode == OP_ATOMIC_ADD_I4)
5481 t = LLVMInt32Type ();
5483 t = LLVMInt64Type ();
5485 g_assert (ins->inst_offset == 0);
5487 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5488 args [1] = convert (ctx, rhs, t);
5489 ARM64_ATOMIC_FENCE_FIX;
5490 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5491 ARM64_ATOMIC_FENCE_FIX;
5494 case OP_ATOMIC_CAS_I4:
5495 case OP_ATOMIC_CAS_I8: {
5496 LLVMValueRef args [3], val;
5499 if (ins->opcode == OP_ATOMIC_CAS_I4)
5500 t = LLVMInt32Type ();
5502 t = LLVMInt64Type ();
5504 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5506 args [1] = convert (ctx, values [ins->sreg3], t);
5508 args [2] = convert (ctx, values [ins->sreg2], t);
5509 ARM64_ATOMIC_FENCE_FIX;
5510 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5511 ARM64_ATOMIC_FENCE_FIX;
5512 /* cmpxchg returns a pair */
5513 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5516 case OP_MEMORY_BARRIER: {
5517 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5520 case OP_ATOMIC_LOAD_I1:
5521 case OP_ATOMIC_LOAD_I2:
5522 case OP_ATOMIC_LOAD_I4:
5523 case OP_ATOMIC_LOAD_I8:
5524 case OP_ATOMIC_LOAD_U1:
5525 case OP_ATOMIC_LOAD_U2:
5526 case OP_ATOMIC_LOAD_U4:
5527 case OP_ATOMIC_LOAD_U8:
5528 case OP_ATOMIC_LOAD_R4:
5529 case OP_ATOMIC_LOAD_R8: {
5530 #if LLVM_API_VERSION > 100
5532 gboolean sext, zext;
5534 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5535 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5536 LLVMValueRef index, addr;
5538 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5543 if (ins->inst_offset != 0) {
5544 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5545 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5550 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5552 ARM64_ATOMIC_FENCE_FIX;
5553 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5554 ARM64_ATOMIC_FENCE_FIX;
5557 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5559 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5562 set_failure (ctx, "atomic mono.load intrinsic");
5566 case OP_ATOMIC_STORE_I1:
5567 case OP_ATOMIC_STORE_I2:
5568 case OP_ATOMIC_STORE_I4:
5569 case OP_ATOMIC_STORE_I8:
5570 case OP_ATOMIC_STORE_U1:
5571 case OP_ATOMIC_STORE_U2:
5572 case OP_ATOMIC_STORE_U4:
5573 case OP_ATOMIC_STORE_U8:
5574 case OP_ATOMIC_STORE_R4:
5575 case OP_ATOMIC_STORE_R8: {
5577 gboolean sext, zext;
5579 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5580 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5581 LLVMValueRef index, addr, value, base;
5583 #if LLVM_API_VERSION < 100
5584 if (!cfg->llvm_only) {
5585 set_failure (ctx, "atomic mono.store intrinsic");
5590 if (!values [ins->inst_destbasereg]) {
5591 set_failure (ctx, "inst_destbasereg");
5595 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5597 base = values [ins->inst_destbasereg];
5598 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5599 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5600 value = convert (ctx, values [ins->sreg1], t);
5602 ARM64_ATOMIC_FENCE_FIX;
5603 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5604 ARM64_ATOMIC_FENCE_FIX;
5607 case OP_RELAXED_NOP: {
5608 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5609 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5616 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5618 // 257 == FS segment register
5619 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5621 // 256 == GS segment register
5622 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5625 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5626 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5627 /* See mono_amd64_emit_tls_get () */
5628 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5630 // 256 == GS segment register
5631 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5632 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5634 set_failure (ctx, "opcode tls-get");
5640 case OP_GC_SAFE_POINT: {
5641 LLVMValueRef val, cmp, callee;
5642 LLVMBasicBlockRef poll_bb, cont_bb;
5643 static LLVMTypeRef sig;
5644 const char *icall_name = "mono_threads_state_poll";
5647 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5651 * mono_threads_state_poll ();
5652 * FIXME: Use a preserveall wrapper
5654 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5655 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5656 poll_bb = gen_bb (ctx, "POLL_BB");
5657 cont_bb = gen_bb (ctx, "CONT_BB");
5658 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5660 ctx->builder = builder = create_builder (ctx);
5661 LLVMPositionBuilderAtEnd (builder, poll_bb);
5663 if (ctx->cfg->compile_aot) {
5664 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5666 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5667 callee = emit_jit_callee (ctx, icall_name, sig, target);
5669 LLVMBuildCall (builder, callee, NULL, 0, "");
5670 LLVMBuildBr (builder, cont_bb);
5672 ctx->builder = builder = create_builder (ctx);
5673 LLVMPositionBuilderAtEnd (builder, cont_bb);
5674 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5682 case OP_IADD_OVF_UN:
5684 case OP_ISUB_OVF_UN:
5686 case OP_IMUL_OVF_UN:
5688 case OP_LADD_OVF_UN:
5690 case OP_LSUB_OVF_UN:
5692 case OP_LMUL_OVF_UN:
5694 LLVMValueRef args [2], val, ovf, func;
5696 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5697 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5698 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5700 val = LLVMBuildCall (builder, func, args, 2, "");
5701 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5702 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5703 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5706 builder = ctx->builder;
5712 * We currently model them using arrays. Promotion to local vregs is
5713 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5714 * so we always have an entry in cfg->varinfo for them.
5715 * FIXME: Is this needed ?
5718 MonoClass *klass = ins->klass;
5719 LLVMValueRef args [5];
5723 set_failure (ctx, "!klass");
5727 if (!addresses [ins->dreg])
5728 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5729 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5730 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5731 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5733 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5734 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5735 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5738 case OP_DUMMY_VZERO:
5741 case OP_STOREV_MEMBASE:
5742 case OP_LOADV_MEMBASE:
5744 MonoClass *klass = ins->klass;
5745 LLVMValueRef src = NULL, dst, args [5];
5746 gboolean done = FALSE;
5750 set_failure (ctx, "!klass");
5754 if (mini_is_gsharedvt_klass (klass)) {
5756 set_failure (ctx, "gsharedvt");
5760 switch (ins->opcode) {
5761 case OP_STOREV_MEMBASE:
5762 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5763 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5764 /* Decomposed earlier */
5765 g_assert_not_reached ();
5768 if (!addresses [ins->sreg1]) {
5770 g_assert (values [ins->sreg1]);
5771 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));
5772 LLVMBuildStore (builder, values [ins->sreg1], dst);
5775 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5776 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5779 case OP_LOADV_MEMBASE:
5780 if (!addresses [ins->dreg])
5781 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5782 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5783 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5786 if (!addresses [ins->sreg1])
5787 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5788 if (!addresses [ins->dreg])
5789 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5790 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5791 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5794 g_assert_not_reached ();
5804 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5805 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5807 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5808 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5809 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5812 case OP_LLVM_OUTARG_VT: {
5813 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5814 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5816 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5817 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5819 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5820 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5822 g_assert (addresses [ins->sreg1]);
5823 addresses [ins->dreg] = addresses [ins->sreg1];
5825 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5826 if (!addresses [ins->sreg1]) {
5827 addresses [ins->sreg1] = build_alloca (ctx, t);
5828 g_assert (values [ins->sreg1]);
5830 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5831 addresses [ins->dreg] = addresses [ins->sreg1];
5833 if (!addresses [ins->sreg1]) {
5834 addresses [ins->sreg1] = build_alloca (ctx, t);
5835 g_assert (values [ins->sreg1]);
5836 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5838 addresses [ins->dreg] = addresses [ins->sreg1];
5842 case OP_OBJC_GET_SELECTOR: {
5843 const char *name = (const char*)ins->inst_p0;
5846 if (!ctx->module->objc_selector_to_var) {
5847 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5849 LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
5850 int32_t objc_imageinfo [] = { 0, 16 };
5851 LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
5852 LLVMSetLinkage (info_var, LLVMPrivateLinkage);
5853 LLVMSetExternallyInitialized (info_var, TRUE);
5854 LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
5855 LLVMSetAlignment (info_var, sizeof (mgreg_t));
5856 mark_as_used (ctx->module, info_var);
5859 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5861 LLVMValueRef indexes [16];
5863 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5864 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5865 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5866 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5867 mark_as_used (ctx->module, name_var);
5869 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5871 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5872 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5873 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5874 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5875 LLVMSetExternallyInitialized (ref_var, TRUE);
5876 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5877 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5878 mark_as_used (ctx->module, ref_var);
5880 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5884 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5891 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5893 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5896 case OP_LOADX_MEMBASE: {
5897 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5900 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5901 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5904 case OP_STOREX_MEMBASE: {
5905 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5908 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5909 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5916 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5920 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5926 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5930 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5934 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5938 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5941 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5944 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5947 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5951 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5962 LLVMValueRef v = NULL;
5964 switch (ins->opcode) {
5969 t = LLVMVectorType (LLVMInt32Type (), 4);
5970 rt = LLVMVectorType (LLVMFloatType (), 4);
5976 t = LLVMVectorType (LLVMInt64Type (), 2);
5977 rt = LLVMVectorType (LLVMDoubleType (), 2);
5980 t = LLVMInt32Type ();
5981 rt = LLVMInt32Type ();
5982 g_assert_not_reached ();
5985 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5986 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5987 switch (ins->opcode) {
5990 v = LLVMBuildAnd (builder, lhs, rhs, "");
5994 v = LLVMBuildOr (builder, lhs, rhs, "");
5998 v = LLVMBuildXor (builder, lhs, rhs, "");
6002 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
6005 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
6011 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
6012 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6018 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6019 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6023 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6024 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6041 case OP_PADDB_SAT_UN:
6042 case OP_PADDW_SAT_UN:
6043 case OP_PSUBB_SAT_UN:
6044 case OP_PSUBW_SAT_UN:
6052 case OP_PMULW_HIGH_UN: {
6053 LLVMValueRef args [2];
6058 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6065 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6069 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6077 case OP_EXTRACTX_U2:
6079 case OP_EXTRACT_U1: {
6081 gboolean zext = FALSE;
6083 t = simd_op_to_llvm_type (ins->opcode);
6085 switch (ins->opcode) {
6093 case OP_EXTRACTX_U2:
6098 t = LLVMInt32Type ();
6099 g_assert_not_reached ();
6102 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6103 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6105 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6114 case OP_EXPAND_R8: {
6115 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6116 LLVMValueRef mask [16], v;
6119 for (i = 0; i < 16; ++i)
6120 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6122 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6124 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6125 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6130 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6133 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6136 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6139 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6142 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6145 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6148 #if LLVM_API_VERSION > 100
6150 LLVMValueRef indexes [16];
6152 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6153 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6154 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6155 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6156 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6160 LLVMValueRef indexes [16];
6162 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6163 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6164 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6165 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6166 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6170 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6174 #if LLVM_API_VERSION <= 100
6184 case OP_EXTRACT_MASK:
6191 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6193 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6198 LLVMRealPredicate op;
6200 switch (ins->inst_c0) {
6210 case SIMD_COMP_UNORD:
6226 g_assert_not_reached ();
6229 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6230 if (ins->opcode == OP_COMPPD)
6231 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6233 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6237 /* This is only used for implementing shifts by non-immediate */
6238 values [ins->dreg] = lhs;
6249 LLVMValueRef args [3];
6252 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6254 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6265 case OP_PSHLQ_REG: {
6266 LLVMValueRef args [3];
6269 args [1] = values [ins->sreg2];
6271 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6278 case OP_PSHUFLEW_LOW:
6279 case OP_PSHUFLEW_HIGH: {
6281 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6282 int i, mask_size = 0;
6283 int imask = ins->inst_c0;
6285 /* Convert the x86 shuffle mask to LLVM's */
6286 switch (ins->opcode) {
6289 mask [0] = ((imask >> 0) & 3);
6290 mask [1] = ((imask >> 2) & 3);
6291 mask [2] = ((imask >> 4) & 3) + 4;
6292 mask [3] = ((imask >> 6) & 3) + 4;
6293 v1 = values [ins->sreg1];
6294 v2 = values [ins->sreg2];
6298 mask [0] = ((imask >> 0) & 1);
6299 mask [1] = ((imask >> 1) & 1) + 2;
6300 v1 = values [ins->sreg1];
6301 v2 = values [ins->sreg2];
6303 case OP_PSHUFLEW_LOW:
6305 mask [0] = ((imask >> 0) & 3);
6306 mask [1] = ((imask >> 2) & 3);
6307 mask [2] = ((imask >> 4) & 3);
6308 mask [3] = ((imask >> 6) & 3);
6313 v1 = values [ins->sreg1];
6314 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6316 case OP_PSHUFLEW_HIGH:
6322 mask [4] = 4 + ((imask >> 0) & 3);
6323 mask [5] = 4 + ((imask >> 2) & 3);
6324 mask [6] = 4 + ((imask >> 4) & 3);
6325 mask [7] = 4 + ((imask >> 6) & 3);
6326 v1 = values [ins->sreg1];
6327 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6331 mask [0] = ((imask >> 0) & 3);
6332 mask [1] = ((imask >> 2) & 3);
6333 mask [2] = ((imask >> 4) & 3);
6334 mask [3] = ((imask >> 6) & 3);
6335 v1 = values [ins->sreg1];
6336 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6339 g_assert_not_reached ();
6341 for (i = 0; i < mask_size; ++i)
6342 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6344 values [ins->dreg] =
6345 LLVMBuildShuffleVector (builder, v1, v2,
6346 LLVMConstVector (mask_values, mask_size), dname);
6350 case OP_UNPACK_LOWB:
6351 case OP_UNPACK_LOWW:
6352 case OP_UNPACK_LOWD:
6353 case OP_UNPACK_LOWQ:
6354 case OP_UNPACK_LOWPS:
6355 case OP_UNPACK_LOWPD:
6356 case OP_UNPACK_HIGHB:
6357 case OP_UNPACK_HIGHW:
6358 case OP_UNPACK_HIGHD:
6359 case OP_UNPACK_HIGHQ:
6360 case OP_UNPACK_HIGHPS:
6361 case OP_UNPACK_HIGHPD: {
6363 LLVMValueRef mask_values [16];
6364 int i, mask_size = 0;
6365 gboolean low = FALSE;
6367 switch (ins->opcode) {
6368 case OP_UNPACK_LOWB:
6372 case OP_UNPACK_LOWW:
6376 case OP_UNPACK_LOWD:
6377 case OP_UNPACK_LOWPS:
6381 case OP_UNPACK_LOWQ:
6382 case OP_UNPACK_LOWPD:
6386 case OP_UNPACK_HIGHB:
6389 case OP_UNPACK_HIGHW:
6392 case OP_UNPACK_HIGHD:
6393 case OP_UNPACK_HIGHPS:
6396 case OP_UNPACK_HIGHQ:
6397 case OP_UNPACK_HIGHPD:
6401 g_assert_not_reached ();
6405 for (i = 0; i < (mask_size / 2); ++i) {
6407 mask [(i * 2) + 1] = mask_size + i;
6410 for (i = 0; i < (mask_size / 2); ++i) {
6411 mask [(i * 2)] = (mask_size / 2) + i;
6412 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6416 for (i = 0; i < mask_size; ++i)
6417 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6419 values [ins->dreg] =
6420 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6421 LLVMConstVector (mask_values, mask_size), dname);
6426 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6427 LLVMValueRef v, val;
6429 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6430 val = LLVMConstNull (t);
6431 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6432 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6434 values [ins->dreg] = val;
6438 case OP_DUPPS_HIGH: {
6439 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6440 LLVMValueRef v1, v2, val;
6443 if (ins->opcode == OP_DUPPS_LOW) {
6444 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6445 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6447 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6448 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6450 val = LLVMConstNull (t);
6451 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6452 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6453 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6454 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6456 values [ins->dreg] = val;
6461 LLVMValueRef args [3];
6465 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6466 #if LLVM_API_VERSION >= 500
6467 args [2] = LLVMConstInt (LLVMInt8Type (), 0xf1, FALSE);
6469 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6472 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6482 * EXCEPTION HANDLING
6484 case OP_IMPLICIT_EXCEPTION:
6485 /* This marks a place where an implicit exception can happen */
6486 if (bb->region != -1)
6487 set_failure (ctx, "implicit-exception");
6491 gboolean rethrow = (ins->opcode == OP_RETHROW);
6492 if (ctx->llvm_only) {
6493 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6494 has_terminator = TRUE;
6495 ctx->unreachable [bb->block_num] = TRUE;
6497 emit_throw (ctx, bb, rethrow, lhs);
6498 builder = ctx->builder;
6502 case OP_CALL_HANDLER: {
6504 * We don't 'call' handlers, but instead simply branch to them.
6505 * The code generated by ENDFINALLY will branch back to us.
6507 LLVMBasicBlockRef noex_bb;
6509 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6511 bb_list = info->call_handler_return_bbs;
6514 * Set the indicator variable for the finally clause.
6516 lhs = info->finally_ind;
6518 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6520 /* Branch to the finally clause */
6521 LLVMBuildBr (builder, info->call_handler_target_bb);
6523 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6524 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6526 builder = ctx->builder = create_builder (ctx);
6527 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6529 bblocks [bb->block_num].end_bblock = noex_bb;
6532 case OP_START_HANDLER: {
6535 case OP_ENDFINALLY: {
6536 LLVMBasicBlockRef resume_bb;
6537 MonoBasicBlock *handler_bb;
6538 LLVMValueRef val, switch_ins, callee;
6541 gboolean is_fault = MONO_REGION_FLAGS (bb->region) == MONO_EXCEPTION_CLAUSE_FAULT;
6544 * Fault clauses are like finally clauses, but they are only called if an exception is thrown.
6547 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6548 g_assert (handler_bb);
6549 info = &bblocks [handler_bb->block_num];
6550 lhs = info->finally_ind;
6553 bb_list = info->call_handler_return_bbs;
6555 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6557 /* Load the finally variable */
6558 val = LLVMBuildLoad (builder, lhs, "");
6560 /* Reset the variable */
6561 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6563 /* Branch to either resume_bb, or to the bblocks in bb_list */
6564 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6566 * The other targets are added at the end to handle OP_CALL_HANDLER
6567 * opcodes processed later.
6569 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6571 builder = ctx->builder = create_builder (ctx);
6572 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6575 if (ctx->llvm_only) {
6576 emit_resume_eh (ctx, bb);
6578 if (ctx->cfg->compile_aot) {
6579 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6581 #if LLVM_API_VERSION > 100
6582 MonoJitICallInfo *info;
6584 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6586 gpointer target = (void*)info->func;
6587 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6588 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6590 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6593 LLVMBuildCall (builder, callee, NULL, 0, "");
6594 LLVMBuildUnreachable (builder);
6597 has_terminator = TRUE;
6600 case OP_IL_SEQ_POINT:
6605 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6606 set_failure (ctx, reason);
6614 /* Convert the value to the type required by phi nodes */
6615 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6616 if (ctx->is_vphi [ins->dreg])
6618 values [ins->dreg] = addresses [ins->dreg];
6620 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6623 /* Add stores for volatile variables */
6624 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6625 emit_volatile_store (ctx, ins->dreg);
6631 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6632 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6635 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6636 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6637 LLVMBuildRetVoid (builder);
6640 if (bb == cfg->bb_entry)
6641 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6645 * mono_llvm_check_method_supported:
6647 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6648 * compiling a method twice.
6651 mono_llvm_check_method_supported (MonoCompile *cfg)
6658 if (cfg->method->save_lmf) {
6659 cfg->exception_message = g_strdup ("lmf");
6660 cfg->disable_llvm = TRUE;
6662 if (cfg->disable_llvm)
6666 * Nested clauses where one of the clauses is a finally clause is
6667 * not supported, because LLVM can't figure out the control flow,
6668 * probably because we resume exception handling by calling our
6669 * own function instead of using the 'resume' llvm instruction.
6671 for (i = 0; i < cfg->header->num_clauses; ++i) {
6672 for (j = 0; j < cfg->header->num_clauses; ++j) {
6673 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6674 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6676 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6677 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6678 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6679 cfg->exception_message = g_strdup ("nested clauses");
6680 cfg->disable_llvm = TRUE;
6685 if (cfg->disable_llvm)
6689 if (cfg->method->dynamic) {
6690 cfg->exception_message = g_strdup ("dynamic.");
6691 cfg->disable_llvm = TRUE;
6693 if (cfg->disable_llvm)
6697 static LLVMCallInfo*
6698 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6700 LLVMCallInfo *linfo;
6703 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6707 * Gsharedvt methods have the following calling convention:
6708 * - all arguments are passed by ref, even non generic ones
6709 * - the return value is returned by ref too, using a vret
6710 * argument passed after 'this'.
6712 n = sig->param_count + sig->hasthis;
6713 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6717 linfo->args [pindex ++].storage = LLVMArgNormal;
6719 if (sig->ret->type != MONO_TYPE_VOID) {
6720 if (mini_is_gsharedvt_variable_type (sig->ret))
6721 linfo->ret.storage = LLVMArgGsharedvtVariable;
6722 else if (mini_type_is_vtype (sig->ret))
6723 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6725 linfo->ret.storage = LLVMArgGsharedvtFixed;
6726 linfo->vret_arg_index = pindex;
6728 linfo->ret.storage = LLVMArgNone;
6731 for (i = 0; i < sig->param_count; ++i) {
6732 if (sig->params [i]->byref)
6733 linfo->args [pindex].storage = LLVMArgNormal;
6734 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6735 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6736 else if (mini_type_is_vtype (sig->params [i]))
6737 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6739 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6740 linfo->args [pindex].type = sig->params [i];
6747 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6748 for (i = 0; i < sig->param_count; ++i)
6749 linfo->args [i + sig->hasthis].type = sig->params [i];
6755 emit_method_inner (EmitContext *ctx);
6758 free_ctx (EmitContext *ctx)
6762 g_free (ctx->values);
6763 g_free (ctx->addresses);
6764 g_free (ctx->vreg_types);
6765 g_free (ctx->is_vphi);
6766 g_free (ctx->vreg_cli_types);
6767 g_free (ctx->is_dead);
6768 g_free (ctx->unreachable);
6769 g_ptr_array_free (ctx->phi_values, TRUE);
6770 g_free (ctx->bblocks);
6771 g_hash_table_destroy (ctx->region_to_handler);
6772 g_hash_table_destroy (ctx->clause_to_handler);
6773 g_hash_table_destroy (ctx->jit_callees);
6775 GHashTableIter iter;
6776 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6777 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6780 g_hash_table_destroy (ctx->method_to_callers);
6782 g_free (ctx->method_name);
6783 g_ptr_array_free (ctx->bblock_list, TRUE);
6785 for (l = ctx->builders; l; l = l->next) {
6786 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6787 LLVMDisposeBuilder (builder);
6794 * mono_llvm_emit_method:
6796 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6799 mono_llvm_emit_method (MonoCompile *cfg)
6803 gboolean is_linkonce = FALSE;
6806 /* The code below might acquire the loader lock, so use it for global locking */
6807 mono_loader_lock ();
6809 /* Used to communicate with the callbacks */
6810 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6812 ctx = g_new0 (EmitContext, 1);
6814 ctx->mempool = cfg->mempool;
6817 * This maps vregs to the LLVM instruction defining them
6819 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6821 * This maps vregs for volatile variables to the LLVM instruction defining their
6824 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6825 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6826 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6827 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6828 ctx->phi_values = g_ptr_array_sized_new (256);
6830 * This signals whenever the vreg was defined by a phi node with no input vars
6831 * (i.e. all its input bblocks end with NOT_REACHABLE).
6833 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6834 /* Whenever the bblock is unreachable */
6835 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6836 ctx->bblock_list = g_ptr_array_sized_new (256);
6838 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6839 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6840 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6841 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6842 if (cfg->compile_aot) {
6843 ctx->module = &aot_module;
6847 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6848 * linkage for them. This requires the following:
6849 * - the method needs to have a unique mangled name
6850 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6852 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6854 method_name = mono_aot_get_mangled_method_name (cfg->method);
6856 is_linkonce = FALSE;
6859 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6861 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6865 method_name = mono_aot_get_method_name (cfg);
6866 cfg->llvm_method_name = g_strdup (method_name);
6868 init_jit_module (cfg->domain);
6869 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6870 method_name = mono_method_full_name (cfg->method, TRUE);
6872 ctx->method_name = method_name;
6873 ctx->is_linkonce = is_linkonce;
6875 #if LLVM_API_VERSION > 100
6876 if (cfg->compile_aot)
6877 ctx->lmodule = ctx->module->lmodule;
6879 ctx->lmodule = LLVMModuleCreateWithName (g_strdup_printf ("jit-module-%s", cfg->method->name));
6881 ctx->lmodule = ctx->module->lmodule;
6883 ctx->llvm_only = ctx->module->llvm_only;
6885 emit_method_inner (ctx);
6887 if (!ctx_ok (ctx)) {
6889 /* Need to add unused phi nodes as they can be referenced by other values */
6890 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6891 LLVMBuilderRef builder;
6893 builder = create_builder (ctx);
6894 LLVMPositionBuilderAtEnd (builder, phi_bb);
6896 for (i = 0; i < ctx->phi_values->len; ++i) {
6897 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6898 if (LLVMGetInstructionParent (v) == NULL)
6899 LLVMInsertIntoBuilder (builder, v);
6902 LLVMDeleteFunction (ctx->lmethod);
6908 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6910 mono_loader_unlock ();
6914 emit_method_inner (EmitContext *ctx)
6916 MonoCompile *cfg = ctx->cfg;
6917 MonoMethodSignature *sig;
6919 LLVMTypeRef method_type;
6920 LLVMValueRef method = NULL;
6921 LLVMValueRef *values = ctx->values;
6922 int i, max_block_num, bb_index;
6923 gboolean last = FALSE;
6924 LLVMCallInfo *linfo;
6925 LLVMModuleRef lmodule = ctx->lmodule;
6927 GPtrArray *bblock_list = ctx->bblock_list;
6928 MonoMethodHeader *header;
6929 MonoExceptionClause *clause;
6932 if (cfg->gsharedvt && !cfg->llvm_only) {
6933 set_failure (ctx, "gsharedvt");
6939 static int count = 0;
6942 char *llvm_count_str = g_getenv ("LLVM_COUNT");
6943 if (llvm_count_str) {
6944 int lcount = atoi (llvm_count_str);
6945 g_free (llvm_count_str);
6946 if (count == lcount) {
6947 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6951 if (count > lcount) {
6952 set_failure (ctx, "count");
6959 sig = mono_method_signature (cfg->method);
6962 linfo = get_llvm_call_info (cfg, sig);
6968 linfo->rgctx_arg = TRUE;
6969 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6973 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6974 ctx->lmethod = method;
6976 if (!cfg->llvm_only)
6977 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6978 LLVMSetLinkage (method, LLVMPrivateLinkage);
6980 mono_llvm_add_func_attr (method, LLVM_ATTR_UW_TABLE);
6982 if (cfg->compile_aot) {
6983 LLVMSetLinkage (method, LLVMInternalLinkage);
6984 if (ctx->module->external_symbols) {
6985 LLVMSetLinkage (method, LLVMExternalLinkage);
6986 LLVMSetVisibility (method, LLVMHiddenVisibility);
6988 if (ctx->is_linkonce) {
6989 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6990 LLVMSetVisibility (method, LLVMDefaultVisibility);
6993 #if LLVM_API_VERSION > 100
6994 LLVMSetLinkage (method, LLVMExternalLinkage);
6996 LLVMSetLinkage (method, LLVMPrivateLinkage);
7000 if (cfg->method->save_lmf && !cfg->llvm_only) {
7001 set_failure (ctx, "lmf");
7005 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
7006 set_failure (ctx, "pinvoke signature");
7010 header = cfg->header;
7011 for (i = 0; i < header->num_clauses; ++i) {
7012 clause = &header->clauses [i];
7013 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_FAULT && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
7014 set_failure (ctx, "non-finally/catch/fault clause.");
7018 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7019 /* We can't handle inlined methods with clauses */
7020 mono_llvm_add_func_attr (method, LLVM_ATTR_NO_INLINE);
7022 if (linfo->rgctx_arg) {
7023 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7024 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7026 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7027 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7028 * CC_X86_64_Mono in X86CallingConv.td.
7030 if (!ctx->llvm_only)
7031 mono_llvm_add_param_attr (ctx->rgctx_arg, LLVM_ATTR_IN_REG);
7032 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7034 ctx->rgctx_arg_pindex = -1;
7036 if (cfg->vret_addr) {
7037 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7038 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7039 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7040 mono_llvm_add_param_attr (LLVMGetParam (method, linfo->vret_arg_pindex), LLVM_ATTR_STRUCT_RET);
7041 mono_llvm_add_param_attr (LLVMGetParam (method, linfo->vret_arg_pindex), LLVM_ATTR_NO_ALIAS);
7046 ctx->this_arg_pindex = linfo->this_arg_pindex;
7047 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7048 values [cfg->args [0]->dreg] = ctx->this_arg;
7049 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7052 names = g_new (char *, sig->param_count);
7053 mono_method_get_param_names (cfg->method, (const char **) names);
7055 /* Set parameter names/attributes */
7056 for (i = 0; i < sig->param_count; ++i) {
7057 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7059 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7062 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7063 name = g_strdup_printf ("dummy_%d_%d", i, j);
7064 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7068 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7071 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7072 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7073 if (names [i] && names [i][0] != '\0')
7074 name = g_strdup_printf ("p_arg_%s", names [i]);
7076 name = g_strdup_printf ("p_arg_%d", i);
7078 if (names [i] && names [i][0] != '\0')
7079 name = g_strdup_printf ("arg_%s", names [i]);
7081 name = g_strdup_printf ("arg_%d", i);
7083 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7085 if (ainfo->storage == LLVMArgVtypeByVal)
7086 mono_llvm_add_param_attr (LLVMGetParam (method, pindex), LLVM_ATTR_BY_VAL);
7088 if (ainfo->storage == LLVMArgVtypeByRef) {
7090 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7095 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7096 ctx->minfo = mono_debug_lookup_method (cfg->method);
7097 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7101 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7102 max_block_num = MAX (max_block_num, bb->block_num);
7103 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7105 /* Add branches between non-consecutive bblocks */
7106 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7107 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7108 bb->next_bb != bb->last_ins->inst_false_bb) {
7110 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7111 inst->opcode = OP_BR;
7112 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7113 mono_bblock_add_inst (bb, inst);
7118 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7120 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7122 LLVMBuilderRef builder;
7124 char dname_buf[128];
7126 builder = create_builder (ctx);
7128 for (ins = bb->code; ins; ins = ins->next) {
7129 switch (ins->opcode) {
7134 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7139 if (ins->opcode == OP_VPHI) {
7140 /* Treat valuetype PHI nodes as operating on the address itself */
7141 g_assert (ins->klass);
7142 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7146 * Have to precreate these, as they can be referenced by
7147 * earlier instructions.
7149 sprintf (dname_buf, "t%d", ins->dreg);
7151 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7153 if (ins->opcode == OP_VPHI)
7154 ctx->addresses [ins->dreg] = values [ins->dreg];
7156 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7159 * Set the expected type of the incoming arguments since these have
7160 * to have the same type.
7162 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7163 int sreg1 = ins->inst_phi_args [i + 1];
7166 if (ins->opcode == OP_VPHI)
7167 ctx->is_vphi [sreg1] = TRUE;
7168 ctx->vreg_types [sreg1] = phi_type;
7174 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7183 * Create an ordering for bblocks, use the depth first order first, then
7184 * put the exception handling bblocks last.
7186 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7187 bb = cfg->bblocks [bb_index];
7188 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7189 g_ptr_array_add (bblock_list, bb);
7190 bblocks [bb->block_num].added = TRUE;
7194 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7195 if (!bblocks [bb->block_num].added)
7196 g_ptr_array_add (bblock_list, bb);
7200 * Second pass: generate code.
7203 LLVMBuilderRef entry_builder = create_builder (ctx);
7204 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7205 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7206 emit_entry_bb (ctx, entry_builder);
7208 // Make landing pads first
7209 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7211 if (ctx->llvm_only) {
7212 size_t group_index = 0;
7213 while (group_index < cfg->header->num_clauses) {
7215 size_t cursor = group_index;
7216 while (cursor < cfg->header->num_clauses &&
7217 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7218 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7223 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7224 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7225 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7227 group_index = cursor;
7231 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7232 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7234 // Prune unreachable mono BBs.
7235 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7238 process_bb (ctx, bb);
7242 g_hash_table_destroy (ctx->exc_meta);
7244 mono_memory_barrier ();
7246 /* Add incoming phi values */
7247 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7248 GSList *l, *ins_list;
7250 ins_list = bblocks [bb->block_num].phi_nodes;
7252 for (l = ins_list; l; l = l->next) {
7253 PhiNode *node = (PhiNode*)l->data;
7254 MonoInst *phi = node->phi;
7255 int sreg1 = node->sreg;
7256 LLVMBasicBlockRef in_bb;
7261 in_bb = get_end_bb (ctx, node->in_bb);
7263 if (ctx->unreachable [node->in_bb->block_num])
7266 if (!values [sreg1]) {
7267 /* Can happen with values in EH clauses */
7268 set_failure (ctx, "incoming phi sreg1");
7272 if (phi->opcode == OP_VPHI) {
7273 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7274 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7276 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7277 set_failure (ctx, "incoming phi arg type mismatch");
7280 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7281 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7286 /* Nullify empty phi instructions */
7287 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7288 GSList *l, *ins_list;
7290 ins_list = bblocks [bb->block_num].phi_nodes;
7292 for (l = ins_list; l; l = l->next) {
7293 PhiNode *node = (PhiNode*)l->data;
7294 MonoInst *phi = node->phi;
7295 LLVMValueRef phi_ins = values [phi->dreg];
7298 /* Already removed */
7301 if (LLVMCountIncoming (phi_ins) == 0) {
7302 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7303 LLVMInstructionEraseFromParent (phi_ins);
7304 values [phi->dreg] = NULL;
7309 /* Create the SWITCH statements for ENDFINALLY instructions */
7310 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7311 BBInfo *info = &bblocks [bb->block_num];
7313 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7314 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7315 GSList *bb_list = info->call_handler_return_bbs;
7317 GSList *bb_list_iter;
7319 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7320 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7326 /* Initialize the method if needed */
7327 if (cfg->compile_aot && ctx->llvm_only) {
7328 // FIXME: Add more shared got entries
7329 ctx->builder = create_builder (ctx);
7330 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7332 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7334 // FIXME: beforefieldinit
7336 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7337 * in load_method ().
7339 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7341 * linkonce methods shouldn't have initialization,
7342 * because they might belong to assemblies which
7343 * haven't been loaded yet.
7345 g_assert (!ctx->is_linkonce);
7346 emit_init_method (ctx);
7348 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7352 if (cfg->llvm_only) {
7353 GHashTableIter iter;
7355 GSList *callers, *l, *l2;
7358 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7359 * We can't do this earlier, as it contains llvm instructions which can be
7360 * freed if compilation fails.
7361 * FIXME: Get rid of this when all methods can be llvm compiled.
7363 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7364 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7365 for (l = callers; l; l = l->next) {
7366 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7367 l2 = g_slist_prepend (l2, l->data);
7368 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7373 if (cfg->verbose_level > 1)
7374 mono_llvm_dump_value (method);
7376 if (cfg->compile_aot && !cfg->llvm_only)
7377 mark_as_used (ctx->module, method);
7379 if (!cfg->llvm_only) {
7380 LLVMValueRef md_args [16];
7381 LLVMValueRef md_node;
7384 if (cfg->compile_aot)
7385 method_index = mono_aot_get_method_index (cfg->orig_method);
7388 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7389 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7390 md_node = LLVMMDNode (md_args, 2);
7391 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7392 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7395 if (cfg->compile_aot) {
7396 /* Don't generate native code, keep the LLVM IR */
7397 if (cfg->verbose_level)
7398 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7400 #if LLVM_API_VERSION < 100
7401 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7402 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7403 g_assert (err == 0);
7406 //LLVMVerifyFunction(method, 0);
7407 #if LLVM_API_VERSION > 100
7408 MonoDomain *domain = mono_domain_get ();
7409 MonoJitDomainInfo *domain_info;
7410 int nvars = g_hash_table_size (ctx->jit_callees);
7411 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7412 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7413 GHashTableIter iter;
7419 * Compute the addresses of the LLVM globals pointing to the
7420 * methods called by the current method. Pass it to the trampoline
7421 * code so it can update them after their corresponding method was
7424 g_hash_table_iter_init (&iter, ctx->jit_callees);
7426 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7427 callee_vars [i ++] = var;
7429 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7431 decode_llvm_eh_info (ctx, eh_frame);
7433 mono_domain_lock (domain);
7434 domain_info = domain_jit_info (domain);
7435 if (!domain_info->llvm_jit_callees)
7436 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7437 g_hash_table_iter_init (&iter, ctx->jit_callees);
7439 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7440 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7441 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7442 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7445 mono_domain_unlock (domain);
7447 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7449 if (cfg->verbose_level > 1)
7450 mono_llvm_dump_value (ctx->lmethod);
7452 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7454 /* Set by emit_cb */
7455 g_assert (cfg->code_len);
7459 if (ctx->module->method_to_lmethod)
7460 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7461 if (ctx->module->idx_to_lmethod)
7462 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7464 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7465 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7469 * mono_llvm_create_vars:
7471 * Same as mono_arch_create_vars () for LLVM.
7474 mono_llvm_create_vars (MonoCompile *cfg)
7476 MonoMethodSignature *sig;
7478 sig = mono_method_signature (cfg->method);
7479 if (cfg->gsharedvt && cfg->llvm_only) {
7480 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7481 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7482 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7483 printf ("vret_addr = ");
7484 mono_print_ins (cfg->vret_addr);
7488 mono_arch_create_vars (cfg);
7493 * mono_llvm_emit_call:
7495 * Same as mono_arch_emit_call () for LLVM.
7498 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7501 MonoMethodSignature *sig;
7502 int i, n, stack_size;
7507 sig = call->signature;
7508 n = sig->param_count + sig->hasthis;
7510 call->cinfo = get_llvm_call_info (cfg, sig);
7512 if (cfg->disable_llvm)
7515 if (sig->call_convention == MONO_CALL_VARARG) {
7516 cfg->exception_message = g_strdup ("varargs");
7517 cfg->disable_llvm = TRUE;
7520 for (i = 0; i < n; ++i) {
7523 ainfo = call->cinfo->args + i;
7525 in = call->args [i];
7527 /* Simply remember the arguments */
7528 switch (ainfo->storage) {
7529 case LLVMArgNormal: {
7530 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7533 opcode = mono_type_to_regmove (cfg, t);
7534 if (opcode == OP_FMOVE) {
7535 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7536 ins->dreg = mono_alloc_freg (cfg);
7537 } else if (opcode == OP_LMOVE) {
7538 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7539 ins->dreg = mono_alloc_lreg (cfg);
7540 } else if (opcode == OP_RMOVE) {
7541 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7542 ins->dreg = mono_alloc_freg (cfg);
7544 MONO_INST_NEW (cfg, ins, OP_MOVE);
7545 ins->dreg = mono_alloc_ireg (cfg);
7547 ins->sreg1 = in->dreg;
7550 case LLVMArgVtypeByVal:
7551 case LLVMArgVtypeByRef:
7552 case LLVMArgVtypeInReg:
7553 case LLVMArgVtypeAsScalar:
7554 case LLVMArgAsIArgs:
7555 case LLVMArgAsFpArgs:
7556 case LLVMArgGsharedvtVariable:
7557 case LLVMArgGsharedvtFixed:
7558 case LLVMArgGsharedvtFixedVtype:
7559 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7560 ins->dreg = mono_alloc_ireg (cfg);
7561 ins->sreg1 = in->dreg;
7562 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7563 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7564 ins->inst_vtype = ainfo->type;
7565 ins->klass = mono_class_from_mono_type (ainfo->type);
7568 cfg->exception_message = g_strdup ("ainfo->storage");
7569 cfg->disable_llvm = TRUE;
7573 if (!cfg->disable_llvm) {
7574 MONO_ADD_INS (cfg->cbb, ins);
7575 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7580 static unsigned char*
7581 alloc_cb (LLVMValueRef function, int size)
7585 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7589 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7591 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7596 emitted_cb (LLVMValueRef function, void *start, void *end)
7600 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7602 cfg->code_len = (guint8*)end - (guint8*)start;
7606 exception_cb (void *data)
7609 MonoJitExceptionInfo *ei;
7610 guint32 ei_len, i, j, nested_len, nindex;
7611 gpointer *type_info;
7612 int this_reg, this_offset;
7614 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7618 * data points to a DWARF FDE structure, convert it to our unwind format and
7620 * An alternative would be to save it directly, and modify our unwinder to work
7623 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);
7624 if (cfg->verbose_level > 1)
7625 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7627 /* Count nested clauses */
7629 for (i = 0; i < ei_len; ++i) {
7630 gint32 cindex1 = *(gint32*)type_info [i];
7631 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7633 for (j = 0; j < cfg->header->num_clauses; ++j) {
7635 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7637 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7643 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7644 cfg->llvm_ex_info_len = ei_len + nested_len;
7645 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7646 /* Fill the rest of the information from the type info */
7647 for (i = 0; i < ei_len; ++i) {
7648 gint32 clause_index = *(gint32*)type_info [i];
7649 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7651 cfg->llvm_ex_info [i].flags = clause->flags;
7652 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7653 cfg->llvm_ex_info [i].clause_index = clause_index;
7657 * For nested clauses, the LLVM produced exception info associates the try interval with
7658 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7659 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7660 * and everything else from the nested clause.
7663 for (i = 0; i < ei_len; ++i) {
7664 gint32 cindex1 = *(gint32*)type_info [i];
7665 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7667 for (j = 0; j < cfg->header->num_clauses; ++j) {
7669 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7670 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7672 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7673 /* clause1 is the nested clause */
7674 nested_ei = &cfg->llvm_ex_info [i];
7675 nesting_ei = &cfg->llvm_ex_info [nindex];
7678 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7680 nesting_ei->flags = clause2->flags;
7681 nesting_ei->data.catch_class = clause2->data.catch_class;
7682 nesting_ei->clause_index = cindex2;
7686 g_assert (nindex == ei_len + nested_len);
7687 cfg->llvm_this_reg = this_reg;
7688 cfg->llvm_this_offset = this_offset;
7690 /* type_info [i] is cfg mempool allocated, no need to free it */
7696 #if LLVM_API_VERSION > 100
7698 * decode_llvm_eh_info:
7700 * Decode the EH table emitted by llvm in jit mode, and store
7701 * the result into cfg.
7704 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7706 MonoCompile *cfg = ctx->cfg;
7709 MonoLLVMFDEInfo info;
7710 MonoJitExceptionInfo *ei;
7711 guint8 *p = eh_frame;
7712 int version, fde_count, fde_offset;
7713 guint32 ei_len, i, nested_len;
7714 gpointer *type_info;
7719 * Decode the one element EH table emitted by the MonoException class
7723 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7726 g_assert (version == 3);
7729 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7731 fde_count = *(guint32*)p;
7735 g_assert (fde_count <= 2);
7737 /* The first entry is the real method */
7738 g_assert (table [0] == 1);
7739 fde_offset = table [1];
7740 table += fde_count * 2;
7742 cfg->code_len = table [0];
7743 fde_len = table [1] - fde_offset;
7746 fde = (guint8*)eh_frame + fde_offset;
7747 cie = (guint8*)table;
7749 /* Compute lengths */
7750 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info, NULL, NULL, NULL);
7752 ei = (MonoJitExceptionInfo *)g_malloc0 (info.ex_info_len * sizeof (MonoJitExceptionInfo));
7753 type_info = (gpointer *)g_malloc0 (info.ex_info_len * sizeof (gpointer));
7754 unw_info = (guint8*)g_malloc0 (info.unw_info_len);
7756 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info, ei, type_info, unw_info);
7758 cfg->encoded_unwind_ops = unw_info;
7759 cfg->encoded_unwind_ops_len = info.unw_info_len;
7760 if (cfg->verbose_level > 1)
7761 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7762 if (info.this_reg != -1) {
7763 cfg->llvm_this_reg = info.this_reg;
7764 cfg->llvm_this_offset = info.this_offset;
7767 ei_len = info.ex_info_len;
7769 // Nested clauses are currently disabled
7772 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7773 cfg->llvm_ex_info_len = ei_len + nested_len;
7774 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7775 /* Fill the rest of the information from the type info */
7776 for (i = 0; i < ei_len; ++i) {
7777 gint32 clause_index = *(gint32*)type_info [i];
7778 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7780 cfg->llvm_ex_info [i].flags = clause->flags;
7781 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7782 cfg->llvm_ex_info [i].clause_index = clause_index;
7788 dlsym_cb (const char *name, void **symbol)
7794 if (!strcmp (name, "__bzero")) {
7795 *symbol = (void*)bzero;
7797 current = mono_dl_open (NULL, 0, NULL);
7800 err = mono_dl_symbol (current, name, symbol);
7802 mono_dl_close (current);
7804 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7805 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7811 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7813 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7817 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7819 LLVMTypeRef param_types [4];
7821 param_types [0] = param_type1;
7822 param_types [1] = param_type2;
7824 AddFunc (module, name, ret_type, param_types, 2);
7830 INTRINS_SADD_OVF_I32,
7831 INTRINS_UADD_OVF_I32,
7832 INTRINS_SSUB_OVF_I32,
7833 INTRINS_USUB_OVF_I32,
7834 INTRINS_SMUL_OVF_I32,
7835 INTRINS_UMUL_OVF_I32,
7836 INTRINS_SADD_OVF_I64,
7837 INTRINS_UADD_OVF_I64,
7838 INTRINS_SSUB_OVF_I64,
7839 INTRINS_USUB_OVF_I64,
7840 INTRINS_SMUL_OVF_I64,
7841 INTRINS_UMUL_OVF_I64,
7848 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7849 INTRINS_SSE_PMOVMSKB,
7850 INTRINS_SSE_PSRLI_W,
7851 INTRINS_SSE_PSRAI_W,
7852 INTRINS_SSE_PSLLI_W,
7853 INTRINS_SSE_PSRLI_D,
7854 INTRINS_SSE_PSRAI_D,
7855 INTRINS_SSE_PSLLI_D,
7856 INTRINS_SSE_PSRLI_Q,
7857 INTRINS_SSE_PSLLI_Q,
7858 INTRINS_SSE_SQRT_PD,
7859 INTRINS_SSE_SQRT_PS,
7860 INTRINS_SSE_RSQRT_PS,
7862 INTRINS_SSE_CVTTPD2DQ,
7863 INTRINS_SSE_CVTTPS2DQ,
7864 INTRINS_SSE_CVTDQ2PD,
7865 INTRINS_SSE_CVTDQ2PS,
7866 INTRINS_SSE_CVTPD2DQ,
7867 INTRINS_SSE_CVTPS2DQ,
7868 INTRINS_SSE_CVTPD2PS,
7869 INTRINS_SSE_CVTPS2PD,
7872 INTRINS_SSE_PACKSSWB,
7873 INTRINS_SSE_PACKUSWB,
7874 INTRINS_SSE_PACKSSDW,
7875 INTRINS_SSE_PACKUSDW,
7880 INTRINS_SSE_ADDSUBPS,
7885 INTRINS_SSE_ADDSUBPD,
7888 INTRINS_SSE_PADDUSW,
7889 INTRINS_SSE_PSUBUSW,
7895 INTRINS_SSE_PADDUSB,
7896 INTRINS_SSE_PSUBUSB,
7909 static IntrinsicDesc intrinsics[] = {
7910 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7911 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7912 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7913 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7914 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7915 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7916 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7917 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7918 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7919 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7920 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7921 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7922 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7923 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7924 {INTRINS_SIN, "llvm.sin.f64"},
7925 {INTRINS_COS, "llvm.cos.f64"},
7926 {INTRINS_SQRT, "llvm.sqrt.f64"},
7927 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7928 {INTRINS_FABS, "fabs"},
7929 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7930 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7931 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7932 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7933 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7934 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7935 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7936 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7937 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7938 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7939 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7940 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7941 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7942 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7943 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7944 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7945 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7946 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7947 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7948 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7949 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7950 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7951 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7952 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7953 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7954 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7955 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7956 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7957 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7958 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7959 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7960 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7961 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7962 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7963 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7964 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7965 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7966 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7967 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7968 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7969 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7970 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7971 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7972 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7973 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7974 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7975 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7976 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7977 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7978 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7979 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7980 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7981 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7982 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7987 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7989 LLVMTypeRef ret_type = type_to_simd_type (type);
7990 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7994 add_intrinsic (LLVMModuleRef module, int id)
7997 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7998 LLVMTypeRef ret_type, arg_types [16];
8001 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
8005 case INTRINS_MEMSET: {
8006 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8008 AddFunc (module, name, LLVMVoidType (), params, 5);
8011 case INTRINS_MEMCPY: {
8012 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8014 AddFunc (module, name, LLVMVoidType (), params, 5);
8017 case INTRINS_SADD_OVF_I32:
8018 case INTRINS_UADD_OVF_I32:
8019 case INTRINS_SSUB_OVF_I32:
8020 case INTRINS_USUB_OVF_I32:
8021 case INTRINS_SMUL_OVF_I32:
8022 case INTRINS_UMUL_OVF_I32: {
8023 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
8024 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
8025 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
8027 AddFunc (module, name, ret_type, params, 2);
8030 case INTRINS_SADD_OVF_I64:
8031 case INTRINS_UADD_OVF_I64:
8032 case INTRINS_SSUB_OVF_I64:
8033 case INTRINS_USUB_OVF_I64:
8034 case INTRINS_SMUL_OVF_I64:
8035 case INTRINS_UMUL_OVF_I64: {
8036 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8037 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8038 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8040 AddFunc (module, name, ret_type, params, 2);
8046 case INTRINS_FABS: {
8047 LLVMTypeRef params [] = { LLVMDoubleType () };
8049 AddFunc (module, name, LLVMDoubleType (), params, 1);
8052 case INTRINS_EXPECT_I8:
8053 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8055 case INTRINS_EXPECT_I1:
8056 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8058 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8059 case INTRINS_SSE_PMOVMSKB:
8061 ret_type = LLVMInt32Type ();
8062 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8063 AddFunc (module, name, ret_type, arg_types, 1);
8065 case INTRINS_SSE_PSRLI_W:
8066 case INTRINS_SSE_PSRAI_W:
8067 case INTRINS_SSE_PSLLI_W:
8069 ret_type = type_to_simd_type (MONO_TYPE_I2);
8070 arg_types [0] = ret_type;
8071 arg_types [1] = LLVMInt32Type ();
8072 AddFunc (module, name, ret_type, arg_types, 2);
8074 case INTRINS_SSE_PSRLI_D:
8075 case INTRINS_SSE_PSRAI_D:
8076 case INTRINS_SSE_PSLLI_D:
8077 ret_type = type_to_simd_type (MONO_TYPE_I4);
8078 arg_types [0] = ret_type;
8079 arg_types [1] = LLVMInt32Type ();
8080 AddFunc (module, name, ret_type, arg_types, 2);
8082 case INTRINS_SSE_PSRLI_Q:
8083 case INTRINS_SSE_PSLLI_Q:
8084 ret_type = type_to_simd_type (MONO_TYPE_I8);
8085 arg_types [0] = ret_type;
8086 arg_types [1] = LLVMInt32Type ();
8087 AddFunc (module, name, ret_type, arg_types, 2);
8089 case INTRINS_SSE_SQRT_PD:
8091 ret_type = type_to_simd_type (MONO_TYPE_R8);
8092 arg_types [0] = ret_type;
8093 AddFunc (module, name, ret_type, arg_types, 1);
8095 case INTRINS_SSE_SQRT_PS:
8096 ret_type = type_to_simd_type (MONO_TYPE_R4);
8097 arg_types [0] = ret_type;
8098 AddFunc (module, name, ret_type, arg_types, 1);
8100 case INTRINS_SSE_RSQRT_PS:
8101 ret_type = type_to_simd_type (MONO_TYPE_R4);
8102 arg_types [0] = ret_type;
8103 AddFunc (module, name, ret_type, arg_types, 1);
8105 case INTRINS_SSE_RCP_PS:
8106 ret_type = type_to_simd_type (MONO_TYPE_R4);
8107 arg_types [0] = ret_type;
8108 AddFunc (module, name, ret_type, arg_types, 1);
8110 case INTRINS_SSE_CVTTPD2DQ:
8111 ret_type = type_to_simd_type (MONO_TYPE_I4);
8112 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8113 AddFunc (module, name, ret_type, arg_types, 1);
8115 case INTRINS_SSE_CVTTPS2DQ:
8116 ret_type = type_to_simd_type (MONO_TYPE_I4);
8117 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8118 AddFunc (module, name, ret_type, arg_types, 1);
8120 case INTRINS_SSE_CVTDQ2PD:
8121 /* Conversion ops */
8122 ret_type = type_to_simd_type (MONO_TYPE_R8);
8123 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8124 AddFunc (module, name, ret_type, arg_types, 1);
8126 case INTRINS_SSE_CVTDQ2PS:
8127 ret_type = type_to_simd_type (MONO_TYPE_R4);
8128 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8129 AddFunc (module, name, ret_type, arg_types, 1);
8131 case INTRINS_SSE_CVTPD2DQ:
8132 ret_type = type_to_simd_type (MONO_TYPE_I4);
8133 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8134 AddFunc (module, name, ret_type, arg_types, 1);
8136 case INTRINS_SSE_CVTPS2DQ:
8137 ret_type = type_to_simd_type (MONO_TYPE_I4);
8138 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8139 AddFunc (module, name, ret_type, arg_types, 1);
8141 case INTRINS_SSE_CVTPD2PS:
8142 ret_type = type_to_simd_type (MONO_TYPE_R4);
8143 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8144 AddFunc (module, name, ret_type, arg_types, 1);
8146 case INTRINS_SSE_CVTPS2PD:
8147 ret_type = type_to_simd_type (MONO_TYPE_R8);
8148 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8149 AddFunc (module, name, ret_type, arg_types, 1);
8151 case INTRINS_SSE_CMPPD:
8153 ret_type = type_to_simd_type (MONO_TYPE_R8);
8154 arg_types [0] = ret_type;
8155 arg_types [1] = ret_type;
8156 arg_types [2] = LLVMInt8Type ();
8157 AddFunc (module, name, ret_type, arg_types, 3);
8159 case INTRINS_SSE_CMPPS:
8160 ret_type = type_to_simd_type (MONO_TYPE_R4);
8161 arg_types [0] = ret_type;
8162 arg_types [1] = ret_type;
8163 arg_types [2] = LLVMInt8Type ();
8164 AddFunc (module, name, ret_type, arg_types, 3);
8166 case INTRINS_SSE_PACKSSWB:
8167 case INTRINS_SSE_PACKUSWB:
8168 case INTRINS_SSE_PACKSSDW:
8170 ret_type = type_to_simd_type (MONO_TYPE_I1);
8171 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8172 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8173 AddFunc (module, name, ret_type, arg_types, 2);
8175 case INTRINS_SSE_PACKUSDW:
8176 ret_type = type_to_simd_type (MONO_TYPE_I2);
8177 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8178 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8179 AddFunc (module, name, ret_type, arg_types, 2);
8181 /* SSE Binary ops */
8182 case INTRINS_SSE_PADDSW:
8183 case INTRINS_SSE_PSUBSW:
8184 case INTRINS_SSE_PADDUSW:
8185 case INTRINS_SSE_PSUBUSW:
8186 case INTRINS_SSE_PAVGW:
8187 case INTRINS_SSE_PMULHW:
8188 case INTRINS_SSE_PMULHU:
8189 add_sse_binary (module, name, MONO_TYPE_I2);
8191 case INTRINS_SSE_MINPS:
8192 case INTRINS_SSE_MAXPS:
8193 case INTRINS_SSE_HADDPS:
8194 case INTRINS_SSE_HSUBPS:
8195 case INTRINS_SSE_ADDSUBPS:
8196 add_sse_binary (module, name, MONO_TYPE_R4);
8198 case INTRINS_SSE_MINPD:
8199 case INTRINS_SSE_MAXPD:
8200 case INTRINS_SSE_HADDPD:
8201 case INTRINS_SSE_HSUBPD:
8202 case INTRINS_SSE_ADDSUBPD:
8203 add_sse_binary (module, name, MONO_TYPE_R8);
8205 case INTRINS_SE_PADDSB:
8206 case INTRINS_SSE_PSUBSB:
8207 case INTRINS_SSE_PADDUSB:
8208 case INTRINS_SSE_PSUBUSB:
8209 case INTRINS_SSE_PAVGB:
8210 add_sse_binary (module, name, MONO_TYPE_I1);
8212 case INTRINS_SSE_PAUSE:
8213 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8215 case INTRINS_SSE_DPPS:
8216 ret_type = type_to_simd_type (MONO_TYPE_R4);
8217 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8218 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8219 #if LLVM_API_VERSION >= 500
8220 arg_types [2] = LLVMInt8Type ();
8222 arg_types [2] = LLVMInt32Type ();
8224 AddFunc (module, name, ret_type, arg_types, 3);
8228 g_assert_not_reached ();
8234 get_intrinsic (EmitContext *ctx, const char *name)
8236 #if LLVM_API_VERSION > 100
8240 * Every method is emitted into its own module so
8241 * we can add intrinsics on demand.
8243 res = LLVMGetNamedFunction (ctx->lmodule, name);
8247 /* No locking needed */
8248 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8251 printf ("%s\n", name);
8252 g_assert (id != -1);
8253 add_intrinsic (ctx->lmodule, id);
8254 res = LLVMGetNamedFunction (ctx->lmodule, name);
8262 res = LLVMGetNamedFunction (ctx->lmodule, name);
8269 add_intrinsics (LLVMModuleRef module)
8273 /* Emit declarations of instrinsics */
8275 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8276 * type doesn't seem to do any locking.
8278 for (i = 0; i < INTRINS_NUM; ++i)
8279 add_intrinsic (module, i);
8283 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8285 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8288 /* Load/Store intrinsics */
8290 LLVMTypeRef arg_types [5];
8294 for (i = 1; i <= 8; i *= 2) {
8295 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8296 arg_types [1] = LLVMInt32Type ();
8297 arg_types [2] = LLVMInt1Type ();
8298 arg_types [3] = LLVMInt32Type ();
8299 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8300 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8302 arg_types [0] = LLVMIntType (i * 8);
8303 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8304 arg_types [2] = LLVMInt32Type ();
8305 arg_types [3] = LLVMInt1Type ();
8306 arg_types [4] = LLVMInt32Type ();
8307 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8308 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8314 add_types (MonoLLVMModule *module)
8316 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8320 mono_llvm_init (void)
8325 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8327 h = g_hash_table_new (NULL, NULL);
8328 for (i = 0; i < INTRINS_NUM; ++i)
8329 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8330 intrins_id_to_name = h;
8332 h = g_hash_table_new (g_str_hash, g_str_equal);
8333 for (i = 0; i < INTRINS_NUM; ++i)
8334 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8335 intrins_name_to_id = h;
8339 init_jit_module (MonoDomain *domain)
8341 MonoJitDomainInfo *dinfo;
8342 MonoLLVMModule *module;
8345 dinfo = domain_jit_info (domain);
8346 if (dinfo->llvm_module)
8349 mono_loader_lock ();
8351 if (dinfo->llvm_module) {
8352 mono_loader_unlock ();
8356 module = g_new0 (MonoLLVMModule, 1);
8358 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8359 module->lmodule = LLVMModuleCreateWithName (name);
8360 module->context = LLVMGetGlobalContext ();
8362 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8364 add_intrinsics (module->lmodule);
8367 module->llvm_types = g_hash_table_new (NULL, NULL);
8369 #if LLVM_API_VERSION < 100
8370 MonoJitICallInfo *info;
8372 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8374 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8377 mono_memory_barrier ();
8379 dinfo->llvm_module = module;
8381 mono_loader_unlock ();
8385 mono_llvm_cleanup (void)
8387 MonoLLVMModule *module = &aot_module;
8389 if (module->lmodule)
8390 LLVMDisposeModule (module->lmodule);
8392 if (module->context)
8393 LLVMContextDispose (module->context);
8397 mono_llvm_free_domain_info (MonoDomain *domain)
8399 MonoJitDomainInfo *info = domain_jit_info (domain);
8400 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8406 if (module->llvm_types)
8407 g_hash_table_destroy (module->llvm_types);
8409 mono_llvm_dispose_ee (module->mono_ee);
8411 if (module->bb_names) {
8412 for (i = 0; i < module->bb_names_len; ++i)
8413 g_free (module->bb_names [i]);
8414 g_free (module->bb_names);
8416 //LLVMDisposeModule (module->module);
8420 info->llvm_module = NULL;
8424 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, int initial_got_size, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8426 MonoLLVMModule *module = &aot_module;
8428 /* Delete previous module */
8429 if (module->plt_entries)
8430 g_hash_table_destroy (module->plt_entries);
8431 if (module->lmodule)
8432 LLVMDisposeModule (module->lmodule);
8434 memset (module, 0, sizeof (aot_module));
8436 module->lmodule = LLVMModuleCreateWithName ("aot");
8437 module->assembly = assembly;
8438 module->global_prefix = g_strdup (global_prefix);
8439 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8440 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8441 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8442 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8443 module->external_symbols = TRUE;
8444 module->emit_dwarf = emit_dwarf;
8445 module->static_link = static_link;
8446 module->llvm_only = llvm_only;
8447 /* The first few entries are reserved */
8448 module->max_got_offset = initial_got_size;
8449 module->context = LLVMGetGlobalContext ();
8452 /* clang ignores our debug info because it has an invalid version */
8453 module->emit_dwarf = FALSE;
8455 add_intrinsics (module->lmodule);
8458 #if LLVM_API_VERSION > 100
8459 if (module->emit_dwarf) {
8460 char *dir, *build_info, *s, *cu_name;
8462 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8465 dir = g_strdup (".");
8466 build_info = mono_get_runtime_build_info ();
8467 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8468 cu_name = g_path_get_basename (assembly->image->name);
8469 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8471 g_free (build_info);
8478 * We couldn't compute the type of the LLVM global representing the got because
8479 * its size is only known after all the methods have been emitted. So create
8480 * a dummy variable, and replace all uses it with the real got variable when
8481 * its size is known in mono_llvm_emit_aot_module ().
8484 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8486 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8487 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8490 /* Add initialization array */
8492 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8494 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8495 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8499 emit_init_icall_wrappers (module);
8501 emit_llvm_code_start (module);
8503 /* Add a dummy personality function */
8504 if (!use_debug_personality) {
8505 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8506 LLVMSetLinkage (personality, LLVMExternalLinkage);
8507 mark_as_used (module, personality);
8510 /* Add a reference to the c++ exception we throw/catch */
8512 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8513 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8514 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8515 mono_llvm_set_is_constant (module->sentinel_exception);
8518 module->llvm_types = g_hash_table_new (NULL, NULL);
8519 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8520 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8521 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8522 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8523 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8524 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8525 module->method_to_callers = g_hash_table_new (NULL, NULL);
8529 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8532 LLVMValueRef res, *vals;
8534 vals = g_new0 (LLVMValueRef, nvalues);
8535 for (i = 0; i < nvalues; ++i)
8536 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8537 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8543 llvm_array_from_bytes (guint8 *values, int nvalues)
8546 LLVMValueRef res, *vals;
8548 vals = g_new0 (LLVMValueRef, nvalues);
8549 for (i = 0; i < nvalues; ++i)
8550 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8551 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8556 * mono_llvm_emit_aot_file_info:
8558 * Emit the MonoAotFileInfo structure.
8559 * Same as emit_aot_file_info () in aot-compiler.c.
8562 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8564 MonoLLVMModule *module = &aot_module;
8566 /* Save these for later */
8567 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8568 module->has_jitted_code = has_jitted_code;
8572 * mono_llvm_emit_aot_data:
8574 * Emit the binary data DATA pointed to by symbol SYMBOL.
8577 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8579 MonoLLVMModule *module = &aot_module;
8583 type = LLVMArrayType (LLVMInt8Type (), data_len);
8584 d = LLVMAddGlobal (module->lmodule, type, symbol);
8585 LLVMSetVisibility (d, LLVMHiddenVisibility);
8586 LLVMSetLinkage (d, LLVMInternalLinkage);
8587 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8588 LLVMSetAlignment (d, 8);
8589 mono_llvm_set_is_constant (d);
8592 /* Add a reference to a global defined in JITted code */
8594 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8599 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8600 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8606 emit_aot_file_info (MonoLLVMModule *module)
8608 LLVMTypeRef file_info_type;
8609 LLVMTypeRef *eltypes, eltype;
8610 LLVMValueRef info_var;
8611 LLVMValueRef *fields;
8612 int i, nfields, tindex;
8613 MonoAotFileInfo *info;
8614 LLVMModuleRef lmodule = module->lmodule;
8616 info = &module->aot_info;
8618 /* Create an LLVM type to represent MonoAotFileInfo */
8619 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8620 eltypes = g_new (LLVMTypeRef, nfields);
8622 eltypes [tindex ++] = LLVMInt32Type ();
8623 eltypes [tindex ++] = LLVMInt32Type ();
8625 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8626 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8628 for (i = 0; i < 15; ++i)
8629 eltypes [tindex ++] = LLVMInt32Type ();
8631 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8632 for (i = 0; i < 4; ++i)
8633 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8634 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8635 g_assert (tindex == nfields);
8636 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8637 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8639 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8640 if (module->static_link) {
8641 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8642 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8644 fields = g_new (LLVMValueRef, nfields);
8646 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8647 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8651 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8652 * for symbols defined in the .s file emitted by the aot compiler.
8654 eltype = eltypes [tindex];
8655 if (module->llvm_only)
8656 fields [tindex ++] = LLVMConstNull (eltype);
8658 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8659 fields [tindex ++] = module->got_var;
8660 /* llc defines this directly */
8661 if (!module->llvm_only) {
8662 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8663 fields [tindex ++] = LLVMConstNull (eltype);
8664 fields [tindex ++] = LLVMConstNull (eltype);
8666 fields [tindex ++] = LLVMConstNull (eltype);
8667 fields [tindex ++] = module->get_method;
8668 fields [tindex ++] = module->get_unbox_tramp;
8670 if (module->has_jitted_code) {
8671 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8672 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8674 fields [tindex ++] = LLVMConstNull (eltype);
8675 fields [tindex ++] = LLVMConstNull (eltype);
8677 if (!module->llvm_only)
8678 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8680 fields [tindex ++] = LLVMConstNull (eltype);
8681 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8682 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8683 fields [tindex ++] = LLVMConstNull (eltype);
8685 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8686 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8687 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8688 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8689 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8690 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8691 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8692 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8693 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8694 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8696 /* Not needed (mem_end) */
8697 fields [tindex ++] = LLVMConstNull (eltype);
8698 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8699 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8700 if (info->trampoline_size [0]) {
8701 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8702 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8703 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8704 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8706 fields [tindex ++] = LLVMConstNull (eltype);
8707 fields [tindex ++] = LLVMConstNull (eltype);
8708 fields [tindex ++] = LLVMConstNull (eltype);
8709 fields [tindex ++] = LLVMConstNull (eltype);
8711 if (module->static_link && !module->llvm_only)
8712 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8714 fields [tindex ++] = LLVMConstNull (eltype);
8715 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8716 if (!module->llvm_only) {
8717 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8718 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8719 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8720 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8721 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8722 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8724 fields [tindex ++] = LLVMConstNull (eltype);
8725 fields [tindex ++] = LLVMConstNull (eltype);
8726 fields [tindex ++] = LLVMConstNull (eltype);
8727 fields [tindex ++] = LLVMConstNull (eltype);
8728 fields [tindex ++] = LLVMConstNull (eltype);
8729 fields [tindex ++] = LLVMConstNull (eltype);
8732 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8733 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8736 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8737 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8738 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8739 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8740 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8741 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8742 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8743 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8744 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8745 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8746 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8747 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8748 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8749 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8750 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8752 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8753 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8754 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8755 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8756 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8758 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8759 g_assert (tindex == nfields);
8761 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8763 if (module->static_link) {
8767 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8768 /* Get rid of characters which cannot occur in symbols */
8770 for (p = s; *p; ++p) {
8771 if (!(isalnum (*p) || *p == '_'))
8774 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8776 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8777 LLVMSetLinkage (var, LLVMExternalLinkage);
8782 * Emit the aot module into the LLVM bitcode file FILENAME.
8785 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8787 LLVMTypeRef got_type, inited_type;
8788 LLVMValueRef real_got, real_inited;
8789 MonoLLVMModule *module = &aot_module;
8791 emit_llvm_code_end (module);
8794 * Create the real got variable and replace all uses of the dummy variable with
8797 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8798 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8799 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8800 if (module->external_symbols) {
8801 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8802 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8804 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8806 mono_llvm_replace_uses_of (module->got_var, real_got);
8808 mark_as_used (&aot_module, real_got);
8810 /* Delete the dummy got so it doesn't become a global */
8811 LLVMDeleteGlobal (module->got_var);
8812 module->got_var = real_got;
8815 * Same for the init_var
8817 if (module->llvm_only) {
8818 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8819 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8820 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8821 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8822 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8823 LLVMDeleteGlobal (module->inited_var);
8826 if (module->llvm_only) {
8827 emit_get_method (&aot_module);
8828 emit_get_unbox_tramp (&aot_module);
8831 emit_llvm_used (&aot_module);
8832 emit_dbg_info (&aot_module, filename, cu_name);
8833 emit_aot_file_info (&aot_module);
8836 * Replace GOT entries for directly callable methods with the methods themselves.
8837 * It would be easier to implement this by predefining all methods before compiling
8838 * their bodies, but that couldn't handle the case when a method fails to compile
8841 if (module->llvm_only) {
8842 GHashTableIter iter;
8844 GSList *callers, *l;
8846 g_hash_table_iter_init (&iter, module->method_to_callers);
8847 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8848 LLVMValueRef lmethod;
8850 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8853 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8855 for (l = callers; l; l = l->next) {
8856 LLVMValueRef caller = (LLVMValueRef)l->data;
8858 mono_llvm_replace_uses_of (caller, lmethod);
8864 /* Replace PLT entries for directly callable methods with the methods themselves */
8866 GHashTableIter iter;
8868 LLVMValueRef callee;
8870 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8871 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8872 if (mono_aot_is_direct_callable (ji)) {
8873 LLVMValueRef lmethod;
8875 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8876 /* The types might not match because the caller might pass an rgctx */
8877 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8878 mono_llvm_replace_uses_of (callee, lmethod);
8879 mono_aot_mark_unused_llvm_plt_entry (ji);
8889 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8890 printf ("%s\n", verifier_err);
8891 g_assert_not_reached ();
8896 LLVMWriteBitcodeToFile (module->lmodule, filename);
8901 md_string (const char *s)
8903 return LLVMMDString (s, strlen (s));
8906 /* Debugging support */
8909 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8911 LLVMModuleRef lmodule = module->lmodule;
8912 LLVMValueRef args [16], ver;
8915 * This can only be enabled when LLVM code is emitted into a separate object
8916 * file, since the AOT compiler also emits dwarf info,
8917 * and the abbrev indexes will not be correct since llvm has added its own
8920 if (!module->emit_dwarf)
8923 #if LLVM_API_VERSION > 100
8924 mono_llvm_di_builder_finalize (module->di_builder);
8926 LLVMValueRef cu_args [16], cu;
8928 char *build_info, *s, *dir;
8931 * Emit dwarf info in the form of LLVM metadata. There is some
8932 * out-of-date documentation at:
8933 * http://llvm.org/docs/SourceLevelDebugging.html
8934 * but most of this was gathered from the llvm and
8939 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8940 /* CU name/compilation dir */
8941 dir = g_path_get_dirname (filename);
8942 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8943 args [1] = LLVMMDString (dir, strlen (dir));
8944 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8947 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8949 build_info = mono_get_runtime_build_info ();
8950 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8951 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8952 g_free (build_info);
8954 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8956 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8957 /* Runtime version */
8958 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8960 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8961 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8963 if (module->subprogram_mds) {
8967 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8968 for (i = 0; i < module->subprogram_mds->len; ++i)
8969 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8970 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8972 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8975 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8976 /* Imported modules */
8977 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8979 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8980 /* DebugEmissionKind = FullDebug */
8981 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8982 cu = LLVMMDNode (cu_args, n_cuargs);
8983 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8986 #if LLVM_API_VERSION > 100
8987 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8988 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8989 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8990 ver = LLVMMDNode (args, 3);
8991 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8993 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8994 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8995 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8996 ver = LLVMMDNode (args, 3);
8997 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8999 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9000 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9001 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
9002 ver = LLVMMDNode (args, 3);
9003 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9005 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9006 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9007 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9008 ver = LLVMMDNode (args, 3);
9009 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9014 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9016 MonoLLVMModule *module = ctx->module;
9017 MonoDebugMethodInfo *minfo = ctx->minfo;
9018 char *source_file, *dir, *filename;
9019 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9020 MonoSymSeqPoint *sym_seq_points;
9026 mono_debug_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9028 source_file = g_strdup ("<unknown>");
9029 dir = g_path_get_dirname (source_file);
9030 filename = g_path_get_basename (source_file);
9032 #if LLVM_API_VERSION > 100
9033 return mono_llvm_di_create_function (module->di_builder, module->cu, method, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
9036 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9037 args [0] = md_string (filename);
9038 args [1] = md_string (dir);
9039 ctx_args [1] = LLVMMDNode (args, 2);
9040 ctx_md = LLVMMDNode (ctx_args, 2);
9042 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9043 type_args [1] = NULL;
9044 type_args [2] = NULL;
9045 type_args [3] = LLVMMDString ("", 0);
9046 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9047 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9048 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9049 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9050 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9051 type_args [9] = NULL;
9052 type_args [10] = NULL;
9053 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9054 type_args [12] = NULL;
9055 type_args [13] = NULL;
9056 type_args [14] = NULL;
9057 type_md = LLVMMDNode (type_args, 14);
9059 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9060 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9061 /* Source directory + file pair */
9062 args [0] = md_string (filename);
9063 args [1] = md_string (dir);
9064 md_args [1] = LLVMMDNode (args ,2);
9065 md_args [2] = ctx_md;
9066 md_args [3] = md_string (cfg->method->name);
9067 md_args [4] = md_string (name);
9068 md_args [5] = md_string (name);
9071 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9073 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9075 md_args [7] = type_md;
9077 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9079 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9081 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9082 /* Index into a virtual function */
9083 md_args [11] = NULL;
9084 md_args [12] = NULL;
9086 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9088 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9089 /* Pointer to LLVM function */
9090 md_args [15] = method;
9091 /* Function template parameter */
9092 md_args [16] = NULL;
9093 /* Function declaration descriptor */
9094 md_args [17] = NULL;
9095 /* List of function variables */
9096 md_args [18] = LLVMMDNode (args, 0);
9098 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9099 md = LLVMMDNode (md_args, 20);
9101 if (!module->subprogram_mds)
9102 module->subprogram_mds = g_ptr_array_new ();
9103 g_ptr_array_add (module->subprogram_mds, md);
9107 g_free (source_file);
9108 g_free (sym_seq_points);
9114 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9116 MonoCompile *cfg = ctx->cfg;
9118 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9119 MonoDebugSourceLocation *loc;
9120 LLVMValueRef loc_md;
9122 loc = mono_debug_method_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9125 #if LLVM_API_VERSION > 100
9126 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9127 mono_llvm_di_set_location (builder, loc_md);
9129 LLVMValueRef md_args [16];
9133 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9134 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9135 md_args [nmd_args ++] = ctx->dbg_md;
9136 md_args [nmd_args ++] = NULL;
9137 loc_md = LLVMMDNode (md_args, nmd_args);
9138 LLVMSetCurrentDebugLocation (builder, loc_md);
9140 mono_debug_free_source_location (loc);
9146 default_mono_llvm_unhandled_exception (void)
9148 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9149 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9151 mono_unhandled_exception (target);
9152 mono_invoke_unhandled_exception_hook (target);
9153 g_assert_not_reached ();
9158 - Emit LLVM IR from the mono IR using the LLVM C API.
9159 - The original arch specific code remains, so we can fall back to it if we run
9160 into something we can't handle.
9164 A partial list of issues:
9165 - Handling of opcodes which can throw exceptions.
9167 In the mono JIT, these are implemented using code like this:
9174 push throw_pos - method
9175 call <exception trampoline>
9177 The problematic part is push throw_pos - method, which cannot be represented
9178 in the LLVM IR, since it does not support label values.
9179 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9180 be implemented in JIT mode ?
9181 -> a possible but slower implementation would use the normal exception
9182 throwing code but it would need to control the placement of the throw code
9183 (it needs to be exactly after the compare+branch).
9184 -> perhaps add a PC offset intrinsics ?
9186 - efficient implementation of .ovf opcodes.
9188 These are currently implemented as:
9189 <ins which sets the condition codes>
9192 Some overflow opcodes are now supported by LLVM SVN.
9194 - exception handling, unwinding.
9195 - SSA is disabled for methods with exception handlers
9196 - How to obtain unwind info for LLVM compiled methods ?
9197 -> this is now solved by converting the unwind info generated by LLVM
9199 - LLVM uses the c++ exception handling framework, while we use our home grown
9200 code, and couldn't use the c++ one:
9201 - its not supported under VC++, other exotic platforms.
9202 - it might be impossible to support filter clauses with it.
9206 The trampolines need a predictable call sequence, since they need to disasm
9207 the calling code to obtain register numbers / offsets.
9209 LLVM currently generates this code in non-JIT mode:
9210 mov -0x98(%rax),%eax
9212 Here, the vtable pointer is lost.
9213 -> solution: use one vtable trampoline per class.
9215 - passing/receiving the IMT pointer/RGCTX.
9216 -> solution: pass them as normal arguments ?
9220 LLVM does not allow the specification of argument registers etc. This means
9221 that all calls are made according to the platform ABI.
9223 - passing/receiving vtypes.
9225 Vtypes passed/received in registers are handled by the front end by using
9226 a signature with scalar arguments, and loading the parts of the vtype into those
9229 Vtypes passed on the stack are handled using the 'byval' attribute.
9233 Supported though alloca, we need to emit the load/store code.
9237 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9238 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9239 This is made easier because the IR is already in SSA form.
9240 An additional problem is that our IR is not consistent with types, i.e. i32/i64
9241 types are frequently used incorrectly.
9246 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9247 it with the file containing the methods emitted by the JIT and the AOT data
9251 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9252 * - each bblock should end with a branch
9253 * - setting the return value, making cfg->ret non-volatile
9254 * - avoid some transformations in the JIT which make it harder for us to generate
9256 * - use pointer types to help optimizations.
9259 #else /* DISABLE_JIT */
9262 mono_llvm_cleanup (void)
9267 mono_llvm_free_domain_info (MonoDomain *domain)
9272 mono_llvm_init (void)
9277 default_mono_llvm_unhandled_exception (void)
9281 #endif /* DISABLE_JIT */