3 * llvm "Backend" for the mono JIT
5 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
6 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
7 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #include <mono/metadata/debug-helpers.h>
13 #include <mono/metadata/debug-internals.h>
14 #include <mono/metadata/mempool-internals.h>
15 #include <mono/metadata/environment.h>
16 #include <mono/metadata/object-internals.h>
17 #include <mono/metadata/abi-details.h>
18 #include <mono/utils/mono-tls.h>
19 #include <mono/utils/mono-dl.h>
20 #include <mono/utils/mono-time.h>
21 #include <mono/utils/freebsd-dwarf.h>
23 #ifndef __STDC_LIMIT_MACROS
24 #define __STDC_LIMIT_MACROS
26 #ifndef __STDC_CONSTANT_MACROS
27 #define __STDC_CONSTANT_MACROS
30 #include "llvm-c/BitWriter.h"
31 #include "llvm-c/Analysis.h"
33 #include "mini-llvm-cpp.h"
35 #include "aot-compiler.h"
36 #include "mini-llvm.h"
43 extern void *memset(void *, int, size_t);
44 void bzero (void *to, size_t count) { memset (to, 0, count); }
48 #if LLVM_API_VERSION < 4
49 #error "The version of the mono llvm repository is too old."
52 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
55 * Information associated by mono with LLVM modules.
58 LLVMModuleRef lmodule;
59 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
60 GHashTable *llvm_types;
62 const char *got_symbol;
63 const char *get_method_symbol;
64 const char *get_unbox_tramp_symbol;
65 GHashTable *plt_entries;
66 GHashTable *plt_entries_ji;
67 GHashTable *method_to_lmethod;
68 GHashTable *direct_callables;
73 GPtrArray *subprogram_mds;
75 LLVMExecutionEngineRef ee;
76 gboolean external_symbols;
79 LLVMValueRef personality;
82 MonoAssembly *assembly;
84 MonoAotFileInfo aot_info;
85 const char *jit_got_symbol;
86 const char *eh_frame_symbol;
87 LLVMValueRef get_method, get_unbox_tramp;
88 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
89 LLVMValueRef code_start, code_end;
90 LLVMValueRef inited_var;
91 int max_inited_idx, max_method_idx;
92 gboolean has_jitted_code;
95 GHashTable *idx_to_lmethod;
96 GHashTable *idx_to_unbox_tramp;
97 /* Maps a MonoMethod to LLVM instructions representing it */
98 GHashTable *method_to_callers;
99 LLVMContextRef context;
100 LLVMValueRef sentinel_exception;
101 void *di_builder, *cu;
102 GHashTable *objc_selector_to_var;
106 * Information associated by the backend with mono basic blocks.
109 LLVMBasicBlockRef bblock, end_bblock;
110 LLVMValueRef finally_ind;
111 gboolean added, invoke_target;
113 * If this bblock is the start of a finally clause, this is a list of bblocks it
114 * needs to branch to in ENDFINALLY.
116 GSList *call_handler_return_bbs;
118 * If this bblock is the start of a finally clause, this is the bblock that
119 * CALL_HANDLER needs to branch to.
121 LLVMBasicBlockRef call_handler_target_bb;
122 /* The list of switch statements generated by ENDFINALLY instructions */
123 GSList *endfinally_switch_ins_list;
128 * Structure containing emit state
131 MonoMemPool *mempool;
133 /* Maps method names to the corresponding LLVMValueRef */
134 GHashTable *emitted_method_decls;
137 LLVMValueRef lmethod;
138 MonoLLVMModule *module;
139 LLVMModuleRef lmodule;
141 int sindex, default_index, ex_index;
142 LLVMBuilderRef builder;
143 LLVMValueRef *values, *addresses;
144 MonoType **vreg_cli_types;
146 MonoMethodSignature *sig;
148 GHashTable *region_to_handler;
149 GHashTable *clause_to_handler;
150 LLVMBuilderRef alloca_builder;
151 LLVMValueRef last_alloca;
152 LLVMValueRef rgctx_arg;
153 LLVMValueRef this_arg;
154 LLVMTypeRef *vreg_types;
156 LLVMTypeRef method_type;
157 LLVMBasicBlockRef init_bb, inited_bb;
159 gboolean *unreachable;
161 gboolean has_got_access;
162 gboolean is_linkonce;
163 int this_arg_pindex, rgctx_arg_pindex;
164 LLVMValueRef imt_rgctx_loc;
165 GHashTable *llvm_types;
167 MonoDebugMethodInfo *minfo;
169 /* For every clause, the clauses it is nested in */
172 GHashTable *exc_meta;
173 GHashTable *method_to_callers;
174 GPtrArray *phi_values;
175 GPtrArray *bblock_list;
177 GHashTable *jit_callees;
178 LLVMValueRef long_bb_break_var;
184 MonoBasicBlock *in_bb;
189 * Instruction metadata
190 * This is the same as ins_info, but LREG != IREG.
198 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
199 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
206 /* keep in sync with the enum in mini.h */
209 #include "mini-ops.h"
214 #if SIZEOF_VOID_P == 4
215 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
217 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
220 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
223 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
225 #define TRACE_FAILURE(msg)
229 #define IS_TARGET_X86 1
231 #define IS_TARGET_X86 0
235 #define IS_TARGET_AMD64 1
237 #define IS_TARGET_AMD64 0
240 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
242 static LLVMIntPredicate cond_to_llvm_cond [] = {
255 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
268 static MonoNativeTlsKey current_cfg_tls_id;
270 static MonoLLVMModule aot_module;
272 static GHashTable *intrins_id_to_name;
273 static GHashTable *intrins_name_to_id;
275 static void init_jit_module (MonoDomain *domain);
277 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
278 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
279 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
280 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
281 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
282 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
285 set_failure (EmitContext *ctx, const char *message)
287 TRACE_FAILURE (reason);
288 ctx->cfg->exception_message = g_strdup (message);
289 ctx->cfg->disable_llvm = TRUE;
295 * The LLVM type with width == sizeof (gpointer)
300 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
306 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
312 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
318 * Return the size of the LLVM representation of the vtype T.
321 get_vtype_size (MonoType *t)
325 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
327 /* LLVMArgAsIArgs depends on this since it stores whole words */
328 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
335 * simd_class_to_llvm_type:
337 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
340 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
342 if (!strcmp (klass->name, "Vector2d")) {
343 return LLVMVectorType (LLVMDoubleType (), 2);
344 } else if (!strcmp (klass->name, "Vector2l")) {
345 return LLVMVectorType (LLVMInt64Type (), 2);
346 } else if (!strcmp (klass->name, "Vector2ul")) {
347 return LLVMVectorType (LLVMInt64Type (), 2);
348 } else if (!strcmp (klass->name, "Vector4i")) {
349 return LLVMVectorType (LLVMInt32Type (), 4);
350 } else if (!strcmp (klass->name, "Vector4ui")) {
351 return LLVMVectorType (LLVMInt32Type (), 4);
352 } else if (!strcmp (klass->name, "Vector4f")) {
353 return LLVMVectorType (LLVMFloatType (), 4);
354 } else if (!strcmp (klass->name, "Vector8s")) {
355 return LLVMVectorType (LLVMInt16Type (), 8);
356 } else if (!strcmp (klass->name, "Vector8us")) {
357 return LLVMVectorType (LLVMInt16Type (), 8);
358 } else if (!strcmp (klass->name, "Vector16sb")) {
359 return LLVMVectorType (LLVMInt8Type (), 16);
360 } else if (!strcmp (klass->name, "Vector16b")) {
361 return LLVMVectorType (LLVMInt8Type (), 16);
362 } else if (!strcmp (klass->name, "Vector2")) {
363 /* System.Numerics */
364 return LLVMVectorType (LLVMFloatType (), 4);
365 } else if (!strcmp (klass->name, "Vector3")) {
366 return LLVMVectorType (LLVMFloatType (), 4);
367 } else if (!strcmp (klass->name, "Vector4")) {
368 return LLVMVectorType (LLVMFloatType (), 4);
369 } else if (!strcmp (klass->name, "Vector`1")) {
370 MonoType *etype = mono_class_get_generic_class (klass)->context.class_inst->type_argv [0];
371 switch (etype->type) {
374 return LLVMVectorType (LLVMInt8Type (), 16);
377 return LLVMVectorType (LLVMInt16Type (), 8);
380 return LLVMVectorType (LLVMInt32Type (), 4);
383 return LLVMVectorType (LLVMInt64Type (), 2);
385 return LLVMVectorType (LLVMFloatType (), 4);
387 return LLVMVectorType (LLVMDoubleType (), 2);
389 g_assert_not_reached ();
393 printf ("%s\n", klass->name);
399 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
400 static inline G_GNUC_UNUSED LLVMTypeRef
401 type_to_simd_type (int type)
405 return LLVMVectorType (LLVMInt8Type (), 16);
407 return LLVMVectorType (LLVMInt16Type (), 8);
409 return LLVMVectorType (LLVMInt32Type (), 4);
411 return LLVMVectorType (LLVMInt64Type (), 2);
413 return LLVMVectorType (LLVMDoubleType (), 2);
415 return LLVMVectorType (LLVMFloatType (), 4);
417 g_assert_not_reached ();
423 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
425 int i, size, nfields, esize;
426 LLVMTypeRef *eltypes;
431 t = &klass->byval_arg;
433 if (mini_type_is_hfa (t, &nfields, &esize)) {
435 * This is needed on arm64 where HFAs are returned in
438 /* SIMD types have size 16 in mono_class_value_size () */
439 if (klass->simd_type)
442 eltypes = g_new (LLVMTypeRef, size);
443 for (i = 0; i < size; ++i)
444 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
446 size = get_vtype_size (t);
448 eltypes = g_new (LLVMTypeRef, size);
449 for (i = 0; i < size; ++i)
450 eltypes [i] = LLVMInt8Type ();
453 name = mono_type_full_name (&klass->byval_arg);
454 ltype = LLVMStructCreateNamed (module->context, name);
455 LLVMStructSetBody (ltype, eltypes, size, FALSE);
465 * Return the LLVM type corresponding to T.
468 type_to_llvm_type (EmitContext *ctx, MonoType *t)
470 t = mini_get_underlying_type (t);
474 return LLVMVoidType ();
476 return LLVMInt8Type ();
478 return LLVMInt16Type ();
480 return LLVMInt32Type ();
482 return LLVMInt8Type ();
484 return LLVMInt16Type ();
486 return LLVMInt32Type ();
489 return LLVMInt64Type ();
491 return LLVMFloatType ();
493 return LLVMDoubleType ();
496 return IntPtrType ();
497 case MONO_TYPE_OBJECT:
499 return ObjRefType ();
502 /* Because of generic sharing */
503 return ObjRefType ();
504 case MONO_TYPE_GENERICINST:
505 if (!mono_type_generic_inst_is_valuetype (t))
506 return ObjRefType ();
508 case MONO_TYPE_VALUETYPE:
509 case MONO_TYPE_TYPEDBYREF: {
513 klass = mono_class_from_mono_type (t);
515 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
516 return simd_class_to_llvm_type (ctx, klass);
519 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
521 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
523 ltype = create_llvm_type_for_type (ctx->module, klass);
524 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
530 printf ("X: %d\n", t->type);
531 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
532 ctx->cfg->disable_llvm = TRUE;
540 * Return whenever T is an unsigned int type.
543 type_is_unsigned (EmitContext *ctx, MonoType *t)
545 t = mini_get_underlying_type (t);
561 * type_to_llvm_arg_type:
563 * Same as type_to_llvm_type, but treat i8/i16 as i32.
566 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
568 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
570 if (ctx->cfg->llvm_only)
574 * This works on all abis except arm64/ios which passes multiple
575 * arguments in one stack slot.
578 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
580 * LLVM generates code which only sets the lower bits, while JITted
581 * code expects all the bits to be set.
583 ptype = LLVMInt32Type ();
591 * llvm_type_to_stack_type:
593 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
596 static G_GNUC_UNUSED LLVMTypeRef
597 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
601 if (type == LLVMInt8Type ())
602 return LLVMInt32Type ();
603 else if (type == LLVMInt16Type ())
604 return LLVMInt32Type ();
605 else if (!cfg->r4fp && type == LLVMFloatType ())
606 return LLVMDoubleType ();
612 * regtype_to_llvm_type:
614 * Return the LLVM type corresponding to the regtype C used in instruction
618 regtype_to_llvm_type (char c)
622 return LLVMInt32Type ();
624 return LLVMInt64Type ();
626 return LLVMDoubleType ();
635 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
638 op_to_llvm_type (int opcode)
643 return LLVMInt8Type ();
646 return LLVMInt8Type ();
649 return LLVMInt16Type ();
652 return LLVMInt16Type ();
655 return LLVMInt32Type ();
658 return LLVMInt32Type ();
660 return LLVMInt64Type ();
662 return LLVMFloatType ();
664 return LLVMDoubleType ();
666 return LLVMInt64Type ();
668 return LLVMInt32Type ();
670 return LLVMInt64Type ();
675 return LLVMInt8Type ();
680 return LLVMInt16Type ();
682 return LLVMInt32Type ();
685 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
692 return LLVMInt32Type ();
699 return LLVMInt64Type ();
701 printf ("%s\n", mono_inst_name (opcode));
702 g_assert_not_reached ();
707 #define CLAUSE_START(clause) ((clause)->try_offset)
708 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
711 * load_store_to_llvm_type:
713 * Return the size/sign/zero extension corresponding to the load/store opcode
717 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
723 case OP_LOADI1_MEMBASE:
724 case OP_STOREI1_MEMBASE_REG:
725 case OP_STOREI1_MEMBASE_IMM:
726 case OP_ATOMIC_LOAD_I1:
727 case OP_ATOMIC_STORE_I1:
730 return LLVMInt8Type ();
731 case OP_LOADU1_MEMBASE:
733 case OP_ATOMIC_LOAD_U1:
734 case OP_ATOMIC_STORE_U1:
737 return LLVMInt8Type ();
738 case OP_LOADI2_MEMBASE:
739 case OP_STOREI2_MEMBASE_REG:
740 case OP_STOREI2_MEMBASE_IMM:
741 case OP_ATOMIC_LOAD_I2:
742 case OP_ATOMIC_STORE_I2:
745 return LLVMInt16Type ();
746 case OP_LOADU2_MEMBASE:
748 case OP_ATOMIC_LOAD_U2:
749 case OP_ATOMIC_STORE_U2:
752 return LLVMInt16Type ();
753 case OP_LOADI4_MEMBASE:
754 case OP_LOADU4_MEMBASE:
757 case OP_STOREI4_MEMBASE_REG:
758 case OP_STOREI4_MEMBASE_IMM:
759 case OP_ATOMIC_LOAD_I4:
760 case OP_ATOMIC_STORE_I4:
761 case OP_ATOMIC_LOAD_U4:
762 case OP_ATOMIC_STORE_U4:
764 return LLVMInt32Type ();
765 case OP_LOADI8_MEMBASE:
767 case OP_STOREI8_MEMBASE_REG:
768 case OP_STOREI8_MEMBASE_IMM:
769 case OP_ATOMIC_LOAD_I8:
770 case OP_ATOMIC_STORE_I8:
771 case OP_ATOMIC_LOAD_U8:
772 case OP_ATOMIC_STORE_U8:
774 return LLVMInt64Type ();
775 case OP_LOADR4_MEMBASE:
776 case OP_STORER4_MEMBASE_REG:
777 case OP_ATOMIC_LOAD_R4:
778 case OP_ATOMIC_STORE_R4:
780 return LLVMFloatType ();
781 case OP_LOADR8_MEMBASE:
782 case OP_STORER8_MEMBASE_REG:
783 case OP_ATOMIC_LOAD_R8:
784 case OP_ATOMIC_STORE_R8:
786 return LLVMDoubleType ();
787 case OP_LOAD_MEMBASE:
789 case OP_STORE_MEMBASE_REG:
790 case OP_STORE_MEMBASE_IMM:
791 *size = sizeof (gpointer);
792 return IntPtrType ();
794 g_assert_not_reached ();
802 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
805 ovf_op_to_intrins (int opcode)
809 return "llvm.sadd.with.overflow.i32";
811 return "llvm.uadd.with.overflow.i32";
813 return "llvm.ssub.with.overflow.i32";
815 return "llvm.usub.with.overflow.i32";
817 return "llvm.smul.with.overflow.i32";
819 return "llvm.umul.with.overflow.i32";
821 return "llvm.sadd.with.overflow.i64";
823 return "llvm.uadd.with.overflow.i64";
825 return "llvm.ssub.with.overflow.i64";
827 return "llvm.usub.with.overflow.i64";
829 return "llvm.smul.with.overflow.i64";
831 return "llvm.umul.with.overflow.i64";
833 g_assert_not_reached ();
839 simd_op_to_intrins (int opcode)
842 #if defined(TARGET_X86) || defined(TARGET_AMD64)
844 return "llvm.x86.sse2.min.pd";
846 return "llvm.x86.sse.min.ps";
848 return "llvm.x86.sse2.max.pd";
850 return "llvm.x86.sse.max.ps";
852 return "llvm.x86.sse3.hadd.pd";
854 return "llvm.x86.sse3.hadd.ps";
856 return "llvm.x86.sse3.hsub.pd";
858 return "llvm.x86.sse3.hsub.ps";
860 return "llvm.x86.sse3.addsub.ps";
862 return "llvm.x86.sse3.addsub.pd";
863 case OP_EXTRACT_MASK:
864 return "llvm.x86.sse2.pmovmskb.128";
867 return "llvm.x86.sse2.psrli.w";
870 return "llvm.x86.sse2.psrli.d";
873 return "llvm.x86.sse2.psrli.q";
876 return "llvm.x86.sse2.pslli.w";
879 return "llvm.x86.sse2.pslli.d";
882 return "llvm.x86.sse2.pslli.q";
885 return "llvm.x86.sse2.psrai.w";
888 return "llvm.x86.sse2.psrai.d";
890 return "llvm.x86.sse2.padds.b";
892 return "llvm.x86.sse2.padds.w";
894 return "llvm.x86.sse2.psubs.b";
896 return "llvm.x86.sse2.psubs.w";
897 case OP_PADDB_SAT_UN:
898 return "llvm.x86.sse2.paddus.b";
899 case OP_PADDW_SAT_UN:
900 return "llvm.x86.sse2.paddus.w";
901 case OP_PSUBB_SAT_UN:
902 return "llvm.x86.sse2.psubus.b";
903 case OP_PSUBW_SAT_UN:
904 return "llvm.x86.sse2.psubus.w";
906 return "llvm.x86.sse2.pavg.b";
908 return "llvm.x86.sse2.pavg.w";
910 return "llvm.x86.sse.sqrt.ps";
912 return "llvm.x86.sse2.sqrt.pd";
914 return "llvm.x86.sse.rsqrt.ps";
916 return "llvm.x86.sse.rcp.ps";
918 return "llvm.x86.sse2.cvtdq2pd";
920 return "llvm.x86.sse2.cvtdq2ps";
922 return "llvm.x86.sse2.cvtpd2dq";
924 return "llvm.x86.sse2.cvtps2dq";
926 return "llvm.x86.sse2.cvtpd2ps";
928 return "llvm.x86.sse2.cvtps2pd";
930 return "llvm.x86.sse2.cvttpd2dq";
932 return "llvm.x86.sse2.cvttps2dq";
934 return "llvm.x86.sse2.packsswb.128";
936 return "llvm.x86.sse2.packssdw.128";
938 return "llvm.x86.sse2.packuswb.128";
940 return "llvm.x86.sse41.packusdw";
942 return "llvm.x86.sse2.pmulh.w";
943 case OP_PMULW_HIGH_UN:
944 return "llvm.x86.sse2.pmulhu.w";
946 return "llvm.x86.sse41.dpps";
949 g_assert_not_reached ();
955 simd_op_to_llvm_type (int opcode)
957 #if defined(TARGET_X86) || defined(TARGET_AMD64)
961 return type_to_simd_type (MONO_TYPE_R8);
964 return type_to_simd_type (MONO_TYPE_I8);
967 return type_to_simd_type (MONO_TYPE_I4);
972 return type_to_simd_type (MONO_TYPE_I2);
976 return type_to_simd_type (MONO_TYPE_I1);
978 return type_to_simd_type (MONO_TYPE_R4);
981 return type_to_simd_type (MONO_TYPE_I4);
985 return type_to_simd_type (MONO_TYPE_R8);
989 return type_to_simd_type (MONO_TYPE_R4);
990 case OP_EXTRACT_MASK:
991 return type_to_simd_type (MONO_TYPE_I1);
997 return type_to_simd_type (MONO_TYPE_R4);
1000 return type_to_simd_type (MONO_TYPE_R8);
1002 g_assert_not_reached ();
1013 * Return the LLVM basic block corresponding to BB.
1015 static LLVMBasicBlockRef
1016 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1018 char bb_name_buf [128];
1021 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1022 if (bb->flags & BB_EXCEPTION_HANDLER) {
1023 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1024 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1025 bb_name = bb_name_buf;
1026 } else if (bb->block_num < 256) {
1027 if (!ctx->module->bb_names) {
1028 ctx->module->bb_names_len = 256;
1029 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1031 if (!ctx->module->bb_names [bb->block_num]) {
1034 n = g_strdup_printf ("BB%d", bb->block_num);
1035 mono_memory_barrier ();
1036 ctx->module->bb_names [bb->block_num] = n;
1038 bb_name = ctx->module->bb_names [bb->block_num];
1040 sprintf (bb_name_buf, "BB%d", bb->block_num);
1041 bb_name = bb_name_buf;
1044 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1045 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1048 return ctx->bblocks [bb->block_num].bblock;
1054 * Return the last LLVM bblock corresponding to BB.
1055 * This might not be equal to the bb returned by get_bb () since we need to generate
1056 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1058 static LLVMBasicBlockRef
1059 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1062 return ctx->bblocks [bb->block_num].end_bblock;
1065 static LLVMBasicBlockRef
1066 gen_bb (EmitContext *ctx, const char *prefix)
1070 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1071 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1077 * Return the target of the patch identified by TYPE and TARGET.
1080 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1086 memset (&ji, 0, sizeof (ji));
1088 ji.data.target = target;
1090 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1091 mono_error_assert_ok (&error);
1099 * Emit code to convert the LLVM value V to DTYPE.
1102 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1104 LLVMTypeRef stype = LLVMTypeOf (v);
1106 if (stype != dtype) {
1107 gboolean ext = FALSE;
1110 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1112 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1114 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1118 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1120 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1121 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1124 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1125 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1126 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1127 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1128 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1129 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1130 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1131 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1133 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1134 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1135 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1136 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1137 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1138 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1140 if (mono_arch_is_soft_float ()) {
1141 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1142 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1143 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1144 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1147 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1148 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1151 LLVMDumpValue (LLVMConstNull (dtype));
1152 g_assert_not_reached ();
1160 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1162 return convert_full (ctx, v, dtype, FALSE);
1166 * emit_volatile_load:
1168 * If vreg is volatile, emit a load from its address.
1171 emit_volatile_load (EmitContext *ctx, int vreg)
1177 // FIXME: This hack is required because we pass the rgctx in a callee saved
1178 // register on arm64 (x15), and llvm might keep the value in that register
1179 // even through the register is marked as 'reserved' inside llvm.
1180 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1181 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1183 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1185 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1187 t = ctx->vreg_cli_types [vreg];
1188 if (t && !t->byref) {
1190 * Might have to zero extend since llvm doesn't have
1193 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1194 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1195 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1196 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1197 else if (t->type == MONO_TYPE_U8)
1198 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1205 * emit_volatile_store:
1207 * If VREG is volatile, emit a store from its value to its address.
1210 emit_volatile_store (EmitContext *ctx, int vreg)
1212 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1214 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1215 g_assert (ctx->addresses [vreg]);
1216 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1221 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1223 LLVMTypeRef ret_type;
1224 LLVMTypeRef *param_types = NULL;
1229 rtype = mini_get_underlying_type (sig->ret);
1230 ret_type = type_to_llvm_type (ctx, rtype);
1234 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1238 param_types [pindex ++] = ThisType ();
1239 for (i = 0; i < sig->param_count; ++i)
1240 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1242 if (!ctx_ok (ctx)) {
1243 g_free (param_types);
1247 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1248 g_free (param_types);
1254 * sig_to_llvm_sig_full:
1256 * Return the LLVM signature corresponding to the mono signature SIG using the
1257 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1260 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1262 LLVMTypeRef ret_type;
1263 LLVMTypeRef *param_types = NULL;
1265 int i, j, pindex, vret_arg_pindex = 0;
1266 gboolean vretaddr = FALSE;
1270 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1272 rtype = mini_get_underlying_type (sig->ret);
1273 ret_type = type_to_llvm_type (ctx, rtype);
1277 switch (cinfo->ret.storage) {
1278 case LLVMArgVtypeInReg:
1279 /* LLVM models this by returning an aggregate value */
1280 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1281 LLVMTypeRef members [2];
1283 members [0] = IntPtrType ();
1284 ret_type = LLVMStructType (members, 1, FALSE);
1285 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1287 ret_type = LLVMVoidType ();
1288 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1289 LLVMTypeRef members [2];
1291 members [0] = IntPtrType ();
1292 members [1] = IntPtrType ();
1293 ret_type = LLVMStructType (members, 2, FALSE);
1295 g_assert_not_reached ();
1298 case LLVMArgVtypeByVal:
1299 /* Vtype returned normally by val */
1301 case LLVMArgVtypeAsScalar: {
1302 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1303 /* LLVM models this by returning an int */
1304 if (size < SIZEOF_VOID_P) {
1305 g_assert (cinfo->ret.nslots == 1);
1306 ret_type = LLVMIntType (size * 8);
1308 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1309 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1313 case LLVMArgAsIArgs:
1314 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1316 case LLVMArgFpStruct: {
1317 /* Vtype returned as a fp struct */
1318 LLVMTypeRef members [16];
1320 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1321 for (i = 0; i < cinfo->ret.nslots; ++i)
1322 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1323 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1326 case LLVMArgVtypeByRef:
1327 /* Vtype returned using a hidden argument */
1328 ret_type = LLVMVoidType ();
1330 case LLVMArgVtypeRetAddr:
1331 case LLVMArgGsharedvtFixed:
1332 case LLVMArgGsharedvtFixedVtype:
1333 case LLVMArgGsharedvtVariable:
1335 ret_type = LLVMVoidType ();
1341 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1343 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1345 * Has to be the first argument because of the sret argument attribute
1346 * FIXME: This might conflict with passing 'this' as the first argument, but
1347 * this is only used on arm64 which has a dedicated struct return register.
1349 cinfo->vret_arg_pindex = pindex;
1350 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1351 if (!ctx_ok (ctx)) {
1352 g_free (param_types);
1355 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1358 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1359 cinfo->rgctx_arg_pindex = pindex;
1360 param_types [pindex] = ctx->module->ptr_type;
1363 if (cinfo->imt_arg) {
1364 cinfo->imt_arg_pindex = pindex;
1365 param_types [pindex] = ctx->module->ptr_type;
1369 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1370 vret_arg_pindex = pindex;
1371 if (cinfo->vret_arg_index == 1) {
1372 /* Add the slots consumed by the first argument */
1373 LLVMArgInfo *ainfo = &cinfo->args [0];
1374 switch (ainfo->storage) {
1375 case LLVMArgVtypeInReg:
1376 for (j = 0; j < 2; ++j) {
1377 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1386 cinfo->vret_arg_pindex = vret_arg_pindex;
1389 if (vretaddr && vret_arg_pindex == pindex)
1390 param_types [pindex ++] = IntPtrType ();
1392 cinfo->this_arg_pindex = pindex;
1393 param_types [pindex ++] = ThisType ();
1394 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1396 if (vretaddr && vret_arg_pindex == pindex)
1397 param_types [pindex ++] = IntPtrType ();
1398 for (i = 0; i < sig->param_count; ++i) {
1399 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1401 if (vretaddr && vret_arg_pindex == pindex)
1402 param_types [pindex ++] = IntPtrType ();
1403 ainfo->pindex = pindex;
1405 switch (ainfo->storage) {
1406 case LLVMArgVtypeInReg:
1407 for (j = 0; j < 2; ++j) {
1408 switch (ainfo->pair_storage [j]) {
1410 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1415 g_assert_not_reached ();
1419 case LLVMArgVtypeByVal:
1420 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1423 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1426 case LLVMArgAsIArgs:
1427 if (ainfo->esize == 8)
1428 param_types [pindex] = LLVMArrayType (LLVMInt64Type (), ainfo->nslots);
1430 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1433 case LLVMArgVtypeByRef:
1434 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1437 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1440 case LLVMArgAsFpArgs: {
1443 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1444 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1445 param_types [pindex ++] = LLVMDoubleType ();
1446 for (j = 0; j < ainfo->nslots; ++j)
1447 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1450 case LLVMArgVtypeAsScalar:
1451 g_assert_not_reached ();
1453 case LLVMArgGsharedvtFixed:
1454 case LLVMArgGsharedvtFixedVtype:
1455 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1457 case LLVMArgGsharedvtVariable:
1458 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1461 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1465 if (!ctx_ok (ctx)) {
1466 g_free (param_types);
1469 if (vretaddr && vret_arg_pindex == pindex)
1470 param_types [pindex ++] = IntPtrType ();
1471 if (ctx->llvm_only && cinfo->rgctx_arg) {
1472 /* Pass the rgctx as the last argument */
1473 cinfo->rgctx_arg_pindex = pindex;
1474 param_types [pindex] = ctx->module->ptr_type;
1478 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1479 g_free (param_types);
1485 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1487 return sig_to_llvm_sig_full (ctx, sig, NULL);
1491 * LLVMFunctionType1:
1493 * Create an LLVM function type from the arguments.
1495 static G_GNUC_UNUSED LLVMTypeRef
1496 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1499 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1503 * LLVMFunctionType1:
1505 * Create an LLVM function type from the arguments.
1507 static G_GNUC_UNUSED LLVMTypeRef
1508 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1509 LLVMTypeRef ParamType1,
1512 LLVMTypeRef param_types [1];
1514 param_types [0] = ParamType1;
1516 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1520 * LLVMFunctionType2:
1522 * Create an LLVM function type from the arguments.
1524 static G_GNUC_UNUSED LLVMTypeRef
1525 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1526 LLVMTypeRef ParamType1,
1527 LLVMTypeRef ParamType2,
1530 LLVMTypeRef param_types [2];
1532 param_types [0] = ParamType1;
1533 param_types [1] = ParamType2;
1535 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1539 * LLVMFunctionType3:
1541 * Create an LLVM function type from the arguments.
1543 static G_GNUC_UNUSED LLVMTypeRef
1544 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1545 LLVMTypeRef ParamType1,
1546 LLVMTypeRef ParamType2,
1547 LLVMTypeRef ParamType3,
1550 LLVMTypeRef param_types [3];
1552 param_types [0] = ParamType1;
1553 param_types [1] = ParamType2;
1554 param_types [2] = ParamType3;
1556 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1559 static G_GNUC_UNUSED LLVMTypeRef
1560 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1561 LLVMTypeRef ParamType1,
1562 LLVMTypeRef ParamType2,
1563 LLVMTypeRef ParamType3,
1564 LLVMTypeRef ParamType4,
1565 LLVMTypeRef ParamType5,
1568 LLVMTypeRef param_types [5];
1570 param_types [0] = ParamType1;
1571 param_types [1] = ParamType2;
1572 param_types [2] = ParamType3;
1573 param_types [3] = ParamType4;
1574 param_types [4] = ParamType5;
1576 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1582 * Create an LLVM builder and remember it so it can be freed later.
1584 static LLVMBuilderRef
1585 create_builder (EmitContext *ctx)
1587 LLVMBuilderRef builder = LLVMCreateBuilder ();
1589 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1595 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1600 case MONO_PATCH_INFO_INTERNAL_METHOD:
1601 name = g_strdup_printf ("jit_icall_%s", data);
1603 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1604 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1605 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1609 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1617 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1621 LLVMValueRef indexes [2];
1622 LLVMValueRef got_entry_addr, load;
1623 LLVMBuilderRef builder = ctx->builder;
1628 MonoJumpInfo tmp_ji;
1630 tmp_ji.data.target = data;
1632 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1634 ji->next = cfg->patch_info;
1635 cfg->patch_info = ji;
1637 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1638 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1640 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1641 * explicitly initialize it.
1643 if (!mono_aot_is_shared_got_offset (got_offset)) {
1644 //mono_print_ji (ji);
1646 ctx->has_got_access = TRUE;
1649 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1650 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1651 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1653 name = get_aotconst_name (type, data, got_offset);
1655 load = LLVMBuildLoad (builder, got_entry_addr, "");
1656 load = convert (ctx, load, llvm_type);
1657 LLVMSetValueName (load, name ? name : "");
1659 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1662 //set_invariant_load_flag (load);
1668 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1670 return get_aotconst_typed (ctx, type, data, NULL);
1674 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1676 LLVMValueRef callee;
1678 if (ctx->llvm_only) {
1679 callee_name = mono_aot_get_direct_call_symbol (type, data);
1681 /* Directly callable */
1683 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1685 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1687 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1689 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1691 /* LLVMTypeRef's are uniqued */
1692 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1693 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1695 g_free (callee_name);
1701 * Calls are made through the GOT.
1703 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1705 MonoJumpInfo *ji = NULL;
1707 callee_name = mono_aot_get_plt_symbol (type, data);
1711 if (ctx->cfg->compile_aot)
1712 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1713 mono_add_patch_info (ctx->cfg, 0, type, data);
1716 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1718 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1720 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1722 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1725 if (ctx->cfg->compile_aot) {
1726 ji = g_new0 (MonoJumpInfo, 1);
1728 ji->data.target = data;
1730 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1738 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1740 #if LLVM_API_VERSION > 100
1741 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1742 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1743 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1744 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1747 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1748 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1754 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1756 MonoMethodHeader *header = cfg->header;
1757 MonoExceptionClause *clause;
1761 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1762 return (bb->region >> 8) - 1;
1765 for (i = 0; i < header->num_clauses; ++i) {
1766 clause = &header->clauses [i];
1768 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1775 static MonoExceptionClause *
1776 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1778 if (bb == cfg->bb_init)
1780 // Since they're sorted by nesting we just need
1781 // the first one that the bb is a member of
1782 for (int i = 0; i < cfg->header->num_clauses; i++) {
1783 MonoExceptionClause *curr = &cfg->header->clauses [i];
1785 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1793 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1795 LLVMValueRef md_arg;
1798 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1799 md_arg = LLVMMDString ("mono", 4);
1800 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1804 set_invariant_load_flag (LLVMValueRef v)
1806 LLVMValueRef md_arg;
1808 const char *flag_name;
1810 // FIXME: Cache this
1811 flag_name = "invariant.load";
1812 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1813 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1814 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1820 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1824 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1826 MonoCompile *cfg = ctx->cfg;
1827 LLVMValueRef lcall = NULL;
1828 LLVMBuilderRef builder = *builder_ref;
1829 MonoExceptionClause *clause;
1831 if (ctx->llvm_only) {
1832 clause = get_most_deep_clause (cfg, ctx, bb);
1835 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1838 * Have to use an invoke instead of a call, branching to the
1839 * handler bblock of the clause containing this bblock.
1841 intptr_t key = CLAUSE_END(clause);
1843 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1845 // FIXME: Find the one that has the lowest end bound for the right start address
1846 // FIXME: Finally + nesting
1849 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1852 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1854 builder = ctx->builder = create_builder (ctx);
1855 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1857 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1861 int clause_index = get_handler_clause (cfg, bb);
1863 if (clause_index != -1) {
1864 MonoMethodHeader *header = cfg->header;
1865 MonoExceptionClause *ec = &header->clauses [clause_index];
1866 MonoBasicBlock *tblock;
1867 LLVMBasicBlockRef ex_bb, noex_bb;
1870 * Have to use an invoke instead of a call, branching to the
1871 * handler bblock of the clause containing this bblock.
1874 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1876 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1879 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1881 ex_bb = get_bb (ctx, tblock);
1883 noex_bb = gen_bb (ctx, "NOEX_BB");
1886 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1888 builder = ctx->builder = create_builder (ctx);
1889 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1891 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1896 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1897 ctx->builder = builder;
1901 *builder_ref = ctx->builder;
1907 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1909 const char *intrins_name;
1910 LLVMValueRef args [16], res;
1911 LLVMTypeRef addr_type;
1912 gboolean use_intrinsics = TRUE;
1914 #if LLVM_API_VERSION > 100
1915 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1916 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1919 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1920 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1921 *builder_ref = ctx->builder;
1922 use_intrinsics = FALSE;
1926 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1927 LLVMAtomicOrdering ordering;
1930 case LLVM_BARRIER_NONE:
1931 ordering = LLVMAtomicOrderingNotAtomic;
1933 case LLVM_BARRIER_ACQ:
1934 ordering = LLVMAtomicOrderingAcquire;
1936 case LLVM_BARRIER_SEQ:
1937 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1940 g_assert_not_reached ();
1945 * We handle loads which can fault by calling a mono specific intrinsic
1946 * using an invoke, so they are handled properly inside try blocks.
1947 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1948 * are marked with IntrReadArgMem.
1952 intrins_name = "llvm.mono.load.i8.p0i8";
1955 intrins_name = "llvm.mono.load.i16.p0i16";
1958 intrins_name = "llvm.mono.load.i32.p0i32";
1961 intrins_name = "llvm.mono.load.i64.p0i64";
1964 g_assert_not_reached ();
1967 addr_type = LLVMTypeOf (addr);
1968 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1969 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1972 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1973 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1974 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1975 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1977 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1978 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1979 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1980 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1987 * We emit volatile loads for loads which can fault, because otherwise
1988 * LLVM will generate invalid code when encountering a load from a
1991 if (barrier != LLVM_BARRIER_NONE)
1992 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1994 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1996 /* Mark it with a custom metadata */
1999 set_metadata_flag (res, "mono.faulting.load");
2007 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
2009 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
2013 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
2015 const char *intrins_name;
2016 LLVMValueRef args [16];
2017 gboolean use_intrinsics = TRUE;
2019 #if LLVM_API_VERSION > 100
2020 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
2021 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2022 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
2023 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
2024 *builder_ref = ctx->builder;
2025 use_intrinsics = FALSE;
2029 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2030 LLVMAtomicOrdering ordering;
2033 case LLVM_BARRIER_NONE:
2034 ordering = LLVMAtomicOrderingNotAtomic;
2036 case LLVM_BARRIER_REL:
2037 ordering = LLVMAtomicOrderingRelease;
2039 case LLVM_BARRIER_SEQ:
2040 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2043 g_assert_not_reached ();
2049 intrins_name = "llvm.mono.store.i8.p0i8";
2052 intrins_name = "llvm.mono.store.i16.p0i16";
2055 intrins_name = "llvm.mono.store.i32.p0i32";
2058 intrins_name = "llvm.mono.store.i64.p0i64";
2061 g_assert_not_reached ();
2064 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2065 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2066 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2071 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2072 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2073 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2074 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2076 if (barrier != LLVM_BARRIER_NONE)
2077 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2079 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2084 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2086 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2090 * emit_cond_system_exception:
2092 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2093 * Might set the ctx exception.
2096 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2098 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2099 LLVMBuilderRef builder;
2100 MonoClass *exc_class;
2101 LLVMValueRef args [2];
2102 LLVMValueRef callee;
2103 gboolean no_pc = FALSE;
2105 if (IS_TARGET_AMD64)
2106 /* Some platforms don't require the pc argument */
2109 ex_bb = gen_bb (ctx, "EX_BB");
2111 ex2_bb = gen_bb (ctx, "EX2_BB");
2112 noex_bb = gen_bb (ctx, "NOEX_BB");
2114 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2116 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2118 /* Emit exception throwing code */
2119 ctx->builder = builder = create_builder (ctx);
2120 LLVMPositionBuilderAtEnd (builder, ex_bb);
2122 if (ctx->cfg->llvm_only) {
2123 static LLVMTypeRef sig;
2126 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2127 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2129 LLVMBuildBr (builder, ex2_bb);
2131 ctx->builder = builder = create_builder (ctx);
2132 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2134 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2135 emit_call (ctx, bb, &builder, callee, args, 1);
2136 LLVMBuildUnreachable (builder);
2138 ctx->builder = builder = create_builder (ctx);
2139 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2141 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2147 callee = ctx->module->throw_corlib_exception;
2150 const char *icall_name;
2153 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2155 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2156 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2158 if (ctx->cfg->compile_aot) {
2159 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2162 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2163 * - On x86, LLVM generated code doesn't push the arguments
2164 * - The trampoline takes the throw address as an arguments, not a pc offset.
2166 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2167 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2169 #if LLVM_API_VERSION > 100
2171 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2172 * added by emit_jit_callee ().
2174 ex2_bb = gen_bb (ctx, "EX2_BB");
2175 LLVMBuildBr (builder, ex2_bb);
2178 ctx->builder = builder = create_builder (ctx);
2179 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2181 mono_memory_barrier ();
2182 ctx->module->throw_corlib_exception = callee;
2187 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2190 * The LLVM mono branch contains changes so a block address can be passed as an
2191 * argument to a call.
2194 emit_call (ctx, bb, &builder, callee, args, 1);
2196 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2197 emit_call (ctx, bb, &builder, callee, args, 2);
2200 LLVMBuildUnreachable (builder);
2202 ctx->builder = builder = create_builder (ctx);
2203 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2205 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2212 * emit_args_to_vtype:
2214 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2217 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2219 int j, size, nslots;
2221 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2223 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2224 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2227 if (ainfo->storage == LLVMArgAsFpArgs)
2228 nslots = ainfo->nslots;
2232 for (j = 0; j < nslots; ++j) {
2233 LLVMValueRef index [2], addr, daddr;
2234 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2235 LLVMTypeRef part_type;
2237 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2240 if (ainfo->pair_storage [j] == LLVMArgNone)
2243 switch (ainfo->pair_storage [j]) {
2244 case LLVMArgInIReg: {
2245 part_type = LLVMIntType (part_size * 8);
2246 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2247 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2248 addr = LLVMBuildGEP (builder, address, index, 1, "");
2250 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2251 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2252 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2254 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2257 case LLVMArgInFPReg: {
2258 LLVMTypeRef arg_type;
2260 if (ainfo->esize == 8)
2261 arg_type = LLVMDoubleType ();
2263 arg_type = LLVMFloatType ();
2265 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2266 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2267 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2268 LLVMBuildStore (builder, args [j], addr);
2274 g_assert_not_reached ();
2277 size -= sizeof (gpointer);
2282 * emit_vtype_to_args:
2284 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2285 * into ARGS, and the number of arguments into NARGS.
2288 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2291 int j, size, nslots;
2292 LLVMTypeRef arg_type;
2294 size = get_vtype_size (t);
2296 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2297 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2299 if (ainfo->storage == LLVMArgAsFpArgs)
2300 nslots = ainfo->nslots;
2303 for (j = 0; j < nslots; ++j) {
2304 LLVMValueRef index [2], addr, daddr;
2305 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2307 if (ainfo->pair_storage [j] == LLVMArgNone)
2310 switch (ainfo->pair_storage [j]) {
2312 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2313 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2314 addr = LLVMBuildGEP (builder, address, index, 1, "");
2316 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2317 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2318 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2320 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2322 case LLVMArgInFPReg:
2323 if (ainfo->esize == 8)
2324 arg_type = LLVMDoubleType ();
2326 arg_type = LLVMFloatType ();
2327 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2328 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2329 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2330 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2335 g_assert_not_reached ();
2337 size -= sizeof (gpointer);
2344 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2347 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2348 * get executed every time control reaches them.
2350 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2352 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2353 return ctx->last_alloca;
2357 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2359 return build_alloca_llvm_type_name (ctx, t, align, "");
2363 build_alloca (EmitContext *ctx, MonoType *t)
2365 MonoClass *k = mono_class_from_mono_type (t);
2368 g_assert (!mini_is_gsharedvt_variable_type (t));
2370 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2373 align = mono_class_min_align (k);
2375 /* Sometimes align is not a power of 2 */
2376 while (mono_is_power_of_two (align) == -1)
2379 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2383 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2387 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2389 MonoCompile *cfg = ctx->cfg;
2390 LLVMBuilderRef builder = ctx->builder;
2391 LLVMValueRef offset, offset_var;
2392 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2393 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2397 g_assert (info_var);
2398 g_assert (locals_var);
2400 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2402 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2403 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2405 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2406 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2408 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2412 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2415 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2418 module->used = g_ptr_array_sized_new (16);
2419 g_ptr_array_add (module->used, global);
2423 emit_llvm_used (MonoLLVMModule *module)
2425 LLVMModuleRef lmodule = module->lmodule;
2426 LLVMTypeRef used_type;
2427 LLVMValueRef used, *used_elem;
2433 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2434 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2435 used_elem = g_new0 (LLVMValueRef, module->used->len);
2436 for (i = 0; i < module->used->len; ++i)
2437 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2438 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2439 LLVMSetLinkage (used, LLVMAppendingLinkage);
2440 LLVMSetSection (used, "llvm.metadata");
2446 * Emit a function mapping method indexes to their code
2449 emit_get_method (MonoLLVMModule *module)
2451 LLVMModuleRef lmodule = module->lmodule;
2452 LLVMValueRef func, switch_ins, m;
2453 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2454 LLVMBasicBlockRef *bbs;
2456 LLVMBuilderRef builder = LLVMCreateBuilder ();
2461 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2462 * but generating code seems safer.
2464 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2465 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2466 LLVMSetLinkage (func, LLVMExternalLinkage);
2467 LLVMSetVisibility (func, LLVMHiddenVisibility);
2468 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2469 module->get_method = func;
2471 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2474 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2475 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2476 * then we will have to find another solution.
2479 name = g_strdup_printf ("BB_CODE_START");
2480 code_start_bb = LLVMAppendBasicBlock (func, name);
2482 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2483 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2485 name = g_strdup_printf ("BB_CODE_END");
2486 code_end_bb = LLVMAppendBasicBlock (func, name);
2488 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2489 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2491 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2492 for (i = 0; i < module->max_method_idx + 1; ++i) {
2493 name = g_strdup_printf ("BB_%d", i);
2494 bb = LLVMAppendBasicBlock (func, name);
2498 LLVMPositionBuilderAtEnd (builder, bb);
2500 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2502 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2504 LLVMBuildRet (builder, LLVMConstNull (rtype));
2507 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2508 LLVMPositionBuilderAtEnd (builder, fail_bb);
2509 LLVMBuildRet (builder, LLVMConstNull (rtype));
2511 LLVMPositionBuilderAtEnd (builder, entry_bb);
2513 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2514 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2515 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2516 for (i = 0; i < module->max_method_idx + 1; ++i) {
2517 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2520 mark_as_used (module, func);
2522 LLVMDisposeBuilder (builder);
2526 * emit_get_unbox_tramp:
2528 * Emit a function mapping method indexes to their unbox trampoline
2531 emit_get_unbox_tramp (MonoLLVMModule *module)
2533 LLVMModuleRef lmodule = module->lmodule;
2534 LLVMValueRef func, switch_ins, m;
2535 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2536 LLVMBasicBlockRef *bbs;
2538 LLVMBuilderRef builder = LLVMCreateBuilder ();
2542 /* Similar to emit_get_method () */
2544 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2545 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2546 LLVMSetLinkage (func, LLVMExternalLinkage);
2547 LLVMSetVisibility (func, LLVMHiddenVisibility);
2548 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2549 module->get_unbox_tramp = func;
2551 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2553 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2554 for (i = 0; i < module->max_method_idx + 1; ++i) {
2555 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2559 name = g_strdup_printf ("BB_%d", i);
2560 bb = LLVMAppendBasicBlock (func, name);
2564 LLVMPositionBuilderAtEnd (builder, bb);
2566 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2569 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2570 LLVMPositionBuilderAtEnd (builder, fail_bb);
2571 LLVMBuildRet (builder, LLVMConstNull (rtype));
2573 LLVMPositionBuilderAtEnd (builder, entry_bb);
2575 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2576 for (i = 0; i < module->max_method_idx + 1; ++i) {
2577 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2581 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2584 mark_as_used (module, func);
2585 LLVMDisposeBuilder (builder);
2588 /* Add a function to mark the beginning of LLVM code */
2590 emit_llvm_code_start (MonoLLVMModule *module)
2592 LLVMModuleRef lmodule = module->lmodule;
2594 LLVMBasicBlockRef entry_bb;
2595 LLVMBuilderRef builder;
2597 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2598 LLVMSetLinkage (func, LLVMInternalLinkage);
2599 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2600 module->code_start = func;
2601 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2602 builder = LLVMCreateBuilder ();
2603 LLVMPositionBuilderAtEnd (builder, entry_bb);
2604 LLVMBuildRetVoid (builder);
2605 LLVMDisposeBuilder (builder);
2609 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2611 LLVMModuleRef lmodule = module->lmodule;
2612 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2613 LLVMBasicBlockRef entry_bb;
2614 LLVMBuilderRef builder;
2621 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2622 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2627 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2628 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2631 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2632 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2635 g_assert_not_reached ();
2637 LLVMSetLinkage (func, LLVMInternalLinkage);
2638 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2639 mono_llvm_set_preserveall_cc (func);
2640 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2641 builder = LLVMCreateBuilder ();
2642 LLVMPositionBuilderAtEnd (builder, entry_bb);
2645 ji = g_new0 (MonoJumpInfo, 1);
2646 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2647 ji = mono_aot_patch_info_dup (ji);
2648 got_offset = mono_aot_get_got_offset (ji);
2649 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2650 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2651 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2652 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2653 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2654 args [1] = LLVMGetParam (func, 0);
2656 args [2] = LLVMGetParam (func, 1);
2658 ji = g_new0 (MonoJumpInfo, 1);
2659 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2660 ji->data.name = icall_name;
2661 ji = mono_aot_patch_info_dup (ji);
2662 got_offset = mono_aot_get_got_offset (ji);
2663 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2664 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2665 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2666 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2667 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2668 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2669 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2671 // Set the inited flag
2672 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2673 indexes [1] = LLVMGetParam (func, 0);
2674 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2676 LLVMBuildRetVoid (builder);
2678 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2679 LLVMDisposeBuilder (builder);
2684 * Emit wrappers around the C icalls used to initialize llvm methods, to
2685 * make the calling code smaller and to enable usage of the llvm
2686 * PreserveAll calling convention.
2689 emit_init_icall_wrappers (MonoLLVMModule *module)
2691 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2692 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2693 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2694 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2698 emit_llvm_code_end (MonoLLVMModule *module)
2700 LLVMModuleRef lmodule = module->lmodule;
2702 LLVMBasicBlockRef entry_bb;
2703 LLVMBuilderRef builder;
2705 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2706 LLVMSetLinkage (func, LLVMInternalLinkage);
2707 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2708 module->code_end = func;
2709 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2710 builder = LLVMCreateBuilder ();
2711 LLVMPositionBuilderAtEnd (builder, entry_bb);
2712 LLVMBuildRetVoid (builder);
2713 LLVMDisposeBuilder (builder);
2717 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2719 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2722 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2723 need_div_check = TRUE;
2725 if (!need_div_check)
2728 switch (ins->opcode) {
2741 case OP_IDIV_UN_IMM:
2742 case OP_LDIV_UN_IMM:
2743 case OP_IREM_UN_IMM:
2744 case OP_LREM_UN_IMM: {
2746 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2747 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2749 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2750 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2753 builder = ctx->builder;
2755 /* b == -1 && a == 0x80000000 */
2757 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2758 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2759 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2761 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2762 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2765 builder = ctx->builder;
2777 * Emit code to initialize the GOT slots used by the method.
2780 emit_init_method (EmitContext *ctx)
2782 LLVMValueRef indexes [16], args [16], callee;
2783 LLVMValueRef inited_var, cmp, call;
2784 LLVMBasicBlockRef inited_bb, notinited_bb;
2785 LLVMBuilderRef builder = ctx->builder;
2786 MonoCompile *cfg = ctx->cfg;
2788 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2790 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2791 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2792 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2794 args [0] = inited_var;
2795 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2796 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2798 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2800 inited_bb = ctx->inited_bb;
2801 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2803 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2805 builder = ctx->builder = create_builder (ctx);
2806 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2809 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2810 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2811 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2812 callee = ctx->module->init_method_gshared_mrgctx;
2813 call = LLVMBuildCall (builder, callee, args, 2, "");
2814 } else if (ctx->rgctx_arg) {
2815 /* A vtable is passed as the rgctx argument */
2816 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2817 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2818 callee = ctx->module->init_method_gshared_vtable;
2819 call = LLVMBuildCall (builder, callee, args, 2, "");
2820 } else if (cfg->gshared) {
2821 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2822 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2823 callee = ctx->module->init_method_gshared_this;
2824 call = LLVMBuildCall (builder, callee, args, 2, "");
2826 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2827 callee = ctx->module->init_method;
2828 call = LLVMBuildCall (builder, callee, args, 1, "");
2832 * This enables llvm to keep arguments in their original registers/
2833 * scratch registers, since the call will not clobber them.
2835 mono_llvm_set_call_preserveall_cc (call);
2837 LLVMBuildBr (builder, inited_bb);
2838 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2840 builder = ctx->builder = create_builder (ctx);
2841 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2845 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2848 * Emit unbox trampoline using a tail call
2850 LLVMValueRef tramp, call, *args;
2851 LLVMBuilderRef builder;
2852 LLVMBasicBlockRef lbb;
2853 LLVMCallInfo *linfo;
2857 tramp_name = g_strdup_printf ("ut_%s", method_name);
2858 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2859 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2860 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2861 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2863 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2864 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2865 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2866 if (ctx->cfg->vret_addr) {
2867 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2868 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2869 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2870 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2874 lbb = LLVMAppendBasicBlock (tramp, "");
2875 builder = LLVMCreateBuilder ();
2876 LLVMPositionBuilderAtEnd (builder, lbb);
2878 nargs = LLVMCountParamTypes (method_type);
2879 args = g_new0 (LLVMValueRef, nargs);
2880 for (i = 0; i < nargs; ++i) {
2881 args [i] = LLVMGetParam (tramp, i);
2882 if (i == ctx->this_arg_pindex) {
2883 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2885 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2886 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2887 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2890 call = LLVMBuildCall (builder, method, args, nargs, "");
2891 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2892 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2893 if (linfo->ret.storage == LLVMArgVtypeByRef)
2894 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2896 // FIXME: This causes assertions in clang
2897 //mono_llvm_set_must_tail (call);
2898 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2899 LLVMBuildRetVoid (builder);
2901 LLVMBuildRet (builder, call);
2903 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2904 LLVMDisposeBuilder (builder);
2910 * Emit code to load/convert arguments.
2913 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2916 MonoCompile *cfg = ctx->cfg;
2917 MonoMethodSignature *sig = ctx->sig;
2918 LLVMCallInfo *linfo = ctx->linfo;
2922 LLVMBuilderRef old_builder = ctx->builder;
2923 ctx->builder = builder;
2925 ctx->alloca_builder = create_builder (ctx);
2928 * Handle indirect/volatile variables by allocating memory for them
2929 * using 'alloca', and storing their address in a temporary.
2931 for (i = 0; i < cfg->num_varinfo; ++i) {
2932 MonoInst *var = cfg->varinfo [i];
2935 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2936 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2937 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2940 /* Could be already created by an OP_VPHI */
2941 if (!ctx->addresses [var->dreg]) {
2942 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2943 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2945 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2949 names = g_new (char *, sig->param_count);
2950 mono_method_get_param_names (cfg->method, (const char **) names);
2952 for (i = 0; i < sig->param_count; ++i) {
2953 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2954 int reg = cfg->args [i + sig->hasthis]->dreg;
2957 pindex = ainfo->pindex;
2959 switch (ainfo->storage) {
2960 case LLVMArgVtypeInReg:
2961 case LLVMArgAsFpArgs: {
2962 LLVMValueRef args [8];
2965 pindex += ainfo->ndummy_fpargs;
2967 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2968 memset (args, 0, sizeof (args));
2969 if (ainfo->storage == LLVMArgVtypeInReg) {
2970 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2971 if (ainfo->pair_storage [1] != LLVMArgNone)
2972 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2974 g_assert (ainfo->nslots <= 8);
2975 for (j = 0; j < ainfo->nslots; ++j)
2976 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2978 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2980 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2982 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2983 /* Treat these as normal values */
2984 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2988 case LLVMArgVtypeByVal: {
2989 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2991 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2992 /* Treat these as normal values */
2993 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2997 case LLVMArgVtypeByRef: {
2998 /* The argument is passed by ref */
2999 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3002 case LLVMArgAsIArgs: {
3003 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3006 /* The argument is received as an array of ints, store it into the real argument */
3007 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
3009 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
3010 if (size < SIZEOF_VOID_P) {
3011 /* The upper bits of the registers might not be valid */
3012 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
3013 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
3014 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
3016 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
3020 case LLVMArgVtypeAsScalar:
3021 g_assert_not_reached ();
3023 case LLVMArgGsharedvtFixed: {
3024 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3025 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3028 name = g_strdup_printf ("arg_%s", names [i]);
3030 name = g_strdup_printf ("arg_%d", i);
3032 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3035 case LLVMArgGsharedvtFixedVtype: {
3036 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3039 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3041 name = g_strdup_printf ("vtype_arg_%d", i);
3043 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3044 g_assert (ctx->addresses [reg]);
3045 LLVMSetValueName (ctx->addresses [reg], name);
3046 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3049 case LLVMArgGsharedvtVariable:
3050 /* The IR treats these as variables with addresses */
3051 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3054 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
3061 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3063 emit_volatile_store (ctx, cfg->args [0]->dreg);
3064 for (i = 0; i < sig->param_count; ++i)
3065 if (!mini_type_is_vtype (sig->params [i]))
3066 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3068 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3069 LLVMValueRef this_alloc;
3072 * The exception handling code needs the location where the this argument was
3073 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3074 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3075 * location into the LSDA.
3077 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3078 /* This volatile store will keep the alloca alive */
3079 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3081 set_metadata_flag (this_alloc, "mono.this");
3084 if (cfg->rgctx_var) {
3085 LLVMValueRef rgctx_alloc, store;
3088 * We handle the rgctx arg similarly to the this pointer.
3090 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3091 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3092 /* This volatile store will keep the alloca alive */
3093 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3095 set_metadata_flag (rgctx_alloc, "mono.this");
3098 /* Initialize the method if needed */
3099 if (cfg->compile_aot && ctx->llvm_only) {
3100 /* Emit a location for the initialization code */
3101 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3102 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3104 LLVMBuildBr (ctx->builder, ctx->init_bb);
3105 builder = ctx->builder = create_builder (ctx);
3106 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3107 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3110 /* Compute nesting between clauses */
3111 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3112 for (i = 0; i < cfg->header->num_clauses; ++i) {
3113 for (j = 0; j < cfg->header->num_clauses; ++j) {
3114 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3115 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3117 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3118 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3123 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3124 * it needs to continue normally, or return back to the exception handling system.
3126 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3130 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3133 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3134 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3135 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3137 if (bb->in_scount == 0) {
3140 sprintf (name, "finally_ind_bb%d", bb->block_num);
3141 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3142 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3144 ctx->bblocks [bb->block_num].finally_ind = val;
3146 /* Create a variable to hold the exception var */
3148 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3152 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3153 * LLVM bblock containing a landing pad causes problems for the
3154 * LLVM optimizer passes.
3156 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3157 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3159 ctx->builder = old_builder;
3163 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3165 MonoCompile *cfg = ctx->cfg;
3166 LLVMValueRef *values = ctx->values;
3167 LLVMValueRef *addresses = ctx->addresses;
3168 MonoCallInst *call = (MonoCallInst*)ins;
3169 MonoMethodSignature *sig = call->signature;
3170 LLVMValueRef callee = NULL, lcall;
3172 LLVMCallInfo *cinfo;
3176 LLVMTypeRef llvm_sig;
3178 gboolean is_virtual, calli, preserveall;
3179 LLVMBuilderRef builder = *builder_ref;
3181 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3182 set_failure (ctx, "non-default callconv");
3186 cinfo = call->cinfo;
3188 if (call->rgctx_arg_reg)
3189 cinfo->rgctx_arg = TRUE;
3190 if (call->imt_arg_reg)
3191 cinfo->imt_arg = TRUE;
3193 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3195 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3199 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3200 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3202 preserveall = FALSE;
3204 /* FIXME: Avoid creating duplicate methods */
3206 if (ins->flags & MONO_INST_HAS_METHOD) {
3210 if (cfg->compile_aot) {
3211 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3213 set_failure (ctx, "can't encode patch");
3216 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3218 * Collect instructions representing the callee into a hash so they can be replaced
3219 * by the llvm method for the callee if the callee turns out to be direct
3220 * callable. Currently this only requires it to not fail llvm compilation.
3222 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3223 l = g_slist_prepend (l, callee);
3224 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3228 static int tramp_index;
3231 name = g_strdup_printf ("tramp_%d", tramp_index);
3234 #if LLVM_API_VERSION > 100
3236 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3237 * Make all calls through a global. The address of the global will be saved in
3238 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3241 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3244 mono_create_jit_trampoline (mono_domain_get (),
3245 call->method, &error);
3246 if (!is_ok (&error)) {
3247 set_failure (ctx, mono_error_get_message (&error));
3248 mono_error_cleanup (&error);
3252 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3253 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3254 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3255 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3257 callee = LLVMBuildLoad (builder, tramp_var, "");
3260 mono_create_jit_trampoline (mono_domain_get (),
3261 call->method, &error);
3262 if (!is_ok (&error)) {
3264 set_failure (ctx, mono_error_get_message (&error));
3265 mono_error_cleanup (&error);
3269 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3272 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3277 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3278 /* LLVM miscompiles async methods */
3279 set_failure (ctx, "#13734");
3284 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3290 memset (&ji, 0, sizeof (ji));
3291 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3292 ji.data.target = info->name;
3294 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3296 if (cfg->compile_aot) {
3297 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3299 set_failure (ctx, "can't encode patch");
3303 target = (gpointer)mono_icall_get_wrapper (info);
3304 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3307 if (cfg->compile_aot) {
3309 if (cfg->abs_patches) {
3310 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3312 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3314 set_failure (ctx, "can't encode patch");
3320 set_failure (ctx, "aot");
3324 #if LLVM_API_VERSION > 100
3325 if (cfg->abs_patches) {
3326 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3330 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3331 mono_error_assert_ok (&error);
3332 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3334 g_assert_not_reached ();
3337 g_assert_not_reached ();
3340 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3342 if (cfg->abs_patches) {
3343 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3348 * FIXME: Some trampolines might have
3349 * their own calling convention on some platforms.
3351 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3352 mono_error_assert_ok (&error);
3353 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3357 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3364 int size = sizeof (gpointer);
3367 g_assert (ins->inst_offset % size == 0);
3368 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3370 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3372 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3374 if (ins->flags & MONO_INST_HAS_METHOD) {
3379 * Collect and convert arguments
3381 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3382 len = sizeof (LLVMValueRef) * nargs;
3383 args = (LLVMValueRef*)alloca (len);
3384 memset (args, 0, len);
3385 l = call->out_ireg_args;
3387 if (call->rgctx_arg_reg) {
3388 g_assert (values [call->rgctx_arg_reg]);
3389 g_assert (cinfo->rgctx_arg_pindex < nargs);
3391 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3392 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3393 * it using a volatile load.
3396 if (!ctx->imt_rgctx_loc)
3397 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3398 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3399 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3401 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3404 if (call->imt_arg_reg) {
3405 g_assert (!ctx->llvm_only);
3406 g_assert (values [call->imt_arg_reg]);
3407 g_assert (cinfo->imt_arg_pindex < nargs);
3409 if (!ctx->imt_rgctx_loc)
3410 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3411 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3412 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3414 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3417 switch (cinfo->ret.storage) {
3418 case LLVMArgGsharedvtVariable: {
3419 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3421 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3422 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3424 g_assert (addresses [call->inst.dreg]);
3425 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3431 if (!addresses [call->inst.dreg])
3432 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3433 g_assert (cinfo->vret_arg_pindex < nargs);
3434 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3435 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3437 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3443 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3444 * use the real callee for argument type conversion.
3446 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3447 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3448 LLVMGetParamTypes (callee_type, param_types);
3450 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3453 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3455 pindex = ainfo->pindex;
3457 regpair = (guint32)(gssize)(l->data);
3458 reg = regpair & 0xffffff;
3459 args [pindex] = values [reg];
3460 switch (ainfo->storage) {
3461 case LLVMArgVtypeInReg:
3462 case LLVMArgAsFpArgs: {
3466 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3467 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3468 pindex += ainfo->ndummy_fpargs;
3470 g_assert (addresses [reg]);
3471 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3475 // FIXME: Get rid of the VMOVE
3478 case LLVMArgVtypeByVal:
3479 g_assert (addresses [reg]);
3480 args [pindex] = addresses [reg];
3482 case LLVMArgVtypeByRef: {
3483 g_assert (addresses [reg]);
3484 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3487 case LLVMArgAsIArgs:
3488 g_assert (addresses [reg]);
3489 if (ainfo->esize == 8)
3490 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (LLVMInt64Type (), ainfo->nslots), 0)), "");
3492 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3494 case LLVMArgVtypeAsScalar:
3495 g_assert_not_reached ();
3497 case LLVMArgGsharedvtFixed:
3498 case LLVMArgGsharedvtFixedVtype:
3499 g_assert (addresses [reg]);
3500 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3502 case LLVMArgGsharedvtVariable:
3503 g_assert (addresses [reg]);
3504 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3507 g_assert (args [pindex]);
3508 if (i == 0 && sig->hasthis)
3509 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3511 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3514 g_assert (pindex <= nargs);
3519 // FIXME: Align call sites
3525 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3527 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3528 mono_llvm_set_call_notail (lcall);
3531 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3533 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3534 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3536 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3537 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3538 if (!sig->pinvoke && !cfg->llvm_only)
3539 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3541 mono_llvm_set_call_preserveall_cc (lcall);
3543 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3544 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3545 if (!ctx->llvm_only && call->rgctx_arg_reg)
3546 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3547 if (call->imt_arg_reg)
3548 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3550 /* Add byval attributes if needed */
3551 for (i = 0; i < sig->param_count; ++i) {
3552 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3554 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3555 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3559 * Convert the result
3561 switch (cinfo->ret.storage) {
3562 case LLVMArgVtypeInReg: {
3563 LLVMValueRef regs [2];
3565 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3569 if (!addresses [ins->dreg])
3570 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3572 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3573 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3574 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3575 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3578 case LLVMArgVtypeByVal:
3579 if (!addresses [call->inst.dreg])
3580 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3581 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3583 case LLVMArgAsIArgs:
3584 case LLVMArgFpStruct:
3585 if (!addresses [call->inst.dreg])
3586 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3587 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3589 case LLVMArgVtypeAsScalar:
3590 if (!addresses [call->inst.dreg])
3591 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3592 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3594 case LLVMArgVtypeRetAddr:
3595 case LLVMArgVtypeByRef:
3596 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3597 /* Some opcodes like STOREX_MEMBASE access these by value */
3598 g_assert (addresses [call->inst.dreg]);
3599 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3602 case LLVMArgGsharedvtVariable:
3604 case LLVMArgGsharedvtFixed:
3605 case LLVMArgGsharedvtFixedVtype:
3606 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3609 if (sig->ret->type != MONO_TYPE_VOID)
3610 /* If the method returns an unsigned value, need to zext it */
3611 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
3615 *builder_ref = ctx->builder;
3619 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3621 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3622 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3624 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3627 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3629 if (ctx->cfg->compile_aot) {
3630 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3632 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3633 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3634 mono_memory_barrier ();
3637 ctx->module->rethrow = callee;
3639 ctx->module->throw_icall = callee;
3643 LLVMValueRef args [2];
3645 args [0] = convert (ctx, exc, exc_type);
3646 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3648 LLVMBuildUnreachable (ctx->builder);
3650 ctx->builder = create_builder (ctx);
3654 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3656 MonoMethodSignature *throw_sig;
3657 LLVMValueRef callee, arg;
3658 const char *icall_name;
3660 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3661 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3664 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3665 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3666 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3667 if (ctx->cfg->compile_aot) {
3668 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3673 * LLVM doesn't push the exception argument, so we need a different
3676 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3678 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3680 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3683 mono_memory_barrier ();
3684 #if LLVM_API_VERSION < 100
3686 ctx->module->rethrow = callee;
3688 ctx->module->throw_icall = callee;
3691 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3692 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3696 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3698 const char *icall_name = "mono_llvm_resume_exception";
3699 LLVMValueRef callee = ctx->module->resume_eh;
3701 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3704 if (ctx->cfg->compile_aot) {
3705 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3707 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3708 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3709 mono_memory_barrier ();
3711 ctx->module->resume_eh = callee;
3715 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3717 LLVMBuildUnreachable (ctx->builder);
3719 ctx->builder = create_builder (ctx);
3723 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3725 const char *icall_name = "mono_llvm_clear_exception";
3727 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3728 LLVMValueRef callee = NULL;
3731 if (ctx->cfg->compile_aot) {
3732 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3734 // FIXME: This is broken.
3735 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3739 g_assert (builder && callee);
3741 return LLVMBuildCall (builder, callee, NULL, 0, "");
3745 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3747 const char *icall_name = "mono_llvm_load_exception";
3749 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3750 LLVMValueRef callee = NULL;
3753 if (ctx->cfg->compile_aot) {
3754 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3756 // FIXME: This is broken.
3757 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3761 g_assert (builder && callee);
3763 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3768 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3770 const char *icall_name = "mono_llvm_match_exception";
3772 ctx->builder = builder;
3774 const int num_args = 5;
3775 LLVMValueRef args [num_args];
3776 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3777 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3778 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3779 if (ctx->cfg->rgctx_var) {
3780 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3781 g_assert (rgctx_alloc);
3782 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3784 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3787 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3789 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3791 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3792 LLVMValueRef callee = ctx->module->match_exc;
3795 if (ctx->cfg->compile_aot) {
3796 ctx->builder = builder;
3797 // get_callee expects ctx->builder to be the emitting builder
3798 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3800 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3801 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3802 ctx->module->match_exc = callee;
3803 mono_memory_barrier ();
3807 g_assert (builder && callee);
3809 g_assert (ctx->ex_var);
3811 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3814 // FIXME: This won't work because the code-finding makes this
3816 /*#define MONO_PERSONALITY_DEBUG*/
3818 #ifdef MONO_PERSONALITY_DEBUG
3819 static const gboolean use_debug_personality = TRUE;
3820 static const char *default_personality_name = "mono_debug_personality";
3822 static const gboolean use_debug_personality = FALSE;
3823 static const char *default_personality_name = "__gxx_personality_v0";
3827 default_cpp_lpad_exc_signature (void)
3829 static gboolean inited = FALSE;
3830 static LLVMTypeRef sig;
3833 LLVMTypeRef signature [2];
3834 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3835 signature [1] = LLVMInt32Type ();
3836 sig = LLVMStructType (signature, 2, FALSE);
3844 get_mono_personality (EmitContext *ctx)
3846 LLVMValueRef personality = NULL;
3847 static gint32 mapping_inited = FALSE;
3848 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3850 if (!use_debug_personality) {
3851 if (ctx->cfg->compile_aot) {
3852 personality = get_intrinsic (ctx, default_personality_name);
3853 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3854 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3855 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3858 if (ctx->cfg->compile_aot) {
3859 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3861 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3862 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3863 mono_memory_barrier ();
3867 g_assert (personality);
3871 static LLVMBasicBlockRef
3872 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3874 MonoCompile *cfg = ctx->cfg;
3875 LLVMBuilderRef old_builder = ctx->builder;
3876 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3878 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3879 ctx->builder = lpadBuilder;
3881 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3882 g_assert (handler_bb);
3884 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3885 LLVMValueRef personality = get_mono_personality (ctx);
3886 g_assert (personality);
3888 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3889 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3891 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3892 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3893 g_assert (landing_pad);
3895 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3896 LLVMAddClause (landing_pad, cast);
3898 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3899 LLVMBuilderRef resume_builder = create_builder (ctx);
3900 ctx->builder = resume_builder;
3901 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3903 emit_resume_eh (ctx, handler_bb);
3906 ctx->builder = lpadBuilder;
3907 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3909 gboolean finally_only = TRUE;
3911 MonoExceptionClause *group_cursor = group_start;
3913 for (int i = 0; i < group_size; i ++) {
3914 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3915 finally_only = FALSE;
3921 // Handle landing pad inlining
3923 if (!finally_only) {
3924 // So at each level of the exception stack we will match the exception again.
3925 // During that match, we need to compare against the handler types for the current
3926 // protected region. We send the try start and end so that we can only check against
3927 // handlers for this lexical protected region.
3928 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3930 // if returns -1, resume
3931 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3933 // else move to that target bb
3934 for (int i = 0; i < group_size; i++) {
3935 MonoExceptionClause *clause = group_start + i;
3936 int clause_index = clause - cfg->header->clauses;
3937 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3938 g_assert (handler_bb);
3939 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3940 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3943 int clause_index = group_start - cfg->header->clauses;
3944 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3945 g_assert (finally_bb);
3947 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3950 ctx->builder = old_builder;
3957 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3959 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3960 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3962 // Make exception available to catch blocks
3963 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3964 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3966 g_assert (ctx->ex_var);
3967 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3969 if (bb->in_scount == 1) {
3970 MonoInst *exvar = bb->in_stack [0];
3971 g_assert (!ctx->values [exvar->dreg]);
3972 g_assert (ctx->ex_var);
3973 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3974 emit_volatile_store (ctx, exvar->dreg);
3977 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3980 LLVMBuilderRef handler_builder = create_builder (ctx);
3981 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3982 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3984 // Make the handler code end with a jump to cbb
3985 LLVMBuildBr (handler_builder, cbb);
3989 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3991 MonoCompile *cfg = ctx->cfg;
3992 LLVMValueRef *values = ctx->values;
3993 LLVMModuleRef lmodule = ctx->lmodule;
3994 BBInfo *bblocks = ctx->bblocks;
3996 LLVMValueRef personality;
3997 LLVMValueRef landing_pad;
3998 LLVMBasicBlockRef target_bb;
4000 static int ti_generator;
4002 LLVMValueRef type_info;
4006 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4008 if (cfg->compile_aot) {
4009 /* Use a dummy personality function */
4010 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4011 g_assert (personality);
4013 #if LLVM_API_VERSION > 100
4014 personality = ctx->module->personality;
4016 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
4017 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
4018 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
4019 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
4020 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
4021 LLVMPositionBuilderAtEnd (builder2, entry_bb);
4022 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
4023 ctx->module->personality = personality;
4024 LLVMDisposeBuilder (builder2);
4027 static gint32 mapping_inited;
4029 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4031 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
4032 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4036 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4038 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4041 * Create the type info
4043 sprintf (ti_name, "type_info_%d", ti_generator);
4046 if (cfg->compile_aot) {
4047 /* decode_eh_frame () in aot-runtime.c will decode this */
4048 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4049 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4052 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4054 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4056 #if LLVM_API_VERSION > 100
4057 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4058 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4063 * After the cfg mempool is freed, the type info will point to stale memory,
4064 * but this is not a problem, since we decode it once in exception_cb during
4067 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4068 *(gint32*)ti = clause_index;
4070 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4072 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4077 LLVMTypeRef members [2], ret_type;
4079 members [0] = i8ptr;
4080 members [1] = LLVMInt32Type ();
4081 ret_type = LLVMStructType (members, 2, FALSE);
4083 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4084 LLVMAddClause (landing_pad, type_info);
4086 /* Store the exception into the exvar */
4088 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4092 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4093 * code expects control to be transferred to this landing pad even in the
4094 * presence of nested clauses. The landing pad needs to branch to the landing
4095 * pads belonging to nested clauses based on the selector value returned by
4096 * the landing pad instruction, which is passed to the landing pad in a
4097 * register by the EH code.
4099 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4100 g_assert (target_bb);
4103 * Branch to the correct landing pad
4105 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4106 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4108 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4109 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4110 MonoBasicBlock *handler_bb;
4112 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4113 g_assert (handler_bb);
4115 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4116 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4119 /* Start a new bblock which CALL_HANDLER can branch to */
4120 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4122 ctx->builder = builder = create_builder (ctx);
4123 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4125 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4127 /* Store the exception into the IL level exvar */
4128 if (bb->in_scount == 1) {
4129 g_assert (bb->in_scount == 1);
4130 exvar = bb->in_stack [0];
4132 // FIXME: This is shared with filter clauses ?
4133 g_assert (!values [exvar->dreg]);
4135 g_assert (ctx->ex_var);
4136 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4137 emit_volatile_store (ctx, exvar->dreg);
4143 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4145 MonoCompile *cfg = ctx->cfg;
4146 MonoMethodSignature *sig = ctx->sig;
4147 LLVMValueRef method = ctx->lmethod;
4148 LLVMValueRef *values = ctx->values;
4149 LLVMValueRef *addresses = ctx->addresses;
4150 LLVMCallInfo *linfo = ctx->linfo;
4151 BBInfo *bblocks = ctx->bblocks;
4153 LLVMBasicBlockRef cbb;
4154 LLVMBuilderRef builder, starting_builder;
4155 gboolean has_terminator;
4157 LLVMValueRef lhs, rhs;
4160 cbb = get_end_bb (ctx, bb);
4162 builder = create_builder (ctx);
4163 ctx->builder = builder;
4164 LLVMPositionBuilderAtEnd (builder, cbb);
4169 if (bb->flags & BB_EXCEPTION_HANDLER) {
4170 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4171 set_failure (ctx, "handler without invokes");
4176 emit_llvmonly_handler_start (ctx, bb, cbb);
4178 emit_handler_start (ctx, bb, builder);
4181 builder = ctx->builder;
4184 has_terminator = FALSE;
4185 starting_builder = builder;
4186 for (ins = bb->code; ins; ins = ins->next) {
4187 const char *spec = LLVM_INS_INFO (ins->opcode);
4189 char dname_buf [128];
4191 emit_dbg_loc (ctx, builder, ins->cil_code);
4196 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4197 * Start a new bblock.
4198 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4199 * from localloc-ed memory.
4201 if (!cfg->llvm_only)
4202 ;//set_failure (ctx, "basic block too long");
4204 if (!ctx->long_bb_break_var) {
4205 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4206 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4209 cbb = gen_bb (ctx, "CONT_LONG_BB");
4210 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4212 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4214 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4215 * but llvm doesn't know that, so the branch is not going to be eliminated.
4217 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4219 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4221 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4222 ctx->builder = builder = create_builder (ctx);
4223 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4224 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4225 LLVMBuildBr (builder, cbb);
4227 ctx->builder = builder = create_builder (ctx);
4228 LLVMPositionBuilderAtEnd (builder, cbb);
4229 ctx->bblocks [bb->block_num].end_bblock = cbb;
4234 /* There could be instructions after a terminator, skip them */
4237 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4238 sprintf (dname_buf, "t%d", ins->dreg);
4242 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4243 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4245 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4246 lhs = emit_volatile_load (ctx, ins->sreg1);
4248 /* It is ok for SETRET to have an uninitialized argument */
4249 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4250 set_failure (ctx, "sreg1");
4253 lhs = values [ins->sreg1];
4259 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4260 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4261 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4262 rhs = emit_volatile_load (ctx, ins->sreg2);
4264 if (!values [ins->sreg2]) {
4265 set_failure (ctx, "sreg2");
4268 rhs = values [ins->sreg2];
4274 //mono_print_ins (ins);
4275 switch (ins->opcode) {
4278 case OP_LIVERANGE_START:
4279 case OP_LIVERANGE_END:
4282 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4285 #if SIZEOF_VOID_P == 4
4286 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4288 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4292 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4296 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4298 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4300 case OP_DUMMY_ICONST:
4301 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4303 case OP_DUMMY_I8CONST:
4304 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4306 case OP_DUMMY_R8CONST:
4307 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4310 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4311 LLVMBuildBr (builder, target_bb);
4312 has_terminator = TRUE;
4319 LLVMBasicBlockRef new_bb;
4320 LLVMBuilderRef new_builder;
4322 // The default branch is already handled
4323 // FIXME: Handle it here
4325 /* Start new bblock */
4326 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4327 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4329 lhs = convert (ctx, lhs, LLVMInt32Type ());
4330 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4331 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4332 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4334 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4337 new_builder = create_builder (ctx);
4338 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4339 LLVMBuildUnreachable (new_builder);
4341 has_terminator = TRUE;
4342 g_assert (!ins->next);
4348 switch (linfo->ret.storage) {
4349 case LLVMArgVtypeInReg: {
4350 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4351 LLVMValueRef val, addr, retval;
4354 retval = LLVMGetUndef (ret_type);
4356 if (!addresses [ins->sreg1]) {
4358 * The return type is an LLVM vector type, have to convert between it and the
4359 * real return type which is a struct type.
4361 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4362 /* Convert to 2xi64 first */
4363 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4365 for (i = 0; i < 2; ++i) {
4366 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4367 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4369 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4373 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4374 for (i = 0; i < 2; ++i) {
4375 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4376 LLVMValueRef indexes [2], part_addr;
4378 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4379 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4380 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4382 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4384 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4388 LLVMBuildRet (builder, retval);
4391 case LLVMArgVtypeAsScalar: {
4392 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4393 LLVMValueRef retval;
4395 g_assert (addresses [ins->sreg1]);
4397 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4398 LLVMBuildRet (builder, retval);
4401 case LLVMArgVtypeByVal: {
4402 LLVMValueRef retval;
4404 g_assert (addresses [ins->sreg1]);
4405 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4406 LLVMBuildRet (builder, retval);
4409 case LLVMArgVtypeByRef: {
4410 LLVMBuildRetVoid (builder);
4413 case LLVMArgGsharedvtFixed: {
4414 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4415 /* The return value is in lhs, need to store to the vret argument */
4416 /* sreg1 might not be set */
4418 g_assert (cfg->vret_addr);
4419 g_assert (values [cfg->vret_addr->dreg]);
4420 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4422 LLVMBuildRetVoid (builder);
4425 case LLVMArgGsharedvtFixedVtype: {
4427 LLVMBuildRetVoid (builder);
4430 case LLVMArgGsharedvtVariable: {
4432 LLVMBuildRetVoid (builder);
4435 case LLVMArgVtypeRetAddr: {
4436 LLVMBuildRetVoid (builder);
4439 case LLVMArgAsIArgs:
4440 case LLVMArgFpStruct: {
4441 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4442 LLVMValueRef retval;
4444 g_assert (addresses [ins->sreg1]);
4445 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4446 LLVMBuildRet (builder, retval);
4450 case LLVMArgNormal: {
4451 if (!lhs || ctx->is_dead [ins->sreg1]) {
4453 * The method did not set its return value, probably because it
4454 * ends with a throw.
4457 LLVMBuildRetVoid (builder);
4459 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4461 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4463 has_terminator = TRUE;
4467 g_assert_not_reached ();
4476 case OP_ICOMPARE_IMM:
4477 case OP_LCOMPARE_IMM:
4478 case OP_COMPARE_IMM: {
4480 LLVMValueRef cmp, args [16];
4481 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4483 if (ins->next->opcode == OP_NOP)
4486 if (ins->next->opcode == OP_BR)
4487 /* The comparison result is not needed */
4490 rel = mono_opcode_to_cond (ins->next->opcode);
4492 if (ins->opcode == OP_ICOMPARE_IMM) {
4493 lhs = convert (ctx, lhs, LLVMInt32Type ());
4494 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4496 if (ins->opcode == OP_LCOMPARE_IMM) {
4497 lhs = convert (ctx, lhs, LLVMInt64Type ());
4498 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4500 if (ins->opcode == OP_LCOMPARE) {
4501 lhs = convert (ctx, lhs, LLVMInt64Type ());
4502 rhs = convert (ctx, rhs, LLVMInt64Type ());
4504 if (ins->opcode == OP_ICOMPARE) {
4505 lhs = convert (ctx, lhs, LLVMInt32Type ());
4506 rhs = convert (ctx, rhs, LLVMInt32Type ());
4510 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4511 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4512 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4513 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4516 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4517 if (ins->opcode == OP_FCOMPARE) {
4518 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4519 } else if (ins->opcode == OP_RCOMPARE) {
4520 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4521 } else if (ins->opcode == OP_COMPARE_IMM) {
4522 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4523 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4525 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4526 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4527 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4528 /* The immediate is encoded in two fields */
4529 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4530 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4532 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4535 else if (ins->opcode == OP_COMPARE) {
4536 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4537 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4539 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4541 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4545 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4546 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4549 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4550 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4552 * If the target bb contains PHI instructions, LLVM requires
4553 * two PHI entries for this bblock, while we only generate one.
4554 * So convert this to an unconditional bblock. (bxc #171).
4556 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4558 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4560 has_terminator = TRUE;
4561 } else if (MONO_IS_SETCC (ins->next)) {
4562 sprintf (dname_buf, "t%d", ins->next->dreg);
4564 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4566 /* Add stores for volatile variables */
4567 emit_volatile_store (ctx, ins->next->dreg);
4568 } else if (MONO_IS_COND_EXC (ins->next)) {
4569 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4572 builder = ctx->builder;
4574 set_failure (ctx, "next");
4592 rel = mono_opcode_to_cond (ins->opcode);
4594 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4595 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4606 rel = mono_opcode_to_cond (ins->opcode);
4608 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4609 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4617 gboolean empty = TRUE;
4619 /* Check that all input bblocks really branch to us */
4620 for (i = 0; i < bb->in_count; ++i) {
4621 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4622 ins->inst_phi_args [i + 1] = -1;
4628 /* LLVM doesn't like phi instructions with zero operands */
4629 ctx->is_dead [ins->dreg] = TRUE;
4633 /* Created earlier, insert it now */
4634 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4636 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4637 int sreg1 = ins->inst_phi_args [i + 1];
4641 * Count the number of times the incoming bblock branches to us,
4642 * since llvm requires a separate entry for each.
4644 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4645 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4648 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4649 if (switch_ins->inst_many_bb [j] == bb)
4656 /* Remember for later */
4657 for (j = 0; j < count; ++j) {
4658 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4661 node->in_bb = bb->in_bb [i];
4663 bblocks [bb->in_bb [i]->block_num].phi_nodes = g_slist_prepend_mempool (ctx->mempool, bblocks [bb->in_bb [i]->block_num].phi_nodes, node);
4673 values [ins->dreg] = lhs;
4677 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4680 values [ins->dreg] = lhs;
4682 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4684 * This is added by the spilling pass in case of the JIT,
4685 * but we have to do it ourselves.
4687 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4691 case OP_MOVE_F_TO_I4: {
4692 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4695 case OP_MOVE_I4_TO_F: {
4696 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4699 case OP_MOVE_F_TO_I8: {
4700 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4703 case OP_MOVE_I8_TO_F: {
4704 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4737 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4738 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4740 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4743 builder = ctx->builder;
4745 switch (ins->opcode) {
4748 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4752 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4756 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4760 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4764 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4768 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4772 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4776 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4780 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4784 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4788 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4792 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4796 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4800 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4804 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4807 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4810 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4814 g_assert_not_reached ();
4821 lhs = convert (ctx, lhs, LLVMFloatType ());
4822 rhs = convert (ctx, rhs, LLVMFloatType ());
4823 switch (ins->opcode) {
4825 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4828 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4831 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4834 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4837 g_assert_not_reached ();
4846 case OP_IREM_UN_IMM:
4848 case OP_IDIV_UN_IMM:
4854 case OP_ISHR_UN_IMM:
4864 case OP_LSHR_UN_IMM:
4870 case OP_SHR_UN_IMM: {
4873 if (spec [MONO_INST_SRC1] == 'l') {
4874 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4876 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4879 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4882 builder = ctx->builder;
4884 #if SIZEOF_VOID_P == 4
4885 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4886 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4889 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4890 lhs = convert (ctx, lhs, IntPtrType ());
4891 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4892 switch (ins->opcode) {
4896 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4900 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4905 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4909 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4911 case OP_IDIV_UN_IMM:
4912 case OP_LDIV_UN_IMM:
4913 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4917 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4919 case OP_IREM_UN_IMM:
4920 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4925 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4929 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4933 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4938 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4943 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4945 case OP_ISHR_UN_IMM:
4946 /* This is used to implement conv.u4, so the lhs could be an i8 */
4947 lhs = convert (ctx, lhs, LLVMInt32Type ());
4948 imm = convert (ctx, imm, LLVMInt32Type ());
4949 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4951 case OP_LSHR_UN_IMM:
4953 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4956 g_assert_not_reached ();
4961 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4964 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4967 lhs = convert (ctx, lhs, LLVMDoubleType ());
4968 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4971 lhs = convert (ctx, lhs, LLVMFloatType ());
4972 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4975 guint32 v = 0xffffffff;
4976 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4980 guint64 v = 0xffffffffffffffffLL;
4981 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4984 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4986 LLVMValueRef v1, v2;
4988 rhs = LLVMBuildSExt (builder, convert (ctx, rhs, LLVMInt32Type ()), LLVMInt64Type (), "");
4990 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4991 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4992 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4997 case OP_ICONV_TO_I1:
4998 case OP_ICONV_TO_I2:
4999 case OP_ICONV_TO_I4:
5000 case OP_ICONV_TO_U1:
5001 case OP_ICONV_TO_U2:
5002 case OP_ICONV_TO_U4:
5003 case OP_LCONV_TO_I1:
5004 case OP_LCONV_TO_I2:
5005 case OP_LCONV_TO_U1:
5006 case OP_LCONV_TO_U2:
5007 case OP_LCONV_TO_U4: {
5010 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);
5012 /* Have to do two casts since our vregs have type int */
5013 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
5015 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
5017 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
5020 case OP_ICONV_TO_I8:
5021 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
5023 case OP_ICONV_TO_U8:
5024 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
5026 case OP_FCONV_TO_I4:
5027 case OP_RCONV_TO_I4:
5028 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
5030 case OP_FCONV_TO_I1:
5031 case OP_RCONV_TO_I1:
5032 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
5034 case OP_FCONV_TO_U1:
5035 case OP_RCONV_TO_U1:
5036 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5038 case OP_FCONV_TO_I2:
5039 case OP_RCONV_TO_I2:
5040 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5042 case OP_FCONV_TO_U2:
5043 case OP_RCONV_TO_U2:
5044 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5046 case OP_RCONV_TO_U4:
5047 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5049 case OP_FCONV_TO_I8:
5050 case OP_RCONV_TO_I8:
5051 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5054 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5056 case OP_ICONV_TO_R8:
5057 case OP_LCONV_TO_R8:
5058 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5060 case OP_ICONV_TO_R_UN:
5061 case OP_LCONV_TO_R_UN:
5062 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5064 #if SIZEOF_VOID_P == 4
5067 case OP_LCONV_TO_I4:
5068 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5070 case OP_ICONV_TO_R4:
5071 case OP_LCONV_TO_R4:
5072 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5074 values [ins->dreg] = v;
5076 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5078 case OP_FCONV_TO_R4:
5079 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5081 values [ins->dreg] = v;
5083 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5085 case OP_RCONV_TO_R8:
5086 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5088 case OP_RCONV_TO_R4:
5089 values [ins->dreg] = lhs;
5092 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5095 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5098 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5100 case OP_LOCALLOC_IMM: {
5103 guint32 size = ins->inst_imm;
5104 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5106 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5108 if (ins->flags & MONO_INST_INIT) {
5109 LLVMValueRef args [5];
5112 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5113 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5114 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5115 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5116 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5119 values [ins->dreg] = v;
5123 LLVMValueRef v, size;
5125 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), "");
5127 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5129 if (ins->flags & MONO_INST_INIT) {
5130 LLVMValueRef args [5];
5133 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5135 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5136 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5137 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5139 values [ins->dreg] = v;
5143 case OP_LOADI1_MEMBASE:
5144 case OP_LOADU1_MEMBASE:
5145 case OP_LOADI2_MEMBASE:
5146 case OP_LOADU2_MEMBASE:
5147 case OP_LOADI4_MEMBASE:
5148 case OP_LOADU4_MEMBASE:
5149 case OP_LOADI8_MEMBASE:
5150 case OP_LOADR4_MEMBASE:
5151 case OP_LOADR8_MEMBASE:
5152 case OP_LOAD_MEMBASE:
5160 LLVMValueRef base, index, addr;
5162 gboolean sext = FALSE, zext = FALSE;
5163 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5165 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5170 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)) {
5171 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5177 if (ins->inst_offset == 0) {
5179 } else if (ins->inst_offset % size != 0) {
5180 /* Unaligned load */
5181 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5182 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5184 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5185 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5189 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5191 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5193 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5195 * These will signal LLVM that these loads do not alias any stores, and
5196 * they can't fail, allowing them to be hoisted out of loops.
5198 set_invariant_load_flag (values [ins->dreg]);
5199 #if LLVM_API_VERSION < 100
5200 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5205 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5207 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5208 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5209 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5213 case OP_STOREI1_MEMBASE_REG:
5214 case OP_STOREI2_MEMBASE_REG:
5215 case OP_STOREI4_MEMBASE_REG:
5216 case OP_STOREI8_MEMBASE_REG:
5217 case OP_STORER4_MEMBASE_REG:
5218 case OP_STORER8_MEMBASE_REG:
5219 case OP_STORE_MEMBASE_REG: {
5221 LLVMValueRef index, addr, base;
5223 gboolean sext = FALSE, zext = FALSE;
5224 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5226 if (!values [ins->inst_destbasereg]) {
5227 set_failure (ctx, "inst_destbasereg");
5231 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5233 base = values [ins->inst_destbasereg];
5234 if (ins->inst_offset % size != 0) {
5235 /* Unaligned store */
5236 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5237 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5239 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5240 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5242 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5246 case OP_STOREI1_MEMBASE_IMM:
5247 case OP_STOREI2_MEMBASE_IMM:
5248 case OP_STOREI4_MEMBASE_IMM:
5249 case OP_STOREI8_MEMBASE_IMM:
5250 case OP_STORE_MEMBASE_IMM: {
5252 LLVMValueRef index, addr, base;
5254 gboolean sext = FALSE, zext = FALSE;
5255 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5257 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5259 base = values [ins->inst_destbasereg];
5260 if (ins->inst_offset % size != 0) {
5261 /* Unaligned store */
5262 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5263 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5265 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5266 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5268 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5273 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5275 case OP_OUTARG_VTRETADDR:
5283 case OP_VOIDCALL_MEMBASE:
5284 case OP_CALL_MEMBASE:
5285 case OP_LCALL_MEMBASE:
5286 case OP_FCALL_MEMBASE:
5287 case OP_RCALL_MEMBASE:
5288 case OP_VCALL_MEMBASE:
5289 case OP_VOIDCALL_REG:
5294 case OP_VCALL_REG: {
5295 process_call (ctx, bb, &builder, ins);
5300 LLVMValueRef indexes [2];
5301 MonoJumpInfo *tmp_ji, *ji;
5302 LLVMValueRef got_entry_addr;
5306 * FIXME: Can't allocate from the cfg mempool since that is freed if
5307 * the LLVM compile fails.
5309 tmp_ji = g_new0 (MonoJumpInfo, 1);
5310 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5311 tmp_ji->data.target = ins->inst_p0;
5313 ji = mono_aot_patch_info_dup (tmp_ji);
5316 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5317 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5320 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5321 * resolvable at runtime using dlsym ().
5324 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5329 ji->next = cfg->patch_info;
5330 cfg->patch_info = ji;
5332 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5333 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5334 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5335 if (!mono_aot_is_shared_got_offset (got_offset)) {
5336 //mono_print_ji (ji);
5338 ctx->has_got_access = TRUE;
5341 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5342 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5343 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5345 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5346 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5348 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5349 if (!cfg->llvm_only)
5350 set_invariant_load_flag (values [ins->dreg]);
5353 case OP_NOT_REACHED:
5354 LLVMBuildUnreachable (builder);
5355 has_terminator = TRUE;
5356 g_assert (bb->block_num < cfg->max_block_num);
5357 ctx->unreachable [bb->block_num] = TRUE;
5358 /* Might have instructions after this */
5360 MonoInst *next = ins->next;
5362 * FIXME: If later code uses the regs defined by these instructions,
5363 * compilation will fail.
5365 MONO_DELETE_INS (bb, next);
5369 MonoInst *var = ins->inst_i0;
5371 if (var->opcode == OP_VTARG_ADDR) {
5372 /* The variable contains the vtype address */
5373 values [ins->dreg] = values [var->dreg];
5374 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5375 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5377 values [ins->dreg] = addresses [var->dreg];
5382 LLVMValueRef args [1];
5384 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5385 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5389 LLVMValueRef args [1];
5391 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5392 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5396 LLVMValueRef args [1];
5398 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5399 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5403 LLVMValueRef args [1];
5405 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5406 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5420 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5421 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5423 switch (ins->opcode) {
5426 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5430 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5434 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5438 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5441 g_assert_not_reached ();
5444 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5449 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5450 * hack is necessary (for now).
5453 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5455 #define ARM64_ATOMIC_FENCE_FIX
5458 case OP_ATOMIC_EXCHANGE_I4:
5459 case OP_ATOMIC_EXCHANGE_I8: {
5460 LLVMValueRef args [2];
5463 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5464 t = LLVMInt32Type ();
5466 t = LLVMInt64Type ();
5468 g_assert (ins->inst_offset == 0);
5470 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5471 args [1] = convert (ctx, rhs, t);
5473 ARM64_ATOMIC_FENCE_FIX;
5474 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5475 ARM64_ATOMIC_FENCE_FIX;
5478 case OP_ATOMIC_ADD_I4:
5479 case OP_ATOMIC_ADD_I8: {
5480 LLVMValueRef args [2];
5483 if (ins->opcode == OP_ATOMIC_ADD_I4)
5484 t = LLVMInt32Type ();
5486 t = LLVMInt64Type ();
5488 g_assert (ins->inst_offset == 0);
5490 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5491 args [1] = convert (ctx, rhs, t);
5492 ARM64_ATOMIC_FENCE_FIX;
5493 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5494 ARM64_ATOMIC_FENCE_FIX;
5497 case OP_ATOMIC_CAS_I4:
5498 case OP_ATOMIC_CAS_I8: {
5499 LLVMValueRef args [3], val;
5502 if (ins->opcode == OP_ATOMIC_CAS_I4)
5503 t = LLVMInt32Type ();
5505 t = LLVMInt64Type ();
5507 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5509 args [1] = convert (ctx, values [ins->sreg3], t);
5511 args [2] = convert (ctx, values [ins->sreg2], t);
5512 ARM64_ATOMIC_FENCE_FIX;
5513 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5514 ARM64_ATOMIC_FENCE_FIX;
5515 /* cmpxchg returns a pair */
5516 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5519 case OP_MEMORY_BARRIER: {
5520 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5523 case OP_ATOMIC_LOAD_I1:
5524 case OP_ATOMIC_LOAD_I2:
5525 case OP_ATOMIC_LOAD_I4:
5526 case OP_ATOMIC_LOAD_I8:
5527 case OP_ATOMIC_LOAD_U1:
5528 case OP_ATOMIC_LOAD_U2:
5529 case OP_ATOMIC_LOAD_U4:
5530 case OP_ATOMIC_LOAD_U8:
5531 case OP_ATOMIC_LOAD_R4:
5532 case OP_ATOMIC_LOAD_R8: {
5533 #if LLVM_API_VERSION > 100
5535 gboolean sext, zext;
5537 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5538 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5539 LLVMValueRef index, addr;
5541 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5546 if (ins->inst_offset != 0) {
5547 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5548 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5553 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5555 ARM64_ATOMIC_FENCE_FIX;
5556 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5557 ARM64_ATOMIC_FENCE_FIX;
5560 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5562 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5565 set_failure (ctx, "atomic mono.load intrinsic");
5569 case OP_ATOMIC_STORE_I1:
5570 case OP_ATOMIC_STORE_I2:
5571 case OP_ATOMIC_STORE_I4:
5572 case OP_ATOMIC_STORE_I8:
5573 case OP_ATOMIC_STORE_U1:
5574 case OP_ATOMIC_STORE_U2:
5575 case OP_ATOMIC_STORE_U4:
5576 case OP_ATOMIC_STORE_U8:
5577 case OP_ATOMIC_STORE_R4:
5578 case OP_ATOMIC_STORE_R8: {
5580 gboolean sext, zext;
5582 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5583 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5584 LLVMValueRef index, addr, value, base;
5586 #if LLVM_API_VERSION < 100
5587 if (!cfg->llvm_only) {
5588 set_failure (ctx, "atomic mono.store intrinsic");
5593 if (!values [ins->inst_destbasereg]) {
5594 set_failure (ctx, "inst_destbasereg");
5598 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5600 base = values [ins->inst_destbasereg];
5601 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5602 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5603 value = convert (ctx, values [ins->sreg1], t);
5605 ARM64_ATOMIC_FENCE_FIX;
5606 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5607 ARM64_ATOMIC_FENCE_FIX;
5610 case OP_RELAXED_NOP: {
5611 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5612 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5619 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5621 // 257 == FS segment register
5622 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5624 // 256 == GS segment register
5625 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5628 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5629 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5630 /* See mono_amd64_emit_tls_get () */
5631 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5633 // 256 == GS segment register
5634 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5635 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5637 set_failure (ctx, "opcode tls-get");
5643 case OP_GC_SAFE_POINT: {
5644 LLVMValueRef val, cmp, callee;
5645 LLVMBasicBlockRef poll_bb, cont_bb;
5646 static LLVMTypeRef sig;
5647 const char *icall_name = "mono_threads_state_poll";
5650 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5654 * mono_threads_state_poll ();
5655 * FIXME: Use a preserveall wrapper
5657 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5658 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5659 poll_bb = gen_bb (ctx, "POLL_BB");
5660 cont_bb = gen_bb (ctx, "CONT_BB");
5661 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5663 ctx->builder = builder = create_builder (ctx);
5664 LLVMPositionBuilderAtEnd (builder, poll_bb);
5666 if (ctx->cfg->compile_aot) {
5667 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5669 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5670 callee = emit_jit_callee (ctx, icall_name, sig, target);
5672 LLVMBuildCall (builder, callee, NULL, 0, "");
5673 LLVMBuildBr (builder, cont_bb);
5675 ctx->builder = builder = create_builder (ctx);
5676 LLVMPositionBuilderAtEnd (builder, cont_bb);
5677 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5685 case OP_IADD_OVF_UN:
5687 case OP_ISUB_OVF_UN:
5689 case OP_IMUL_OVF_UN:
5691 case OP_LADD_OVF_UN:
5693 case OP_LSUB_OVF_UN:
5695 case OP_LMUL_OVF_UN:
5697 LLVMValueRef args [2], val, ovf, func;
5699 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5700 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5701 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5703 val = LLVMBuildCall (builder, func, args, 2, "");
5704 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5705 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5706 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5709 builder = ctx->builder;
5715 * We currently model them using arrays. Promotion to local vregs is
5716 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5717 * so we always have an entry in cfg->varinfo for them.
5718 * FIXME: Is this needed ?
5721 MonoClass *klass = ins->klass;
5722 LLVMValueRef args [5];
5726 set_failure (ctx, "!klass");
5730 if (!addresses [ins->dreg])
5731 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5732 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5733 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5734 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5736 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5737 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5738 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5741 case OP_DUMMY_VZERO:
5744 case OP_STOREV_MEMBASE:
5745 case OP_LOADV_MEMBASE:
5747 MonoClass *klass = ins->klass;
5748 LLVMValueRef src = NULL, dst, args [5];
5749 gboolean done = FALSE;
5753 set_failure (ctx, "!klass");
5757 if (mini_is_gsharedvt_klass (klass)) {
5759 set_failure (ctx, "gsharedvt");
5763 switch (ins->opcode) {
5764 case OP_STOREV_MEMBASE:
5765 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5766 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5767 /* Decomposed earlier */
5768 g_assert_not_reached ();
5771 if (!addresses [ins->sreg1]) {
5773 g_assert (values [ins->sreg1]);
5774 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));
5775 LLVMBuildStore (builder, values [ins->sreg1], dst);
5778 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5779 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5782 case OP_LOADV_MEMBASE:
5783 if (!addresses [ins->dreg])
5784 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5785 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5786 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5789 if (!addresses [ins->sreg1])
5790 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5791 if (!addresses [ins->dreg])
5792 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5793 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5794 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5797 g_assert_not_reached ();
5807 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5808 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5810 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5811 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5812 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5815 case OP_LLVM_OUTARG_VT: {
5816 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5817 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5819 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5820 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5822 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5823 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5825 g_assert (addresses [ins->sreg1]);
5826 addresses [ins->dreg] = addresses [ins->sreg1];
5828 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5829 if (!addresses [ins->sreg1]) {
5830 addresses [ins->sreg1] = build_alloca (ctx, t);
5831 g_assert (values [ins->sreg1]);
5833 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5834 addresses [ins->dreg] = addresses [ins->sreg1];
5836 if (!addresses [ins->sreg1]) {
5837 addresses [ins->sreg1] = build_alloca (ctx, t);
5838 g_assert (values [ins->sreg1]);
5839 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5841 addresses [ins->dreg] = addresses [ins->sreg1];
5845 case OP_OBJC_GET_SELECTOR: {
5846 const char *name = (const char*)ins->inst_p0;
5849 if (!ctx->module->objc_selector_to_var) {
5850 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5852 LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
5853 int32_t objc_imageinfo [] = { 0, 16 };
5854 LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
5855 LLVMSetLinkage (info_var, LLVMPrivateLinkage);
5856 LLVMSetExternallyInitialized (info_var, TRUE);
5857 LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
5858 LLVMSetAlignment (info_var, sizeof (mgreg_t));
5859 mark_as_used (ctx->module, info_var);
5862 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5864 LLVMValueRef indexes [16];
5866 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5867 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5868 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5869 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5870 mark_as_used (ctx->module, name_var);
5872 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5874 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5875 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5876 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5877 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5878 LLVMSetExternallyInitialized (ref_var, TRUE);
5879 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5880 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5881 mark_as_used (ctx->module, ref_var);
5883 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5887 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5894 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5896 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5899 case OP_LOADX_MEMBASE: {
5900 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5903 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5904 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5907 case OP_STOREX_MEMBASE: {
5908 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5911 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5912 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5919 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5923 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5929 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5933 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5937 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5941 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5944 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5947 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5950 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5954 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5965 LLVMValueRef v = NULL;
5967 switch (ins->opcode) {
5972 t = LLVMVectorType (LLVMInt32Type (), 4);
5973 rt = LLVMVectorType (LLVMFloatType (), 4);
5979 t = LLVMVectorType (LLVMInt64Type (), 2);
5980 rt = LLVMVectorType (LLVMDoubleType (), 2);
5983 t = LLVMInt32Type ();
5984 rt = LLVMInt32Type ();
5985 g_assert_not_reached ();
5988 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5989 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5990 switch (ins->opcode) {
5993 v = LLVMBuildAnd (builder, lhs, rhs, "");
5997 v = LLVMBuildOr (builder, lhs, rhs, "");
6001 v = LLVMBuildXor (builder, lhs, rhs, "");
6005 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
6008 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
6014 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
6015 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6021 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6022 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6026 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6027 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6044 case OP_PADDB_SAT_UN:
6045 case OP_PADDW_SAT_UN:
6046 case OP_PSUBB_SAT_UN:
6047 case OP_PSUBW_SAT_UN:
6055 case OP_PMULW_HIGH_UN: {
6056 LLVMValueRef args [2];
6061 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6068 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6072 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6080 case OP_EXTRACTX_U2:
6082 case OP_EXTRACT_U1: {
6084 gboolean zext = FALSE;
6086 t = simd_op_to_llvm_type (ins->opcode);
6088 switch (ins->opcode) {
6096 case OP_EXTRACTX_U2:
6101 t = LLVMInt32Type ();
6102 g_assert_not_reached ();
6105 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6106 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6108 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6117 case OP_EXPAND_R8: {
6118 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6119 LLVMValueRef mask [16], v;
6122 for (i = 0; i < 16; ++i)
6123 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6125 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6127 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6128 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6133 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6136 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6139 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6142 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6145 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6148 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6151 #if LLVM_API_VERSION > 100
6153 LLVMValueRef indexes [16];
6155 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6156 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6157 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6158 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6159 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6163 LLVMValueRef indexes [16];
6165 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6166 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6167 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6168 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6169 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6173 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6177 #if LLVM_API_VERSION <= 100
6187 case OP_EXTRACT_MASK:
6194 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6196 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6201 LLVMRealPredicate op;
6203 switch (ins->inst_c0) {
6213 case SIMD_COMP_UNORD:
6229 g_assert_not_reached ();
6232 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6233 if (ins->opcode == OP_COMPPD)
6234 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6236 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6240 /* This is only used for implementing shifts by non-immediate */
6241 values [ins->dreg] = lhs;
6252 LLVMValueRef args [3];
6255 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6257 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6268 case OP_PSHLQ_REG: {
6269 LLVMValueRef args [3];
6272 args [1] = values [ins->sreg2];
6274 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6281 case OP_PSHUFLEW_LOW:
6282 case OP_PSHUFLEW_HIGH: {
6284 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6285 int i, mask_size = 0;
6286 int imask = ins->inst_c0;
6288 /* Convert the x86 shuffle mask to LLVM's */
6289 switch (ins->opcode) {
6292 mask [0] = ((imask >> 0) & 3);
6293 mask [1] = ((imask >> 2) & 3);
6294 mask [2] = ((imask >> 4) & 3) + 4;
6295 mask [3] = ((imask >> 6) & 3) + 4;
6296 v1 = values [ins->sreg1];
6297 v2 = values [ins->sreg2];
6301 mask [0] = ((imask >> 0) & 1);
6302 mask [1] = ((imask >> 1) & 1) + 2;
6303 v1 = values [ins->sreg1];
6304 v2 = values [ins->sreg2];
6306 case OP_PSHUFLEW_LOW:
6308 mask [0] = ((imask >> 0) & 3);
6309 mask [1] = ((imask >> 2) & 3);
6310 mask [2] = ((imask >> 4) & 3);
6311 mask [3] = ((imask >> 6) & 3);
6316 v1 = values [ins->sreg1];
6317 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6319 case OP_PSHUFLEW_HIGH:
6325 mask [4] = 4 + ((imask >> 0) & 3);
6326 mask [5] = 4 + ((imask >> 2) & 3);
6327 mask [6] = 4 + ((imask >> 4) & 3);
6328 mask [7] = 4 + ((imask >> 6) & 3);
6329 v1 = values [ins->sreg1];
6330 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6334 mask [0] = ((imask >> 0) & 3);
6335 mask [1] = ((imask >> 2) & 3);
6336 mask [2] = ((imask >> 4) & 3);
6337 mask [3] = ((imask >> 6) & 3);
6338 v1 = values [ins->sreg1];
6339 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6342 g_assert_not_reached ();
6344 for (i = 0; i < mask_size; ++i)
6345 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6347 values [ins->dreg] =
6348 LLVMBuildShuffleVector (builder, v1, v2,
6349 LLVMConstVector (mask_values, mask_size), dname);
6353 case OP_UNPACK_LOWB:
6354 case OP_UNPACK_LOWW:
6355 case OP_UNPACK_LOWD:
6356 case OP_UNPACK_LOWQ:
6357 case OP_UNPACK_LOWPS:
6358 case OP_UNPACK_LOWPD:
6359 case OP_UNPACK_HIGHB:
6360 case OP_UNPACK_HIGHW:
6361 case OP_UNPACK_HIGHD:
6362 case OP_UNPACK_HIGHQ:
6363 case OP_UNPACK_HIGHPS:
6364 case OP_UNPACK_HIGHPD: {
6366 LLVMValueRef mask_values [16];
6367 int i, mask_size = 0;
6368 gboolean low = FALSE;
6370 switch (ins->opcode) {
6371 case OP_UNPACK_LOWB:
6375 case OP_UNPACK_LOWW:
6379 case OP_UNPACK_LOWD:
6380 case OP_UNPACK_LOWPS:
6384 case OP_UNPACK_LOWQ:
6385 case OP_UNPACK_LOWPD:
6389 case OP_UNPACK_HIGHB:
6392 case OP_UNPACK_HIGHW:
6395 case OP_UNPACK_HIGHD:
6396 case OP_UNPACK_HIGHPS:
6399 case OP_UNPACK_HIGHQ:
6400 case OP_UNPACK_HIGHPD:
6404 g_assert_not_reached ();
6408 for (i = 0; i < (mask_size / 2); ++i) {
6410 mask [(i * 2) + 1] = mask_size + i;
6413 for (i = 0; i < (mask_size / 2); ++i) {
6414 mask [(i * 2)] = (mask_size / 2) + i;
6415 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6419 for (i = 0; i < mask_size; ++i)
6420 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6422 values [ins->dreg] =
6423 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6424 LLVMConstVector (mask_values, mask_size), dname);
6429 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6430 LLVMValueRef v, val;
6432 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6433 val = LLVMConstNull (t);
6434 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6435 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6437 values [ins->dreg] = val;
6441 case OP_DUPPS_HIGH: {
6442 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6443 LLVMValueRef v1, v2, val;
6446 if (ins->opcode == OP_DUPPS_LOW) {
6447 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6448 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6450 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6451 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6453 val = LLVMConstNull (t);
6454 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6455 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6456 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6457 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6459 values [ins->dreg] = val;
6464 LLVMValueRef args [3];
6468 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6469 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6471 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6481 * EXCEPTION HANDLING
6483 case OP_IMPLICIT_EXCEPTION:
6484 /* This marks a place where an implicit exception can happen */
6485 if (bb->region != -1)
6486 set_failure (ctx, "implicit-exception");
6490 gboolean rethrow = (ins->opcode == OP_RETHROW);
6491 if (ctx->llvm_only) {
6492 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6493 has_terminator = TRUE;
6494 ctx->unreachable [bb->block_num] = TRUE;
6496 emit_throw (ctx, bb, rethrow, lhs);
6497 builder = ctx->builder;
6501 case OP_CALL_HANDLER: {
6503 * We don't 'call' handlers, but instead simply branch to them.
6504 * The code generated by ENDFINALLY will branch back to us.
6506 LLVMBasicBlockRef noex_bb;
6508 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6510 bb_list = info->call_handler_return_bbs;
6513 * Set the indicator variable for the finally clause.
6515 lhs = info->finally_ind;
6517 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6519 /* Branch to the finally clause */
6520 LLVMBuildBr (builder, info->call_handler_target_bb);
6522 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6523 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6525 builder = ctx->builder = create_builder (ctx);
6526 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6528 bblocks [bb->block_num].end_bblock = noex_bb;
6531 case OP_START_HANDLER: {
6534 case OP_ENDFINALLY: {
6535 LLVMBasicBlockRef resume_bb;
6536 MonoBasicBlock *handler_bb;
6537 LLVMValueRef val, switch_ins, callee;
6541 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6542 g_assert (handler_bb);
6543 info = &bblocks [handler_bb->block_num];
6544 lhs = info->finally_ind;
6547 bb_list = info->call_handler_return_bbs;
6549 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6551 /* Load the finally variable */
6552 val = LLVMBuildLoad (builder, lhs, "");
6554 /* Reset the variable */
6555 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6557 /* Branch to either resume_bb, or to the bblocks in bb_list */
6558 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6560 * The other targets are added at the end to handle OP_CALL_HANDLER
6561 * opcodes processed later.
6563 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6565 builder = ctx->builder = create_builder (ctx);
6566 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6568 if (ctx->llvm_only) {
6569 emit_resume_eh (ctx, bb);
6571 if (ctx->cfg->compile_aot) {
6572 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6574 #if LLVM_API_VERSION > 100
6575 MonoJitICallInfo *info;
6577 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6579 gpointer target = (void*)info->func;
6580 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6581 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6583 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6586 LLVMBuildCall (builder, callee, NULL, 0, "");
6587 LLVMBuildUnreachable (builder);
6590 has_terminator = TRUE;
6593 case OP_IL_SEQ_POINT:
6598 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6599 set_failure (ctx, reason);
6607 /* Convert the value to the type required by phi nodes */
6608 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6609 if (ctx->is_vphi [ins->dreg])
6611 values [ins->dreg] = addresses [ins->dreg];
6613 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6616 /* Add stores for volatile variables */
6617 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6618 emit_volatile_store (ctx, ins->dreg);
6624 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6625 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6628 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6629 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6630 LLVMBuildRetVoid (builder);
6633 if (bb == cfg->bb_entry)
6634 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6638 * mono_llvm_check_method_supported:
6640 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6641 * compiling a method twice.
6644 mono_llvm_check_method_supported (MonoCompile *cfg)
6651 if (cfg->method->save_lmf) {
6652 cfg->exception_message = g_strdup ("lmf");
6653 cfg->disable_llvm = TRUE;
6655 if (cfg->disable_llvm)
6659 * Nested clauses where one of the clauses is a finally clause is
6660 * not supported, because LLVM can't figure out the control flow,
6661 * probably because we resume exception handling by calling our
6662 * own function instead of using the 'resume' llvm instruction.
6664 for (i = 0; i < cfg->header->num_clauses; ++i) {
6665 for (j = 0; j < cfg->header->num_clauses; ++j) {
6666 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6667 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6669 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6670 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6671 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6672 cfg->exception_message = g_strdup ("nested clauses");
6673 cfg->disable_llvm = TRUE;
6678 if (cfg->disable_llvm)
6682 if (cfg->method->dynamic) {
6683 cfg->exception_message = g_strdup ("dynamic.");
6684 cfg->disable_llvm = TRUE;
6686 if (cfg->disable_llvm)
6690 static LLVMCallInfo*
6691 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6693 LLVMCallInfo *linfo;
6696 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6700 * Gsharedvt methods have the following calling convention:
6701 * - all arguments are passed by ref, even non generic ones
6702 * - the return value is returned by ref too, using a vret
6703 * argument passed after 'this'.
6705 n = sig->param_count + sig->hasthis;
6706 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6710 linfo->args [pindex ++].storage = LLVMArgNormal;
6712 if (sig->ret->type != MONO_TYPE_VOID) {
6713 if (mini_is_gsharedvt_variable_type (sig->ret))
6714 linfo->ret.storage = LLVMArgGsharedvtVariable;
6715 else if (mini_type_is_vtype (sig->ret))
6716 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6718 linfo->ret.storage = LLVMArgGsharedvtFixed;
6719 linfo->vret_arg_index = pindex;
6721 linfo->ret.storage = LLVMArgNone;
6724 for (i = 0; i < sig->param_count; ++i) {
6725 if (sig->params [i]->byref)
6726 linfo->args [pindex].storage = LLVMArgNormal;
6727 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6728 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6729 else if (mini_type_is_vtype (sig->params [i]))
6730 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6732 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6733 linfo->args [pindex].type = sig->params [i];
6740 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6741 for (i = 0; i < sig->param_count; ++i)
6742 linfo->args [i + sig->hasthis].type = sig->params [i];
6748 emit_method_inner (EmitContext *ctx);
6751 free_ctx (EmitContext *ctx)
6755 g_free (ctx->values);
6756 g_free (ctx->addresses);
6757 g_free (ctx->vreg_types);
6758 g_free (ctx->is_vphi);
6759 g_free (ctx->vreg_cli_types);
6760 g_free (ctx->is_dead);
6761 g_free (ctx->unreachable);
6762 g_ptr_array_free (ctx->phi_values, TRUE);
6763 g_free (ctx->bblocks);
6764 g_hash_table_destroy (ctx->region_to_handler);
6765 g_hash_table_destroy (ctx->clause_to_handler);
6766 g_hash_table_destroy (ctx->jit_callees);
6768 GHashTableIter iter;
6769 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6770 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6773 g_hash_table_destroy (ctx->method_to_callers);
6775 g_free (ctx->method_name);
6776 g_ptr_array_free (ctx->bblock_list, TRUE);
6778 for (l = ctx->builders; l; l = l->next) {
6779 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6780 LLVMDisposeBuilder (builder);
6787 * mono_llvm_emit_method:
6789 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6792 mono_llvm_emit_method (MonoCompile *cfg)
6796 gboolean is_linkonce = FALSE;
6799 /* The code below might acquire the loader lock, so use it for global locking */
6800 mono_loader_lock ();
6802 /* Used to communicate with the callbacks */
6803 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6805 ctx = g_new0 (EmitContext, 1);
6807 ctx->mempool = cfg->mempool;
6810 * This maps vregs to the LLVM instruction defining them
6812 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6814 * This maps vregs for volatile variables to the LLVM instruction defining their
6817 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6818 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6819 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6820 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6821 ctx->phi_values = g_ptr_array_sized_new (256);
6823 * This signals whenever the vreg was defined by a phi node with no input vars
6824 * (i.e. all its input bblocks end with NOT_REACHABLE).
6826 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6827 /* Whenever the bblock is unreachable */
6828 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6829 ctx->bblock_list = g_ptr_array_sized_new (256);
6831 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6832 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6833 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6834 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6835 if (cfg->compile_aot) {
6836 ctx->module = &aot_module;
6840 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6841 * linkage for them. This requires the following:
6842 * - the method needs to have a unique mangled name
6843 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6845 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6847 method_name = mono_aot_get_mangled_method_name (cfg->method);
6849 is_linkonce = FALSE;
6852 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6854 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6858 method_name = mono_aot_get_method_name (cfg);
6859 cfg->llvm_method_name = g_strdup (method_name);
6861 init_jit_module (cfg->domain);
6862 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6863 method_name = mono_method_full_name (cfg->method, TRUE);
6865 ctx->method_name = method_name;
6866 ctx->is_linkonce = is_linkonce;
6868 #if LLVM_API_VERSION > 100
6869 if (cfg->compile_aot)
6870 ctx->lmodule = ctx->module->lmodule;
6872 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6874 ctx->lmodule = ctx->module->lmodule;
6876 ctx->llvm_only = ctx->module->llvm_only;
6878 emit_method_inner (ctx);
6880 if (!ctx_ok (ctx)) {
6882 /* Need to add unused phi nodes as they can be referenced by other values */
6883 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6884 LLVMBuilderRef builder;
6886 builder = create_builder (ctx);
6887 LLVMPositionBuilderAtEnd (builder, phi_bb);
6889 for (i = 0; i < ctx->phi_values->len; ++i) {
6890 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6891 if (LLVMGetInstructionParent (v) == NULL)
6892 LLVMInsertIntoBuilder (builder, v);
6895 LLVMDeleteFunction (ctx->lmethod);
6901 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6903 mono_loader_unlock ();
6907 emit_method_inner (EmitContext *ctx)
6909 MonoCompile *cfg = ctx->cfg;
6910 MonoMethodSignature *sig;
6912 LLVMTypeRef method_type;
6913 LLVMValueRef method = NULL;
6914 LLVMValueRef *values = ctx->values;
6915 int i, max_block_num, bb_index;
6916 gboolean last = FALSE;
6917 LLVMCallInfo *linfo;
6918 LLVMModuleRef lmodule = ctx->lmodule;
6920 GPtrArray *bblock_list = ctx->bblock_list;
6921 MonoMethodHeader *header;
6922 MonoExceptionClause *clause;
6925 if (cfg->gsharedvt && !cfg->llvm_only) {
6926 set_failure (ctx, "gsharedvt");
6932 static int count = 0;
6935 char *llvm_count_str = g_getenv ("LLVM_COUNT");
6936 if (llvm_count_str) {
6937 int lcount = atoi (llvm_count_str);
6938 g_free (llvm_count_str);
6939 if (count == lcount) {
6940 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6944 if (count > lcount) {
6945 set_failure (ctx, "count");
6952 sig = mono_method_signature (cfg->method);
6955 linfo = get_llvm_call_info (cfg, sig);
6961 linfo->rgctx_arg = TRUE;
6962 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6966 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6967 ctx->lmethod = method;
6969 if (!cfg->llvm_only)
6970 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6971 LLVMSetLinkage (method, LLVMPrivateLinkage);
6973 LLVMAddFunctionAttr (method, LLVMUWTable);
6975 if (cfg->compile_aot) {
6976 LLVMSetLinkage (method, LLVMInternalLinkage);
6977 if (ctx->module->external_symbols) {
6978 LLVMSetLinkage (method, LLVMExternalLinkage);
6979 LLVMSetVisibility (method, LLVMHiddenVisibility);
6981 if (ctx->is_linkonce) {
6982 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6983 LLVMSetVisibility (method, LLVMDefaultVisibility);
6986 #if LLVM_API_VERSION > 100
6987 LLVMSetLinkage (method, LLVMExternalLinkage);
6989 LLVMSetLinkage (method, LLVMPrivateLinkage);
6993 if (cfg->method->save_lmf && !cfg->llvm_only) {
6994 set_failure (ctx, "lmf");
6998 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6999 set_failure (ctx, "pinvoke signature");
7003 header = cfg->header;
7004 for (i = 0; i < header->num_clauses; ++i) {
7005 clause = &header->clauses [i];
7006 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
7007 set_failure (ctx, "non-finally/catch clause.");
7011 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7012 /* We can't handle inlined methods with clauses */
7013 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
7015 if (linfo->rgctx_arg) {
7016 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7017 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7019 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7020 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7021 * CC_X86_64_Mono in X86CallingConv.td.
7023 if (!ctx->llvm_only)
7024 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
7025 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7027 ctx->rgctx_arg_pindex = -1;
7029 if (cfg->vret_addr) {
7030 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7031 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7032 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7033 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7034 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7039 ctx->this_arg_pindex = linfo->this_arg_pindex;
7040 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7041 values [cfg->args [0]->dreg] = ctx->this_arg;
7042 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7045 names = g_new (char *, sig->param_count);
7046 mono_method_get_param_names (cfg->method, (const char **) names);
7048 /* Set parameter names/attributes */
7049 for (i = 0; i < sig->param_count; ++i) {
7050 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7052 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7055 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7056 name = g_strdup_printf ("dummy_%d_%d", i, j);
7057 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7061 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7064 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7065 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7066 if (names [i] && names [i][0] != '\0')
7067 name = g_strdup_printf ("p_arg_%s", names [i]);
7069 name = g_strdup_printf ("p_arg_%d", i);
7071 if (names [i] && names [i][0] != '\0')
7072 name = g_strdup_printf ("arg_%s", names [i]);
7074 name = g_strdup_printf ("arg_%d", i);
7076 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7078 if (ainfo->storage == LLVMArgVtypeByVal)
7079 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7081 if (ainfo->storage == LLVMArgVtypeByRef) {
7083 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7088 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7089 ctx->minfo = mono_debug_lookup_method (cfg->method);
7090 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7094 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7095 max_block_num = MAX (max_block_num, bb->block_num);
7096 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7098 /* Add branches between non-consecutive bblocks */
7099 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7100 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7101 bb->next_bb != bb->last_ins->inst_false_bb) {
7103 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7104 inst->opcode = OP_BR;
7105 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7106 mono_bblock_add_inst (bb, inst);
7111 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7112 * was later optimized away, so clear these flags, and add them back for the still
7113 * present OP_LDADDR instructions.
7115 for (i = 0; i < cfg->next_vreg; ++i) {
7118 ins = get_vreg_to_inst (cfg, i);
7119 if (ins && ins != cfg->rgctx_var)
7120 ins->flags &= ~MONO_INST_INDIRECT;
7124 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7126 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7128 LLVMBuilderRef builder;
7130 char dname_buf[128];
7132 builder = create_builder (ctx);
7134 for (ins = bb->code; ins; ins = ins->next) {
7135 switch (ins->opcode) {
7140 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7145 if (ins->opcode == OP_VPHI) {
7146 /* Treat valuetype PHI nodes as operating on the address itself */
7147 g_assert (ins->klass);
7148 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7152 * Have to precreate these, as they can be referenced by
7153 * earlier instructions.
7155 sprintf (dname_buf, "t%d", ins->dreg);
7157 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7159 if (ins->opcode == OP_VPHI)
7160 ctx->addresses [ins->dreg] = values [ins->dreg];
7162 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7165 * Set the expected type of the incoming arguments since these have
7166 * to have the same type.
7168 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7169 int sreg1 = ins->inst_phi_args [i + 1];
7172 if (ins->opcode == OP_VPHI)
7173 ctx->is_vphi [sreg1] = TRUE;
7174 ctx->vreg_types [sreg1] = phi_type;
7180 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7189 * Create an ordering for bblocks, use the depth first order first, then
7190 * put the exception handling bblocks last.
7192 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7193 bb = cfg->bblocks [bb_index];
7194 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7195 g_ptr_array_add (bblock_list, bb);
7196 bblocks [bb->block_num].added = TRUE;
7200 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7201 if (!bblocks [bb->block_num].added)
7202 g_ptr_array_add (bblock_list, bb);
7206 * Second pass: generate code.
7209 LLVMBuilderRef entry_builder = create_builder (ctx);
7210 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7211 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7212 emit_entry_bb (ctx, entry_builder);
7214 // Make landing pads first
7215 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7217 if (ctx->llvm_only) {
7218 size_t group_index = 0;
7219 while (group_index < cfg->header->num_clauses) {
7221 size_t cursor = group_index;
7222 while (cursor < cfg->header->num_clauses &&
7223 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7224 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7229 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7230 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7231 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7233 group_index = cursor;
7237 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7238 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7240 // Prune unreachable mono BBs.
7241 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7244 process_bb (ctx, bb);
7248 g_hash_table_destroy (ctx->exc_meta);
7250 mono_memory_barrier ();
7252 /* Add incoming phi values */
7253 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7254 GSList *l, *ins_list;
7256 ins_list = bblocks [bb->block_num].phi_nodes;
7258 for (l = ins_list; l; l = l->next) {
7259 PhiNode *node = (PhiNode*)l->data;
7260 MonoInst *phi = node->phi;
7261 int sreg1 = node->sreg;
7262 LLVMBasicBlockRef in_bb;
7267 in_bb = get_end_bb (ctx, node->in_bb);
7269 if (ctx->unreachable [node->in_bb->block_num])
7272 if (!values [sreg1]) {
7273 /* Can happen with values in EH clauses */
7274 set_failure (ctx, "incoming phi sreg1");
7278 if (phi->opcode == OP_VPHI) {
7279 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7280 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7282 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7283 set_failure (ctx, "incoming phi arg type mismatch");
7286 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7287 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7292 /* Nullify empty phi instructions */
7293 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7294 GSList *l, *ins_list;
7296 ins_list = bblocks [bb->block_num].phi_nodes;
7298 for (l = ins_list; l; l = l->next) {
7299 PhiNode *node = (PhiNode*)l->data;
7300 MonoInst *phi = node->phi;
7301 LLVMValueRef phi_ins = values [phi->dreg];
7304 /* Already removed */
7307 if (LLVMCountIncoming (phi_ins) == 0) {
7308 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7309 LLVMInstructionEraseFromParent (phi_ins);
7310 values [phi->dreg] = NULL;
7315 /* Create the SWITCH statements for ENDFINALLY instructions */
7316 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7317 BBInfo *info = &bblocks [bb->block_num];
7319 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7320 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7321 GSList *bb_list = info->call_handler_return_bbs;
7323 GSList *bb_list_iter;
7325 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7326 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7332 /* Initialize the method if needed */
7333 if (cfg->compile_aot && ctx->llvm_only) {
7334 // FIXME: Add more shared got entries
7335 ctx->builder = create_builder (ctx);
7336 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7338 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7340 // FIXME: beforefieldinit
7342 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7343 * in load_method ().
7345 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7347 * linkonce methods shouldn't have initialization,
7348 * because they might belong to assemblies which
7349 * haven't been loaded yet.
7351 g_assert (!ctx->is_linkonce);
7352 emit_init_method (ctx);
7354 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7358 if (cfg->llvm_only) {
7359 GHashTableIter iter;
7361 GSList *callers, *l, *l2;
7364 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7365 * We can't do this earlier, as it contains llvm instructions which can be
7366 * freed if compilation fails.
7367 * FIXME: Get rid of this when all methods can be llvm compiled.
7369 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7370 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7371 for (l = callers; l; l = l->next) {
7372 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7373 l2 = g_slist_prepend (l2, l->data);
7374 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7379 if (cfg->verbose_level > 1)
7380 mono_llvm_dump_value (method);
7382 if (cfg->compile_aot && !cfg->llvm_only)
7383 mark_as_used (ctx->module, method);
7385 if (!cfg->llvm_only) {
7386 LLVMValueRef md_args [16];
7387 LLVMValueRef md_node;
7390 if (cfg->compile_aot)
7391 method_index = mono_aot_get_method_index (cfg->orig_method);
7394 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7395 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7396 md_node = LLVMMDNode (md_args, 2);
7397 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7398 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7401 if (cfg->compile_aot) {
7402 /* Don't generate native code, keep the LLVM IR */
7403 if (cfg->verbose_level)
7404 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7406 #if LLVM_API_VERSION < 100
7407 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7408 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7409 g_assert (err == 0);
7412 //LLVMVerifyFunction(method, 0);
7413 #if LLVM_API_VERSION > 100
7414 MonoDomain *domain = mono_domain_get ();
7415 MonoJitDomainInfo *domain_info;
7416 int nvars = g_hash_table_size (ctx->jit_callees);
7417 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7418 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7419 GHashTableIter iter;
7425 * Compute the addresses of the LLVM globals pointing to the
7426 * methods called by the current method. Pass it to the trampoline
7427 * code so it can update them after their corresponding method was
7430 g_hash_table_iter_init (&iter, ctx->jit_callees);
7432 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7433 callee_vars [i ++] = var;
7435 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7437 decode_llvm_eh_info (ctx, eh_frame);
7439 mono_domain_lock (domain);
7440 domain_info = domain_jit_info (domain);
7441 if (!domain_info->llvm_jit_callees)
7442 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7443 g_hash_table_iter_init (&iter, ctx->jit_callees);
7445 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7446 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7447 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7448 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7451 mono_domain_unlock (domain);
7453 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7455 if (cfg->verbose_level > 1)
7456 mono_llvm_dump_value (ctx->lmethod);
7458 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7460 /* Set by emit_cb */
7461 g_assert (cfg->code_len);
7465 if (ctx->module->method_to_lmethod)
7466 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7467 if (ctx->module->idx_to_lmethod)
7468 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7470 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7471 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7475 * mono_llvm_create_vars:
7477 * Same as mono_arch_create_vars () for LLVM.
7480 mono_llvm_create_vars (MonoCompile *cfg)
7482 MonoMethodSignature *sig;
7484 sig = mono_method_signature (cfg->method);
7485 if (cfg->gsharedvt && cfg->llvm_only) {
7486 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7487 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7488 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7489 printf ("vret_addr = ");
7490 mono_print_ins (cfg->vret_addr);
7494 mono_arch_create_vars (cfg);
7499 * mono_llvm_emit_call:
7501 * Same as mono_arch_emit_call () for LLVM.
7504 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7507 MonoMethodSignature *sig;
7508 int i, n, stack_size;
7513 sig = call->signature;
7514 n = sig->param_count + sig->hasthis;
7516 call->cinfo = get_llvm_call_info (cfg, sig);
7518 if (cfg->disable_llvm)
7521 if (sig->call_convention == MONO_CALL_VARARG) {
7522 cfg->exception_message = g_strdup ("varargs");
7523 cfg->disable_llvm = TRUE;
7526 for (i = 0; i < n; ++i) {
7529 ainfo = call->cinfo->args + i;
7531 in = call->args [i];
7533 /* Simply remember the arguments */
7534 switch (ainfo->storage) {
7535 case LLVMArgNormal: {
7536 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7539 opcode = mono_type_to_regmove (cfg, t);
7540 if (opcode == OP_FMOVE) {
7541 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7542 ins->dreg = mono_alloc_freg (cfg);
7543 } else if (opcode == OP_LMOVE) {
7544 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7545 ins->dreg = mono_alloc_lreg (cfg);
7546 } else if (opcode == OP_RMOVE) {
7547 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7548 ins->dreg = mono_alloc_freg (cfg);
7550 MONO_INST_NEW (cfg, ins, OP_MOVE);
7551 ins->dreg = mono_alloc_ireg (cfg);
7553 ins->sreg1 = in->dreg;
7556 case LLVMArgVtypeByVal:
7557 case LLVMArgVtypeByRef:
7558 case LLVMArgVtypeInReg:
7559 case LLVMArgVtypeAsScalar:
7560 case LLVMArgAsIArgs:
7561 case LLVMArgAsFpArgs:
7562 case LLVMArgGsharedvtVariable:
7563 case LLVMArgGsharedvtFixed:
7564 case LLVMArgGsharedvtFixedVtype:
7565 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7566 ins->dreg = mono_alloc_ireg (cfg);
7567 ins->sreg1 = in->dreg;
7568 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7569 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7570 ins->inst_vtype = ainfo->type;
7571 ins->klass = mono_class_from_mono_type (ainfo->type);
7574 cfg->exception_message = g_strdup ("ainfo->storage");
7575 cfg->disable_llvm = TRUE;
7579 if (!cfg->disable_llvm) {
7580 MONO_ADD_INS (cfg->cbb, ins);
7581 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7586 static unsigned char*
7587 alloc_cb (LLVMValueRef function, int size)
7591 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7595 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7597 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7602 emitted_cb (LLVMValueRef function, void *start, void *end)
7606 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7608 cfg->code_len = (guint8*)end - (guint8*)start;
7612 exception_cb (void *data)
7615 MonoJitExceptionInfo *ei;
7616 guint32 ei_len, i, j, nested_len, nindex;
7617 gpointer *type_info;
7618 int this_reg, this_offset;
7620 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7624 * data points to a DWARF FDE structure, convert it to our unwind format and
7626 * An alternative would be to save it directly, and modify our unwinder to work
7629 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);
7630 if (cfg->verbose_level > 1)
7631 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7633 /* Count nested clauses */
7635 for (i = 0; i < ei_len; ++i) {
7636 gint32 cindex1 = *(gint32*)type_info [i];
7637 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7639 for (j = 0; j < cfg->header->num_clauses; ++j) {
7641 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7643 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7649 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7650 cfg->llvm_ex_info_len = ei_len + nested_len;
7651 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7652 /* Fill the rest of the information from the type info */
7653 for (i = 0; i < ei_len; ++i) {
7654 gint32 clause_index = *(gint32*)type_info [i];
7655 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7657 cfg->llvm_ex_info [i].flags = clause->flags;
7658 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7659 cfg->llvm_ex_info [i].clause_index = clause_index;
7663 * For nested clauses, the LLVM produced exception info associates the try interval with
7664 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7665 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7666 * and everything else from the nested clause.
7669 for (i = 0; i < ei_len; ++i) {
7670 gint32 cindex1 = *(gint32*)type_info [i];
7671 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7673 for (j = 0; j < cfg->header->num_clauses; ++j) {
7675 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7676 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7678 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7679 /* clause1 is the nested clause */
7680 nested_ei = &cfg->llvm_ex_info [i];
7681 nesting_ei = &cfg->llvm_ex_info [nindex];
7684 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7686 nesting_ei->flags = clause2->flags;
7687 nesting_ei->data.catch_class = clause2->data.catch_class;
7688 nesting_ei->clause_index = cindex2;
7692 g_assert (nindex == ei_len + nested_len);
7693 cfg->llvm_this_reg = this_reg;
7694 cfg->llvm_this_offset = this_offset;
7696 /* type_info [i] is cfg mempool allocated, no need to free it */
7702 #if LLVM_API_VERSION > 100
7704 * decode_llvm_eh_info:
7706 * Decode the EH table emitted by llvm in jit mode, and store
7707 * the result into cfg.
7710 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7712 MonoCompile *cfg = ctx->cfg;
7715 MonoLLVMFDEInfo info;
7716 MonoJitExceptionInfo *ei;
7717 guint8 *p = eh_frame;
7718 int version, fde_count, fde_offset;
7719 guint32 ei_len, i, nested_len;
7720 gpointer *type_info;
7724 * Decode the one element EH table emitted by the MonoException class
7728 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7731 g_assert (version == 3);
7734 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7736 fde_count = *(guint32*)p;
7740 g_assert (fde_count <= 2);
7742 /* The first entry is the real method */
7743 g_assert (table [0] == 1);
7744 fde_offset = table [1];
7745 table += fde_count * 2;
7747 cfg->code_len = table [0];
7748 fde_len = table [1] - fde_offset;
7751 fde = (guint8*)eh_frame + fde_offset;
7752 cie = (guint8*)table;
7754 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7756 cfg->encoded_unwind_ops = info.unw_info;
7757 cfg->encoded_unwind_ops_len = info.unw_info_len;
7758 if (cfg->verbose_level > 1)
7759 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7760 if (info.this_reg != -1) {
7761 cfg->llvm_this_reg = info.this_reg;
7762 cfg->llvm_this_offset = info.this_offset;
7766 ei_len = info.ex_info_len;
7767 type_info = info.type_info;
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 arg_types [2] = LLVMInt32Type ();
8220 AddFunc (module, name, ret_type, arg_types, 3);
8224 g_assert_not_reached ();
8230 get_intrinsic (EmitContext *ctx, const char *name)
8232 #if LLVM_API_VERSION > 100
8236 * Every method is emitted into its own module so
8237 * we can add intrinsics on demand.
8239 res = LLVMGetNamedFunction (ctx->lmodule, name);
8243 /* No locking needed */
8244 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8247 printf ("%s\n", name);
8248 g_assert (id != -1);
8249 add_intrinsic (ctx->lmodule, id);
8250 res = LLVMGetNamedFunction (ctx->lmodule, name);
8258 res = LLVMGetNamedFunction (ctx->lmodule, name);
8265 add_intrinsics (LLVMModuleRef module)
8269 /* Emit declarations of instrinsics */
8271 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8272 * type doesn't seem to do any locking.
8274 for (i = 0; i < INTRINS_NUM; ++i)
8275 add_intrinsic (module, i);
8279 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8281 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8284 /* Load/Store intrinsics */
8286 LLVMTypeRef arg_types [5];
8290 for (i = 1; i <= 8; i *= 2) {
8291 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8292 arg_types [1] = LLVMInt32Type ();
8293 arg_types [2] = LLVMInt1Type ();
8294 arg_types [3] = LLVMInt32Type ();
8295 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8296 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8298 arg_types [0] = LLVMIntType (i * 8);
8299 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8300 arg_types [2] = LLVMInt32Type ();
8301 arg_types [3] = LLVMInt1Type ();
8302 arg_types [4] = LLVMInt32Type ();
8303 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8304 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8310 add_types (MonoLLVMModule *module)
8312 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8316 mono_llvm_init (void)
8321 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8323 h = g_hash_table_new (NULL, NULL);
8324 for (i = 0; i < INTRINS_NUM; ++i)
8325 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8326 intrins_id_to_name = h;
8328 h = g_hash_table_new (g_str_hash, g_str_equal);
8329 for (i = 0; i < INTRINS_NUM; ++i)
8330 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8331 intrins_name_to_id = h;
8335 init_jit_module (MonoDomain *domain)
8337 MonoJitDomainInfo *dinfo;
8338 MonoLLVMModule *module;
8341 dinfo = domain_jit_info (domain);
8342 if (dinfo->llvm_module)
8345 mono_loader_lock ();
8347 if (dinfo->llvm_module) {
8348 mono_loader_unlock ();
8352 module = g_new0 (MonoLLVMModule, 1);
8354 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8355 module->lmodule = LLVMModuleCreateWithName (name);
8356 module->context = LLVMGetGlobalContext ();
8358 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8360 add_intrinsics (module->lmodule);
8363 module->llvm_types = g_hash_table_new (NULL, NULL);
8365 #if LLVM_API_VERSION < 100
8366 MonoJitICallInfo *info;
8368 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8370 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8373 mono_memory_barrier ();
8375 dinfo->llvm_module = module;
8377 mono_loader_unlock ();
8381 mono_llvm_cleanup (void)
8383 MonoLLVMModule *module = &aot_module;
8385 if (module->lmodule)
8386 LLVMDisposeModule (module->lmodule);
8388 if (module->context)
8389 LLVMContextDispose (module->context);
8393 mono_llvm_free_domain_info (MonoDomain *domain)
8395 MonoJitDomainInfo *info = domain_jit_info (domain);
8396 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8402 if (module->llvm_types)
8403 g_hash_table_destroy (module->llvm_types);
8405 mono_llvm_dispose_ee (module->mono_ee);
8407 if (module->bb_names) {
8408 for (i = 0; i < module->bb_names_len; ++i)
8409 g_free (module->bb_names [i]);
8410 g_free (module->bb_names);
8412 //LLVMDisposeModule (module->module);
8416 info->llvm_module = NULL;
8420 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8422 MonoLLVMModule *module = &aot_module;
8424 /* Delete previous module */
8425 if (module->plt_entries)
8426 g_hash_table_destroy (module->plt_entries);
8427 if (module->lmodule)
8428 LLVMDisposeModule (module->lmodule);
8430 memset (module, 0, sizeof (aot_module));
8432 module->lmodule = LLVMModuleCreateWithName ("aot");
8433 module->assembly = assembly;
8434 module->global_prefix = g_strdup (global_prefix);
8435 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8436 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8437 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8438 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8439 module->external_symbols = TRUE;
8440 module->emit_dwarf = emit_dwarf;
8441 module->static_link = static_link;
8442 module->llvm_only = llvm_only;
8443 /* The first few entries are reserved */
8444 module->max_got_offset = 16;
8445 module->context = LLVMGetGlobalContext ();
8448 /* clang ignores our debug info because it has an invalid version */
8449 module->emit_dwarf = FALSE;
8451 add_intrinsics (module->lmodule);
8454 #if LLVM_API_VERSION > 100
8455 if (module->emit_dwarf) {
8456 char *dir, *build_info, *s, *cu_name;
8458 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8461 dir = g_strdup (".");
8462 build_info = mono_get_runtime_build_info ();
8463 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8464 cu_name = g_path_get_basename (assembly->image->name);
8465 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8467 g_free (build_info);
8474 * We couldn't compute the type of the LLVM global representing the got because
8475 * its size is only known after all the methods have been emitted. So create
8476 * a dummy variable, and replace all uses it with the real got variable when
8477 * its size is known in mono_llvm_emit_aot_module ().
8480 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8482 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8483 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8486 /* Add initialization array */
8488 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8490 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8491 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8495 emit_init_icall_wrappers (module);
8497 emit_llvm_code_start (module);
8499 /* Add a dummy personality function */
8500 if (!use_debug_personality) {
8501 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8502 LLVMSetLinkage (personality, LLVMExternalLinkage);
8503 mark_as_used (module, personality);
8506 /* Add a reference to the c++ exception we throw/catch */
8508 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8509 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8510 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8511 mono_llvm_set_is_constant (module->sentinel_exception);
8514 module->llvm_types = g_hash_table_new (NULL, NULL);
8515 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8516 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8517 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8518 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8519 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8520 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8521 module->method_to_callers = g_hash_table_new (NULL, NULL);
8525 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8528 LLVMValueRef res, *vals;
8530 vals = g_new0 (LLVMValueRef, nvalues);
8531 for (i = 0; i < nvalues; ++i)
8532 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8533 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8539 llvm_array_from_bytes (guint8 *values, int nvalues)
8542 LLVMValueRef res, *vals;
8544 vals = g_new0 (LLVMValueRef, nvalues);
8545 for (i = 0; i < nvalues; ++i)
8546 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8547 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8552 * mono_llvm_emit_aot_file_info:
8554 * Emit the MonoAotFileInfo structure.
8555 * Same as emit_aot_file_info () in aot-compiler.c.
8558 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8560 MonoLLVMModule *module = &aot_module;
8562 /* Save these for later */
8563 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8564 module->has_jitted_code = has_jitted_code;
8568 * mono_llvm_emit_aot_data:
8570 * Emit the binary data DATA pointed to by symbol SYMBOL.
8573 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8575 MonoLLVMModule *module = &aot_module;
8579 type = LLVMArrayType (LLVMInt8Type (), data_len);
8580 d = LLVMAddGlobal (module->lmodule, type, symbol);
8581 LLVMSetVisibility (d, LLVMHiddenVisibility);
8582 LLVMSetLinkage (d, LLVMInternalLinkage);
8583 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8584 mono_llvm_set_is_constant (d);
8587 /* Add a reference to a global defined in JITted code */
8589 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8594 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8595 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8601 emit_aot_file_info (MonoLLVMModule *module)
8603 LLVMTypeRef file_info_type;
8604 LLVMTypeRef *eltypes, eltype;
8605 LLVMValueRef info_var;
8606 LLVMValueRef *fields;
8607 int i, nfields, tindex;
8608 MonoAotFileInfo *info;
8609 LLVMModuleRef lmodule = module->lmodule;
8611 info = &module->aot_info;
8613 /* Create an LLVM type to represent MonoAotFileInfo */
8614 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8615 eltypes = g_new (LLVMTypeRef, nfields);
8617 eltypes [tindex ++] = LLVMInt32Type ();
8618 eltypes [tindex ++] = LLVMInt32Type ();
8620 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8621 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8623 for (i = 0; i < 15; ++i)
8624 eltypes [tindex ++] = LLVMInt32Type ();
8626 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8627 for (i = 0; i < 4; ++i)
8628 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8629 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8630 g_assert (tindex == nfields);
8631 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8632 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8634 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8635 if (module->static_link) {
8636 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8637 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8639 fields = g_new (LLVMValueRef, nfields);
8641 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8642 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8646 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8647 * for symbols defined in the .s file emitted by the aot compiler.
8649 eltype = eltypes [tindex];
8650 if (module->llvm_only)
8651 fields [tindex ++] = LLVMConstNull (eltype);
8653 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8654 fields [tindex ++] = module->got_var;
8655 /* llc defines this directly */
8656 if (!module->llvm_only) {
8657 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8658 fields [tindex ++] = LLVMConstNull (eltype);
8659 fields [tindex ++] = LLVMConstNull (eltype);
8661 fields [tindex ++] = LLVMConstNull (eltype);
8662 fields [tindex ++] = module->get_method;
8663 fields [tindex ++] = module->get_unbox_tramp;
8665 if (module->has_jitted_code) {
8666 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8667 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8669 fields [tindex ++] = LLVMConstNull (eltype);
8670 fields [tindex ++] = LLVMConstNull (eltype);
8672 if (!module->llvm_only)
8673 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8675 fields [tindex ++] = LLVMConstNull (eltype);
8676 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8677 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8678 fields [tindex ++] = LLVMConstNull (eltype);
8680 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8681 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8682 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8683 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8684 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8685 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8686 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8687 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8688 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8689 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8691 /* Not needed (mem_end) */
8692 fields [tindex ++] = LLVMConstNull (eltype);
8693 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8694 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8695 if (info->trampoline_size [0]) {
8696 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8697 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8698 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8699 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8701 fields [tindex ++] = LLVMConstNull (eltype);
8702 fields [tindex ++] = LLVMConstNull (eltype);
8703 fields [tindex ++] = LLVMConstNull (eltype);
8704 fields [tindex ++] = LLVMConstNull (eltype);
8706 if (module->static_link && !module->llvm_only)
8707 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8709 fields [tindex ++] = LLVMConstNull (eltype);
8710 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8711 if (!module->llvm_only) {
8712 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8713 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8714 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8715 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8716 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8717 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8719 fields [tindex ++] = LLVMConstNull (eltype);
8720 fields [tindex ++] = LLVMConstNull (eltype);
8721 fields [tindex ++] = LLVMConstNull (eltype);
8722 fields [tindex ++] = LLVMConstNull (eltype);
8723 fields [tindex ++] = LLVMConstNull (eltype);
8724 fields [tindex ++] = LLVMConstNull (eltype);
8727 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8728 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8731 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8732 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8733 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8734 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8735 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8736 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8737 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8738 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8739 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8740 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8741 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8742 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8743 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8744 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8745 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8747 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8748 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8749 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8750 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8751 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8753 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8754 g_assert (tindex == nfields);
8756 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8758 if (module->static_link) {
8762 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8763 /* Get rid of characters which cannot occur in symbols */
8765 for (p = s; *p; ++p) {
8766 if (!(isalnum (*p) || *p == '_'))
8769 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8771 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8772 LLVMSetLinkage (var, LLVMExternalLinkage);
8777 * Emit the aot module into the LLVM bitcode file FILENAME.
8780 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8782 LLVMTypeRef got_type, inited_type;
8783 LLVMValueRef real_got, real_inited;
8784 MonoLLVMModule *module = &aot_module;
8786 emit_llvm_code_end (module);
8789 * Create the real got variable and replace all uses of the dummy variable with
8792 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8793 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8794 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8795 if (module->external_symbols) {
8796 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8797 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8799 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8801 mono_llvm_replace_uses_of (module->got_var, real_got);
8803 mark_as_used (&aot_module, real_got);
8805 /* Delete the dummy got so it doesn't become a global */
8806 LLVMDeleteGlobal (module->got_var);
8807 module->got_var = real_got;
8810 * Same for the init_var
8812 if (module->llvm_only) {
8813 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8814 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8815 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8816 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8817 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8818 LLVMDeleteGlobal (module->inited_var);
8821 if (module->llvm_only) {
8822 emit_get_method (&aot_module);
8823 emit_get_unbox_tramp (&aot_module);
8826 emit_llvm_used (&aot_module);
8827 emit_dbg_info (&aot_module, filename, cu_name);
8828 emit_aot_file_info (&aot_module);
8831 * Replace GOT entries for directly callable methods with the methods themselves.
8832 * It would be easier to implement this by predefining all methods before compiling
8833 * their bodies, but that couldn't handle the case when a method fails to compile
8836 if (module->llvm_only) {
8837 GHashTableIter iter;
8839 GSList *callers, *l;
8841 g_hash_table_iter_init (&iter, module->method_to_callers);
8842 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8843 LLVMValueRef lmethod;
8845 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8848 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8850 for (l = callers; l; l = l->next) {
8851 LLVMValueRef caller = (LLVMValueRef)l->data;
8853 mono_llvm_replace_uses_of (caller, lmethod);
8859 /* Replace PLT entries for directly callable methods with the methods themselves */
8861 GHashTableIter iter;
8863 LLVMValueRef callee;
8865 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8866 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8867 if (mono_aot_is_direct_callable (ji)) {
8868 LLVMValueRef lmethod;
8870 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8871 /* The types might not match because the caller might pass an rgctx */
8872 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8873 mono_llvm_replace_uses_of (callee, lmethod);
8874 mono_aot_mark_unused_llvm_plt_entry (ji);
8884 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8885 printf ("%s\n", verifier_err);
8886 g_assert_not_reached ();
8891 LLVMWriteBitcodeToFile (module->lmodule, filename);
8896 md_string (const char *s)
8898 return LLVMMDString (s, strlen (s));
8901 /* Debugging support */
8904 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8906 LLVMModuleRef lmodule = module->lmodule;
8907 LLVMValueRef args [16], ver;
8910 * This can only be enabled when LLVM code is emitted into a separate object
8911 * file, since the AOT compiler also emits dwarf info,
8912 * and the abbrev indexes will not be correct since llvm has added its own
8915 if (!module->emit_dwarf)
8918 #if LLVM_API_VERSION > 100
8919 mono_llvm_di_builder_finalize (module->di_builder);
8921 LLVMValueRef cu_args [16], cu;
8923 char *build_info, *s, *dir;
8926 * Emit dwarf info in the form of LLVM metadata. There is some
8927 * out-of-date documentation at:
8928 * http://llvm.org/docs/SourceLevelDebugging.html
8929 * but most of this was gathered from the llvm and
8934 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8935 /* CU name/compilation dir */
8936 dir = g_path_get_dirname (filename);
8937 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8938 args [1] = LLVMMDString (dir, strlen (dir));
8939 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8942 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8944 build_info = mono_get_runtime_build_info ();
8945 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8946 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8947 g_free (build_info);
8949 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8951 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8952 /* Runtime version */
8953 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8955 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8956 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8958 if (module->subprogram_mds) {
8962 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8963 for (i = 0; i < module->subprogram_mds->len; ++i)
8964 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8965 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8967 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8970 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8971 /* Imported modules */
8972 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8974 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8975 /* DebugEmissionKind = FullDebug */
8976 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8977 cu = LLVMMDNode (cu_args, n_cuargs);
8978 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8981 #if LLVM_API_VERSION > 100
8982 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8983 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8984 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8985 ver = LLVMMDNode (args, 3);
8986 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8988 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8989 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8990 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8991 ver = LLVMMDNode (args, 3);
8992 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8994 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8995 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8996 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8997 ver = LLVMMDNode (args, 3);
8998 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9000 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9001 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9002 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9003 ver = LLVMMDNode (args, 3);
9004 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9009 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9011 MonoLLVMModule *module = ctx->module;
9012 MonoDebugMethodInfo *minfo = ctx->minfo;
9013 char *source_file, *dir, *filename;
9014 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9015 MonoSymSeqPoint *sym_seq_points;
9021 mono_debug_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9023 source_file = g_strdup ("<unknown>");
9024 dir = g_path_get_dirname (source_file);
9025 filename = g_path_get_basename (source_file);
9027 #if LLVM_API_VERSION > 100
9028 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);
9031 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9032 args [0] = md_string (filename);
9033 args [1] = md_string (dir);
9034 ctx_args [1] = LLVMMDNode (args, 2);
9035 ctx_md = LLVMMDNode (ctx_args, 2);
9037 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9038 type_args [1] = NULL;
9039 type_args [2] = NULL;
9040 type_args [3] = LLVMMDString ("", 0);
9041 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9042 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9043 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9044 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9045 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9046 type_args [9] = NULL;
9047 type_args [10] = NULL;
9048 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9049 type_args [12] = NULL;
9050 type_args [13] = NULL;
9051 type_args [14] = NULL;
9052 type_md = LLVMMDNode (type_args, 14);
9054 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9055 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9056 /* Source directory + file pair */
9057 args [0] = md_string (filename);
9058 args [1] = md_string (dir);
9059 md_args [1] = LLVMMDNode (args ,2);
9060 md_args [2] = ctx_md;
9061 md_args [3] = md_string (cfg->method->name);
9062 md_args [4] = md_string (name);
9063 md_args [5] = md_string (name);
9066 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9068 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9070 md_args [7] = type_md;
9072 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9074 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9076 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9077 /* Index into a virtual function */
9078 md_args [11] = NULL;
9079 md_args [12] = NULL;
9081 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9083 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9084 /* Pointer to LLVM function */
9085 md_args [15] = method;
9086 /* Function template parameter */
9087 md_args [16] = NULL;
9088 /* Function declaration descriptor */
9089 md_args [17] = NULL;
9090 /* List of function variables */
9091 md_args [18] = LLVMMDNode (args, 0);
9093 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9094 md = LLVMMDNode (md_args, 20);
9096 if (!module->subprogram_mds)
9097 module->subprogram_mds = g_ptr_array_new ();
9098 g_ptr_array_add (module->subprogram_mds, md);
9102 g_free (source_file);
9103 g_free (sym_seq_points);
9109 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9111 MonoCompile *cfg = ctx->cfg;
9113 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9114 MonoDebugSourceLocation *loc;
9115 LLVMValueRef loc_md;
9117 loc = mono_debug_method_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9120 #if LLVM_API_VERSION > 100
9121 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9122 mono_llvm_di_set_location (builder, loc_md);
9124 LLVMValueRef md_args [16];
9128 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9129 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9130 md_args [nmd_args ++] = ctx->dbg_md;
9131 md_args [nmd_args ++] = NULL;
9132 loc_md = LLVMMDNode (md_args, nmd_args);
9133 LLVMSetCurrentDebugLocation (builder, loc_md);
9135 mono_debug_free_source_location (loc);
9141 default_mono_llvm_unhandled_exception (void)
9143 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9144 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9146 mono_unhandled_exception (target);
9147 mono_invoke_unhandled_exception_hook (target);
9148 g_assert_not_reached ();
9153 - Emit LLVM IR from the mono IR using the LLVM C API.
9154 - The original arch specific code remains, so we can fall back to it if we run
9155 into something we can't handle.
9159 A partial list of issues:
9160 - Handling of opcodes which can throw exceptions.
9162 In the mono JIT, these are implemented using code like this:
9169 push throw_pos - method
9170 call <exception trampoline>
9172 The problematic part is push throw_pos - method, which cannot be represented
9173 in the LLVM IR, since it does not support label values.
9174 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9175 be implemented in JIT mode ?
9176 -> a possible but slower implementation would use the normal exception
9177 throwing code but it would need to control the placement of the throw code
9178 (it needs to be exactly after the compare+branch).
9179 -> perhaps add a PC offset intrinsics ?
9181 - efficient implementation of .ovf opcodes.
9183 These are currently implemented as:
9184 <ins which sets the condition codes>
9187 Some overflow opcodes are now supported by LLVM SVN.
9189 - exception handling, unwinding.
9190 - SSA is disabled for methods with exception handlers
9191 - How to obtain unwind info for LLVM compiled methods ?
9192 -> this is now solved by converting the unwind info generated by LLVM
9194 - LLVM uses the c++ exception handling framework, while we use our home grown
9195 code, and couldn't use the c++ one:
9196 - its not supported under VC++, other exotic platforms.
9197 - it might be impossible to support filter clauses with it.
9201 The trampolines need a predictable call sequence, since they need to disasm
9202 the calling code to obtain register numbers / offsets.
9204 LLVM currently generates this code in non-JIT mode:
9205 mov -0x98(%rax),%eax
9207 Here, the vtable pointer is lost.
9208 -> solution: use one vtable trampoline per class.
9210 - passing/receiving the IMT pointer/RGCTX.
9211 -> solution: pass them as normal arguments ?
9215 LLVM does not allow the specification of argument registers etc. This means
9216 that all calls are made according to the platform ABI.
9218 - passing/receiving vtypes.
9220 Vtypes passed/received in registers are handled by the front end by using
9221 a signature with scalar arguments, and loading the parts of the vtype into those
9224 Vtypes passed on the stack are handled using the 'byval' attribute.
9228 Supported though alloca, we need to emit the load/store code.
9232 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9233 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9234 This is made easier because the IR is already in SSA form.
9235 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9236 types are frequently used incorrectly.
9241 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9242 it with the file containing the methods emitted by the JIT and the AOT data
9246 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9247 * - each bblock should end with a branch
9248 * - setting the return value, making cfg->ret non-volatile
9249 * - avoid some transformations in the JIT which make it harder for us to generate
9251 * - use pointer types to help optimizations.
9254 #else /* DISABLE_JIT */
9257 mono_llvm_cleanup (void)
9262 mono_llvm_free_domain_info (MonoDomain *domain)
9267 mono_llvm_init (void)
9272 default_mono_llvm_unhandled_exception (void)
9276 #endif /* DISABLE_JIT */