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
;
152 LLVMTypeRef method_type
;
153 LLVMBasicBlockRef init_bb
, inited_bb
;
155 gboolean
*unreachable
;
157 gboolean has_got_access
;
158 gboolean is_linkonce
;
159 int this_arg_pindex
, rgctx_arg_pindex
;
160 LLVMValueRef imt_rgctx_loc
;
161 GHashTable
*llvm_types
;
163 MonoDebugMethodInfo
*minfo
;
165 /* For every clause, the clauses it is nested in */
168 GHashTable
*exc_meta
;
169 GHashTable
*method_to_callers
;
170 GPtrArray
*phi_values
;
171 GPtrArray
*bblock_list
;
173 GHashTable
*jit_callees
;
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 if (bb
== cfg
->bb_init
)
1745 // Since they're sorted by nesting we just need
1746 // the first one that the bb is a member of
1747 for (int i
= 0; i
< cfg
->header
->num_clauses
; i
++) {
1748 MonoExceptionClause
*curr
= &cfg
->header
->clauses
[i
];
1750 if (MONO_OFFSET_IN_CLAUSE (curr
, bb
->real_offset
))
1758 set_metadata_flag (LLVMValueRef v
, const char *flag_name
)
1760 LLVMValueRef md_arg
;
1763 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1764 md_arg
= LLVMMDString ("mono", 4);
1765 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1769 set_invariant_load_flag (LLVMValueRef v
)
1771 LLVMValueRef md_arg
;
1773 const char *flag_name
;
1775 // FIXME: Cache this
1776 flag_name
= "invariant.load";
1777 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1778 md_arg
= LLVMMDString ("<index>", strlen ("<index>"));
1779 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1785 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1789 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
1791 MonoCompile
*cfg
= ctx
->cfg
;
1792 LLVMValueRef lcall
= NULL
;
1793 LLVMBuilderRef builder
= *builder_ref
;
1794 MonoExceptionClause
*clause
;
1796 if (ctx
->llvm_only
) {
1797 clause
= get_most_deep_clause (cfg
, ctx
, bb
);
1800 g_assert (clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| clause
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1803 * Have to use an invoke instead of a call, branching to the
1804 * handler bblock of the clause containing this bblock.
1806 intptr_t key
= CLAUSE_END(clause
);
1808 LLVMBasicBlockRef lpad_bb
= (LLVMBasicBlockRef
)g_hash_table_lookup (ctx
->exc_meta
, (gconstpointer
)key
);
1810 // FIXME: Find the one that has the lowest end bound for the right start address
1811 // FIXME: Finally + nesting
1814 LLVMBasicBlockRef noex_bb
= gen_bb (ctx
, "CALL_NOEX_BB");
1817 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, lpad_bb
, "");
1819 builder
= ctx
->builder
= create_builder (ctx
);
1820 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1822 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1826 int clause_index
= get_handler_clause (cfg
, bb
);
1828 if (clause_index
!= -1) {
1829 MonoMethodHeader
*header
= cfg
->header
;
1830 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
1831 MonoBasicBlock
*tblock
;
1832 LLVMBasicBlockRef ex_bb
, noex_bb
;
1835 * Have to use an invoke instead of a call, branching to the
1836 * handler bblock of the clause containing this bblock.
1839 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1841 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
1844 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
1846 ex_bb
= get_bb (ctx
, tblock
);
1848 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1851 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
1853 builder
= ctx
->builder
= create_builder (ctx
);
1854 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1856 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1861 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
1862 ctx
->builder
= builder
;
1866 *builder_ref
= ctx
->builder
;
1872 emit_load_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, LLVMValueRef base
, const char *name
, gboolean is_faulting
, BarrierKind barrier
)
1874 const char *intrins_name
;
1875 LLVMValueRef args
[16], res
;
1876 LLVMTypeRef addr_type
;
1877 gboolean use_intrinsics
= TRUE
;
1879 #if LLVM_API_VERSION > 100
1880 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
1881 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1884 cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
1885 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
1886 *builder_ref
= ctx
->builder
;
1887 use_intrinsics
= FALSE
;
1891 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
1892 LLVMAtomicOrdering ordering
;
1895 case LLVM_BARRIER_NONE
:
1896 ordering
= LLVMAtomicOrderingNotAtomic
;
1898 case LLVM_BARRIER_ACQ
:
1899 ordering
= LLVMAtomicOrderingAcquire
;
1901 case LLVM_BARRIER_SEQ
:
1902 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
1905 g_assert_not_reached ();
1910 * We handle loads which can fault by calling a mono specific intrinsic
1911 * using an invoke, so they are handled properly inside try blocks.
1912 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1913 * are marked with IntrReadArgMem.
1917 intrins_name
= "llvm.mono.load.i8.p0i8";
1920 intrins_name
= "llvm.mono.load.i16.p0i16";
1923 intrins_name
= "llvm.mono.load.i32.p0i32";
1926 intrins_name
= "llvm.mono.load.i64.p0i64";
1929 g_assert_not_reached ();
1932 addr_type
= LLVMTypeOf (addr
);
1933 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0) || addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1934 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1937 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1938 args
[2] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1939 args
[3] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
1940 res
= emit_call (ctx
, bb
, builder_ref
, get_intrinsic (ctx
, intrins_name
), args
, 4);
1942 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0))
1943 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMDoubleType (), "");
1944 else if (addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1945 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMFloatType (), "");
1952 * We emit volatile loads for loads which can fault, because otherwise
1953 * LLVM will generate invalid code when encountering a load from a
1956 if (barrier
!= LLVM_BARRIER_NONE
)
1957 res
= mono_llvm_build_atomic_load (*builder_ref
, addr
, name
, is_faulting
, size
, barrier
);
1959 res
= mono_llvm_build_load (*builder_ref
, addr
, name
, is_faulting
);
1961 /* Mark it with a custom metadata */
1964 set_metadata_flag (res, "mono.faulting.load");
1972 emit_load (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, const char *name
, gboolean is_faulting
)
1974 return emit_load_general (ctx
, bb
, builder_ref
, size
, addr
, addr
, name
, is_faulting
, LLVM_BARRIER_NONE
);
1978 emit_store_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
, BarrierKind barrier
)
1980 const char *intrins_name
;
1981 LLVMValueRef args
[16];
1982 gboolean use_intrinsics
= TRUE
;
1984 #if LLVM_API_VERSION > 100
1985 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
1986 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1987 LLVMValueRef cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
1988 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
1989 *builder_ref
= ctx
->builder
;
1990 use_intrinsics
= FALSE
;
1994 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
1995 LLVMAtomicOrdering ordering
;
1998 case LLVM_BARRIER_NONE
:
1999 ordering
= LLVMAtomicOrderingNotAtomic
;
2001 case LLVM_BARRIER_REL
:
2002 ordering
= LLVMAtomicOrderingRelease
;
2004 case LLVM_BARRIER_SEQ
:
2005 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
2008 g_assert_not_reached ();
2014 intrins_name
= "llvm.mono.store.i8.p0i8";
2017 intrins_name
= "llvm.mono.store.i16.p0i16";
2020 intrins_name
= "llvm.mono.store.i32.p0i32";
2023 intrins_name
= "llvm.mono.store.i64.p0i64";
2026 g_assert_not_reached ();
2029 if (LLVMTypeOf (value
) == LLVMDoubleType () || LLVMTypeOf (value
) == LLVMFloatType ()) {
2030 value
= LLVMBuildBitCast (*builder_ref
, value
, LLVMIntType (size
* 8), "");
2031 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
2036 args
[2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2037 args
[3] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
2038 args
[4] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
2039 emit_call (ctx
, bb
, builder_ref
, get_intrinsic (ctx
, intrins_name
), args
, 5);
2041 if (barrier
!= LLVM_BARRIER_NONE
)
2042 mono_llvm_build_aligned_store (*builder_ref
, value
, addr
, barrier
, size
);
2044 mono_llvm_build_store (*builder_ref
, value
, addr
, is_faulting
, barrier
);
2049 emit_store (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
)
2051 emit_store_general (ctx
, bb
, builder_ref
, size
, value
, addr
, base
, is_faulting
, LLVM_BARRIER_NONE
);
2055 * emit_cond_system_exception:
2057 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2058 * Might set the ctx exception.
2061 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
2063 LLVMBasicBlockRef ex_bb
, ex2_bb
= NULL
, noex_bb
;
2064 LLVMBuilderRef builder
;
2065 MonoClass
*exc_class
;
2066 LLVMValueRef args
[2];
2067 LLVMValueRef callee
;
2068 gboolean no_pc
= FALSE
;
2070 if (IS_TARGET_AMD64
)
2071 /* Some platforms don't require the pc argument */
2074 ex_bb
= gen_bb (ctx
, "EX_BB");
2076 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2077 noex_bb
= gen_bb (ctx
, "NOEX_BB");
2079 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
2081 exc_class
= mono_class_load_from_name (mono_get_corlib (), "System", exc_type
);
2083 /* Emit exception throwing code */
2084 ctx
->builder
= builder
= create_builder (ctx
);
2085 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
2087 if (ctx
->cfg
->llvm_only
) {
2088 static LLVMTypeRef sig
;
2091 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2092 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, "mono_llvm_throw_corlib_exception");
2094 LLVMBuildBr (builder
, ex2_bb
);
2096 ctx
->builder
= builder
= create_builder (ctx
);
2097 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2099 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
2100 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2101 LLVMBuildUnreachable (builder
);
2103 ctx
->builder
= builder
= create_builder (ctx
);
2104 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2106 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2112 callee
= ctx
->module
->throw_corlib_exception
;
2115 const char *icall_name
;
2118 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2120 sig
= LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE
);
2121 icall_name
= "llvm_throw_corlib_exception_abs_trampoline";
2123 if (ctx
->cfg
->compile_aot
) {
2124 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
2127 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2128 * - On x86, LLVM generated code doesn't push the arguments
2129 * - The trampoline takes the throw address as an arguments, not a pc offset.
2131 gpointer target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
2132 callee
= emit_jit_callee (ctx
, "llvm_throw_corlib_exception_trampoline", sig
, target
);
2134 #if LLVM_API_VERSION > 100
2136 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2137 * added by emit_jit_callee ().
2139 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2140 LLVMBuildBr (builder
, ex2_bb
);
2143 ctx
->builder
= builder
= create_builder (ctx
);
2144 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2146 mono_memory_barrier ();
2147 ctx
->module
->throw_corlib_exception
= callee
;
2152 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
2155 * The LLVM mono branch contains changes so a block address can be passed as an
2156 * argument to a call.
2159 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2161 args
[1] = LLVMBlockAddress (ctx
->lmethod
, ex_bb
);
2162 emit_call (ctx
, bb
, &builder
, callee
, args
, 2);
2165 LLVMBuildUnreachable (builder
);
2167 ctx
->builder
= builder
= create_builder (ctx
);
2168 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2170 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2177 * emit_args_to_vtype:
2179 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2182 emit_args_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
)
2184 int j
, size
, nslots
;
2186 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
2188 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2189 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2192 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2193 nslots
= ainfo
->nslots
;
2197 for (j
= 0; j
< nslots
; ++j
) {
2198 LLVMValueRef index
[2], addr
, daddr
;
2199 int part_size
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
2200 LLVMTypeRef part_type
;
2202 while (part_size
!= 1 && part_size
!= 2 && part_size
!= 4 && part_size
< 8)
2205 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2208 switch (ainfo
->pair_storage
[j
]) {
2209 case LLVMArgInIReg
: {
2210 part_type
= LLVMIntType (part_size
* 8);
2211 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2212 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
2213 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2215 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2216 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2217 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2219 LLVMBuildStore (builder
, convert (ctx
, args
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
2222 case LLVMArgInFPReg
: {
2223 LLVMTypeRef arg_type
;
2225 if (ainfo
->esize
== 8)
2226 arg_type
= LLVMDoubleType ();
2228 arg_type
= LLVMFloatType ();
2230 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2231 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2232 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2233 LLVMBuildStore (builder
, args
[j
], addr
);
2239 g_assert_not_reached ();
2242 size
-= sizeof (gpointer
);
2247 * emit_vtype_to_args:
2249 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2250 * into ARGS, and the number of arguments into NARGS.
2253 emit_vtype_to_args (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
, guint32
*nargs
)
2256 int j
, size
, nslots
;
2257 LLVMTypeRef arg_type
;
2259 size
= get_vtype_size (t
);
2261 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
)))
2262 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2264 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2265 nslots
= ainfo
->nslots
;
2268 for (j
= 0; j
< nslots
; ++j
) {
2269 LLVMValueRef index
[2], addr
, daddr
;
2270 int partsize
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
2272 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2275 switch (ainfo
->pair_storage
[j
]) {
2277 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2278 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
2279 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2281 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2282 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2283 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2285 args
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
2287 case LLVMArgInFPReg
:
2288 if (ainfo
->esize
== 8)
2289 arg_type
= LLVMDoubleType ();
2291 arg_type
= LLVMFloatType ();
2292 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2293 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2294 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2295 args
[pindex
++] = LLVMBuildLoad (builder
, addr
, "");
2300 g_assert_not_reached ();
2302 size
-= sizeof (gpointer
);
2309 build_alloca_llvm_type_name (EmitContext
*ctx
, LLVMTypeRef t
, int align
, const char *name
)
2312 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2313 * get executed every time control reaches them.
2315 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
2317 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, t
, NULL
, align
, name
);
2318 return ctx
->last_alloca
;
2322 build_alloca_llvm_type (EmitContext
*ctx
, LLVMTypeRef t
, int align
)
2324 return build_alloca_llvm_type_name (ctx
, t
, align
, "");
2328 build_alloca (EmitContext
*ctx
, MonoType
*t
)
2330 MonoClass
*k
= mono_class_from_mono_type (t
);
2333 g_assert (!mini_is_gsharedvt_variable_type (t
));
2335 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
2338 align
= mono_class_min_align (k
);
2340 /* Sometimes align is not a power of 2 */
2341 while (mono_is_power_of_two (align
) == -1)
2344 return build_alloca_llvm_type (ctx
, type_to_llvm_type (ctx
, t
), align
);
2348 emit_gsharedvt_ldaddr (EmitContext
*ctx
, int vreg
)
2352 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2354 MonoCompile
*cfg
= ctx
->cfg
;
2355 LLVMBuilderRef builder
= ctx
->builder
;
2356 LLVMValueRef offset
, offset_var
;
2357 LLVMValueRef info_var
= ctx
->values
[cfg
->gsharedvt_info_var
->dreg
];
2358 LLVMValueRef locals_var
= ctx
->values
[cfg
->gsharedvt_locals_var
->dreg
];
2362 g_assert (info_var
);
2363 g_assert (locals_var
);
2365 int idx
= cfg
->gsharedvt_vreg_to_idx
[vreg
] - 1;
2367 offset
= LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo
, entries
) + (idx
* sizeof (gpointer
)), FALSE
);
2368 ptr
= LLVMBuildAdd (builder
, convert (ctx
, info_var
, IntPtrType ()), convert (ctx
, offset
, IntPtrType ()), "");
2370 name
= g_strdup_printf ("gsharedvt_local_%d_offset", vreg
);
2371 offset_var
= LLVMBuildLoad (builder
, convert (ctx
, ptr
, LLVMPointerType (LLVMInt32Type (), 0)), name
);
2373 return LLVMBuildAdd (builder
, convert (ctx
, locals_var
, IntPtrType ()), convert (ctx
, offset_var
, IntPtrType ()), "");
2377 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2380 mark_as_used (MonoLLVMModule
*module
, LLVMValueRef global
)
2383 module
->used
= g_ptr_array_sized_new (16);
2384 g_ptr_array_add (module
->used
, global
);
2388 emit_llvm_used (MonoLLVMModule
*module
)
2390 LLVMModuleRef lmodule
= module
->lmodule
;
2391 LLVMTypeRef used_type
;
2392 LLVMValueRef used
, *used_elem
;
2398 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module
->used
->len
);
2399 used
= LLVMAddGlobal (lmodule
, used_type
, "llvm.used");
2400 used_elem
= g_new0 (LLVMValueRef
, module
->used
->len
);
2401 for (i
= 0; i
< module
->used
->len
; ++i
)
2402 used_elem
[i
] = LLVMConstBitCast ((LLVMValueRef
)g_ptr_array_index (module
->used
, i
), LLVMPointerType (LLVMInt8Type (), 0));
2403 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem
, module
->used
->len
));
2404 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
2405 LLVMSetSection (used
, "llvm.metadata");
2411 * Emit a function mapping method indexes to their code
2414 emit_get_method (MonoLLVMModule
*module
)
2416 LLVMModuleRef lmodule
= module
->lmodule
;
2417 LLVMValueRef func
, switch_ins
, m
;
2418 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
, code_start_bb
, code_end_bb
;
2419 LLVMBasicBlockRef
*bbs
;
2421 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2426 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2427 * but generating code seems safer.
2429 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2430 func
= LLVMAddFunction (lmodule
, module
->get_method_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2431 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2432 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2433 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2434 module
->get_method
= func
;
2436 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2439 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2440 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2441 * then we will have to find another solution.
2444 name
= g_strdup_printf ("BB_CODE_START");
2445 code_start_bb
= LLVMAppendBasicBlock (func
, name
);
2447 LLVMPositionBuilderAtEnd (builder
, code_start_bb
);
2448 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_start
, rtype
, ""));
2450 name
= g_strdup_printf ("BB_CODE_END");
2451 code_end_bb
= LLVMAppendBasicBlock (func
, name
);
2453 LLVMPositionBuilderAtEnd (builder
, code_end_bb
);
2454 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_end
, rtype
, ""));
2456 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2457 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2458 name
= g_strdup_printf ("BB_%d", i
);
2459 bb
= LLVMAppendBasicBlock (func
, name
);
2463 LLVMPositionBuilderAtEnd (builder
, bb
);
2465 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_lmethod
, GINT_TO_POINTER (i
));
2467 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2469 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2472 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2473 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2474 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2476 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2478 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2479 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -1, FALSE
), code_start_bb
);
2480 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -2, FALSE
), code_end_bb
);
2481 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2482 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2485 mark_as_used (module
, func
);
2487 LLVMDisposeBuilder (builder
);
2491 * emit_get_unbox_tramp:
2493 * Emit a function mapping method indexes to their unbox trampoline
2496 emit_get_unbox_tramp (MonoLLVMModule
*module
)
2498 LLVMModuleRef lmodule
= module
->lmodule
;
2499 LLVMValueRef func
, switch_ins
, m
;
2500 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
;
2501 LLVMBasicBlockRef
*bbs
;
2503 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2507 /* Similar to emit_get_method () */
2509 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2510 func
= LLVMAddFunction (lmodule
, module
->get_unbox_tramp_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2511 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2512 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2513 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2514 module
->get_unbox_tramp
= func
;
2516 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2518 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2519 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2520 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2524 name
= g_strdup_printf ("BB_%d", i
);
2525 bb
= LLVMAppendBasicBlock (func
, name
);
2529 LLVMPositionBuilderAtEnd (builder
, bb
);
2531 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2534 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2535 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2536 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2538 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2540 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2541 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2542 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2546 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2549 mark_as_used (module
, func
);
2550 LLVMDisposeBuilder (builder
);
2553 /* Add a function to mark the beginning of LLVM code */
2555 emit_llvm_code_start (MonoLLVMModule
*module
)
2557 LLVMModuleRef lmodule
= module
->lmodule
;
2559 LLVMBasicBlockRef entry_bb
;
2560 LLVMBuilderRef builder
;
2562 func
= LLVMAddFunction (lmodule
, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
2563 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2564 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2565 module
->code_start
= func
;
2566 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2567 builder
= LLVMCreateBuilder ();
2568 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2569 LLVMBuildRetVoid (builder
);
2570 LLVMDisposeBuilder (builder
);
2574 emit_init_icall_wrapper (MonoLLVMModule
*module
, const char *name
, const char *icall_name
, int subtype
)
2576 LLVMModuleRef lmodule
= module
->lmodule
;
2577 LLVMValueRef func
, indexes
[2], got_entry_addr
, args
[16], callee
;
2578 LLVMBasicBlockRef entry_bb
;
2579 LLVMBuilderRef builder
;
2586 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
));
2587 sig
= LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE
);
2592 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE
));
2593 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE
);
2596 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE
));
2597 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE
);
2600 g_assert_not_reached ();
2602 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2603 LLVMAddFunctionAttr (func
, LLVMNoInlineAttribute
);
2604 mono_llvm_set_preserveall_cc (func
);
2605 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2606 builder
= LLVMCreateBuilder ();
2607 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2610 ji
= g_new0 (MonoJumpInfo
, 1);
2611 ji
->type
= MONO_PATCH_INFO_AOT_MODULE
;
2612 ji
= mono_aot_patch_info_dup (ji
);
2613 got_offset
= mono_aot_get_got_offset (ji
);
2614 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
2615 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2616 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
2617 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
2618 args
[0] = LLVMBuildPtrToInt (builder
, LLVMBuildLoad (builder
, got_entry_addr
, ""), IntPtrType (), "");
2619 args
[1] = LLVMGetParam (func
, 0);
2621 args
[2] = LLVMGetParam (func
, 1);
2623 ji
= g_new0 (MonoJumpInfo
, 1);
2624 ji
->type
= MONO_PATCH_INFO_INTERNAL_METHOD
;
2625 ji
->data
.name
= icall_name
;
2626 ji
= mono_aot_patch_info_dup (ji
);
2627 got_offset
= mono_aot_get_got_offset (ji
);
2628 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
2629 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2630 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
2631 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
2632 callee
= LLVMBuildLoad (builder
, got_entry_addr
, "");
2633 callee
= LLVMBuildBitCast (builder
, callee
, LLVMPointerType (sig
, 0), "");
2634 LLVMBuildCall (builder
, callee
, args
, LLVMCountParamTypes (sig
), "");
2636 // Set the inited flag
2637 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2638 indexes
[1] = LLVMGetParam (func
, 0);
2639 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt8Type (), 1, FALSE
), LLVMBuildGEP (builder
, module
->inited_var
, indexes
, 2, ""));
2641 LLVMBuildRetVoid (builder
);
2643 LLVMVerifyFunction(func
, LLVMAbortProcessAction
);
2644 LLVMDisposeBuilder (builder
);
2649 * Emit wrappers around the C icalls used to initialize llvm methods, to
2650 * make the calling code smaller and to enable usage of the llvm
2651 * PreserveAll calling convention.
2654 emit_init_icall_wrappers (MonoLLVMModule
*module
)
2656 module
->init_method
= emit_init_icall_wrapper (module
, "init_method", "mono_aot_init_llvm_method", 0);
2657 module
->init_method_gshared_mrgctx
= emit_init_icall_wrapper (module
, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2658 module
->init_method_gshared_this
= emit_init_icall_wrapper (module
, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2659 module
->init_method_gshared_vtable
= emit_init_icall_wrapper (module
, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2663 emit_llvm_code_end (MonoLLVMModule
*module
)
2665 LLVMModuleRef lmodule
= module
->lmodule
;
2667 LLVMBasicBlockRef entry_bb
;
2668 LLVMBuilderRef builder
;
2670 func
= LLVMAddFunction (lmodule
, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
2671 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2672 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2673 module
->code_end
= func
;
2674 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2675 builder
= LLVMCreateBuilder ();
2676 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2677 LLVMBuildRetVoid (builder
);
2678 LLVMDisposeBuilder (builder
);
2682 emit_div_check (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoBasicBlock
*bb
, MonoInst
*ins
, LLVMValueRef lhs
, LLVMValueRef rhs
)
2684 gboolean need_div_check
= ctx
->cfg
->backend
->need_div_check
;
2687 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2688 need_div_check
= TRUE
;
2690 if (!need_div_check
)
2693 switch (ins
->opcode
) {
2706 case OP_IDIV_UN_IMM
:
2707 case OP_LDIV_UN_IMM
:
2708 case OP_IREM_UN_IMM
:
2709 case OP_LREM_UN_IMM
: {
2711 gboolean is_signed
= (ins
->opcode
== OP_IDIV
|| ins
->opcode
== OP_LDIV
|| ins
->opcode
== OP_IREM
|| ins
->opcode
== OP_LREM
||
2712 ins
->opcode
== OP_IDIV_IMM
|| ins
->opcode
== OP_LDIV_IMM
|| ins
->opcode
== OP_IREM_IMM
|| ins
->opcode
== OP_LREM_IMM
);
2714 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), 0, FALSE
), "");
2715 emit_cond_system_exception (ctx
, bb
, "DivideByZeroException", cmp
);
2718 builder
= ctx
->builder
;
2720 /* b == -1 && a == 0x80000000 */
2722 LLVMValueRef c
= (LLVMTypeOf (lhs
) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs
), 0x80000000, FALSE
) : LLVMConstInt (LLVMTypeOf (lhs
), 0x8000000000000000LL
, FALSE
);
2723 LLVMValueRef cond1
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), -1, FALSE
), "");
2724 LLVMValueRef cond2
= LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, c
, "");
2726 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, LLVMBuildAnd (builder
, cond1
, cond2
, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE
), "");
2727 emit_cond_system_exception (ctx
, bb
, "OverflowException", cmp
);
2730 builder
= ctx
->builder
;
2742 * Emit code to initialize the GOT slots used by the method.
2745 emit_init_method (EmitContext
*ctx
)
2747 LLVMValueRef indexes
[16], args
[16], callee
;
2748 LLVMValueRef inited_var
, cmp
, call
;
2749 LLVMBasicBlockRef inited_bb
, notinited_bb
;
2750 LLVMBuilderRef builder
= ctx
->builder
;
2751 MonoCompile
*cfg
= ctx
->cfg
;
2753 ctx
->module
->max_inited_idx
= MAX (ctx
->module
->max_inited_idx
, cfg
->method_index
);
2755 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2756 indexes
[1] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, FALSE
);
2757 inited_var
= LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, ctx
->module
->inited_var
, indexes
, 2, ""), "is_inited");
2759 args
[0] = inited_var
;
2760 args
[1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE
);
2761 inited_var
= LLVMBuildCall (ctx
->builder
, get_intrinsic (ctx
, "llvm.expect.i8"), args
, 2, "");
2763 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, inited_var
, LLVMConstInt (LLVMTypeOf (inited_var
), 0, FALSE
), "");
2765 inited_bb
= ctx
->inited_bb
;
2766 notinited_bb
= gen_bb (ctx
, "NOTINITED_BB");
2768 LLVMBuildCondBr (ctx
->builder
, cmp
, notinited_bb
, inited_bb
);
2770 builder
= ctx
->builder
= create_builder (ctx
);
2771 LLVMPositionBuilderAtEnd (ctx
->builder
, notinited_bb
);
2774 if (ctx
->rgctx_arg
&& cfg
->method
->is_inflated
&& mono_method_get_context (cfg
->method
)->method_inst
) {
2775 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2776 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
2777 callee
= ctx
->module
->init_method_gshared_mrgctx
;
2778 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2779 } else if (ctx
->rgctx_arg
) {
2780 /* A vtable is passed as the rgctx argument */
2781 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2782 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
2783 callee
= ctx
->module
->init_method_gshared_vtable
;
2784 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2785 } else if (cfg
->gshared
) {
2786 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2787 args
[1] = convert (ctx
, ctx
->this_arg
, ObjRefType ());
2788 callee
= ctx
->module
->init_method_gshared_this
;
2789 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2791 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2792 callee
= ctx
->module
->init_method
;
2793 call
= LLVMBuildCall (builder
, callee
, args
, 1, "");
2797 * This enables llvm to keep arguments in their original registers/
2798 * scratch registers, since the call will not clobber them.
2800 mono_llvm_set_call_preserveall_cc (call
);
2802 LLVMBuildBr (builder
, inited_bb
);
2803 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= inited_bb
;
2805 builder
= ctx
->builder
= create_builder (ctx
);
2806 LLVMPositionBuilderAtEnd (ctx
->builder
, inited_bb
);
2810 emit_unbox_tramp (EmitContext
*ctx
, const char *method_name
, LLVMTypeRef method_type
, LLVMValueRef method
, int method_index
)
2813 * Emit unbox trampoline using a tail call
2815 LLVMValueRef tramp
, call
, *args
;
2816 LLVMBuilderRef builder
;
2817 LLVMBasicBlockRef lbb
;
2818 LLVMCallInfo
*linfo
;
2822 tramp_name
= g_strdup_printf ("ut_%s", method_name
);
2823 tramp
= LLVMAddFunction (ctx
->module
->lmodule
, tramp_name
, method_type
);
2824 LLVMSetLinkage (tramp
, LLVMInternalLinkage
);
2825 LLVMAddFunctionAttr (tramp
, LLVMOptimizeForSizeAttribute
);
2826 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2828 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2829 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
2830 LLVMAddAttribute (LLVMGetParam (tramp
, ctx
->rgctx_arg_pindex
), LLVMInRegAttribute
);
2831 if (ctx
->cfg
->vret_addr
) {
2832 LLVMSetValueName (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), "vret");
2833 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
2834 LLVMAddAttribute (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVMStructRetAttribute
);
2835 LLVMAddAttribute (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVMNoAliasAttribute
);
2839 lbb
= LLVMAppendBasicBlock (tramp
, "");
2840 builder
= LLVMCreateBuilder ();
2841 LLVMPositionBuilderAtEnd (builder
, lbb
);
2843 nargs
= LLVMCountParamTypes (method_type
);
2844 args
= g_new0 (LLVMValueRef
, nargs
);
2845 for (i
= 0; i
< nargs
; ++i
) {
2846 args
[i
] = LLVMGetParam (tramp
, i
);
2847 if (i
== ctx
->this_arg_pindex
) {
2848 LLVMTypeRef arg_type
= LLVMTypeOf (args
[i
]);
2850 args
[i
] = LLVMBuildPtrToInt (builder
, args
[i
], IntPtrType (), "");
2851 args
[i
] = LLVMBuildAdd (builder
, args
[i
], LLVMConstInt (IntPtrType (), sizeof (MonoObject
), FALSE
), "");
2852 args
[i
] = LLVMBuildIntToPtr (builder
, args
[i
], arg_type
, "");
2855 call
= LLVMBuildCall (builder
, method
, args
, nargs
, "");
2856 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
2857 LLVMAddInstrAttribute (call
, 1 + ctx
->rgctx_arg_pindex
, LLVMInRegAttribute
);
2858 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
)
2859 LLVMAddInstrAttribute (call
, 1 + linfo
->vret_arg_pindex
, LLVMStructRetAttribute
);
2861 // FIXME: This causes assertions in clang
2862 //mono_llvm_set_must_tail (call);
2863 if (LLVMGetReturnType (method_type
) == LLVMVoidType ())
2864 LLVMBuildRetVoid (builder
);
2866 LLVMBuildRet (builder
, call
);
2868 g_hash_table_insert (ctx
->module
->idx_to_unbox_tramp
, GINT_TO_POINTER (method_index
), tramp
);
2869 LLVMDisposeBuilder (builder
);
2875 * Emit code to load/convert arguments.
2878 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
)
2881 MonoCompile
*cfg
= ctx
->cfg
;
2882 MonoMethodSignature
*sig
= ctx
->sig
;
2883 LLVMCallInfo
*linfo
= ctx
->linfo
;
2887 LLVMBuilderRef old_builder
= ctx
->builder
;
2888 ctx
->builder
= builder
;
2890 ctx
->alloca_builder
= create_builder (ctx
);
2893 * Handle indirect/volatile variables by allocating memory for them
2894 * using 'alloca', and storing their address in a temporary.
2896 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
2897 MonoInst
*var
= cfg
->varinfo
[i
];
2900 if (var
->opcode
== OP_GSHAREDVT_LOCAL
|| var
->opcode
== OP_GSHAREDVT_ARG_REGOFFSET
) {
2901 } 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
))) {
2902 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
2905 /* Could be already created by an OP_VPHI */
2906 if (!ctx
->addresses
[var
->dreg
]) {
2907 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
2908 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2910 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
2914 names
= g_new (char *, sig
->param_count
);
2915 mono_method_get_param_names (cfg
->method
, (const char **) names
);
2917 for (i
= 0; i
< sig
->param_count
; ++i
) {
2918 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
2919 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
2922 pindex
= ainfo
->pindex
;
2924 switch (ainfo
->storage
) {
2925 case LLVMArgVtypeInReg
:
2926 case LLVMArgAsFpArgs
: {
2927 LLVMValueRef args
[8];
2930 pindex
+= ainfo
->ndummy_fpargs
;
2932 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2933 memset (args
, 0, sizeof (args
));
2934 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
2935 args
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
2936 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
2937 args
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
2939 g_assert (ainfo
->nslots
<= 8);
2940 for (j
= 0; j
< ainfo
->nslots
; ++j
)
2941 args
[j
] = LLVMGetParam (ctx
->lmethod
, pindex
+ j
);
2943 ctx
->addresses
[reg
] = build_alloca (ctx
, ainfo
->type
);
2945 emit_args_to_vtype (ctx
, builder
, ainfo
->type
, ctx
->addresses
[reg
], ainfo
, args
);
2947 if (ainfo
->storage
== LLVMArgVtypeInReg
&& MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (ainfo
->type
))) {
2948 /* Treat these as normal values */
2949 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
2953 case LLVMArgVtypeByVal
: {
2954 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
2956 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (ainfo
->type
))) {
2957 /* Treat these as normal values */
2958 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
2962 case LLVMArgVtypeByRef
: {
2963 /* The argument is passed by ref */
2964 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
2967 case LLVMArgAsIArgs
: {
2968 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
2971 /* The argument is received as an array of ints, store it into the real argument */
2972 ctx
->addresses
[reg
] = build_alloca (ctx
, ainfo
->type
);
2974 size
= mono_class_value_size (mono_class_from_mono_type (ainfo
->type
), NULL
);
2975 if (size
< SIZEOF_VOID_P
) {
2976 /* The upper bits of the registers might not be valid */
2977 LLVMValueRef val
= LLVMBuildExtractValue (builder
, arg
, 0, "");
2978 LLVMValueRef dest
= convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMIntType (size
* 8), 0));
2979 LLVMBuildStore (ctx
->builder
, LLVMBuildTrunc (builder
, val
, LLVMIntType (size
* 8), ""), dest
);
2981 LLVMBuildStore (ctx
->builder
, arg
, convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMTypeOf (arg
), 0)));
2985 case LLVMArgVtypeAsScalar
:
2986 g_assert_not_reached ();
2988 case LLVMArgGsharedvtFixed
: {
2989 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2990 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
2993 name
= g_strdup_printf ("arg_%s", names
[i
]);
2995 name
= g_strdup_printf ("arg_%d", i
);
2997 ctx
->values
[reg
] = LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), name
);
3000 case LLVMArgGsharedvtFixedVtype
: {
3001 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3004 name
= g_strdup_printf ("vtype_arg_%s", names
[i
]);
3006 name
= g_strdup_printf ("vtype_arg_%d", i
);
3008 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3009 g_assert (ctx
->addresses
[reg
]);
3010 LLVMSetValueName (ctx
->addresses
[reg
], name
);
3011 LLVMBuildStore (builder
, LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), ""), ctx
->addresses
[reg
]);
3014 case LLVMArgGsharedvtVariable
:
3015 /* The IR treats these as variables with addresses */
3016 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3019 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
));
3026 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
3028 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
3029 for (i
= 0; i
< sig
->param_count
; ++i
)
3030 if (!mini_type_is_vtype (sig
->params
[i
]))
3031 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
3033 if (sig
->hasthis
&& !cfg
->rgctx_var
&& cfg
->gshared
) {
3034 LLVMValueRef this_alloc
;
3037 * The exception handling code needs the location where the this argument was
3038 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3039 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3040 * location into the LSDA.
3042 this_alloc
= mono_llvm_build_alloca (builder
, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
3043 /* This volatile store will keep the alloca alive */
3044 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3046 set_metadata_flag (this_alloc
, "mono.this");
3049 if (cfg
->rgctx_var
) {
3050 LLVMValueRef rgctx_alloc
, store
;
3053 * We handle the rgctx arg similarly to the this pointer.
3055 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
3056 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
3057 /* This volatile store will keep the alloca alive */
3058 store
= mono_llvm_build_store (builder
, convert (ctx
, ctx
->rgctx_arg
, IntPtrType ()), rgctx_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3060 set_metadata_flag (rgctx_alloc
, "mono.this");
3063 /* Initialize the method if needed */
3064 if (cfg
->compile_aot
&& ctx
->llvm_only
) {
3065 /* Emit a location for the initialization code */
3066 ctx
->init_bb
= gen_bb (ctx
, "INIT_BB");
3067 ctx
->inited_bb
= gen_bb (ctx
, "INITED_BB");
3069 LLVMBuildBr (ctx
->builder
, ctx
->init_bb
);
3070 builder
= ctx
->builder
= create_builder (ctx
);
3071 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->inited_bb
);
3072 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= ctx
->inited_bb
;
3075 /* Compute nesting between clauses */
3076 ctx
->nested_in
= (GSList
**)mono_mempool_alloc0 (cfg
->mempool
, sizeof (GSList
*) * cfg
->header
->num_clauses
);
3077 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
3078 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
3079 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
3080 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
3082 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
)
3083 ctx
->nested_in
[i
] = g_slist_prepend_mempool (cfg
->mempool
, ctx
->nested_in
[i
], GINT_TO_POINTER (j
));
3088 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3089 * it needs to continue normally, or return back to the exception handling system.
3091 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
3095 if (!(bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
)))
3098 clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
3099 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
3100 g_hash_table_insert (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
), bb
);
3102 if (bb
->in_scount
== 0) {
3105 sprintf (name
, "finally_ind_bb%d", bb
->block_num
);
3106 val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), name
);
3107 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
3109 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
3111 /* Create a variable to hold the exception var */
3113 ctx
->ex_var
= LLVMBuildAlloca (builder
, ObjRefType (), "exvar");
3117 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3118 * LLVM bblock containing a landing pad causes problems for the
3119 * LLVM optimizer passes.
3121 sprintf (name
, "BB%d_CALL_HANDLER_TARGET", bb
->block_num
);
3122 ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, name
);
3124 ctx
->builder
= old_builder
;
3128 process_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, MonoInst
*ins
)
3130 MonoCompile
*cfg
= ctx
->cfg
;
3131 LLVMValueRef
*values
= ctx
->values
;
3132 LLVMValueRef
*addresses
= ctx
->addresses
;
3133 MonoCallInst
*call
= (MonoCallInst
*)ins
;
3134 MonoMethodSignature
*sig
= call
->signature
;
3135 LLVMValueRef callee
= NULL
, lcall
;
3137 LLVMCallInfo
*cinfo
;
3141 LLVMTypeRef llvm_sig
;
3143 gboolean is_virtual
, calli
, preserveall
;
3144 LLVMBuilderRef builder
= *builder_ref
;
3146 if ((call
->signature
->call_convention
!= MONO_CALL_DEFAULT
) && !((call
->signature
->call_convention
== MONO_CALL_C
) && ctx
->llvm_only
)) {
3147 set_failure (ctx
, "non-default callconv");
3151 cinfo
= call
->cinfo
;
3153 if (call
->rgctx_arg_reg
)
3154 cinfo
->rgctx_arg
= TRUE
;
3155 if (call
->imt_arg_reg
)
3156 cinfo
->imt_arg
= TRUE
;
3158 vretaddr
= (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
|| cinfo
->ret
.storage
== LLVMArgVtypeByRef
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixed
|| cinfo
->ret
.storage
== LLVMArgGsharedvtVariable
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixedVtype
);
3160 llvm_sig
= sig_to_llvm_sig_full (ctx
, sig
, cinfo
);
3164 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
);
3165 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
);
3167 preserveall
= FALSE
;
3169 /* FIXME: Avoid creating duplicate methods */
3171 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3175 if (cfg
->compile_aot
) {
3176 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
3178 set_failure (ctx
, "can't encode patch");
3181 if (cfg
->llvm_only
&& call
->method
->klass
->image
->assembly
== ctx
->module
->assembly
) {
3183 * Collect instructions representing the callee into a hash so they can be replaced
3184 * by the llvm method for the callee if the callee turns out to be direct
3185 * callable. Currently this only requires it to not fail llvm compilation.
3187 GSList
*l
= (GSList
*)g_hash_table_lookup (ctx
->method_to_callers
, call
->method
);
3188 l
= g_slist_prepend (l
, callee
);
3189 g_hash_table_insert (ctx
->method_to_callers
, call
->method
, l
);
3193 static int tramp_index
;
3196 name
= g_strdup_printf ("tramp_%d", tramp_index
);
3199 #if LLVM_API_VERSION > 100
3201 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3202 * Make all calls through a global. The address of the global will be saved in
3203 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3206 LLVMValueRef tramp_var
= g_hash_table_lookup (ctx
->jit_callees
, call
->method
);
3209 mono_create_jit_trampoline (mono_domain_get (),
3210 call
->method
, &error
);
3211 if (!is_ok (&error
)) {
3212 set_failure (ctx
, mono_error_get_message (&error
));
3213 mono_error_cleanup (&error
);
3217 tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
3218 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
3219 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
3220 g_hash_table_insert (ctx
->jit_callees
, call
->method
, tramp_var
);
3222 callee
= LLVMBuildLoad (builder
, tramp_var
, "");
3225 mono_create_jit_trampoline (mono_domain_get (),
3226 call
->method
, &error
);
3227 if (!is_ok (&error
)) {
3229 set_failure (ctx
, mono_error_get_message (&error
));
3230 mono_error_cleanup (&error
);
3234 callee
= LLVMAddFunction (ctx
->lmodule
, name
, llvm_sig
);
3237 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, target
);
3242 if (!cfg
->llvm_only
&& call
->method
&& strstr (call
->method
->klass
->name
, "AsyncVoidMethodBuilder")) {
3243 /* LLVM miscompiles async methods */
3244 set_failure (ctx
, "#13734");
3249 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
3255 memset (&ji, 0, sizeof (ji));
3256 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3257 ji.data.target = info->name;
3259 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3261 if (cfg
->compile_aot
) {
3262 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, (char*)info
->name
);
3264 set_failure (ctx
, "can't encode patch");
3268 target
= (gpointer
)mono_icall_get_wrapper (info
);
3269 callee
= emit_jit_callee (ctx
, "", llvm_sig
, target
);
3272 if (cfg
->compile_aot
) {
3274 if (cfg
->abs_patches
) {
3275 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3277 callee
= get_callee (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
3279 set_failure (ctx
, "can't encode patch");
3285 set_failure (ctx
, "aot");
3289 #if LLVM_API_VERSION > 100
3290 if (cfg
->abs_patches
) {
3291 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3295 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
, &error
);
3296 mono_error_assert_ok (&error
);
3297 callee
= emit_jit_callee (ctx
, "", llvm_sig
, target
);
3299 g_assert_not_reached ();
3302 g_assert_not_reached ();
3305 callee
= LLVMAddFunction (ctx
->lmodule
, "", llvm_sig
);
3307 if (cfg
->abs_patches
) {
3308 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3313 * FIXME: Some trampolines might have
3314 * their own calling convention on some platforms.
3316 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
, &error
);
3317 mono_error_assert_ok (&error
);
3318 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, target
);
3322 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, (gpointer
)call
->fptr
);
3329 int size
= sizeof (gpointer
);
3332 g_assert (ins
->inst_offset
% size
== 0);
3333 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3335 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
3337 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
3339 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3344 * Collect and convert arguments
3346 nargs
= (sig
->param_count
* 16) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
+ call
->imt_arg_reg
;
3347 len
= sizeof (LLVMValueRef
) * nargs
;
3348 args
= (LLVMValueRef
*)alloca (len
);
3349 memset (args
, 0, len
);
3350 l
= call
->out_ireg_args
;
3352 if (call
->rgctx_arg_reg
) {
3353 g_assert (values
[call
->rgctx_arg_reg
]);
3354 g_assert (cinfo
->rgctx_arg_pindex
< nargs
);
3356 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3357 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3358 * it using a volatile load.
3361 if (!ctx
->imt_rgctx_loc
)
3362 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, sizeof (gpointer
));
3363 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3364 args
[cinfo
->rgctx_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3366 args
[cinfo
->rgctx_arg_pindex
] = convert (ctx
, values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
);
3369 if (call
->imt_arg_reg
) {
3370 g_assert (!ctx
->llvm_only
);
3371 g_assert (values
[call
->imt_arg_reg
]);
3372 g_assert (cinfo
->imt_arg_pindex
< nargs
);
3374 if (!ctx
->imt_rgctx_loc
)
3375 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, sizeof (gpointer
));
3376 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3377 args
[cinfo
->imt_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3379 args
[cinfo
->imt_arg_pindex
] = convert (ctx
, values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
);
3382 switch (cinfo
->ret
.storage
) {
3383 case LLVMArgGsharedvtVariable
: {
3384 MonoInst
*var
= get_vreg_to_inst (cfg
, call
->inst
.dreg
);
3386 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
3387 args
[cinfo
->vret_arg_pindex
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), IntPtrType ());
3389 g_assert (addresses
[call
->inst
.dreg
]);
3390 args
[cinfo
->vret_arg_pindex
] = addresses
[call
->inst
.dreg
];
3396 if (!addresses
[call
->inst
.dreg
])
3397 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3398 g_assert (cinfo
->vret_arg_pindex
< nargs
);
3399 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
3400 args
[cinfo
->vret_arg_pindex
] = addresses
[call
->inst
.dreg
];
3402 args
[cinfo
->vret_arg_pindex
] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
3408 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3409 * use the real callee for argument type conversion.
3411 LLVMTypeRef callee_type
= LLVMGetElementType (LLVMTypeOf (callee
));
3412 LLVMTypeRef
*param_types
= (LLVMTypeRef
*)g_alloca (sizeof (LLVMTypeRef
) * LLVMCountParamTypes (callee_type
));
3413 LLVMGetParamTypes (callee_type
, param_types
);
3415 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
3418 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
];
3420 pindex
= ainfo
->pindex
;
3422 regpair
= (guint32
)(gssize
)(l
->data
);
3423 reg
= regpair
& 0xffffff;
3424 args
[pindex
] = values
[reg
];
3425 switch (ainfo
->storage
) {
3426 case LLVMArgVtypeInReg
:
3427 case LLVMArgAsFpArgs
: {
3431 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
3432 args
[pindex
+ j
] = LLVMConstNull (LLVMDoubleType ());
3433 pindex
+= ainfo
->ndummy_fpargs
;
3435 g_assert (addresses
[reg
]);
3436 emit_vtype_to_args (ctx
, builder
, ainfo
->type
, addresses
[reg
], ainfo
, args
+ pindex
, &nargs
);
3440 // FIXME: Get rid of the VMOVE
3443 case LLVMArgVtypeByVal
:
3444 g_assert (addresses
[reg
]);
3445 args
[pindex
] = addresses
[reg
];
3447 case LLVMArgVtypeByRef
: {
3448 g_assert (addresses
[reg
]);
3449 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
3452 case LLVMArgAsIArgs
:
3453 g_assert (addresses
[reg
]);
3454 args
[pindex
] = LLVMBuildLoad (ctx
->builder
, convert (ctx
, addresses
[reg
], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo
->nslots
), 0)), "");
3456 case LLVMArgVtypeAsScalar
:
3457 g_assert_not_reached ();
3459 case LLVMArgGsharedvtFixed
:
3460 case LLVMArgGsharedvtFixedVtype
:
3461 g_assert (addresses
[reg
]);
3462 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
3464 case LLVMArgGsharedvtVariable
:
3465 g_assert (addresses
[reg
]);
3466 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (IntPtrType (), 0));
3469 g_assert (args
[pindex
]);
3470 if (i
== 0 && sig
->hasthis
)
3471 args
[pindex
] = convert (ctx
, args
[pindex
], param_types
[pindex
]);
3473 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, ainfo
->type
));
3476 g_assert (pindex
<= nargs
);
3481 // FIXME: Align call sites
3487 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, LLVMCountParamTypes (llvm_sig
));
3490 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3492 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3493 g_assert (MONO_ARCH_IMT_REG
== MONO_ARCH_RGCTX_REG
);
3495 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3496 g_assert (!(call
->rgctx_arg_reg
&& call
->imt_arg_reg
));
3497 if (!sig
->pinvoke
&& !cfg
->llvm_only
)
3498 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
3500 mono_llvm_set_call_preserveall_cc (lcall
);
3502 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
3503 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->vret_arg_pindex
, LLVMStructRetAttribute
);
3504 if (!ctx
->llvm_only
&& call
->rgctx_arg_reg
)
3505 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->rgctx_arg_pindex
, LLVMInRegAttribute
);
3506 if (call
->imt_arg_reg
)
3507 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->imt_arg_pindex
, LLVMInRegAttribute
);
3509 /* Add byval attributes if needed */
3510 for (i
= 0; i
< sig
->param_count
; ++i
) {
3511 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
+ sig
->hasthis
];
3513 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
)
3514 LLVMAddInstrAttribute (lcall
, 1 + ainfo
->pindex
, LLVMByValAttribute
);
3518 * Convert the result
3520 switch (cinfo
->ret
.storage
) {
3521 case LLVMArgVtypeInReg
: {
3522 LLVMValueRef regs
[2];
3524 if (LLVMTypeOf (lcall
) == LLVMVoidType ())
3528 if (!addresses
[ins
->dreg
])
3529 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
3531 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
3532 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
3533 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
3534 emit_args_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
3537 case LLVMArgVtypeByVal
:
3538 if (!addresses
[call
->inst
.dreg
])
3539 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3540 LLVMBuildStore (builder
, lcall
, addresses
[call
->inst
.dreg
]);
3542 case LLVMArgAsIArgs
:
3543 case LLVMArgFpStruct
:
3544 if (!addresses
[call
->inst
.dreg
])
3545 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3546 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
3548 case LLVMArgVtypeAsScalar
:
3549 if (!addresses
[call
->inst
.dreg
])
3550 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3551 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
3553 case LLVMArgVtypeRetAddr
:
3554 case LLVMArgVtypeByRef
:
3555 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->ret
))) {
3556 /* Some opcodes like STOREX_MEMBASE access these by value */
3557 g_assert (addresses
[call
->inst
.dreg
]);
3558 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
3561 case LLVMArgGsharedvtVariable
:
3563 case LLVMArgGsharedvtFixed
:
3564 case LLVMArgGsharedvtFixedVtype
:
3565 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
3568 if (sig
->ret
->type
!= MONO_TYPE_VOID
)
3569 /* If the method returns an unsigned value, need to zext it */
3570 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
));
3574 *builder_ref
= ctx
->builder
;
3578 emit_llvmonly_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
3580 const char *icall_name
= rethrow
? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3581 LLVMValueRef callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
3583 LLVMTypeRef exc_type
= type_to_llvm_type (ctx
, &mono_get_exception_class ()->byval_arg
);
3586 LLVMTypeRef fun_sig
= LLVMFunctionType1 (LLVMVoidType (), exc_type
, FALSE
);
3588 if (ctx
->cfg
->compile_aot
) {
3589 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, icall_name
);
3591 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, fun_sig
);
3592 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3593 mono_memory_barrier ();
3596 ctx
->module
->rethrow
= callee
;
3598 ctx
->module
->throw_icall
= callee
;
3602 LLVMValueRef args
[2];
3604 args
[0] = convert (ctx
, exc
, exc_type
);
3605 emit_call (ctx
, bb
, &ctx
->builder
, callee
, args
, 1);
3607 LLVMBuildUnreachable (ctx
->builder
);
3609 ctx
->builder
= create_builder (ctx
);
3613 emit_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
3615 MonoMethodSignature
*throw_sig
;
3616 LLVMValueRef callee
, arg
;
3617 const char *icall_name
;
3619 callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
3620 icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3623 throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 1);
3624 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
3625 throw_sig
->params
[0] = &mono_get_object_class ()->byval_arg
;
3626 if (ctx
->cfg
->compile_aot
) {
3627 callee
= get_callee (ctx
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3632 * LLVM doesn't push the exception argument, so we need a different
3635 target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, rethrow
? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3637 target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3639 callee
= emit_jit_callee (ctx
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
), target
);
3642 mono_memory_barrier ();
3643 #if LLVM_API_VERSION < 100
3645 ctx
->module
->rethrow
= callee
;
3647 ctx
->module
->throw_icall
= callee
;
3650 arg
= convert (ctx
, exc
, type_to_llvm_type (ctx
, &mono_get_object_class ()->byval_arg
));
3651 emit_call (ctx
, bb
, &ctx
->builder
, callee
, &arg
, 1);
3655 emit_resume_eh (EmitContext
*ctx
, MonoBasicBlock
*bb
)
3657 const char *icall_name
= "mono_llvm_resume_exception";
3658 LLVMValueRef callee
= ctx
->module
->resume_eh
;
3660 LLVMTypeRef fun_sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
3663 if (ctx
->cfg
->compile_aot
) {
3664 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3666 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, fun_sig
);
3667 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3668 mono_memory_barrier ();
3670 ctx
->module
->resume_eh
= callee
;
3674 emit_call (ctx
, bb
, &ctx
->builder
, callee
, NULL
, 0);
3676 LLVMBuildUnreachable (ctx
->builder
);
3678 ctx
->builder
= create_builder (ctx
);
3682 mono_llvm_emit_clear_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
3684 const char *icall_name
= "mono_llvm_clear_exception";
3686 LLVMTypeRef call_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
3687 LLVMValueRef callee
= NULL
;
3690 if (ctx
->cfg
->compile_aot
) {
3691 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3693 // FIXME: This is broken.
3694 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
3698 g_assert (builder
&& callee
);
3700 return LLVMBuildCall (builder
, callee
, NULL
, 0, "");
3704 mono_llvm_emit_load_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
3706 const char *icall_name
= "mono_llvm_load_exception";
3708 LLVMTypeRef call_sig
= LLVMFunctionType (ObjRefType (), NULL
, 0, FALSE
);
3709 LLVMValueRef callee
= NULL
;
3712 if (ctx
->cfg
->compile_aot
) {
3713 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3715 // FIXME: This is broken.
3716 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
3720 g_assert (builder
&& callee
);
3722 return LLVMBuildCall (builder
, callee
, NULL
, 0, icall_name
);
3727 mono_llvm_emit_match_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
, gint32 region_start
, gint32 region_end
)
3729 const char *icall_name
= "mono_llvm_match_exception";
3731 ctx
->builder
= builder
;
3733 const int num_args
= 5;
3734 LLVMValueRef args
[num_args
];
3735 args
[0] = convert (ctx
, get_aotconst (ctx
, MONO_PATCH_INFO_AOT_JIT_INFO
, GINT_TO_POINTER (ctx
->cfg
->method_index
)), IntPtrType ());
3736 args
[1] = LLVMConstInt (LLVMInt32Type (), region_start
, 0);
3737 args
[2] = LLVMConstInt (LLVMInt32Type (), region_end
, 0);
3738 if (ctx
->cfg
->rgctx_var
) {
3739 LLVMValueRef rgctx_alloc
= ctx
->addresses
[ctx
->cfg
->rgctx_var
->dreg
];
3740 g_assert (rgctx_alloc
);
3741 args
[3] = LLVMBuildLoad (builder
, convert (ctx
, rgctx_alloc
, LLVMPointerType (IntPtrType (), 0)), "");
3743 args
[3] = LLVMConstInt (IntPtrType (), 0, 0);
3746 args
[4] = convert (ctx
, ctx
->this_arg
, IntPtrType ());
3748 args
[4] = LLVMConstInt (IntPtrType (), 0, 0);
3750 LLVMTypeRef match_sig
= LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE
);
3751 LLVMValueRef callee
= ctx
->module
->match_exc
;
3754 if (ctx
->cfg
->compile_aot
) {
3755 ctx
->builder
= builder
;
3756 // get_callee expects ctx->builder to be the emitting builder
3757 callee
= get_callee (ctx
, match_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3759 callee
= ctx
->module
->match_exc
= LLVMAddFunction (ctx
->lmodule
, icall_name
, match_sig
);
3760 LLVMAddGlobalMapping (ctx
->module
->ee
, ctx
->module
->match_exc
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3761 ctx
->module
->match_exc
= callee
;
3762 mono_memory_barrier ();
3766 g_assert (builder
&& callee
);
3768 g_assert (ctx
->ex_var
);
3770 return LLVMBuildCall (builder
, callee
, args
, num_args
, icall_name
);
3773 // FIXME: This won't work because the code-finding makes this
3775 /*#define MONO_PERSONALITY_DEBUG*/
3777 #ifdef MONO_PERSONALITY_DEBUG
3778 static const gboolean use_debug_personality
= TRUE
;
3779 static const char *default_personality_name
= "mono_debug_personality";
3781 static const gboolean use_debug_personality
= FALSE
;
3782 static const char *default_personality_name
= "__gxx_personality_v0";
3786 default_cpp_lpad_exc_signature (void)
3788 static gboolean inited
= FALSE
;
3789 static LLVMTypeRef sig
;
3792 LLVMTypeRef signature
[2];
3793 signature
[0] = LLVMPointerType (LLVMInt8Type (), 0);
3794 signature
[1] = LLVMInt32Type ();
3795 sig
= LLVMStructType (signature
, 2, FALSE
);
3803 get_mono_personality (EmitContext
*ctx
)
3805 LLVMValueRef personality
= NULL
;
3806 static gint32 mapping_inited
= FALSE
;
3807 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
3809 if (!use_debug_personality
) {
3810 if (ctx
->cfg
->compile_aot
) {
3811 personality
= get_intrinsic (ctx
, default_personality_name
);
3812 } else if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0) {
3813 personality
= LLVMAddFunction (ctx
->lmodule
, default_personality_name
, personality_type
);
3814 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, personality
);
3817 if (ctx
->cfg
->compile_aot
) {
3818 personality
= get_callee (ctx
, personality_type
, MONO_PATCH_INFO_INTERNAL_METHOD
, default_personality_name
);
3820 personality
= LLVMAddFunction (ctx
->lmodule
, default_personality_name
, personality_type
);
3821 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, default_personality_name
));
3822 mono_memory_barrier ();
3826 g_assert (personality
);
3830 static LLVMBasicBlockRef
3831 emit_landing_pad (EmitContext
*ctx
, int group_index
, int group_size
)
3833 MonoCompile
*cfg
= ctx
->cfg
;
3834 LLVMBuilderRef old_builder
= ctx
->builder
;
3835 MonoExceptionClause
*group_start
= cfg
->header
->clauses
+ group_index
;
3837 LLVMBuilderRef lpadBuilder
= create_builder (ctx
);
3838 ctx
->builder
= lpadBuilder
;
3840 MonoBasicBlock
*handler_bb
= cfg
->cil_offset_to_bb
[CLAUSE_START (group_start
)];
3841 g_assert (handler_bb
);
3843 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3844 LLVMValueRef personality
= get_mono_personality (ctx
);
3845 g_assert (personality
);
3847 char *bb_name
= g_strdup_printf ("LPAD%d_BB", group_index
);
3848 LLVMBasicBlockRef lpad_bb
= gen_bb (ctx
, bb_name
);
3850 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
3851 LLVMValueRef landing_pad
= LLVMBuildLandingPad (lpadBuilder
, default_cpp_lpad_exc_signature (), personality
, 0, "");
3852 g_assert (landing_pad
);
3854 LLVMValueRef cast
= LLVMBuildBitCast (lpadBuilder
, ctx
->module
->sentinel_exception
, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3855 LLVMAddClause (landing_pad
, cast
);
3857 LLVMBasicBlockRef resume_bb
= gen_bb (ctx
, "RESUME_BB");
3858 LLVMBuilderRef resume_builder
= create_builder (ctx
);
3859 ctx
->builder
= resume_builder
;
3860 LLVMPositionBuilderAtEnd (resume_builder
, resume_bb
);
3862 emit_resume_eh (ctx
, handler_bb
);
3865 ctx
->builder
= lpadBuilder
;
3866 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
3868 gboolean finally_only
= TRUE
;
3870 MonoExceptionClause
*group_cursor
= group_start
;
3872 for (int i
= 0; i
< group_size
; i
++) {
3873 if (!(group_cursor
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
))
3874 finally_only
= FALSE
;
3880 // Handle landing pad inlining
3882 if (!finally_only
) {
3883 // So at each level of the exception stack we will match the exception again.
3884 // During that match, we need to compare against the handler types for the current
3885 // protected region. We send the try start and end so that we can only check against
3886 // handlers for this lexical protected region.
3887 LLVMValueRef match
= mono_llvm_emit_match_exception_call (ctx
, lpadBuilder
, group_start
->try_offset
, group_start
->try_offset
+ group_start
->try_len
);
3889 // if returns -1, resume
3890 LLVMValueRef switch_ins
= LLVMBuildSwitch (lpadBuilder
, match
, resume_bb
, group_size
);
3892 // else move to that target bb
3893 for (int i
=0; i
< group_size
; i
++) {
3894 MonoExceptionClause
*clause
= group_start
+ i
;
3895 int clause_index
= clause
- cfg
->header
->clauses
;
3896 MonoBasicBlock
*handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
3897 g_assert (handler_bb
);
3898 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
3899 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
3902 int clause_index
= group_start
- cfg
->header
->clauses
;
3903 MonoBasicBlock
*finally_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
3904 g_assert (finally_bb
);
3906 LLVMBuildBr (ctx
->builder
, ctx
->bblocks
[finally_bb
->block_num
].call_handler_target_bb
);
3909 ctx
->builder
= old_builder
;
3916 emit_llvmonly_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBasicBlockRef cbb
)
3918 int clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
3919 MonoExceptionClause
*clause
= &ctx
->cfg
->header
->clauses
[clause_index
];
3921 // Make exception available to catch blocks
3922 if (!(clause
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
)) {
3923 LLVMValueRef mono_exc
= mono_llvm_emit_load_exception_call (ctx
, ctx
->builder
);
3925 g_assert (ctx
->ex_var
);
3926 LLVMBuildStore (ctx
->builder
, LLVMBuildBitCast (ctx
->builder
, mono_exc
, ObjRefType (), ""), ctx
->ex_var
);
3928 if (bb
->in_scount
== 1) {
3929 MonoInst
*exvar
= bb
->in_stack
[0];
3930 g_assert (!ctx
->values
[exvar
->dreg
]);
3931 g_assert (ctx
->ex_var
);
3932 ctx
->values
[exvar
->dreg
] = LLVMBuildLoad (ctx
->builder
, ctx
->ex_var
, "save_exception");
3933 emit_volatile_store (ctx
, exvar
->dreg
);
3936 mono_llvm_emit_clear_exception_call (ctx
, ctx
->builder
);
3939 LLVMBuilderRef handler_builder
= create_builder (ctx
);
3940 LLVMBasicBlockRef target_bb
= ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
;
3941 LLVMPositionBuilderAtEnd (handler_builder
, target_bb
);
3943 // Make the handler code end with a jump to cbb
3944 LLVMBuildBr (handler_builder
, cbb
);
3948 emit_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef builder
)
3950 MonoCompile
*cfg
= ctx
->cfg
;
3951 LLVMValueRef
*values
= ctx
->values
;
3952 LLVMModuleRef lmodule
= ctx
->lmodule
;
3953 BBInfo
*bblocks
= ctx
->bblocks
;
3955 LLVMValueRef personality
;
3956 LLVMValueRef landing_pad
;
3957 LLVMBasicBlockRef target_bb
;
3959 static int ti_generator
;
3961 LLVMValueRef type_info
;
3965 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3967 if (cfg
->compile_aot
) {
3968 /* Use a dummy personality function */
3969 personality
= LLVMGetNamedFunction (lmodule
, "mono_personality");
3970 g_assert (personality
);
3972 #if LLVM_API_VERSION > 100
3973 personality
= ctx
->module
->personality
;
3975 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
3976 personality
= LLVMAddFunction (ctx
->lmodule
, "mono_personality", personality_type
);
3977 LLVMAddFunctionAttr (personality
, LLVMNoUnwindAttribute
);
3978 LLVMBasicBlockRef entry_bb
= LLVMAppendBasicBlock (personality
, "ENTRY");
3979 LLVMBuilderRef builder2
= LLVMCreateBuilder ();
3980 LLVMPositionBuilderAtEnd (builder2
, entry_bb
);
3981 LLVMBuildRet (builder2
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
));
3982 ctx
->module
->personality
= personality
;
3983 LLVMDisposeBuilder (builder2
);
3986 static gint32 mapping_inited
;
3988 personality
= LLVMGetNamedFunction (lmodule
, "mono_personality");
3990 if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0)
3991 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, (gpointer
)mono_personality
);
3995 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
3997 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
4000 * Create the type info
4002 sprintf (ti_name
, "type_info_%d", ti_generator
);
4005 if (cfg
->compile_aot
) {
4006 /* decode_eh_frame () in aot-runtime.c will decode this */
4007 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4008 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4011 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4013 LLVMSetLinkage (type_info
, LLVMInternalLinkage
);
4015 #if LLVM_API_VERSION > 100
4016 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4017 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4022 * After the cfg mempool is freed, the type info will point to stale memory,
4023 * but this is not a problem, since we decode it once in exception_cb during
4026 ti
= (gint32
*)mono_mempool_alloc (cfg
->mempool
, sizeof (gint32
));
4027 *(gint32
*)ti
= clause_index
;
4029 type_info
= LLVMAddGlobal (lmodule
, i8ptr
, ti_name
);
4031 LLVMAddGlobalMapping (ctx
->module
->ee
, type_info
, ti
);
4036 LLVMTypeRef members
[2], ret_type
;
4038 members
[0] = i8ptr
;
4039 members
[1] = LLVMInt32Type ();
4040 ret_type
= LLVMStructType (members
, 2, FALSE
);
4042 landing_pad
= LLVMBuildLandingPad (builder
, ret_type
, personality
, 1, "");
4043 LLVMAddClause (landing_pad
, type_info
);
4045 /* Store the exception into the exvar */
4047 LLVMBuildStore (builder
, convert (ctx
, LLVMBuildExtractValue (builder
, landing_pad
, 0, "ex_obj"), ObjRefType ()), ctx
->ex_var
);
4051 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4052 * code expects control to be transferred to this landing pad even in the
4053 * presence of nested clauses. The landing pad needs to branch to the landing
4054 * pads belonging to nested clauses based on the selector value returned by
4055 * the landing pad instruction, which is passed to the landing pad in a
4056 * register by the EH code.
4058 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
4059 g_assert (target_bb
);
4062 * Branch to the correct landing pad
4064 LLVMValueRef ex_selector
= LLVMBuildExtractValue (builder
, landing_pad
, 1, "ex_selector");
4065 LLVMValueRef switch_ins
= LLVMBuildSwitch (builder
, ex_selector
, target_bb
, 0);
4067 for (l
= ctx
->nested_in
[clause_index
]; l
; l
= l
->next
) {
4068 int nesting_clause_index
= GPOINTER_TO_INT (l
->data
);
4069 MonoBasicBlock
*handler_bb
;
4071 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (nesting_clause_index
));
4072 g_assert (handler_bb
);
4074 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4075 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), nesting_clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4078 /* Start a new bblock which CALL_HANDLER can branch to */
4079 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
4081 ctx
->builder
= builder
= create_builder (ctx
);
4082 LLVMPositionBuilderAtEnd (ctx
->builder
, target_bb
);
4084 ctx
->bblocks
[bb
->block_num
].end_bblock
= target_bb
;
4086 /* Store the exception into the IL level exvar */
4087 if (bb
->in_scount
== 1) {
4088 g_assert (bb
->in_scount
== 1);
4089 exvar
= bb
->in_stack
[0];
4091 // FIXME: This is shared with filter clauses ?
4092 g_assert (!values
[exvar
->dreg
]);
4094 g_assert (ctx
->ex_var
);
4095 values
[exvar
->dreg
] = LLVMBuildLoad (builder
, ctx
->ex_var
, "");
4096 emit_volatile_store (ctx
, exvar
->dreg
);
4102 process_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
4104 MonoCompile
*cfg
= ctx
->cfg
;
4105 MonoMethodSignature
*sig
= ctx
->sig
;
4106 LLVMValueRef method
= ctx
->lmethod
;
4107 LLVMValueRef
*values
= ctx
->values
;
4108 LLVMValueRef
*addresses
= ctx
->addresses
;
4109 LLVMCallInfo
*linfo
= ctx
->linfo
;
4110 BBInfo
*bblocks
= ctx
->bblocks
;
4112 LLVMBasicBlockRef cbb
;
4113 LLVMBuilderRef builder
, starting_builder
;
4114 gboolean has_terminator
;
4116 LLVMValueRef lhs
, rhs
;
4119 cbb
= get_end_bb (ctx
, bb
);
4121 builder
= create_builder (ctx
);
4122 ctx
->builder
= builder
;
4123 LLVMPositionBuilderAtEnd (builder
, cbb
);
4128 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
4129 if (!ctx
->llvm_only
&& !bblocks
[bb
->block_num
].invoke_target
) {
4130 set_failure (ctx
, "handler without invokes");
4135 emit_llvmonly_handler_start (ctx
, bb
, cbb
);
4137 emit_handler_start (ctx
, bb
, builder
);
4140 builder
= ctx
->builder
;
4143 has_terminator
= FALSE
;
4144 starting_builder
= builder
;
4145 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
4146 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
4148 char dname_buf
[128];
4150 emit_dbg_loc (ctx
, builder
, ins
->cil_code
);
4155 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4156 * Start a new bblock. If the llvm optimization passes merge these, we
4157 * can work around that by doing a volatile load + cond branch from
4158 * localloc-ed memory.
4160 if (!cfg
->llvm_only
)
4161 set_failure (ctx
, "basic block too long");
4162 cbb
= gen_bb (ctx
, "CONT_LONG_BB");
4163 LLVMBuildBr (ctx
->builder
, cbb
);
4164 ctx
->builder
= builder
= create_builder (ctx
);
4165 LLVMPositionBuilderAtEnd (builder
, cbb
);
4166 ctx
->bblocks
[bb
->block_num
].end_bblock
= cbb
;
4171 /* There could be instructions after a terminator, skip them */
4174 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
4175 sprintf (dname_buf
, "t%d", ins
->dreg
);
4179 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
4180 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
4182 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) && var
->opcode
!= OP_GSHAREDVT_ARG_REGOFFSET
) {
4183 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
4185 /* It is ok for SETRET to have an uninitialized argument */
4186 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
) {
4187 set_failure (ctx
, "sreg1");
4190 lhs
= values
[ins
->sreg1
];
4196 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
4197 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
4198 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
4199 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
4201 if (!values
[ins
->sreg2
]) {
4202 set_failure (ctx
, "sreg2");
4205 rhs
= values
[ins
->sreg2
];
4211 //mono_print_ins (ins);
4212 switch (ins
->opcode
) {
4215 case OP_LIVERANGE_START
:
4216 case OP_LIVERANGE_END
:
4219 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
4222 #if SIZEOF_VOID_P == 4
4223 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4225 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
4229 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), *(double*)ins
->inst_p0
);
4233 values
[ins
->dreg
] = LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
);
4235 values
[ins
->dreg
] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
), LLVMDoubleType ());
4237 case OP_DUMMY_ICONST
:
4238 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4240 case OP_DUMMY_I8CONST
:
4241 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
4243 case OP_DUMMY_R8CONST
:
4244 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), 0.0f
);
4247 LLVMBasicBlockRef target_bb
= get_bb (ctx
, ins
->inst_target_bb
);
4248 LLVMBuildBr (builder
, target_bb
);
4249 has_terminator
= TRUE
;
4256 LLVMBasicBlockRef new_bb
;
4257 LLVMBuilderRef new_builder
;
4259 // The default branch is already handled
4260 // FIXME: Handle it here
4262 /* Start new bblock */
4263 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
4264 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
4266 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4267 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
4268 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
4269 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
4271 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
4274 new_builder
= create_builder (ctx
);
4275 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
4276 LLVMBuildUnreachable (new_builder
);
4278 has_terminator
= TRUE
;
4279 g_assert (!ins
->next
);
4285 switch (linfo
->ret
.storage
) {
4286 case LLVMArgVtypeInReg
: {
4287 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4288 LLVMValueRef val
, addr
, retval
;
4291 retval
= LLVMGetUndef (ret_type
);
4293 if (!addresses
[ins
->sreg1
]) {
4295 * The return type is an LLVM vector type, have to convert between it and the
4296 * real return type which is a struct type.
4298 g_assert (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->ret
)));
4299 /* Convert to 2xi64 first */
4300 val
= LLVMBuildBitCast (builder
, values
[ins
->sreg1
], LLVMVectorType (IntPtrType (), 2), "");
4302 for (i
= 0; i
< 2; ++i
) {
4303 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4304 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildExtractElement (builder
, val
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), ""), i
, "");
4306 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4310 addr
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), "");
4311 for (i
= 0; i
< 2; ++i
) {
4312 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4313 LLVMValueRef indexes
[2], part_addr
;
4315 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4316 indexes
[1] = LLVMConstInt (LLVMInt32Type (), i
, FALSE
);
4317 part_addr
= LLVMBuildGEP (builder
, addr
, indexes
, 2, "");
4319 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildLoad (builder
, part_addr
, ""), i
, "");
4321 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4325 LLVMBuildRet (builder
, retval
);
4328 case LLVMArgVtypeAsScalar
: {
4329 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4330 LLVMValueRef retval
;
4332 g_assert (addresses
[ins
->sreg1
]);
4334 retval
= LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), ""), "");
4335 LLVMBuildRet (builder
, retval
);
4338 case LLVMArgVtypeByVal
: {
4339 LLVMValueRef retval
;
4341 g_assert (addresses
[ins
->sreg1
]);
4342 retval
= LLVMBuildLoad (builder
, addresses
[ins
->sreg1
], "");
4343 LLVMBuildRet (builder
, retval
);
4346 case LLVMArgVtypeByRef
: {
4347 LLVMBuildRetVoid (builder
);
4350 case LLVMArgGsharedvtFixed
: {
4351 LLVMTypeRef ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
4352 /* The return value is in lhs, need to store to the vret argument */
4353 /* sreg1 might not be set */
4355 g_assert (cfg
->vret_addr
);
4356 g_assert (values
[cfg
->vret_addr
->dreg
]);
4357 LLVMBuildStore (builder
, convert (ctx
, lhs
, ret_type
), convert (ctx
, values
[cfg
->vret_addr
->dreg
], LLVMPointerType (ret_type
, 0)));
4359 LLVMBuildRetVoid (builder
);
4362 case LLVMArgGsharedvtFixedVtype
: {
4364 LLVMBuildRetVoid (builder
);
4367 case LLVMArgGsharedvtVariable
: {
4369 LLVMBuildRetVoid (builder
);
4372 case LLVMArgVtypeRetAddr
: {
4373 LLVMBuildRetVoid (builder
);
4376 case LLVMArgAsIArgs
:
4377 case LLVMArgFpStruct
: {
4378 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4379 LLVMValueRef retval
;
4381 g_assert (addresses
[ins
->sreg1
]);
4382 retval
= LLVMBuildLoad (builder
, convert (ctx
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0)), "");
4383 LLVMBuildRet (builder
, retval
);
4387 case LLVMArgNormal
: {
4388 if (!lhs
|| ctx
->is_dead
[ins
->sreg1
]) {
4390 * The method did not set its return value, probably because it
4391 * ends with a throw.
4394 LLVMBuildRetVoid (builder
);
4396 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
4398 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
4400 has_terminator
= TRUE
;
4404 g_assert_not_reached ();
4413 case OP_ICOMPARE_IMM
:
4414 case OP_LCOMPARE_IMM
:
4415 case OP_COMPARE_IMM
: {
4417 LLVMValueRef cmp
, args
[16];
4418 gboolean likely
= (ins
->flags
& MONO_INST_LIKELY
) != 0;
4420 if (ins
->next
->opcode
== OP_NOP
)
4423 if (ins
->next
->opcode
== OP_BR
)
4424 /* The comparison result is not needed */
4427 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
4429 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
4430 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4431 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4433 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
4434 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
4435 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4437 if (ins
->opcode
== OP_LCOMPARE
) {
4438 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
4439 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
4441 if (ins
->opcode
== OP_ICOMPARE
) {
4442 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4443 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
4447 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
4448 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
4449 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
4450 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
4453 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4454 if (ins
->opcode
== OP_FCOMPARE
) {
4455 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
4456 } else if (ins
->opcode
== OP_RCOMPARE
) {
4457 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
4458 } else if (ins
->opcode
== OP_COMPARE_IMM
) {
4459 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& ins
->inst_imm
== 0)
4460 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), "");
4462 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
4463 } else if (ins
->opcode
== OP_LCOMPARE_IMM
) {
4464 if (SIZEOF_REGISTER
== 4 && COMPILE_LLVM (cfg
)) {
4465 /* The immediate is encoded in two fields */
4466 guint64 l
= ((guint64
)(guint32
)ins
->inst_offset
<< 32) | ((guint32
)ins
->inst_imm
);
4467 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l
, FALSE
), "");
4469 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins
->inst_imm
, FALSE
), "");
4472 else if (ins
->opcode
== OP_COMPARE
) {
4473 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& LLVMTypeOf (lhs
) == LLVMTypeOf (rhs
))
4474 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
4476 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
4478 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
4482 args
[1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
4483 cmp
= LLVMBuildCall (ctx
->builder
, get_intrinsic (ctx
, "llvm.expect.i1"), args
, 2, "");
4486 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
4487 if (ins
->next
->inst_true_bb
== ins
->next
->inst_false_bb
) {
4489 * If the target bb contains PHI instructions, LLVM requires
4490 * two PHI entries for this bblock, while we only generate one.
4491 * So convert this to an unconditional bblock. (bxc #171).
4493 LLVMBuildBr (builder
, get_bb (ctx
, ins
->next
->inst_true_bb
));
4495 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
4497 has_terminator
= TRUE
;
4498 } else if (MONO_IS_SETCC (ins
->next
)) {
4499 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
4501 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4503 /* Add stores for volatile variables */
4504 emit_volatile_store (ctx
, ins
->next
->dreg
);
4505 } else if (MONO_IS_COND_EXC (ins
->next
)) {
4506 emit_cond_system_exception (ctx
, bb
, (const char*)ins
->next
->inst_p1
, cmp
);
4509 builder
= ctx
->builder
;
4511 set_failure (ctx
, "next");
4529 rel
= mono_opcode_to_cond (ins
->opcode
);
4531 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
4532 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4543 rel
= mono_opcode_to_cond (ins
->opcode
);
4545 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
4546 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4554 gboolean empty
= TRUE
;
4556 /* Check that all input bblocks really branch to us */
4557 for (i
= 0; i
< bb
->in_count
; ++i
) {
4558 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
4559 ins
->inst_phi_args
[i
+ 1] = -1;
4565 /* LLVM doesn't like phi instructions with zero operands */
4566 ctx
->is_dead
[ins
->dreg
] = TRUE
;
4570 /* Created earlier, insert it now */
4571 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
4573 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
4574 int sreg1
= ins
->inst_phi_args
[i
+ 1];
4578 * Count the number of times the incoming bblock branches to us,
4579 * since llvm requires a separate entry for each.
4581 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
4582 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
4585 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
4586 if (switch_ins
->inst_many_bb
[j
] == bb
)
4593 /* Remember for later */
4594 for (j
= 0; j
< count
; ++j
) {
4595 PhiNode
*node
= (PhiNode
*)mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
4598 node
->in_bb
= bb
->in_bb
[i
];
4600 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
);
4610 values
[ins
->dreg
] = lhs
;
4614 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
4617 values
[ins
->dreg
] = lhs
;
4619 if (var
&& var
->klass
->byval_arg
.type
== MONO_TYPE_R4
) {
4621 * This is added by the spilling pass in case of the JIT,
4622 * but we have to do it ourselves.
4624 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
4628 case OP_MOVE_F_TO_I4
: {
4629 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), ""), LLVMInt32Type (), "");
4632 case OP_MOVE_I4_TO_F
: {
4633 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, LLVMBuildBitCast (builder
, lhs
, LLVMFloatType (), ""), LLVMDoubleType (), "");
4636 case OP_MOVE_F_TO_I8
: {
4637 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMInt64Type (), "");
4640 case OP_MOVE_I8_TO_F
: {
4641 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMDoubleType (), "");
4674 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
4675 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
4677 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, rhs
);
4680 builder
= ctx
->builder
;
4682 switch (ins
->opcode
) {
4685 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
4689 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
4693 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
4697 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
4701 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
4705 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
4709 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
4713 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
4717 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
4721 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
4725 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
4729 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
4733 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
4737 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
4741 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
4744 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
4747 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
4751 g_assert_not_reached ();
4758 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
4759 rhs
= convert (ctx
, rhs
, LLVMFloatType ());
4760 switch (ins
->opcode
) {
4762 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
4765 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
4768 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
4771 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
4774 g_assert_not_reached ();
4783 case OP_IREM_UN_IMM
:
4785 case OP_IDIV_UN_IMM
:
4791 case OP_ISHR_UN_IMM
:
4801 case OP_LSHR_UN_IMM
:
4807 case OP_SHR_UN_IMM
: {
4810 if (spec
[MONO_INST_SRC1
] == 'l') {
4811 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4813 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4816 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, imm
);
4819 builder
= ctx
->builder
;
4821 #if SIZEOF_VOID_P == 4
4822 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
4823 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4826 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
4827 lhs
= convert (ctx
, lhs
, IntPtrType ());
4828 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
4829 switch (ins
->opcode
) {
4833 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
4837 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
4842 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
4846 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
4848 case OP_IDIV_UN_IMM
:
4849 case OP_LDIV_UN_IMM
:
4850 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
4854 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
4856 case OP_IREM_UN_IMM
:
4857 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
4862 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
4866 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
4870 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
4875 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
4880 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
4882 case OP_ISHR_UN_IMM
:
4883 /* This is used to implement conv.u4, so the lhs could be an i8 */
4884 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4885 imm
= convert (ctx
, imm
, LLVMInt32Type ());
4886 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
4888 case OP_LSHR_UN_IMM
:
4890 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
4893 g_assert_not_reached ();
4898 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
4901 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
4904 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
4905 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
4908 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
4909 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMFloatType (), 0.0), lhs
, dname
);
4912 guint32 v
= 0xffffffff;
4913 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
4917 guint64 v
= 0xffffffffffffffffLL
;
4918 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
4921 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4923 LLVMValueRef v1
, v2
;
4925 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins
->backend
.shift_amount
), FALSE
), "");
4926 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
4927 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
4932 case OP_ICONV_TO_I1
:
4933 case OP_ICONV_TO_I2
:
4934 case OP_ICONV_TO_I4
:
4935 case OP_ICONV_TO_U1
:
4936 case OP_ICONV_TO_U2
:
4937 case OP_ICONV_TO_U4
:
4938 case OP_LCONV_TO_I1
:
4939 case OP_LCONV_TO_I2
:
4940 case OP_LCONV_TO_U1
:
4941 case OP_LCONV_TO_U2
:
4942 case OP_LCONV_TO_U4
: {
4945 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
);
4947 /* Have to do two casts since our vregs have type int */
4948 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
4950 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
4952 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
4955 case OP_ICONV_TO_I8
:
4956 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
4958 case OP_ICONV_TO_U8
:
4959 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
4961 case OP_FCONV_TO_I4
:
4962 case OP_RCONV_TO_I4
:
4963 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
4965 case OP_FCONV_TO_I1
:
4966 case OP_RCONV_TO_I1
:
4967 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
4969 case OP_FCONV_TO_U1
:
4970 case OP_RCONV_TO_U1
:
4971 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildTrunc (builder
, LLVMBuildFPToUI (builder
, lhs
, IntPtrType (), dname
), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4973 case OP_FCONV_TO_I2
:
4974 case OP_RCONV_TO_I2
:
4975 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
4977 case OP_FCONV_TO_U2
:
4978 case OP_RCONV_TO_U2
:
4979 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
4981 case OP_RCONV_TO_U4
:
4982 values
[ins
->dreg
] = LLVMBuildFPToUI (builder
, lhs
, LLVMInt32Type (), dname
);
4984 case OP_FCONV_TO_I8
:
4985 case OP_RCONV_TO_I8
:
4986 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
4989 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
4991 case OP_ICONV_TO_R8
:
4992 case OP_LCONV_TO_R8
:
4993 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
4995 case OP_ICONV_TO_R_UN
:
4996 case OP_LCONV_TO_R_UN
:
4997 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
4999 #if SIZEOF_VOID_P == 4
5002 case OP_LCONV_TO_I4
:
5003 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5005 case OP_ICONV_TO_R4
:
5006 case OP_LCONV_TO_R4
:
5007 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
5009 values
[ins
->dreg
] = v
;
5011 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5013 case OP_FCONV_TO_R4
:
5014 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
5016 values
[ins
->dreg
] = v
;
5018 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5020 case OP_RCONV_TO_R8
:
5021 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, lhs
, LLVMDoubleType (), dname
);
5023 case OP_RCONV_TO_R4
:
5024 values
[ins
->dreg
] = lhs
;
5027 values
[ins
->dreg
] = LLVMBuildSExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5030 values
[ins
->dreg
] = LLVMBuildZExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5033 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5035 case OP_LOCALLOC_IMM
: {
5038 guint32 size
= ins
->inst_imm
;
5039 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
5041 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
5043 if (ins
->flags
& MONO_INST_INIT
) {
5044 LLVMValueRef args
[5];
5047 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5048 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
5049 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5050 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5051 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5054 values
[ins
->dreg
] = v
;
5058 LLVMValueRef v
, size
;
5060 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
), "");
5062 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
5064 if (ins
->flags
& MONO_INST_INIT
) {
5065 LLVMValueRef args
[5];
5068 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5070 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5071 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5072 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5074 values
[ins
->dreg
] = v
;
5078 case OP_LOADI1_MEMBASE
:
5079 case OP_LOADU1_MEMBASE
:
5080 case OP_LOADI2_MEMBASE
:
5081 case OP_LOADU2_MEMBASE
:
5082 case OP_LOADI4_MEMBASE
:
5083 case OP_LOADU4_MEMBASE
:
5084 case OP_LOADI8_MEMBASE
:
5085 case OP_LOADR4_MEMBASE
:
5086 case OP_LOADR8_MEMBASE
:
5087 case OP_LOAD_MEMBASE
:
5095 LLVMValueRef base
, index
, addr
;
5097 gboolean sext
= FALSE
, zext
= FALSE
;
5098 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5100 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5105 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
)) {
5106 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
5112 if (ins
->inst_offset
== 0) {
5114 } else if (ins
->inst_offset
% size
!= 0) {
5115 /* Unaligned load */
5116 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5117 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5119 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5120 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5124 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
5126 values
[ins
->dreg
] = emit_load_general (ctx
, bb
, &builder
, size
, addr
, base
, dname
, is_volatile
, LLVM_BARRIER_NONE
);
5128 if (!is_volatile
&& (ins
->flags
& MONO_INST_INVARIANT_LOAD
)) {
5130 * These will signal LLVM that these loads do not alias any stores, and
5131 * they can't fail, allowing them to be hoisted out of loops.
5133 set_invariant_load_flag (values
[ins
->dreg
]);
5134 #if LLVM_API_VERSION < 100
5135 set_metadata_flag (values
[ins
->dreg
], "mono.nofail.load");
5140 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5142 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5143 else if (!cfg
->r4fp
&& ins
->opcode
== OP_LOADR4_MEMBASE
)
5144 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
5148 case OP_STOREI1_MEMBASE_REG
:
5149 case OP_STOREI2_MEMBASE_REG
:
5150 case OP_STOREI4_MEMBASE_REG
:
5151 case OP_STOREI8_MEMBASE_REG
:
5152 case OP_STORER4_MEMBASE_REG
:
5153 case OP_STORER8_MEMBASE_REG
:
5154 case OP_STORE_MEMBASE_REG
: {
5156 LLVMValueRef index
, addr
, base
;
5158 gboolean sext
= FALSE
, zext
= FALSE
;
5159 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5161 if (!values
[ins
->inst_destbasereg
]) {
5162 set_failure (ctx
, "inst_destbasereg");
5166 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5168 base
= values
[ins
->inst_destbasereg
];
5169 if (ins
->inst_offset
% size
!= 0) {
5170 /* Unaligned store */
5171 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5172 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5174 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5175 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5177 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5181 case OP_STOREI1_MEMBASE_IMM
:
5182 case OP_STOREI2_MEMBASE_IMM
:
5183 case OP_STOREI4_MEMBASE_IMM
:
5184 case OP_STOREI8_MEMBASE_IMM
:
5185 case OP_STORE_MEMBASE_IMM
: {
5187 LLVMValueRef index
, addr
, base
;
5189 gboolean sext
= FALSE
, zext
= FALSE
;
5190 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5192 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5194 base
= values
[ins
->inst_destbasereg
];
5195 if (ins
->inst_offset
% size
!= 0) {
5196 /* Unaligned store */
5197 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5198 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5200 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5201 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5203 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5208 emit_load_general (ctx
, bb
, &builder
, sizeof (gpointer
), convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), lhs
, "", TRUE
, LLVM_BARRIER_NONE
);
5210 case OP_OUTARG_VTRETADDR
:
5218 case OP_VOIDCALL_MEMBASE
:
5219 case OP_CALL_MEMBASE
:
5220 case OP_LCALL_MEMBASE
:
5221 case OP_FCALL_MEMBASE
:
5222 case OP_RCALL_MEMBASE
:
5223 case OP_VCALL_MEMBASE
:
5224 case OP_VOIDCALL_REG
:
5229 case OP_VCALL_REG
: {
5230 process_call (ctx
, bb
, &builder
, ins
);
5235 LLVMValueRef indexes
[2];
5236 MonoJumpInfo
*tmp_ji
, *ji
;
5237 LLVMValueRef got_entry_addr
;
5241 * FIXME: Can't allocate from the cfg mempool since that is freed if
5242 * the LLVM compile fails.
5244 tmp_ji
= g_new0 (MonoJumpInfo
, 1);
5245 tmp_ji
->type
= (MonoJumpInfoType
)ins
->inst_c1
;
5246 tmp_ji
->data
.target
= ins
->inst_p0
;
5248 ji
= mono_aot_patch_info_dup (tmp_ji
);
5251 if (ji
->type
== MONO_PATCH_INFO_ICALL_ADDR
) {
5252 char *symbol
= mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL
, ji
->data
.target
);
5255 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5256 * resolvable at runtime using dlsym ().
5259 values
[ins
->dreg
] = LLVMConstInt (IntPtrType (), 0, FALSE
);
5264 ji
->next
= cfg
->patch_info
;
5265 cfg
->patch_info
= ji
;
5267 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5268 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
5269 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
5270 if (!mono_aot_is_shared_got_offset (got_offset
)) {
5271 //mono_print_ji (ji);
5273 ctx
->has_got_access
= TRUE
;
5276 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5277 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
5278 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
5280 name
= get_aotconst_name (ji
->type
, ji
->data
.target
, got_offset
);
5281 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, name
);
5283 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5284 if (!cfg
->llvm_only
)
5285 set_invariant_load_flag (values
[ins
->dreg
]);
5288 case OP_NOT_REACHED
:
5289 LLVMBuildUnreachable (builder
);
5290 has_terminator
= TRUE
;
5291 g_assert (bb
->block_num
< cfg
->max_block_num
);
5292 ctx
->unreachable
[bb
->block_num
] = TRUE
;
5293 /* Might have instructions after this */
5295 MonoInst
*next
= ins
->next
;
5297 * FIXME: If later code uses the regs defined by these instructions,
5298 * compilation will fail.
5300 MONO_DELETE_INS (bb
, next
);
5304 MonoInst
*var
= ins
->inst_i0
;
5306 if (var
->opcode
== OP_VTARG_ADDR
) {
5307 /* The variable contains the vtype address */
5308 values
[ins
->dreg
] = values
[var
->dreg
];
5309 } else if (var
->opcode
== OP_GSHAREDVT_LOCAL
) {
5310 values
[ins
->dreg
] = emit_gsharedvt_ldaddr (ctx
, var
->dreg
);
5312 values
[ins
->dreg
] = addresses
[var
->dreg
];
5317 LLVMValueRef args
[1];
5319 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5320 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.sin.f64"), args
, 1, dname
);
5324 LLVMValueRef args
[1];
5326 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5327 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.cos.f64"), args
, 1, dname
);
5331 LLVMValueRef args
[1];
5333 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5334 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.sqrt.f64"), args
, 1, dname
);
5338 LLVMValueRef args
[1];
5340 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5341 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "fabs"), args
, 1, dname
);
5355 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5356 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5358 switch (ins
->opcode
) {
5361 v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
5365 v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
5369 v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
5373 v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
5376 g_assert_not_reached ();
5379 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
5384 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5385 * hack is necessary (for now).
5388 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5390 #define ARM64_ATOMIC_FENCE_FIX
5393 case OP_ATOMIC_EXCHANGE_I4
:
5394 case OP_ATOMIC_EXCHANGE_I8
: {
5395 LLVMValueRef args
[2];
5398 if (ins
->opcode
== OP_ATOMIC_EXCHANGE_I4
)
5399 t
= LLVMInt32Type ();
5401 t
= LLVMInt64Type ();
5403 g_assert (ins
->inst_offset
== 0);
5405 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
5406 args
[1] = convert (ctx
, rhs
, t
);
5408 ARM64_ATOMIC_FENCE_FIX
;
5409 values
[ins
->dreg
] = mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_XCHG
, args
[0], args
[1]);
5410 ARM64_ATOMIC_FENCE_FIX
;
5413 case OP_ATOMIC_ADD_I4
:
5414 case OP_ATOMIC_ADD_I8
: {
5415 LLVMValueRef args
[2];
5418 if (ins
->opcode
== OP_ATOMIC_ADD_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
);
5427 ARM64_ATOMIC_FENCE_FIX
;
5428 values
[ins
->dreg
] = LLVMBuildAdd (builder
, mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_ADD
, args
[0], args
[1]), args
[1], dname
);
5429 ARM64_ATOMIC_FENCE_FIX
;
5432 case OP_ATOMIC_CAS_I4
:
5433 case OP_ATOMIC_CAS_I8
: {
5434 LLVMValueRef args
[3], val
;
5437 if (ins
->opcode
== OP_ATOMIC_CAS_I4
)
5438 t
= LLVMInt32Type ();
5440 t
= LLVMInt64Type ();
5442 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
5444 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
5446 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
5447 ARM64_ATOMIC_FENCE_FIX
;
5448 val
= mono_llvm_build_cmpxchg (builder
, args
[0], args
[1], args
[2]);
5449 ARM64_ATOMIC_FENCE_FIX
;
5450 /* cmpxchg returns a pair */
5451 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, "");
5454 case OP_MEMORY_BARRIER
: {
5455 mono_llvm_build_fence (builder
, (BarrierKind
) ins
->backend
.memory_barrier_kind
);
5458 case OP_ATOMIC_LOAD_I1
:
5459 case OP_ATOMIC_LOAD_I2
:
5460 case OP_ATOMIC_LOAD_I4
:
5461 case OP_ATOMIC_LOAD_I8
:
5462 case OP_ATOMIC_LOAD_U1
:
5463 case OP_ATOMIC_LOAD_U2
:
5464 case OP_ATOMIC_LOAD_U4
:
5465 case OP_ATOMIC_LOAD_U8
:
5466 case OP_ATOMIC_LOAD_R4
:
5467 case OP_ATOMIC_LOAD_R8
: {
5468 #if LLVM_API_VERSION > 100
5470 gboolean sext
, zext
;
5472 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5473 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
5474 LLVMValueRef index
, addr
;
5476 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5481 if (ins
->inst_offset
!= 0) {
5482 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5483 addr
= LLVMBuildGEP (builder
, convert (ctx
, lhs
, LLVMPointerType (t
, 0)), &index
, 1, "");
5488 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
5490 ARM64_ATOMIC_FENCE_FIX
;
5491 values
[ins
->dreg
] = emit_load_general (ctx
, bb
, &builder
, size
, addr
, lhs
, dname
, is_volatile
, barrier
);
5492 ARM64_ATOMIC_FENCE_FIX
;
5495 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5497 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5500 set_failure (ctx
, "atomic mono.load intrinsic");
5504 case OP_ATOMIC_STORE_I1
:
5505 case OP_ATOMIC_STORE_I2
:
5506 case OP_ATOMIC_STORE_I4
:
5507 case OP_ATOMIC_STORE_I8
:
5508 case OP_ATOMIC_STORE_U1
:
5509 case OP_ATOMIC_STORE_U2
:
5510 case OP_ATOMIC_STORE_U4
:
5511 case OP_ATOMIC_STORE_U8
:
5512 case OP_ATOMIC_STORE_R4
:
5513 case OP_ATOMIC_STORE_R8
: {
5515 gboolean sext
, zext
;
5517 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5518 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
5519 LLVMValueRef index
, addr
, value
, base
;
5521 #if LLVM_API_VERSION < 100
5522 if (!cfg
->llvm_only
) {
5523 set_failure (ctx
, "atomic mono.store intrinsic");
5528 if (!values
[ins
->inst_destbasereg
]) {
5529 set_failure (ctx
, "inst_destbasereg");
5533 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5535 base
= values
[ins
->inst_destbasereg
];
5536 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5537 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5538 value
= convert (ctx
, values
[ins
->sreg1
], t
);
5540 ARM64_ATOMIC_FENCE_FIX
;
5541 emit_store_general (ctx
, bb
, &builder
, size
, value
, addr
, base
, is_volatile
, barrier
);
5542 ARM64_ATOMIC_FENCE_FIX
;
5545 case OP_RELAXED_NOP
: {
5546 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5547 emit_call (ctx
, bb
, &builder
, get_intrinsic (ctx
, "llvm.x86.sse2.pause"), NULL
, 0);
5554 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5556 // 257 == FS segment register
5557 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
5559 // 256 == GS segment register
5560 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5563 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
5564 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5565 /* See mono_amd64_emit_tls_get () */
5566 int offset
= mono_amd64_get_tls_gs_offset () + (ins
->inst_offset
* 8);
5568 // 256 == GS segment register
5569 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5570 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), offset
, TRUE
), ptrtype
, ""), "");
5572 set_failure (ctx
, "opcode tls-get");
5578 case OP_TLS_GET_REG
: {
5579 #if defined(TARGET_AMD64) && defined(__linux__)
5580 // 257 == FS segment register
5581 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
5582 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, convert (ctx
, lhs
, LLVMInt64Type ()), ptrtype
, ""), "");
5583 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5584 /* See emit_tls_get_reg () */
5585 // 256 == GS segment register
5586 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5587 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), ptrtype
, ""), "");
5589 set_failure (ctx
, "opcode tls-get");
5595 case OP_TLS_SET_REG
: {
5596 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5597 /* See emit_tls_get_reg () */
5598 // 256 == GS segment register
5599 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5600 LLVMBuildStore (builder
, convert (ctx
, lhs
, IntPtrType ()), LLVMBuildIntToPtr (builder
, convert (ctx
, rhs
, LLVMInt32Type ()), ptrtype
, ""));
5602 set_failure (ctx
, "opcode tls-set-reg");
5607 case OP_GC_SAFE_POINT
: {
5608 LLVMValueRef val
, cmp
, callee
;
5609 LLVMBasicBlockRef poll_bb
, cont_bb
;
5610 static LLVMTypeRef sig
;
5611 const char *icall_name
= "mono_threads_state_poll";
5614 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
5618 * mono_threads_state_poll ();
5619 * FIXME: Use a preserveall wrapper
5621 val
= mono_llvm_build_load (builder
, convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
5622 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, val
, LLVMConstNull (LLVMTypeOf (val
)), "");
5623 poll_bb
= gen_bb (ctx
, "POLL_BB");
5624 cont_bb
= gen_bb (ctx
, "CONT_BB");
5625 LLVMBuildCondBr (builder
, cmp
, cont_bb
, poll_bb
);
5627 ctx
->builder
= builder
= create_builder (ctx
);
5628 LLVMPositionBuilderAtEnd (builder
, poll_bb
);
5630 if (ctx
->cfg
->compile_aot
) {
5631 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
5633 gpointer target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
5634 callee
= emit_jit_callee (ctx
, icall_name
, sig
, target
);
5636 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
5637 LLVMBuildBr (builder
, cont_bb
);
5639 ctx
->builder
= builder
= create_builder (ctx
);
5640 LLVMPositionBuilderAtEnd (builder
, cont_bb
);
5641 ctx
->bblocks
[bb
->block_num
].end_bblock
= cont_bb
;
5649 case OP_IADD_OVF_UN
:
5651 case OP_ISUB_OVF_UN
:
5653 case OP_IMUL_OVF_UN
:
5655 case OP_LADD_OVF_UN
:
5657 case OP_LSUB_OVF_UN
:
5659 case OP_LMUL_OVF_UN
:
5661 LLVMValueRef args
[2], val
, ovf
, func
;
5663 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
5664 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
5665 func
= get_intrinsic (ctx
, ovf_op_to_intrins (ins
->opcode
));
5667 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
5668 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
5669 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
5670 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
5673 builder
= ctx
->builder
;
5679 * We currently model them using arrays. Promotion to local vregs is
5680 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5681 * so we always have an entry in cfg->varinfo for them.
5682 * FIXME: Is this needed ?
5685 MonoClass
*klass
= ins
->klass
;
5686 LLVMValueRef args
[5];
5690 set_failure (ctx
, "!klass");
5694 if (!addresses
[ins
->dreg
])
5695 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5696 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5697 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5698 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
5700 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5701 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5702 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5705 case OP_DUMMY_VZERO
:
5708 case OP_STOREV_MEMBASE
:
5709 case OP_LOADV_MEMBASE
:
5711 MonoClass
*klass
= ins
->klass
;
5712 LLVMValueRef src
= NULL
, dst
, args
[5];
5713 gboolean done
= FALSE
;
5717 set_failure (ctx
, "!klass");
5721 if (mini_is_gsharedvt_klass (klass
)) {
5723 set_failure (ctx
, "gsharedvt");
5727 switch (ins
->opcode
) {
5728 case OP_STOREV_MEMBASE
:
5729 if (cfg
->gen_write_barriers
&& klass
->has_references
&& ins
->inst_destbasereg
!= cfg
->frame_reg
&&
5730 LLVMGetInstructionOpcode (values
[ins
->inst_destbasereg
]) != LLVMAlloca
) {
5731 /* Decomposed earlier */
5732 g_assert_not_reached ();
5735 if (!addresses
[ins
->sreg1
]) {
5737 g_assert (values
[ins
->sreg1
]);
5738 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));
5739 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
5742 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
5743 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
5746 case OP_LOADV_MEMBASE
:
5747 if (!addresses
[ins
->dreg
])
5748 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5749 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
5750 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5753 if (!addresses
[ins
->sreg1
])
5754 addresses
[ins
->sreg1
] = build_alloca (ctx
, &klass
->byval_arg
);
5755 if (!addresses
[ins
->dreg
])
5756 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5757 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
5758 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5761 g_assert_not_reached ();
5771 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
5772 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5774 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5775 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5776 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memcpy.p0i8.p0i8.i32"), args
, 5, "");
5779 case OP_LLVM_OUTARG_VT
: {
5780 LLVMArgInfo
*ainfo
= (LLVMArgInfo
*)ins
->inst_p0
;
5781 MonoType
*t
= mini_get_underlying_type (ins
->inst_vtype
);
5783 if (ainfo
->storage
== LLVMArgGsharedvtVariable
) {
5784 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
5786 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
5787 addresses
[ins
->dreg
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), LLVMPointerType (IntPtrType (), 0));
5789 g_assert (addresses
[ins
->sreg1
]);
5790 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5792 } else if (ainfo
->storage
== LLVMArgGsharedvtFixed
) {
5793 if (!addresses
[ins
->sreg1
]) {
5794 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
5795 g_assert (values
[ins
->sreg1
]);
5797 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (LLVMTypeOf (addresses
[ins
->sreg1
]))), addresses
[ins
->sreg1
]);
5798 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5800 if (!addresses
[ins
->sreg1
]) {
5801 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
5802 g_assert (values
[ins
->sreg1
]);
5803 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, t
)), addresses
[ins
->sreg1
]);
5805 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5809 case OP_OBJC_GET_SELECTOR
: {
5810 const char *name
= (const char*)ins
->inst_p0
;
5813 if (!ctx
->module
->objc_selector_to_var
)
5814 ctx
->module
->objc_selector_to_var
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
5815 var
= g_hash_table_lookup (ctx
->module
->objc_selector_to_var
, name
);
5817 LLVMValueRef indexes
[16];
5819 LLVMValueRef name_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMArrayType (LLVMInt8Type (), strlen (name
) + 1), "@OBJC_METH_VAR_NAME_");
5820 LLVMSetInitializer (name_var
, mono_llvm_create_constant_data_array ((const uint8_t*)name
, strlen (name
) + 1));
5821 LLVMSetLinkage (name_var
, LLVMPrivateLinkage
);
5822 LLVMSetSection (name_var
, "__TEXT,__objc_methname,cstring_literals");
5823 mark_as_used (ctx
->module
, name_var
);
5825 LLVMValueRef ref_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5827 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5828 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5829 LLVMSetInitializer (ref_var
, LLVMConstGEP (name_var
, indexes
, 2));
5830 LLVMSetLinkage (ref_var
, LLVMPrivateLinkage
);
5831 LLVMSetExternallyInitialized (ref_var
, TRUE
);
5832 LLVMSetSection (ref_var
, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5833 LLVMSetAlignment (ref_var
, sizeof (mgreg_t
));
5834 mark_as_used (ctx
->module
, ref_var
);
5836 g_hash_table_insert (ctx
->module
->objc_selector_to_var
, g_strdup (name
), ref_var
);
5840 values
[ins
->dreg
] = LLVMBuildLoad (builder
, var
, "");
5847 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5849 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
5852 case OP_LOADX_MEMBASE
: {
5853 LLVMTypeRef t
= type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
);
5856 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
5857 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
5860 case OP_STOREX_MEMBASE
: {
5861 LLVMTypeRef t
= LLVMTypeOf (values
[ins
->sreg1
]);
5864 dest
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
5865 mono_llvm_build_aligned_store (builder
, values
[ins
->sreg1
], dest
, FALSE
, 1);
5872 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
5876 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
5882 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
5886 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
5890 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
5894 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
5897 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
5900 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
5903 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
5907 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, "");
5918 LLVMValueRef v
= NULL
;
5920 switch (ins
->opcode
) {
5925 t
= LLVMVectorType (LLVMInt32Type (), 4);
5926 rt
= LLVMVectorType (LLVMFloatType (), 4);
5932 t
= LLVMVectorType (LLVMInt64Type (), 2);
5933 rt
= LLVMVectorType (LLVMDoubleType (), 2);
5936 t
= LLVMInt32Type ();
5937 rt
= LLVMInt32Type ();
5938 g_assert_not_reached ();
5941 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
5942 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
5943 switch (ins
->opcode
) {
5946 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
5950 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
5954 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
5958 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
5961 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
5967 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntULT
, lhs
, rhs
, "");
5968 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
5974 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntUGT
, lhs
, rhs
, "");
5975 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
5979 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntSLT
, lhs
, rhs
, "");
5980 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
5997 case OP_PADDB_SAT_UN
:
5998 case OP_PADDW_SAT_UN
:
5999 case OP_PSUBB_SAT_UN
:
6000 case OP_PSUBW_SAT_UN
:
6008 case OP_PMULW_HIGH_UN
: {
6009 LLVMValueRef args
[2];
6014 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6021 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
6025 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntSGT
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
6033 case OP_EXTRACTX_U2
:
6035 case OP_EXTRACT_U1
: {
6037 gboolean zext
= FALSE
;
6039 t
= simd_op_to_llvm_type (ins
->opcode
);
6041 switch (ins
->opcode
) {
6049 case OP_EXTRACTX_U2
:
6054 t
= LLVMInt32Type ();
6055 g_assert_not_reached ();
6058 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
6059 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
6061 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
6070 case OP_EXPAND_R8
: {
6071 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6072 LLVMValueRef mask
[16], v
;
6075 for (i
= 0; i
< 16; ++i
)
6076 mask
[i
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6078 v
= convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (t
));
6080 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (t
), v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6081 values
[ins
->dreg
] = LLVMBuildShuffleVector (builder
, values
[ins
->dreg
], LLVMGetUndef (t
), LLVMConstVector (mask
, LLVMGetVectorSize (t
)), "");
6086 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6089 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6092 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6095 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6098 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6101 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6105 // Requires a later llvm version
6107 LLVMValueRef indexes
[16];
6109 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6110 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
6111 LLVMValueRef mask
= LLVMConstVector (indexes
, 2);
6112 LLVMValueRef shuffle
= LLVMBuildShuffleVector (builder
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), mask
, "");
6113 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, shuffle
, LLVMVectorType (LLVMDoubleType (), 2), dname
);
6117 LLVMValueRef indexes
[16];
6119 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6120 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
6121 LLVMValueRef mask
= LLVMConstVector (indexes
, 2);
6122 LLVMValueRef shuffle
= LLVMBuildShuffleVector (builder
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), mask
, "");
6123 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, shuffle
, LLVMVectorType (LLVMDoubleType (), 2), dname
);
6127 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMVectorType (LLVMInt32Type (), 4), dname
);
6139 case OP_EXTRACT_MASK
:
6146 v
= convert (ctx
, values
[ins
->sreg1
], simd_op_to_llvm_type (ins
->opcode
));
6148 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), &v
, 1, dname
);
6153 LLVMRealPredicate op
;
6155 switch (ins
->inst_c0
) {
6165 case SIMD_COMP_UNORD
:
6181 g_assert_not_reached ();
6184 LLVMValueRef cmp
= LLVMBuildFCmp (builder
, op
, lhs
, rhs
, "");
6185 if (ins
->opcode
== OP_COMPPD
)
6186 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs
), "");
6188 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs
), "");
6192 /* This is only used for implementing shifts by non-immediate */
6193 values
[ins
->dreg
] = lhs
;
6204 LLVMValueRef args
[3];
6207 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
6209 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6220 case OP_PSHLQ_REG
: {
6221 LLVMValueRef args
[3];
6224 args
[1] = values
[ins
->sreg2
];
6226 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6233 case OP_PSHUFLEW_LOW
:
6234 case OP_PSHUFLEW_HIGH
: {
6236 LLVMValueRef v1
= NULL
, v2
= NULL
, mask_values
[16];
6237 int i
, mask_size
= 0;
6238 int imask
= ins
->inst_c0
;
6240 /* Convert the x86 shuffle mask to LLVM's */
6241 switch (ins
->opcode
) {
6244 mask
[0] = ((imask
>> 0) & 3);
6245 mask
[1] = ((imask
>> 2) & 3);
6246 mask
[2] = ((imask
>> 4) & 3) + 4;
6247 mask
[3] = ((imask
>> 6) & 3) + 4;
6248 v1
= values
[ins
->sreg1
];
6249 v2
= values
[ins
->sreg2
];
6253 mask
[0] = ((imask
>> 0) & 1);
6254 mask
[1] = ((imask
>> 1) & 1) + 2;
6255 v1
= values
[ins
->sreg1
];
6256 v2
= values
[ins
->sreg2
];
6258 case OP_PSHUFLEW_LOW
:
6260 mask
[0] = ((imask
>> 0) & 3);
6261 mask
[1] = ((imask
>> 2) & 3);
6262 mask
[2] = ((imask
>> 4) & 3);
6263 mask
[3] = ((imask
>> 6) & 3);
6268 v1
= values
[ins
->sreg1
];
6269 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6271 case OP_PSHUFLEW_HIGH
:
6277 mask
[4] = 4 + ((imask
>> 0) & 3);
6278 mask
[5] = 4 + ((imask
>> 2) & 3);
6279 mask
[6] = 4 + ((imask
>> 4) & 3);
6280 mask
[7] = 4 + ((imask
>> 6) & 3);
6281 v1
= values
[ins
->sreg1
];
6282 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6286 mask
[0] = ((imask
>> 0) & 3);
6287 mask
[1] = ((imask
>> 2) & 3);
6288 mask
[2] = ((imask
>> 4) & 3);
6289 mask
[3] = ((imask
>> 6) & 3);
6290 v1
= values
[ins
->sreg1
];
6291 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6294 g_assert_not_reached ();
6296 for (i
= 0; i
< mask_size
; ++i
)
6297 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
6299 values
[ins
->dreg
] =
6300 LLVMBuildShuffleVector (builder
, v1
, v2
,
6301 LLVMConstVector (mask_values
, mask_size
), dname
);
6305 case OP_UNPACK_LOWB
:
6306 case OP_UNPACK_LOWW
:
6307 case OP_UNPACK_LOWD
:
6308 case OP_UNPACK_LOWQ
:
6309 case OP_UNPACK_LOWPS
:
6310 case OP_UNPACK_LOWPD
:
6311 case OP_UNPACK_HIGHB
:
6312 case OP_UNPACK_HIGHW
:
6313 case OP_UNPACK_HIGHD
:
6314 case OP_UNPACK_HIGHQ
:
6315 case OP_UNPACK_HIGHPS
:
6316 case OP_UNPACK_HIGHPD
: {
6318 LLVMValueRef mask_values
[16];
6319 int i
, mask_size
= 0;
6320 gboolean low
= FALSE
;
6322 switch (ins
->opcode
) {
6323 case OP_UNPACK_LOWB
:
6327 case OP_UNPACK_LOWW
:
6331 case OP_UNPACK_LOWD
:
6332 case OP_UNPACK_LOWPS
:
6336 case OP_UNPACK_LOWQ
:
6337 case OP_UNPACK_LOWPD
:
6341 case OP_UNPACK_HIGHB
:
6344 case OP_UNPACK_HIGHW
:
6347 case OP_UNPACK_HIGHD
:
6348 case OP_UNPACK_HIGHPS
:
6351 case OP_UNPACK_HIGHQ
:
6352 case OP_UNPACK_HIGHPD
:
6356 g_assert_not_reached ();
6360 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
6362 mask
[(i
* 2) + 1] = mask_size
+ i
;
6365 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
6366 mask
[(i
* 2)] = (mask_size
/ 2) + i
;
6367 mask
[(i
* 2) + 1] = mask_size
+ (mask_size
/ 2) + i
;
6371 for (i
= 0; i
< mask_size
; ++i
)
6372 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
6374 values
[ins
->dreg
] =
6375 LLVMBuildShuffleVector (builder
, values
[ins
->sreg1
], values
[ins
->sreg2
],
6376 LLVMConstVector (mask_values
, mask_size
), dname
);
6381 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6382 LLVMValueRef v
, val
;
6384 v
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6385 val
= LLVMConstNull (t
);
6386 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6387 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), dname
);
6389 values
[ins
->dreg
] = val
;
6393 case OP_DUPPS_HIGH
: {
6394 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6395 LLVMValueRef v1
, v2
, val
;
6398 if (ins
->opcode
== OP_DUPPS_LOW
) {
6399 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6400 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
6402 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
6403 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
6405 val
= LLVMConstNull (t
);
6406 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6407 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
6408 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
6409 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
6411 values
[ins
->dreg
] = val
;
6421 * EXCEPTION HANDLING
6423 case OP_IMPLICIT_EXCEPTION
:
6424 /* This marks a place where an implicit exception can happen */
6425 if (bb
->region
!= -1)
6426 set_failure (ctx
, "implicit-exception");
6430 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
6431 if (ctx
->llvm_only
) {
6432 emit_llvmonly_throw (ctx
, bb
, rethrow
, lhs
);
6433 has_terminator
= TRUE
;
6434 ctx
->unreachable
[bb
->block_num
] = TRUE
;
6436 emit_throw (ctx
, bb
, rethrow
, lhs
);
6437 builder
= ctx
->builder
;
6441 case OP_CALL_HANDLER
: {
6443 * We don't 'call' handlers, but instead simply branch to them.
6444 * The code generated by ENDFINALLY will branch back to us.
6446 LLVMBasicBlockRef noex_bb
;
6448 BBInfo
*info
= &bblocks
[ins
->inst_target_bb
->block_num
];
6450 bb_list
= info
->call_handler_return_bbs
;
6453 * Set the indicator variable for the finally clause.
6455 lhs
= info
->finally_ind
;
6457 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
6459 /* Branch to the finally clause */
6460 LLVMBuildBr (builder
, info
->call_handler_target_bb
);
6462 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
6463 info
->call_handler_return_bbs
= g_slist_append_mempool (cfg
->mempool
, info
->call_handler_return_bbs
, noex_bb
);
6465 builder
= ctx
->builder
= create_builder (ctx
);
6466 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
6468 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
6471 case OP_START_HANDLER
: {
6474 case OP_ENDFINALLY
: {
6475 LLVMBasicBlockRef resume_bb
;
6476 MonoBasicBlock
*handler_bb
;
6477 LLVMValueRef val
, switch_ins
, callee
;
6481 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
6482 g_assert (handler_bb
);
6483 info
= &bblocks
[handler_bb
->block_num
];
6484 lhs
= info
->finally_ind
;
6487 bb_list
= info
->call_handler_return_bbs
;
6489 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
6491 /* Load the finally variable */
6492 val
= LLVMBuildLoad (builder
, lhs
, "");
6494 /* Reset the variable */
6495 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
6497 /* Branch to either resume_bb, or to the bblocks in bb_list */
6498 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
6500 * The other targets are added at the end to handle OP_CALL_HANDLER
6501 * opcodes processed later.
6503 info
->endfinally_switch_ins_list
= g_slist_append_mempool (cfg
->mempool
, info
->endfinally_switch_ins_list
, switch_ins
);
6505 builder
= ctx
->builder
= create_builder (ctx
);
6506 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
6508 if (ctx
->llvm_only
) {
6509 emit_resume_eh (ctx
, bb
);
6511 if (ctx
->cfg
->compile_aot
) {
6512 callee
= get_callee (ctx
, LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
), MONO_PATCH_INFO_INTERNAL_METHOD
, "llvm_resume_unwind_trampoline");
6514 #if LLVM_API_VERSION > 100
6515 MonoJitICallInfo
*info
;
6517 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6519 gpointer target
= (void*)info
->func
;
6520 LLVMTypeRef icall_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
6521 callee
= emit_jit_callee (ctx
, "llvm_resume_unwind_trampoline", icall_sig
, target
);
6523 callee
= LLVMGetNamedFunction (ctx
->lmodule
, "llvm_resume_unwind_trampoline");
6526 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
6527 LLVMBuildUnreachable (builder
);
6530 has_terminator
= TRUE
;
6533 case OP_IL_SEQ_POINT
:
6538 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
6539 set_failure (ctx
, reason
);
6547 /* Convert the value to the type required by phi nodes */
6548 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && ctx
->vreg_types
[ins
->dreg
]) {
6549 if (ctx
->is_vphi
[ins
->dreg
])
6551 values
[ins
->dreg
] = addresses
[ins
->dreg
];
6553 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], ctx
->vreg_types
[ins
->dreg
]);
6556 /* Add stores for volatile variables */
6557 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
6558 emit_volatile_store (ctx
, ins
->dreg
);
6564 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0)) {
6565 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
6568 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
) {
6569 emit_dbg_loc (ctx
, builder
, cfg
->header
->code
+ cfg
->header
->code_size
- 1);
6570 LLVMBuildRetVoid (builder
);
6573 if (bb
== cfg
->bb_entry
)
6574 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
6578 * mono_llvm_check_method_supported:
6580 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6581 * compiling a method twice.
6584 mono_llvm_check_method_supported (MonoCompile
*cfg
)
6591 if (cfg
->method
->save_lmf
) {
6592 cfg
->exception_message
= g_strdup ("lmf");
6593 cfg
->disable_llvm
= TRUE
;
6595 if (cfg
->disable_llvm
)
6599 * Nested clauses where one of the clauses is a finally clause is
6600 * not supported, because LLVM can't figure out the control flow,
6601 * probably because we resume exception handling by calling our
6602 * own function instead of using the 'resume' llvm instruction.
6604 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
6605 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
6606 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
6607 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
6609 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6610 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
6611 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6612 cfg
->exception_message
= g_strdup ("nested clauses");
6613 cfg
->disable_llvm
= TRUE
;
6618 if (cfg
->disable_llvm
)
6622 if (cfg
->method
->dynamic
) {
6623 cfg
->exception_message
= g_strdup ("dynamic.");
6624 cfg
->disable_llvm
= TRUE
;
6626 if (cfg
->disable_llvm
)
6630 static LLVMCallInfo
*
6631 get_llvm_call_info (MonoCompile
*cfg
, MonoMethodSignature
*sig
)
6633 LLVMCallInfo
*linfo
;
6636 if (cfg
->gsharedvt
&& cfg
->llvm_only
&& mini_is_gsharedvt_variable_signature (sig
)) {
6640 * Gsharedvt methods have the following calling convention:
6641 * - all arguments are passed by ref, even non generic ones
6642 * - the return value is returned by ref too, using a vret
6643 * argument passed after 'this'.
6645 n
= sig
->param_count
+ sig
->hasthis
;
6646 linfo
= (LLVMCallInfo
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMCallInfo
) + (sizeof (LLVMArgInfo
) * n
));
6650 linfo
->args
[pindex
++].storage
= LLVMArgNormal
;
6652 if (sig
->ret
->type
!= MONO_TYPE_VOID
) {
6653 if (mini_is_gsharedvt_variable_type (sig
->ret
))
6654 linfo
->ret
.storage
= LLVMArgGsharedvtVariable
;
6655 else if (mini_type_is_vtype (sig
->ret
))
6656 linfo
->ret
.storage
= LLVMArgGsharedvtFixedVtype
;
6658 linfo
->ret
.storage
= LLVMArgGsharedvtFixed
;
6659 linfo
->vret_arg_index
= pindex
;
6661 linfo
->ret
.storage
= LLVMArgNone
;
6664 for (i
= 0; i
< sig
->param_count
; ++i
) {
6665 if (sig
->params
[i
]->byref
)
6666 linfo
->args
[pindex
].storage
= LLVMArgNormal
;
6667 else if (mini_is_gsharedvt_variable_type (sig
->params
[i
]))
6668 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtVariable
;
6669 else if (mini_type_is_vtype (sig
->params
[i
]))
6670 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixedVtype
;
6672 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixed
;
6673 linfo
->args
[pindex
].type
= sig
->params
[i
];
6680 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
6681 for (i
= 0; i
< sig
->param_count
; ++i
)
6682 linfo
->args
[i
+ sig
->hasthis
].type
= sig
->params
[i
];
6688 emit_method_inner (EmitContext
*ctx
);
6691 free_ctx (EmitContext
*ctx
)
6695 g_free (ctx
->values
);
6696 g_free (ctx
->addresses
);
6697 g_free (ctx
->vreg_types
);
6698 g_free (ctx
->is_vphi
);
6699 g_free (ctx
->vreg_cli_types
);
6700 g_free (ctx
->is_dead
);
6701 g_free (ctx
->unreachable
);
6702 g_ptr_array_free (ctx
->phi_values
, TRUE
);
6703 g_free (ctx
->bblocks
);
6704 g_hash_table_destroy (ctx
->region_to_handler
);
6705 g_hash_table_destroy (ctx
->clause_to_handler
);
6706 g_hash_table_destroy (ctx
->jit_callees
);
6708 GHashTableIter iter
;
6709 g_hash_table_iter_init (&iter
, ctx
->method_to_callers
);
6710 while (g_hash_table_iter_next (&iter
, NULL
, (gpointer
)&l
))
6713 g_hash_table_destroy (ctx
->method_to_callers
);
6715 g_free (ctx
->method_name
);
6716 g_ptr_array_free (ctx
->bblock_list
, TRUE
);
6718 for (l
= ctx
->builders
; l
; l
= l
->next
) {
6719 LLVMBuilderRef builder
= (LLVMBuilderRef
)l
->data
;
6720 LLVMDisposeBuilder (builder
);
6727 * mono_llvm_emit_method:
6729 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6732 mono_llvm_emit_method (MonoCompile
*cfg
)
6736 gboolean is_linkonce
= FALSE
;
6739 /* The code below might acquire the loader lock, so use it for global locking */
6740 mono_loader_lock ();
6742 /* Used to communicate with the callbacks */
6743 mono_native_tls_set_value (current_cfg_tls_id
, cfg
);
6745 ctx
= g_new0 (EmitContext
, 1);
6747 ctx
->mempool
= cfg
->mempool
;
6750 * This maps vregs to the LLVM instruction defining them
6752 ctx
->values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
6754 * This maps vregs for volatile variables to the LLVM instruction defining their
6757 ctx
->addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
6758 ctx
->vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
6759 ctx
->is_vphi
= g_new0 (gboolean
, cfg
->next_vreg
);
6760 ctx
->vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
6761 ctx
->phi_values
= g_ptr_array_sized_new (256);
6763 * This signals whenever the vreg was defined by a phi node with no input vars
6764 * (i.e. all its input bblocks end with NOT_REACHABLE).
6766 ctx
->is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
6767 /* Whenever the bblock is unreachable */
6768 ctx
->unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
6769 ctx
->bblock_list
= g_ptr_array_sized_new (256);
6771 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
6772 ctx
->clause_to_handler
= g_hash_table_new (NULL
, NULL
);
6773 ctx
->method_to_callers
= g_hash_table_new (NULL
, NULL
);
6774 ctx
->jit_callees
= g_hash_table_new (NULL
, NULL
);
6775 if (cfg
->compile_aot
) {
6776 ctx
->module
= &aot_module
;
6780 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6781 * linkage for them. This requires the following:
6782 * - the method needs to have a unique mangled name
6783 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6785 is_linkonce
= ctx
->module
->llvm_only
&& ctx
->module
->static_link
&& mono_aot_is_linkonce_method (cfg
->method
);
6787 method_name
= mono_aot_get_mangled_method_name (cfg
->method
);
6789 is_linkonce
= FALSE
;
6792 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6794 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6798 method_name
= mono_aot_get_method_name (cfg
);
6799 cfg
->llvm_method_name
= g_strdup (method_name
);
6801 init_jit_module (cfg
->domain
);
6802 ctx
->module
= (MonoLLVMModule
*)domain_jit_info (cfg
->domain
)->llvm_module
;
6803 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
6805 ctx
->method_name
= method_name
;
6806 ctx
->is_linkonce
= is_linkonce
;
6808 #if LLVM_API_VERSION > 100
6809 if (cfg
->compile_aot
)
6810 ctx
->lmodule
= ctx
->module
->lmodule
;
6812 ctx
->lmodule
= LLVMModuleCreateWithName ("jit-module");
6814 ctx
->lmodule
= ctx
->module
->lmodule
;
6816 ctx
->llvm_only
= ctx
->module
->llvm_only
;
6818 emit_method_inner (ctx
);
6820 if (!ctx_ok (ctx
)) {
6822 /* Need to add unused phi nodes as they can be referenced by other values */
6823 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, "PHI_BB");
6824 LLVMBuilderRef builder
;
6826 builder
= create_builder (ctx
);
6827 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
6829 for (i
= 0; i
< ctx
->phi_values
->len
; ++i
) {
6830 LLVMValueRef v
= (LLVMValueRef
)g_ptr_array_index (ctx
->phi_values
, i
);
6831 if (LLVMGetInstructionParent (v
) == NULL
)
6832 LLVMInsertIntoBuilder (builder
, v
);
6835 LLVMDeleteFunction (ctx
->lmethod
);
6841 mono_native_tls_set_value (current_cfg_tls_id
, NULL
);
6843 mono_loader_unlock ();
6847 emit_method_inner (EmitContext
*ctx
)
6849 MonoCompile
*cfg
= ctx
->cfg
;
6850 MonoMethodSignature
*sig
;
6852 LLVMTypeRef method_type
;
6853 LLVMValueRef method
= NULL
;
6854 LLVMValueRef
*values
= ctx
->values
;
6855 int i
, max_block_num
, bb_index
;
6856 gboolean last
= FALSE
;
6857 LLVMCallInfo
*linfo
;
6858 LLVMModuleRef lmodule
= ctx
->lmodule
;
6860 GPtrArray
*bblock_list
= ctx
->bblock_list
;
6861 MonoMethodHeader
*header
;
6862 MonoExceptionClause
*clause
;
6865 if (cfg
->gsharedvt
&& !cfg
->llvm_only
) {
6866 set_failure (ctx
, "gsharedvt");
6872 static int count
= 0;
6875 if (g_getenv ("LLVM_COUNT")) {
6876 if (count
== atoi (g_getenv ("LLVM_COUNT"))) {
6877 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
6881 if (count
> atoi (g_getenv ("LLVM_COUNT"))) {
6882 set_failure (ctx
, "count");
6889 sig
= mono_method_signature (cfg
->method
);
6892 linfo
= get_llvm_call_info (cfg
, sig
);
6898 linfo
->rgctx_arg
= TRUE
;
6899 ctx
->method_type
= method_type
= sig_to_llvm_sig_full (ctx
, sig
, linfo
);
6903 method
= LLVMAddFunction (lmodule
, ctx
->method_name
, method_type
);
6904 ctx
->lmethod
= method
;
6906 if (!cfg
->llvm_only
)
6907 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
6908 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
6910 LLVMAddFunctionAttr (method
, LLVMUWTable
);
6912 if (cfg
->compile_aot
) {
6913 LLVMSetLinkage (method
, LLVMInternalLinkage
);
6914 if (ctx
->module
->external_symbols
) {
6915 LLVMSetLinkage (method
, LLVMExternalLinkage
);
6916 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
6918 if (ctx
->is_linkonce
) {
6919 LLVMSetLinkage (method
, LLVMLinkOnceAnyLinkage
);
6920 LLVMSetVisibility (method
, LLVMDefaultVisibility
);
6923 #if LLVM_API_VERSION > 100
6924 LLVMSetLinkage (method
, LLVMExternalLinkage
);
6926 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
6930 if (cfg
->method
->save_lmf
&& !cfg
->llvm_only
) {
6931 set_failure (ctx
, "lmf");
6935 if (sig
->pinvoke
&& cfg
->method
->wrapper_type
!= MONO_WRAPPER_RUNTIME_INVOKE
&& !cfg
->llvm_only
) {
6936 set_failure (ctx
, "pinvoke signature");
6940 header
= cfg
->header
;
6941 for (i
= 0; i
< header
->num_clauses
; ++i
) {
6942 clause
= &header
->clauses
[i
];
6943 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
) {
6944 set_failure (ctx
, "non-finally/catch clause.");
6948 if (header
->num_clauses
|| (cfg
->method
->iflags
& METHOD_IMPL_ATTRIBUTE_NOINLINING
) || cfg
->no_inline
)
6949 /* We can't handle inlined methods with clauses */
6950 LLVMAddFunctionAttr (method
, LLVMNoInlineAttribute
);
6952 if (linfo
->rgctx_arg
) {
6953 ctx
->rgctx_arg
= LLVMGetParam (method
, linfo
->rgctx_arg_pindex
);
6954 ctx
->rgctx_arg_pindex
= linfo
->rgctx_arg_pindex
;
6956 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6957 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6958 * CC_X86_64_Mono in X86CallingConv.td.
6960 if (!ctx
->llvm_only
)
6961 LLVMAddAttribute (ctx
->rgctx_arg
, LLVMInRegAttribute
);
6962 LLVMSetValueName (ctx
->rgctx_arg
, "rgctx");
6964 ctx
->rgctx_arg_pindex
= -1;
6966 if (cfg
->vret_addr
) {
6967 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, linfo
->vret_arg_pindex
);
6968 LLVMSetValueName (values
[cfg
->vret_addr
->dreg
], "vret");
6969 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
6970 LLVMAddAttribute (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVMStructRetAttribute
);
6971 LLVMAddAttribute (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVMNoAliasAttribute
);
6976 ctx
->this_arg_pindex
= linfo
->this_arg_pindex
;
6977 ctx
->this_arg
= LLVMGetParam (method
, linfo
->this_arg_pindex
);
6978 values
[cfg
->args
[0]->dreg
] = ctx
->this_arg
;
6979 LLVMSetValueName (values
[cfg
->args
[0]->dreg
], "this");
6982 names
= g_new (char *, sig
->param_count
);
6983 mono_method_get_param_names (cfg
->method
, (const char **) names
);
6985 /* Set parameter names/attributes */
6986 for (i
= 0; i
< sig
->param_count
; ++i
) {
6987 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
6989 int pindex
= ainfo
->pindex
+ ainfo
->ndummy_fpargs
;
6992 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
) {
6993 name
= g_strdup_printf ("dummy_%d_%d", i
, j
);
6994 LLVMSetValueName (LLVMGetParam (method
, ainfo
->pindex
+ j
), name
);
6998 if (ainfo
->storage
== LLVMArgVtypeInReg
&& ainfo
->pair_storage
[0] == LLVMArgNone
&& ainfo
->pair_storage
[1] == LLVMArgNone
)
7001 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, pindex
);
7002 if (ainfo
->storage
== LLVMArgGsharedvtFixed
|| ainfo
->storage
== LLVMArgGsharedvtFixedVtype
) {
7003 if (names
[i
] && names
[i
][0] != '\0')
7004 name
= g_strdup_printf ("p_arg_%s", names
[i
]);
7006 name
= g_strdup_printf ("p_arg_%d", i
);
7008 if (names
[i
] && names
[i
][0] != '\0')
7009 name
= g_strdup_printf ("arg_%s", names
[i
]);
7011 name
= g_strdup_printf ("arg_%d", i
);
7013 LLVMSetValueName (values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
], name
);
7015 if (ainfo
->storage
== LLVMArgVtypeByVal
)
7016 LLVMAddAttribute (LLVMGetParam (method
, pindex
), LLVMByValAttribute
);
7018 if (ainfo
->storage
== LLVMArgVtypeByRef
) {
7020 cfg
->args
[i
+ sig
->hasthis
]->opcode
= OP_VTARG_ADDR
;
7025 if (ctx
->module
->emit_dwarf
&& cfg
->compile_aot
&& mono_debug_enabled ()) {
7026 ctx
->minfo
= mono_debug_lookup_method (cfg
->method
);
7027 ctx
->dbg_md
= emit_dbg_subprogram (ctx
, cfg
, method
, ctx
->method_name
);
7031 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
7032 max_block_num
= MAX (max_block_num
, bb
->block_num
);
7033 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
7035 /* Add branches between non-consecutive bblocks */
7036 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7037 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
7038 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
7040 MonoInst
*inst
= (MonoInst
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
7041 inst
->opcode
= OP_BR
;
7042 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
7043 mono_bblock_add_inst (bb
, inst
);
7048 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7049 * was later optimized away, so clear these flags, and add them back for the still
7050 * present OP_LDADDR instructions.
7052 for (i
= 0; i
< cfg
->next_vreg
; ++i
) {
7055 ins
= get_vreg_to_inst (cfg
, i
);
7056 if (ins
&& ins
!= cfg
->rgctx_var
)
7057 ins
->flags
&= ~MONO_INST_INDIRECT
;
7061 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7063 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7065 LLVMBuilderRef builder
;
7067 char dname_buf
[128];
7069 builder
= create_builder (ctx
);
7071 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
7072 switch (ins
->opcode
) {
7077 LLVMTypeRef phi_type
= llvm_type_to_stack_type (cfg
, type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
7082 if (ins
->opcode
== OP_VPHI
) {
7083 /* Treat valuetype PHI nodes as operating on the address itself */
7084 g_assert (ins
->klass
);
7085 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
), 0);
7089 * Have to precreate these, as they can be referenced by
7090 * earlier instructions.
7092 sprintf (dname_buf
, "t%d", ins
->dreg
);
7094 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
7096 if (ins
->opcode
== OP_VPHI
)
7097 ctx
->addresses
[ins
->dreg
] = values
[ins
->dreg
];
7099 g_ptr_array_add (ctx
->phi_values
, values
[ins
->dreg
]);
7102 * Set the expected type of the incoming arguments since these have
7103 * to have the same type.
7105 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
7106 int sreg1
= ins
->inst_phi_args
[i
+ 1];
7109 if (ins
->opcode
== OP_VPHI
)
7110 ctx
->is_vphi
[sreg1
] = TRUE
;
7111 ctx
->vreg_types
[sreg1
] = phi_type
;
7117 ((MonoInst
*)ins
->inst_p0
)->flags
|= MONO_INST_INDIRECT
;
7126 * Create an ordering for bblocks, use the depth first order first, then
7127 * put the exception handling bblocks last.
7129 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
7130 bb
= cfg
->bblocks
[bb_index
];
7131 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
7132 g_ptr_array_add (bblock_list
, bb
);
7133 bblocks
[bb
->block_num
].added
= TRUE
;
7137 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7138 if (!bblocks
[bb
->block_num
].added
)
7139 g_ptr_array_add (bblock_list
, bb
);
7143 * Second pass: generate code.
7146 LLVMBuilderRef entry_builder
= create_builder (ctx
);
7147 LLVMBasicBlockRef entry_bb
= get_bb (ctx
, cfg
->bb_entry
);
7148 LLVMPositionBuilderAtEnd (entry_builder
, entry_bb
);
7149 emit_entry_bb (ctx
, entry_builder
);
7151 // Make landing pads first
7152 ctx
->exc_meta
= g_hash_table_new_full (NULL
, NULL
, NULL
, NULL
);
7154 if (ctx
->llvm_only
) {
7155 size_t group_index
= 0;
7156 while (group_index
< cfg
->header
->num_clauses
) {
7158 size_t cursor
= group_index
;
7159 while (cursor
< cfg
->header
->num_clauses
&&
7160 CLAUSE_START (&cfg
->header
->clauses
[cursor
]) == CLAUSE_START (&cfg
->header
->clauses
[group_index
]) &&
7161 CLAUSE_END (&cfg
->header
->clauses
[cursor
]) == CLAUSE_END (&cfg
->header
->clauses
[group_index
])) {
7166 LLVMBasicBlockRef lpad_bb
= emit_landing_pad (ctx
, group_index
, count
);
7167 intptr_t key
= CLAUSE_END (&cfg
->header
->clauses
[group_index
]);
7168 g_hash_table_insert (ctx
->exc_meta
, (gpointer
)key
, lpad_bb
);
7170 group_index
= cursor
;
7174 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
7175 bb
= (MonoBasicBlock
*)g_ptr_array_index (bblock_list
, bb_index
);
7177 // Prune unreachable mono BBs.
7178 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
7181 process_bb (ctx
, bb
);
7185 g_hash_table_destroy (ctx
->exc_meta
);
7187 mono_memory_barrier ();
7189 /* Add incoming phi values */
7190 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7191 GSList
*l
, *ins_list
;
7193 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7195 for (l
= ins_list
; l
; l
= l
->next
) {
7196 PhiNode
*node
= (PhiNode
*)l
->data
;
7197 MonoInst
*phi
= node
->phi
;
7198 int sreg1
= node
->sreg
;
7199 LLVMBasicBlockRef in_bb
;
7204 in_bb
= get_end_bb (ctx
, node
->in_bb
);
7206 if (ctx
->unreachable
[node
->in_bb
->block_num
])
7209 if (!values
[sreg1
]) {
7210 /* Can happen with values in EH clauses */
7211 set_failure (ctx
, "incoming phi sreg1");
7215 if (phi
->opcode
== OP_VPHI
) {
7216 g_assert (LLVMTypeOf (ctx
->addresses
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
7217 LLVMAddIncoming (values
[phi
->dreg
], &ctx
->addresses
[sreg1
], &in_bb
, 1);
7219 if (LLVMTypeOf (values
[sreg1
]) != LLVMTypeOf (values
[phi
->dreg
])) {
7220 set_failure (ctx
, "incoming phi arg type mismatch");
7223 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
7224 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
7229 /* Nullify empty phi instructions */
7230 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7231 GSList
*l
, *ins_list
;
7233 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7235 for (l
= ins_list
; l
; l
= l
->next
) {
7236 PhiNode
*node
= (PhiNode
*)l
->data
;
7237 MonoInst
*phi
= node
->phi
;
7238 LLVMValueRef phi_ins
= values
[phi
->dreg
];
7241 /* Already removed */
7244 if (LLVMCountIncoming (phi_ins
) == 0) {
7245 mono_llvm_replace_uses_of (phi_ins
, LLVMConstNull (LLVMTypeOf (phi_ins
)));
7246 LLVMInstructionEraseFromParent (phi_ins
);
7247 values
[phi
->dreg
] = NULL
;
7252 /* Create the SWITCH statements for ENDFINALLY instructions */
7253 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7254 BBInfo
*info
= &bblocks
[bb
->block_num
];
7256 for (l
= info
->endfinally_switch_ins_list
; l
; l
= l
->next
) {
7257 LLVMValueRef switch_ins
= (LLVMValueRef
)l
->data
;
7258 GSList
*bb_list
= info
->call_handler_return_bbs
;
7260 for (i
= 0; i
< g_slist_length (bb_list
); ++i
)
7261 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), (LLVMBasicBlockRef
)(g_slist_nth (bb_list
, i
)->data
));
7265 /* Initialize the method if needed */
7266 if (cfg
->compile_aot
&& ctx
->llvm_only
) {
7267 // FIXME: Add more shared got entries
7268 ctx
->builder
= create_builder (ctx
);
7269 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->init_bb
);
7271 ctx
->module
->max_method_idx
= MAX (ctx
->module
->max_method_idx
, cfg
->method_index
);
7273 // FIXME: beforefieldinit
7275 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7276 * in load_method ().
7278 if ((ctx
->has_got_access
|| mono_class_get_cctor (cfg
->method
->klass
)) && !(cfg
->method
->wrapper_type
== MONO_WRAPPER_NATIVE_TO_MANAGED
)) {
7280 * linkonce methods shouldn't have initialization,
7281 * because they might belong to assemblies which
7282 * haven't been loaded yet.
7284 g_assert (!ctx
->is_linkonce
);
7285 emit_init_method (ctx
);
7287 LLVMBuildBr (ctx
->builder
, ctx
->inited_bb
);
7291 if (cfg
->llvm_only
) {
7292 GHashTableIter iter
;
7294 GSList
*callers
, *l
, *l2
;
7297 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7298 * We can't do this earlier, as it contains llvm instructions which can be
7299 * freed if compilation fails.
7300 * FIXME: Get rid of this when all methods can be llvm compiled.
7302 g_hash_table_iter_init (&iter
, ctx
->method_to_callers
);
7303 while (g_hash_table_iter_next (&iter
, (void**)&method
, (void**)&callers
)) {
7304 for (l
= callers
; l
; l
= l
->next
) {
7305 l2
= (GSList
*)g_hash_table_lookup (ctx
->module
->method_to_callers
, method
);
7306 l2
= g_slist_prepend (l2
, l
->data
);
7307 g_hash_table_insert (ctx
->module
->method_to_callers
, method
, l2
);
7312 if (cfg
->verbose_level
> 1)
7313 mono_llvm_dump_value (method
);
7315 if (cfg
->compile_aot
&& !cfg
->llvm_only
)
7316 mark_as_used (ctx
->module
, method
);
7318 if (!cfg
->llvm_only
) {
7319 LLVMValueRef md_args
[16];
7320 LLVMValueRef md_node
;
7323 if (cfg
->compile_aot
)
7324 method_index
= mono_aot_get_method_index (cfg
->orig_method
);
7327 md_args
[0] = LLVMMDString (ctx
->method_name
, strlen (ctx
->method_name
));
7328 md_args
[1] = LLVMConstInt (LLVMInt32Type (), method_index
, FALSE
);
7329 md_node
= LLVMMDNode (md_args
, 2);
7330 LLVMAddNamedMetadataOperand (lmodule
, "mono.function_indexes", md_node
);
7331 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7334 if (cfg
->compile_aot
) {
7335 /* Don't generate native code, keep the LLVM IR */
7336 if (cfg
->verbose_level
)
7337 printf ("%s emitted as %s\n", mono_method_full_name (cfg
->method
, TRUE
), ctx
->method_name
);
7339 #if LLVM_API_VERSION < 100
7340 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7341 int err
= LLVMVerifyFunction(ctx
->lmethod
, LLVMPrintMessageAction
);
7342 g_assert (err
== 0);
7345 //LLVMVerifyFunction(method, 0);
7346 #if LLVM_API_VERSION > 100
7347 MonoDomain
*domain
= mono_domain_get ();
7348 MonoJitDomainInfo
*domain_info
;
7349 int nvars
= g_hash_table_size (ctx
->jit_callees
);
7350 LLVMValueRef
*callee_vars
= g_new0 (LLVMValueRef
, nvars
);
7351 gpointer
*callee_addrs
= g_new0 (gpointer
, nvars
);
7352 GHashTableIter iter
;
7358 * Compute the addresses of the LLVM globals pointing to the
7359 * methods called by the current method. Pass it to the trampoline
7360 * code so it can update them after their corresponding method was
7363 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
7365 while (g_hash_table_iter_next (&iter
, NULL
, (void**)&var
))
7366 callee_vars
[i
++] = var
;
7368 cfg
->native_code
= mono_llvm_compile_method (ctx
->module
->mono_ee
, ctx
->lmethod
, nvars
, callee_vars
, callee_addrs
, &eh_frame
);
7370 decode_llvm_eh_info (ctx
, eh_frame
);
7372 mono_domain_lock (domain
);
7373 domain_info
= domain_jit_info (domain
);
7374 if (!domain_info
->llvm_jit_callees
)
7375 domain_info
->llvm_jit_callees
= g_hash_table_new (NULL
, NULL
);
7376 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
7378 while (g_hash_table_iter_next (&iter
, (void**)&callee
, (void**)&var
)) {
7379 GSList
*addrs
= g_hash_table_lookup (domain_info
->llvm_jit_callees
, callee
);
7380 addrs
= g_slist_prepend (addrs
, callee_addrs
[i
]);
7381 g_hash_table_insert (domain_info
->llvm_jit_callees
, callee
, addrs
);
7384 mono_domain_unlock (domain
);
7386 mono_llvm_optimize_method (ctx
->module
->mono_ee
, ctx
->lmethod
);
7388 if (cfg
->verbose_level
> 1)
7389 mono_llvm_dump_value (ctx
->lmethod
);
7391 cfg
->native_code
= (unsigned char*)LLVMGetPointerToGlobal (ctx
->module
->ee
, ctx
->lmethod
);
7393 /* Set by emit_cb */
7394 g_assert (cfg
->code_len
);
7398 if (ctx
->module
->method_to_lmethod
)
7399 g_hash_table_insert (ctx
->module
->method_to_lmethod
, cfg
->method
, ctx
->lmethod
);
7400 if (ctx
->module
->idx_to_lmethod
)
7401 g_hash_table_insert (ctx
->module
->idx_to_lmethod
, GINT_TO_POINTER (cfg
->method_index
), ctx
->lmethod
);
7403 if (ctx
->llvm_only
&& cfg
->orig_method
->klass
->valuetype
&& !(cfg
->orig_method
->flags
& METHOD_ATTRIBUTE_STATIC
))
7404 emit_unbox_tramp (ctx
, ctx
->method_name
, ctx
->method_type
, ctx
->lmethod
, cfg
->method_index
);
7408 * mono_llvm_create_vars:
7410 * Same as mono_arch_create_vars () for LLVM.
7413 mono_llvm_create_vars (MonoCompile
*cfg
)
7415 MonoMethodSignature
*sig
;
7417 sig
= mono_method_signature (cfg
->method
);
7418 if (cfg
->gsharedvt
&& cfg
->llvm_only
) {
7419 if (mini_is_gsharedvt_variable_signature (sig
) && sig
->ret
->type
!= MONO_TYPE_VOID
) {
7420 cfg
->vret_addr
= mono_compile_create_var (cfg
, &mono_get_intptr_class ()->byval_arg
, OP_ARG
);
7421 if (G_UNLIKELY (cfg
->verbose_level
> 1)) {
7422 printf ("vret_addr = ");
7423 mono_print_ins (cfg
->vret_addr
);
7427 mono_arch_create_vars (cfg
);
7432 * mono_llvm_emit_call:
7434 * Same as mono_arch_emit_call () for LLVM.
7437 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
7440 MonoMethodSignature
*sig
;
7441 int i
, n
, stack_size
;
7446 sig
= call
->signature
;
7447 n
= sig
->param_count
+ sig
->hasthis
;
7449 call
->cinfo
= get_llvm_call_info (cfg
, sig
);
7451 if (cfg
->disable_llvm
)
7454 if (sig
->call_convention
== MONO_CALL_VARARG
) {
7455 cfg
->exception_message
= g_strdup ("varargs");
7456 cfg
->disable_llvm
= TRUE
;
7459 for (i
= 0; i
< n
; ++i
) {
7462 ainfo
= call
->cinfo
->args
+ i
;
7464 in
= call
->args
[i
];
7466 /* Simply remember the arguments */
7467 switch (ainfo
->storage
) {
7468 case LLVMArgNormal
: {
7469 MonoType
*t
= (sig
->hasthis
&& i
== 0) ? &mono_get_intptr_class ()->byval_arg
: ainfo
->type
;
7472 opcode
= mono_type_to_regmove (cfg
, t
);
7473 if (opcode
== OP_FMOVE
) {
7474 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
7475 ins
->dreg
= mono_alloc_freg (cfg
);
7476 } else if (opcode
== OP_LMOVE
) {
7477 MONO_INST_NEW (cfg
, ins
, OP_LMOVE
);
7478 ins
->dreg
= mono_alloc_lreg (cfg
);
7479 } else if (opcode
== OP_RMOVE
) {
7480 MONO_INST_NEW (cfg
, ins
, OP_RMOVE
);
7481 ins
->dreg
= mono_alloc_freg (cfg
);
7483 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
7484 ins
->dreg
= mono_alloc_ireg (cfg
);
7486 ins
->sreg1
= in
->dreg
;
7489 case LLVMArgVtypeByVal
:
7490 case LLVMArgVtypeByRef
:
7491 case LLVMArgVtypeInReg
:
7492 case LLVMArgVtypeAsScalar
:
7493 case LLVMArgAsIArgs
:
7494 case LLVMArgAsFpArgs
:
7495 case LLVMArgGsharedvtVariable
:
7496 case LLVMArgGsharedvtFixed
:
7497 case LLVMArgGsharedvtFixedVtype
:
7498 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
7499 ins
->dreg
= mono_alloc_ireg (cfg
);
7500 ins
->sreg1
= in
->dreg
;
7501 ins
->inst_p0
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMArgInfo
));
7502 memcpy (ins
->inst_p0
, ainfo
, sizeof (LLVMArgInfo
));
7503 ins
->inst_vtype
= ainfo
->type
;
7504 ins
->klass
= mono_class_from_mono_type (ainfo
->type
);
7507 cfg
->exception_message
= g_strdup ("ainfo->storage");
7508 cfg
->disable_llvm
= TRUE
;
7512 if (!cfg
->disable_llvm
) {
7513 MONO_ADD_INS (cfg
->cbb
, ins
);
7514 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
7519 static unsigned char*
7520 alloc_cb (LLVMValueRef function
, int size
)
7524 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7528 return (unsigned char*)mono_domain_code_reserve (cfg
->domain
, size
);
7530 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size
);
7535 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
7539 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7541 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
7545 exception_cb (void *data
)
7548 MonoJitExceptionInfo
*ei
;
7549 guint32 ei_len
, i
, j
, nested_len
, nindex
;
7550 gpointer
*type_info
;
7551 int this_reg
, this_offset
;
7553 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7557 * data points to a DWARF FDE structure, convert it to our unwind format and
7559 * An alternative would be to save it directly, and modify our unwinder to work
7562 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
);
7563 if (cfg
->verbose_level
> 1)
7564 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
7566 /* Count nested clauses */
7568 for (i
= 0; i
< ei_len
; ++i
) {
7569 gint32 cindex1
= *(gint32
*)type_info
[i
];
7570 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
7572 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
7574 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
7576 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
7582 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
7583 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
7584 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
7585 /* Fill the rest of the information from the type info */
7586 for (i
= 0; i
< ei_len
; ++i
) {
7587 gint32 clause_index
= *(gint32
*)type_info
[i
];
7588 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
7590 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
7591 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
7592 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
7596 * For nested clauses, the LLVM produced exception info associates the try interval with
7597 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7598 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7599 * and everything else from the nested clause.
7602 for (i
= 0; i
< ei_len
; ++i
) {
7603 gint32 cindex1
= *(gint32
*)type_info
[i
];
7604 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
7606 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
7608 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
7609 MonoJitExceptionInfo
*nesting_ei
, *nested_ei
;
7611 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
7612 /* clause1 is the nested clause */
7613 nested_ei
= &cfg
->llvm_ex_info
[i
];
7614 nesting_ei
= &cfg
->llvm_ex_info
[nindex
];
7617 memcpy (nesting_ei
, nested_ei
, sizeof (MonoJitExceptionInfo
));
7619 nesting_ei
->flags
= clause2
->flags
;
7620 nesting_ei
->data
.catch_class
= clause2
->data
.catch_class
;
7621 nesting_ei
->clause_index
= cindex2
;
7625 g_assert (nindex
== ei_len
+ nested_len
);
7626 cfg
->llvm_this_reg
= this_reg
;
7627 cfg
->llvm_this_offset
= this_offset
;
7629 /* type_info [i] is cfg mempool allocated, no need to free it */
7635 #if LLVM_API_VERSION > 100
7637 * decode_llvm_eh_info:
7639 * Decode the EH table emitted by llvm in jit mode, and store
7640 * the result into cfg.
7643 decode_llvm_eh_info (EmitContext
*ctx
, gpointer eh_frame
)
7645 MonoCompile
*cfg
= ctx
->cfg
;
7648 MonoLLVMFDEInfo info
;
7649 MonoJitExceptionInfo
*ei
;
7650 guint8
*p
= eh_frame
;
7651 int version
, fde_count
, fde_offset
;
7652 guint32 ei_len
, i
, nested_len
;
7653 gpointer
*type_info
;
7657 * Decode the one element EH table emitted by the MonoException class
7661 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7664 g_assert (version
== 3);
7667 p
= (guint8
*)ALIGN_PTR_TO (p
, 4);
7669 fde_count
= *(guint32
*)p
;
7673 g_assert (fde_count
<= 2);
7675 /* The first entry is the real method */
7676 g_assert (table
[0] == 1);
7677 fde_offset
= table
[1];
7678 table
+= fde_count
* 2;
7680 cfg
->code_len
= table
[0];
7681 fde_len
= table
[1] - fde_offset
;
7684 fde
= (guint8
*)eh_frame
+ fde_offset
;
7685 cie
= (guint8
*)table
;
7687 mono_unwind_decode_llvm_mono_fde (fde
, fde_len
, cie
, cfg
->native_code
, &info
);
7689 cfg
->encoded_unwind_ops
= info
.unw_info
;
7690 cfg
->encoded_unwind_ops_len
= info
.unw_info_len
;
7691 if (cfg
->verbose_level
> 1)
7692 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
7693 if (info
.this_reg
!= -1) {
7694 cfg
->llvm_this_reg
= info
.this_reg
;
7695 cfg
->llvm_this_offset
= info
.this_offset
;
7699 ei_len
= info
.ex_info_len
;
7700 type_info
= info
.type_info
;
7702 // Nested clauses are currently disabled
7705 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
7706 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
7707 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
7708 /* Fill the rest of the information from the type info */
7709 for (i
= 0; i
< ei_len
; ++i
) {
7710 gint32 clause_index
= *(gint32
*)type_info
[i
];
7711 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
7713 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
7714 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
7715 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
7721 dlsym_cb (const char *name
, void **symbol
)
7727 if (!strcmp (name
, "__bzero")) {
7728 *symbol
= (void*)bzero
;
7730 current
= mono_dl_open (NULL
, 0, NULL
);
7733 err
= mono_dl_symbol (current
, name
, symbol
);
7735 mono_dl_close (current
);
7737 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7738 *symbol
= (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8
*)(*symbol
));
7744 AddFunc (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef
*param_types
, int nparams
)
7746 LLVMAddFunction (module
, name
, LLVMFunctionType (ret_type
, param_types
, nparams
, FALSE
));
7750 AddFunc2 (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef param_type1
, LLVMTypeRef param_type2
)
7752 LLVMTypeRef param_types
[4];
7754 param_types
[0] = param_type1
;
7755 param_types
[1] = param_type2
;
7757 AddFunc (module
, name
, ret_type
, param_types
, 2);
7763 INTRINS_SADD_OVF_I32
,
7764 INTRINS_UADD_OVF_I32
,
7765 INTRINS_SSUB_OVF_I32
,
7766 INTRINS_USUB_OVF_I32
,
7767 INTRINS_SMUL_OVF_I32
,
7768 INTRINS_UMUL_OVF_I32
,
7769 INTRINS_SADD_OVF_I64
,
7770 INTRINS_UADD_OVF_I64
,
7771 INTRINS_SSUB_OVF_I64
,
7772 INTRINS_USUB_OVF_I64
,
7773 INTRINS_SMUL_OVF_I64
,
7774 INTRINS_UMUL_OVF_I64
,
7781 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7782 INTRINS_SSE_PMOVMSKB
,
7783 INTRINS_SSE_PSRLI_W
,
7784 INTRINS_SSE_PSRAI_W
,
7785 INTRINS_SSE_PSLLI_W
,
7786 INTRINS_SSE_PSRLI_D
,
7787 INTRINS_SSE_PSRAI_D
,
7788 INTRINS_SSE_PSLLI_D
,
7789 INTRINS_SSE_PSRLI_Q
,
7790 INTRINS_SSE_PSLLI_Q
,
7791 INTRINS_SSE_SQRT_PD
,
7792 INTRINS_SSE_SQRT_PS
,
7793 INTRINS_SSE_RSQRT_PS
,
7795 INTRINS_SSE_CVTTPD2DQ
,
7796 INTRINS_SSE_CVTTPS2DQ
,
7797 INTRINS_SSE_CVTDQ2PD
,
7798 INTRINS_SSE_CVTDQ2PS
,
7799 INTRINS_SSE_CVTPD2DQ
,
7800 INTRINS_SSE_CVTPS2DQ
,
7801 INTRINS_SSE_CVTPD2PS
,
7802 INTRINS_SSE_CVTPS2PD
,
7805 INTRINS_SSE_PACKSSWB
,
7806 INTRINS_SSE_PACKUSWB
,
7807 INTRINS_SSE_PACKSSDW
,
7808 INTRINS_SSE_PACKUSDW
,
7813 INTRINS_SSE_ADDSUBPS
,
7818 INTRINS_SSE_ADDSUBPD
,
7821 INTRINS_SSE_PADDUSW
,
7822 INTRINS_SSE_PSUBUSW
,
7828 INTRINS_SSE_PADDUSB
,
7829 INTRINS_SSE_PSUBUSB
,
7841 static IntrinsicDesc intrinsics
[] = {
7842 {INTRINS_MEMSET
, "llvm.memset.p0i8.i32"},
7843 {INTRINS_MEMCPY
, "llvm.memcpy.p0i8.p0i8.i32"},
7844 {INTRINS_SADD_OVF_I32
, "llvm.sadd.with.overflow.i32"},
7845 {INTRINS_UADD_OVF_I32
, "llvm.uadd.with.overflow.i32"},
7846 {INTRINS_SSUB_OVF_I32
, "llvm.ssub.with.overflow.i32"},
7847 {INTRINS_USUB_OVF_I32
, "llvm.usub.with.overflow.i32"},
7848 {INTRINS_SMUL_OVF_I32
, "llvm.smul.with.overflow.i32"},
7849 {INTRINS_UMUL_OVF_I32
, "llvm.umul.with.overflow.i32"},
7850 {INTRINS_SADD_OVF_I64
, "llvm.sadd.with.overflow.i64"},
7851 {INTRINS_UADD_OVF_I64
, "llvm.uadd.with.overflow.i64"},
7852 {INTRINS_SSUB_OVF_I64
, "llvm.ssub.with.overflow.i64"},
7853 {INTRINS_USUB_OVF_I64
, "llvm.usub.with.overflow.i64"},
7854 {INTRINS_SMUL_OVF_I64
, "llvm.smul.with.overflow.i64"},
7855 {INTRINS_UMUL_OVF_I64
, "llvm.umul.with.overflow.i64"},
7856 {INTRINS_SIN
, "llvm.sin.f64"},
7857 {INTRINS_COS
, "llvm.cos.f64"},
7858 {INTRINS_SQRT
, "llvm.sqrt.f64"},
7859 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7860 {INTRINS_FABS
, "fabs"},
7861 {INTRINS_EXPECT_I8
, "llvm.expect.i8"},
7862 {INTRINS_EXPECT_I1
, "llvm.expect.i1"},
7863 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7864 {INTRINS_SSE_PMOVMSKB
, "llvm.x86.sse2.pmovmskb.128"},
7865 {INTRINS_SSE_PSRLI_W
, "llvm.x86.sse2.psrli.w"},
7866 {INTRINS_SSE_PSRAI_W
, "llvm.x86.sse2.psrai.w"},
7867 {INTRINS_SSE_PSLLI_W
, "llvm.x86.sse2.pslli.w"},
7868 {INTRINS_SSE_PSRLI_D
, "llvm.x86.sse2.psrli.d"},
7869 {INTRINS_SSE_PSRAI_D
, "llvm.x86.sse2.psrai.d"},
7870 {INTRINS_SSE_PSLLI_D
, "llvm.x86.sse2.pslli.d"},
7871 {INTRINS_SSE_PSRLI_Q
, "llvm.x86.sse2.psrli.q"},
7872 {INTRINS_SSE_PSLLI_Q
, "llvm.x86.sse2.pslli.q"},
7873 {INTRINS_SSE_SQRT_PD
, "llvm.x86.sse2.sqrt.pd"},
7874 {INTRINS_SSE_SQRT_PS
, "llvm.x86.sse.sqrt.ps"},
7875 {INTRINS_SSE_RSQRT_PS
, "llvm.x86.sse.rsqrt.ps"},
7876 {INTRINS_SSE_RCP_PS
, "llvm.x86.sse.rcp.ps"},
7877 {INTRINS_SSE_CVTTPD2DQ
, "llvm.x86.sse2.cvttpd2dq"},
7878 {INTRINS_SSE_CVTTPS2DQ
, "llvm.x86.sse2.cvttps2dq"},
7879 {INTRINS_SSE_CVTDQ2PD
, "llvm.x86.sse2.cvtdq2pd"},
7880 {INTRINS_SSE_CVTDQ2PS
, "llvm.x86.sse2.cvtdq2ps"},
7881 {INTRINS_SSE_CVTPD2DQ
, "llvm.x86.sse2.cvtpd2dq"},
7882 {INTRINS_SSE_CVTPS2DQ
, "llvm.x86.sse2.cvtps2dq"},
7883 {INTRINS_SSE_CVTPD2PS
, "llvm.x86.sse2.cvtpd2ps"},
7884 {INTRINS_SSE_CVTPS2PD
, "llvm.x86.sse2.cvtps2pd"},
7885 {INTRINS_SSE_CMPPD
, "llvm.x86.sse2.cmp.pd"},
7886 {INTRINS_SSE_CMPPS
, "llvm.x86.sse.cmp.ps"},
7887 {INTRINS_SSE_PACKSSWB
, "llvm.x86.sse2.packsswb.128"},
7888 {INTRINS_SSE_PACKUSWB
, "llvm.x86.sse2.packuswb.128"},
7889 {INTRINS_SSE_PACKSSDW
, "llvm.x86.sse2.packssdw.128"},
7890 {INTRINS_SSE_PACKUSDW
, "llvm.x86.sse41.packusdw"},
7891 {INTRINS_SSE_MINPS
, "llvm.x86.sse.min.ps"},
7892 {INTRINS_SSE_MAXPS
, "llvm.x86.sse.max.ps"},
7893 {INTRINS_SSE_HADDPS
, "llvm.x86.sse3.hadd.ps"},
7894 {INTRINS_SSE_HSUBPS
, "llvm.x86.sse3.hsub.ps"},
7895 {INTRINS_SSE_ADDSUBPS
, "llvm.x86.sse3.addsub.ps"},
7896 {INTRINS_SSE_MINPD
, "llvm.x86.sse2.min.pd"},
7897 {INTRINS_SSE_MAXPD
, "llvm.x86.sse2.max.pd"},
7898 {INTRINS_SSE_HADDPD
, "llvm.x86.sse3.hadd.pd"},
7899 {INTRINS_SSE_HSUBPD
, "llvm.x86.sse3.hsub.pd"},
7900 {INTRINS_SSE_ADDSUBPD
, "llvm.x86.sse3.addsub.pd"},
7901 {INTRINS_SSE_PADDSW
, "llvm.x86.sse2.padds.w"},
7902 {INTRINS_SSE_PSUBSW
, "llvm.x86.sse2.psubs.w"},
7903 {INTRINS_SSE_PADDUSW
, "llvm.x86.sse2.paddus.w"},
7904 {INTRINS_SSE_PSUBUSW
, "llvm.x86.sse2.psubus.w"},
7905 {INTRINS_SSE_PAVGW
, "llvm.x86.sse2.pavg.w"},
7906 {INTRINS_SSE_PMULHW
, "llvm.x86.sse2.pmulh.w"},
7907 {INTRINS_SSE_PMULHU
, "llvm.x86.sse2.pmulhu.w"},
7908 {INTRINS_SE_PADDSB
, "llvm.x86.sse2.padds.b"},
7909 {INTRINS_SSE_PSUBSB
, "llvm.x86.sse2.psubs.b"},
7910 {INTRINS_SSE_PADDUSB
, "llvm.x86.sse2.paddus.b"},
7911 {INTRINS_SSE_PSUBUSB
, "llvm.x86.sse2.psubus.b"},
7912 {INTRINS_SSE_PAVGB
, "llvm.x86.sse2.pavg.b"},
7913 {INTRINS_SSE_PAUSE
, "llvm.x86.sse2.pause"}
7918 add_sse_binary (LLVMModuleRef module
, const char *name
, int type
)
7920 LLVMTypeRef ret_type
= type_to_simd_type (type
);
7921 AddFunc2 (module
, name
, ret_type
, ret_type
, ret_type
);
7925 add_intrinsic (LLVMModuleRef module
, int id
)
7928 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7929 LLVMTypeRef ret_type
, arg_types
[16];
7932 name
= g_hash_table_lookup (intrins_id_to_name
, GINT_TO_POINTER (id
));
7936 case INTRINS_MEMSET
: {
7937 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7939 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
7942 case INTRINS_MEMCPY
: {
7943 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7945 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
7948 case INTRINS_SADD_OVF_I32
:
7949 case INTRINS_UADD_OVF_I32
:
7950 case INTRINS_SSUB_OVF_I32
:
7951 case INTRINS_USUB_OVF_I32
:
7952 case INTRINS_SMUL_OVF_I32
:
7953 case INTRINS_UMUL_OVF_I32
: {
7954 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
7955 LLVMTypeRef params
[] = { LLVMInt32Type (), LLVMInt32Type () };
7956 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i32
, 2, FALSE
);
7958 AddFunc (module
, name
, ret_type
, params
, 2);
7961 case INTRINS_SADD_OVF_I64
:
7962 case INTRINS_UADD_OVF_I64
:
7963 case INTRINS_SSUB_OVF_I64
:
7964 case INTRINS_USUB_OVF_I64
:
7965 case INTRINS_SMUL_OVF_I64
:
7966 case INTRINS_UMUL_OVF_I64
: {
7967 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
7968 LLVMTypeRef params
[] = { LLVMInt64Type (), LLVMInt64Type () };
7969 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i64
, 2, FALSE
);
7971 AddFunc (module
, name
, ret_type
, params
, 2);
7977 case INTRINS_FABS
: {
7978 LLVMTypeRef params
[] = { LLVMDoubleType () };
7980 AddFunc (module
, name
, LLVMDoubleType (), params
, 1);
7983 case INTRINS_EXPECT_I8
:
7984 AddFunc2 (module
, name
, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7986 case INTRINS_EXPECT_I1
:
7987 AddFunc2 (module
, name
, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7989 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7990 case INTRINS_SSE_PMOVMSKB
:
7992 ret_type
= LLVMInt32Type ();
7993 arg_types
[0] = type_to_simd_type (MONO_TYPE_I1
);
7994 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7996 case INTRINS_SSE_PSRLI_W
:
7997 case INTRINS_SSE_PSRAI_W
:
7998 case INTRINS_SSE_PSLLI_W
:
8000 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8001 arg_types
[0] = ret_type
;
8002 arg_types
[1] = LLVMInt32Type ();
8003 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8005 case INTRINS_SSE_PSRLI_D
:
8006 case INTRINS_SSE_PSRAI_D
:
8007 case INTRINS_SSE_PSLLI_D
:
8008 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8009 arg_types
[0] = ret_type
;
8010 arg_types
[1] = LLVMInt32Type ();
8011 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8013 case INTRINS_SSE_PSRLI_Q
:
8014 case INTRINS_SSE_PSLLI_Q
:
8015 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
8016 arg_types
[0] = ret_type
;
8017 arg_types
[1] = LLVMInt32Type ();
8018 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8020 case INTRINS_SSE_SQRT_PD
:
8022 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8023 arg_types
[0] = ret_type
;
8024 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8026 case INTRINS_SSE_SQRT_PS
:
8027 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8028 arg_types
[0] = ret_type
;
8029 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8031 case INTRINS_SSE_RSQRT_PS
:
8032 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8033 arg_types
[0] = ret_type
;
8034 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8036 case INTRINS_SSE_RCP_PS
:
8037 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8038 arg_types
[0] = ret_type
;
8039 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8041 case INTRINS_SSE_CVTTPD2DQ
:
8042 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8043 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8044 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8046 case INTRINS_SSE_CVTTPS2DQ
:
8047 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8048 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8049 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8051 case INTRINS_SSE_CVTDQ2PD
:
8052 /* Conversion ops */
8053 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8054 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8055 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8057 case INTRINS_SSE_CVTDQ2PS
:
8058 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8059 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8060 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8062 case INTRINS_SSE_CVTPD2DQ
:
8063 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8064 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8065 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8067 case INTRINS_SSE_CVTPS2DQ
:
8068 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8069 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8070 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8072 case INTRINS_SSE_CVTPD2PS
:
8073 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8074 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8075 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8077 case INTRINS_SSE_CVTPS2PD
:
8078 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8079 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8080 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8082 case INTRINS_SSE_CMPPD
:
8084 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8085 arg_types
[0] = ret_type
;
8086 arg_types
[1] = ret_type
;
8087 arg_types
[2] = LLVMInt8Type ();
8088 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8090 case INTRINS_SSE_CMPPS
:
8091 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8092 arg_types
[0] = ret_type
;
8093 arg_types
[1] = ret_type
;
8094 arg_types
[2] = LLVMInt8Type ();
8095 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8097 case INTRINS_SSE_PACKSSWB
:
8098 case INTRINS_SSE_PACKUSWB
:
8099 case INTRINS_SSE_PACKSSDW
:
8101 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
8102 arg_types
[0] = type_to_simd_type (MONO_TYPE_I2
);
8103 arg_types
[1] = type_to_simd_type (MONO_TYPE_I2
);
8104 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8106 case INTRINS_SSE_PACKUSDW
:
8107 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8108 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8109 arg_types
[1] = type_to_simd_type (MONO_TYPE_I4
);
8110 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8112 /* SSE Binary ops */
8113 case INTRINS_SSE_PADDSW
:
8114 case INTRINS_SSE_PSUBSW
:
8115 case INTRINS_SSE_PADDUSW
:
8116 case INTRINS_SSE_PSUBUSW
:
8117 case INTRINS_SSE_PAVGW
:
8118 case INTRINS_SSE_PMULHW
:
8119 case INTRINS_SSE_PMULHU
:
8120 add_sse_binary (module
, name
, MONO_TYPE_I2
);
8122 case INTRINS_SSE_MINPS
:
8123 case INTRINS_SSE_MAXPS
:
8124 case INTRINS_SSE_HADDPS
:
8125 case INTRINS_SSE_HSUBPS
:
8126 case INTRINS_SSE_ADDSUBPS
:
8127 add_sse_binary (module
, name
, MONO_TYPE_R4
);
8129 case INTRINS_SSE_MINPD
:
8130 case INTRINS_SSE_MAXPD
:
8131 case INTRINS_SSE_HADDPD
:
8132 case INTRINS_SSE_HSUBPD
:
8133 case INTRINS_SSE_ADDSUBPD
:
8134 add_sse_binary (module
, name
, MONO_TYPE_R8
);
8136 case INTRINS_SE_PADDSB
:
8137 case INTRINS_SSE_PSUBSB
:
8138 case INTRINS_SSE_PADDUSB
:
8139 case INTRINS_SSE_PSUBUSB
:
8140 case INTRINS_SSE_PAVGB
:
8141 add_sse_binary (module
, name
, MONO_TYPE_I1
);
8143 case INTRINS_SSE_PAUSE
:
8144 AddFunc (module
, "llvm.x86.sse2.pause", LLVMVoidType (), NULL
, 0);
8148 g_assert_not_reached ();
8154 get_intrinsic (EmitContext
*ctx
, const char *name
)
8156 #if LLVM_API_VERSION > 100
8160 * Every method is emitted into its own module so
8161 * we can add intrinsics on demand.
8163 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8167 /* No locking needed */
8168 id
= GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id
, name
));
8171 printf ("%s\n", name
);
8172 g_assert (id
!= -1);
8173 add_intrinsic (ctx
->lmodule
, id
);
8174 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8182 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8189 add_intrinsics (LLVMModuleRef module
)
8193 /* Emit declarations of instrinsics */
8195 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8196 * type doesn't seem to do any locking.
8198 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8199 add_intrinsic (module
, i
);
8203 AddFunc (module
, "mono_personality", LLVMVoidType (), NULL
, 0);
8205 AddFunc (module
, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL
, 0);
8208 /* Load/Store intrinsics */
8210 LLVMTypeRef arg_types
[5];
8214 for (i
= 1; i
<= 8; i
*= 2) {
8215 arg_types
[0] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8216 arg_types
[1] = LLVMInt32Type ();
8217 arg_types
[2] = LLVMInt1Type ();
8218 arg_types
[3] = LLVMInt32Type ();
8219 sprintf (name
, "llvm.mono.load.i%d.p0i%d", i
* 8, i
* 8);
8220 AddFunc (module
, name
, LLVMIntType (i
* 8), arg_types
, 4);
8222 arg_types
[0] = LLVMIntType (i
* 8);
8223 arg_types
[1] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8224 arg_types
[2] = LLVMInt32Type ();
8225 arg_types
[3] = LLVMInt1Type ();
8226 arg_types
[4] = LLVMInt32Type ();
8227 sprintf (name
, "llvm.mono.store.i%d.p0i%d", i
* 8, i
* 8);
8228 AddFunc (module
, name
, LLVMVoidType (), arg_types
, 5);
8234 add_types (MonoLLVMModule
*module
)
8236 module
->ptr_type
= LLVMPointerType (sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8240 mono_llvm_init (void)
8245 mono_native_tls_alloc (¤t_cfg_tls_id
, NULL
);
8247 h
= g_hash_table_new (NULL
, NULL
);
8248 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8249 g_hash_table_insert (h
, GINT_TO_POINTER (intrinsics
[i
].id
), (gpointer
)intrinsics
[i
].name
);
8250 intrins_id_to_name
= h
;
8252 h
= g_hash_table_new (g_str_hash
, g_str_equal
);
8253 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8254 g_hash_table_insert (h
, (gpointer
)intrinsics
[i
].name
, GINT_TO_POINTER (intrinsics
[i
].id
+ 1));
8255 intrins_name_to_id
= h
;
8259 init_jit_module (MonoDomain
*domain
)
8261 MonoJitDomainInfo
*dinfo
;
8262 MonoLLVMModule
*module
;
8265 dinfo
= domain_jit_info (domain
);
8266 if (dinfo
->llvm_module
)
8269 mono_loader_lock ();
8271 if (dinfo
->llvm_module
) {
8272 mono_loader_unlock ();
8276 module
= g_new0 (MonoLLVMModule
, 1);
8278 name
= g_strdup_printf ("mono-%s", domain
->friendly_name
);
8279 module
->lmodule
= LLVMModuleCreateWithName (name
);
8280 module
->context
= LLVMGetGlobalContext ();
8282 module
->mono_ee
= (MonoEERef
*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module
->lmodule
), alloc_cb
, emitted_cb
, exception_cb
, dlsym_cb
, &module
->ee
);
8284 add_intrinsics (module
->lmodule
);
8287 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
8289 #if LLVM_API_VERSION < 100
8290 MonoJitICallInfo
*info
;
8292 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8294 LLVMAddGlobalMapping (module
->ee
, LLVMGetNamedFunction (module
->lmodule
, "llvm_resume_unwind_trampoline"), (void*)info
->func
);
8297 mono_memory_barrier ();
8299 dinfo
->llvm_module
= module
;
8301 mono_loader_unlock ();
8305 mono_llvm_cleanup (void)
8307 MonoLLVMModule
*module
= &aot_module
;
8309 if (module
->lmodule
)
8310 LLVMDisposeModule (module
->lmodule
);
8312 if (module
->context
)
8313 LLVMContextDispose (module
->context
);
8317 mono_llvm_free_domain_info (MonoDomain
*domain
)
8319 MonoJitDomainInfo
*info
= domain_jit_info (domain
);
8320 MonoLLVMModule
*module
= (MonoLLVMModule
*)info
->llvm_module
;
8326 if (module
->llvm_types
)
8327 g_hash_table_destroy (module
->llvm_types
);
8329 mono_llvm_dispose_ee (module
->mono_ee
);
8331 if (module
->bb_names
) {
8332 for (i
= 0; i
< module
->bb_names_len
; ++i
)
8333 g_free (module
->bb_names
[i
]);
8334 g_free (module
->bb_names
);
8336 //LLVMDisposeModule (module->module);
8340 info
->llvm_module
= NULL
;
8344 mono_llvm_create_aot_module (MonoAssembly
*assembly
, const char *global_prefix
, gboolean emit_dwarf
, gboolean static_link
, gboolean llvm_only
)
8346 MonoLLVMModule
*module
= &aot_module
;
8348 /* Delete previous module */
8349 if (module
->plt_entries
)
8350 g_hash_table_destroy (module
->plt_entries
);
8351 if (module
->lmodule
)
8352 LLVMDisposeModule (module
->lmodule
);
8354 memset (module
, 0, sizeof (aot_module
));
8356 module
->lmodule
= LLVMModuleCreateWithName ("aot");
8357 module
->assembly
= assembly
;
8358 module
->global_prefix
= g_strdup (global_prefix
);
8359 module
->got_symbol
= g_strdup_printf ("%s_llvm_got", global_prefix
);
8360 module
->eh_frame_symbol
= g_strdup_printf ("%s_eh_frame", global_prefix
);
8361 module
->get_method_symbol
= g_strdup_printf ("%s_get_method", global_prefix
);
8362 module
->get_unbox_tramp_symbol
= g_strdup_printf ("%s_get_unbox_tramp", global_prefix
);
8363 module
->external_symbols
= TRUE
;
8364 module
->emit_dwarf
= emit_dwarf
;
8365 module
->static_link
= static_link
;
8366 module
->llvm_only
= llvm_only
;
8367 /* The first few entries are reserved */
8368 module
->max_got_offset
= 16;
8369 module
->context
= LLVMGetGlobalContext ();
8372 /* clang ignores our debug info because it has an invalid version */
8373 module
->emit_dwarf
= FALSE
;
8375 add_intrinsics (module
->lmodule
);
8378 #if LLVM_API_VERSION > 100
8379 if (module
->emit_dwarf
) {
8380 char *dir
, *build_info
, *s
, *cu_name
;
8382 module
->di_builder
= mono_llvm_create_di_builder (module
->lmodule
);
8385 dir
= g_strdup (".");
8386 build_info
= mono_get_runtime_build_info ();
8387 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
8388 cu_name
= g_path_get_basename (assembly
->image
->name
);
8389 module
->cu
= mono_llvm_di_create_compile_unit (module
->di_builder
, cu_name
, dir
, s
);
8391 g_free (build_info
);
8398 * We couldn't compute the type of the LLVM global representing the got because
8399 * its size is only known after all the methods have been emitted. So create
8400 * a dummy variable, and replace all uses it with the real got variable when
8401 * its size is known in mono_llvm_emit_aot_module ().
8404 LLVMTypeRef got_type
= LLVMArrayType (module
->ptr_type
, 0);
8406 module
->got_var
= LLVMAddGlobal (module
->lmodule
, got_type
, "mono_dummy_got");
8407 LLVMSetInitializer (module
->got_var
, LLVMConstNull (got_type
));
8410 /* Add initialization array */
8412 LLVMTypeRef inited_type
= LLVMArrayType (LLVMInt8Type (), 0);
8414 module
->inited_var
= LLVMAddGlobal (aot_module
.lmodule
, inited_type
, "mono_inited_tmp");
8415 LLVMSetInitializer (module
->inited_var
, LLVMConstNull (inited_type
));
8419 emit_init_icall_wrappers (module
);
8421 emit_llvm_code_start (module
);
8423 /* Add a dummy personality function */
8424 if (!use_debug_personality
) {
8425 LLVMValueRef personality
= LLVMAddFunction (module
->lmodule
, default_personality_name
, LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
));
8426 LLVMSetLinkage (personality
, LLVMExternalLinkage
);
8427 mark_as_used (module
, personality
);
8430 /* Add a reference to the c++ exception we throw/catch */
8432 LLVMTypeRef exc
= LLVMPointerType (LLVMInt8Type (), 0);
8433 module
->sentinel_exception
= LLVMAddGlobal (module
->lmodule
, exc
, "_ZTIPi");
8434 LLVMSetLinkage (module
->sentinel_exception
, LLVMExternalLinkage
);
8435 mono_llvm_set_is_constant (module
->sentinel_exception
);
8438 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
8439 module
->plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
8440 module
->plt_entries_ji
= g_hash_table_new (NULL
, NULL
);
8441 module
->direct_callables
= g_hash_table_new (g_str_hash
, g_str_equal
);
8442 module
->method_to_lmethod
= g_hash_table_new (NULL
, NULL
);
8443 module
->idx_to_lmethod
= g_hash_table_new (NULL
, NULL
);
8444 module
->idx_to_unbox_tramp
= g_hash_table_new (NULL
, NULL
);
8445 module
->method_to_callers
= g_hash_table_new (NULL
, NULL
);
8449 llvm_array_from_uints (LLVMTypeRef el_type
, guint32
*values
, int nvalues
)
8452 LLVMValueRef res
, *vals
;
8454 vals
= g_new0 (LLVMValueRef
, nvalues
);
8455 for (i
= 0; i
< nvalues
; ++i
)
8456 vals
[i
] = LLVMConstInt (LLVMInt32Type (), values
[i
], FALSE
);
8457 res
= LLVMConstArray (LLVMInt32Type (), vals
, nvalues
);
8463 llvm_array_from_bytes (guint8
*values
, int nvalues
)
8466 LLVMValueRef res
, *vals
;
8468 vals
= g_new0 (LLVMValueRef
, nvalues
);
8469 for (i
= 0; i
< nvalues
; ++i
)
8470 vals
[i
] = LLVMConstInt (LLVMInt8Type (), values
[i
], FALSE
);
8471 res
= LLVMConstArray (LLVMInt8Type (), vals
, nvalues
);
8476 * mono_llvm_emit_aot_file_info:
8478 * Emit the MonoAotFileInfo structure.
8479 * Same as emit_aot_file_info () in aot-compiler.c.
8482 mono_llvm_emit_aot_file_info (MonoAotFileInfo
*info
, gboolean has_jitted_code
)
8484 MonoLLVMModule
*module
= &aot_module
;
8486 /* Save these for later */
8487 memcpy (&module
->aot_info
, info
, sizeof (MonoAotFileInfo
));
8488 module
->has_jitted_code
= has_jitted_code
;
8492 * mono_llvm_emit_aot_data:
8494 * Emit the binary data DATA pointed to by symbol SYMBOL.
8497 mono_llvm_emit_aot_data (const char *symbol
, guint8
*data
, int data_len
)
8499 MonoLLVMModule
*module
= &aot_module
;
8503 type
= LLVMArrayType (LLVMInt8Type (), data_len
);
8504 d
= LLVMAddGlobal (module
->lmodule
, type
, symbol
);
8505 LLVMSetVisibility (d
, LLVMHiddenVisibility
);
8506 LLVMSetLinkage (d
, LLVMInternalLinkage
);
8507 LLVMSetInitializer (d
, mono_llvm_create_constant_data_array (data
, data_len
));
8508 mono_llvm_set_is_constant (d
);
8511 /* Add a reference to a global defined in JITted code */
8513 AddJitGlobal (MonoLLVMModule
*module
, LLVMTypeRef type
, const char *name
)
8518 s
= g_strdup_printf ("%s%s", module
->global_prefix
, name
);
8519 v
= LLVMAddGlobal (module
->lmodule
, LLVMInt8Type (), s
);
8525 emit_aot_file_info (MonoLLVMModule
*module
)
8527 LLVMTypeRef file_info_type
;
8528 LLVMTypeRef
*eltypes
, eltype
;
8529 LLVMValueRef info_var
;
8530 LLVMValueRef
*fields
;
8531 int i
, nfields
, tindex
;
8532 MonoAotFileInfo
*info
;
8533 LLVMModuleRef lmodule
= module
->lmodule
;
8535 info
= &module
->aot_info
;
8537 /* Create an LLVM type to represent MonoAotFileInfo */
8538 nfields
= 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS
+ 16 + 5;
8539 eltypes
= g_new (LLVMTypeRef
, nfields
);
8541 eltypes
[tindex
++] = LLVMInt32Type ();
8542 eltypes
[tindex
++] = LLVMInt32Type ();
8544 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
)
8545 eltypes
[tindex
++] = LLVMPointerType (LLVMInt8Type (), 0);
8547 for (i
= 0; i
< 15; ++i
)
8548 eltypes
[tindex
++] = LLVMInt32Type ();
8550 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM
);
8551 for (i
= 0; i
< 4; ++i
)
8552 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM
);
8553 eltypes
[tindex
++] = LLVMArrayType (LLVMInt8Type (), 16);
8554 g_assert (tindex
== nfields
);
8555 file_info_type
= LLVMStructCreateNamed (module
->context
, "MonoAotFileInfo");
8556 LLVMStructSetBody (file_info_type
, eltypes
, nfields
, FALSE
);
8558 info_var
= LLVMAddGlobal (lmodule
, file_info_type
, "mono_aot_file_info");
8559 if (module
->static_link
) {
8560 LLVMSetVisibility (info_var
, LLVMHiddenVisibility
);
8561 LLVMSetLinkage (info_var
, LLVMInternalLinkage
);
8563 fields
= g_new (LLVMValueRef
, nfields
);
8565 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->version
, FALSE
);
8566 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->dummy
, FALSE
);
8570 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8571 * for symbols defined in the .s file emitted by the aot compiler.
8573 eltype
= eltypes
[tindex
];
8574 if (module
->llvm_only
)
8575 fields
[tindex
++] = LLVMConstNull (eltype
);
8577 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_got");
8578 fields
[tindex
++] = module
->got_var
;
8579 /* llc defines this directly */
8580 if (!module
->llvm_only
) {
8581 fields
[tindex
++] = LLVMAddGlobal (lmodule
, eltype
, module
->eh_frame_symbol
);
8582 fields
[tindex
++] = LLVMConstNull (eltype
);
8583 fields
[tindex
++] = LLVMConstNull (eltype
);
8585 fields
[tindex
++] = LLVMConstNull (eltype
);
8586 fields
[tindex
++] = module
->get_method
;
8587 fields
[tindex
++] = module
->get_unbox_tramp
;
8589 if (module
->has_jitted_code
) {
8590 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_start");
8591 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_end");
8593 fields
[tindex
++] = LLVMConstNull (eltype
);
8594 fields
[tindex
++] = LLVMConstNull (eltype
);
8596 if (!module
->llvm_only
)
8597 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "method_addresses");
8599 fields
[tindex
++] = LLVMConstNull (eltype
);
8600 if (info
->flags
& MONO_AOT_FILE_FLAG_SEPARATE_DATA
) {
8601 for (i
= 0; i
< MONO_AOT_TABLE_NUM
; ++i
)
8602 fields
[tindex
++] = LLVMConstNull (eltype
);
8604 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "blob");
8605 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_name_table");
8606 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_info_offsets");
8607 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "method_info_offsets");
8608 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "ex_info_offsets");
8609 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_info_offsets");
8610 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_table");
8611 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "got_info_offsets");
8612 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "llvm_got_info_offsets");
8613 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "image_table");
8615 /* Not needed (mem_end) */
8616 fields
[tindex
++] = LLVMConstNull (eltype
);
8617 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_guid");
8618 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "runtime_version");
8619 if (info
->trampoline_size
[0]) {
8620 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "specific_trampolines");
8621 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "static_rgctx_trampolines");
8622 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "imt_thunks");
8623 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "gsharedvt_arg_trampolines");
8625 fields
[tindex
++] = LLVMConstNull (eltype
);
8626 fields
[tindex
++] = LLVMConstNull (eltype
);
8627 fields
[tindex
++] = LLVMConstNull (eltype
);
8628 fields
[tindex
++] = LLVMConstNull (eltype
);
8630 if (module
->static_link
&& !module
->llvm_only
)
8631 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "globals");
8633 fields
[tindex
++] = LLVMConstNull (eltype
);
8634 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_name");
8635 if (!module
->llvm_only
) {
8636 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt");
8637 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt_end");
8638 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unwind_info");
8639 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines");
8640 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines_end");
8641 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampoline_addresses");
8643 fields
[tindex
++] = LLVMConstNull (eltype
);
8644 fields
[tindex
++] = LLVMConstNull (eltype
);
8645 fields
[tindex
++] = LLVMConstNull (eltype
);
8646 fields
[tindex
++] = LLVMConstNull (eltype
);
8647 fields
[tindex
++] = LLVMConstNull (eltype
);
8648 fields
[tindex
++] = LLVMConstNull (eltype
);
8651 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
)
8652 fields
[2 + i
] = LLVMConstBitCast (fields
[2 + i
], eltype
);
8655 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_got_offset_base
, FALSE
);
8656 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->got_size
, FALSE
);
8657 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_size
, FALSE
);
8658 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nmethods
, FALSE
);
8659 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->flags
, FALSE
);
8660 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->opts
, FALSE
);
8661 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->simd_opts
, FALSE
);
8662 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->gc_name_index
, FALSE
);
8663 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->num_rgctx_fetch_trampolines
, FALSE
);
8664 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->double_align
, FALSE
);
8665 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->long_align
, FALSE
);
8666 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->generic_tramp_num
, FALSE
);
8667 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->tramp_page_size
, FALSE
);
8668 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nshared_got_entries
, FALSE
);
8669 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->datafile_size
, FALSE
);
8671 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->table_offsets
, MONO_AOT_TABLE_NUM
);
8672 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->num_trampolines
, MONO_AOT_TRAMP_NUM
);
8673 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_got_offset_base
, MONO_AOT_TRAMP_NUM
);
8674 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_size
, MONO_AOT_TRAMP_NUM
);
8675 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->tramp_page_code_offsets
, MONO_AOT_TRAMP_NUM
);
8677 fields
[tindex
++] = llvm_array_from_bytes (info
->aotid
, 16);
8678 g_assert (tindex
== nfields
);
8680 LLVMSetInitializer (info_var
, LLVMConstNamedStruct (file_info_type
, fields
, nfields
));
8682 if (module
->static_link
) {
8686 s
= g_strdup_printf ("mono_aot_module_%s_info", module
->assembly
->aname
.name
);
8687 /* Get rid of characters which cannot occur in symbols */
8689 for (p
= s
; *p
; ++p
) {
8690 if (!(isalnum (*p
) || *p
== '_'))
8693 var
= LLVMAddGlobal (module
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), s
);
8695 LLVMSetInitializer (var
, LLVMConstBitCast (LLVMGetNamedGlobal (module
->lmodule
, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8696 LLVMSetLinkage (var
, LLVMExternalLinkage
);
8701 * Emit the aot module into the LLVM bitcode file FILENAME.
8704 mono_llvm_emit_aot_module (const char *filename
, const char *cu_name
)
8706 LLVMTypeRef got_type
, inited_type
;
8707 LLVMValueRef real_got
, real_inited
;
8708 MonoLLVMModule
*module
= &aot_module
;
8710 emit_llvm_code_end (module
);
8713 * Create the real got variable and replace all uses of the dummy variable with
8716 got_type
= LLVMArrayType (module
->ptr_type
, module
->max_got_offset
+ 1);
8717 real_got
= LLVMAddGlobal (module
->lmodule
, got_type
, module
->got_symbol
);
8718 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
8719 if (module
->external_symbols
) {
8720 LLVMSetLinkage (real_got
, LLVMExternalLinkage
);
8721 LLVMSetVisibility (real_got
, LLVMHiddenVisibility
);
8723 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
8725 mono_llvm_replace_uses_of (module
->got_var
, real_got
);
8727 mark_as_used (&aot_module
, real_got
);
8729 /* Delete the dummy got so it doesn't become a global */
8730 LLVMDeleteGlobal (module
->got_var
);
8731 module
->got_var
= real_got
;
8734 * Same for the init_var
8736 if (module
->llvm_only
) {
8737 inited_type
= LLVMArrayType (LLVMInt8Type (), module
->max_inited_idx
+ 1);
8738 real_inited
= LLVMAddGlobal (module
->lmodule
, inited_type
, "mono_inited");
8739 LLVMSetInitializer (real_inited
, LLVMConstNull (inited_type
));
8740 LLVMSetLinkage (real_inited
, LLVMInternalLinkage
);
8741 mono_llvm_replace_uses_of (module
->inited_var
, real_inited
);
8742 LLVMDeleteGlobal (module
->inited_var
);
8745 if (module
->llvm_only
) {
8746 emit_get_method (&aot_module
);
8747 emit_get_unbox_tramp (&aot_module
);
8750 emit_llvm_used (&aot_module
);
8751 emit_dbg_info (&aot_module
, filename
, cu_name
);
8752 emit_aot_file_info (&aot_module
);
8755 * Replace GOT entries for directly callable methods with the methods themselves.
8756 * It would be easier to implement this by predefining all methods before compiling
8757 * their bodies, but that couldn't handle the case when a method fails to compile
8760 if (module
->llvm_only
) {
8761 GHashTableIter iter
;
8763 GSList
*callers
, *l
;
8765 g_hash_table_iter_init (&iter
, module
->method_to_callers
);
8766 while (g_hash_table_iter_next (&iter
, (void**)&method
, (void**)&callers
)) {
8767 LLVMValueRef lmethod
;
8769 if (method
->iflags
& METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED
)
8772 lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, method
);
8774 for (l
= callers
; l
; l
= l
->next
) {
8775 LLVMValueRef caller
= (LLVMValueRef
)l
->data
;
8777 mono_llvm_replace_uses_of (caller
, lmethod
);
8783 /* Replace PLT entries for directly callable methods with the methods themselves */
8785 GHashTableIter iter
;
8787 LLVMValueRef callee
;
8789 g_hash_table_iter_init (&iter
, module
->plt_entries_ji
);
8790 while (g_hash_table_iter_next (&iter
, (void**)&ji
, (void**)&callee
)) {
8791 if (mono_aot_is_direct_callable (ji
)) {
8792 LLVMValueRef lmethod
;
8794 lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, ji
->data
.method
);
8795 /* The types might not match because the caller might pass an rgctx */
8796 if (lmethod
&& LLVMTypeOf (callee
) == LLVMTypeOf (lmethod
)) {
8797 mono_llvm_replace_uses_of (callee
, lmethod
);
8798 mono_aot_mark_unused_llvm_plt_entry (ji
);
8808 if (LLVMVerifyModule (module
->lmodule
, LLVMReturnStatusAction
, &verifier_err
)) {
8809 printf ("%s\n", verifier_err
);
8810 g_assert_not_reached ();
8815 LLVMWriteBitcodeToFile (module
->lmodule
, filename
);
8820 md_string (const char *s
)
8822 return LLVMMDString (s
, strlen (s
));
8825 /* Debugging support */
8828 emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
)
8830 LLVMModuleRef lmodule
= module
->lmodule
;
8831 LLVMValueRef args
[16], ver
;
8834 * This can only be enabled when LLVM code is emitted into a separate object
8835 * file, since the AOT compiler also emits dwarf info,
8836 * and the abbrev indexes will not be correct since llvm has added its own
8839 if (!module
->emit_dwarf
)
8842 #if LLVM_API_VERSION > 100
8843 mono_llvm_di_builder_finalize (module
->di_builder
);
8845 LLVMValueRef cu_args
[16], cu
;
8847 char *build_info
, *s
, *dir
;
8850 * Emit dwarf info in the form of LLVM metadata. There is some
8851 * out-of-date documentation at:
8852 * http://llvm.org/docs/SourceLevelDebugging.html
8853 * but most of this was gathered from the llvm and
8858 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit
, FALSE
);
8859 /* CU name/compilation dir */
8860 dir
= g_path_get_dirname (filename
);
8861 args
[0] = LLVMMDString (cu_name
, strlen (cu_name
));
8862 args
[1] = LLVMMDString (dir
, strlen (dir
));
8863 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 2);
8866 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99
, FALSE
);
8868 build_info
= mono_get_runtime_build_info ();
8869 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
8870 cu_args
[n_cuargs
++] = LLVMMDString (s
, strlen (s
));
8871 g_free (build_info
);
8873 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8875 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
8876 /* Runtime version */
8877 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8879 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8880 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8882 if (module
->subprogram_mds
) {
8886 mds
= g_new0 (LLVMValueRef
, module
->subprogram_mds
->len
);
8887 for (i
= 0; i
< module
->subprogram_mds
->len
; ++i
)
8888 mds
[i
] = (LLVMValueRef
)g_ptr_array_index (module
->subprogram_mds
, i
);
8889 cu_args
[n_cuargs
++] = LLVMMDNode (mds
, module
->subprogram_mds
->len
);
8891 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8894 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8895 /* Imported modules */
8896 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8898 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
8899 /* DebugEmissionKind = FullDebug */
8900 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8901 cu
= LLVMMDNode (cu_args
, n_cuargs
);
8902 LLVMAddNamedMetadataOperand (lmodule
, "llvm.dbg.cu", cu
);
8905 #if LLVM_API_VERSION > 100
8906 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8907 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8908 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8909 ver
= LLVMMDNode (args
, 3);
8910 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8912 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8913 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8914 args
[2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE
);
8915 ver
= LLVMMDNode (args
, 3);
8916 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8918 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8919 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8920 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8921 ver
= LLVMMDNode (args
, 3);
8922 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8924 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8925 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8926 args
[2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8927 ver
= LLVMMDNode (args
, 3);
8928 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8933 emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
)
8935 MonoLLVMModule
*module
= ctx
->module
;
8936 MonoDebugMethodInfo
*minfo
= ctx
->minfo
;
8937 char *source_file
, *dir
, *filename
;
8938 LLVMValueRef md
, args
[16], ctx_args
[16], md_args
[64], type_args
[16], ctx_md
, type_md
;
8939 MonoSymSeqPoint
*sym_seq_points
;
8945 mono_debug_symfile_get_seq_points (minfo
, &source_file
, NULL
, NULL
, &sym_seq_points
, &n_seq_points
);
8947 source_file
= g_strdup ("<unknown>");
8948 dir
= g_path_get_dirname (source_file
);
8949 filename
= g_path_get_basename (source_file
);
8951 #if LLVM_API_VERSION > 100
8952 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);
8955 ctx_args
[0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE
);
8956 args
[0] = md_string (filename
);
8957 args
[1] = md_string (dir
);
8958 ctx_args
[1] = LLVMMDNode (args
, 2);
8959 ctx_md
= LLVMMDNode (ctx_args
, 2);
8961 type_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type
, FALSE
);
8962 type_args
[1] = NULL
;
8963 type_args
[2] = NULL
;
8964 type_args
[3] = LLVMMDString ("", 0);
8965 type_args
[4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8966 type_args
[5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
8967 type_args
[6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
8968 type_args
[7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
8969 type_args
[8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8970 type_args
[9] = NULL
;
8971 type_args
[10] = NULL
;
8972 type_args
[11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8973 type_args
[12] = NULL
;
8974 type_args
[13] = NULL
;
8975 type_args
[14] = NULL
;
8976 type_md
= LLVMMDNode (type_args
, 14);
8978 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8979 md_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram
, FALSE
);
8980 /* Source directory + file pair */
8981 args
[0] = md_string (filename
);
8982 args
[1] = md_string (dir
);
8983 md_args
[1] = LLVMMDNode (args
,2);
8984 md_args
[2] = ctx_md
;
8985 md_args
[3] = md_string (cfg
->method
->name
);
8986 md_args
[4] = md_string (name
);
8987 md_args
[5] = md_string (name
);
8990 md_args
[6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points
[0].line
, FALSE
);
8992 md_args
[6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8994 md_args
[7] = type_md
;
8996 md_args
[8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
8998 md_args
[9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
9000 md_args
[10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9001 /* Index into a virtual function */
9002 md_args
[11] = NULL
;
9003 md_args
[12] = NULL
;
9005 md_args
[13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
9007 md_args
[14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
9008 /* Pointer to LLVM function */
9009 md_args
[15] = method
;
9010 /* Function template parameter */
9011 md_args
[16] = NULL
;
9012 /* Function declaration descriptor */
9013 md_args
[17] = NULL
;
9014 /* List of function variables */
9015 md_args
[18] = LLVMMDNode (args
, 0);
9017 md_args
[19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9018 md
= LLVMMDNode (md_args
, 20);
9020 if (!module
->subprogram_mds
)
9021 module
->subprogram_mds
= g_ptr_array_new ();
9022 g_ptr_array_add (module
->subprogram_mds
, md
);
9026 g_free (source_file
);
9027 g_free (sym_seq_points
);
9033 emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
)
9035 MonoCompile
*cfg
= ctx
->cfg
;
9037 if (ctx
->minfo
&& cil_code
&& cil_code
>= cfg
->header
->code
&& cil_code
< cfg
->header
->code
+ cfg
->header
->code_size
) {
9038 MonoDebugSourceLocation
*loc
;
9039 LLVMValueRef loc_md
;
9041 loc
= mono_debug_symfile_lookup_location (ctx
->minfo
, cil_code
- cfg
->header
->code
);
9044 #if LLVM_API_VERSION > 100
9045 loc_md
= mono_llvm_di_create_location (ctx
->module
->di_builder
, ctx
->dbg_md
, loc
->row
, loc
->column
);
9046 mono_llvm_di_set_location (builder
, loc_md
);
9048 LLVMValueRef md_args
[16];
9052 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->row
, FALSE
);
9053 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->column
, FALSE
);
9054 md_args
[nmd_args
++] = ctx
->dbg_md
;
9055 md_args
[nmd_args
++] = NULL
;
9056 loc_md
= LLVMMDNode (md_args
, nmd_args
);
9057 LLVMSetCurrentDebugLocation (builder
, loc_md
);
9059 mono_debug_symfile_free_location (loc
);
9065 default_mono_llvm_unhandled_exception (void)
9067 MonoJitTlsData
*jit_tls
= mono_get_jit_tls ();
9068 MonoObject
*target
= mono_gchandle_get_target (jit_tls
->thrown_exc
);
9070 mono_unhandled_exception (target
);
9071 mono_invoke_unhandled_exception_hook (target
);
9072 g_assert_not_reached ();
9077 - Emit LLVM IR from the mono IR using the LLVM C API.
9078 - The original arch specific code remains, so we can fall back to it if we run
9079 into something we can't handle.
9083 A partial list of issues:
9084 - Handling of opcodes which can throw exceptions.
9086 In the mono JIT, these are implemented using code like this:
9093 push throw_pos - method
9094 call <exception trampoline>
9096 The problematic part is push throw_pos - method, which cannot be represented
9097 in the LLVM IR, since it does not support label values.
9098 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9099 be implemented in JIT mode ?
9100 -> a possible but slower implementation would use the normal exception
9101 throwing code but it would need to control the placement of the throw code
9102 (it needs to be exactly after the compare+branch).
9103 -> perhaps add a PC offset intrinsics ?
9105 - efficient implementation of .ovf opcodes.
9107 These are currently implemented as:
9108 <ins which sets the condition codes>
9111 Some overflow opcodes are now supported by LLVM SVN.
9113 - exception handling, unwinding.
9114 - SSA is disabled for methods with exception handlers
9115 - How to obtain unwind info for LLVM compiled methods ?
9116 -> this is now solved by converting the unwind info generated by LLVM
9118 - LLVM uses the c++ exception handling framework, while we use our home grown
9119 code, and couldn't use the c++ one:
9120 - its not supported under VC++, other exotic platforms.
9121 - it might be impossible to support filter clauses with it.
9125 The trampolines need a predictable call sequence, since they need to disasm
9126 the calling code to obtain register numbers / offsets.
9128 LLVM currently generates this code in non-JIT mode:
9129 mov -0x98(%rax),%eax
9131 Here, the vtable pointer is lost.
9132 -> solution: use one vtable trampoline per class.
9134 - passing/receiving the IMT pointer/RGCTX.
9135 -> solution: pass them as normal arguments ?
9139 LLVM does not allow the specification of argument registers etc. This means
9140 that all calls are made according to the platform ABI.
9142 - passing/receiving vtypes.
9144 Vtypes passed/received in registers are handled by the front end by using
9145 a signature with scalar arguments, and loading the parts of the vtype into those
9148 Vtypes passed on the stack are handled using the 'byval' attribute.
9152 Supported though alloca, we need to emit the load/store code.
9156 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9157 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9158 This is made easier because the IR is already in SSA form.
9159 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9160 types are frequently used incorrectly.
9165 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9166 it with the file containing the methods emitted by the JIT and the AOT data
9170 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9171 * - each bblock should end with a branch
9172 * - setting the return value, making cfg->ret non-volatile
9173 * - avoid some transformations in the JIT which make it harder for us to generate
9175 * - use pointer types to help optimizations.