2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
54 LLVMModuleRef lmodule;
55 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
56 GHashTable *llvm_types;
58 const char *got_symbol;
59 const char *get_method_symbol;
60 const char *get_unbox_tramp_symbol;
61 GHashTable *plt_entries;
62 GHashTable *plt_entries_ji;
63 GHashTable *method_to_lmethod;
64 GHashTable *direct_callables;
69 GPtrArray *subprogram_mds;
71 LLVMExecutionEngineRef ee;
72 gboolean external_symbols;
75 LLVMValueRef personality;
78 MonoAssembly *assembly;
80 MonoAotFileInfo aot_info;
81 const char *jit_got_symbol;
82 const char *eh_frame_symbol;
83 LLVMValueRef get_method, get_unbox_tramp;
84 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
85 LLVMValueRef code_start, code_end;
86 LLVMValueRef inited_var;
87 int max_inited_idx, max_method_idx;
88 gboolean has_jitted_code;
91 GHashTable *idx_to_lmethod;
92 GHashTable *idx_to_unbox_tramp;
93 /* Maps a MonoMethod to LLVM instructions representing it */
94 GHashTable *method_to_callers;
95 LLVMContextRef context;
96 LLVMValueRef sentinel_exception;
97 void *di_builder, *cu;
98 GHashTable *objc_selector_to_var;
102 * Information associated by the backend with mono basic blocks.
105 LLVMBasicBlockRef bblock, end_bblock;
106 LLVMValueRef finally_ind;
107 gboolean added, invoke_target;
109 * If this bblock is the start of a finally clause, this is a list of bblocks it
110 * needs to branch to in ENDFINALLY.
112 GSList *call_handler_return_bbs;
114 * If this bblock is the start of a finally clause, this is the bblock that
115 * CALL_HANDLER needs to branch to.
117 LLVMBasicBlockRef call_handler_target_bb;
118 /* The list of switch statements generated by ENDFINALLY instructions */
119 GSList *endfinally_switch_ins_list;
124 * Structure containing emit state
127 MonoMemPool *mempool;
129 /* Maps method names to the corresponding LLVMValueRef */
130 GHashTable *emitted_method_decls;
133 LLVMValueRef lmethod;
134 MonoLLVMModule *module;
135 LLVMModuleRef lmodule;
137 int sindex, default_index, ex_index;
138 LLVMBuilderRef builder;
139 LLVMValueRef *values, *addresses;
140 MonoType **vreg_cli_types;
142 MonoMethodSignature *sig;
144 GHashTable *region_to_handler;
145 GHashTable *clause_to_handler;
146 LLVMBuilderRef alloca_builder;
147 LLVMValueRef last_alloca;
148 LLVMValueRef rgctx_arg;
149 LLVMValueRef this_arg;
150 LLVMTypeRef *vreg_types;
151 LLVMTypeRef method_type;
152 LLVMBasicBlockRef init_bb, inited_bb;
154 gboolean *unreachable;
156 gboolean has_got_access;
157 gboolean is_linkonce;
158 int this_arg_pindex, rgctx_arg_pindex;
159 LLVMValueRef imt_rgctx_loc;
160 GHashTable *llvm_types;
162 MonoDebugMethodInfo *minfo;
164 /* For every clause, the clauses it is nested in */
167 GHashTable *exc_meta;
168 GHashTable *method_to_callers;
169 GPtrArray *phi_values;
170 GPtrArray *bblock_list;
172 GHashTable *jit_callees;
173 LLVMValueRef long_bb_break_var;
179 MonoBasicBlock *in_bb;
184 * Instruction metadata
185 * This is the same as ins_info, but LREG != IREG.
193 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
194 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
201 /* keep in sync with the enum in mini.h */
204 #include "mini-ops.h"
209 #if SIZEOF_VOID_P == 4
210 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
212 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
215 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
218 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
220 #define TRACE_FAILURE(msg)
224 #define IS_TARGET_X86 1
226 #define IS_TARGET_X86 0
230 #define IS_TARGET_AMD64 1
232 #define IS_TARGET_AMD64 0
235 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
237 static LLVMIntPredicate cond_to_llvm_cond [] = {
250 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
263 static MonoNativeTlsKey current_cfg_tls_id;
265 static MonoLLVMModule aot_module;
267 static GHashTable *intrins_id_to_name;
268 static GHashTable *intrins_name_to_id;
270 static void init_jit_module (MonoDomain *domain);
272 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
273 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
274 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
275 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
276 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
277 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
280 set_failure (EmitContext *ctx, const char *message)
282 TRACE_FAILURE (reason);
283 ctx->cfg->exception_message = g_strdup (message);
284 ctx->cfg->disable_llvm = TRUE;
290 * The LLVM type with width == sizeof (gpointer)
295 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
301 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
307 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
313 * Return the size of the LLVM representation of the vtype T.
316 get_vtype_size (MonoType *t)
320 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
322 /* LLVMArgAsIArgs depends on this since it stores whole words */
323 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
330 * simd_class_to_llvm_type:
332 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
335 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
337 if (!strcmp (klass->name, "Vector2d")) {
338 return LLVMVectorType (LLVMDoubleType (), 2);
339 } else if (!strcmp (klass->name, "Vector2l")) {
340 return LLVMVectorType (LLVMInt64Type (), 2);
341 } else if (!strcmp (klass->name, "Vector2ul")) {
342 return LLVMVectorType (LLVMInt64Type (), 2);
343 } else if (!strcmp (klass->name, "Vector4i")) {
344 return LLVMVectorType (LLVMInt32Type (), 4);
345 } else if (!strcmp (klass->name, "Vector4ui")) {
346 return LLVMVectorType (LLVMInt32Type (), 4);
347 } else if (!strcmp (klass->name, "Vector4f")) {
348 return LLVMVectorType (LLVMFloatType (), 4);
349 } else if (!strcmp (klass->name, "Vector8s")) {
350 return LLVMVectorType (LLVMInt16Type (), 8);
351 } else if (!strcmp (klass->name, "Vector8us")) {
352 return LLVMVectorType (LLVMInt16Type (), 8);
353 } else if (!strcmp (klass->name, "Vector16sb")) {
354 return LLVMVectorType (LLVMInt8Type (), 16);
355 } else if (!strcmp (klass->name, "Vector16b")) {
356 return LLVMVectorType (LLVMInt8Type (), 16);
358 printf ("%s\n", klass->name);
364 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
365 static inline G_GNUC_UNUSED LLVMTypeRef
366 type_to_simd_type (int type)
370 return LLVMVectorType (LLVMInt8Type (), 16);
372 return LLVMVectorType (LLVMInt16Type (), 8);
374 return LLVMVectorType (LLVMInt32Type (), 4);
376 return LLVMVectorType (LLVMInt64Type (), 2);
378 return LLVMVectorType (LLVMDoubleType (), 2);
380 return LLVMVectorType (LLVMFloatType (), 4);
382 g_assert_not_reached ();
388 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
390 int i, size, nfields, esize;
391 LLVMTypeRef *eltypes;
396 t = &klass->byval_arg;
398 if (mini_type_is_hfa (t, &nfields, &esize)) {
400 * This is needed on arm64 where HFAs are returned in
404 eltypes = g_new (LLVMTypeRef, size);
405 for (i = 0; i < size; ++i)
406 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
408 size = get_vtype_size (t);
410 eltypes = g_new (LLVMTypeRef, size);
411 for (i = 0; i < size; ++i)
412 eltypes [i] = LLVMInt8Type ();
415 name = mono_type_full_name (&klass->byval_arg);
416 ltype = LLVMStructCreateNamed (module->context, name);
417 LLVMStructSetBody (ltype, eltypes, size, FALSE);
427 * Return the LLVM type corresponding to T.
430 type_to_llvm_type (EmitContext *ctx, MonoType *t)
432 t = mini_get_underlying_type (t);
436 return LLVMVoidType ();
438 return LLVMInt8Type ();
440 return LLVMInt16Type ();
442 return LLVMInt32Type ();
444 return LLVMInt8Type ();
446 return LLVMInt16Type ();
448 return LLVMInt32Type ();
449 case MONO_TYPE_BOOLEAN:
450 return LLVMInt8Type ();
453 return LLVMInt64Type ();
455 return LLVMInt16Type ();
457 return LLVMFloatType ();
459 return LLVMDoubleType ();
462 return IntPtrType ();
463 case MONO_TYPE_OBJECT:
464 case MONO_TYPE_CLASS:
465 case MONO_TYPE_ARRAY:
466 case MONO_TYPE_SZARRAY:
467 case MONO_TYPE_STRING:
469 return ObjRefType ();
472 /* Because of generic sharing */
473 return ObjRefType ();
474 case MONO_TYPE_GENERICINST:
475 if (!mono_type_generic_inst_is_valuetype (t))
476 return ObjRefType ();
478 case MONO_TYPE_VALUETYPE:
479 case MONO_TYPE_TYPEDBYREF: {
483 klass = mono_class_from_mono_type (t);
485 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
486 return simd_class_to_llvm_type (ctx, klass);
489 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
491 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
493 ltype = create_llvm_type_for_type (ctx->module, klass);
494 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
500 printf ("X: %d\n", t->type);
501 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
502 ctx->cfg->disable_llvm = TRUE;
510 * Return whenever T is an unsigned int type.
513 type_is_unsigned (EmitContext *ctx, MonoType *t)
515 t = mini_get_underlying_type (t);
531 * type_to_llvm_arg_type:
533 * Same as type_to_llvm_type, but treat i8/i16 as i32.
536 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
538 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
540 if (ctx->cfg->llvm_only)
544 * This works on all abis except arm64/ios which passes multiple
545 * arguments in one stack slot.
548 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
550 * LLVM generates code which only sets the lower bits, while JITted
551 * code expects all the bits to be set.
553 ptype = LLVMInt32Type ();
561 * llvm_type_to_stack_type:
563 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
566 static G_GNUC_UNUSED LLVMTypeRef
567 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
571 if (type == LLVMInt8Type ())
572 return LLVMInt32Type ();
573 else if (type == LLVMInt16Type ())
574 return LLVMInt32Type ();
575 else if (!cfg->r4fp && type == LLVMFloatType ())
576 return LLVMDoubleType ();
582 * regtype_to_llvm_type:
584 * Return the LLVM type corresponding to the regtype C used in instruction
588 regtype_to_llvm_type (char c)
592 return LLVMInt32Type ();
594 return LLVMInt64Type ();
596 return LLVMDoubleType ();
605 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
608 op_to_llvm_type (int opcode)
613 return LLVMInt8Type ();
616 return LLVMInt8Type ();
619 return LLVMInt16Type ();
622 return LLVMInt16Type ();
625 return LLVMInt32Type ();
628 return LLVMInt32Type ();
630 return LLVMInt64Type ();
632 return LLVMFloatType ();
634 return LLVMDoubleType ();
636 return LLVMInt64Type ();
638 return LLVMInt32Type ();
640 return LLVMInt64Type ();
645 return LLVMInt8Type ();
650 return LLVMInt16Type ();
652 return LLVMInt32Type ();
655 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
662 return LLVMInt32Type ();
669 return LLVMInt64Type ();
671 printf ("%s\n", mono_inst_name (opcode));
672 g_assert_not_reached ();
677 #define CLAUSE_START(clause) ((clause)->try_offset)
678 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
681 * load_store_to_llvm_type:
683 * Return the size/sign/zero extension corresponding to the load/store opcode
687 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
693 case OP_LOADI1_MEMBASE:
694 case OP_STOREI1_MEMBASE_REG:
695 case OP_STOREI1_MEMBASE_IMM:
696 case OP_ATOMIC_LOAD_I1:
697 case OP_ATOMIC_STORE_I1:
700 return LLVMInt8Type ();
701 case OP_LOADU1_MEMBASE:
703 case OP_ATOMIC_LOAD_U1:
704 case OP_ATOMIC_STORE_U1:
707 return LLVMInt8Type ();
708 case OP_LOADI2_MEMBASE:
709 case OP_STOREI2_MEMBASE_REG:
710 case OP_STOREI2_MEMBASE_IMM:
711 case OP_ATOMIC_LOAD_I2:
712 case OP_ATOMIC_STORE_I2:
715 return LLVMInt16Type ();
716 case OP_LOADU2_MEMBASE:
718 case OP_ATOMIC_LOAD_U2:
719 case OP_ATOMIC_STORE_U2:
722 return LLVMInt16Type ();
723 case OP_LOADI4_MEMBASE:
724 case OP_LOADU4_MEMBASE:
727 case OP_STOREI4_MEMBASE_REG:
728 case OP_STOREI4_MEMBASE_IMM:
729 case OP_ATOMIC_LOAD_I4:
730 case OP_ATOMIC_STORE_I4:
731 case OP_ATOMIC_LOAD_U4:
732 case OP_ATOMIC_STORE_U4:
734 return LLVMInt32Type ();
735 case OP_LOADI8_MEMBASE:
737 case OP_STOREI8_MEMBASE_REG:
738 case OP_STOREI8_MEMBASE_IMM:
739 case OP_ATOMIC_LOAD_I8:
740 case OP_ATOMIC_STORE_I8:
741 case OP_ATOMIC_LOAD_U8:
742 case OP_ATOMIC_STORE_U8:
744 return LLVMInt64Type ();
745 case OP_LOADR4_MEMBASE:
746 case OP_STORER4_MEMBASE_REG:
747 case OP_ATOMIC_LOAD_R4:
748 case OP_ATOMIC_STORE_R4:
750 return LLVMFloatType ();
751 case OP_LOADR8_MEMBASE:
752 case OP_STORER8_MEMBASE_REG:
753 case OP_ATOMIC_LOAD_R8:
754 case OP_ATOMIC_STORE_R8:
756 return LLVMDoubleType ();
757 case OP_LOAD_MEMBASE:
759 case OP_STORE_MEMBASE_REG:
760 case OP_STORE_MEMBASE_IMM:
761 *size = sizeof (gpointer);
762 return IntPtrType ();
764 g_assert_not_reached ();
772 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
775 ovf_op_to_intrins (int opcode)
779 return "llvm.sadd.with.overflow.i32";
781 return "llvm.uadd.with.overflow.i32";
783 return "llvm.ssub.with.overflow.i32";
785 return "llvm.usub.with.overflow.i32";
787 return "llvm.smul.with.overflow.i32";
789 return "llvm.umul.with.overflow.i32";
791 return "llvm.sadd.with.overflow.i64";
793 return "llvm.uadd.with.overflow.i64";
795 return "llvm.ssub.with.overflow.i64";
797 return "llvm.usub.with.overflow.i64";
799 return "llvm.smul.with.overflow.i64";
801 return "llvm.umul.with.overflow.i64";
803 g_assert_not_reached ();
809 simd_op_to_intrins (int opcode)
812 #if defined(TARGET_X86) || defined(TARGET_AMD64)
814 return "llvm.x86.sse2.min.pd";
816 return "llvm.x86.sse.min.ps";
818 return "llvm.x86.sse2.max.pd";
820 return "llvm.x86.sse.max.ps";
822 return "llvm.x86.sse3.hadd.pd";
824 return "llvm.x86.sse3.hadd.ps";
826 return "llvm.x86.sse3.hsub.pd";
828 return "llvm.x86.sse3.hsub.ps";
830 return "llvm.x86.sse3.addsub.ps";
832 return "llvm.x86.sse3.addsub.pd";
833 case OP_EXTRACT_MASK:
834 return "llvm.x86.sse2.pmovmskb.128";
837 return "llvm.x86.sse2.psrli.w";
840 return "llvm.x86.sse2.psrli.d";
843 return "llvm.x86.sse2.psrli.q";
846 return "llvm.x86.sse2.pslli.w";
849 return "llvm.x86.sse2.pslli.d";
852 return "llvm.x86.sse2.pslli.q";
855 return "llvm.x86.sse2.psrai.w";
858 return "llvm.x86.sse2.psrai.d";
860 return "llvm.x86.sse2.padds.b";
862 return "llvm.x86.sse2.padds.w";
864 return "llvm.x86.sse2.psubs.b";
866 return "llvm.x86.sse2.psubs.w";
867 case OP_PADDB_SAT_UN:
868 return "llvm.x86.sse2.paddus.b";
869 case OP_PADDW_SAT_UN:
870 return "llvm.x86.sse2.paddus.w";
871 case OP_PSUBB_SAT_UN:
872 return "llvm.x86.sse2.psubus.b";
873 case OP_PSUBW_SAT_UN:
874 return "llvm.x86.sse2.psubus.w";
876 return "llvm.x86.sse2.pavg.b";
878 return "llvm.x86.sse2.pavg.w";
880 return "llvm.x86.sse.sqrt.ps";
882 return "llvm.x86.sse2.sqrt.pd";
884 return "llvm.x86.sse.rsqrt.ps";
886 return "llvm.x86.sse.rcp.ps";
888 return "llvm.x86.sse2.cvtdq2pd";
890 return "llvm.x86.sse2.cvtdq2ps";
892 return "llvm.x86.sse2.cvtpd2dq";
894 return "llvm.x86.sse2.cvtps2dq";
896 return "llvm.x86.sse2.cvtpd2ps";
898 return "llvm.x86.sse2.cvtps2pd";
900 return "llvm.x86.sse2.cvttpd2dq";
902 return "llvm.x86.sse2.cvttps2dq";
904 return "llvm.x86.sse2.packsswb.128";
906 return "llvm.x86.sse2.packssdw.128";
908 return "llvm.x86.sse2.packuswb.128";
910 return "llvm.x86.sse41.packusdw";
912 return "llvm.x86.sse2.pmulh.w";
913 case OP_PMULW_HIGH_UN:
914 return "llvm.x86.sse2.pmulhu.w";
917 g_assert_not_reached ();
923 simd_op_to_llvm_type (int opcode)
925 #if defined(TARGET_X86) || defined(TARGET_AMD64)
929 return type_to_simd_type (MONO_TYPE_R8);
932 return type_to_simd_type (MONO_TYPE_I8);
935 return type_to_simd_type (MONO_TYPE_I4);
940 return type_to_simd_type (MONO_TYPE_I2);
944 return type_to_simd_type (MONO_TYPE_I1);
946 return type_to_simd_type (MONO_TYPE_R4);
949 return type_to_simd_type (MONO_TYPE_I4);
953 return type_to_simd_type (MONO_TYPE_R8);
957 return type_to_simd_type (MONO_TYPE_R4);
958 case OP_EXTRACT_MASK:
959 return type_to_simd_type (MONO_TYPE_I1);
965 return type_to_simd_type (MONO_TYPE_R4);
968 return type_to_simd_type (MONO_TYPE_R8);
970 g_assert_not_reached ();
981 * Return the LLVM basic block corresponding to BB.
983 static LLVMBasicBlockRef
984 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
986 char bb_name_buf [128];
989 if (ctx->bblocks [bb->block_num].bblock == NULL) {
990 if (bb->flags & BB_EXCEPTION_HANDLER) {
991 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
992 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
993 bb_name = bb_name_buf;
994 } else if (bb->block_num < 256) {
995 if (!ctx->module->bb_names) {
996 ctx->module->bb_names_len = 256;
997 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
999 if (!ctx->module->bb_names [bb->block_num]) {
1002 n = g_strdup_printf ("BB%d", bb->block_num);
1003 mono_memory_barrier ();
1004 ctx->module->bb_names [bb->block_num] = n;
1006 bb_name = ctx->module->bb_names [bb->block_num];
1008 sprintf (bb_name_buf, "BB%d", bb->block_num);
1009 bb_name = bb_name_buf;
1012 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1013 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1016 return ctx->bblocks [bb->block_num].bblock;
1022 * Return the last LLVM bblock corresponding to BB.
1023 * This might not be equal to the bb returned by get_bb () since we need to generate
1024 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1026 static LLVMBasicBlockRef
1027 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1030 return ctx->bblocks [bb->block_num].end_bblock;
1033 static LLVMBasicBlockRef
1034 gen_bb (EmitContext *ctx, const char *prefix)
1038 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1039 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1045 * Return the target of the patch identified by TYPE and TARGET.
1048 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1054 memset (&ji, 0, sizeof (ji));
1056 ji.data.target = target;
1058 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1059 mono_error_assert_ok (&error);
1067 * Emit code to convert the LLVM value V to DTYPE.
1070 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1072 LLVMTypeRef stype = LLVMTypeOf (v);
1074 if (stype != dtype) {
1075 gboolean ext = FALSE;
1078 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1080 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1082 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1086 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1088 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1089 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1092 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1093 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1094 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1095 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1096 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1097 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1098 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1099 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1101 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1102 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1103 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1104 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1105 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1106 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1108 if (mono_arch_is_soft_float ()) {
1109 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1110 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1111 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1112 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1115 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1116 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1119 LLVMDumpValue (LLVMConstNull (dtype));
1120 g_assert_not_reached ();
1128 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1130 return convert_full (ctx, v, dtype, FALSE);
1134 * emit_volatile_load:
1136 * If vreg is volatile, emit a load from its address.
1139 emit_volatile_load (EmitContext *ctx, int vreg)
1145 // FIXME: This hack is required because we pass the rgctx in a callee saved
1146 // register on arm64 (x15), and llvm might keep the value in that register
1147 // even through the register is marked as 'reserved' inside llvm.
1148 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1149 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1151 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1153 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1155 t = ctx->vreg_cli_types [vreg];
1156 if (t && !t->byref) {
1158 * Might have to zero extend since llvm doesn't have
1161 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1162 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1163 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1164 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1165 else if (t->type == MONO_TYPE_U8)
1166 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1173 * emit_volatile_store:
1175 * If VREG is volatile, emit a store from its value to its address.
1178 emit_volatile_store (EmitContext *ctx, int vreg)
1180 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1182 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1183 g_assert (ctx->addresses [vreg]);
1184 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1189 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1191 LLVMTypeRef ret_type;
1192 LLVMTypeRef *param_types = NULL;
1197 rtype = mini_get_underlying_type (sig->ret);
1198 ret_type = type_to_llvm_type (ctx, rtype);
1202 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1206 param_types [pindex ++] = ThisType ();
1207 for (i = 0; i < sig->param_count; ++i)
1208 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1210 if (!ctx_ok (ctx)) {
1211 g_free (param_types);
1215 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1216 g_free (param_types);
1222 * sig_to_llvm_sig_full:
1224 * Return the LLVM signature corresponding to the mono signature SIG using the
1225 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1228 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1230 LLVMTypeRef ret_type;
1231 LLVMTypeRef *param_types = NULL;
1233 int i, j, pindex, vret_arg_pindex = 0;
1234 gboolean vretaddr = FALSE;
1238 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1240 rtype = mini_get_underlying_type (sig->ret);
1241 ret_type = type_to_llvm_type (ctx, rtype);
1245 switch (cinfo->ret.storage) {
1246 case LLVMArgVtypeInReg:
1247 /* LLVM models this by returning an aggregate value */
1248 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1249 LLVMTypeRef members [2];
1251 members [0] = IntPtrType ();
1252 ret_type = LLVMStructType (members, 1, FALSE);
1253 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1255 ret_type = LLVMVoidType ();
1256 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1257 LLVMTypeRef members [2];
1259 members [0] = IntPtrType ();
1260 members [1] = IntPtrType ();
1261 ret_type = LLVMStructType (members, 2, FALSE);
1263 g_assert_not_reached ();
1266 case LLVMArgVtypeByVal:
1267 /* Vtype returned normally by val */
1269 case LLVMArgVtypeAsScalar: {
1270 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1271 /* LLVM models this by returning an int */
1272 if (size < SIZEOF_VOID_P) {
1273 g_assert (cinfo->ret.nslots == 1);
1274 ret_type = LLVMIntType (size * 8);
1276 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1277 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1281 case LLVMArgAsIArgs:
1282 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1284 case LLVMArgFpStruct: {
1285 /* Vtype returned as a fp struct */
1286 LLVMTypeRef members [16];
1288 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1289 for (i = 0; i < cinfo->ret.nslots; ++i)
1290 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1291 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1294 case LLVMArgVtypeByRef:
1295 /* Vtype returned using a hidden argument */
1296 ret_type = LLVMVoidType ();
1298 case LLVMArgVtypeRetAddr:
1299 case LLVMArgGsharedvtFixed:
1300 case LLVMArgGsharedvtFixedVtype:
1301 case LLVMArgGsharedvtVariable:
1303 ret_type = LLVMVoidType ();
1309 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1311 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1313 * Has to be the first argument because of the sret argument attribute
1314 * FIXME: This might conflict with passing 'this' as the first argument, but
1315 * this is only used on arm64 which has a dedicated struct return register.
1317 cinfo->vret_arg_pindex = pindex;
1318 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1319 if (!ctx_ok (ctx)) {
1320 g_free (param_types);
1323 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1326 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1327 cinfo->rgctx_arg_pindex = pindex;
1328 param_types [pindex] = ctx->module->ptr_type;
1331 if (cinfo->imt_arg) {
1332 cinfo->imt_arg_pindex = pindex;
1333 param_types [pindex] = ctx->module->ptr_type;
1337 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1338 vret_arg_pindex = pindex;
1339 if (cinfo->vret_arg_index == 1) {
1340 /* Add the slots consumed by the first argument */
1341 LLVMArgInfo *ainfo = &cinfo->args [0];
1342 switch (ainfo->storage) {
1343 case LLVMArgVtypeInReg:
1344 for (j = 0; j < 2; ++j) {
1345 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1354 cinfo->vret_arg_pindex = vret_arg_pindex;
1357 if (vretaddr && vret_arg_pindex == pindex)
1358 param_types [pindex ++] = IntPtrType ();
1360 cinfo->this_arg_pindex = pindex;
1361 param_types [pindex ++] = ThisType ();
1362 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1364 if (vretaddr && vret_arg_pindex == pindex)
1365 param_types [pindex ++] = IntPtrType ();
1366 for (i = 0; i < sig->param_count; ++i) {
1367 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1369 if (vretaddr && vret_arg_pindex == pindex)
1370 param_types [pindex ++] = IntPtrType ();
1371 ainfo->pindex = pindex;
1373 switch (ainfo->storage) {
1374 case LLVMArgVtypeInReg:
1375 for (j = 0; j < 2; ++j) {
1376 switch (ainfo->pair_storage [j]) {
1378 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1383 g_assert_not_reached ();
1387 case LLVMArgVtypeByVal:
1388 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1391 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1394 case LLVMArgAsIArgs:
1395 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1398 case LLVMArgVtypeByRef:
1399 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1402 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1405 case LLVMArgAsFpArgs: {
1408 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1409 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1410 param_types [pindex ++] = LLVMDoubleType ();
1411 for (j = 0; j < ainfo->nslots; ++j)
1412 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1415 case LLVMArgVtypeAsScalar:
1416 g_assert_not_reached ();
1418 case LLVMArgGsharedvtFixed:
1419 case LLVMArgGsharedvtFixedVtype:
1420 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1422 case LLVMArgGsharedvtVariable:
1423 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1426 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1430 if (!ctx_ok (ctx)) {
1431 g_free (param_types);
1434 if (vretaddr && vret_arg_pindex == pindex)
1435 param_types [pindex ++] = IntPtrType ();
1436 if (ctx->llvm_only && cinfo->rgctx_arg) {
1437 /* Pass the rgctx as the last argument */
1438 cinfo->rgctx_arg_pindex = pindex;
1439 param_types [pindex] = ctx->module->ptr_type;
1443 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1444 g_free (param_types);
1450 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1452 return sig_to_llvm_sig_full (ctx, sig, NULL);
1456 * LLVMFunctionType1:
1458 * Create an LLVM function type from the arguments.
1460 static G_GNUC_UNUSED LLVMTypeRef
1461 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1464 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1468 * LLVMFunctionType1:
1470 * Create an LLVM function type from the arguments.
1472 static G_GNUC_UNUSED LLVMTypeRef
1473 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1474 LLVMTypeRef ParamType1,
1477 LLVMTypeRef param_types [1];
1479 param_types [0] = ParamType1;
1481 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1485 * LLVMFunctionType2:
1487 * Create an LLVM function type from the arguments.
1489 static G_GNUC_UNUSED LLVMTypeRef
1490 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1491 LLVMTypeRef ParamType1,
1492 LLVMTypeRef ParamType2,
1495 LLVMTypeRef param_types [2];
1497 param_types [0] = ParamType1;
1498 param_types [1] = ParamType2;
1500 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1504 * LLVMFunctionType3:
1506 * Create an LLVM function type from the arguments.
1508 static G_GNUC_UNUSED LLVMTypeRef
1509 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1510 LLVMTypeRef ParamType1,
1511 LLVMTypeRef ParamType2,
1512 LLVMTypeRef ParamType3,
1515 LLVMTypeRef param_types [3];
1517 param_types [0] = ParamType1;
1518 param_types [1] = ParamType2;
1519 param_types [2] = ParamType3;
1521 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1524 static G_GNUC_UNUSED LLVMTypeRef
1525 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1526 LLVMTypeRef ParamType1,
1527 LLVMTypeRef ParamType2,
1528 LLVMTypeRef ParamType3,
1529 LLVMTypeRef ParamType4,
1530 LLVMTypeRef ParamType5,
1533 LLVMTypeRef param_types [5];
1535 param_types [0] = ParamType1;
1536 param_types [1] = ParamType2;
1537 param_types [2] = ParamType3;
1538 param_types [3] = ParamType4;
1539 param_types [4] = ParamType5;
1541 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1547 * Create an LLVM builder and remember it so it can be freed later.
1549 static LLVMBuilderRef
1550 create_builder (EmitContext *ctx)
1552 LLVMBuilderRef builder = LLVMCreateBuilder ();
1554 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1560 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1565 case MONO_PATCH_INFO_INTERNAL_METHOD:
1566 name = g_strdup_printf ("jit_icall_%s", data);
1568 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1569 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1570 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1574 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1582 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1586 LLVMValueRef indexes [2];
1587 LLVMValueRef got_entry_addr, load;
1588 LLVMBuilderRef builder = ctx->builder;
1593 MonoJumpInfo tmp_ji;
1595 tmp_ji.data.target = data;
1597 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1599 ji->next = cfg->patch_info;
1600 cfg->patch_info = ji;
1602 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1603 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1605 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1606 * explicitly initialize it.
1608 if (!mono_aot_is_shared_got_offset (got_offset)) {
1609 //mono_print_ji (ji);
1611 ctx->has_got_access = TRUE;
1614 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1615 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1616 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1618 name = get_aotconst_name (type, data, got_offset);
1620 load = LLVMBuildLoad (builder, got_entry_addr, "");
1621 load = convert (ctx, load, llvm_type);
1622 LLVMSetValueName (load, name ? name : "");
1624 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1627 //set_invariant_load_flag (load);
1633 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1635 return get_aotconst_typed (ctx, type, data, NULL);
1639 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1641 LLVMValueRef callee;
1643 if (ctx->llvm_only) {
1644 callee_name = mono_aot_get_direct_call_symbol (type, data);
1646 /* Directly callable */
1648 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1650 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1652 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1654 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1656 /* LLVMTypeRef's are uniqued */
1657 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1658 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1660 g_free (callee_name);
1666 * Calls are made through the GOT.
1668 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1670 MonoJumpInfo *ji = NULL;
1672 callee_name = mono_aot_get_plt_symbol (type, data);
1676 if (ctx->cfg->compile_aot)
1677 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1678 mono_add_patch_info (ctx->cfg, 0, type, data);
1681 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1683 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1685 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1687 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1690 if (ctx->cfg->compile_aot) {
1691 ji = g_new0 (MonoJumpInfo, 1);
1693 ji->data.target = data;
1695 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1703 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1705 #if LLVM_API_VERSION > 100
1706 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1707 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1708 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1709 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1712 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1713 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1719 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1721 MonoMethodHeader *header = cfg->header;
1722 MonoExceptionClause *clause;
1726 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1727 return (bb->region >> 8) - 1;
1730 for (i = 0; i < header->num_clauses; ++i) {
1731 clause = &header->clauses [i];
1733 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1740 static MonoExceptionClause *
1741 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1743 // Since they're sorted by nesting we just need
1744 // the first one that the bb is a member of
1745 for (int i = 0; i < cfg->header->num_clauses; i++) {
1746 MonoExceptionClause *curr = &cfg->header->clauses [i];
1748 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1756 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1758 LLVMValueRef md_arg;
1761 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1762 md_arg = LLVMMDString ("mono", 4);
1763 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1767 set_invariant_load_flag (LLVMValueRef v)
1769 LLVMValueRef md_arg;
1771 const char *flag_name;
1773 // FIXME: Cache this
1774 flag_name = "invariant.load";
1775 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1776 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1777 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1783 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1787 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1789 MonoCompile *cfg = ctx->cfg;
1790 LLVMValueRef lcall = NULL;
1791 LLVMBuilderRef builder = *builder_ref;
1792 MonoExceptionClause *clause;
1794 if (ctx->llvm_only) {
1795 clause = get_most_deep_clause (cfg, ctx, bb);
1798 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1801 * Have to use an invoke instead of a call, branching to the
1802 * handler bblock of the clause containing this bblock.
1804 intptr_t key = CLAUSE_END(clause);
1806 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1808 // FIXME: Find the one that has the lowest end bound for the right start address
1809 // FIXME: Finally + nesting
1812 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1815 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1817 builder = ctx->builder = create_builder (ctx);
1818 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1820 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1824 int clause_index = get_handler_clause (cfg, bb);
1826 if (clause_index != -1) {
1827 MonoMethodHeader *header = cfg->header;
1828 MonoExceptionClause *ec = &header->clauses [clause_index];
1829 MonoBasicBlock *tblock;
1830 LLVMBasicBlockRef ex_bb, noex_bb;
1833 * Have to use an invoke instead of a call, branching to the
1834 * handler bblock of the clause containing this bblock.
1837 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1839 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1842 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1844 ex_bb = get_bb (ctx, tblock);
1846 noex_bb = gen_bb (ctx, "NOEX_BB");
1849 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1851 builder = ctx->builder = create_builder (ctx);
1852 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1854 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1859 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1860 ctx->builder = builder;
1864 *builder_ref = ctx->builder;
1870 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1872 const char *intrins_name;
1873 LLVMValueRef args [16], res;
1874 LLVMTypeRef addr_type;
1875 gboolean use_intrinsics = TRUE;
1877 #if LLVM_API_VERSION > 100
1878 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1879 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1882 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1883 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1884 *builder_ref = ctx->builder;
1885 use_intrinsics = FALSE;
1889 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1890 LLVMAtomicOrdering ordering;
1893 case LLVM_BARRIER_NONE:
1894 ordering = LLVMAtomicOrderingNotAtomic;
1896 case LLVM_BARRIER_ACQ:
1897 ordering = LLVMAtomicOrderingAcquire;
1899 case LLVM_BARRIER_SEQ:
1900 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1903 g_assert_not_reached ();
1908 * We handle loads which can fault by calling a mono specific intrinsic
1909 * using an invoke, so they are handled properly inside try blocks.
1910 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1911 * are marked with IntrReadArgMem.
1915 intrins_name = "llvm.mono.load.i8.p0i8";
1918 intrins_name = "llvm.mono.load.i16.p0i16";
1921 intrins_name = "llvm.mono.load.i32.p0i32";
1924 intrins_name = "llvm.mono.load.i64.p0i64";
1927 g_assert_not_reached ();
1930 addr_type = LLVMTypeOf (addr);
1931 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1932 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1935 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1936 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1937 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1938 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1940 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1941 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1942 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1943 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1950 * We emit volatile loads for loads which can fault, because otherwise
1951 * LLVM will generate invalid code when encountering a load from a
1954 if (barrier != LLVM_BARRIER_NONE)
1955 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1957 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1959 /* Mark it with a custom metadata */
1962 set_metadata_flag (res, "mono.faulting.load");
1970 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1972 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
1976 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
1978 const char *intrins_name;
1979 LLVMValueRef args [16];
1980 gboolean use_intrinsics = TRUE;
1982 #if LLVM_API_VERSION > 100
1983 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1984 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1985 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1986 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1987 *builder_ref = ctx->builder;
1988 use_intrinsics = FALSE;
1992 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1993 LLVMAtomicOrdering ordering;
1996 case LLVM_BARRIER_NONE:
1997 ordering = LLVMAtomicOrderingNotAtomic;
1999 case LLVM_BARRIER_REL:
2000 ordering = LLVMAtomicOrderingRelease;
2002 case LLVM_BARRIER_SEQ:
2003 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2006 g_assert_not_reached ();
2012 intrins_name = "llvm.mono.store.i8.p0i8";
2015 intrins_name = "llvm.mono.store.i16.p0i16";
2018 intrins_name = "llvm.mono.store.i32.p0i32";
2021 intrins_name = "llvm.mono.store.i64.p0i64";
2024 g_assert_not_reached ();
2027 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2028 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2029 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2034 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2035 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2036 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2037 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2039 if (barrier != LLVM_BARRIER_NONE)
2040 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2042 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2047 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2049 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2053 * emit_cond_system_exception:
2055 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2056 * Might set the ctx exception.
2059 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2061 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2062 LLVMBuilderRef builder;
2063 MonoClass *exc_class;
2064 LLVMValueRef args [2];
2065 LLVMValueRef callee;
2066 gboolean no_pc = FALSE;
2068 if (IS_TARGET_AMD64)
2069 /* Some platforms don't require the pc argument */
2072 ex_bb = gen_bb (ctx, "EX_BB");
2074 ex2_bb = gen_bb (ctx, "EX2_BB");
2075 noex_bb = gen_bb (ctx, "NOEX_BB");
2077 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2079 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2081 /* Emit exception throwing code */
2082 ctx->builder = builder = create_builder (ctx);
2083 LLVMPositionBuilderAtEnd (builder, ex_bb);
2085 if (ctx->cfg->llvm_only) {
2086 static LLVMTypeRef sig;
2089 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2090 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2092 LLVMBuildBr (builder, ex2_bb);
2094 ctx->builder = builder = create_builder (ctx);
2095 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2097 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2098 emit_call (ctx, bb, &builder, callee, args, 1);
2099 LLVMBuildUnreachable (builder);
2101 ctx->builder = builder = create_builder (ctx);
2102 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2104 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2110 callee = ctx->module->throw_corlib_exception;
2113 const char *icall_name;
2116 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2118 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2119 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2121 if (ctx->cfg->compile_aot) {
2122 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2125 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2126 * - On x86, LLVM generated code doesn't push the arguments
2127 * - The trampoline takes the throw address as an arguments, not a pc offset.
2129 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2130 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2132 #if LLVM_API_VERSION > 100
2134 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2135 * added by emit_jit_callee ().
2137 ex2_bb = gen_bb (ctx, "EX2_BB");
2138 LLVMBuildBr (builder, ex2_bb);
2141 ctx->builder = builder = create_builder (ctx);
2142 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2144 mono_memory_barrier ();
2145 ctx->module->throw_corlib_exception = callee;
2150 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2153 * The LLVM mono branch contains changes so a block address can be passed as an
2154 * argument to a call.
2157 emit_call (ctx, bb, &builder, callee, args, 1);
2159 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2160 emit_call (ctx, bb, &builder, callee, args, 2);
2163 LLVMBuildUnreachable (builder);
2165 ctx->builder = builder = create_builder (ctx);
2166 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2168 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2175 * emit_args_to_vtype:
2177 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2180 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2182 int j, size, nslots;
2184 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2186 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2187 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2190 if (ainfo->storage == LLVMArgAsFpArgs)
2191 nslots = ainfo->nslots;
2195 for (j = 0; j < nslots; ++j) {
2196 LLVMValueRef index [2], addr, daddr;
2197 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2198 LLVMTypeRef part_type;
2200 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2203 if (ainfo->pair_storage [j] == LLVMArgNone)
2206 switch (ainfo->pair_storage [j]) {
2207 case LLVMArgInIReg: {
2208 part_type = LLVMIntType (part_size * 8);
2209 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2210 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2211 addr = LLVMBuildGEP (builder, address, index, 1, "");
2213 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2214 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2215 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2217 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2220 case LLVMArgInFPReg: {
2221 LLVMTypeRef arg_type;
2223 if (ainfo->esize == 8)
2224 arg_type = LLVMDoubleType ();
2226 arg_type = LLVMFloatType ();
2228 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2229 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2230 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2231 LLVMBuildStore (builder, args [j], addr);
2237 g_assert_not_reached ();
2240 size -= sizeof (gpointer);
2245 * emit_vtype_to_args:
2247 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2248 * into ARGS, and the number of arguments into NARGS.
2251 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2254 int j, size, nslots;
2255 LLVMTypeRef arg_type;
2257 size = get_vtype_size (t);
2259 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2260 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2262 if (ainfo->storage == LLVMArgAsFpArgs)
2263 nslots = ainfo->nslots;
2266 for (j = 0; j < nslots; ++j) {
2267 LLVMValueRef index [2], addr, daddr;
2268 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2270 if (ainfo->pair_storage [j] == LLVMArgNone)
2273 switch (ainfo->pair_storage [j]) {
2275 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2276 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2277 addr = LLVMBuildGEP (builder, address, index, 1, "");
2279 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2280 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2281 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2283 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2285 case LLVMArgInFPReg:
2286 if (ainfo->esize == 8)
2287 arg_type = LLVMDoubleType ();
2289 arg_type = LLVMFloatType ();
2290 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2291 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2292 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2293 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2298 g_assert_not_reached ();
2300 size -= sizeof (gpointer);
2307 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2310 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2311 * get executed every time control reaches them.
2313 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2315 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2316 return ctx->last_alloca;
2320 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2322 return build_alloca_llvm_type_name (ctx, t, align, "");
2326 build_alloca (EmitContext *ctx, MonoType *t)
2328 MonoClass *k = mono_class_from_mono_type (t);
2331 g_assert (!mini_is_gsharedvt_variable_type (t));
2333 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2336 align = mono_class_min_align (k);
2338 /* Sometimes align is not a power of 2 */
2339 while (mono_is_power_of_two (align) == -1)
2342 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2346 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2350 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2352 MonoCompile *cfg = ctx->cfg;
2353 LLVMBuilderRef builder = ctx->builder;
2354 LLVMValueRef offset, offset_var;
2355 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2356 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2360 g_assert (info_var);
2361 g_assert (locals_var);
2363 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2365 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2366 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2368 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2369 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2371 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2375 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2378 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2381 module->used = g_ptr_array_sized_new (16);
2382 g_ptr_array_add (module->used, global);
2386 emit_llvm_used (MonoLLVMModule *module)
2388 LLVMModuleRef lmodule = module->lmodule;
2389 LLVMTypeRef used_type;
2390 LLVMValueRef used, *used_elem;
2396 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2397 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2398 used_elem = g_new0 (LLVMValueRef, module->used->len);
2399 for (i = 0; i < module->used->len; ++i)
2400 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2401 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2402 LLVMSetLinkage (used, LLVMAppendingLinkage);
2403 LLVMSetSection (used, "llvm.metadata");
2409 * Emit a function mapping method indexes to their code
2412 emit_get_method (MonoLLVMModule *module)
2414 LLVMModuleRef lmodule = module->lmodule;
2415 LLVMValueRef func, switch_ins, m;
2416 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2417 LLVMBasicBlockRef *bbs;
2419 LLVMBuilderRef builder = LLVMCreateBuilder ();
2424 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2425 * but generating code seems safer.
2427 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2428 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2429 LLVMSetLinkage (func, LLVMExternalLinkage);
2430 LLVMSetVisibility (func, LLVMHiddenVisibility);
2431 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2432 module->get_method = func;
2434 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2437 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2438 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2439 * then we will have to find another solution.
2442 name = g_strdup_printf ("BB_CODE_START");
2443 code_start_bb = LLVMAppendBasicBlock (func, name);
2445 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2446 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2448 name = g_strdup_printf ("BB_CODE_END");
2449 code_end_bb = LLVMAppendBasicBlock (func, name);
2451 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2452 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2454 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2455 for (i = 0; i < module->max_method_idx + 1; ++i) {
2456 name = g_strdup_printf ("BB_%d", i);
2457 bb = LLVMAppendBasicBlock (func, name);
2461 LLVMPositionBuilderAtEnd (builder, bb);
2463 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2465 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2467 LLVMBuildRet (builder, LLVMConstNull (rtype));
2470 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2471 LLVMPositionBuilderAtEnd (builder, fail_bb);
2472 LLVMBuildRet (builder, LLVMConstNull (rtype));
2474 LLVMPositionBuilderAtEnd (builder, entry_bb);
2476 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2477 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2478 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2479 for (i = 0; i < module->max_method_idx + 1; ++i) {
2480 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2483 mark_as_used (module, func);
2485 LLVMDisposeBuilder (builder);
2489 * emit_get_unbox_tramp:
2491 * Emit a function mapping method indexes to their unbox trampoline
2494 emit_get_unbox_tramp (MonoLLVMModule *module)
2496 LLVMModuleRef lmodule = module->lmodule;
2497 LLVMValueRef func, switch_ins, m;
2498 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2499 LLVMBasicBlockRef *bbs;
2501 LLVMBuilderRef builder = LLVMCreateBuilder ();
2505 /* Similar to emit_get_method () */
2507 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2508 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2509 LLVMSetLinkage (func, LLVMExternalLinkage);
2510 LLVMSetVisibility (func, LLVMHiddenVisibility);
2511 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2512 module->get_unbox_tramp = func;
2514 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2516 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2517 for (i = 0; i < module->max_method_idx + 1; ++i) {
2518 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2522 name = g_strdup_printf ("BB_%d", i);
2523 bb = LLVMAppendBasicBlock (func, name);
2527 LLVMPositionBuilderAtEnd (builder, bb);
2529 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2532 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2533 LLVMPositionBuilderAtEnd (builder, fail_bb);
2534 LLVMBuildRet (builder, LLVMConstNull (rtype));
2536 LLVMPositionBuilderAtEnd (builder, entry_bb);
2538 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2539 for (i = 0; i < module->max_method_idx + 1; ++i) {
2540 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2544 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2547 mark_as_used (module, func);
2548 LLVMDisposeBuilder (builder);
2551 /* Add a function to mark the beginning of LLVM code */
2553 emit_llvm_code_start (MonoLLVMModule *module)
2555 LLVMModuleRef lmodule = module->lmodule;
2557 LLVMBasicBlockRef entry_bb;
2558 LLVMBuilderRef builder;
2560 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2561 LLVMSetLinkage (func, LLVMInternalLinkage);
2562 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2563 module->code_start = func;
2564 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2565 builder = LLVMCreateBuilder ();
2566 LLVMPositionBuilderAtEnd (builder, entry_bb);
2567 LLVMBuildRetVoid (builder);
2568 LLVMDisposeBuilder (builder);
2572 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2574 LLVMModuleRef lmodule = module->lmodule;
2575 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2576 LLVMBasicBlockRef entry_bb;
2577 LLVMBuilderRef builder;
2584 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2585 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2590 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2591 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2594 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2595 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2598 g_assert_not_reached ();
2600 LLVMSetLinkage (func, LLVMInternalLinkage);
2601 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2602 mono_llvm_set_preserveall_cc (func);
2603 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2604 builder = LLVMCreateBuilder ();
2605 LLVMPositionBuilderAtEnd (builder, entry_bb);
2608 ji = g_new0 (MonoJumpInfo, 1);
2609 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2610 ji = mono_aot_patch_info_dup (ji);
2611 got_offset = mono_aot_get_got_offset (ji);
2612 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2613 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2614 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2615 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2616 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2617 args [1] = LLVMGetParam (func, 0);
2619 args [2] = LLVMGetParam (func, 1);
2621 ji = g_new0 (MonoJumpInfo, 1);
2622 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2623 ji->data.name = icall_name;
2624 ji = mono_aot_patch_info_dup (ji);
2625 got_offset = mono_aot_get_got_offset (ji);
2626 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2627 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2628 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2629 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2630 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2631 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2632 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2634 // Set the inited flag
2635 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2636 indexes [1] = LLVMGetParam (func, 0);
2637 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2639 LLVMBuildRetVoid (builder);
2641 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2642 LLVMDisposeBuilder (builder);
2647 * Emit wrappers around the C icalls used to initialize llvm methods, to
2648 * make the calling code smaller and to enable usage of the llvm
2649 * PreserveAll calling convention.
2652 emit_init_icall_wrappers (MonoLLVMModule *module)
2654 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2655 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2656 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2657 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2661 emit_llvm_code_end (MonoLLVMModule *module)
2663 LLVMModuleRef lmodule = module->lmodule;
2665 LLVMBasicBlockRef entry_bb;
2666 LLVMBuilderRef builder;
2668 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2669 LLVMSetLinkage (func, LLVMInternalLinkage);
2670 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2671 module->code_end = func;
2672 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2673 builder = LLVMCreateBuilder ();
2674 LLVMPositionBuilderAtEnd (builder, entry_bb);
2675 LLVMBuildRetVoid (builder);
2676 LLVMDisposeBuilder (builder);
2680 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2682 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2685 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2686 need_div_check = TRUE;
2688 if (!need_div_check)
2691 switch (ins->opcode) {
2704 case OP_IDIV_UN_IMM:
2705 case OP_LDIV_UN_IMM:
2706 case OP_IREM_UN_IMM:
2707 case OP_LREM_UN_IMM: {
2709 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2710 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2712 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2713 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2716 builder = ctx->builder;
2718 /* b == -1 && a == 0x80000000 */
2720 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2721 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2722 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2724 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2725 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2728 builder = ctx->builder;
2740 * Emit code to initialize the GOT slots used by the method.
2743 emit_init_method (EmitContext *ctx)
2745 LLVMValueRef indexes [16], args [16], callee;
2746 LLVMValueRef inited_var, cmp, call;
2747 LLVMBasicBlockRef inited_bb, notinited_bb;
2748 LLVMBuilderRef builder = ctx->builder;
2749 MonoCompile *cfg = ctx->cfg;
2751 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2753 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2754 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2755 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2757 args [0] = inited_var;
2758 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2759 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2761 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2763 inited_bb = ctx->inited_bb;
2764 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2766 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2768 builder = ctx->builder = create_builder (ctx);
2769 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2772 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2773 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2774 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2775 callee = ctx->module->init_method_gshared_mrgctx;
2776 call = LLVMBuildCall (builder, callee, args, 2, "");
2777 } else if (ctx->rgctx_arg) {
2778 /* A vtable is passed as the rgctx argument */
2779 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2780 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2781 callee = ctx->module->init_method_gshared_vtable;
2782 call = LLVMBuildCall (builder, callee, args, 2, "");
2783 } else if (cfg->gshared) {
2784 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2785 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2786 callee = ctx->module->init_method_gshared_this;
2787 call = LLVMBuildCall (builder, callee, args, 2, "");
2789 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2790 callee = ctx->module->init_method;
2791 call = LLVMBuildCall (builder, callee, args, 1, "");
2795 * This enables llvm to keep arguments in their original registers/
2796 * scratch registers, since the call will not clobber them.
2798 mono_llvm_set_call_preserveall_cc (call);
2800 LLVMBuildBr (builder, inited_bb);
2801 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2803 builder = ctx->builder = create_builder (ctx);
2804 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2808 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2811 * Emit unbox trampoline using a tail call
2813 LLVMValueRef tramp, call, *args;
2814 LLVMBuilderRef builder;
2815 LLVMBasicBlockRef lbb;
2816 LLVMCallInfo *linfo;
2820 tramp_name = g_strdup_printf ("ut_%s", method_name);
2821 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2822 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2823 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2824 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2826 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2827 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2828 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2829 if (ctx->cfg->vret_addr) {
2830 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2831 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2832 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2833 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2837 lbb = LLVMAppendBasicBlock (tramp, "");
2838 builder = LLVMCreateBuilder ();
2839 LLVMPositionBuilderAtEnd (builder, lbb);
2841 nargs = LLVMCountParamTypes (method_type);
2842 args = g_new0 (LLVMValueRef, nargs);
2843 for (i = 0; i < nargs; ++i) {
2844 args [i] = LLVMGetParam (tramp, i);
2845 if (i == ctx->this_arg_pindex) {
2846 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2848 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2849 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2850 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2853 call = LLVMBuildCall (builder, method, args, nargs, "");
2854 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2855 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2856 if (linfo->ret.storage == LLVMArgVtypeByRef)
2857 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2859 // FIXME: This causes assertions in clang
2860 //mono_llvm_set_must_tail (call);
2861 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2862 LLVMBuildRetVoid (builder);
2864 LLVMBuildRet (builder, call);
2866 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2867 LLVMDisposeBuilder (builder);
2873 * Emit code to load/convert arguments.
2876 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2879 MonoCompile *cfg = ctx->cfg;
2880 MonoMethodSignature *sig = ctx->sig;
2881 LLVMCallInfo *linfo = ctx->linfo;
2885 LLVMBuilderRef old_builder = ctx->builder;
2886 ctx->builder = builder;
2888 ctx->alloca_builder = create_builder (ctx);
2891 * Handle indirect/volatile variables by allocating memory for them
2892 * using 'alloca', and storing their address in a temporary.
2894 for (i = 0; i < cfg->num_varinfo; ++i) {
2895 MonoInst *var = cfg->varinfo [i];
2898 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2899 } 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))) {
2900 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2903 /* Could be already created by an OP_VPHI */
2904 if (!ctx->addresses [var->dreg]) {
2905 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2906 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2908 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2912 names = g_new (char *, sig->param_count);
2913 mono_method_get_param_names (cfg->method, (const char **) names);
2915 for (i = 0; i < sig->param_count; ++i) {
2916 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2917 int reg = cfg->args [i + sig->hasthis]->dreg;
2920 pindex = ainfo->pindex;
2922 switch (ainfo->storage) {
2923 case LLVMArgVtypeInReg:
2924 case LLVMArgAsFpArgs: {
2925 LLVMValueRef args [8];
2928 pindex += ainfo->ndummy_fpargs;
2930 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2931 memset (args, 0, sizeof (args));
2932 if (ainfo->storage == LLVMArgVtypeInReg) {
2933 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2934 if (ainfo->pair_storage [1] != LLVMArgNone)
2935 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2937 g_assert (ainfo->nslots <= 8);
2938 for (j = 0; j < ainfo->nslots; ++j)
2939 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2941 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2943 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2945 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2946 /* Treat these as normal values */
2947 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2951 case LLVMArgVtypeByVal: {
2952 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2954 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2955 /* Treat these as normal values */
2956 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2960 case LLVMArgVtypeByRef: {
2961 /* The argument is passed by ref */
2962 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2965 case LLVMArgAsIArgs: {
2966 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2969 /* The argument is received as an array of ints, store it into the real argument */
2970 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2972 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2973 if (size < SIZEOF_VOID_P) {
2974 /* The upper bits of the registers might not be valid */
2975 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2976 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2977 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2979 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2983 case LLVMArgVtypeAsScalar:
2984 g_assert_not_reached ();
2986 case LLVMArgGsharedvtFixed: {
2987 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2988 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2991 name = g_strdup_printf ("arg_%s", names [i]);
2993 name = g_strdup_printf ("arg_%d", i);
2995 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2998 case LLVMArgGsharedvtFixedVtype: {
2999 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3002 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3004 name = g_strdup_printf ("vtype_arg_%d", i);
3006 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3007 g_assert (ctx->addresses [reg]);
3008 LLVMSetValueName (ctx->addresses [reg], name);
3009 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3012 case LLVMArgGsharedvtVariable:
3013 /* The IR treats these as variables with addresses */
3014 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3017 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));
3024 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3026 emit_volatile_store (ctx, cfg->args [0]->dreg);
3027 for (i = 0; i < sig->param_count; ++i)
3028 if (!mini_type_is_vtype (sig->params [i]))
3029 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3031 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3032 LLVMValueRef this_alloc;
3035 * The exception handling code needs the location where the this argument was
3036 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3037 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3038 * location into the LSDA.
3040 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3041 /* This volatile store will keep the alloca alive */
3042 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3044 set_metadata_flag (this_alloc, "mono.this");
3047 if (cfg->rgctx_var) {
3048 LLVMValueRef rgctx_alloc, store;
3051 * We handle the rgctx arg similarly to the this pointer.
3053 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3054 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3055 /* This volatile store will keep the alloca alive */
3056 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3058 set_metadata_flag (rgctx_alloc, "mono.this");
3061 /* Initialize the method if needed */
3062 if (cfg->compile_aot && ctx->llvm_only) {
3063 /* Emit a location for the initialization code */
3064 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3065 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3067 LLVMBuildBr (ctx->builder, ctx->init_bb);
3068 builder = ctx->builder = create_builder (ctx);
3069 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3070 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3073 /* Compute nesting between clauses */
3074 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3075 for (i = 0; i < cfg->header->num_clauses; ++i) {
3076 for (j = 0; j < cfg->header->num_clauses; ++j) {
3077 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3078 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3080 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3081 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3086 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3087 * it needs to continue normally, or return back to the exception handling system.
3089 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3093 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3096 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3097 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3098 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3100 if (bb->in_scount == 0) {
3103 sprintf (name, "finally_ind_bb%d", bb->block_num);
3104 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3105 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3107 ctx->bblocks [bb->block_num].finally_ind = val;
3109 /* Create a variable to hold the exception var */
3111 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3115 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3116 * LLVM bblock containing a landing pad causes problems for the
3117 * LLVM optimizer passes.
3119 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3120 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3122 ctx->builder = old_builder;
3126 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3128 MonoCompile *cfg = ctx->cfg;
3129 LLVMValueRef *values = ctx->values;
3130 LLVMValueRef *addresses = ctx->addresses;
3131 MonoCallInst *call = (MonoCallInst*)ins;
3132 MonoMethodSignature *sig = call->signature;
3133 LLVMValueRef callee = NULL, lcall;
3135 LLVMCallInfo *cinfo;
3139 LLVMTypeRef llvm_sig;
3141 gboolean is_virtual, calli, preserveall;
3142 LLVMBuilderRef builder = *builder_ref;
3144 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3145 set_failure (ctx, "non-default callconv");
3149 cinfo = call->cinfo;
3151 if (call->rgctx_arg_reg)
3152 cinfo->rgctx_arg = TRUE;
3153 if (call->imt_arg_reg)
3154 cinfo->imt_arg = TRUE;
3156 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3158 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3162 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);
3163 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);
3165 preserveall = FALSE;
3167 /* FIXME: Avoid creating duplicate methods */
3169 if (ins->flags & MONO_INST_HAS_METHOD) {
3173 if (cfg->compile_aot) {
3174 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3176 set_failure (ctx, "can't encode patch");
3179 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3181 * Collect instructions representing the callee into a hash so they can be replaced
3182 * by the llvm method for the callee if the callee turns out to be direct
3183 * callable. Currently this only requires it to not fail llvm compilation.
3185 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3186 l = g_slist_prepend (l, callee);
3187 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3191 static int tramp_index;
3194 name = g_strdup_printf ("tramp_%d", tramp_index);
3197 #if LLVM_API_VERSION > 100
3199 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3200 * Make all calls through a global. The address of the global will be saved in
3201 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3204 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3207 mono_create_jit_trampoline (mono_domain_get (),
3208 call->method, &error);
3209 if (!is_ok (&error)) {
3210 set_failure (ctx, mono_error_get_message (&error));
3211 mono_error_cleanup (&error);
3215 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3216 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3217 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3218 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3220 callee = LLVMBuildLoad (builder, tramp_var, "");
3223 mono_create_jit_trampoline (mono_domain_get (),
3224 call->method, &error);
3225 if (!is_ok (&error)) {
3227 set_failure (ctx, mono_error_get_message (&error));
3228 mono_error_cleanup (&error);
3232 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3235 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3240 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3241 /* LLVM miscompiles async methods */
3242 set_failure (ctx, "#13734");
3247 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3253 memset (&ji, 0, sizeof (ji));
3254 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3255 ji.data.target = info->name;
3257 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3259 if (cfg->compile_aot) {
3260 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3262 set_failure (ctx, "can't encode patch");
3266 target = (gpointer)mono_icall_get_wrapper (info);
3267 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3270 if (cfg->compile_aot) {
3272 if (cfg->abs_patches) {
3273 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3275 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3277 set_failure (ctx, "can't encode patch");
3283 set_failure (ctx, "aot");
3287 #if LLVM_API_VERSION > 100
3288 if (cfg->abs_patches) {
3289 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3293 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3294 mono_error_assert_ok (&error);
3295 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3297 g_assert_not_reached ();
3300 g_assert_not_reached ();
3303 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3305 if (cfg->abs_patches) {
3306 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3311 * FIXME: Some trampolines might have
3312 * their own calling convention on some platforms.
3314 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3315 mono_error_assert_ok (&error);
3316 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3320 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3327 int size = sizeof (gpointer);
3330 g_assert (ins->inst_offset % size == 0);
3331 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3333 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3335 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3337 if (ins->flags & MONO_INST_HAS_METHOD) {
3342 * Collect and convert arguments
3344 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3345 len = sizeof (LLVMValueRef) * nargs;
3346 args = (LLVMValueRef*)alloca (len);
3347 memset (args, 0, len);
3348 l = call->out_ireg_args;
3350 if (call->rgctx_arg_reg) {
3351 g_assert (values [call->rgctx_arg_reg]);
3352 g_assert (cinfo->rgctx_arg_pindex < nargs);
3354 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3355 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3356 * it using a volatile load.
3359 if (!ctx->imt_rgctx_loc)
3360 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3361 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3362 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3364 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3367 if (call->imt_arg_reg) {
3368 g_assert (!ctx->llvm_only);
3369 g_assert (values [call->imt_arg_reg]);
3370 g_assert (cinfo->imt_arg_pindex < nargs);
3372 if (!ctx->imt_rgctx_loc)
3373 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3374 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3375 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3377 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3380 switch (cinfo->ret.storage) {
3381 case LLVMArgGsharedvtVariable: {
3382 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3384 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3385 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3387 g_assert (addresses [call->inst.dreg]);
3388 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3394 if (!addresses [call->inst.dreg])
3395 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3396 g_assert (cinfo->vret_arg_pindex < nargs);
3397 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3398 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3400 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3406 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3407 * use the real callee for argument type conversion.
3409 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3410 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3411 LLVMGetParamTypes (callee_type, param_types);
3413 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3416 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3418 pindex = ainfo->pindex;
3420 regpair = (guint32)(gssize)(l->data);
3421 reg = regpair & 0xffffff;
3422 args [pindex] = values [reg];
3423 switch (ainfo->storage) {
3424 case LLVMArgVtypeInReg:
3425 case LLVMArgAsFpArgs: {
3429 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3430 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3431 pindex += ainfo->ndummy_fpargs;
3433 g_assert (addresses [reg]);
3434 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3438 // FIXME: Get rid of the VMOVE
3441 case LLVMArgVtypeByVal:
3442 g_assert (addresses [reg]);
3443 args [pindex] = addresses [reg];
3445 case LLVMArgVtypeByRef: {
3446 g_assert (addresses [reg]);
3447 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3450 case LLVMArgAsIArgs:
3451 g_assert (addresses [reg]);
3452 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3454 case LLVMArgVtypeAsScalar:
3455 g_assert_not_reached ();
3457 case LLVMArgGsharedvtFixed:
3458 case LLVMArgGsharedvtFixedVtype:
3459 g_assert (addresses [reg]);
3460 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3462 case LLVMArgGsharedvtVariable:
3463 g_assert (addresses [reg]);
3464 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3467 g_assert (args [pindex]);
3468 if (i == 0 && sig->hasthis)
3469 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3471 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3474 g_assert (pindex <= nargs);
3479 // FIXME: Align call sites
3485 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3488 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3490 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3491 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3493 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3494 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3495 if (!sig->pinvoke && !cfg->llvm_only)
3496 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3498 mono_llvm_set_call_preserveall_cc (lcall);
3500 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3501 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3502 if (!ctx->llvm_only && call->rgctx_arg_reg)
3503 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3504 if (call->imt_arg_reg)
3505 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3507 /* Add byval attributes if needed */
3508 for (i = 0; i < sig->param_count; ++i) {
3509 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3511 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3512 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3516 * Convert the result
3518 switch (cinfo->ret.storage) {
3519 case LLVMArgVtypeInReg: {
3520 LLVMValueRef regs [2];
3522 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3526 if (!addresses [ins->dreg])
3527 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3529 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3530 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3531 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3532 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3535 case LLVMArgVtypeByVal:
3536 if (!addresses [call->inst.dreg])
3537 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3538 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3540 case LLVMArgAsIArgs:
3541 case LLVMArgFpStruct:
3542 if (!addresses [call->inst.dreg])
3543 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3544 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3546 case LLVMArgVtypeAsScalar:
3547 if (!addresses [call->inst.dreg])
3548 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3549 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3551 case LLVMArgVtypeRetAddr:
3552 case LLVMArgVtypeByRef:
3553 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3554 /* Some opcodes like STOREX_MEMBASE access these by value */
3555 g_assert (addresses [call->inst.dreg]);
3556 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3559 case LLVMArgGsharedvtVariable:
3561 case LLVMArgGsharedvtFixed:
3562 case LLVMArgGsharedvtFixedVtype:
3563 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3566 if (sig->ret->type != MONO_TYPE_VOID)
3567 /* If the method returns an unsigned value, need to zext it */
3568 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));
3572 *builder_ref = ctx->builder;
3576 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3578 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3579 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3581 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3584 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3586 if (ctx->cfg->compile_aot) {
3587 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3589 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3590 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3591 mono_memory_barrier ();
3594 ctx->module->rethrow = callee;
3596 ctx->module->throw_icall = callee;
3600 LLVMValueRef args [2];
3602 args [0] = convert (ctx, exc, exc_type);
3603 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3605 LLVMBuildUnreachable (ctx->builder);
3607 ctx->builder = create_builder (ctx);
3611 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3613 MonoMethodSignature *throw_sig;
3614 LLVMValueRef callee, arg;
3615 const char *icall_name;
3617 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3618 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3621 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3622 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3623 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3624 if (ctx->cfg->compile_aot) {
3625 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3630 * LLVM doesn't push the exception argument, so we need a different
3633 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3635 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3637 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3640 mono_memory_barrier ();
3641 #if LLVM_API_VERSION < 100
3643 ctx->module->rethrow = callee;
3645 ctx->module->throw_icall = callee;
3648 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3649 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3653 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3655 const char *icall_name = "mono_llvm_resume_exception";
3656 LLVMValueRef callee = ctx->module->resume_eh;
3658 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3661 if (ctx->cfg->compile_aot) {
3662 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3664 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3665 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3666 mono_memory_barrier ();
3668 ctx->module->resume_eh = callee;
3672 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3674 LLVMBuildUnreachable (ctx->builder);
3676 ctx->builder = create_builder (ctx);
3680 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3682 const char *icall_name = "mono_llvm_clear_exception";
3684 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3685 LLVMValueRef callee = NULL;
3688 if (ctx->cfg->compile_aot) {
3689 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3691 // FIXME: This is broken.
3692 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3696 g_assert (builder && callee);
3698 return LLVMBuildCall (builder, callee, NULL, 0, "");
3702 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3704 const char *icall_name = "mono_llvm_load_exception";
3706 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3707 LLVMValueRef callee = NULL;
3710 if (ctx->cfg->compile_aot) {
3711 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3713 // FIXME: This is broken.
3714 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3718 g_assert (builder && callee);
3720 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3725 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3727 const char *icall_name = "mono_llvm_match_exception";
3729 ctx->builder = builder;
3731 const int num_args = 5;
3732 LLVMValueRef args [num_args];
3733 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3734 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3735 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3736 if (ctx->cfg->rgctx_var) {
3737 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3738 g_assert (rgctx_alloc);
3739 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3741 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3744 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3746 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3748 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3749 LLVMValueRef callee = ctx->module->match_exc;
3752 if (ctx->cfg->compile_aot) {
3753 ctx->builder = builder;
3754 // get_callee expects ctx->builder to be the emitting builder
3755 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3757 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3758 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3759 ctx->module->match_exc = callee;
3760 mono_memory_barrier ();
3764 g_assert (builder && callee);
3766 g_assert (ctx->ex_var);
3768 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3771 // FIXME: This won't work because the code-finding makes this
3773 /*#define MONO_PERSONALITY_DEBUG*/
3775 #ifdef MONO_PERSONALITY_DEBUG
3776 static const gboolean use_debug_personality = TRUE;
3777 static const char *default_personality_name = "mono_debug_personality";
3779 static const gboolean use_debug_personality = FALSE;
3780 static const char *default_personality_name = "__gxx_personality_v0";
3784 default_cpp_lpad_exc_signature (void)
3786 static gboolean inited = FALSE;
3787 static LLVMTypeRef sig;
3790 LLVMTypeRef signature [2];
3791 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3792 signature [1] = LLVMInt32Type ();
3793 sig = LLVMStructType (signature, 2, FALSE);
3801 get_mono_personality (EmitContext *ctx)
3803 LLVMValueRef personality = NULL;
3804 static gint32 mapping_inited = FALSE;
3805 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3807 if (!use_debug_personality) {
3808 if (ctx->cfg->compile_aot) {
3809 personality = get_intrinsic (ctx, default_personality_name);
3810 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3811 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3812 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3815 if (ctx->cfg->compile_aot) {
3816 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3818 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3819 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3820 mono_memory_barrier ();
3824 g_assert (personality);
3828 static LLVMBasicBlockRef
3829 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3831 MonoCompile *cfg = ctx->cfg;
3832 LLVMBuilderRef old_builder = ctx->builder;
3833 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3835 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3836 ctx->builder = lpadBuilder;
3838 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3839 g_assert (handler_bb);
3841 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3842 LLVMValueRef personality = get_mono_personality (ctx);
3843 g_assert (personality);
3845 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3846 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3848 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3849 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3850 g_assert (landing_pad);
3852 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3853 LLVMAddClause (landing_pad, cast);
3855 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3856 LLVMBuilderRef resume_builder = create_builder (ctx);
3857 ctx->builder = resume_builder;
3858 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3860 emit_resume_eh (ctx, handler_bb);
3863 ctx->builder = lpadBuilder;
3864 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3866 gboolean finally_only = TRUE;
3868 MonoExceptionClause *group_cursor = group_start;
3870 for (int i = 0; i < group_size; i ++) {
3871 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3872 finally_only = FALSE;
3878 // Handle landing pad inlining
3880 if (!finally_only) {
3881 // So at each level of the exception stack we will match the exception again.
3882 // During that match, we need to compare against the handler types for the current
3883 // protected region. We send the try start and end so that we can only check against
3884 // handlers for this lexical protected region.
3885 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3887 // if returns -1, resume
3888 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3890 // else move to that target bb
3891 for (int i=0; i < group_size; i++) {
3892 MonoExceptionClause *clause = group_start + i;
3893 int clause_index = clause - cfg->header->clauses;
3894 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3895 g_assert (handler_bb);
3896 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3897 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3900 int clause_index = group_start - cfg->header->clauses;
3901 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3902 g_assert (finally_bb);
3904 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3907 ctx->builder = old_builder;
3914 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3916 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3917 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3919 // Make exception available to catch blocks
3920 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3921 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3923 g_assert (ctx->ex_var);
3924 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3926 if (bb->in_scount == 1) {
3927 MonoInst *exvar = bb->in_stack [0];
3928 g_assert (!ctx->values [exvar->dreg]);
3929 g_assert (ctx->ex_var);
3930 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3931 emit_volatile_store (ctx, exvar->dreg);
3934 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3937 LLVMBuilderRef handler_builder = create_builder (ctx);
3938 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3939 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3941 // Make the handler code end with a jump to cbb
3942 LLVMBuildBr (handler_builder, cbb);
3946 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3948 MonoCompile *cfg = ctx->cfg;
3949 LLVMValueRef *values = ctx->values;
3950 LLVMModuleRef lmodule = ctx->lmodule;
3951 BBInfo *bblocks = ctx->bblocks;
3953 LLVMValueRef personality;
3954 LLVMValueRef landing_pad;
3955 LLVMBasicBlockRef target_bb;
3957 static int ti_generator;
3959 LLVMValueRef type_info;
3963 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3965 if (cfg->compile_aot) {
3966 /* Use a dummy personality function */
3967 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3968 g_assert (personality);
3970 #if LLVM_API_VERSION > 100
3971 personality = ctx->module->personality;
3973 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3974 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3975 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3976 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3977 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3978 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3979 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3980 ctx->module->personality = personality;
3981 LLVMDisposeBuilder (builder2);
3984 static gint32 mapping_inited;
3986 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3988 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3989 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3993 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3995 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3998 * Create the type info
4000 sprintf (ti_name, "type_info_%d", ti_generator);
4003 if (cfg->compile_aot) {
4004 /* decode_eh_frame () in aot-runtime.c will decode this */
4005 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4006 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4009 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4011 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4013 #if LLVM_API_VERSION > 100
4014 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4015 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4020 * After the cfg mempool is freed, the type info will point to stale memory,
4021 * but this is not a problem, since we decode it once in exception_cb during
4024 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4025 *(gint32*)ti = clause_index;
4027 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4029 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4034 LLVMTypeRef members [2], ret_type;
4036 members [0] = i8ptr;
4037 members [1] = LLVMInt32Type ();
4038 ret_type = LLVMStructType (members, 2, FALSE);
4040 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4041 LLVMAddClause (landing_pad, type_info);
4043 /* Store the exception into the exvar */
4045 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4049 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4050 * code expects control to be transferred to this landing pad even in the
4051 * presence of nested clauses. The landing pad needs to branch to the landing
4052 * pads belonging to nested clauses based on the selector value returned by
4053 * the landing pad instruction, which is passed to the landing pad in a
4054 * register by the EH code.
4056 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4057 g_assert (target_bb);
4060 * Branch to the correct landing pad
4062 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4063 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4065 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4066 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4067 MonoBasicBlock *handler_bb;
4069 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4070 g_assert (handler_bb);
4072 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4073 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4076 /* Start a new bblock which CALL_HANDLER can branch to */
4077 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4079 ctx->builder = builder = create_builder (ctx);
4080 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4082 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4084 /* Store the exception into the IL level exvar */
4085 if (bb->in_scount == 1) {
4086 g_assert (bb->in_scount == 1);
4087 exvar = bb->in_stack [0];
4089 // FIXME: This is shared with filter clauses ?
4090 g_assert (!values [exvar->dreg]);
4092 g_assert (ctx->ex_var);
4093 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4094 emit_volatile_store (ctx, exvar->dreg);
4100 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4102 MonoCompile *cfg = ctx->cfg;
4103 MonoMethodSignature *sig = ctx->sig;
4104 LLVMValueRef method = ctx->lmethod;
4105 LLVMValueRef *values = ctx->values;
4106 LLVMValueRef *addresses = ctx->addresses;
4107 LLVMCallInfo *linfo = ctx->linfo;
4108 BBInfo *bblocks = ctx->bblocks;
4110 LLVMBasicBlockRef cbb;
4111 LLVMBuilderRef builder, starting_builder;
4112 gboolean has_terminator;
4114 LLVMValueRef lhs, rhs;
4117 cbb = get_end_bb (ctx, bb);
4119 builder = create_builder (ctx);
4120 ctx->builder = builder;
4121 LLVMPositionBuilderAtEnd (builder, cbb);
4126 if (bb->flags & BB_EXCEPTION_HANDLER) {
4127 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4128 set_failure (ctx, "handler without invokes");
4133 emit_llvmonly_handler_start (ctx, bb, cbb);
4135 emit_handler_start (ctx, bb, builder);
4138 builder = ctx->builder;
4141 has_terminator = FALSE;
4142 starting_builder = builder;
4143 for (ins = bb->code; ins; ins = ins->next) {
4144 const char *spec = LLVM_INS_INFO (ins->opcode);
4146 char dname_buf [128];
4148 emit_dbg_loc (ctx, builder, ins->cil_code);
4153 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4154 * Start a new bblock.
4155 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4156 * from localloc-ed memory.
4158 if (!cfg->llvm_only)
4159 ;//set_failure (ctx, "basic block too long");
4161 if (!ctx->long_bb_break_var) {
4162 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4163 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4166 cbb = gen_bb (ctx, "CONT_LONG_BB");
4167 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4169 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4171 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4172 * but llvm doesn't know that, so the branch is not going to be eliminated.
4174 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4176 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4178 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4179 ctx->builder = builder = create_builder (ctx);
4180 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4181 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4182 LLVMBuildBr (builder, cbb);
4184 ctx->builder = builder = create_builder (ctx);
4185 LLVMPositionBuilderAtEnd (builder, cbb);
4186 ctx->bblocks [bb->block_num].end_bblock = cbb;
4191 /* There could be instructions after a terminator, skip them */
4194 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4195 sprintf (dname_buf, "t%d", ins->dreg);
4199 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4200 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4202 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4203 lhs = emit_volatile_load (ctx, ins->sreg1);
4205 /* It is ok for SETRET to have an uninitialized argument */
4206 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4207 set_failure (ctx, "sreg1");
4210 lhs = values [ins->sreg1];
4216 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4217 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4218 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4219 rhs = emit_volatile_load (ctx, ins->sreg2);
4221 if (!values [ins->sreg2]) {
4222 set_failure (ctx, "sreg2");
4225 rhs = values [ins->sreg2];
4231 //mono_print_ins (ins);
4232 switch (ins->opcode) {
4235 case OP_LIVERANGE_START:
4236 case OP_LIVERANGE_END:
4239 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4242 #if SIZEOF_VOID_P == 4
4243 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4245 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4249 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4253 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4255 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4257 case OP_DUMMY_ICONST:
4258 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4260 case OP_DUMMY_I8CONST:
4261 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4263 case OP_DUMMY_R8CONST:
4264 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4267 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4268 LLVMBuildBr (builder, target_bb);
4269 has_terminator = TRUE;
4276 LLVMBasicBlockRef new_bb;
4277 LLVMBuilderRef new_builder;
4279 // The default branch is already handled
4280 // FIXME: Handle it here
4282 /* Start new bblock */
4283 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4284 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4286 lhs = convert (ctx, lhs, LLVMInt32Type ());
4287 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4288 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4289 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4291 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4294 new_builder = create_builder (ctx);
4295 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4296 LLVMBuildUnreachable (new_builder);
4298 has_terminator = TRUE;
4299 g_assert (!ins->next);
4305 switch (linfo->ret.storage) {
4306 case LLVMArgVtypeInReg: {
4307 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4308 LLVMValueRef val, addr, retval;
4311 retval = LLVMGetUndef (ret_type);
4313 if (!addresses [ins->sreg1]) {
4315 * The return type is an LLVM vector type, have to convert between it and the
4316 * real return type which is a struct type.
4318 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4319 /* Convert to 2xi64 first */
4320 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4322 for (i = 0; i < 2; ++i) {
4323 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4324 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4326 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4330 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4331 for (i = 0; i < 2; ++i) {
4332 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4333 LLVMValueRef indexes [2], part_addr;
4335 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4336 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4337 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4339 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4341 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4345 LLVMBuildRet (builder, retval);
4348 case LLVMArgVtypeAsScalar: {
4349 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4350 LLVMValueRef retval;
4352 g_assert (addresses [ins->sreg1]);
4354 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4355 LLVMBuildRet (builder, retval);
4358 case LLVMArgVtypeByVal: {
4359 LLVMValueRef retval;
4361 g_assert (addresses [ins->sreg1]);
4362 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4363 LLVMBuildRet (builder, retval);
4366 case LLVMArgVtypeByRef: {
4367 LLVMBuildRetVoid (builder);
4370 case LLVMArgGsharedvtFixed: {
4371 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4372 /* The return value is in lhs, need to store to the vret argument */
4373 /* sreg1 might not be set */
4375 g_assert (cfg->vret_addr);
4376 g_assert (values [cfg->vret_addr->dreg]);
4377 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4379 LLVMBuildRetVoid (builder);
4382 case LLVMArgGsharedvtFixedVtype: {
4384 LLVMBuildRetVoid (builder);
4387 case LLVMArgGsharedvtVariable: {
4389 LLVMBuildRetVoid (builder);
4392 case LLVMArgVtypeRetAddr: {
4393 LLVMBuildRetVoid (builder);
4396 case LLVMArgAsIArgs:
4397 case LLVMArgFpStruct: {
4398 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4399 LLVMValueRef retval;
4401 g_assert (addresses [ins->sreg1]);
4402 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4403 LLVMBuildRet (builder, retval);
4407 case LLVMArgNormal: {
4408 if (!lhs || ctx->is_dead [ins->sreg1]) {
4410 * The method did not set its return value, probably because it
4411 * ends with a throw.
4414 LLVMBuildRetVoid (builder);
4416 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4418 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4420 has_terminator = TRUE;
4424 g_assert_not_reached ();
4433 case OP_ICOMPARE_IMM:
4434 case OP_LCOMPARE_IMM:
4435 case OP_COMPARE_IMM: {
4437 LLVMValueRef cmp, args [16];
4438 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4440 if (ins->next->opcode == OP_NOP)
4443 if (ins->next->opcode == OP_BR)
4444 /* The comparison result is not needed */
4447 rel = mono_opcode_to_cond (ins->next->opcode);
4449 if (ins->opcode == OP_ICOMPARE_IMM) {
4450 lhs = convert (ctx, lhs, LLVMInt32Type ());
4451 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4453 if (ins->opcode == OP_LCOMPARE_IMM) {
4454 lhs = convert (ctx, lhs, LLVMInt64Type ());
4455 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4457 if (ins->opcode == OP_LCOMPARE) {
4458 lhs = convert (ctx, lhs, LLVMInt64Type ());
4459 rhs = convert (ctx, rhs, LLVMInt64Type ());
4461 if (ins->opcode == OP_ICOMPARE) {
4462 lhs = convert (ctx, lhs, LLVMInt32Type ());
4463 rhs = convert (ctx, rhs, LLVMInt32Type ());
4467 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4468 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4469 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4470 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4473 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4474 if (ins->opcode == OP_FCOMPARE) {
4475 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4476 } else if (ins->opcode == OP_RCOMPARE) {
4477 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4478 } else if (ins->opcode == OP_COMPARE_IMM) {
4479 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4480 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4482 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4483 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4484 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4485 /* The immediate is encoded in two fields */
4486 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4487 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4489 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4492 else if (ins->opcode == OP_COMPARE) {
4493 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4494 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4496 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4498 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4502 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4503 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4506 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4507 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4509 * If the target bb contains PHI instructions, LLVM requires
4510 * two PHI entries for this bblock, while we only generate one.
4511 * So convert this to an unconditional bblock. (bxc #171).
4513 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4515 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4517 has_terminator = TRUE;
4518 } else if (MONO_IS_SETCC (ins->next)) {
4519 sprintf (dname_buf, "t%d", ins->next->dreg);
4521 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4523 /* Add stores for volatile variables */
4524 emit_volatile_store (ctx, ins->next->dreg);
4525 } else if (MONO_IS_COND_EXC (ins->next)) {
4526 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4529 builder = ctx->builder;
4531 set_failure (ctx, "next");
4549 rel = mono_opcode_to_cond (ins->opcode);
4551 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4552 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4563 rel = mono_opcode_to_cond (ins->opcode);
4565 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4566 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4574 gboolean empty = TRUE;
4576 /* Check that all input bblocks really branch to us */
4577 for (i = 0; i < bb->in_count; ++i) {
4578 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4579 ins->inst_phi_args [i + 1] = -1;
4585 /* LLVM doesn't like phi instructions with zero operands */
4586 ctx->is_dead [ins->dreg] = TRUE;
4590 /* Created earlier, insert it now */
4591 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4593 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4594 int sreg1 = ins->inst_phi_args [i + 1];
4598 * Count the number of times the incoming bblock branches to us,
4599 * since llvm requires a separate entry for each.
4601 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4602 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4605 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4606 if (switch_ins->inst_many_bb [j] == bb)
4613 /* Remember for later */
4614 for (j = 0; j < count; ++j) {
4615 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4618 node->in_bb = bb->in_bb [i];
4620 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);
4630 values [ins->dreg] = lhs;
4634 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4637 values [ins->dreg] = lhs;
4639 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4641 * This is added by the spilling pass in case of the JIT,
4642 * but we have to do it ourselves.
4644 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4648 case OP_MOVE_F_TO_I4: {
4649 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4652 case OP_MOVE_I4_TO_F: {
4653 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4656 case OP_MOVE_F_TO_I8: {
4657 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4660 case OP_MOVE_I8_TO_F: {
4661 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4694 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4695 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4697 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4700 builder = ctx->builder;
4702 switch (ins->opcode) {
4705 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4709 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4713 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4717 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4721 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4725 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4729 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4733 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4737 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4741 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4745 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4749 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4753 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4757 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4761 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4764 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4767 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4771 g_assert_not_reached ();
4778 lhs = convert (ctx, lhs, LLVMFloatType ());
4779 rhs = convert (ctx, rhs, LLVMFloatType ());
4780 switch (ins->opcode) {
4782 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4785 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4788 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4791 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4794 g_assert_not_reached ();
4803 case OP_IREM_UN_IMM:
4805 case OP_IDIV_UN_IMM:
4811 case OP_ISHR_UN_IMM:
4821 case OP_LSHR_UN_IMM:
4827 case OP_SHR_UN_IMM: {
4830 if (spec [MONO_INST_SRC1] == 'l') {
4831 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4833 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4836 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4839 builder = ctx->builder;
4841 #if SIZEOF_VOID_P == 4
4842 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4843 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4846 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4847 lhs = convert (ctx, lhs, IntPtrType ());
4848 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4849 switch (ins->opcode) {
4853 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4857 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4862 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4866 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4868 case OP_IDIV_UN_IMM:
4869 case OP_LDIV_UN_IMM:
4870 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4874 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4876 case OP_IREM_UN_IMM:
4877 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4882 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4886 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4890 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4895 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4900 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4902 case OP_ISHR_UN_IMM:
4903 /* This is used to implement conv.u4, so the lhs could be an i8 */
4904 lhs = convert (ctx, lhs, LLVMInt32Type ());
4905 imm = convert (ctx, imm, LLVMInt32Type ());
4906 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4908 case OP_LSHR_UN_IMM:
4910 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4913 g_assert_not_reached ();
4918 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4921 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4924 lhs = convert (ctx, lhs, LLVMDoubleType ());
4925 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4928 lhs = convert (ctx, lhs, LLVMFloatType ());
4929 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4932 guint32 v = 0xffffffff;
4933 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4937 guint64 v = 0xffffffffffffffffLL;
4938 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4941 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4943 LLVMValueRef v1, v2;
4945 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4946 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4947 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4952 case OP_ICONV_TO_I1:
4953 case OP_ICONV_TO_I2:
4954 case OP_ICONV_TO_I4:
4955 case OP_ICONV_TO_U1:
4956 case OP_ICONV_TO_U2:
4957 case OP_ICONV_TO_U4:
4958 case OP_LCONV_TO_I1:
4959 case OP_LCONV_TO_I2:
4960 case OP_LCONV_TO_U1:
4961 case OP_LCONV_TO_U2:
4962 case OP_LCONV_TO_U4: {
4965 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);
4967 /* Have to do two casts since our vregs have type int */
4968 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4970 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4972 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4975 case OP_ICONV_TO_I8:
4976 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4978 case OP_ICONV_TO_U8:
4979 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4981 case OP_FCONV_TO_I4:
4982 case OP_RCONV_TO_I4:
4983 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4985 case OP_FCONV_TO_I1:
4986 case OP_RCONV_TO_I1:
4987 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4989 case OP_FCONV_TO_U1:
4990 case OP_RCONV_TO_U1:
4991 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4993 case OP_FCONV_TO_I2:
4994 case OP_RCONV_TO_I2:
4995 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4997 case OP_FCONV_TO_U2:
4998 case OP_RCONV_TO_U2:
4999 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5001 case OP_RCONV_TO_U4:
5002 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5004 case OP_FCONV_TO_I8:
5005 case OP_RCONV_TO_I8:
5006 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5009 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5011 case OP_ICONV_TO_R8:
5012 case OP_LCONV_TO_R8:
5013 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5015 case OP_ICONV_TO_R_UN:
5016 case OP_LCONV_TO_R_UN:
5017 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5019 #if SIZEOF_VOID_P == 4
5022 case OP_LCONV_TO_I4:
5023 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5025 case OP_ICONV_TO_R4:
5026 case OP_LCONV_TO_R4:
5027 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5029 values [ins->dreg] = v;
5031 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5033 case OP_FCONV_TO_R4:
5034 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5036 values [ins->dreg] = v;
5038 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5040 case OP_RCONV_TO_R8:
5041 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5043 case OP_RCONV_TO_R4:
5044 values [ins->dreg] = lhs;
5047 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5050 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5053 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5055 case OP_LOCALLOC_IMM: {
5058 guint32 size = ins->inst_imm;
5059 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5061 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5063 if (ins->flags & MONO_INST_INIT) {
5064 LLVMValueRef args [5];
5067 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5068 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5069 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5070 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5071 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5074 values [ins->dreg] = v;
5078 LLVMValueRef v, size;
5080 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), "");
5082 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5084 if (ins->flags & MONO_INST_INIT) {
5085 LLVMValueRef args [5];
5088 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5090 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5091 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5092 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5094 values [ins->dreg] = v;
5098 case OP_LOADI1_MEMBASE:
5099 case OP_LOADU1_MEMBASE:
5100 case OP_LOADI2_MEMBASE:
5101 case OP_LOADU2_MEMBASE:
5102 case OP_LOADI4_MEMBASE:
5103 case OP_LOADU4_MEMBASE:
5104 case OP_LOADI8_MEMBASE:
5105 case OP_LOADR4_MEMBASE:
5106 case OP_LOADR8_MEMBASE:
5107 case OP_LOAD_MEMBASE:
5115 LLVMValueRef base, index, addr;
5117 gboolean sext = FALSE, zext = FALSE;
5118 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5120 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5125 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)) {
5126 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5132 if (ins->inst_offset == 0) {
5134 } else if (ins->inst_offset % size != 0) {
5135 /* Unaligned load */
5136 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5137 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5139 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5140 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5144 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5146 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5148 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5150 * These will signal LLVM that these loads do not alias any stores, and
5151 * they can't fail, allowing them to be hoisted out of loops.
5153 set_invariant_load_flag (values [ins->dreg]);
5154 #if LLVM_API_VERSION < 100
5155 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5160 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5162 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5163 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5164 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5168 case OP_STOREI1_MEMBASE_REG:
5169 case OP_STOREI2_MEMBASE_REG:
5170 case OP_STOREI4_MEMBASE_REG:
5171 case OP_STOREI8_MEMBASE_REG:
5172 case OP_STORER4_MEMBASE_REG:
5173 case OP_STORER8_MEMBASE_REG:
5174 case OP_STORE_MEMBASE_REG: {
5176 LLVMValueRef index, addr, base;
5178 gboolean sext = FALSE, zext = FALSE;
5179 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5181 if (!values [ins->inst_destbasereg]) {
5182 set_failure (ctx, "inst_destbasereg");
5186 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5188 base = values [ins->inst_destbasereg];
5189 if (ins->inst_offset % size != 0) {
5190 /* Unaligned store */
5191 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5192 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5194 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5195 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5197 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5201 case OP_STOREI1_MEMBASE_IMM:
5202 case OP_STOREI2_MEMBASE_IMM:
5203 case OP_STOREI4_MEMBASE_IMM:
5204 case OP_STOREI8_MEMBASE_IMM:
5205 case OP_STORE_MEMBASE_IMM: {
5207 LLVMValueRef index, addr, base;
5209 gboolean sext = FALSE, zext = FALSE;
5210 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5212 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5214 base = values [ins->inst_destbasereg];
5215 if (ins->inst_offset % size != 0) {
5216 /* Unaligned store */
5217 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5218 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5220 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5221 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5223 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5228 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5230 case OP_OUTARG_VTRETADDR:
5238 case OP_VOIDCALL_MEMBASE:
5239 case OP_CALL_MEMBASE:
5240 case OP_LCALL_MEMBASE:
5241 case OP_FCALL_MEMBASE:
5242 case OP_RCALL_MEMBASE:
5243 case OP_VCALL_MEMBASE:
5244 case OP_VOIDCALL_REG:
5249 case OP_VCALL_REG: {
5250 process_call (ctx, bb, &builder, ins);
5255 LLVMValueRef indexes [2];
5256 MonoJumpInfo *tmp_ji, *ji;
5257 LLVMValueRef got_entry_addr;
5261 * FIXME: Can't allocate from the cfg mempool since that is freed if
5262 * the LLVM compile fails.
5264 tmp_ji = g_new0 (MonoJumpInfo, 1);
5265 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5266 tmp_ji->data.target = ins->inst_p0;
5268 ji = mono_aot_patch_info_dup (tmp_ji);
5271 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5272 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5275 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5276 * resolvable at runtime using dlsym ().
5279 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5284 ji->next = cfg->patch_info;
5285 cfg->patch_info = ji;
5287 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5288 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5289 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5290 if (!mono_aot_is_shared_got_offset (got_offset)) {
5291 //mono_print_ji (ji);
5293 ctx->has_got_access = TRUE;
5296 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5297 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5298 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5300 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5301 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5303 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5304 if (!cfg->llvm_only)
5305 set_invariant_load_flag (values [ins->dreg]);
5308 case OP_NOT_REACHED:
5309 LLVMBuildUnreachable (builder);
5310 has_terminator = TRUE;
5311 g_assert (bb->block_num < cfg->max_block_num);
5312 ctx->unreachable [bb->block_num] = TRUE;
5313 /* Might have instructions after this */
5315 MonoInst *next = ins->next;
5317 * FIXME: If later code uses the regs defined by these instructions,
5318 * compilation will fail.
5320 MONO_DELETE_INS (bb, next);
5324 MonoInst *var = ins->inst_i0;
5326 if (var->opcode == OP_VTARG_ADDR) {
5327 /* The variable contains the vtype address */
5328 values [ins->dreg] = values [var->dreg];
5329 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5330 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5332 values [ins->dreg] = addresses [var->dreg];
5337 LLVMValueRef args [1];
5339 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5340 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5344 LLVMValueRef args [1];
5346 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5347 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5351 LLVMValueRef args [1];
5353 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5354 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5358 LLVMValueRef args [1];
5360 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5361 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5375 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5376 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5378 switch (ins->opcode) {
5381 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5385 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5389 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5393 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5396 g_assert_not_reached ();
5399 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5404 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5405 * hack is necessary (for now).
5408 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5410 #define ARM64_ATOMIC_FENCE_FIX
5413 case OP_ATOMIC_EXCHANGE_I4:
5414 case OP_ATOMIC_EXCHANGE_I8: {
5415 LLVMValueRef args [2];
5418 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5419 t = LLVMInt32Type ();
5421 t = LLVMInt64Type ();
5423 g_assert (ins->inst_offset == 0);
5425 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5426 args [1] = convert (ctx, rhs, t);
5428 ARM64_ATOMIC_FENCE_FIX;
5429 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5430 ARM64_ATOMIC_FENCE_FIX;
5433 case OP_ATOMIC_ADD_I4:
5434 case OP_ATOMIC_ADD_I8: {
5435 LLVMValueRef args [2];
5438 if (ins->opcode == OP_ATOMIC_ADD_I4)
5439 t = LLVMInt32Type ();
5441 t = LLVMInt64Type ();
5443 g_assert (ins->inst_offset == 0);
5445 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5446 args [1] = convert (ctx, rhs, t);
5447 ARM64_ATOMIC_FENCE_FIX;
5448 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5449 ARM64_ATOMIC_FENCE_FIX;
5452 case OP_ATOMIC_CAS_I4:
5453 case OP_ATOMIC_CAS_I8: {
5454 LLVMValueRef args [3], val;
5457 if (ins->opcode == OP_ATOMIC_CAS_I4)
5458 t = LLVMInt32Type ();
5460 t = LLVMInt64Type ();
5462 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5464 args [1] = convert (ctx, values [ins->sreg3], t);
5466 args [2] = convert (ctx, values [ins->sreg2], t);
5467 ARM64_ATOMIC_FENCE_FIX;
5468 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5469 ARM64_ATOMIC_FENCE_FIX;
5470 /* cmpxchg returns a pair */
5471 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5474 case OP_MEMORY_BARRIER: {
5475 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5478 case OP_ATOMIC_LOAD_I1:
5479 case OP_ATOMIC_LOAD_I2:
5480 case OP_ATOMIC_LOAD_I4:
5481 case OP_ATOMIC_LOAD_I8:
5482 case OP_ATOMIC_LOAD_U1:
5483 case OP_ATOMIC_LOAD_U2:
5484 case OP_ATOMIC_LOAD_U4:
5485 case OP_ATOMIC_LOAD_U8:
5486 case OP_ATOMIC_LOAD_R4:
5487 case OP_ATOMIC_LOAD_R8: {
5488 #if LLVM_API_VERSION > 100
5490 gboolean sext, zext;
5492 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5493 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5494 LLVMValueRef index, addr;
5496 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5501 if (ins->inst_offset != 0) {
5502 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5503 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5508 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5510 ARM64_ATOMIC_FENCE_FIX;
5511 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5512 ARM64_ATOMIC_FENCE_FIX;
5515 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5517 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5520 set_failure (ctx, "atomic mono.load intrinsic");
5524 case OP_ATOMIC_STORE_I1:
5525 case OP_ATOMIC_STORE_I2:
5526 case OP_ATOMIC_STORE_I4:
5527 case OP_ATOMIC_STORE_I8:
5528 case OP_ATOMIC_STORE_U1:
5529 case OP_ATOMIC_STORE_U2:
5530 case OP_ATOMIC_STORE_U4:
5531 case OP_ATOMIC_STORE_U8:
5532 case OP_ATOMIC_STORE_R4:
5533 case OP_ATOMIC_STORE_R8: {
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, value, base;
5541 #if LLVM_API_VERSION < 100
5542 if (!cfg->llvm_only) {
5543 set_failure (ctx, "atomic mono.store intrinsic");
5548 if (!values [ins->inst_destbasereg]) {
5549 set_failure (ctx, "inst_destbasereg");
5553 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5555 base = values [ins->inst_destbasereg];
5556 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5557 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5558 value = convert (ctx, values [ins->sreg1], t);
5560 ARM64_ATOMIC_FENCE_FIX;
5561 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5562 ARM64_ATOMIC_FENCE_FIX;
5565 case OP_RELAXED_NOP: {
5566 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5567 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5574 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5576 // 257 == FS segment register
5577 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5579 // 256 == GS segment register
5580 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5583 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5584 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5585 /* See mono_amd64_emit_tls_get () */
5586 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5588 // 256 == GS segment register
5589 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5590 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5592 set_failure (ctx, "opcode tls-get");
5598 case OP_TLS_GET_REG: {
5599 #if defined(TARGET_AMD64) && defined(__linux__)
5600 // 257 == FS segment register
5601 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5602 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt64Type ()), ptrtype, ""), "");
5603 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5604 /* See emit_tls_get_reg () */
5605 // 256 == GS segment register
5606 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5607 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5609 set_failure (ctx, "opcode tls-get");
5615 case OP_TLS_SET_REG: {
5616 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5617 /* See emit_tls_get_reg () */
5618 // 256 == GS segment register
5619 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5620 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5622 set_failure (ctx, "opcode tls-set-reg");
5627 case OP_GC_SAFE_POINT: {
5628 LLVMValueRef val, cmp, callee;
5629 LLVMBasicBlockRef poll_bb, cont_bb;
5630 static LLVMTypeRef sig;
5631 const char *icall_name = "mono_threads_state_poll";
5634 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5638 * mono_threads_state_poll ();
5639 * FIXME: Use a preserveall wrapper
5641 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5642 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5643 poll_bb = gen_bb (ctx, "POLL_BB");
5644 cont_bb = gen_bb (ctx, "CONT_BB");
5645 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5647 ctx->builder = builder = create_builder (ctx);
5648 LLVMPositionBuilderAtEnd (builder, poll_bb);
5650 if (ctx->cfg->compile_aot) {
5651 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5653 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5654 callee = emit_jit_callee (ctx, icall_name, sig, target);
5656 LLVMBuildCall (builder, callee, NULL, 0, "");
5657 LLVMBuildBr (builder, cont_bb);
5659 ctx->builder = builder = create_builder (ctx);
5660 LLVMPositionBuilderAtEnd (builder, cont_bb);
5661 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5669 case OP_IADD_OVF_UN:
5671 case OP_ISUB_OVF_UN:
5673 case OP_IMUL_OVF_UN:
5675 case OP_LADD_OVF_UN:
5677 case OP_LSUB_OVF_UN:
5679 case OP_LMUL_OVF_UN:
5681 LLVMValueRef args [2], val, ovf, func;
5683 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5684 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5685 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5687 val = LLVMBuildCall (builder, func, args, 2, "");
5688 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5689 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5690 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5693 builder = ctx->builder;
5699 * We currently model them using arrays. Promotion to local vregs is
5700 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5701 * so we always have an entry in cfg->varinfo for them.
5702 * FIXME: Is this needed ?
5705 MonoClass *klass = ins->klass;
5706 LLVMValueRef args [5];
5710 set_failure (ctx, "!klass");
5714 if (!addresses [ins->dreg])
5715 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5716 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5717 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5718 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5720 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5721 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5722 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5725 case OP_DUMMY_VZERO:
5728 case OP_STOREV_MEMBASE:
5729 case OP_LOADV_MEMBASE:
5731 MonoClass *klass = ins->klass;
5732 LLVMValueRef src = NULL, dst, args [5];
5733 gboolean done = FALSE;
5737 set_failure (ctx, "!klass");
5741 if (mini_is_gsharedvt_klass (klass)) {
5743 set_failure (ctx, "gsharedvt");
5747 switch (ins->opcode) {
5748 case OP_STOREV_MEMBASE:
5749 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5750 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5751 /* Decomposed earlier */
5752 g_assert_not_reached ();
5755 if (!addresses [ins->sreg1]) {
5757 g_assert (values [ins->sreg1]);
5758 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));
5759 LLVMBuildStore (builder, values [ins->sreg1], dst);
5762 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5763 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5766 case OP_LOADV_MEMBASE:
5767 if (!addresses [ins->dreg])
5768 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5769 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5770 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5773 if (!addresses [ins->sreg1])
5774 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5775 if (!addresses [ins->dreg])
5776 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5777 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5778 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5781 g_assert_not_reached ();
5791 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5792 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5794 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5795 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5796 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5799 case OP_LLVM_OUTARG_VT: {
5800 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5801 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5803 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5804 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5806 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5807 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5809 g_assert (addresses [ins->sreg1]);
5810 addresses [ins->dreg] = addresses [ins->sreg1];
5812 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5813 if (!addresses [ins->sreg1]) {
5814 addresses [ins->sreg1] = build_alloca (ctx, t);
5815 g_assert (values [ins->sreg1]);
5817 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5818 addresses [ins->dreg] = addresses [ins->sreg1];
5820 if (!addresses [ins->sreg1]) {
5821 addresses [ins->sreg1] = build_alloca (ctx, t);
5822 g_assert (values [ins->sreg1]);
5823 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5825 addresses [ins->dreg] = addresses [ins->sreg1];
5829 case OP_OBJC_GET_SELECTOR: {
5830 const char *name = (const char*)ins->inst_p0;
5833 if (!ctx->module->objc_selector_to_var)
5834 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5835 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5837 LLVMValueRef indexes [16];
5839 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5840 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5841 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5842 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5843 mark_as_used (ctx->module, name_var);
5845 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5847 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5848 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5849 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5850 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5851 LLVMSetExternallyInitialized (ref_var, TRUE);
5852 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5853 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5854 mark_as_used (ctx->module, ref_var);
5856 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5860 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5867 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5869 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5872 case OP_LOADX_MEMBASE: {
5873 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5876 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5877 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5880 case OP_STOREX_MEMBASE: {
5881 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5884 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5885 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5892 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5896 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5902 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5906 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5910 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5914 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5917 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5920 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5923 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5927 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5938 LLVMValueRef v = NULL;
5940 switch (ins->opcode) {
5945 t = LLVMVectorType (LLVMInt32Type (), 4);
5946 rt = LLVMVectorType (LLVMFloatType (), 4);
5952 t = LLVMVectorType (LLVMInt64Type (), 2);
5953 rt = LLVMVectorType (LLVMDoubleType (), 2);
5956 t = LLVMInt32Type ();
5957 rt = LLVMInt32Type ();
5958 g_assert_not_reached ();
5961 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5962 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5963 switch (ins->opcode) {
5966 v = LLVMBuildAnd (builder, lhs, rhs, "");
5970 v = LLVMBuildOr (builder, lhs, rhs, "");
5974 v = LLVMBuildXor (builder, lhs, rhs, "");
5978 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5981 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5987 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
5988 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
5994 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
5995 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
5999 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6000 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6017 case OP_PADDB_SAT_UN:
6018 case OP_PADDW_SAT_UN:
6019 case OP_PSUBB_SAT_UN:
6020 case OP_PSUBW_SAT_UN:
6028 case OP_PMULW_HIGH_UN: {
6029 LLVMValueRef args [2];
6034 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6041 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6045 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6053 case OP_EXTRACTX_U2:
6055 case OP_EXTRACT_U1: {
6057 gboolean zext = FALSE;
6059 t = simd_op_to_llvm_type (ins->opcode);
6061 switch (ins->opcode) {
6069 case OP_EXTRACTX_U2:
6074 t = LLVMInt32Type ();
6075 g_assert_not_reached ();
6078 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6079 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6081 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6090 case OP_EXPAND_R8: {
6091 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6092 LLVMValueRef mask [16], v;
6095 for (i = 0; i < 16; ++i)
6096 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6098 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6100 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6101 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6106 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6109 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6112 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6115 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6118 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6121 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6125 // Requires a later llvm version
6127 LLVMValueRef indexes [16];
6129 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6130 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6131 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6132 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6133 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6137 LLVMValueRef indexes [16];
6139 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6140 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6141 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6142 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6143 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6147 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6159 case OP_EXTRACT_MASK:
6166 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6168 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6173 LLVMRealPredicate op;
6175 switch (ins->inst_c0) {
6185 case SIMD_COMP_UNORD:
6201 g_assert_not_reached ();
6204 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6205 if (ins->opcode == OP_COMPPD)
6206 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6208 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6212 /* This is only used for implementing shifts by non-immediate */
6213 values [ins->dreg] = lhs;
6224 LLVMValueRef args [3];
6227 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6229 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6240 case OP_PSHLQ_REG: {
6241 LLVMValueRef args [3];
6244 args [1] = values [ins->sreg2];
6246 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6253 case OP_PSHUFLEW_LOW:
6254 case OP_PSHUFLEW_HIGH: {
6256 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6257 int i, mask_size = 0;
6258 int imask = ins->inst_c0;
6260 /* Convert the x86 shuffle mask to LLVM's */
6261 switch (ins->opcode) {
6264 mask [0] = ((imask >> 0) & 3);
6265 mask [1] = ((imask >> 2) & 3);
6266 mask [2] = ((imask >> 4) & 3) + 4;
6267 mask [3] = ((imask >> 6) & 3) + 4;
6268 v1 = values [ins->sreg1];
6269 v2 = values [ins->sreg2];
6273 mask [0] = ((imask >> 0) & 1);
6274 mask [1] = ((imask >> 1) & 1) + 2;
6275 v1 = values [ins->sreg1];
6276 v2 = values [ins->sreg2];
6278 case OP_PSHUFLEW_LOW:
6280 mask [0] = ((imask >> 0) & 3);
6281 mask [1] = ((imask >> 2) & 3);
6282 mask [2] = ((imask >> 4) & 3);
6283 mask [3] = ((imask >> 6) & 3);
6288 v1 = values [ins->sreg1];
6289 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6291 case OP_PSHUFLEW_HIGH:
6297 mask [4] = 4 + ((imask >> 0) & 3);
6298 mask [5] = 4 + ((imask >> 2) & 3);
6299 mask [6] = 4 + ((imask >> 4) & 3);
6300 mask [7] = 4 + ((imask >> 6) & 3);
6301 v1 = values [ins->sreg1];
6302 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6306 mask [0] = ((imask >> 0) & 3);
6307 mask [1] = ((imask >> 2) & 3);
6308 mask [2] = ((imask >> 4) & 3);
6309 mask [3] = ((imask >> 6) & 3);
6310 v1 = values [ins->sreg1];
6311 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6314 g_assert_not_reached ();
6316 for (i = 0; i < mask_size; ++i)
6317 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6319 values [ins->dreg] =
6320 LLVMBuildShuffleVector (builder, v1, v2,
6321 LLVMConstVector (mask_values, mask_size), dname);
6325 case OP_UNPACK_LOWB:
6326 case OP_UNPACK_LOWW:
6327 case OP_UNPACK_LOWD:
6328 case OP_UNPACK_LOWQ:
6329 case OP_UNPACK_LOWPS:
6330 case OP_UNPACK_LOWPD:
6331 case OP_UNPACK_HIGHB:
6332 case OP_UNPACK_HIGHW:
6333 case OP_UNPACK_HIGHD:
6334 case OP_UNPACK_HIGHQ:
6335 case OP_UNPACK_HIGHPS:
6336 case OP_UNPACK_HIGHPD: {
6338 LLVMValueRef mask_values [16];
6339 int i, mask_size = 0;
6340 gboolean low = FALSE;
6342 switch (ins->opcode) {
6343 case OP_UNPACK_LOWB:
6347 case OP_UNPACK_LOWW:
6351 case OP_UNPACK_LOWD:
6352 case OP_UNPACK_LOWPS:
6356 case OP_UNPACK_LOWQ:
6357 case OP_UNPACK_LOWPD:
6361 case OP_UNPACK_HIGHB:
6364 case OP_UNPACK_HIGHW:
6367 case OP_UNPACK_HIGHD:
6368 case OP_UNPACK_HIGHPS:
6371 case OP_UNPACK_HIGHQ:
6372 case OP_UNPACK_HIGHPD:
6376 g_assert_not_reached ();
6380 for (i = 0; i < (mask_size / 2); ++i) {
6382 mask [(i * 2) + 1] = mask_size + i;
6385 for (i = 0; i < (mask_size / 2); ++i) {
6386 mask [(i * 2)] = (mask_size / 2) + i;
6387 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6391 for (i = 0; i < mask_size; ++i)
6392 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6394 values [ins->dreg] =
6395 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6396 LLVMConstVector (mask_values, mask_size), dname);
6401 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6402 LLVMValueRef v, val;
6404 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6405 val = LLVMConstNull (t);
6406 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6407 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6409 values [ins->dreg] = val;
6413 case OP_DUPPS_HIGH: {
6414 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6415 LLVMValueRef v1, v2, val;
6418 if (ins->opcode == OP_DUPPS_LOW) {
6419 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6420 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6422 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6423 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6425 val = LLVMConstNull (t);
6426 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6427 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6428 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6429 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6431 values [ins->dreg] = val;
6441 * EXCEPTION HANDLING
6443 case OP_IMPLICIT_EXCEPTION:
6444 /* This marks a place where an implicit exception can happen */
6445 if (bb->region != -1)
6446 set_failure (ctx, "implicit-exception");
6450 gboolean rethrow = (ins->opcode == OP_RETHROW);
6451 if (ctx->llvm_only) {
6452 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6453 has_terminator = TRUE;
6454 ctx->unreachable [bb->block_num] = TRUE;
6456 emit_throw (ctx, bb, rethrow, lhs);
6457 builder = ctx->builder;
6461 case OP_CALL_HANDLER: {
6463 * We don't 'call' handlers, but instead simply branch to them.
6464 * The code generated by ENDFINALLY will branch back to us.
6466 LLVMBasicBlockRef noex_bb;
6468 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6470 bb_list = info->call_handler_return_bbs;
6473 * Set the indicator variable for the finally clause.
6475 lhs = info->finally_ind;
6477 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6479 /* Branch to the finally clause */
6480 LLVMBuildBr (builder, info->call_handler_target_bb);
6482 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6483 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6485 builder = ctx->builder = create_builder (ctx);
6486 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6488 bblocks [bb->block_num].end_bblock = noex_bb;
6491 case OP_START_HANDLER: {
6494 case OP_ENDFINALLY: {
6495 LLVMBasicBlockRef resume_bb;
6496 MonoBasicBlock *handler_bb;
6497 LLVMValueRef val, switch_ins, callee;
6501 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6502 g_assert (handler_bb);
6503 info = &bblocks [handler_bb->block_num];
6504 lhs = info->finally_ind;
6507 bb_list = info->call_handler_return_bbs;
6509 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6511 /* Load the finally variable */
6512 val = LLVMBuildLoad (builder, lhs, "");
6514 /* Reset the variable */
6515 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6517 /* Branch to either resume_bb, or to the bblocks in bb_list */
6518 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6520 * The other targets are added at the end to handle OP_CALL_HANDLER
6521 * opcodes processed later.
6523 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6525 builder = ctx->builder = create_builder (ctx);
6526 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6528 if (ctx->llvm_only) {
6529 emit_resume_eh (ctx, bb);
6531 if (ctx->cfg->compile_aot) {
6532 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6534 #if LLVM_API_VERSION > 100
6535 MonoJitICallInfo *info;
6537 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6539 gpointer target = (void*)info->func;
6540 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6541 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6543 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6546 LLVMBuildCall (builder, callee, NULL, 0, "");
6547 LLVMBuildUnreachable (builder);
6550 has_terminator = TRUE;
6553 case OP_IL_SEQ_POINT:
6558 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6559 set_failure (ctx, reason);
6567 /* Convert the value to the type required by phi nodes */
6568 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6569 if (!values [ins->dreg])
6571 values [ins->dreg] = addresses [ins->dreg];
6573 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6576 /* Add stores for volatile variables */
6577 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6578 emit_volatile_store (ctx, ins->dreg);
6584 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6585 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6588 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6589 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6590 LLVMBuildRetVoid (builder);
6593 if (bb == cfg->bb_entry)
6594 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6598 * mono_llvm_check_method_supported:
6600 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6601 * compiling a method twice.
6604 mono_llvm_check_method_supported (MonoCompile *cfg)
6611 if (cfg->method->save_lmf) {
6612 cfg->exception_message = g_strdup ("lmf");
6613 cfg->disable_llvm = TRUE;
6615 if (cfg->disable_llvm)
6619 * Nested clauses where one of the clauses is a finally clause is
6620 * not supported, because LLVM can't figure out the control flow,
6621 * probably because we resume exception handling by calling our
6622 * own function instead of using the 'resume' llvm instruction.
6624 for (i = 0; i < cfg->header->num_clauses; ++i) {
6625 for (j = 0; j < cfg->header->num_clauses; ++j) {
6626 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6627 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6629 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6630 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6631 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6632 cfg->exception_message = g_strdup ("nested clauses");
6633 cfg->disable_llvm = TRUE;
6638 if (cfg->disable_llvm)
6642 if (cfg->method->dynamic) {
6643 cfg->exception_message = g_strdup ("dynamic.");
6644 cfg->disable_llvm = TRUE;
6646 if (cfg->disable_llvm)
6650 static LLVMCallInfo*
6651 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6653 LLVMCallInfo *linfo;
6656 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6660 * Gsharedvt methods have the following calling convention:
6661 * - all arguments are passed by ref, even non generic ones
6662 * - the return value is returned by ref too, using a vret
6663 * argument passed after 'this'.
6665 n = sig->param_count + sig->hasthis;
6666 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6670 linfo->args [pindex ++].storage = LLVMArgNormal;
6672 if (sig->ret->type != MONO_TYPE_VOID) {
6673 if (mini_is_gsharedvt_variable_type (sig->ret))
6674 linfo->ret.storage = LLVMArgGsharedvtVariable;
6675 else if (mini_type_is_vtype (sig->ret))
6676 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6678 linfo->ret.storage = LLVMArgGsharedvtFixed;
6679 linfo->vret_arg_index = pindex;
6681 linfo->ret.storage = LLVMArgNone;
6684 for (i = 0; i < sig->param_count; ++i) {
6685 if (sig->params [i]->byref)
6686 linfo->args [pindex].storage = LLVMArgNormal;
6687 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6688 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6689 else if (mini_type_is_vtype (sig->params [i]))
6690 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6692 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6693 linfo->args [pindex].type = sig->params [i];
6700 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6701 for (i = 0; i < sig->param_count; ++i)
6702 linfo->args [i + sig->hasthis].type = sig->params [i];
6708 emit_method_inner (EmitContext *ctx);
6711 free_ctx (EmitContext *ctx)
6715 g_free (ctx->values);
6716 g_free (ctx->addresses);
6717 g_free (ctx->vreg_types);
6718 g_free (ctx->vreg_cli_types);
6719 g_free (ctx->is_dead);
6720 g_free (ctx->unreachable);
6721 g_ptr_array_free (ctx->phi_values, TRUE);
6722 g_free (ctx->bblocks);
6723 g_hash_table_destroy (ctx->region_to_handler);
6724 g_hash_table_destroy (ctx->clause_to_handler);
6725 g_hash_table_destroy (ctx->jit_callees);
6727 GHashTableIter iter;
6728 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6729 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6732 g_hash_table_destroy (ctx->method_to_callers);
6734 g_free (ctx->method_name);
6735 g_ptr_array_free (ctx->bblock_list, TRUE);
6737 for (l = ctx->builders; l; l = l->next) {
6738 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6739 LLVMDisposeBuilder (builder);
6746 * mono_llvm_emit_method:
6748 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6751 mono_llvm_emit_method (MonoCompile *cfg)
6755 gboolean is_linkonce = FALSE;
6758 /* The code below might acquire the loader lock, so use it for global locking */
6759 mono_loader_lock ();
6761 /* Used to communicate with the callbacks */
6762 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6764 ctx = g_new0 (EmitContext, 1);
6766 ctx->mempool = cfg->mempool;
6769 * This maps vregs to the LLVM instruction defining them
6771 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6773 * This maps vregs for volatile variables to the LLVM instruction defining their
6776 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6777 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6778 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6779 ctx->phi_values = g_ptr_array_sized_new (256);
6781 * This signals whenever the vreg was defined by a phi node with no input vars
6782 * (i.e. all its input bblocks end with NOT_REACHABLE).
6784 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6785 /* Whenever the bblock is unreachable */
6786 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6787 ctx->bblock_list = g_ptr_array_sized_new (256);
6789 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6790 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6791 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6792 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6793 if (cfg->compile_aot) {
6794 ctx->module = &aot_module;
6798 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6799 * linkage for them. This requires the following:
6800 * - the method needs to have a unique mangled name
6801 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6803 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6805 method_name = mono_aot_get_mangled_method_name (cfg->method);
6807 is_linkonce = FALSE;
6810 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6812 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6816 method_name = mono_aot_get_method_name (cfg);
6817 cfg->llvm_method_name = g_strdup (method_name);
6819 init_jit_module (cfg->domain);
6820 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6821 method_name = mono_method_full_name (cfg->method, TRUE);
6823 ctx->method_name = method_name;
6824 ctx->is_linkonce = is_linkonce;
6826 #if LLVM_API_VERSION > 100
6827 if (cfg->compile_aot)
6828 ctx->lmodule = ctx->module->lmodule;
6830 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6832 ctx->lmodule = ctx->module->lmodule;
6834 ctx->llvm_only = ctx->module->llvm_only;
6836 emit_method_inner (ctx);
6838 if (!ctx_ok (ctx)) {
6840 /* Need to add unused phi nodes as they can be referenced by other values */
6841 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6842 LLVMBuilderRef builder;
6844 builder = create_builder (ctx);
6845 LLVMPositionBuilderAtEnd (builder, phi_bb);
6847 for (i = 0; i < ctx->phi_values->len; ++i) {
6848 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6849 if (LLVMGetInstructionParent (v) == NULL)
6850 LLVMInsertIntoBuilder (builder, v);
6853 LLVMDeleteFunction (ctx->lmethod);
6859 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6861 mono_loader_unlock ();
6865 emit_method_inner (EmitContext *ctx)
6867 MonoCompile *cfg = ctx->cfg;
6868 MonoMethodSignature *sig;
6870 LLVMTypeRef method_type;
6871 LLVMValueRef method = NULL;
6872 LLVMValueRef *values = ctx->values;
6873 int i, max_block_num, bb_index;
6874 gboolean last = FALSE;
6875 LLVMCallInfo *linfo;
6876 LLVMModuleRef lmodule = ctx->lmodule;
6878 GPtrArray *bblock_list = ctx->bblock_list;
6879 MonoMethodHeader *header;
6880 MonoExceptionClause *clause;
6883 if (cfg->gsharedvt && !cfg->llvm_only) {
6884 set_failure (ctx, "gsharedvt");
6890 static int count = 0;
6893 if (g_getenv ("LLVM_COUNT")) {
6894 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6895 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6899 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6900 set_failure (ctx, "count");
6907 sig = mono_method_signature (cfg->method);
6910 linfo = get_llvm_call_info (cfg, sig);
6916 linfo->rgctx_arg = TRUE;
6917 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6921 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6922 ctx->lmethod = method;
6924 if (!cfg->llvm_only)
6925 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6926 LLVMSetLinkage (method, LLVMPrivateLinkage);
6928 LLVMAddFunctionAttr (method, LLVMUWTable);
6930 if (cfg->compile_aot) {
6931 LLVMSetLinkage (method, LLVMInternalLinkage);
6932 if (ctx->module->external_symbols) {
6933 LLVMSetLinkage (method, LLVMExternalLinkage);
6934 LLVMSetVisibility (method, LLVMHiddenVisibility);
6936 if (ctx->is_linkonce) {
6937 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6938 LLVMSetVisibility (method, LLVMDefaultVisibility);
6941 #if LLVM_API_VERSION > 100
6942 LLVMSetLinkage (method, LLVMExternalLinkage);
6944 LLVMSetLinkage (method, LLVMPrivateLinkage);
6948 if (cfg->method->save_lmf && !cfg->llvm_only) {
6949 set_failure (ctx, "lmf");
6953 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6954 set_failure (ctx, "pinvoke signature");
6958 header = cfg->header;
6959 for (i = 0; i < header->num_clauses; ++i) {
6960 clause = &header->clauses [i];
6961 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6962 set_failure (ctx, "non-finally/catch clause.");
6966 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6967 /* We can't handle inlined methods with clauses */
6968 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6970 if (linfo->rgctx_arg) {
6971 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6972 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6974 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6975 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6976 * CC_X86_64_Mono in X86CallingConv.td.
6978 if (!ctx->llvm_only)
6979 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6980 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6982 ctx->rgctx_arg_pindex = -1;
6984 if (cfg->vret_addr) {
6985 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6986 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6987 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6988 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6989 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6994 ctx->this_arg_pindex = linfo->this_arg_pindex;
6995 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6996 values [cfg->args [0]->dreg] = ctx->this_arg;
6997 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7000 names = g_new (char *, sig->param_count);
7001 mono_method_get_param_names (cfg->method, (const char **) names);
7003 /* Set parameter names/attributes */
7004 for (i = 0; i < sig->param_count; ++i) {
7005 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7007 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7010 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7011 name = g_strdup_printf ("dummy_%d_%d", i, j);
7012 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7016 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7019 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7020 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7021 if (names [i] && names [i][0] != '\0')
7022 name = g_strdup_printf ("p_arg_%s", names [i]);
7024 name = g_strdup_printf ("p_arg_%d", i);
7026 if (names [i] && names [i][0] != '\0')
7027 name = g_strdup_printf ("arg_%s", names [i]);
7029 name = g_strdup_printf ("arg_%d", i);
7031 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7033 if (ainfo->storage == LLVMArgVtypeByVal)
7034 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7036 if (ainfo->storage == LLVMArgVtypeByRef) {
7038 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7043 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7044 ctx->minfo = mono_debug_lookup_method (cfg->method);
7045 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7049 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7050 max_block_num = MAX (max_block_num, bb->block_num);
7051 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7053 /* Add branches between non-consecutive bblocks */
7054 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7055 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7056 bb->next_bb != bb->last_ins->inst_false_bb) {
7058 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7059 inst->opcode = OP_BR;
7060 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7061 mono_bblock_add_inst (bb, inst);
7066 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7067 * was later optimized away, so clear these flags, and add them back for the still
7068 * present OP_LDADDR instructions.
7070 for (i = 0; i < cfg->next_vreg; ++i) {
7073 ins = get_vreg_to_inst (cfg, i);
7074 if (ins && ins != cfg->rgctx_var)
7075 ins->flags &= ~MONO_INST_INDIRECT;
7079 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7081 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7083 LLVMBuilderRef builder;
7085 char dname_buf[128];
7087 builder = create_builder (ctx);
7089 for (ins = bb->code; ins; ins = ins->next) {
7090 switch (ins->opcode) {
7095 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7100 if (ins->opcode == OP_VPHI) {
7101 /* Treat valuetype PHI nodes as operating on the address itself */
7102 g_assert (ins->klass);
7103 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7107 * Have to precreate these, as they can be referenced by
7108 * earlier instructions.
7110 sprintf (dname_buf, "t%d", ins->dreg);
7112 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7114 if (ins->opcode == OP_VPHI)
7115 ctx->addresses [ins->dreg] = values [ins->dreg];
7117 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7120 * Set the expected type of the incoming arguments since these have
7121 * to have the same type.
7123 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7124 int sreg1 = ins->inst_phi_args [i + 1];
7127 ctx->vreg_types [sreg1] = phi_type;
7132 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7141 * Create an ordering for bblocks, use the depth first order first, then
7142 * put the exception handling bblocks last.
7144 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7145 bb = cfg->bblocks [bb_index];
7146 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7147 g_ptr_array_add (bblock_list, bb);
7148 bblocks [bb->block_num].added = TRUE;
7152 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7153 if (!bblocks [bb->block_num].added)
7154 g_ptr_array_add (bblock_list, bb);
7158 * Second pass: generate code.
7161 LLVMBuilderRef entry_builder = create_builder (ctx);
7162 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7163 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7164 emit_entry_bb (ctx, entry_builder);
7166 // Make landing pads first
7167 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7169 if (ctx->llvm_only) {
7170 size_t group_index = 0;
7171 while (group_index < cfg->header->num_clauses) {
7173 size_t cursor = group_index;
7174 while (cursor < cfg->header->num_clauses &&
7175 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7176 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7181 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7182 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7183 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7185 group_index = cursor;
7189 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7190 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7192 // Prune unreachable mono BBs.
7193 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7196 process_bb (ctx, bb);
7200 g_hash_table_destroy (ctx->exc_meta);
7202 mono_memory_barrier ();
7204 /* Add incoming phi values */
7205 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7206 GSList *l, *ins_list;
7208 ins_list = bblocks [bb->block_num].phi_nodes;
7210 for (l = ins_list; l; l = l->next) {
7211 PhiNode *node = (PhiNode*)l->data;
7212 MonoInst *phi = node->phi;
7213 int sreg1 = node->sreg;
7214 LLVMBasicBlockRef in_bb;
7219 in_bb = get_end_bb (ctx, node->in_bb);
7221 if (ctx->unreachable [node->in_bb->block_num])
7224 if (!values [sreg1]) {
7225 /* Can happen with values in EH clauses */
7226 set_failure (ctx, "incoming phi sreg1");
7230 if (phi->opcode == OP_VPHI) {
7231 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7232 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7234 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7235 set_failure (ctx, "incoming phi arg type mismatch");
7238 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7239 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7244 /* Nullify empty phi instructions */
7245 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7246 GSList *l, *ins_list;
7248 ins_list = bblocks [bb->block_num].phi_nodes;
7250 for (l = ins_list; l; l = l->next) {
7251 PhiNode *node = (PhiNode*)l->data;
7252 MonoInst *phi = node->phi;
7253 LLVMValueRef phi_ins = values [phi->dreg];
7256 /* Already removed */
7259 if (LLVMCountIncoming (phi_ins) == 0) {
7260 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7261 LLVMInstructionEraseFromParent (phi_ins);
7262 values [phi->dreg] = NULL;
7267 /* Create the SWITCH statements for ENDFINALLY instructions */
7268 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7269 BBInfo *info = &bblocks [bb->block_num];
7271 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7272 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7273 GSList *bb_list = info->call_handler_return_bbs;
7275 for (i = 0; i < g_slist_length (bb_list); ++i)
7276 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7280 /* Initialize the method if needed */
7281 if (cfg->compile_aot && ctx->llvm_only) {
7282 // FIXME: Add more shared got entries
7283 ctx->builder = create_builder (ctx);
7284 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7286 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7288 // FIXME: beforefieldinit
7290 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7291 * in load_method ().
7293 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7295 * linkonce methods shouldn't have initialization,
7296 * because they might belong to assemblies which
7297 * haven't been loaded yet.
7299 g_assert (!ctx->is_linkonce);
7300 emit_init_method (ctx);
7302 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7306 if (cfg->llvm_only) {
7307 GHashTableIter iter;
7309 GSList *callers, *l, *l2;
7312 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7313 * We can't do this earlier, as it contains llvm instructions which can be
7314 * freed if compilation fails.
7315 * FIXME: Get rid of this when all methods can be llvm compiled.
7317 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7318 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7319 for (l = callers; l; l = l->next) {
7320 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7321 l2 = g_slist_prepend (l2, l->data);
7322 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7327 if (cfg->verbose_level > 1)
7328 mono_llvm_dump_value (method);
7330 if (cfg->compile_aot && !cfg->llvm_only)
7331 mark_as_used (ctx->module, method);
7333 if (!cfg->llvm_only) {
7334 LLVMValueRef md_args [16];
7335 LLVMValueRef md_node;
7338 if (cfg->compile_aot)
7339 method_index = mono_aot_get_method_index (cfg->orig_method);
7342 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7343 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7344 md_node = LLVMMDNode (md_args, 2);
7345 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7346 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7349 if (cfg->compile_aot) {
7350 /* Don't generate native code, keep the LLVM IR */
7351 if (cfg->verbose_level)
7352 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7354 #if LLVM_API_VERSION < 100
7355 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7356 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7357 g_assert (err == 0);
7360 //LLVMVerifyFunction(method, 0);
7361 #if LLVM_API_VERSION > 100
7362 MonoDomain *domain = mono_domain_get ();
7363 MonoJitDomainInfo *domain_info;
7364 int nvars = g_hash_table_size (ctx->jit_callees);
7365 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7366 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7367 GHashTableIter iter;
7373 * Compute the addresses of the LLVM globals pointing to the
7374 * methods called by the current method. Pass it to the trampoline
7375 * code so it can update them after their corresponding method was
7378 g_hash_table_iter_init (&iter, ctx->jit_callees);
7380 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7381 callee_vars [i ++] = var;
7383 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7385 decode_llvm_eh_info (ctx, eh_frame);
7387 mono_domain_lock (domain);
7388 domain_info = domain_jit_info (domain);
7389 if (!domain_info->llvm_jit_callees)
7390 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7391 g_hash_table_iter_init (&iter, ctx->jit_callees);
7393 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7394 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7395 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7396 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7399 mono_domain_unlock (domain);
7401 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7403 if (cfg->verbose_level > 1)
7404 mono_llvm_dump_value (ctx->lmethod);
7406 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7408 /* Set by emit_cb */
7409 g_assert (cfg->code_len);
7413 if (ctx->module->method_to_lmethod)
7414 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7415 if (ctx->module->idx_to_lmethod)
7416 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7418 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7419 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7423 * mono_llvm_create_vars:
7425 * Same as mono_arch_create_vars () for LLVM.
7428 mono_llvm_create_vars (MonoCompile *cfg)
7430 MonoMethodSignature *sig;
7432 sig = mono_method_signature (cfg->method);
7433 if (cfg->gsharedvt && cfg->llvm_only) {
7434 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7435 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7436 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7437 printf ("vret_addr = ");
7438 mono_print_ins (cfg->vret_addr);
7442 mono_arch_create_vars (cfg);
7447 * mono_llvm_emit_call:
7449 * Same as mono_arch_emit_call () for LLVM.
7452 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7455 MonoMethodSignature *sig;
7456 int i, n, stack_size;
7461 sig = call->signature;
7462 n = sig->param_count + sig->hasthis;
7464 call->cinfo = get_llvm_call_info (cfg, sig);
7466 if (cfg->disable_llvm)
7469 if (sig->call_convention == MONO_CALL_VARARG) {
7470 cfg->exception_message = g_strdup ("varargs");
7471 cfg->disable_llvm = TRUE;
7474 for (i = 0; i < n; ++i) {
7477 ainfo = call->cinfo->args + i;
7479 in = call->args [i];
7481 /* Simply remember the arguments */
7482 switch (ainfo->storage) {
7483 case LLVMArgNormal: {
7484 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7487 opcode = mono_type_to_regmove (cfg, t);
7488 if (opcode == OP_FMOVE) {
7489 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7490 ins->dreg = mono_alloc_freg (cfg);
7491 } else if (opcode == OP_LMOVE) {
7492 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7493 ins->dreg = mono_alloc_lreg (cfg);
7494 } else if (opcode == OP_RMOVE) {
7495 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7496 ins->dreg = mono_alloc_freg (cfg);
7498 MONO_INST_NEW (cfg, ins, OP_MOVE);
7499 ins->dreg = mono_alloc_ireg (cfg);
7501 ins->sreg1 = in->dreg;
7504 case LLVMArgVtypeByVal:
7505 case LLVMArgVtypeByRef:
7506 case LLVMArgVtypeInReg:
7507 case LLVMArgVtypeAsScalar:
7508 case LLVMArgAsIArgs:
7509 case LLVMArgAsFpArgs:
7510 case LLVMArgGsharedvtVariable:
7511 case LLVMArgGsharedvtFixed:
7512 case LLVMArgGsharedvtFixedVtype:
7513 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7514 ins->dreg = mono_alloc_ireg (cfg);
7515 ins->sreg1 = in->dreg;
7516 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7517 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7518 ins->inst_vtype = ainfo->type;
7519 ins->klass = mono_class_from_mono_type (ainfo->type);
7522 cfg->exception_message = g_strdup ("ainfo->storage");
7523 cfg->disable_llvm = TRUE;
7527 if (!cfg->disable_llvm) {
7528 MONO_ADD_INS (cfg->cbb, ins);
7529 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7534 static unsigned char*
7535 alloc_cb (LLVMValueRef function, int size)
7539 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7543 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7545 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7550 emitted_cb (LLVMValueRef function, void *start, void *end)
7554 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7556 cfg->code_len = (guint8*)end - (guint8*)start;
7560 exception_cb (void *data)
7563 MonoJitExceptionInfo *ei;
7564 guint32 ei_len, i, j, nested_len, nindex;
7565 gpointer *type_info;
7566 int this_reg, this_offset;
7568 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7572 * data points to a DWARF FDE structure, convert it to our unwind format and
7574 * An alternative would be to save it directly, and modify our unwinder to work
7577 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);
7578 if (cfg->verbose_level > 1)
7579 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7581 /* Count nested clauses */
7583 for (i = 0; i < ei_len; ++i) {
7584 gint32 cindex1 = *(gint32*)type_info [i];
7585 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7587 for (j = 0; j < cfg->header->num_clauses; ++j) {
7589 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7591 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7597 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7598 cfg->llvm_ex_info_len = ei_len + nested_len;
7599 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7600 /* Fill the rest of the information from the type info */
7601 for (i = 0; i < ei_len; ++i) {
7602 gint32 clause_index = *(gint32*)type_info [i];
7603 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7605 cfg->llvm_ex_info [i].flags = clause->flags;
7606 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7607 cfg->llvm_ex_info [i].clause_index = clause_index;
7611 * For nested clauses, the LLVM produced exception info associates the try interval with
7612 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7613 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7614 * and everything else from the nested clause.
7617 for (i = 0; i < ei_len; ++i) {
7618 gint32 cindex1 = *(gint32*)type_info [i];
7619 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7621 for (j = 0; j < cfg->header->num_clauses; ++j) {
7623 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7624 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7626 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7627 /* clause1 is the nested clause */
7628 nested_ei = &cfg->llvm_ex_info [i];
7629 nesting_ei = &cfg->llvm_ex_info [nindex];
7632 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7634 nesting_ei->flags = clause2->flags;
7635 nesting_ei->data.catch_class = clause2->data.catch_class;
7636 nesting_ei->clause_index = cindex2;
7640 g_assert (nindex == ei_len + nested_len);
7641 cfg->llvm_this_reg = this_reg;
7642 cfg->llvm_this_offset = this_offset;
7644 /* type_info [i] is cfg mempool allocated, no need to free it */
7650 #if LLVM_API_VERSION > 100
7652 * decode_llvm_eh_info:
7654 * Decode the EH table emitted by llvm in jit mode, and store
7655 * the result into cfg.
7658 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7660 MonoCompile *cfg = ctx->cfg;
7663 MonoLLVMFDEInfo info;
7664 MonoJitExceptionInfo *ei;
7665 guint8 *p = eh_frame;
7666 int version, fde_count, fde_offset;
7667 guint32 ei_len, i, nested_len;
7668 gpointer *type_info;
7672 * Decode the one element EH table emitted by the MonoException class
7676 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7679 g_assert (version == 3);
7682 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7684 fde_count = *(guint32*)p;
7688 g_assert (fde_count <= 2);
7690 /* The first entry is the real method */
7691 g_assert (table [0] == 1);
7692 fde_offset = table [1];
7693 table += fde_count * 2;
7695 cfg->code_len = table [0];
7696 fde_len = table [1] - fde_offset;
7699 fde = (guint8*)eh_frame + fde_offset;
7700 cie = (guint8*)table;
7702 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7704 cfg->encoded_unwind_ops = info.unw_info;
7705 cfg->encoded_unwind_ops_len = info.unw_info_len;
7706 if (cfg->verbose_level > 1)
7707 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7708 if (info.this_reg != -1) {
7709 cfg->llvm_this_reg = info.this_reg;
7710 cfg->llvm_this_offset = info.this_offset;
7714 ei_len = info.ex_info_len;
7715 type_info = info.type_info;
7717 // Nested clauses are currently disabled
7720 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7721 cfg->llvm_ex_info_len = ei_len + nested_len;
7722 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7723 /* Fill the rest of the information from the type info */
7724 for (i = 0; i < ei_len; ++i) {
7725 gint32 clause_index = *(gint32*)type_info [i];
7726 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7728 cfg->llvm_ex_info [i].flags = clause->flags;
7729 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7730 cfg->llvm_ex_info [i].clause_index = clause_index;
7736 dlsym_cb (const char *name, void **symbol)
7742 if (!strcmp (name, "__bzero")) {
7743 *symbol = (void*)bzero;
7745 current = mono_dl_open (NULL, 0, NULL);
7748 err = mono_dl_symbol (current, name, symbol);
7750 mono_dl_close (current);
7752 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7753 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7759 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7761 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7765 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7767 LLVMTypeRef param_types [4];
7769 param_types [0] = param_type1;
7770 param_types [1] = param_type2;
7772 AddFunc (module, name, ret_type, param_types, 2);
7778 INTRINS_SADD_OVF_I32,
7779 INTRINS_UADD_OVF_I32,
7780 INTRINS_SSUB_OVF_I32,
7781 INTRINS_USUB_OVF_I32,
7782 INTRINS_SMUL_OVF_I32,
7783 INTRINS_UMUL_OVF_I32,
7784 INTRINS_SADD_OVF_I64,
7785 INTRINS_UADD_OVF_I64,
7786 INTRINS_SSUB_OVF_I64,
7787 INTRINS_USUB_OVF_I64,
7788 INTRINS_SMUL_OVF_I64,
7789 INTRINS_UMUL_OVF_I64,
7796 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7797 INTRINS_SSE_PMOVMSKB,
7798 INTRINS_SSE_PSRLI_W,
7799 INTRINS_SSE_PSRAI_W,
7800 INTRINS_SSE_PSLLI_W,
7801 INTRINS_SSE_PSRLI_D,
7802 INTRINS_SSE_PSRAI_D,
7803 INTRINS_SSE_PSLLI_D,
7804 INTRINS_SSE_PSRLI_Q,
7805 INTRINS_SSE_PSLLI_Q,
7806 INTRINS_SSE_SQRT_PD,
7807 INTRINS_SSE_SQRT_PS,
7808 INTRINS_SSE_RSQRT_PS,
7810 INTRINS_SSE_CVTTPD2DQ,
7811 INTRINS_SSE_CVTTPS2DQ,
7812 INTRINS_SSE_CVTDQ2PD,
7813 INTRINS_SSE_CVTDQ2PS,
7814 INTRINS_SSE_CVTPD2DQ,
7815 INTRINS_SSE_CVTPS2DQ,
7816 INTRINS_SSE_CVTPD2PS,
7817 INTRINS_SSE_CVTPS2PD,
7820 INTRINS_SSE_PACKSSWB,
7821 INTRINS_SSE_PACKUSWB,
7822 INTRINS_SSE_PACKSSDW,
7823 INTRINS_SSE_PACKUSDW,
7828 INTRINS_SSE_ADDSUBPS,
7833 INTRINS_SSE_ADDSUBPD,
7836 INTRINS_SSE_PADDUSW,
7837 INTRINS_SSE_PSUBUSW,
7843 INTRINS_SSE_PADDUSB,
7844 INTRINS_SSE_PSUBUSB,
7856 static IntrinsicDesc intrinsics[] = {
7857 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7858 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7859 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7860 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7861 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7862 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7863 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7864 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7865 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7866 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7867 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7868 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7869 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7870 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7871 {INTRINS_SIN, "llvm.sin.f64"},
7872 {INTRINS_COS, "llvm.cos.f64"},
7873 {INTRINS_SQRT, "llvm.sqrt.f64"},
7874 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7875 {INTRINS_FABS, "fabs"},
7876 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7877 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7878 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7879 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7880 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7881 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7882 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7883 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7884 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7885 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7886 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7887 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7888 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7889 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7890 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7891 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7892 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7893 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7894 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7895 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7896 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7897 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7898 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7899 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7900 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7901 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7902 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7903 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7904 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7905 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7906 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7907 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7908 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7909 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7910 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7911 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7912 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7913 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7914 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7915 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7916 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7917 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7918 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7919 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7920 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7921 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7922 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7923 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7924 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7925 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7926 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7927 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7928 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7933 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7935 LLVMTypeRef ret_type = type_to_simd_type (type);
7936 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7940 add_intrinsic (LLVMModuleRef module, int id)
7943 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7944 LLVMTypeRef ret_type, arg_types [16];
7947 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7951 case INTRINS_MEMSET: {
7952 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7954 AddFunc (module, name, LLVMVoidType (), params, 5);
7957 case INTRINS_MEMCPY: {
7958 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7960 AddFunc (module, name, LLVMVoidType (), params, 5);
7963 case INTRINS_SADD_OVF_I32:
7964 case INTRINS_UADD_OVF_I32:
7965 case INTRINS_SSUB_OVF_I32:
7966 case INTRINS_USUB_OVF_I32:
7967 case INTRINS_SMUL_OVF_I32:
7968 case INTRINS_UMUL_OVF_I32: {
7969 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7970 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7971 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7973 AddFunc (module, name, ret_type, params, 2);
7976 case INTRINS_SADD_OVF_I64:
7977 case INTRINS_UADD_OVF_I64:
7978 case INTRINS_SSUB_OVF_I64:
7979 case INTRINS_USUB_OVF_I64:
7980 case INTRINS_SMUL_OVF_I64:
7981 case INTRINS_UMUL_OVF_I64: {
7982 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7983 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7984 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7986 AddFunc (module, name, ret_type, params, 2);
7992 case INTRINS_FABS: {
7993 LLVMTypeRef params [] = { LLVMDoubleType () };
7995 AddFunc (module, name, LLVMDoubleType (), params, 1);
7998 case INTRINS_EXPECT_I8:
7999 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8001 case INTRINS_EXPECT_I1:
8002 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8004 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8005 case INTRINS_SSE_PMOVMSKB:
8007 ret_type = LLVMInt32Type ();
8008 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8009 AddFunc (module, name, ret_type, arg_types, 1);
8011 case INTRINS_SSE_PSRLI_W:
8012 case INTRINS_SSE_PSRAI_W:
8013 case INTRINS_SSE_PSLLI_W:
8015 ret_type = type_to_simd_type (MONO_TYPE_I2);
8016 arg_types [0] = ret_type;
8017 arg_types [1] = LLVMInt32Type ();
8018 AddFunc (module, name, ret_type, arg_types, 2);
8020 case INTRINS_SSE_PSRLI_D:
8021 case INTRINS_SSE_PSRAI_D:
8022 case INTRINS_SSE_PSLLI_D:
8023 ret_type = type_to_simd_type (MONO_TYPE_I4);
8024 arg_types [0] = ret_type;
8025 arg_types [1] = LLVMInt32Type ();
8026 AddFunc (module, name, ret_type, arg_types, 2);
8028 case INTRINS_SSE_PSRLI_Q:
8029 case INTRINS_SSE_PSLLI_Q:
8030 ret_type = type_to_simd_type (MONO_TYPE_I8);
8031 arg_types [0] = ret_type;
8032 arg_types [1] = LLVMInt32Type ();
8033 AddFunc (module, name, ret_type, arg_types, 2);
8035 case INTRINS_SSE_SQRT_PD:
8037 ret_type = type_to_simd_type (MONO_TYPE_R8);
8038 arg_types [0] = ret_type;
8039 AddFunc (module, name, ret_type, arg_types, 1);
8041 case INTRINS_SSE_SQRT_PS:
8042 ret_type = type_to_simd_type (MONO_TYPE_R4);
8043 arg_types [0] = ret_type;
8044 AddFunc (module, name, ret_type, arg_types, 1);
8046 case INTRINS_SSE_RSQRT_PS:
8047 ret_type = type_to_simd_type (MONO_TYPE_R4);
8048 arg_types [0] = ret_type;
8049 AddFunc (module, name, ret_type, arg_types, 1);
8051 case INTRINS_SSE_RCP_PS:
8052 ret_type = type_to_simd_type (MONO_TYPE_R4);
8053 arg_types [0] = ret_type;
8054 AddFunc (module, name, ret_type, arg_types, 1);
8056 case INTRINS_SSE_CVTTPD2DQ:
8057 ret_type = type_to_simd_type (MONO_TYPE_I4);
8058 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8059 AddFunc (module, name, ret_type, arg_types, 1);
8061 case INTRINS_SSE_CVTTPS2DQ:
8062 ret_type = type_to_simd_type (MONO_TYPE_I4);
8063 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8064 AddFunc (module, name, ret_type, arg_types, 1);
8066 case INTRINS_SSE_CVTDQ2PD:
8067 /* Conversion ops */
8068 ret_type = type_to_simd_type (MONO_TYPE_R8);
8069 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8070 AddFunc (module, name, ret_type, arg_types, 1);
8072 case INTRINS_SSE_CVTDQ2PS:
8073 ret_type = type_to_simd_type (MONO_TYPE_R4);
8074 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8075 AddFunc (module, name, ret_type, arg_types, 1);
8077 case INTRINS_SSE_CVTPD2DQ:
8078 ret_type = type_to_simd_type (MONO_TYPE_I4);
8079 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8080 AddFunc (module, name, ret_type, arg_types, 1);
8082 case INTRINS_SSE_CVTPS2DQ:
8083 ret_type = type_to_simd_type (MONO_TYPE_I4);
8084 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8085 AddFunc (module, name, ret_type, arg_types, 1);
8087 case INTRINS_SSE_CVTPD2PS:
8088 ret_type = type_to_simd_type (MONO_TYPE_R4);
8089 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8090 AddFunc (module, name, ret_type, arg_types, 1);
8092 case INTRINS_SSE_CVTPS2PD:
8093 ret_type = type_to_simd_type (MONO_TYPE_R8);
8094 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8095 AddFunc (module, name, ret_type, arg_types, 1);
8097 case INTRINS_SSE_CMPPD:
8099 ret_type = type_to_simd_type (MONO_TYPE_R8);
8100 arg_types [0] = ret_type;
8101 arg_types [1] = ret_type;
8102 arg_types [2] = LLVMInt8Type ();
8103 AddFunc (module, name, ret_type, arg_types, 3);
8105 case INTRINS_SSE_CMPPS:
8106 ret_type = type_to_simd_type (MONO_TYPE_R4);
8107 arg_types [0] = ret_type;
8108 arg_types [1] = ret_type;
8109 arg_types [2] = LLVMInt8Type ();
8110 AddFunc (module, name, ret_type, arg_types, 3);
8112 case INTRINS_SSE_PACKSSWB:
8113 case INTRINS_SSE_PACKUSWB:
8114 case INTRINS_SSE_PACKSSDW:
8116 ret_type = type_to_simd_type (MONO_TYPE_I1);
8117 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8118 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8119 AddFunc (module, name, ret_type, arg_types, 2);
8121 case INTRINS_SSE_PACKUSDW:
8122 ret_type = type_to_simd_type (MONO_TYPE_I2);
8123 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8124 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8125 AddFunc (module, name, ret_type, arg_types, 2);
8127 /* SSE Binary ops */
8128 case INTRINS_SSE_PADDSW:
8129 case INTRINS_SSE_PSUBSW:
8130 case INTRINS_SSE_PADDUSW:
8131 case INTRINS_SSE_PSUBUSW:
8132 case INTRINS_SSE_PAVGW:
8133 case INTRINS_SSE_PMULHW:
8134 case INTRINS_SSE_PMULHU:
8135 add_sse_binary (module, name, MONO_TYPE_I2);
8137 case INTRINS_SSE_MINPS:
8138 case INTRINS_SSE_MAXPS:
8139 case INTRINS_SSE_HADDPS:
8140 case INTRINS_SSE_HSUBPS:
8141 case INTRINS_SSE_ADDSUBPS:
8142 add_sse_binary (module, name, MONO_TYPE_R4);
8144 case INTRINS_SSE_MINPD:
8145 case INTRINS_SSE_MAXPD:
8146 case INTRINS_SSE_HADDPD:
8147 case INTRINS_SSE_HSUBPD:
8148 case INTRINS_SSE_ADDSUBPD:
8149 add_sse_binary (module, name, MONO_TYPE_R8);
8151 case INTRINS_SE_PADDSB:
8152 case INTRINS_SSE_PSUBSB:
8153 case INTRINS_SSE_PADDUSB:
8154 case INTRINS_SSE_PSUBUSB:
8155 case INTRINS_SSE_PAVGB:
8156 add_sse_binary (module, name, MONO_TYPE_I1);
8158 case INTRINS_SSE_PAUSE:
8159 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8163 g_assert_not_reached ();
8169 get_intrinsic (EmitContext *ctx, const char *name)
8171 #if LLVM_API_VERSION > 100
8175 * Every method is emitted into its own module so
8176 * we can add intrinsics on demand.
8178 res = LLVMGetNamedFunction (ctx->lmodule, name);
8182 /* No locking needed */
8183 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8186 printf ("%s\n", name);
8187 g_assert (id != -1);
8188 add_intrinsic (ctx->lmodule, id);
8189 res = LLVMGetNamedFunction (ctx->lmodule, name);
8197 res = LLVMGetNamedFunction (ctx->lmodule, name);
8204 add_intrinsics (LLVMModuleRef module)
8208 /* Emit declarations of instrinsics */
8210 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8211 * type doesn't seem to do any locking.
8213 for (i = 0; i < INTRINS_NUM; ++i)
8214 add_intrinsic (module, i);
8218 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8220 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8223 /* Load/Store intrinsics */
8225 LLVMTypeRef arg_types [5];
8229 for (i = 1; i <= 8; i *= 2) {
8230 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8231 arg_types [1] = LLVMInt32Type ();
8232 arg_types [2] = LLVMInt1Type ();
8233 arg_types [3] = LLVMInt32Type ();
8234 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8235 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8237 arg_types [0] = LLVMIntType (i * 8);
8238 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8239 arg_types [2] = LLVMInt32Type ();
8240 arg_types [3] = LLVMInt1Type ();
8241 arg_types [4] = LLVMInt32Type ();
8242 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8243 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8249 add_types (MonoLLVMModule *module)
8251 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8255 mono_llvm_init (void)
8260 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8262 h = g_hash_table_new (NULL, NULL);
8263 for (i = 0; i < INTRINS_NUM; ++i)
8264 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8265 intrins_id_to_name = h;
8267 h = g_hash_table_new (g_str_hash, g_str_equal);
8268 for (i = 0; i < INTRINS_NUM; ++i)
8269 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8270 intrins_name_to_id = h;
8274 init_jit_module (MonoDomain *domain)
8276 MonoJitDomainInfo *dinfo;
8277 MonoLLVMModule *module;
8280 dinfo = domain_jit_info (domain);
8281 if (dinfo->llvm_module)
8284 mono_loader_lock ();
8286 if (dinfo->llvm_module) {
8287 mono_loader_unlock ();
8291 module = g_new0 (MonoLLVMModule, 1);
8293 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8294 module->lmodule = LLVMModuleCreateWithName (name);
8295 module->context = LLVMGetGlobalContext ();
8297 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8299 add_intrinsics (module->lmodule);
8302 module->llvm_types = g_hash_table_new (NULL, NULL);
8304 #if LLVM_API_VERSION < 100
8305 MonoJitICallInfo *info;
8307 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8309 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8312 mono_memory_barrier ();
8314 dinfo->llvm_module = module;
8316 mono_loader_unlock ();
8320 mono_llvm_cleanup (void)
8322 MonoLLVMModule *module = &aot_module;
8324 if (module->lmodule)
8325 LLVMDisposeModule (module->lmodule);
8327 if (module->context)
8328 LLVMContextDispose (module->context);
8332 mono_llvm_free_domain_info (MonoDomain *domain)
8334 MonoJitDomainInfo *info = domain_jit_info (domain);
8335 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8341 if (module->llvm_types)
8342 g_hash_table_destroy (module->llvm_types);
8344 mono_llvm_dispose_ee (module->mono_ee);
8346 if (module->bb_names) {
8347 for (i = 0; i < module->bb_names_len; ++i)
8348 g_free (module->bb_names [i]);
8349 g_free (module->bb_names);
8351 //LLVMDisposeModule (module->module);
8355 info->llvm_module = NULL;
8359 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8361 MonoLLVMModule *module = &aot_module;
8363 /* Delete previous module */
8364 if (module->plt_entries)
8365 g_hash_table_destroy (module->plt_entries);
8366 if (module->lmodule)
8367 LLVMDisposeModule (module->lmodule);
8369 memset (module, 0, sizeof (aot_module));
8371 module->lmodule = LLVMModuleCreateWithName ("aot");
8372 module->assembly = assembly;
8373 module->global_prefix = g_strdup (global_prefix);
8374 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8375 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8376 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8377 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8378 module->external_symbols = TRUE;
8379 module->emit_dwarf = emit_dwarf;
8380 module->static_link = static_link;
8381 module->llvm_only = llvm_only;
8382 /* The first few entries are reserved */
8383 module->max_got_offset = 16;
8384 module->context = LLVMContextCreate ();
8387 /* clang ignores our debug info because it has an invalid version */
8388 module->emit_dwarf = FALSE;
8390 add_intrinsics (module->lmodule);
8393 #if LLVM_API_VERSION > 100
8394 if (module->emit_dwarf) {
8395 char *dir, *build_info, *s, *cu_name;
8397 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8400 dir = g_strdup (".");
8401 build_info = mono_get_runtime_build_info ();
8402 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8403 cu_name = g_path_get_basename (assembly->image->name);
8404 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8406 g_free (build_info);
8413 * We couldn't compute the type of the LLVM global representing the got because
8414 * its size is only known after all the methods have been emitted. So create
8415 * a dummy variable, and replace all uses it with the real got variable when
8416 * its size is known in mono_llvm_emit_aot_module ().
8419 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8421 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8422 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8425 /* Add initialization array */
8427 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8429 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8430 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8434 emit_init_icall_wrappers (module);
8436 emit_llvm_code_start (module);
8438 /* Add a dummy personality function */
8439 if (!use_debug_personality) {
8440 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8441 LLVMSetLinkage (personality, LLVMExternalLinkage);
8442 mark_as_used (module, personality);
8445 /* Add a reference to the c++ exception we throw/catch */
8447 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8448 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8449 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8450 mono_llvm_set_is_constant (module->sentinel_exception);
8453 module->llvm_types = g_hash_table_new (NULL, NULL);
8454 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8455 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8456 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8457 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8458 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8459 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8460 module->method_to_callers = g_hash_table_new (NULL, NULL);
8464 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8467 LLVMValueRef res, *vals;
8469 vals = g_new0 (LLVMValueRef, nvalues);
8470 for (i = 0; i < nvalues; ++i)
8471 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8472 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8478 llvm_array_from_bytes (guint8 *values, int nvalues)
8481 LLVMValueRef res, *vals;
8483 vals = g_new0 (LLVMValueRef, nvalues);
8484 for (i = 0; i < nvalues; ++i)
8485 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8486 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8491 * mono_llvm_emit_aot_file_info:
8493 * Emit the MonoAotFileInfo structure.
8494 * Same as emit_aot_file_info () in aot-compiler.c.
8497 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8499 MonoLLVMModule *module = &aot_module;
8501 /* Save these for later */
8502 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8503 module->has_jitted_code = has_jitted_code;
8507 * mono_llvm_emit_aot_data:
8509 * Emit the binary data DATA pointed to by symbol SYMBOL.
8512 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8514 MonoLLVMModule *module = &aot_module;
8518 type = LLVMArrayType (LLVMInt8Type (), data_len);
8519 d = LLVMAddGlobal (module->lmodule, type, symbol);
8520 LLVMSetVisibility (d, LLVMHiddenVisibility);
8521 LLVMSetLinkage (d, LLVMInternalLinkage);
8522 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8523 mono_llvm_set_is_constant (d);
8526 /* Add a reference to a global defined in JITted code */
8528 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8533 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8534 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8540 emit_aot_file_info (MonoLLVMModule *module)
8542 LLVMTypeRef file_info_type;
8543 LLVMTypeRef *eltypes, eltype;
8544 LLVMValueRef info_var;
8545 LLVMValueRef *fields;
8546 int i, nfields, tindex;
8547 MonoAotFileInfo *info;
8548 LLVMModuleRef lmodule = module->lmodule;
8550 info = &module->aot_info;
8552 /* Create an LLVM type to represent MonoAotFileInfo */
8553 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8554 eltypes = g_new (LLVMTypeRef, nfields);
8556 eltypes [tindex ++] = LLVMInt32Type ();
8557 eltypes [tindex ++] = LLVMInt32Type ();
8559 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8560 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8562 for (i = 0; i < 15; ++i)
8563 eltypes [tindex ++] = LLVMInt32Type ();
8565 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8566 for (i = 0; i < 4; ++i)
8567 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8568 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8569 g_assert (tindex == nfields);
8570 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8571 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8573 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8574 if (module->static_link) {
8575 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8576 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8578 fields = g_new (LLVMValueRef, nfields);
8580 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8581 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8585 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8586 * for symbols defined in the .s file emitted by the aot compiler.
8588 eltype = eltypes [tindex];
8589 if (module->llvm_only)
8590 fields [tindex ++] = LLVMConstNull (eltype);
8592 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8593 fields [tindex ++] = module->got_var;
8594 /* llc defines this directly */
8595 if (!module->llvm_only) {
8596 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8597 fields [tindex ++] = LLVMConstNull (eltype);
8598 fields [tindex ++] = LLVMConstNull (eltype);
8600 fields [tindex ++] = LLVMConstNull (eltype);
8601 fields [tindex ++] = module->get_method;
8602 fields [tindex ++] = module->get_unbox_tramp;
8604 if (module->has_jitted_code) {
8605 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8606 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8608 fields [tindex ++] = LLVMConstNull (eltype);
8609 fields [tindex ++] = LLVMConstNull (eltype);
8611 if (!module->llvm_only)
8612 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8614 fields [tindex ++] = LLVMConstNull (eltype);
8615 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8616 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8617 fields [tindex ++] = LLVMConstNull (eltype);
8619 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8620 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8621 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8622 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8623 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8624 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8625 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8626 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8627 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8628 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8630 /* Not needed (mem_end) */
8631 fields [tindex ++] = LLVMConstNull (eltype);
8632 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8633 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8634 if (info->trampoline_size [0]) {
8635 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8636 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8637 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8638 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8640 fields [tindex ++] = LLVMConstNull (eltype);
8641 fields [tindex ++] = LLVMConstNull (eltype);
8642 fields [tindex ++] = LLVMConstNull (eltype);
8643 fields [tindex ++] = LLVMConstNull (eltype);
8645 if (module->static_link && !module->llvm_only)
8646 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8648 fields [tindex ++] = LLVMConstNull (eltype);
8649 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8650 if (!module->llvm_only) {
8651 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8652 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8653 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8654 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8655 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8656 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8658 fields [tindex ++] = LLVMConstNull (eltype);
8659 fields [tindex ++] = LLVMConstNull (eltype);
8660 fields [tindex ++] = LLVMConstNull (eltype);
8661 fields [tindex ++] = LLVMConstNull (eltype);
8662 fields [tindex ++] = LLVMConstNull (eltype);
8663 fields [tindex ++] = LLVMConstNull (eltype);
8666 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8667 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8670 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8671 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8672 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8673 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8674 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8675 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8676 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8677 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8678 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8679 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8680 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8681 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8682 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8683 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8684 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8686 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8687 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8688 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8689 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8690 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8692 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8693 g_assert (tindex == nfields);
8695 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8697 if (module->static_link) {
8701 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8702 /* Get rid of characters which cannot occur in symbols */
8704 for (p = s; *p; ++p) {
8705 if (!(isalnum (*p) || *p == '_'))
8708 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8710 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8711 LLVMSetLinkage (var, LLVMExternalLinkage);
8716 * Emit the aot module into the LLVM bitcode file FILENAME.
8719 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8721 LLVMTypeRef got_type, inited_type;
8722 LLVMValueRef real_got, real_inited;
8723 MonoLLVMModule *module = &aot_module;
8725 emit_llvm_code_end (module);
8728 * Create the real got variable and replace all uses of the dummy variable with
8731 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8732 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8733 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8734 if (module->external_symbols) {
8735 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8736 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8738 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8740 mono_llvm_replace_uses_of (module->got_var, real_got);
8742 mark_as_used (&aot_module, real_got);
8744 /* Delete the dummy got so it doesn't become a global */
8745 LLVMDeleteGlobal (module->got_var);
8746 module->got_var = real_got;
8749 * Same for the init_var
8751 if (module->llvm_only) {
8752 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8753 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8754 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8755 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8756 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8757 LLVMDeleteGlobal (module->inited_var);
8760 if (module->llvm_only) {
8761 emit_get_method (&aot_module);
8762 emit_get_unbox_tramp (&aot_module);
8765 emit_llvm_used (&aot_module);
8766 emit_dbg_info (&aot_module, filename, cu_name);
8767 emit_aot_file_info (&aot_module);
8770 * Replace GOT entries for directly callable methods with the methods themselves.
8771 * It would be easier to implement this by predefining all methods before compiling
8772 * their bodies, but that couldn't handle the case when a method fails to compile
8775 if (module->llvm_only) {
8776 GHashTableIter iter;
8778 GSList *callers, *l;
8780 g_hash_table_iter_init (&iter, module->method_to_callers);
8781 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8782 LLVMValueRef lmethod;
8784 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8787 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8789 for (l = callers; l; l = l->next) {
8790 LLVMValueRef caller = (LLVMValueRef)l->data;
8792 mono_llvm_replace_uses_of (caller, lmethod);
8798 /* Replace PLT entries for directly callable methods with the methods themselves */
8800 GHashTableIter iter;
8802 LLVMValueRef callee;
8804 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8805 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8806 if (mono_aot_is_direct_callable (ji)) {
8807 LLVMValueRef lmethod;
8809 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8810 /* The types might not match because the caller might pass an rgctx */
8811 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8812 mono_llvm_replace_uses_of (callee, lmethod);
8813 mono_aot_mark_unused_llvm_plt_entry (ji);
8823 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8824 printf ("%s\n", verifier_err);
8825 g_assert_not_reached ();
8830 LLVMWriteBitcodeToFile (module->lmodule, filename);
8835 md_string (const char *s)
8837 return LLVMMDString (s, strlen (s));
8840 /* Debugging support */
8843 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8845 LLVMModuleRef lmodule = module->lmodule;
8846 LLVMValueRef args [16], ver;
8849 * This can only be enabled when LLVM code is emitted into a separate object
8850 * file, since the AOT compiler also emits dwarf info,
8851 * and the abbrev indexes will not be correct since llvm has added its own
8854 if (!module->emit_dwarf)
8857 #if LLVM_API_VERSION > 100
8858 mono_llvm_di_builder_finalize (module->di_builder);
8860 LLVMValueRef cu_args [16], cu;
8862 char *build_info, *s, *dir;
8865 * Emit dwarf info in the form of LLVM metadata. There is some
8866 * out-of-date documentation at:
8867 * http://llvm.org/docs/SourceLevelDebugging.html
8868 * but most of this was gathered from the llvm and
8873 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8874 /* CU name/compilation dir */
8875 dir = g_path_get_dirname (filename);
8876 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8877 args [1] = LLVMMDString (dir, strlen (dir));
8878 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8881 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8883 build_info = mono_get_runtime_build_info ();
8884 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8885 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8886 g_free (build_info);
8888 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8890 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8891 /* Runtime version */
8892 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8894 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8895 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8897 if (module->subprogram_mds) {
8901 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8902 for (i = 0; i < module->subprogram_mds->len; ++i)
8903 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8904 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8906 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8909 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8910 /* Imported modules */
8911 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8913 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8914 /* DebugEmissionKind = FullDebug */
8915 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8916 cu = LLVMMDNode (cu_args, n_cuargs);
8917 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8920 #if LLVM_API_VERSION > 100
8921 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8922 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8923 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8924 ver = LLVMMDNode (args, 3);
8925 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8927 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8928 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8929 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8930 ver = LLVMMDNode (args, 3);
8931 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8933 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8934 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8935 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8936 ver = LLVMMDNode (args, 3);
8937 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8939 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8940 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8941 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8942 ver = LLVMMDNode (args, 3);
8943 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8948 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8950 MonoLLVMModule *module = ctx->module;
8951 MonoDebugMethodInfo *minfo = ctx->minfo;
8952 char *source_file, *dir, *filename;
8953 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8954 MonoSymSeqPoint *sym_seq_points;
8960 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8962 source_file = g_strdup ("<unknown>");
8963 dir = g_path_get_dirname (source_file);
8964 filename = g_path_get_basename (source_file);
8966 #if LLVM_API_VERSION > 100
8967 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);
8970 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8971 args [0] = md_string (filename);
8972 args [1] = md_string (dir);
8973 ctx_args [1] = LLVMMDNode (args, 2);
8974 ctx_md = LLVMMDNode (ctx_args, 2);
8976 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8977 type_args [1] = NULL;
8978 type_args [2] = NULL;
8979 type_args [3] = LLVMMDString ("", 0);
8980 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8981 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8982 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8983 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8984 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8985 type_args [9] = NULL;
8986 type_args [10] = NULL;
8987 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8988 type_args [12] = NULL;
8989 type_args [13] = NULL;
8990 type_args [14] = NULL;
8991 type_md = LLVMMDNode (type_args, 14);
8993 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8994 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8995 /* Source directory + file pair */
8996 args [0] = md_string (filename);
8997 args [1] = md_string (dir);
8998 md_args [1] = LLVMMDNode (args ,2);
8999 md_args [2] = ctx_md;
9000 md_args [3] = md_string (cfg->method->name);
9001 md_args [4] = md_string (name);
9002 md_args [5] = md_string (name);
9005 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9007 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9009 md_args [7] = type_md;
9011 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9013 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9015 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9016 /* Index into a virtual function */
9017 md_args [11] = NULL;
9018 md_args [12] = NULL;
9020 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9022 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9023 /* Pointer to LLVM function */
9024 md_args [15] = method;
9025 /* Function template parameter */
9026 md_args [16] = NULL;
9027 /* Function declaration descriptor */
9028 md_args [17] = NULL;
9029 /* List of function variables */
9030 md_args [18] = LLVMMDNode (args, 0);
9032 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9033 md = LLVMMDNode (md_args, 20);
9035 if (!module->subprogram_mds)
9036 module->subprogram_mds = g_ptr_array_new ();
9037 g_ptr_array_add (module->subprogram_mds, md);
9041 g_free (source_file);
9042 g_free (sym_seq_points);
9048 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9050 MonoCompile *cfg = ctx->cfg;
9052 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9053 MonoDebugSourceLocation *loc;
9054 LLVMValueRef loc_md;
9056 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9059 #if LLVM_API_VERSION > 100
9060 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9061 mono_llvm_di_set_location (builder, loc_md);
9063 LLVMValueRef md_args [16];
9067 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9068 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9069 md_args [nmd_args ++] = ctx->dbg_md;
9070 md_args [nmd_args ++] = NULL;
9071 loc_md = LLVMMDNode (md_args, nmd_args);
9072 LLVMSetCurrentDebugLocation (builder, loc_md);
9074 mono_debug_symfile_free_location (loc);
9080 default_mono_llvm_unhandled_exception (void)
9082 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9083 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9085 mono_unhandled_exception (target);
9086 mono_invoke_unhandled_exception_hook (target);
9087 g_assert_not_reached ();
9092 - Emit LLVM IR from the mono IR using the LLVM C API.
9093 - The original arch specific code remains, so we can fall back to it if we run
9094 into something we can't handle.
9098 A partial list of issues:
9099 - Handling of opcodes which can throw exceptions.
9101 In the mono JIT, these are implemented using code like this:
9108 push throw_pos - method
9109 call <exception trampoline>
9111 The problematic part is push throw_pos - method, which cannot be represented
9112 in the LLVM IR, since it does not support label values.
9113 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9114 be implemented in JIT mode ?
9115 -> a possible but slower implementation would use the normal exception
9116 throwing code but it would need to control the placement of the throw code
9117 (it needs to be exactly after the compare+branch).
9118 -> perhaps add a PC offset intrinsics ?
9120 - efficient implementation of .ovf opcodes.
9122 These are currently implemented as:
9123 <ins which sets the condition codes>
9126 Some overflow opcodes are now supported by LLVM SVN.
9128 - exception handling, unwinding.
9129 - SSA is disabled for methods with exception handlers
9130 - How to obtain unwind info for LLVM compiled methods ?
9131 -> this is now solved by converting the unwind info generated by LLVM
9133 - LLVM uses the c++ exception handling framework, while we use our home grown
9134 code, and couldn't use the c++ one:
9135 - its not supported under VC++, other exotic platforms.
9136 - it might be impossible to support filter clauses with it.
9140 The trampolines need a predictable call sequence, since they need to disasm
9141 the calling code to obtain register numbers / offsets.
9143 LLVM currently generates this code in non-JIT mode:
9144 mov -0x98(%rax),%eax
9146 Here, the vtable pointer is lost.
9147 -> solution: use one vtable trampoline per class.
9149 - passing/receiving the IMT pointer/RGCTX.
9150 -> solution: pass them as normal arguments ?
9154 LLVM does not allow the specification of argument registers etc. This means
9155 that all calls are made according to the platform ABI.
9157 - passing/receiving vtypes.
9159 Vtypes passed/received in registers are handled by the front end by using
9160 a signature with scalar arguments, and loading the parts of the vtype into those
9163 Vtypes passed on the stack are handled using the 'byval' attribute.
9167 Supported though alloca, we need to emit the load/store code.
9171 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9172 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9173 This is made easier because the IR is already in SSA form.
9174 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9175 types are frequently used incorrectly.
9180 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9181 it with the file containing the methods emitted by the JIT and the AOT data
9185 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9186 * - each bblock should end with a branch
9187 * - setting the return value, making cfg->ret non-volatile
9188 * - avoid some transformations in the JIT which make it harder for us to generate
9190 * - use pointer types to help optimizations.