3 * llvm "Backend" for the mono JIT
5 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
6 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
7 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #include <mono/metadata/debug-helpers.h>
13 #include <mono/metadata/debug-internals.h>
14 #include <mono/metadata/mempool-internals.h>
15 #include <mono/metadata/environment.h>
16 #include <mono/metadata/object-internals.h>
17 #include <mono/metadata/abi-details.h>
18 #include <mono/utils/mono-tls.h>
19 #include <mono/utils/mono-dl.h>
20 #include <mono/utils/mono-time.h>
21 #include <mono/utils/freebsd-dwarf.h>
23 #ifndef __STDC_LIMIT_MACROS
24 #define __STDC_LIMIT_MACROS
26 #ifndef __STDC_CONSTANT_MACROS
27 #define __STDC_CONSTANT_MACROS
30 #include "llvm-c/BitWriter.h"
31 #include "llvm-c/Analysis.h"
33 #include "mini-llvm-cpp.h"
35 #include "aot-compiler.h"
36 #include "mini-llvm.h"
37 #include "mini-runtime.h"
38 #include <mono/utils/mono-math.h>
42 #if defined(TARGET_AMD64) && defined(TARGET_WIN32) && defined(HOST_WIN32) && defined(_MSC_VER)
43 #define TARGET_X86_64_WIN32_MSVC
46 #if defined(TARGET_X86_64_WIN32_MSVC)
47 #define TARGET_WIN32_MSVC
50 #if LLVM_API_VERSION < 4
51 #error "The version of the mono llvm repository is too old."
55 * Information associated by mono with LLVM modules.
58 LLVMModuleRef lmodule
;
59 LLVMValueRef throw_icall
, rethrow
, throw_corlib_exception
;
60 GHashTable
*llvm_types
;
62 const char *got_symbol
;
63 const char *get_method_symbol
;
64 const char *get_unbox_tramp_symbol
;
65 GHashTable
*plt_entries
;
66 GHashTable
*plt_entries_ji
;
67 GHashTable
*method_to_lmethod
;
68 GHashTable
*direct_callables
;
73 GPtrArray
*subprogram_mds
;
75 LLVMExecutionEngineRef ee
;
76 gboolean external_symbols
;
79 LLVMValueRef personality
;
80 LLVMValueRef
*intrins_by_id
;
83 MonoAssembly
*assembly
;
85 MonoAotFileInfo aot_info
;
86 const char *jit_got_symbol
;
87 const char *eh_frame_symbol
;
88 LLVMValueRef get_method
, get_unbox_tramp
;
89 LLVMValueRef init_method
, init_method_gshared_mrgctx
, init_method_gshared_this
, init_method_gshared_vtable
;
90 LLVMValueRef code_start
, code_end
;
91 LLVMValueRef inited_var
;
92 LLVMValueRef unbox_tramp_indexes
;
93 LLVMValueRef unbox_trampolines
;
94 int max_inited_idx
, max_method_idx
;
95 gboolean has_jitted_code
;
98 gboolean llvm_disable_self_init
;
100 GHashTable
*idx_to_lmethod
;
101 GHashTable
*idx_to_unbox_tramp
;
102 GPtrArray
*callsite_list
;
103 LLVMContextRef context
;
104 LLVMValueRef sentinel_exception
;
105 void *di_builder
, *cu
;
106 GHashTable
*objc_selector_to_var
;
108 int unbox_tramp_num
, unbox_tramp_elemsize
;
109 GHashTable
*got_idx_to_type
;
113 * Information associated by the backend with mono basic blocks.
116 LLVMBasicBlockRef bblock
, end_bblock
;
117 LLVMValueRef finally_ind
;
118 gboolean added
, invoke_target
;
120 * If this bblock is the start of a finally clause, this is a list of bblocks it
121 * needs to branch to in ENDFINALLY.
123 GSList
*call_handler_return_bbs
;
125 * If this bblock is the start of a finally clause, this is the bblock that
126 * CALL_HANDLER needs to branch to.
128 LLVMBasicBlockRef call_handler_target_bb
;
129 /* The list of switch statements generated by ENDFINALLY instructions */
130 GSList
*endfinally_switch_ins_list
;
135 * Structure containing emit state
138 MonoMemPool
*mempool
;
140 /* Maps method names to the corresponding LLVMValueRef */
141 GHashTable
*emitted_method_decls
;
144 LLVMValueRef lmethod
;
145 MonoLLVMModule
*module
;
146 LLVMModuleRef lmodule
;
148 int sindex
, default_index
, ex_index
;
149 LLVMBuilderRef builder
;
150 LLVMValueRef
*values
, *addresses
;
151 MonoType
**vreg_cli_types
;
153 MonoMethodSignature
*sig
;
155 GHashTable
*region_to_handler
;
156 GHashTable
*clause_to_handler
;
157 LLVMBuilderRef alloca_builder
;
158 LLVMValueRef last_alloca
;
159 LLVMValueRef rgctx_arg
;
160 LLVMValueRef this_arg
;
161 LLVMTypeRef
*vreg_types
;
163 LLVMTypeRef method_type
;
164 LLVMBasicBlockRef init_bb
, inited_bb
;
166 gboolean
*unreachable
;
168 gboolean has_got_access
;
169 gboolean emit_dummy_arg
;
170 int this_arg_pindex
, rgctx_arg_pindex
;
171 LLVMValueRef imt_rgctx_loc
;
172 GHashTable
*llvm_types
;
174 MonoDebugMethodInfo
*minfo
;
175 /* For every clause, the clauses it is nested in */
178 GHashTable
*exc_meta
;
179 GPtrArray
*callsite_list
;
180 GPtrArray
*phi_values
;
181 GPtrArray
*bblock_list
;
183 GHashTable
*jit_callees
;
184 LLVMValueRef long_bb_break_var
;
190 MonoBasicBlock
*in_bb
;
195 * Instruction metadata
196 * This is the same as ins_info, but LREG != IREG.
204 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
205 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
212 /* keep in sync with the enum in mini.h */
214 mini_llvm_ins_info
[] = {
215 #include "mini-ops.h"
220 #if TARGET_SIZEOF_VOID_P == 4
221 #define GET_LONG_IMM(ins) ((ins)->inst_l)
223 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
226 #define LLVM_INS_INFO(opcode) (&mini_llvm_ins_info [((opcode) - OP_START - 1) * 4])
229 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
231 #define TRACE_FAILURE(msg)
235 #define IS_TARGET_X86 1
237 #define IS_TARGET_X86 0
241 #define IS_TARGET_AMD64 1
243 #define IS_TARGET_AMD64 0
246 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
248 static LLVMIntPredicate cond_to_llvm_cond
[] = {
261 static LLVMRealPredicate fpcond_to_llvm_cond
[] = {
277 INTRINS_SADD_OVF_I32
,
278 INTRINS_UADD_OVF_I32
,
279 INTRINS_SSUB_OVF_I32
,
280 INTRINS_USUB_OVF_I32
,
281 INTRINS_SMUL_OVF_I32
,
282 INTRINS_UMUL_OVF_I32
,
283 INTRINS_SADD_OVF_I64
,
284 INTRINS_UADD_OVF_I64
,
285 INTRINS_SSUB_OVF_I64
,
286 INTRINS_USUB_OVF_I64
,
287 INTRINS_SMUL_OVF_I64
,
288 INTRINS_UMUL_OVF_I64
,
300 #if defined(TARGET_AMD64) || defined(TARGET_X86)
301 INTRINS_SSE_PMOVMSKB
,
312 INTRINS_SSE_RSQRT_PS
,
314 INTRINS_SSE_CVTTPD2DQ
,
315 INTRINS_SSE_CVTTPS2DQ
,
316 INTRINS_SSE_CVTDQ2PD
,
317 INTRINS_SSE_CVTDQ2PS
,
318 INTRINS_SSE_CVTPD2DQ
,
319 INTRINS_SSE_CVTPS2DQ
,
320 INTRINS_SSE_CVTPD2PS
,
321 INTRINS_SSE_CVTPS2PD
,
324 INTRINS_SSE_PACKSSWB
,
325 INTRINS_SSE_PACKUSWB
,
326 INTRINS_SSE_PACKSSDW
,
327 INTRINS_SSE_PACKUSDW
,
332 INTRINS_SSE_ADDSUBPS
,
337 INTRINS_SSE_ADDSUBPD
,
357 static MonoNativeTlsKey current_cfg_tls_id
;
359 static MonoLLVMModule aot_module
;
361 static GHashTable
*intrins_id_to_name
;
362 static GHashTable
*intrins_name_to_id
;
364 static void init_jit_module (MonoDomain
*domain
);
366 static void emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
);
367 static void emit_default_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
);
368 static LLVMValueRef
emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
);
369 static void emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
);
370 static void emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
);
371 static LLVMValueRef
get_intrins_by_name (EmitContext
*ctx
, const char *name
);
372 static LLVMValueRef
get_intrins (EmitContext
*ctx
, int id
);
373 static void llvm_jit_finalize_method (EmitContext
*ctx
);
376 set_failure (EmitContext
*ctx
, const char *message
)
378 TRACE_FAILURE (reason
);
379 ctx
->cfg
->exception_message
= g_strdup (message
);
380 ctx
->cfg
->disable_llvm
= TRUE
;
386 * The LLVM type with width == TARGET_SIZEOF_VOID_P
391 return TARGET_SIZEOF_VOID_P
== 8 ? LLVMInt64Type () : LLVMInt32Type ();
397 return TARGET_SIZEOF_VOID_P
== 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
403 return TARGET_SIZEOF_VOID_P
== 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
409 * Return the size of the LLVM representation of the vtype T.
412 get_vtype_size (MonoType
*t
)
416 size
= mono_class_value_size (mono_class_from_mono_type_internal (t
), NULL
);
418 /* LLVMArgAsIArgs depends on this since it stores whole words */
419 while (size
< 2 * TARGET_SIZEOF_VOID_P
&& mono_is_power_of_two (size
) == -1)
426 * simd_class_to_llvm_type:
428 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
431 simd_class_to_llvm_type (EmitContext
*ctx
, MonoClass
*klass
)
433 const char *klass_name
= m_class_get_name (klass
);
434 if (!strcmp (klass_name
, "Vector2d")) {
435 return LLVMVectorType (LLVMDoubleType (), 2);
436 } else if (!strcmp (klass_name
, "Vector2l")) {
437 return LLVMVectorType (LLVMInt64Type (), 2);
438 } else if (!strcmp (klass_name
, "Vector2ul")) {
439 return LLVMVectorType (LLVMInt64Type (), 2);
440 } else if (!strcmp (klass_name
, "Vector4i")) {
441 return LLVMVectorType (LLVMInt32Type (), 4);
442 } else if (!strcmp (klass_name
, "Vector4ui")) {
443 return LLVMVectorType (LLVMInt32Type (), 4);
444 } else if (!strcmp (klass_name
, "Vector4f")) {
445 return LLVMVectorType (LLVMFloatType (), 4);
446 } else if (!strcmp (klass_name
, "Vector8s")) {
447 return LLVMVectorType (LLVMInt16Type (), 8);
448 } else if (!strcmp (klass_name
, "Vector8us")) {
449 return LLVMVectorType (LLVMInt16Type (), 8);
450 } else if (!strcmp (klass_name
, "Vector16sb")) {
451 return LLVMVectorType (LLVMInt8Type (), 16);
452 } else if (!strcmp (klass_name
, "Vector16b")) {
453 return LLVMVectorType (LLVMInt8Type (), 16);
454 } else if (!strcmp (klass_name
, "Vector2")) {
455 /* System.Numerics */
456 return LLVMVectorType (LLVMFloatType (), 4);
457 } else if (!strcmp (klass_name
, "Vector3")) {
458 return LLVMVectorType (LLVMFloatType (), 4);
459 } else if (!strcmp (klass_name
, "Vector4")) {
460 return LLVMVectorType (LLVMFloatType (), 4);
461 } else if (!strcmp (klass_name
, "Vector`1")) {
462 MonoType
*etype
= mono_class_get_generic_class (klass
)->context
.class_inst
->type_argv
[0];
463 switch (etype
->type
) {
466 return LLVMVectorType (LLVMInt8Type (), 16);
469 return LLVMVectorType (LLVMInt16Type (), 8);
472 return LLVMVectorType (LLVMInt32Type (), 4);
475 return LLVMVectorType (LLVMInt64Type (), 2);
477 return LLVMVectorType (LLVMFloatType (), 4);
479 return LLVMVectorType (LLVMDoubleType (), 2);
481 g_assert_not_reached ();
485 printf ("%s\n", klass_name
);
491 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
492 static inline G_GNUC_UNUSED LLVMTypeRef
493 type_to_simd_type (int type
)
497 return LLVMVectorType (LLVMInt8Type (), 16);
499 return LLVMVectorType (LLVMInt16Type (), 8);
501 return LLVMVectorType (LLVMInt32Type (), 4);
503 return LLVMVectorType (LLVMInt64Type (), 2);
505 return LLVMVectorType (LLVMDoubleType (), 2);
507 return LLVMVectorType (LLVMFloatType (), 4);
509 g_assert_not_reached ();
515 create_llvm_type_for_type (MonoLLVMModule
*module
, MonoClass
*klass
)
517 int i
, size
, nfields
, esize
;
518 LLVMTypeRef
*eltypes
;
523 t
= m_class_get_byval_arg (klass
);
525 if (mini_type_is_hfa (t
, &nfields
, &esize
)) {
527 * This is needed on arm64 where HFAs are returned in
530 /* SIMD types have size 16 in mono_class_value_size () */
531 if (m_class_is_simd_type (klass
))
534 eltypes
= g_new (LLVMTypeRef
, size
);
535 for (i
= 0; i
< size
; ++i
)
536 eltypes
[i
] = esize
== 4 ? LLVMFloatType () : LLVMDoubleType ();
538 size
= get_vtype_size (t
);
540 eltypes
= g_new (LLVMTypeRef
, size
);
541 for (i
= 0; i
< size
; ++i
)
542 eltypes
[i
] = LLVMInt8Type ();
545 name
= mono_type_full_name (m_class_get_byval_arg (klass
));
546 ltype
= LLVMStructCreateNamed (module
->context
, name
);
547 LLVMStructSetBody (ltype
, eltypes
, size
, FALSE
);
557 * Return the LLVM type corresponding to T.
560 type_to_llvm_type (EmitContext
*ctx
, MonoType
*t
)
565 t
= mini_get_underlying_type (t
);
569 return LLVMVoidType ();
571 return LLVMInt8Type ();
573 return LLVMInt16Type ();
575 return LLVMInt32Type ();
577 return LLVMInt8Type ();
579 return LLVMInt16Type ();
581 return LLVMInt32Type ();
584 return LLVMInt64Type ();
586 return LLVMFloatType ();
588 return LLVMDoubleType ();
591 return IntPtrType ();
592 case MONO_TYPE_OBJECT
:
594 return ObjRefType ();
597 /* Because of generic sharing */
598 return ObjRefType ();
599 case MONO_TYPE_GENERICINST
:
600 if (!mono_type_generic_inst_is_valuetype (t
))
601 return ObjRefType ();
603 case MONO_TYPE_VALUETYPE
:
604 case MONO_TYPE_TYPEDBYREF
: {
608 klass
= mono_class_from_mono_type_internal (t
);
610 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
611 return simd_class_to_llvm_type (ctx
, klass
);
613 if (m_class_is_enumtype (klass
))
614 return type_to_llvm_type (ctx
, mono_class_enum_basetype_internal (klass
));
616 ltype
= (LLVMTypeRef
)g_hash_table_lookup (ctx
->module
->llvm_types
, klass
);
618 ltype
= create_llvm_type_for_type (ctx
->module
, klass
);
619 g_hash_table_insert (ctx
->module
->llvm_types
, klass
, ltype
);
625 printf ("X: %d\n", t
->type
);
626 ctx
->cfg
->exception_message
= g_strdup_printf ("type %s", mono_type_full_name (t
));
627 ctx
->cfg
->disable_llvm
= TRUE
;
635 * Return whenever T is an unsigned int type.
638 type_is_unsigned (EmitContext
*ctx
, MonoType
*t
)
640 t
= mini_get_underlying_type (t
);
656 * type_to_llvm_arg_type:
658 * Same as type_to_llvm_type, but treat i8/i16 as i32.
661 type_to_llvm_arg_type (EmitContext
*ctx
, MonoType
*t
)
663 LLVMTypeRef ptype
= type_to_llvm_type (ctx
, t
);
665 if (ctx
->cfg
->llvm_only
)
669 * This works on all abis except arm64/ios which passes multiple
670 * arguments in one stack slot.
673 if (ptype
== LLVMInt8Type () || ptype
== LLVMInt16Type ()) {
675 * LLVM generates code which only sets the lower bits, while JITted
676 * code expects all the bits to be set.
678 ptype
= LLVMInt32Type ();
686 * llvm_type_to_stack_type:
688 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
691 static G_GNUC_UNUSED LLVMTypeRef
692 llvm_type_to_stack_type (MonoCompile
*cfg
, LLVMTypeRef type
)
696 if (type
== LLVMInt8Type ())
697 return LLVMInt32Type ();
698 else if (type
== LLVMInt16Type ())
699 return LLVMInt32Type ();
700 else if (!cfg
->r4fp
&& type
== LLVMFloatType ())
701 return LLVMDoubleType ();
707 * regtype_to_llvm_type:
709 * Return the LLVM type corresponding to the regtype C used in instruction
713 regtype_to_llvm_type (char c
)
717 return LLVMInt32Type ();
719 return LLVMInt64Type ();
721 return LLVMDoubleType ();
730 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
733 op_to_llvm_type (int opcode
)
738 return LLVMInt8Type ();
741 return LLVMInt8Type ();
744 return LLVMInt16Type ();
747 return LLVMInt16Type ();
750 return LLVMInt32Type ();
753 return LLVMInt32Type ();
755 return LLVMInt64Type ();
757 return LLVMFloatType ();
759 return LLVMDoubleType ();
761 return LLVMInt64Type ();
763 return LLVMInt32Type ();
765 return LLVMInt64Type ();
770 return LLVMInt8Type ();
775 return LLVMInt16Type ();
777 return LLVMInt32Type ();
780 return TARGET_SIZEOF_VOID_P
== 8 ? LLVMInt64Type () : LLVMInt32Type ();
787 return LLVMInt32Type ();
794 return LLVMInt64Type ();
796 printf ("%s\n", mono_inst_name (opcode
));
797 g_assert_not_reached ();
802 #define CLAUSE_START(clause) ((clause)->try_offset)
803 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
806 * load_store_to_llvm_type:
808 * Return the size/sign/zero extension corresponding to the load/store opcode
812 load_store_to_llvm_type (int opcode
, int *size
, gboolean
*sext
, gboolean
*zext
)
818 case OP_LOADI1_MEMBASE
:
819 case OP_STOREI1_MEMBASE_REG
:
820 case OP_STOREI1_MEMBASE_IMM
:
821 case OP_ATOMIC_LOAD_I1
:
822 case OP_ATOMIC_STORE_I1
:
825 return LLVMInt8Type ();
826 case OP_LOADU1_MEMBASE
:
828 case OP_ATOMIC_LOAD_U1
:
829 case OP_ATOMIC_STORE_U1
:
832 return LLVMInt8Type ();
833 case OP_LOADI2_MEMBASE
:
834 case OP_STOREI2_MEMBASE_REG
:
835 case OP_STOREI2_MEMBASE_IMM
:
836 case OP_ATOMIC_LOAD_I2
:
837 case OP_ATOMIC_STORE_I2
:
840 return LLVMInt16Type ();
841 case OP_LOADU2_MEMBASE
:
843 case OP_ATOMIC_LOAD_U2
:
844 case OP_ATOMIC_STORE_U2
:
847 return LLVMInt16Type ();
848 case OP_LOADI4_MEMBASE
:
849 case OP_LOADU4_MEMBASE
:
852 case OP_STOREI4_MEMBASE_REG
:
853 case OP_STOREI4_MEMBASE_IMM
:
854 case OP_ATOMIC_LOAD_I4
:
855 case OP_ATOMIC_STORE_I4
:
856 case OP_ATOMIC_LOAD_U4
:
857 case OP_ATOMIC_STORE_U4
:
859 return LLVMInt32Type ();
860 case OP_LOADI8_MEMBASE
:
862 case OP_STOREI8_MEMBASE_REG
:
863 case OP_STOREI8_MEMBASE_IMM
:
864 case OP_ATOMIC_LOAD_I8
:
865 case OP_ATOMIC_STORE_I8
:
866 case OP_ATOMIC_LOAD_U8
:
867 case OP_ATOMIC_STORE_U8
:
869 return LLVMInt64Type ();
870 case OP_LOADR4_MEMBASE
:
871 case OP_STORER4_MEMBASE_REG
:
872 case OP_ATOMIC_LOAD_R4
:
873 case OP_ATOMIC_STORE_R4
:
875 return LLVMFloatType ();
876 case OP_LOADR8_MEMBASE
:
877 case OP_STORER8_MEMBASE_REG
:
878 case OP_ATOMIC_LOAD_R8
:
879 case OP_ATOMIC_STORE_R8
:
881 return LLVMDoubleType ();
882 case OP_LOAD_MEMBASE
:
884 case OP_STORE_MEMBASE_REG
:
885 case OP_STORE_MEMBASE_IMM
:
886 *size
= TARGET_SIZEOF_VOID_P
;
887 return IntPtrType ();
889 g_assert_not_reached ();
897 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
900 ovf_op_to_intrins (int opcode
)
904 return "llvm.sadd.with.overflow.i32";
906 return "llvm.uadd.with.overflow.i32";
908 return "llvm.ssub.with.overflow.i32";
910 return "llvm.usub.with.overflow.i32";
912 return "llvm.smul.with.overflow.i32";
914 return "llvm.umul.with.overflow.i32";
916 return "llvm.sadd.with.overflow.i64";
918 return "llvm.uadd.with.overflow.i64";
920 return "llvm.ssub.with.overflow.i64";
922 return "llvm.usub.with.overflow.i64";
924 return "llvm.smul.with.overflow.i64";
926 return "llvm.umul.with.overflow.i64";
928 g_assert_not_reached ();
934 simd_op_to_intrins (int opcode
)
937 #if defined(TARGET_X86) || defined(TARGET_AMD64)
939 return "llvm.x86.sse2.min.pd";
941 return "llvm.x86.sse.min.ps";
943 return "llvm.x86.sse2.max.pd";
945 return "llvm.x86.sse.max.ps";
947 return "llvm.x86.sse3.hadd.pd";
949 return "llvm.x86.sse3.hadd.ps";
951 return "llvm.x86.sse3.hsub.pd";
953 return "llvm.x86.sse3.hsub.ps";
955 return "llvm.x86.sse3.addsub.ps";
957 return "llvm.x86.sse3.addsub.pd";
958 case OP_EXTRACT_MASK
:
959 return "llvm.x86.sse2.pmovmskb.128";
962 return "llvm.x86.sse2.psrli.w";
965 return "llvm.x86.sse2.psrli.d";
968 return "llvm.x86.sse2.psrli.q";
971 return "llvm.x86.sse2.pslli.w";
974 return "llvm.x86.sse2.pslli.d";
977 return "llvm.x86.sse2.pslli.q";
980 return "llvm.x86.sse2.psrai.w";
983 return "llvm.x86.sse2.psrai.d";
985 return "llvm.x86.sse2.padds.b";
987 return "llvm.x86.sse2.padds.w";
989 return "llvm.x86.sse2.psubs.b";
991 return "llvm.x86.sse2.psubs.w";
992 case OP_PADDB_SAT_UN
:
993 return "llvm.x86.sse2.paddus.b";
994 case OP_PADDW_SAT_UN
:
995 return "llvm.x86.sse2.paddus.w";
996 case OP_PSUBB_SAT_UN
:
997 return "llvm.x86.sse2.psubus.b";
998 case OP_PSUBW_SAT_UN
:
999 return "llvm.x86.sse2.psubus.w";
1001 return "llvm.x86.sse2.pavg.b";
1003 return "llvm.x86.sse2.pavg.w";
1005 return "llvm.x86.sse.sqrt.ps";
1007 return "llvm.x86.sse2.sqrt.pd";
1009 return "llvm.x86.sse.rsqrt.ps";
1011 return "llvm.x86.sse.rcp.ps";
1013 return "llvm.x86.sse2.cvtdq2pd";
1015 return "llvm.x86.sse2.cvtdq2ps";
1017 return "llvm.x86.sse2.cvtpd2dq";
1019 return "llvm.x86.sse2.cvtps2dq";
1021 return "llvm.x86.sse2.cvtpd2ps";
1023 return "llvm.x86.sse2.cvtps2pd";
1025 return "llvm.x86.sse2.cvttpd2dq";
1027 return "llvm.x86.sse2.cvttps2dq";
1029 return "llvm.x86.sse2.packsswb.128";
1031 return "llvm.x86.sse2.packssdw.128";
1033 return "llvm.x86.sse2.packuswb.128";
1035 return "llvm.x86.sse41.packusdw";
1037 return "llvm.x86.sse2.pmulh.w";
1038 case OP_PMULW_HIGH_UN
:
1039 return "llvm.x86.sse2.pmulhu.w";
1041 return "llvm.x86.sse41.dpps";
1044 g_assert_not_reached ();
1050 simd_op_to_llvm_type (int opcode
)
1052 #if defined(TARGET_X86) || defined(TARGET_AMD64)
1056 return type_to_simd_type (MONO_TYPE_R8
);
1059 return type_to_simd_type (MONO_TYPE_I8
);
1062 return type_to_simd_type (MONO_TYPE_I4
);
1065 case OP_EXTRACTX_U2
:
1067 return type_to_simd_type (MONO_TYPE_I2
);
1071 return type_to_simd_type (MONO_TYPE_I1
);
1073 return type_to_simd_type (MONO_TYPE_R4
);
1076 return type_to_simd_type (MONO_TYPE_I4
);
1080 return type_to_simd_type (MONO_TYPE_R8
);
1084 return type_to_simd_type (MONO_TYPE_R4
);
1085 case OP_EXTRACT_MASK
:
1086 return type_to_simd_type (MONO_TYPE_I1
);
1092 return type_to_simd_type (MONO_TYPE_R4
);
1095 return type_to_simd_type (MONO_TYPE_R8
);
1097 g_assert_not_reached ();
1106 set_preserveall_cc (LLVMValueRef func
)
1109 * xcode10 (watchOS) and ARM/ARM64 doesn't seem to support preserveall, it fails with:
1110 * fatal error: error in backend: Unsupported calling convention
1112 #if !defined(TARGET_WATCHOS) && !defined(TARGET_ARM) && !defined(TARGET_ARM64)
1113 mono_llvm_set_preserveall_cc (func
);
1118 set_call_preserveall_cc (LLVMValueRef func
)
1120 #if !defined(TARGET_WATCHOS) && !defined(TARGET_ARM) && !defined(TARGET_ARM64)
1121 mono_llvm_set_call_preserveall_cc (func
);
1128 * Return the LLVM basic block corresponding to BB.
1130 static LLVMBasicBlockRef
1131 get_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
1133 char bb_name_buf
[128];
1136 if (ctx
->bblocks
[bb
->block_num
].bblock
== NULL
) {
1137 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
1138 int clause_index
= (mono_get_block_region_notry (ctx
->cfg
, bb
->region
) >> 8) - 1;
1139 sprintf (bb_name_buf
, "EH_CLAUSE%d_BB%d", clause_index
, bb
->block_num
);
1140 bb_name
= bb_name_buf
;
1141 } else if (bb
->block_num
< 256) {
1142 if (!ctx
->module
->bb_names
) {
1143 ctx
->module
->bb_names_len
= 256;
1144 ctx
->module
->bb_names
= g_new0 (char*, ctx
->module
->bb_names_len
);
1146 if (!ctx
->module
->bb_names
[bb
->block_num
]) {
1149 n
= g_strdup_printf ("BB%d", bb
->block_num
);
1150 mono_memory_barrier ();
1151 ctx
->module
->bb_names
[bb
->block_num
] = n
;
1153 bb_name
= ctx
->module
->bb_names
[bb
->block_num
];
1155 sprintf (bb_name_buf
, "BB%d", bb
->block_num
);
1156 bb_name
= bb_name_buf
;
1159 ctx
->bblocks
[bb
->block_num
].bblock
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1160 ctx
->bblocks
[bb
->block_num
].end_bblock
= ctx
->bblocks
[bb
->block_num
].bblock
;
1163 return ctx
->bblocks
[bb
->block_num
].bblock
;
1169 * Return the last LLVM bblock corresponding to BB.
1170 * This might not be equal to the bb returned by get_bb () since we need to generate
1171 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1173 static LLVMBasicBlockRef
1174 get_end_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
1177 return ctx
->bblocks
[bb
->block_num
].end_bblock
;
1180 static LLVMBasicBlockRef
1181 gen_bb (EmitContext
*ctx
, const char *prefix
)
1185 sprintf (bb_name
, "%s%d", prefix
, ++ ctx
->ex_index
);
1186 return LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1192 * Return the target of the patch identified by TYPE and TARGET.
1195 resolve_patch (MonoCompile
*cfg
, MonoJumpInfoType type
, gconstpointer target
)
1201 memset (&ji
, 0, sizeof (ji
));
1203 ji
.data
.target
= target
;
1205 res
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, &ji
, FALSE
, error
);
1206 mono_error_assert_ok (error
);
1214 * Emit code to convert the LLVM value V to DTYPE.
1217 convert_full (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
, gboolean is_unsigned
)
1219 LLVMTypeRef stype
= LLVMTypeOf (v
);
1221 if (stype
!= dtype
) {
1222 gboolean ext
= FALSE
;
1225 if (dtype
== LLVMInt64Type () && (stype
== LLVMInt32Type () || stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
1227 else if (dtype
== LLVMInt32Type () && (stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
1229 else if (dtype
== LLVMInt16Type () && (stype
== LLVMInt8Type ()))
1233 return is_unsigned
? LLVMBuildZExt (ctx
->builder
, v
, dtype
, "") : LLVMBuildSExt (ctx
->builder
, v
, dtype
, "");
1235 if (dtype
== LLVMDoubleType () && stype
== LLVMFloatType ())
1236 return LLVMBuildFPExt (ctx
->builder
, v
, dtype
, "");
1239 if (stype
== LLVMInt64Type () && (dtype
== LLVMInt32Type () || dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
1240 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1241 if (stype
== LLVMInt32Type () && (dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
1242 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1243 if (stype
== LLVMInt16Type () && dtype
== LLVMInt8Type ())
1244 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1245 if (stype
== LLVMDoubleType () && dtype
== LLVMFloatType ())
1246 return LLVMBuildFPTrunc (ctx
->builder
, v
, dtype
, "");
1248 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
1249 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1250 if (LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
1251 return LLVMBuildIntToPtr (ctx
->builder
, v
, dtype
, "");
1252 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
)
1253 return LLVMBuildPtrToInt (ctx
->builder
, v
, dtype
, "");
1255 if (mono_arch_is_soft_float ()) {
1256 if (stype
== LLVMInt32Type () && dtype
== LLVMFloatType ())
1257 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1258 if (stype
== LLVMInt32Type () && dtype
== LLVMDoubleType ())
1259 return LLVMBuildBitCast (ctx
->builder
, LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), ""), dtype
, "");
1262 if (LLVMGetTypeKind (stype
) == LLVMVectorTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMVectorTypeKind
)
1263 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1266 LLVMDumpValue (LLVMConstNull (dtype
));
1267 g_assert_not_reached ();
1275 convert (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
)
1277 return convert_full (ctx
, v
, dtype
, FALSE
);
1281 * emit_volatile_load:
1283 * If vreg is volatile, emit a load from its address.
1286 emit_volatile_load (EmitContext
*ctx
, int vreg
)
1291 // On arm64, we pass the rgctx in a callee saved
1292 // register on arm64 (x15), and llvm might keep the value in that register
1293 // even through the register is marked as 'reserved' inside llvm.
1295 v
= mono_llvm_build_load (ctx
->builder
, ctx
->addresses
[vreg
], "", TRUE
);
1296 t
= ctx
->vreg_cli_types
[vreg
];
1297 if (t
&& !t
->byref
) {
1299 * Might have to zero extend since llvm doesn't have
1302 if (t
->type
== MONO_TYPE_U1
|| t
->type
== MONO_TYPE_U2
|| t
->type
== MONO_TYPE_CHAR
|| t
->type
== MONO_TYPE_BOOLEAN
)
1303 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt32Type (), "");
1304 else if (t
->type
== MONO_TYPE_I1
|| t
->type
== MONO_TYPE_I2
)
1305 v
= LLVMBuildSExt (ctx
->builder
, v
, LLVMInt32Type (), "");
1306 else if (t
->type
== MONO_TYPE_U8
)
1307 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), "");
1314 * emit_volatile_store:
1316 * If VREG is volatile, emit a store from its value to its address.
1319 emit_volatile_store (EmitContext
*ctx
, int vreg
)
1321 MonoInst
*var
= get_vreg_to_inst (ctx
->cfg
, vreg
);
1323 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1324 g_assert (ctx
->addresses
[vreg
]);
1325 LLVMBuildStore (ctx
->builder
, convert (ctx
, ctx
->values
[vreg
], type_to_llvm_type (ctx
, var
->inst_vtype
)), ctx
->addresses
[vreg
]);
1330 sig_to_llvm_sig_no_cinfo (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1332 LLVMTypeRef ret_type
;
1333 LLVMTypeRef
*param_types
= NULL
;
1338 ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
1341 rtype
= mini_get_underlying_type (sig
->ret
);
1343 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 8) + 3);
1347 param_types
[pindex
++] = ThisType ();
1348 for (i
= 0; i
< sig
->param_count
; ++i
)
1349 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1351 if (!ctx_ok (ctx
)) {
1352 g_free (param_types
);
1356 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1357 g_free (param_types
);
1363 * sig_to_llvm_sig_full:
1365 * Return the LLVM signature corresponding to the mono signature SIG using the
1366 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1369 sig_to_llvm_sig_full (EmitContext
*ctx
, MonoMethodSignature
*sig
, LLVMCallInfo
*cinfo
)
1371 LLVMTypeRef ret_type
;
1372 LLVMTypeRef
*param_types
= NULL
;
1374 int i
, j
, pindex
, vret_arg_pindex
= 0;
1375 gboolean vretaddr
= FALSE
;
1379 return sig_to_llvm_sig_no_cinfo (ctx
, sig
);
1381 ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
1384 rtype
= mini_get_underlying_type (sig
->ret
);
1386 switch (cinfo
->ret
.storage
) {
1387 case LLVMArgVtypeInReg
:
1388 /* LLVM models this by returning an aggregate value */
1389 if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1390 LLVMTypeRef members
[2];
1392 members
[0] = IntPtrType ();
1393 ret_type
= LLVMStructType (members
, 1, FALSE
);
1394 } else if (cinfo
->ret
.pair_storage
[0] == LLVMArgNone
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1396 ret_type
= LLVMVoidType ();
1397 } else if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgInIReg
) {
1398 LLVMTypeRef members
[2];
1400 members
[0] = IntPtrType ();
1401 members
[1] = IntPtrType ();
1402 ret_type
= LLVMStructType (members
, 2, FALSE
);
1404 g_assert_not_reached ();
1407 case LLVMArgVtypeByVal
:
1408 /* Vtype returned normally by val */
1410 case LLVMArgVtypeAsScalar
: {
1411 int size
= mono_class_value_size (mono_class_from_mono_type_internal (rtype
), NULL
);
1412 /* LLVM models this by returning an int */
1413 if (size
< TARGET_SIZEOF_VOID_P
) {
1414 g_assert (cinfo
->ret
.nslots
== 1);
1415 ret_type
= LLVMIntType (size
* 8);
1417 g_assert (cinfo
->ret
.nslots
== 1 || cinfo
->ret
.nslots
== 2);
1418 ret_type
= LLVMIntType (cinfo
->ret
.nslots
* sizeof (target_mgreg_t
) * 8);
1422 case LLVMArgAsIArgs
:
1423 ret_type
= LLVMArrayType (IntPtrType (), cinfo
->ret
.nslots
);
1425 case LLVMArgFpStruct
: {
1426 /* Vtype returned as a fp struct */
1427 LLVMTypeRef members
[16];
1429 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1430 for (i
= 0; i
< cinfo
->ret
.nslots
; ++i
)
1431 members
[i
] = cinfo
->ret
.esize
== 8 ? LLVMDoubleType () : LLVMFloatType ();
1432 ret_type
= LLVMStructType (members
, cinfo
->ret
.nslots
, FALSE
);
1435 case LLVMArgVtypeByRef
:
1436 /* Vtype returned using a hidden argument */
1437 ret_type
= LLVMVoidType ();
1439 case LLVMArgVtypeRetAddr
:
1440 case LLVMArgGsharedvtFixed
:
1441 case LLVMArgGsharedvtFixedVtype
:
1442 case LLVMArgGsharedvtVariable
:
1444 ret_type
= LLVMVoidType ();
1450 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 8) + 3);
1452 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
) {
1454 * Has to be the first argument because of the sret argument attribute
1455 * FIXME: This might conflict with passing 'this' as the first argument, but
1456 * this is only used on arm64 which has a dedicated struct return register.
1458 cinfo
->vret_arg_pindex
= pindex
;
1459 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, sig
->ret
);
1460 if (!ctx_ok (ctx
)) {
1461 g_free (param_types
);
1464 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1467 if (!ctx
->llvm_only
&& cinfo
->rgctx_arg
) {
1468 cinfo
->rgctx_arg_pindex
= pindex
;
1469 param_types
[pindex
] = ctx
->module
->ptr_type
;
1472 if (cinfo
->imt_arg
) {
1473 cinfo
->imt_arg_pindex
= pindex
;
1474 param_types
[pindex
] = ctx
->module
->ptr_type
;
1478 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1479 vret_arg_pindex
= pindex
;
1480 if (cinfo
->vret_arg_index
== 1) {
1481 /* Add the slots consumed by the first argument */
1482 LLVMArgInfo
*ainfo
= &cinfo
->args
[0];
1483 switch (ainfo
->storage
) {
1484 case LLVMArgVtypeInReg
:
1485 for (j
= 0; j
< 2; ++j
) {
1486 if (ainfo
->pair_storage
[j
] == LLVMArgInIReg
)
1495 cinfo
->vret_arg_pindex
= vret_arg_pindex
;
1498 if (vretaddr
&& vret_arg_pindex
== pindex
)
1499 param_types
[pindex
++] = IntPtrType ();
1501 cinfo
->this_arg_pindex
= pindex
;
1502 param_types
[pindex
++] = ThisType ();
1503 cinfo
->args
[0].pindex
= cinfo
->this_arg_pindex
;
1505 if (vretaddr
&& vret_arg_pindex
== pindex
)
1506 param_types
[pindex
++] = IntPtrType ();
1507 for (i
= 0; i
< sig
->param_count
; ++i
) {
1508 LLVMArgInfo
*ainfo
= &cinfo
->args
[i
+ sig
->hasthis
];
1510 if (vretaddr
&& vret_arg_pindex
== pindex
)
1511 param_types
[pindex
++] = IntPtrType ();
1512 ainfo
->pindex
= pindex
;
1514 switch (ainfo
->storage
) {
1515 case LLVMArgVtypeInReg
:
1516 for (j
= 0; j
< 2; ++j
) {
1517 switch (ainfo
->pair_storage
[j
]) {
1519 param_types
[pindex
++] = LLVMIntType (TARGET_SIZEOF_VOID_P
* 8);
1524 g_assert_not_reached ();
1528 case LLVMArgVtypeByVal
:
1529 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1532 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1535 case LLVMArgAsIArgs
:
1536 if (ainfo
->esize
== 8)
1537 param_types
[pindex
] = LLVMArrayType (LLVMInt64Type (), ainfo
->nslots
);
1539 param_types
[pindex
] = LLVMArrayType (IntPtrType (), ainfo
->nslots
);
1542 case LLVMArgVtypeByRef
:
1543 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1546 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1549 case LLVMArgAsFpArgs
: {
1552 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1553 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
1554 param_types
[pindex
++] = LLVMDoubleType ();
1555 for (j
= 0; j
< ainfo
->nslots
; ++j
)
1556 param_types
[pindex
++] = ainfo
->esize
== 8 ? LLVMDoubleType () : LLVMFloatType ();
1559 case LLVMArgVtypeAsScalar
:
1560 g_assert_not_reached ();
1562 case LLVMArgGsharedvtFixed
:
1563 case LLVMArgGsharedvtFixedVtype
:
1564 param_types
[pindex
++] = LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0);
1566 case LLVMArgGsharedvtVariable
:
1567 param_types
[pindex
++] = LLVMPointerType (IntPtrType (), 0);
1570 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1574 if (!ctx_ok (ctx
)) {
1575 g_free (param_types
);
1578 if (vretaddr
&& vret_arg_pindex
== pindex
)
1579 param_types
[pindex
++] = IntPtrType ();
1580 if (ctx
->llvm_only
&& cinfo
->rgctx_arg
) {
1581 /* Pass the rgctx as the last argument */
1582 cinfo
->rgctx_arg_pindex
= pindex
;
1583 param_types
[pindex
] = ctx
->module
->ptr_type
;
1585 } else if (ctx
->llvm_only
&& cinfo
->dummy_arg
) {
1586 /* Pass a dummy arg last */
1587 cinfo
->dummy_arg_pindex
= pindex
;
1588 param_types
[pindex
] = ctx
->module
->ptr_type
;
1592 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1593 g_free (param_types
);
1599 sig_to_llvm_sig (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1601 return sig_to_llvm_sig_full (ctx
, sig
, NULL
);
1605 * LLVMFunctionType1:
1607 * Create an LLVM function type from the arguments.
1609 static G_GNUC_UNUSED LLVMTypeRef
1610 LLVMFunctionType0 (LLVMTypeRef ReturnType
,
1613 return LLVMFunctionType (ReturnType
, NULL
, 0, IsVarArg
);
1617 * LLVMFunctionType1:
1619 * Create an LLVM function type from the arguments.
1621 static G_GNUC_UNUSED LLVMTypeRef
1622 LLVMFunctionType1 (LLVMTypeRef ReturnType
,
1623 LLVMTypeRef ParamType1
,
1626 LLVMTypeRef param_types
[1];
1628 param_types
[0] = ParamType1
;
1630 return LLVMFunctionType (ReturnType
, param_types
, 1, IsVarArg
);
1634 * LLVMFunctionType2:
1636 * Create an LLVM function type from the arguments.
1638 static G_GNUC_UNUSED LLVMTypeRef
1639 LLVMFunctionType2 (LLVMTypeRef ReturnType
,
1640 LLVMTypeRef ParamType1
,
1641 LLVMTypeRef ParamType2
,
1644 LLVMTypeRef param_types
[2];
1646 param_types
[0] = ParamType1
;
1647 param_types
[1] = ParamType2
;
1649 return LLVMFunctionType (ReturnType
, param_types
, 2, IsVarArg
);
1653 * LLVMFunctionType3:
1655 * Create an LLVM function type from the arguments.
1657 static G_GNUC_UNUSED LLVMTypeRef
1658 LLVMFunctionType3 (LLVMTypeRef ReturnType
,
1659 LLVMTypeRef ParamType1
,
1660 LLVMTypeRef ParamType2
,
1661 LLVMTypeRef ParamType3
,
1664 LLVMTypeRef param_types
[3];
1666 param_types
[0] = ParamType1
;
1667 param_types
[1] = ParamType2
;
1668 param_types
[2] = ParamType3
;
1670 return LLVMFunctionType (ReturnType
, param_types
, 3, IsVarArg
);
1673 static G_GNUC_UNUSED LLVMTypeRef
1674 LLVMFunctionType5 (LLVMTypeRef ReturnType
,
1675 LLVMTypeRef ParamType1
,
1676 LLVMTypeRef ParamType2
,
1677 LLVMTypeRef ParamType3
,
1678 LLVMTypeRef ParamType4
,
1679 LLVMTypeRef ParamType5
,
1682 LLVMTypeRef param_types
[5];
1684 param_types
[0] = ParamType1
;
1685 param_types
[1] = ParamType2
;
1686 param_types
[2] = ParamType3
;
1687 param_types
[3] = ParamType4
;
1688 param_types
[4] = ParamType5
;
1690 return LLVMFunctionType (ReturnType
, param_types
, 5, IsVarArg
);
1696 * Create an LLVM builder and remember it so it can be freed later.
1698 static LLVMBuilderRef
1699 create_builder (EmitContext
*ctx
)
1701 LLVMBuilderRef builder
= LLVMCreateBuilder ();
1703 ctx
->builders
= g_slist_prepend_mempool (ctx
->cfg
->mempool
, ctx
->builders
, builder
);
1705 emit_default_dbg_loc (ctx
, builder
);
1711 get_aotconst_name (MonoJumpInfoType type
, gconstpointer data
, int got_offset
)
1716 case MONO_PATCH_INFO_JIT_ICALL
:
1717 name
= g_strdup_printf ("jit_icall_%s", data
);
1719 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX
: {
1720 MonoJumpInfoRgctxEntry
*entry
= (MonoJumpInfoRgctxEntry
*)data
;
1721 name
= g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry
->info_type
));
1725 name
= g_strdup_printf ("%s_%d", mono_ji_type_to_string (type
), got_offset
);
1733 compute_aot_got_offset (MonoLLVMModule
*module
, MonoJumpInfo
*ji
, LLVMTypeRef llvm_type
)
1735 guint32 got_offset
= mono_aot_get_got_offset (ji
);
1737 LLVMTypeRef lookup_type
= (LLVMTypeRef
) g_hash_table_lookup (module
->got_idx_to_type
, GINT_TO_POINTER (got_offset
));
1740 lookup_type
= llvm_type
;
1741 } else if (llvm_type
!= lookup_type
) {
1742 lookup_type
= module
->ptr_type
;
1747 g_hash_table_insert (module
->got_idx_to_type
, GINT_TO_POINTER (got_offset
), lookup_type
);
1752 get_aotconst_typed (EmitContext
*ctx
, MonoJumpInfoType type
, gconstpointer data
, LLVMTypeRef llvm_type
)
1756 LLVMValueRef indexes
[2];
1757 LLVMValueRef got_entry_addr
, load
;
1758 LLVMBuilderRef builder
= ctx
->builder
;
1763 MonoJumpInfo tmp_ji
;
1765 tmp_ji
.data
.target
= data
;
1767 MonoJumpInfo
*ji
= mono_aot_patch_info_dup (&tmp_ji
);
1769 ji
->next
= cfg
->patch_info
;
1770 cfg
->patch_info
= ji
;
1772 got_offset
= compute_aot_got_offset (ctx
->module
, cfg
->patch_info
, llvm_type
);
1773 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
1775 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1776 * explicitly initialize it.
1778 if (!mono_aot_is_shared_got_offset (got_offset
)) {
1779 //mono_print_ji (ji);
1781 ctx
->cfg
->got_access_count
++;
1784 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1785 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
1786 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
1788 name
= get_aotconst_name (type
, data
, got_offset
);
1790 load
= LLVMBuildLoad (builder
, got_entry_addr
, "");
1791 load
= convert (ctx
, load
, llvm_type
);
1792 LLVMSetValueName (load
, name
? name
: "");
1794 load
= LLVMBuildLoad (builder
, got_entry_addr
, name
? name
: "");
1797 //set_invariant_load_flag (load);
1803 get_aotconst (EmitContext
*ctx
, MonoJumpInfoType type
, gconstpointer data
)
1805 return get_aotconst_typed (ctx
, type
, data
, NULL
);
1816 method_is_direct_callable (MonoMethod
*method
)
1818 if (method
->wrapper_type
== MONO_WRAPPER_ALLOC
)
1820 if (method
->string_ctor
)
1822 if (method
->wrapper_type
)
1824 if ((method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) || (method
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
))
1826 /* Can't enable this as the callee might fail llvm compilation */
1828 if (!method->is_inflated && (mono_class_get_flags (method->klass) & TYPE_ATTRIBUTE_PUBLIC) && (method->flags & METHOD_ATTRIBUTE_PUBLIC))
1835 get_callee_llvmonly (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1837 LLVMValueRef callee
;
1838 char *callee_name
= NULL
;
1840 if (ctx
->module
->static_link
&& ctx
->module
->assembly
->image
!= mono_get_corlib ()) {
1841 if (type
== MONO_PATCH_INFO_JIT_ICALL
) {
1842 MonoJitICallInfo
*info
= mono_find_jit_icall_by_name ((const char*)data
);
1845 if (info
->func
!= info
->wrapper
) {
1846 type
= MONO_PATCH_INFO_METHOD
;
1847 data
= mono_icall_get_wrapper_method (info
);
1848 callee_name
= mono_aot_get_mangled_method_name ((MonoMethod
*)data
);
1850 } else if (type
== MONO_PATCH_INFO_METHOD
) {
1851 MonoMethod
*method
= (MonoMethod
*)data
;
1852 if (m_class_get_image (method
->klass
) != ctx
->module
->assembly
->image
&& method_is_direct_callable (method
))
1853 callee_name
= mono_aot_get_mangled_method_name (method
);
1858 callee_name
= mono_aot_get_direct_call_symbol (type
, data
);
1860 /* Directly callable */
1862 callee
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->direct_callables
, callee_name
);
1864 callee
= LLVMAddFunction (ctx
->lmodule
, callee_name
, llvm_sig
);
1866 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1868 g_hash_table_insert (ctx
->module
->direct_callables
, (char*)callee_name
, callee
);
1870 /* LLVMTypeRef's are uniqued */
1871 if (LLVMGetElementType (LLVMTypeOf (callee
)) != llvm_sig
)
1872 return LLVMConstBitCast (callee
, LLVMPointerType (llvm_sig
, 0));
1874 g_free (callee_name
);
1880 * Change references to jit icalls to the icall wrappers when in corlib, so
1881 * they can be called directly.
1883 if (ctx
->module
->assembly
->image
== mono_get_corlib () && type
== MONO_PATCH_INFO_JIT_ICALL
) {
1884 MonoJitICallInfo
*info
= mono_find_jit_icall_by_name ((const char*)data
);
1887 if (info
->func
!= info
->wrapper
) {
1888 type
= MONO_PATCH_INFO_METHOD
;
1889 data
= mono_icall_get_wrapper_method (info
);
1894 * Instead of emitting an indirect call through a got slot, emit a placeholder, and
1895 * replace it with a direct call or an indirect call in mono_llvm_fixup_aot_module ()
1896 * after all methods have been emitted.
1898 if (type
== MONO_PATCH_INFO_METHOD
) {
1899 MonoMethod
*method
= (MonoMethod
*)data
;
1900 if (m_class_get_image (method
->klass
)->assembly
== ctx
->module
->assembly
) {
1901 MonoJumpInfo tmp_ji
;
1903 tmp_ji
.data
.target
= data
;
1905 MonoJumpInfo
*ji
= mono_aot_patch_info_dup (&tmp_ji
);
1906 ji
->next
= ctx
->cfg
->patch_info
;
1907 ctx
->cfg
->patch_info
= ji
;
1908 LLVMTypeRef llvm_type
= LLVMPointerType (llvm_sig
, 0);
1910 ctx
->cfg
->got_access_count
++;
1912 CallSite
*info
= g_new0 (CallSite
, 1);
1913 info
->method
= method
;
1915 info
->type
= llvm_type
;
1918 * Emit a dummy load to represent the callee, and either replace it with
1919 * a reference to the llvm method for the callee, or from a load from the
1922 LLVMValueRef indexes
[2];
1923 LLVMValueRef got_entry_addr
, load
;
1925 LLVMBuilderRef builder
= ctx
->builder
;
1926 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1927 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1928 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
1930 load
= LLVMBuildLoad (builder
, got_entry_addr
, "");
1931 load
= convert (ctx
, load
, llvm_type
);
1934 g_ptr_array_add (ctx
->callsite_list
, info
);
1941 * Calls are made through the GOT.
1943 callee
= get_aotconst_typed (ctx
, type
, data
, LLVMPointerType (llvm_sig
, 0));
1951 * Return an llvm value representing the callee given by the arguments.
1954 get_callee (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1956 LLVMValueRef callee
;
1958 MonoJumpInfo
*ji
= NULL
;
1961 return get_callee_llvmonly (ctx
, llvm_sig
, type
, data
);
1963 callee_name
= mono_aot_get_plt_symbol (type
, data
);
1967 if (ctx
->cfg
->compile_aot
)
1968 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1969 mono_add_patch_info (ctx
->cfg
, 0, type
, data
);
1972 callee
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->plt_entries
, callee_name
);
1974 callee
= LLVMAddFunction (ctx
->lmodule
, callee_name
, llvm_sig
);
1976 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1978 g_hash_table_insert (ctx
->module
->plt_entries
, (char*)callee_name
, callee
);
1981 if (ctx
->cfg
->compile_aot
) {
1982 ji
= g_new0 (MonoJumpInfo
, 1);
1984 ji
->data
.target
= data
;
1986 g_hash_table_insert (ctx
->module
->plt_entries_ji
, ji
, callee
);
1993 emit_jit_callee (EmitContext
*ctx
, const char *name
, LLVMTypeRef llvm_sig
, gpointer target
)
1995 #if LLVM_API_VERSION > 100
1996 LLVMValueRef tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
1997 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
1998 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
1999 LLVMValueRef callee
= LLVMBuildLoad (ctx
->builder
, tramp_var
, "");
2002 g_assert_not_reached ();
2008 get_handler_clause (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
2010 MonoMethodHeader
*header
= cfg
->header
;
2011 MonoExceptionClause
*clause
;
2015 if (bb
->region
!= -1 && MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))
2016 return (bb
->region
>> 8) - 1;
2019 for (i
= 0; i
< header
->num_clauses
; ++i
) {
2020 clause
= &header
->clauses
[i
];
2022 if (MONO_OFFSET_IN_CLAUSE (clause
, bb
->real_offset
) && clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
)
2029 static MonoExceptionClause
*
2030 get_most_deep_clause (MonoCompile
*cfg
, EmitContext
*ctx
, MonoBasicBlock
*bb
)
2032 if (bb
== cfg
->bb_init
)
2034 // Since they're sorted by nesting we just need
2035 // the first one that the bb is a member of
2036 for (int i
= 0; i
< cfg
->header
->num_clauses
; i
++) {
2037 MonoExceptionClause
*curr
= &cfg
->header
->clauses
[i
];
2039 if (MONO_OFFSET_IN_CLAUSE (curr
, bb
->real_offset
))
2047 set_metadata_flag (LLVMValueRef v
, const char *flag_name
)
2049 LLVMValueRef md_arg
;
2052 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
2053 md_arg
= LLVMMDString ("mono", 4);
2054 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
2058 set_invariant_load_flag (LLVMValueRef v
)
2060 LLVMValueRef md_arg
;
2062 const char *flag_name
;
2064 // FIXME: Cache this
2065 flag_name
= "invariant.load";
2066 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
2067 md_arg
= LLVMMDString ("<index>", strlen ("<index>"));
2068 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
2074 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
2078 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
2080 MonoCompile
*cfg
= ctx
->cfg
;
2081 LLVMValueRef lcall
= NULL
;
2082 LLVMBuilderRef builder
= *builder_ref
;
2083 MonoExceptionClause
*clause
;
2085 if (ctx
->llvm_only
) {
2086 clause
= get_most_deep_clause (cfg
, ctx
, bb
);
2089 g_assert (clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| clause
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
|| clause
->flags
== MONO_EXCEPTION_CLAUSE_FAULT
);
2092 * Have to use an invoke instead of a call, branching to the
2093 * handler bblock of the clause containing this bblock.
2095 intptr_t key
= CLAUSE_END(clause
);
2097 LLVMBasicBlockRef lpad_bb
= (LLVMBasicBlockRef
)g_hash_table_lookup (ctx
->exc_meta
, (gconstpointer
)key
);
2099 // FIXME: Find the one that has the lowest end bound for the right start address
2100 // FIXME: Finally + nesting
2103 LLVMBasicBlockRef noex_bb
= gen_bb (ctx
, "CALL_NOEX_BB");
2106 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, lpad_bb
, "");
2108 builder
= ctx
->builder
= create_builder (ctx
);
2109 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2111 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2115 int clause_index
= get_handler_clause (cfg
, bb
);
2117 if (clause_index
!= -1) {
2118 MonoMethodHeader
*header
= cfg
->header
;
2119 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
2120 MonoBasicBlock
*tblock
;
2121 LLVMBasicBlockRef ex_bb
, noex_bb
;
2124 * Have to use an invoke instead of a call, branching to the
2125 * handler bblock of the clause containing this bblock.
2128 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FAULT
);
2130 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
2133 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
2135 ex_bb
= get_bb (ctx
, tblock
);
2137 noex_bb
= gen_bb (ctx
, "NOEX_BB");
2140 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
2142 builder
= ctx
->builder
= create_builder (ctx
);
2143 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2145 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2150 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
2151 ctx
->builder
= builder
;
2155 *builder_ref
= ctx
->builder
;
2161 emit_load_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, LLVMValueRef base
, const char *name
, gboolean is_faulting
, BarrierKind barrier
)
2163 const char *intrins_name
;
2164 LLVMValueRef args
[16], res
;
2165 LLVMTypeRef addr_type
;
2166 gboolean use_intrinsics
= TRUE
;
2168 #if LLVM_API_VERSION > 100
2169 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
2170 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2173 cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
2174 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
2175 *builder_ref
= ctx
->builder
;
2176 use_intrinsics
= FALSE
;
2180 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
2181 LLVMAtomicOrdering ordering
;
2184 case LLVM_BARRIER_NONE
:
2185 ordering
= LLVMAtomicOrderingNotAtomic
;
2187 case LLVM_BARRIER_ACQ
:
2188 ordering
= LLVMAtomicOrderingAcquire
;
2190 case LLVM_BARRIER_SEQ
:
2191 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
2194 g_assert_not_reached ();
2199 * We handle loads which can fault by calling a mono specific intrinsic
2200 * using an invoke, so they are handled properly inside try blocks.
2201 * We can't use this outside clauses, since LLVM optimizes intrinsics which
2202 * are marked with IntrReadArgMem.
2206 intrins_name
= "llvm.mono.load.i8.p0i8";
2209 intrins_name
= "llvm.mono.load.i16.p0i16";
2212 intrins_name
= "llvm.mono.load.i32.p0i32";
2215 intrins_name
= "llvm.mono.load.i64.p0i64";
2218 g_assert_not_reached ();
2221 addr_type
= LLVMTypeOf (addr
);
2222 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0) || addr_type
== LLVMPointerType (LLVMFloatType (), 0))
2223 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
2226 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2227 args
[2] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
2228 args
[3] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
2229 res
= emit_call (ctx
, bb
, builder_ref
, get_intrins_by_name (ctx
, intrins_name
), args
, 4);
2231 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0))
2232 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMDoubleType (), "");
2233 else if (addr_type
== LLVMPointerType (LLVMFloatType (), 0))
2234 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMFloatType (), "");
2241 * We emit volatile loads for loads which can fault, because otherwise
2242 * LLVM will generate invalid code when encountering a load from a
2245 if (barrier
!= LLVM_BARRIER_NONE
)
2246 res
= mono_llvm_build_atomic_load (*builder_ref
, addr
, name
, is_faulting
, size
, barrier
);
2248 res
= mono_llvm_build_load (*builder_ref
, addr
, name
, is_faulting
);
2250 /* Mark it with a custom metadata */
2253 set_metadata_flag (res, "mono.faulting.load");
2261 emit_load (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, const char *name
, gboolean is_faulting
)
2263 return emit_load_general (ctx
, bb
, builder_ref
, size
, addr
, addr
, name
, is_faulting
, LLVM_BARRIER_NONE
);
2267 emit_store_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
, BarrierKind barrier
)
2269 const char *intrins_name
;
2270 LLVMValueRef args
[16];
2271 gboolean use_intrinsics
= TRUE
;
2273 #if LLVM_API_VERSION > 100
2274 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
2275 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2276 LLVMValueRef cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
2277 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
2278 *builder_ref
= ctx
->builder
;
2279 use_intrinsics
= FALSE
;
2283 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
2284 LLVMAtomicOrdering ordering
;
2287 case LLVM_BARRIER_NONE
:
2288 ordering
= LLVMAtomicOrderingNotAtomic
;
2290 case LLVM_BARRIER_REL
:
2291 ordering
= LLVMAtomicOrderingRelease
;
2293 case LLVM_BARRIER_SEQ
:
2294 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
2297 g_assert_not_reached ();
2303 intrins_name
= "llvm.mono.store.i8.p0i8";
2306 intrins_name
= "llvm.mono.store.i16.p0i16";
2309 intrins_name
= "llvm.mono.store.i32.p0i32";
2312 intrins_name
= "llvm.mono.store.i64.p0i64";
2315 g_assert_not_reached ();
2318 if (LLVMTypeOf (value
) == LLVMDoubleType () || LLVMTypeOf (value
) == LLVMFloatType ()) {
2319 value
= LLVMBuildBitCast (*builder_ref
, value
, LLVMIntType (size
* 8), "");
2320 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
2325 args
[2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2326 args
[3] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
2327 args
[4] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
2328 emit_call (ctx
, bb
, builder_ref
, get_intrins_by_name (ctx
, intrins_name
), args
, 5);
2330 if (barrier
!= LLVM_BARRIER_NONE
)
2331 mono_llvm_build_aligned_store (*builder_ref
, value
, addr
, barrier
, size
);
2333 mono_llvm_build_store (*builder_ref
, value
, addr
, is_faulting
, barrier
);
2338 emit_store (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
)
2340 emit_store_general (ctx
, bb
, builder_ref
, size
, value
, addr
, base
, is_faulting
, LLVM_BARRIER_NONE
);
2344 * emit_cond_system_exception:
2346 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2347 * Might set the ctx exception.
2350 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
2352 LLVMBasicBlockRef ex_bb
, ex2_bb
= NULL
, noex_bb
;
2353 LLVMBuilderRef builder
;
2354 MonoClass
*exc_class
;
2355 LLVMValueRef args
[2];
2356 LLVMValueRef callee
;
2357 gboolean no_pc
= FALSE
;
2358 static MonoClass
*exc_classes
[MONO_EXC_INTRINS_NUM
];
2360 if (IS_TARGET_AMD64
)
2361 /* Some platforms don't require the pc argument */
2364 int exc_id
= mini_exception_id_by_name (exc_type
);
2365 if (!exc_classes
[exc_id
])
2366 exc_classes
[exc_id
] = mono_class_load_from_name (mono_get_corlib (), "System", exc_type
);
2367 exc_class
= exc_classes
[exc_id
];
2369 ex_bb
= gen_bb (ctx
, "EX_BB");
2371 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2372 noex_bb
= gen_bb (ctx
, "NOEX_BB");
2374 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
2376 /* Emit exception throwing code */
2377 ctx
->builder
= builder
= create_builder (ctx
);
2378 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
2380 if (ctx
->cfg
->llvm_only
) {
2381 LLVMBuildBr (builder
, ex2_bb
);
2383 ctx
->builder
= builder
= create_builder (ctx
);
2384 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2386 if (exc_id
== MONO_EXC_NULL_REF
) {
2387 static LLVMTypeRef sig
;
2390 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
2391 /* Can't cache this */
2392 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, "mini_llvmonly_throw_nullref_exception");
2393 emit_call (ctx
, bb
, &builder
, callee
, NULL
, 0);
2395 static LLVMTypeRef sig
;
2398 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2399 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, "mono_llvm_throw_corlib_exception");
2400 args
[0] = LLVMConstInt (LLVMInt32Type (), m_class_get_type_token (exc_class
) - MONO_TOKEN_TYPE_DEF
, FALSE
);
2401 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2404 LLVMBuildUnreachable (builder
);
2406 ctx
->builder
= builder
= create_builder (ctx
);
2407 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2409 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2415 callee
= ctx
->module
->throw_corlib_exception
;
2418 const char *icall_name
;
2421 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2423 sig
= LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE
);
2424 icall_name
= "llvm_throw_corlib_exception_abs_trampoline";
2426 if (ctx
->cfg
->compile_aot
) {
2427 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
2430 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2431 * - On x86, LLVM generated code doesn't push the arguments
2432 * - The trampoline takes the throw address as an arguments, not a pc offset.
2434 gpointer target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
2435 callee
= emit_jit_callee (ctx
, "llvm_throw_corlib_exception_trampoline", sig
, target
);
2437 #if LLVM_API_VERSION > 100
2439 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2440 * added by emit_jit_callee ().
2442 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2443 LLVMBuildBr (builder
, ex2_bb
);
2446 ctx
->builder
= builder
= create_builder (ctx
);
2447 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2449 mono_memory_barrier ();
2450 ctx
->module
->throw_corlib_exception
= callee
;
2455 args
[0] = LLVMConstInt (LLVMInt32Type (), m_class_get_type_token (exc_class
) - MONO_TOKEN_TYPE_DEF
, FALSE
);
2458 * The LLVM mono branch contains changes so a block address can be passed as an
2459 * argument to a call.
2462 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2464 args
[1] = LLVMBlockAddress (ctx
->lmethod
, ex_bb
);
2465 emit_call (ctx
, bb
, &builder
, callee
, args
, 2);
2468 LLVMBuildUnreachable (builder
);
2470 ctx
->builder
= builder
= create_builder (ctx
);
2471 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2473 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2480 * emit_args_to_vtype:
2482 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2485 emit_args_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
)
2487 int j
, size
, nslots
;
2490 t
= mini_get_underlying_type (t
);
2491 klass
= mono_class_from_mono_type_internal (t
);
2492 size
= mono_class_value_size (klass
, NULL
);
2494 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
2495 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2497 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2498 nslots
= ainfo
->nslots
;
2502 for (j
= 0; j
< nslots
; ++j
) {
2503 LLVMValueRef index
[2], addr
, daddr
;
2504 int part_size
= size
> TARGET_SIZEOF_VOID_P
? TARGET_SIZEOF_VOID_P
: size
;
2505 LLVMTypeRef part_type
;
2507 while (part_size
!= 1 && part_size
!= 2 && part_size
!= 4 && part_size
< 8)
2510 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2513 switch (ainfo
->pair_storage
[j
]) {
2514 case LLVMArgInIReg
: {
2515 part_type
= LLVMIntType (part_size
* 8);
2516 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
)) {
2517 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* TARGET_SIZEOF_VOID_P
, FALSE
);
2518 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2520 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2521 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2522 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2524 LLVMBuildStore (builder
, convert (ctx
, args
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
2527 case LLVMArgInFPReg
: {
2528 LLVMTypeRef arg_type
;
2530 if (ainfo
->esize
== 8)
2531 arg_type
= LLVMDoubleType ();
2533 arg_type
= LLVMFloatType ();
2535 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2536 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2537 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2538 LLVMBuildStore (builder
, args
[j
], addr
);
2544 g_assert_not_reached ();
2547 size
-= TARGET_SIZEOF_VOID_P
;
2552 * emit_vtype_to_args:
2554 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2555 * into ARGS, and the number of arguments into NARGS.
2558 emit_vtype_to_args (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
, guint32
*nargs
)
2561 int j
, size
, nslots
;
2562 LLVMTypeRef arg_type
;
2564 t
= mini_get_underlying_type (t
);
2565 size
= get_vtype_size (t
);
2567 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (t
)))
2568 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2570 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2571 nslots
= ainfo
->nslots
;
2574 for (j
= 0; j
< nslots
; ++j
) {
2575 LLVMValueRef index
[2], addr
, daddr
;
2576 int partsize
= size
> TARGET_SIZEOF_VOID_P
? TARGET_SIZEOF_VOID_P
: size
;
2578 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2581 switch (ainfo
->pair_storage
[j
]) {
2583 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (t
))) {
2584 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* TARGET_SIZEOF_VOID_P
, FALSE
);
2585 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2587 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2588 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2589 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2591 args
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
2593 case LLVMArgInFPReg
:
2594 if (ainfo
->esize
== 8)
2595 arg_type
= LLVMDoubleType ();
2597 arg_type
= LLVMFloatType ();
2598 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2599 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2600 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2601 args
[pindex
++] = LLVMBuildLoad (builder
, addr
, "");
2606 g_assert_not_reached ();
2608 size
-= TARGET_SIZEOF_VOID_P
;
2615 build_alloca_llvm_type_name (EmitContext
*ctx
, LLVMTypeRef t
, int align
, const char *name
)
2618 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2619 * get executed every time control reaches them.
2621 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
2623 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, t
, NULL
, align
, name
);
2624 return ctx
->last_alloca
;
2628 build_alloca_llvm_type (EmitContext
*ctx
, LLVMTypeRef t
, int align
)
2630 return build_alloca_llvm_type_name (ctx
, t
, align
, "");
2634 build_alloca (EmitContext
*ctx
, MonoType
*t
)
2636 MonoClass
*k
= mono_class_from_mono_type_internal (t
);
2639 g_assert (!mini_is_gsharedvt_variable_type (t
));
2641 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
2644 align
= mono_class_min_align (k
);
2646 /* Sometimes align is not a power of 2 */
2647 while (mono_is_power_of_two (align
) == -1)
2650 return build_alloca_llvm_type (ctx
, type_to_llvm_type (ctx
, t
), align
);
2654 emit_gsharedvt_ldaddr (EmitContext
*ctx
, int vreg
)
2658 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2660 MonoCompile
*cfg
= ctx
->cfg
;
2661 LLVMBuilderRef builder
= ctx
->builder
;
2662 LLVMValueRef offset
, offset_var
;
2663 LLVMValueRef info_var
= ctx
->values
[cfg
->gsharedvt_info_var
->dreg
];
2664 LLVMValueRef locals_var
= ctx
->values
[cfg
->gsharedvt_locals_var
->dreg
];
2668 g_assert (info_var
);
2669 g_assert (locals_var
);
2671 int idx
= cfg
->gsharedvt_vreg_to_idx
[vreg
] - 1;
2673 offset
= LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo
, entries
) + (idx
* TARGET_SIZEOF_VOID_P
), FALSE
);
2674 ptr
= LLVMBuildAdd (builder
, convert (ctx
, info_var
, IntPtrType ()), convert (ctx
, offset
, IntPtrType ()), "");
2676 name
= g_strdup_printf ("gsharedvt_local_%d_offset", vreg
);
2677 offset_var
= LLVMBuildLoad (builder
, convert (ctx
, ptr
, LLVMPointerType (LLVMInt32Type (), 0)), name
);
2679 return LLVMBuildAdd (builder
, convert (ctx
, locals_var
, IntPtrType ()), convert (ctx
, offset_var
, IntPtrType ()), "");
2683 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2686 mark_as_used (MonoLLVMModule
*module
, LLVMValueRef global
)
2689 module
->used
= g_ptr_array_sized_new (16);
2690 g_ptr_array_add (module
->used
, global
);
2694 emit_llvm_used (MonoLLVMModule
*module
)
2696 LLVMModuleRef lmodule
= module
->lmodule
;
2697 LLVMTypeRef used_type
;
2698 LLVMValueRef used
, *used_elem
;
2704 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module
->used
->len
);
2705 used
= LLVMAddGlobal (lmodule
, used_type
, "llvm.used");
2706 used_elem
= g_new0 (LLVMValueRef
, module
->used
->len
);
2707 for (i
= 0; i
< module
->used
->len
; ++i
)
2708 used_elem
[i
] = LLVMConstBitCast ((LLVMValueRef
)g_ptr_array_index (module
->used
, i
), LLVMPointerType (LLVMInt8Type (), 0));
2709 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem
, module
->used
->len
));
2710 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
2711 LLVMSetSection (used
, "llvm.metadata");
2717 * Emit a function mapping method indexes to their code
2720 emit_get_method (MonoLLVMModule
*module
)
2722 LLVMModuleRef lmodule
= module
->lmodule
;
2723 LLVMValueRef func
, switch_ins
, m
;
2724 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
, code_start_bb
, code_end_bb
;
2725 LLVMBasicBlockRef
*bbs
= NULL
;
2727 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2728 LLVMValueRef table
= NULL
;
2731 gboolean emit_table
= FALSE
;
2735 * Emit a table of functions instead of a switch statement,
2736 * its very efficient on wasm. This might be usable on
2737 * other platforms too.
2742 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2745 LLVMTypeRef table_type
;
2746 LLVMValueRef
*table_elems
;
2749 int table_len
= module
->max_method_idx
+ 1;
2750 table_type
= LLVMArrayType (rtype
, table_len
);
2751 table_name
= g_strdup_printf ("%s_method_table", module
->assembly
->aname
.name
);
2752 table
= LLVMAddGlobal (lmodule
, table_type
, table_name
);
2753 table_elems
= g_new0 (LLVMValueRef
, table_len
);
2754 for (i
= 0; i
< table_len
; ++i
) {
2755 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_lmethod
, GINT_TO_POINTER (i
));
2757 table_elems
[i
] = LLVMBuildBitCast (builder
, m
, rtype
, "");
2759 table_elems
[i
] = LLVMConstNull (rtype
);
2761 LLVMSetInitializer (table
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), table_elems
, table_len
));
2765 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2766 * but generating code seems safer.
2768 func
= LLVMAddFunction (lmodule
, module
->get_method_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2769 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2770 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2771 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
2772 module
->get_method
= func
;
2774 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2777 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2778 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2779 * then we will have to find another solution.
2782 name
= g_strdup_printf ("BB_CODE_START");
2783 code_start_bb
= LLVMAppendBasicBlock (func
, name
);
2785 LLVMPositionBuilderAtEnd (builder
, code_start_bb
);
2786 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_start
, rtype
, ""));
2788 name
= g_strdup_printf ("BB_CODE_END");
2789 code_end_bb
= LLVMAppendBasicBlock (func
, name
);
2791 LLVMPositionBuilderAtEnd (builder
, code_end_bb
);
2792 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_end
, rtype
, ""));
2797 * case -1: return code_start;
2798 * case -2: return code_end;
2799 * default: return method_table [index];
2801 LLVMBasicBlockRef default_bb
= LLVMAppendBasicBlock (func
, "DEFAULT");
2802 LLVMPositionBuilderAtEnd (builder
, default_bb
);
2803 LLVMValueRef base
= table
;
2804 LLVMValueRef indexes
[2];
2805 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2806 indexes
[1] = LLVMGetParam (func
, 0);
2807 LLVMValueRef addr
= LLVMBuildGEP (builder
, base
, indexes
, 2, "");
2808 LLVMValueRef res
= mono_llvm_build_load (builder
, addr
, "", FALSE
);
2809 LLVMBuildRet (builder
, res
);
2811 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2813 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), default_bb
, 0);
2814 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -1, FALSE
), code_start_bb
);
2815 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -2, FALSE
), code_end_bb
);
2817 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2818 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2819 name
= g_strdup_printf ("BB_%d", i
);
2820 bb
= LLVMAppendBasicBlock (func
, name
);
2824 LLVMPositionBuilderAtEnd (builder
, bb
);
2826 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_lmethod
, GINT_TO_POINTER (i
));
2828 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2830 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2833 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2834 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2835 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2837 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2839 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2840 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -1, FALSE
), code_start_bb
);
2841 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -2, FALSE
), code_end_bb
);
2842 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2843 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2847 mark_as_used (module
, func
);
2849 LLVMDisposeBuilder (builder
);
2853 * emit_get_unbox_tramp:
2855 * Emit a function mapping method indexes to their unbox trampoline
2858 emit_get_unbox_tramp (MonoLLVMModule
*module
)
2860 LLVMModuleRef lmodule
= module
->lmodule
;
2861 LLVMValueRef func
, switch_ins
, m
;
2862 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
;
2863 LLVMBasicBlockRef
*bbs
;
2865 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2868 gboolean emit_table
= FALSE
;
2870 /* Similar to emit_get_method () */
2872 #ifndef TARGET_WATCHOS
2876 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2879 // About 10% of methods have an unbox tramp, so emit a table of indexes for them
2880 // that the runtime can search using a binary search
2882 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2883 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2888 LLVMTypeRef table_type
, elemtype
;
2889 LLVMValueRef
*table_elems
;
2896 elemsize
= module
->max_method_idx
< 65000 ? 2 : 4;
2899 elemtype
= elemsize
== 2 ? LLVMInt16Type () : LLVMInt32Type ();
2900 table_type
= LLVMArrayType (elemtype
, table_len
);
2901 table_name
= g_strdup_printf ("%s_unbox_tramp_indexes", module
->assembly
->aname
.name
);
2902 table
= LLVMAddGlobal (lmodule
, table_type
, table_name
);
2903 table_elems
= g_new0 (LLVMValueRef
, table_len
);
2905 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2906 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2908 table_elems
[idx
++] = LLVMConstInt (elemtype
, i
, FALSE
);
2910 LLVMSetInitializer (table
, LLVMConstArray (elemtype
, table_elems
, table_len
));
2911 module
->unbox_tramp_indexes
= table
;
2913 // The trampoline table
2915 table_type
= LLVMArrayType (elemtype
, table_len
);
2916 table_name
= g_strdup_printf ("%s_unbox_trampolines", module
->assembly
->aname
.name
);
2917 table
= LLVMAddGlobal (lmodule
, table_type
, table_name
);
2918 table_elems
= g_new0 (LLVMValueRef
, table_len
);
2920 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2921 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2923 table_elems
[idx
++] = LLVMBuildBitCast (builder
, m
, rtype
, "");
2925 LLVMSetInitializer (table
, LLVMConstArray (elemtype
, table_elems
, table_len
));
2926 module
->unbox_trampolines
= table
;
2928 module
->unbox_tramp_num
= table_len
;
2929 module
->unbox_tramp_elemsize
= elemsize
;
2933 func
= LLVMAddFunction (lmodule
, module
->get_unbox_tramp_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2934 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2935 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2936 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
2937 module
->get_unbox_tramp
= func
;
2939 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2941 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2942 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2943 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2947 name
= g_strdup_printf ("BB_%d", i
);
2948 bb
= LLVMAppendBasicBlock (func
, name
);
2952 LLVMPositionBuilderAtEnd (builder
, bb
);
2954 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2957 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2958 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2959 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2961 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2963 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2964 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2965 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2969 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2972 mark_as_used (module
, func
);
2973 LLVMDisposeBuilder (builder
);
2976 /* Add a function to mark the beginning of LLVM code */
2978 emit_llvm_code_start (MonoLLVMModule
*module
)
2980 LLVMModuleRef lmodule
= module
->lmodule
;
2982 LLVMBasicBlockRef entry_bb
;
2983 LLVMBuilderRef builder
;
2985 func
= LLVMAddFunction (lmodule
, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
2986 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2987 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
2988 module
->code_start
= func
;
2989 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2990 builder
= LLVMCreateBuilder ();
2991 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2992 LLVMBuildRetVoid (builder
);
2993 LLVMDisposeBuilder (builder
);
2997 emit_init_icall_wrapper (MonoLLVMModule
*module
, MonoAotInitSubtype subtype
)
2999 LLVMModuleRef lmodule
= module
->lmodule
;
3000 LLVMValueRef func
, indexes
[2], got_entry_addr
, args
[16], callee
;
3001 LLVMBasicBlockRef entry_bb
;
3002 LLVMBuilderRef builder
;
3006 const char *wrapper_name
= mono_marshal_get_aot_init_wrapper_name (subtype
);
3007 char *name
= g_strdup_printf ("%s%s", module
->global_prefix
, wrapper_name
);
3008 const char *icall_name
= NULL
;
3011 case AOT_INIT_METHOD
:
3012 icall_name
= "mini_llvm_init_method";
3013 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
));
3014 sig
= LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE
);
3016 case AOT_INIT_METHOD_GSHARED_MRGCTX
:
3017 icall_name
= "mini_llvm_init_gshared_method_mrgctx"; // Deliberate fall-through
3018 case AOT_INIT_METHOD_GSHARED_VTABLE
:
3021 icall_name
= "mini_llvm_init_gshared_method_vtable";
3022 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE
));
3023 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE
);
3025 case AOT_INIT_METHOD_GSHARED_THIS
:
3026 icall_name
= "mini_llvm_init_gshared_method_this";
3027 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE
));
3028 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE
);
3031 g_assert_not_reached ();
3034 g_assert (icall_name
);
3035 LLVMSetLinkage (func
, LLVMInternalLinkage
);
3037 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_INLINE
);
3039 // FIXME? Using this with mono debug info causes unwind.c to explode when
3040 // parsing some of these registers saved by this call. Can't unwind through it.
3041 // Not an issue with llvmonly because it doesn't use that DWARF
3042 if (module
->llvm_only
)
3043 set_preserveall_cc (func
);
3045 LLVMSetFunctionCallConv (func
, LLVMMono1CallConv
);
3047 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
3048 builder
= LLVMCreateBuilder ();
3049 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
3052 ji
= g_new0 (MonoJumpInfo
, 1);
3053 ji
->type
= MONO_PATCH_INFO_AOT_MODULE
;
3054 ji
= mono_aot_patch_info_dup (ji
);
3055 got_offset
= compute_aot_got_offset (module
, ji
, IntPtrType ());
3056 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
3057 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3058 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
3059 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
3060 args
[0] = LLVMBuildPtrToInt (builder
, LLVMBuildLoad (builder
, got_entry_addr
, ""), IntPtrType (), "");
3061 args
[1] = LLVMGetParam (func
, 0);
3063 args
[2] = LLVMGetParam (func
, 1);
3065 ji
= g_new0 (MonoJumpInfo
, 1);
3066 ji
->type
= MONO_PATCH_INFO_JIT_ICALL
;
3067 ji
->data
.name
= icall_name
;
3068 ji
= mono_aot_patch_info_dup (ji
);
3069 got_offset
= compute_aot_got_offset (module
, ji
, sig
);
3070 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
3071 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3072 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
3073 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
3074 callee
= LLVMBuildLoad (builder
, got_entry_addr
, "");
3075 callee
= LLVMBuildBitCast (builder
, callee
, LLVMPointerType (sig
, 0), "");
3076 LLVMBuildCall (builder
, callee
, args
, LLVMCountParamTypes (sig
), "");
3078 // Set the inited flag
3079 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3080 indexes
[1] = LLVMGetParam (func
, 0);
3081 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt8Type (), 1, FALSE
), LLVMBuildGEP (builder
, module
->inited_var
, indexes
, 2, ""));
3083 LLVMBuildRetVoid (builder
);
3085 LLVMVerifyFunction(func
, LLVMAbortProcessAction
);
3086 LLVMDisposeBuilder (builder
);
3091 * Emit wrappers around the C icalls used to initialize llvm methods, to
3092 * make the calling code smaller and to enable usage of the llvm
3093 * PreserveAll calling convention.
3096 emit_init_icall_wrappers (MonoLLVMModule
*module
)
3098 module
->init_method
= emit_init_icall_wrapper (module
, AOT_INIT_METHOD
);
3099 module
->init_method_gshared_mrgctx
= emit_init_icall_wrapper (module
, AOT_INIT_METHOD_GSHARED_MRGCTX
);
3100 module
->init_method_gshared_this
= emit_init_icall_wrapper (module
, AOT_INIT_METHOD_GSHARED_THIS
);
3101 module
->init_method_gshared_vtable
= emit_init_icall_wrapper (module
, AOT_INIT_METHOD_GSHARED_VTABLE
);
3105 get_init_icall_wrapper (MonoLLVMModule
*module
, MonoAotInitSubtype subtype
)
3108 case AOT_INIT_METHOD
:
3109 return module
->init_method
;
3110 case AOT_INIT_METHOD_GSHARED_MRGCTX
:
3111 return module
->init_method_gshared_mrgctx
;
3112 case AOT_INIT_METHOD_GSHARED_THIS
:
3113 return module
->init_method_gshared_this
;
3114 case AOT_INIT_METHOD_GSHARED_VTABLE
:
3115 return module
->init_method_gshared_vtable
;
3117 g_assert_not_reached ();
3122 emit_gc_safepoint_poll (MonoLLVMModule
*module
)
3124 LLVMModuleRef lmodule
= module
->lmodule
;
3125 LLVMValueRef func
, indexes
[2], got_entry_addr
, flag_addr
, val_ptr
, callee
, val
, cmp
;
3126 LLVMBasicBlockRef entry_bb
, poll_bb
, exit_bb
;
3127 LLVMBuilderRef builder
;
3132 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
3133 func
= mono_llvm_get_or_insert_gc_safepoint_poll (lmodule
);
3134 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
3135 LLVMSetLinkage (func
, LLVMWeakODRLinkage
);
3136 // set_preserveall_cc (func);
3138 entry_bb
= LLVMAppendBasicBlock (func
, "gc.safepoint_poll.entry");
3139 poll_bb
= LLVMAppendBasicBlock (func
, "gc.safepoint_poll.poll");
3140 exit_bb
= LLVMAppendBasicBlock (func
, "gc.safepoint_poll.exit");
3142 builder
= LLVMCreateBuilder ();
3145 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
3148 ji
= g_new0 (MonoJumpInfo
, 1);
3149 ji
->type
= MONO_PATCH_INFO_GC_SAFE_POINT_FLAG
;
3150 ji
= mono_aot_patch_info_dup (ji
);
3151 got_offset
= compute_aot_got_offset (module
, ji
, IntPtrType ());
3152 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
3153 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3154 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
3155 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
3156 flag_addr
= LLVMBuildLoad (builder
, got_entry_addr
, "");
3157 val_ptr
= LLVMBuildLoad (builder
, flag_addr
, "");
3158 val
= LLVMBuildPtrToInt (builder
, val_ptr
, IntPtrType (), "");
3159 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, val
, LLVMConstNull (LLVMTypeOf (val
)), "");
3160 LLVMBuildCondBr (builder
, cmp
, exit_bb
, poll_bb
);
3163 LLVMPositionBuilderAtEnd(builder
, poll_bb
);
3165 ji
= g_new0 (MonoJumpInfo
, 1);
3166 ji
->type
= MONO_PATCH_INFO_JIT_ICALL
;
3167 ji
->data
.name
= "mono_threads_state_poll";
3168 ji
= mono_aot_patch_info_dup (ji
);
3169 got_offset
= compute_aot_got_offset (module
, ji
, sig
);
3170 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
3171 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3172 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
3173 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
3174 callee
= LLVMBuildLoad (builder
, got_entry_addr
, "");
3175 callee
= LLVMBuildBitCast (builder
, callee
, LLVMPointerType (sig
, 0), "");
3176 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
3177 LLVMBuildBr(builder
, exit_bb
);
3180 LLVMPositionBuilderAtEnd(builder
, exit_bb
);
3182 LLVMBuildRetVoid (builder
);
3184 LLVMVerifyFunction(func
, LLVMAbortProcessAction
);
3185 LLVMDisposeBuilder (builder
);
3189 emit_llvm_code_end (MonoLLVMModule
*module
)
3191 LLVMModuleRef lmodule
= module
->lmodule
;
3193 LLVMBasicBlockRef entry_bb
;
3194 LLVMBuilderRef builder
;
3196 func
= LLVMAddFunction (lmodule
, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
3197 LLVMSetLinkage (func
, LLVMInternalLinkage
);
3198 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
3199 module
->code_end
= func
;
3200 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
3201 builder
= LLVMCreateBuilder ();
3202 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
3203 LLVMBuildRetVoid (builder
);
3204 LLVMDisposeBuilder (builder
);
3208 emit_div_check (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoBasicBlock
*bb
, MonoInst
*ins
, LLVMValueRef lhs
, LLVMValueRef rhs
)
3210 gboolean need_div_check
= ctx
->cfg
->backend
->need_div_check
;
3213 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
3214 need_div_check
= TRUE
;
3216 if (!need_div_check
)
3219 switch (ins
->opcode
) {
3232 case OP_IDIV_UN_IMM
:
3233 case OP_LDIV_UN_IMM
:
3234 case OP_IREM_UN_IMM
:
3235 case OP_LREM_UN_IMM
: {
3237 gboolean is_signed
= (ins
->opcode
== OP_IDIV
|| ins
->opcode
== OP_LDIV
|| ins
->opcode
== OP_IREM
|| ins
->opcode
== OP_LREM
||
3238 ins
->opcode
== OP_IDIV_IMM
|| ins
->opcode
== OP_LDIV_IMM
|| ins
->opcode
== OP_IREM_IMM
|| ins
->opcode
== OP_LREM_IMM
);
3240 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), 0, FALSE
), "");
3241 emit_cond_system_exception (ctx
, bb
, "DivideByZeroException", cmp
);
3244 builder
= ctx
->builder
;
3246 /* b == -1 && a == 0x80000000 */
3248 LLVMValueRef c
= (LLVMTypeOf (lhs
) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs
), 0x80000000, FALSE
) : LLVMConstInt (LLVMTypeOf (lhs
), 0x8000000000000000LL
, FALSE
);
3249 LLVMValueRef cond1
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), -1, FALSE
), "");
3250 LLVMValueRef cond2
= LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, c
, "");
3252 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, LLVMBuildAnd (builder
, cond1
, cond2
, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE
), "");
3253 emit_cond_system_exception (ctx
, bb
, "OverflowException", cmp
);
3256 builder
= ctx
->builder
;
3268 * Emit code to initialize the GOT slots used by the method.
3271 emit_init_method (EmitContext
*ctx
)
3273 LLVMValueRef indexes
[16], args
[16], callee
;
3274 LLVMValueRef inited_var
, cmp
, call
;
3275 LLVMBasicBlockRef inited_bb
, notinited_bb
;
3276 LLVMBuilderRef builder
= ctx
->builder
;
3277 MonoCompile
*cfg
= ctx
->cfg
;
3279 ctx
->module
->max_inited_idx
= MAX (ctx
->module
->max_inited_idx
, cfg
->method_index
);
3281 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3282 indexes
[1] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, FALSE
);
3283 inited_var
= LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, ctx
->module
->inited_var
, indexes
, 2, ""), "is_inited");
3285 //WASM doesn't support the "llvm.expect.i8" intrinsic
3287 args
[0] = inited_var
;
3288 args
[1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE
);
3289 inited_var
= LLVMBuildCall (ctx
->builder
, get_intrins (ctx
, INTRINS_EXPECT_I8
), args
, 2, "");
3292 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, inited_var
, LLVMConstInt (LLVMTypeOf (inited_var
), 0, FALSE
), "");
3294 inited_bb
= ctx
->inited_bb
;
3295 notinited_bb
= gen_bb (ctx
, "NOTINITED_BB");
3297 ctx
->cfg
->llvmonly_init_cond
= LLVMBuildCondBr (ctx
->builder
, cmp
, notinited_bb
, inited_bb
);
3299 builder
= ctx
->builder
= create_builder (ctx
);
3300 LLVMPositionBuilderAtEnd (ctx
->builder
, notinited_bb
);
3303 if (ctx
->rgctx_arg
&& ((cfg
->method
->is_inflated
&& mono_method_get_context (cfg
->method
)->method_inst
) ||
3304 mini_method_is_default_method (cfg
->method
))) {
3305 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
3306 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
3307 callee
= ctx
->module
->init_method_gshared_mrgctx
;
3308 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
3309 } else if (ctx
->rgctx_arg
) {
3310 /* A vtable is passed as the rgctx argument */
3311 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
3312 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
3313 callee
= ctx
->module
->init_method_gshared_vtable
;
3314 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
3315 } else if (cfg
->gshared
) {
3316 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
3317 args
[1] = convert (ctx
, ctx
->this_arg
, ObjRefType ());
3318 callee
= ctx
->module
->init_method_gshared_this
;
3319 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
3321 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
3322 callee
= ctx
->module
->init_method
;
3323 call
= LLVMBuildCall (builder
, callee
, args
, 1, "");
3327 * This enables llvm to keep arguments in their original registers/
3328 * scratch registers, since the call will not clobber them.
3332 set_call_preserveall_cc (call
);
3334 LLVMSetInstructionCallConv (call
, LLVMMono1CallConv
);
3336 LLVMBuildBr (builder
, inited_bb
);
3337 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= inited_bb
;
3339 builder
= ctx
->builder
= create_builder (ctx
);
3340 LLVMPositionBuilderAtEnd (ctx
->builder
, inited_bb
);
3344 emit_unbox_tramp (EmitContext
*ctx
, const char *method_name
, LLVMTypeRef method_type
, LLVMValueRef method
, int method_index
)
3347 * Emit unbox trampoline using a tailcall
3349 LLVMValueRef tramp
, call
, *args
;
3350 LLVMBuilderRef builder
;
3351 LLVMBasicBlockRef lbb
;
3352 LLVMCallInfo
*linfo
;
3356 tramp_name
= g_strdup_printf ("ut_%s", method_name
);
3357 tramp
= LLVMAddFunction (ctx
->module
->lmodule
, tramp_name
, method_type
);
3358 LLVMSetLinkage (tramp
, LLVMInternalLinkage
);
3359 mono_llvm_add_func_attr (tramp
, LLVM_ATTR_OPTIMIZE_FOR_SIZE
);
3360 //mono_llvm_add_func_attr (tramp, LLVM_ATTR_NO_UNWIND);
3362 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
3363 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
3364 mono_llvm_add_param_attr (LLVMGetParam (tramp
, ctx
->rgctx_arg_pindex
), LLVM_ATTR_IN_REG
);
3365 if (ctx
->cfg
->vret_addr
) {
3366 LLVMSetValueName (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), "vret");
3367 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
3368 mono_llvm_add_param_attr (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVM_ATTR_STRUCT_RET
);
3369 mono_llvm_add_param_attr (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVM_ATTR_NO_ALIAS
);
3373 lbb
= LLVMAppendBasicBlock (tramp
, "");
3374 builder
= LLVMCreateBuilder ();
3375 LLVMPositionBuilderAtEnd (builder
, lbb
);
3377 nargs
= LLVMCountParamTypes (method_type
);
3378 args
= g_new0 (LLVMValueRef
, nargs
);
3379 for (i
= 0; i
< nargs
; ++i
) {
3380 args
[i
] = LLVMGetParam (tramp
, i
);
3381 if (i
== ctx
->this_arg_pindex
) {
3382 LLVMTypeRef arg_type
= LLVMTypeOf (args
[i
]);
3384 args
[i
] = LLVMBuildPtrToInt (builder
, args
[i
], IntPtrType (), "");
3385 args
[i
] = LLVMBuildAdd (builder
, args
[i
], LLVMConstInt (IntPtrType (), MONO_ABI_SIZEOF (MonoObject
), FALSE
), "");
3386 args
[i
] = LLVMBuildIntToPtr (builder
, args
[i
], arg_type
, "");
3389 call
= LLVMBuildCall (builder
, method
, args
, nargs
, "");
3390 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
3391 mono_llvm_add_instr_attr (call
, 1 + ctx
->rgctx_arg_pindex
, LLVM_ATTR_IN_REG
);
3392 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
)
3393 mono_llvm_add_instr_attr (call
, 1 + linfo
->vret_arg_pindex
, LLVM_ATTR_STRUCT_RET
);
3395 // FIXME: This causes assertions in clang
3396 //mono_llvm_set_must_tailcall (call);
3397 if (LLVMGetReturnType (method_type
) == LLVMVoidType ())
3398 LLVMBuildRetVoid (builder
);
3400 LLVMBuildRet (builder
, call
);
3402 g_hash_table_insert (ctx
->module
->idx_to_unbox_tramp
, GINT_TO_POINTER (method_index
), tramp
);
3403 LLVMDisposeBuilder (builder
);
3409 * Emit code to load/convert arguments.
3412 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
)
3415 MonoCompile
*cfg
= ctx
->cfg
;
3416 MonoMethodSignature
*sig
= ctx
->sig
;
3417 LLVMCallInfo
*linfo
= ctx
->linfo
;
3421 LLVMBuilderRef old_builder
= ctx
->builder
;
3422 ctx
->builder
= builder
;
3424 ctx
->alloca_builder
= create_builder (ctx
);
3427 * Handle indirect/volatile variables by allocating memory for them
3428 * using 'alloca', and storing their address in a temporary.
3430 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
3431 MonoInst
*var
= cfg
->varinfo
[i
];
3434 if (var
->opcode
== OP_GSHAREDVT_LOCAL
|| var
->opcode
== OP_GSHAREDVT_ARG_REGOFFSET
) {
3435 } 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
))) {
3436 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
3439 /* Could be already created by an OP_VPHI */
3440 if (!ctx
->addresses
[var
->dreg
]) {
3441 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
3442 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
3444 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
3448 names
= g_new (char *, sig
->param_count
);
3449 mono_method_get_param_names (cfg
->method
, (const char **) names
);
3451 for (i
= 0; i
< sig
->param_count
; ++i
) {
3452 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
3453 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
3456 pindex
= ainfo
->pindex
;
3458 switch (ainfo
->storage
) {
3459 case LLVMArgVtypeInReg
:
3460 case LLVMArgAsFpArgs
: {
3461 LLVMValueRef args
[8];
3464 pindex
+= ainfo
->ndummy_fpargs
;
3466 /* The argument is received as a set of int/fp arguments, store them into the real argument */
3467 memset (args
, 0, sizeof (args
));
3468 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
3469 args
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
3470 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
3471 args
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
3473 g_assert (ainfo
->nslots
<= 8);
3474 for (j
= 0; j
< ainfo
->nslots
; ++j
)
3475 args
[j
] = LLVMGetParam (ctx
->lmethod
, pindex
+ j
);
3477 ctx
->addresses
[reg
] = build_alloca (ctx
, ainfo
->type
);
3479 emit_args_to_vtype (ctx
, builder
, ainfo
->type
, ctx
->addresses
[reg
], ainfo
, args
);
3481 if (ainfo
->storage
== LLVMArgVtypeInReg
&& MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (ainfo
->type
))) {
3482 /* Treat these as normal values */
3483 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
3487 case LLVMArgVtypeByVal
: {
3488 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3490 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (ainfo
->type
))) {
3491 /* Treat these as normal values */
3492 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
3496 case LLVMArgVtypeByRef
: {
3497 /* The argument is passed by ref */
3498 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3501 case LLVMArgAsIArgs
: {
3502 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3504 MonoType
*t
= mini_get_underlying_type (ainfo
->type
);
3506 /* The argument is received as an array of ints, store it into the real argument */
3507 ctx
->addresses
[reg
] = build_alloca (ctx
, t
);
3509 size
= mono_class_value_size (mono_class_from_mono_type_internal (t
), NULL
);
3511 } else if (size
< TARGET_SIZEOF_VOID_P
) {
3512 /* The upper bits of the registers might not be valid */
3513 LLVMValueRef val
= LLVMBuildExtractValue (builder
, arg
, 0, "");
3514 LLVMValueRef dest
= convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMIntType (size
* 8), 0));
3515 LLVMBuildStore (ctx
->builder
, LLVMBuildTrunc (builder
, val
, LLVMIntType (size
* 8), ""), dest
);
3517 LLVMBuildStore (ctx
->builder
, arg
, convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMTypeOf (arg
), 0)));
3521 case LLVMArgVtypeAsScalar
:
3522 g_assert_not_reached ();
3524 case LLVMArgGsharedvtFixed
: {
3525 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3526 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3529 name
= g_strdup_printf ("arg_%s", names
[i
]);
3531 name
= g_strdup_printf ("arg_%d", i
);
3533 ctx
->values
[reg
] = LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), name
);
3536 case LLVMArgGsharedvtFixedVtype
: {
3537 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3540 name
= g_strdup_printf ("vtype_arg_%s", names
[i
]);
3542 name
= g_strdup_printf ("vtype_arg_%d", i
);
3544 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3545 g_assert (ctx
->addresses
[reg
]);
3546 LLVMSetValueName (ctx
->addresses
[reg
], name
);
3547 LLVMBuildStore (builder
, LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), ""), ctx
->addresses
[reg
]);
3550 case LLVMArgGsharedvtVariable
:
3551 /* The IR treats these as variables with addresses */
3552 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3555 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
));
3562 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
3564 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
3565 for (i
= 0; i
< sig
->param_count
; ++i
)
3566 if (!mini_type_is_vtype (sig
->params
[i
]))
3567 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
3569 if (sig
->hasthis
&& !cfg
->rgctx_var
&& cfg
->gshared
) {
3570 LLVMValueRef this_alloc
;
3573 * The exception handling code needs the location where the this argument was
3574 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3575 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3576 * location into the LSDA.
3578 this_alloc
= mono_llvm_build_alloca (builder
, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
3579 /* This volatile store will keep the alloca alive */
3580 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3582 set_metadata_flag (this_alloc
, "mono.this");
3585 if (cfg
->rgctx_var
) {
3586 LLVMValueRef rgctx_alloc
, store
;
3589 * We handle the rgctx arg similarly to the this pointer.
3591 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
3592 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
3593 /* This volatile store will keep the alloca alive */
3594 store
= mono_llvm_build_store (builder
, convert (ctx
, ctx
->rgctx_arg
, IntPtrType ()), rgctx_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3596 set_metadata_flag (rgctx_alloc
, "mono.this");
3599 /* Initialize the method if needed */
3600 if (cfg
->compile_aot
&& !ctx
->module
->llvm_disable_self_init
) {
3601 /* Emit a location for the initialization code */
3602 ctx
->init_bb
= gen_bb (ctx
, "INIT_BB");
3603 ctx
->inited_bb
= gen_bb (ctx
, "INITED_BB");
3605 LLVMBuildBr (ctx
->builder
, ctx
->init_bb
);
3606 builder
= ctx
->builder
= create_builder (ctx
);
3607 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->inited_bb
);
3608 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= ctx
->inited_bb
;
3611 /* Compute nesting between clauses */
3612 ctx
->nested_in
= (GSList
**)mono_mempool_alloc0 (cfg
->mempool
, sizeof (GSList
*) * cfg
->header
->num_clauses
);
3613 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
3614 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
3615 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
3616 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
3618 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
)
3619 ctx
->nested_in
[i
] = g_slist_prepend_mempool (cfg
->mempool
, ctx
->nested_in
[i
], GINT_TO_POINTER (j
));
3624 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3625 * it needs to continue normally, or return back to the exception handling system.
3627 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
3631 if (!(bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
)))
3634 clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
3635 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
3636 g_hash_table_insert (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
), bb
);
3638 if (bb
->in_scount
== 0) {
3641 sprintf (name
, "finally_ind_bb%d", bb
->block_num
);
3642 val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), name
);
3643 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
3645 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
3647 /* Create a variable to hold the exception var */
3649 ctx
->ex_var
= LLVMBuildAlloca (builder
, ObjRefType (), "exvar");
3653 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3654 * LLVM bblock containing a landing pad causes problems for the
3655 * LLVM optimizer passes.
3657 sprintf (name
, "BB%d_CALL_HANDLER_TARGET", bb
->block_num
);
3658 ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, name
);
3660 ctx
->builder
= old_builder
;
3664 needs_extra_arg (EmitContext
*ctx
, MonoMethod
*method
)
3666 WrapperInfo
*info
= NULL
;
3669 * When targeting wasm, the caller and callee signature has to match exactly. This means
3670 * that every method which can be called indirectly need an extra arg since the caller
3671 * will call it through an ftnptr and will pass an extra arg.
3673 if (!ctx
->cfg
->llvm_only
|| !ctx
->emit_dummy_arg
)
3675 if (method
->wrapper_type
)
3676 info
= mono_marshal_get_wrapper_info (method
);
3678 switch (method
->wrapper_type
) {
3679 case MONO_WRAPPER_OTHER
:
3680 if (info
->subtype
== WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG
|| info
->subtype
== WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG
)
3681 /* Already have an explicit extra arg */
3684 case MONO_WRAPPER_MANAGED_TO_NATIVE
:
3685 if (strstr (method
->name
, "icall_wrapper"))
3686 /* These are JIT icall wrappers which are only called from JITted code directly */
3688 /* Normal icalls can be virtual methods which need an extra arg */
3690 case MONO_WRAPPER_RUNTIME_INVOKE
:
3691 case MONO_WRAPPER_ALLOC
:
3692 case MONO_WRAPPER_CASTCLASS
:
3693 case MONO_WRAPPER_WRITE_BARRIER
:
3695 case MONO_WRAPPER_STELEMREF
:
3696 if (info
->subtype
!= WRAPPER_SUBTYPE_VIRTUAL_STELEMREF
)
3699 case MONO_WRAPPER_MANAGED_TO_MANAGED
:
3700 if (info
->subtype
== WRAPPER_SUBTYPE_STRING_CTOR
)
3706 if (method
->string_ctor
)
3709 /* These are called from gsharedvt code with an indirect call which doesn't pass an extra arg */
3710 if (method
->klass
== mono_get_string_class () && (strstr (method
->name
, "memcpy") || strstr (method
->name
, "bzero")))
3715 static inline gboolean
3716 is_supported_callconv (EmitContext
*ctx
, MonoCallInst
*call
)
3718 #if defined(TARGET_WIN32) && defined(TARGET_AMD64)
3719 gboolean result
= (call
->signature
->call_convention
== MONO_CALL_DEFAULT
) ||
3720 (call
->signature
->call_convention
== MONO_CALL_C
) ||
3721 (call
->signature
->call_convention
== MONO_CALL_STDCALL
);
3723 gboolean result
= (call
->signature
->call_convention
== MONO_CALL_DEFAULT
) || ((call
->signature
->call_convention
== MONO_CALL_C
) && ctx
->llvm_only
);
3729 process_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, MonoInst
*ins
)
3731 MonoCompile
*cfg
= ctx
->cfg
;
3732 LLVMValueRef
*values
= ctx
->values
;
3733 LLVMValueRef
*addresses
= ctx
->addresses
;
3734 MonoCallInst
*call
= (MonoCallInst
*)ins
;
3735 MonoMethodSignature
*sig
= call
->signature
;
3736 LLVMValueRef callee
= NULL
, lcall
;
3738 LLVMCallInfo
*cinfo
;
3742 LLVMTypeRef llvm_sig
;
3744 gboolean is_virtual
, calli
, preserveall
;
3745 LLVMBuilderRef builder
= *builder_ref
;
3747 /* If both imt and rgctx arg are required, only pass the imt arg, the rgctx trampoline will pass the rgctx */
3748 if (call
->imt_arg_reg
)
3749 call
->rgctx_arg_reg
= 0;
3751 if (!is_supported_callconv (ctx
, call
)) {
3752 set_failure (ctx
, "non-default callconv");
3756 cinfo
= call
->cinfo
;
3758 if (call
->rgctx_arg_reg
)
3759 cinfo
->rgctx_arg
= TRUE
;
3760 if (call
->imt_arg_reg
)
3761 cinfo
->imt_arg
= TRUE
;
3762 if (!call
->rgctx_arg_reg
&& call
->method
&& needs_extra_arg (ctx
, call
->method
))
3763 cinfo
->dummy_arg
= TRUE
;
3765 vretaddr
= (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
|| cinfo
->ret
.storage
== LLVMArgVtypeByRef
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixed
|| cinfo
->ret
.storage
== LLVMArgGsharedvtVariable
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixedVtype
);
3767 llvm_sig
= sig_to_llvm_sig_full (ctx
, sig
, cinfo
);
3771 int const opcode
= ins
->opcode
;
3773 is_virtual
= opcode
== OP_VOIDCALL_MEMBASE
|| opcode
== OP_CALL_MEMBASE
3774 || opcode
== OP_VCALL_MEMBASE
|| opcode
== OP_LCALL_MEMBASE
3775 || opcode
== OP_FCALL_MEMBASE
|| opcode
== OP_RCALL_MEMBASE
3776 || opcode
== OP_TAILCALL_MEMBASE
;
3777 calli
= !call
->fptr_is_patch
&& (opcode
== OP_VOIDCALL_REG
|| opcode
== OP_CALL_REG
3778 || opcode
== OP_VCALL_REG
|| opcode
== OP_LCALL_REG
|| opcode
== OP_FCALL_REG
3779 || opcode
== OP_RCALL_REG
|| opcode
== OP_TAILCALL_REG
);
3782 preserveall
= FALSE
;
3784 /* FIXME: Avoid creating duplicate methods */
3786 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3790 if (cfg
->compile_aot
) {
3791 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
3793 set_failure (ctx
, "can't encode patch");
3798 static int tramp_index
;
3801 name
= g_strdup_printf ("tramp_%d", tramp_index
);
3804 #if LLVM_API_VERSION > 100
3806 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3807 * Make all calls through a global. The address of the global will be saved in
3808 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3811 LLVMValueRef tramp_var
= (LLVMValueRef
)g_hash_table_lookup (ctx
->jit_callees
, call
->method
);
3814 mono_create_jit_trampoline (mono_domain_get (),
3815 call
->method
, error
);
3816 if (!is_ok (error
)) {
3817 set_failure (ctx
, mono_error_get_message (error
));
3818 mono_error_cleanup (error
);
3822 tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
3823 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
3824 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
3825 g_hash_table_insert (ctx
->jit_callees
, call
->method
, tramp_var
);
3827 callee
= LLVMBuildLoad (builder
, tramp_var
, "");
3829 g_assert_not_reached ();
3834 if (!cfg
->llvm_only
&& call
->method
&& strstr (m_class_get_name (call
->method
->klass
), "AsyncVoidMethodBuilder")) {
3835 /* LLVM miscompiles async methods */
3836 set_failure (ctx
, "#13734");
3841 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
3847 memset (&ji, 0, sizeof (ji));
3848 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3849 ji.data.target = info->name;
3851 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3853 if (cfg
->compile_aot
) {
3854 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_JIT_ICALL
, (char*)info
->name
);
3856 set_failure (ctx
, "can't encode patch");
3860 target
= (gpointer
)mono_icall_get_wrapper (info
);
3861 callee
= emit_jit_callee (ctx
, "", llvm_sig
, target
);
3864 if (cfg
->compile_aot
) {
3866 if (cfg
->abs_patches
) {
3867 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3869 callee
= get_callee (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
3871 set_failure (ctx
, "can't encode patch");
3877 set_failure (ctx
, "aot");
3881 #if LLVM_API_VERSION > 100
3882 if (cfg
->abs_patches
) {
3883 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3887 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
, error
);
3888 mono_error_assert_ok (error
);
3889 callee
= emit_jit_callee (ctx
, "", llvm_sig
, target
);
3891 g_assert_not_reached ();
3894 g_assert_not_reached ();
3897 g_assert_not_reached ();
3904 int size
= TARGET_SIZEOF_VOID_P
;
3907 g_assert (ins
->inst_offset
% size
== 0);
3908 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3910 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
3912 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
3914 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3919 * Collect and convert arguments
3921 nargs
= (sig
->param_count
* 16) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
+ call
->imt_arg_reg
+ call
->cinfo
->dummy_arg
+ 1;
3922 len
= sizeof (LLVMValueRef
) * nargs
;
3923 args
= g_newa (LLVMValueRef
, nargs
);
3924 memset (args
, 0, len
);
3925 l
= call
->out_ireg_args
;
3927 if (call
->rgctx_arg_reg
) {
3928 g_assert (values
[call
->rgctx_arg_reg
]);
3929 g_assert (cinfo
->rgctx_arg_pindex
< nargs
);
3931 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3932 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3933 * it using a volatile load.
3936 if (!ctx
->imt_rgctx_loc
)
3937 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, TARGET_SIZEOF_VOID_P
);
3938 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3939 args
[cinfo
->rgctx_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3941 args
[cinfo
->rgctx_arg_pindex
] = convert (ctx
, values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
);
3944 if (call
->imt_arg_reg
) {
3945 g_assert (!ctx
->llvm_only
);
3946 g_assert (values
[call
->imt_arg_reg
]);
3947 g_assert (cinfo
->imt_arg_pindex
< nargs
);
3949 if (!ctx
->imt_rgctx_loc
)
3950 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, TARGET_SIZEOF_VOID_P
);
3951 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3952 args
[cinfo
->imt_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3954 args
[cinfo
->imt_arg_pindex
] = convert (ctx
, values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
);
3957 switch (cinfo
->ret
.storage
) {
3958 case LLVMArgGsharedvtVariable
: {
3959 MonoInst
*var
= get_vreg_to_inst (cfg
, call
->inst
.dreg
);
3961 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
3962 args
[cinfo
->vret_arg_pindex
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), IntPtrType ());
3964 g_assert (addresses
[call
->inst
.dreg
]);
3965 args
[cinfo
->vret_arg_pindex
] = convert (ctx
, addresses
[call
->inst
.dreg
], IntPtrType ());
3971 if (!addresses
[call
->inst
.dreg
])
3972 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3973 g_assert (cinfo
->vret_arg_pindex
< nargs
);
3974 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
3975 args
[cinfo
->vret_arg_pindex
] = addresses
[call
->inst
.dreg
];
3977 args
[cinfo
->vret_arg_pindex
] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
3983 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3984 * use the real callee for argument type conversion.
3986 LLVMTypeRef callee_type
= LLVMGetElementType (LLVMTypeOf (callee
));
3987 LLVMTypeRef
*param_types
= (LLVMTypeRef
*)g_alloca (sizeof (LLVMTypeRef
) * LLVMCountParamTypes (callee_type
));
3988 LLVMGetParamTypes (callee_type
, param_types
);
3990 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
3993 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
];
3995 pindex
= ainfo
->pindex
;
3997 regpair
= (guint32
)(gssize
)(l
->data
);
3998 reg
= regpair
& 0xffffff;
3999 args
[pindex
] = values
[reg
];
4000 switch (ainfo
->storage
) {
4001 case LLVMArgVtypeInReg
:
4002 case LLVMArgAsFpArgs
: {
4006 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
4007 args
[pindex
+ j
] = LLVMConstNull (LLVMDoubleType ());
4008 pindex
+= ainfo
->ndummy_fpargs
;
4010 g_assert (addresses
[reg
]);
4011 emit_vtype_to_args (ctx
, builder
, ainfo
->type
, addresses
[reg
], ainfo
, args
+ pindex
, &nargs
);
4015 // FIXME: Get rid of the VMOVE
4018 case LLVMArgVtypeByVal
:
4019 g_assert (addresses
[reg
]);
4020 args
[pindex
] = addresses
[reg
];
4022 case LLVMArgVtypeByRef
: {
4023 g_assert (addresses
[reg
]);
4024 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
4027 case LLVMArgAsIArgs
:
4028 g_assert (addresses
[reg
]);
4029 if (ainfo
->esize
== 8)
4030 args
[pindex
] = LLVMBuildLoad (ctx
->builder
, convert (ctx
, addresses
[reg
], LLVMPointerType (LLVMArrayType (LLVMInt64Type (), ainfo
->nslots
), 0)), "");
4032 args
[pindex
] = LLVMBuildLoad (ctx
->builder
, convert (ctx
, addresses
[reg
], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo
->nslots
), 0)), "");
4034 case LLVMArgVtypeAsScalar
:
4035 g_assert_not_reached ();
4037 case LLVMArgGsharedvtFixed
:
4038 case LLVMArgGsharedvtFixedVtype
:
4039 g_assert (addresses
[reg
]);
4040 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
4042 case LLVMArgGsharedvtVariable
:
4043 g_assert (addresses
[reg
]);
4044 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (IntPtrType (), 0));
4047 g_assert (args
[pindex
]);
4048 if (i
== 0 && sig
->hasthis
)
4049 args
[pindex
] = convert (ctx
, args
[pindex
], param_types
[pindex
]);
4051 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, ainfo
->type
));
4054 g_assert (pindex
<= nargs
);
4060 if (call
->cinfo
->dummy_arg
) {
4061 g_assert (call
->cinfo
->dummy_arg_pindex
< nargs
);
4062 args
[call
->cinfo
->dummy_arg_pindex
] = LLVMConstNull (ctx
->module
->ptr_type
);
4065 // FIXME: Align call sites
4070 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, LLVMCountParamTypes (llvm_sig
));
4072 if (ins
->opcode
!= OP_TAILCALL
&& ins
->opcode
!= OP_TAILCALL_MEMBASE
&& LLVMGetInstructionOpcode (lcall
) == LLVMCall
)
4073 mono_llvm_set_call_notailcall (lcall
);
4075 // As per the LLVM docs, a function has a noalias return value if and only if
4076 // it is an allocation function. This is an allocation function.
4077 if (call
->method
&& call
->method
->wrapper_type
== MONO_WRAPPER_ALLOC
)
4078 mono_llvm_set_call_noalias_ret (lcall
);
4081 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
4083 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
4084 g_assert (MONO_ARCH_IMT_REG
== MONO_ARCH_RGCTX_REG
);
4086 /* The two can't be used together, so use only one LLVM calling conv to pass them */
4087 g_assert (!(call
->rgctx_arg_reg
&& call
->imt_arg_reg
));
4088 if (!sig
->pinvoke
&& !cfg
->llvm_only
)
4089 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
4091 set_call_preserveall_cc (lcall
);
4093 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
4094 mono_llvm_add_instr_attr (lcall
, 1 + cinfo
->vret_arg_pindex
, LLVM_ATTR_STRUCT_RET
);
4095 if (!ctx
->llvm_only
&& call
->rgctx_arg_reg
)
4096 mono_llvm_add_instr_attr (lcall
, 1 + cinfo
->rgctx_arg_pindex
, LLVM_ATTR_IN_REG
);
4097 if (call
->imt_arg_reg
)
4098 mono_llvm_add_instr_attr (lcall
, 1 + cinfo
->imt_arg_pindex
, LLVM_ATTR_IN_REG
);
4100 /* Add byval attributes if needed */
4101 for (i
= 0; i
< sig
->param_count
; ++i
) {
4102 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
+ sig
->hasthis
];
4104 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
)
4105 mono_llvm_add_instr_attr (lcall
, 1 + ainfo
->pindex
, LLVM_ATTR_BY_VAL
);
4109 * Convert the result
4111 switch (cinfo
->ret
.storage
) {
4112 case LLVMArgVtypeInReg
: {
4113 LLVMValueRef regs
[2];
4115 if (LLVMTypeOf (lcall
) == LLVMVoidType ())
4119 if (!addresses
[ins
->dreg
])
4120 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
4122 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
4123 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
4124 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
4125 emit_args_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
4128 case LLVMArgVtypeByVal
:
4129 if (!addresses
[call
->inst
.dreg
])
4130 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
4131 LLVMBuildStore (builder
, lcall
, addresses
[call
->inst
.dreg
]);
4133 case LLVMArgAsIArgs
:
4134 case LLVMArgFpStruct
:
4135 if (!addresses
[call
->inst
.dreg
])
4136 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
4137 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
4139 case LLVMArgVtypeAsScalar
:
4140 if (!addresses
[call
->inst
.dreg
])
4141 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
4142 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
4144 case LLVMArgVtypeRetAddr
:
4145 case LLVMArgVtypeByRef
:
4146 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (sig
->ret
))) {
4147 /* Some opcodes like STOREX_MEMBASE access these by value */
4148 g_assert (addresses
[call
->inst
.dreg
]);
4149 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
4152 case LLVMArgGsharedvtVariable
:
4154 case LLVMArgGsharedvtFixed
:
4155 case LLVMArgGsharedvtFixedVtype
:
4156 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
4159 if (sig
->ret
->type
!= MONO_TYPE_VOID
)
4160 /* If the method returns an unsigned value, need to zext it */
4161 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
));
4165 *builder_ref
= ctx
->builder
;
4169 emit_llvmonly_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
4171 const char *icall_name
= rethrow
? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
4172 LLVMValueRef callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
4174 LLVMTypeRef exc_type
= type_to_llvm_type (ctx
, m_class_get_byval_arg (mono_get_exception_class ()));
4177 LLVMTypeRef fun_sig
= LLVMFunctionType1 (LLVMVoidType (), exc_type
, FALSE
);
4179 g_assert (ctx
->cfg
->compile_aot
);
4180 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, icall_name
);
4183 LLVMValueRef args
[2];
4185 args
[0] = convert (ctx
, exc
, exc_type
);
4186 emit_call (ctx
, bb
, &ctx
->builder
, callee
, args
, 1);
4188 LLVMBuildUnreachable (ctx
->builder
);
4190 ctx
->builder
= create_builder (ctx
);
4194 emit_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
4196 MonoMethodSignature
*throw_sig
;
4197 LLVMValueRef callee
, arg
;
4198 const char *icall_name
;
4200 callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
4201 icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4204 throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 1);
4205 throw_sig
->ret
= m_class_get_byval_arg (mono_get_void_class ());
4206 throw_sig
->params
[0] = m_class_get_byval_arg (mono_get_object_class ());
4207 if (ctx
->cfg
->compile_aot
) {
4208 callee
= get_callee (ctx
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
4213 * LLVM doesn't push the exception argument, so we need a different
4216 target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_JIT_ICALL
, rethrow
? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
4218 target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
4220 callee
= emit_jit_callee (ctx
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
), target
);
4223 mono_memory_barrier ();
4224 #if LLVM_API_VERSION < 100
4226 ctx
->module
->rethrow
= callee
;
4228 ctx
->module
->throw_icall
= callee
;
4231 arg
= convert (ctx
, exc
, type_to_llvm_type (ctx
, m_class_get_byval_arg (mono_get_object_class ())));
4232 emit_call (ctx
, bb
, &ctx
->builder
, callee
, &arg
, 1);
4236 emit_resume_eh (EmitContext
*ctx
, MonoBasicBlock
*bb
)
4238 const char *icall_name
= "mono_llvm_resume_exception";
4239 LLVMValueRef callee
;
4241 LLVMTypeRef fun_sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
4243 g_assert (ctx
->cfg
->compile_aot
);
4244 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
4246 emit_call (ctx
, bb
, &ctx
->builder
, callee
, NULL
, 0);
4248 LLVMBuildUnreachable (ctx
->builder
);
4250 ctx
->builder
= create_builder (ctx
);
4254 mono_llvm_emit_clear_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
4256 const char *icall_name
= "mono_llvm_clear_exception";
4258 LLVMTypeRef call_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
4259 LLVMValueRef callee
= NULL
;
4262 if (ctx
->cfg
->compile_aot
) {
4263 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
4265 // FIXME: This is broken.
4266 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
4270 g_assert (builder
&& callee
);
4272 return LLVMBuildCall (builder
, callee
, NULL
, 0, "");
4276 mono_llvm_emit_load_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
4278 const char *icall_name
= "mono_llvm_load_exception";
4280 LLVMTypeRef call_sig
= LLVMFunctionType (ObjRefType (), NULL
, 0, FALSE
);
4281 LLVMValueRef callee
= NULL
;
4284 if (ctx
->cfg
->compile_aot
) {
4285 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
4287 // FIXME: This is broken.
4288 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
4292 g_assert (builder
&& callee
);
4294 return LLVMBuildCall (builder
, callee
, NULL
, 0, icall_name
);
4299 mono_llvm_emit_match_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
, gint32 region_start
, gint32 region_end
)
4301 const char *icall_name
= "mono_llvm_match_exception";
4303 ctx
->builder
= builder
;
4305 LLVMValueRef args
[5];
4306 const int num_args
= G_N_ELEMENTS (args
);
4308 args
[0] = convert (ctx
, get_aotconst (ctx
, MONO_PATCH_INFO_AOT_JIT_INFO
, GINT_TO_POINTER (ctx
->cfg
->method_index
)), IntPtrType ());
4309 args
[1] = LLVMConstInt (LLVMInt32Type (), region_start
, 0);
4310 args
[2] = LLVMConstInt (LLVMInt32Type (), region_end
, 0);
4311 if (ctx
->cfg
->rgctx_var
) {
4312 LLVMValueRef rgctx_alloc
= ctx
->addresses
[ctx
->cfg
->rgctx_var
->dreg
];
4313 g_assert (rgctx_alloc
);
4314 args
[3] = LLVMBuildLoad (builder
, convert (ctx
, rgctx_alloc
, LLVMPointerType (IntPtrType (), 0)), "");
4316 args
[3] = LLVMConstInt (IntPtrType (), 0, 0);
4319 args
[4] = convert (ctx
, ctx
->this_arg
, IntPtrType ());
4321 args
[4] = LLVMConstInt (IntPtrType (), 0, 0);
4323 LLVMTypeRef match_sig
= LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE
);
4324 LLVMValueRef callee
;
4325 g_assert (ctx
->cfg
->compile_aot
);
4326 ctx
->builder
= builder
;
4327 // get_callee expects ctx->builder to be the emitting builder
4328 callee
= get_callee (ctx
, match_sig
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
4330 g_assert (builder
&& callee
);
4332 g_assert (ctx
->ex_var
);
4334 return LLVMBuildCall (builder
, callee
, args
, num_args
, icall_name
);
4337 // FIXME: This won't work because the code-finding makes this
4339 /*#define MONO_PERSONALITY_DEBUG*/
4341 #ifdef MONO_PERSONALITY_DEBUG
4342 static const gboolean use_debug_personality
= TRUE
;
4343 static const char *default_personality_name
= "mono_debug_personality";
4345 static const gboolean use_debug_personality
= FALSE
;
4346 static const char *default_personality_name
= "__gxx_personality_v0";
4350 default_cpp_lpad_exc_signature (void)
4352 static gboolean inited
= FALSE
;
4353 static LLVMTypeRef sig
;
4356 LLVMTypeRef signature
[2];
4357 signature
[0] = LLVMPointerType (LLVMInt8Type (), 0);
4358 signature
[1] = LLVMInt32Type ();
4359 sig
= LLVMStructType (signature
, 2, FALSE
);
4367 get_mono_personality (EmitContext
*ctx
)
4369 LLVMValueRef personality
= NULL
;
4370 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
4372 g_assert (ctx
->cfg
->compile_aot
);
4373 if (!use_debug_personality
) {
4374 personality
= get_intrins_by_name (ctx
, default_personality_name
);
4376 personality
= get_callee (ctx
, personality_type
, MONO_PATCH_INFO_JIT_ICALL
, default_personality_name
);
4379 g_assert (personality
);
4383 static LLVMBasicBlockRef
4384 emit_landing_pad (EmitContext
*ctx
, int group_index
, int group_size
)
4386 MonoCompile
*cfg
= ctx
->cfg
;
4387 LLVMBuilderRef old_builder
= ctx
->builder
;
4388 MonoExceptionClause
*group_start
= cfg
->header
->clauses
+ group_index
;
4390 LLVMBuilderRef lpadBuilder
= create_builder (ctx
);
4391 ctx
->builder
= lpadBuilder
;
4393 MonoBasicBlock
*handler_bb
= cfg
->cil_offset_to_bb
[CLAUSE_START (group_start
)];
4394 g_assert (handler_bb
);
4396 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4397 LLVMValueRef personality
= get_mono_personality (ctx
);
4398 g_assert (personality
);
4400 char *bb_name
= g_strdup_printf ("LPAD%d_BB", group_index
);
4401 LLVMBasicBlockRef lpad_bb
= gen_bb (ctx
, bb_name
);
4403 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
4404 LLVMValueRef landing_pad
= LLVMBuildLandingPad (lpadBuilder
, default_cpp_lpad_exc_signature (), personality
, 0, "");
4405 g_assert (landing_pad
);
4407 LLVMValueRef cast
= LLVMBuildBitCast (lpadBuilder
, ctx
->module
->sentinel_exception
, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
4408 LLVMAddClause (landing_pad
, cast
);
4410 LLVMBasicBlockRef resume_bb
= gen_bb (ctx
, "RESUME_BB");
4411 LLVMBuilderRef resume_builder
= create_builder (ctx
);
4412 ctx
->builder
= resume_builder
;
4413 LLVMPositionBuilderAtEnd (resume_builder
, resume_bb
);
4415 emit_resume_eh (ctx
, handler_bb
);
4418 ctx
->builder
= lpadBuilder
;
4419 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
4421 gboolean finally_only
= TRUE
;
4423 MonoExceptionClause
*group_cursor
= group_start
;
4425 for (int i
= 0; i
< group_size
; i
++) {
4426 if (!(group_cursor
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
|| group_cursor
->flags
& MONO_EXCEPTION_CLAUSE_FAULT
))
4427 finally_only
= FALSE
;
4433 // Handle landing pad inlining
4435 if (!finally_only
) {
4436 // So at each level of the exception stack we will match the exception again.
4437 // During that match, we need to compare against the handler types for the current
4438 // protected region. We send the try start and end so that we can only check against
4439 // handlers for this lexical protected region.
4440 LLVMValueRef match
= mono_llvm_emit_match_exception_call (ctx
, lpadBuilder
, group_start
->try_offset
, group_start
->try_offset
+ group_start
->try_len
);
4442 // if returns -1, resume
4443 LLVMValueRef switch_ins
= LLVMBuildSwitch (lpadBuilder
, match
, resume_bb
, group_size
);
4445 // else move to that target bb
4446 for (int i
= 0; i
< group_size
; i
++) {
4447 MonoExceptionClause
*clause
= group_start
+ i
;
4448 int clause_index
= clause
- cfg
->header
->clauses
;
4449 MonoBasicBlock
*handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
4450 g_assert (handler_bb
);
4451 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4452 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4455 int clause_index
= group_start
- cfg
->header
->clauses
;
4456 MonoBasicBlock
*finally_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
4457 g_assert (finally_bb
);
4459 LLVMBuildBr (ctx
->builder
, ctx
->bblocks
[finally_bb
->block_num
].call_handler_target_bb
);
4462 ctx
->builder
= old_builder
;
4469 emit_llvmonly_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBasicBlockRef cbb
)
4471 int clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
4472 MonoExceptionClause
*clause
= &ctx
->cfg
->header
->clauses
[clause_index
];
4474 // Make exception available to catch blocks
4475 if (!(clause
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
|| clause
->flags
& MONO_EXCEPTION_CLAUSE_FAULT
)) {
4476 LLVMValueRef mono_exc
= mono_llvm_emit_load_exception_call (ctx
, ctx
->builder
);
4478 g_assert (ctx
->ex_var
);
4479 LLVMBuildStore (ctx
->builder
, LLVMBuildBitCast (ctx
->builder
, mono_exc
, ObjRefType (), ""), ctx
->ex_var
);
4481 if (bb
->in_scount
== 1) {
4482 MonoInst
*exvar
= bb
->in_stack
[0];
4483 g_assert (!ctx
->values
[exvar
->dreg
]);
4484 g_assert (ctx
->ex_var
);
4485 ctx
->values
[exvar
->dreg
] = LLVMBuildLoad (ctx
->builder
, ctx
->ex_var
, "save_exception");
4486 emit_volatile_store (ctx
, exvar
->dreg
);
4489 mono_llvm_emit_clear_exception_call (ctx
, ctx
->builder
);
4492 LLVMBuilderRef handler_builder
= create_builder (ctx
);
4493 LLVMBasicBlockRef target_bb
= ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
;
4494 LLVMPositionBuilderAtEnd (handler_builder
, target_bb
);
4496 // Make the handler code end with a jump to cbb
4497 LLVMBuildBr (handler_builder
, cbb
);
4501 emit_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef builder
)
4503 MonoCompile
*cfg
= ctx
->cfg
;
4504 LLVMValueRef
*values
= ctx
->values
;
4505 LLVMModuleRef lmodule
= ctx
->lmodule
;
4506 BBInfo
*bblocks
= ctx
->bblocks
;
4508 LLVMValueRef personality
;
4509 LLVMValueRef landing_pad
;
4510 LLVMBasicBlockRef target_bb
;
4512 static int ti_generator
;
4514 LLVMValueRef type_info
;
4518 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4520 if (cfg
->compile_aot
) {
4521 /* Use a dummy personality function */
4522 personality
= LLVMGetNamedFunction (lmodule
, "mono_personality");
4523 g_assert (personality
);
4525 #if LLVM_API_VERSION > 100
4526 /* Can't cache this as each method is in its own llvm module */
4527 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
4528 personality
= LLVMAddFunction (ctx
->lmodule
, "mono_personality", personality_type
);
4529 mono_llvm_add_func_attr (personality
, LLVM_ATTR_NO_UNWIND
);
4530 LLVMBasicBlockRef entry_bb
= LLVMAppendBasicBlock (personality
, "ENTRY");
4531 LLVMBuilderRef builder2
= LLVMCreateBuilder ();
4532 LLVMPositionBuilderAtEnd (builder2
, entry_bb
);
4533 LLVMBuildRet (builder2
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
));
4534 LLVMDisposeBuilder (builder2
);
4536 g_assert_not_reached ();
4540 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
4542 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
4545 * Create the type info
4547 sprintf (ti_name
, "type_info_%d", ti_generator
);
4550 if (cfg
->compile_aot
) {
4551 /* decode_eh_frame () in aot-runtime.c will decode this */
4552 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4553 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4556 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4558 LLVMSetLinkage (type_info
, LLVMInternalLinkage
);
4560 #if LLVM_API_VERSION > 100
4561 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4562 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4564 g_assert_not_reached ();
4569 LLVMTypeRef members
[2], ret_type
;
4571 members
[0] = i8ptr
;
4572 members
[1] = LLVMInt32Type ();
4573 ret_type
= LLVMStructType (members
, 2, FALSE
);
4575 landing_pad
= LLVMBuildLandingPad (builder
, ret_type
, personality
, 1, "");
4576 LLVMAddClause (landing_pad
, type_info
);
4578 /* Store the exception into the exvar */
4580 LLVMBuildStore (builder
, convert (ctx
, LLVMBuildExtractValue (builder
, landing_pad
, 0, "ex_obj"), ObjRefType ()), ctx
->ex_var
);
4584 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4585 * code expects control to be transferred to this landing pad even in the
4586 * presence of nested clauses. The landing pad needs to branch to the landing
4587 * pads belonging to nested clauses based on the selector value returned by
4588 * the landing pad instruction, which is passed to the landing pad in a
4589 * register by the EH code.
4591 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
4592 g_assert (target_bb
);
4595 * Branch to the correct landing pad
4597 LLVMValueRef ex_selector
= LLVMBuildExtractValue (builder
, landing_pad
, 1, "ex_selector");
4598 LLVMValueRef switch_ins
= LLVMBuildSwitch (builder
, ex_selector
, target_bb
, 0);
4600 for (l
= ctx
->nested_in
[clause_index
]; l
; l
= l
->next
) {
4601 int nesting_clause_index
= GPOINTER_TO_INT (l
->data
);
4602 MonoBasicBlock
*handler_bb
;
4604 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (nesting_clause_index
));
4605 g_assert (handler_bb
);
4607 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4608 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), nesting_clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4611 /* Start a new bblock which CALL_HANDLER can branch to */
4612 ctx
->builder
= builder
= create_builder (ctx
);
4613 LLVMPositionBuilderAtEnd (ctx
->builder
, target_bb
);
4615 ctx
->bblocks
[bb
->block_num
].end_bblock
= target_bb
;
4617 /* Store the exception into the IL level exvar */
4618 if (bb
->in_scount
== 1) {
4619 g_assert (bb
->in_scount
== 1);
4620 exvar
= bb
->in_stack
[0];
4622 // FIXME: This is shared with filter clauses ?
4623 g_assert (!values
[exvar
->dreg
]);
4625 g_assert (ctx
->ex_var
);
4626 values
[exvar
->dreg
] = LLVMBuildLoad (builder
, ctx
->ex_var
, "");
4627 emit_volatile_store (ctx
, exvar
->dreg
);
4630 /* Make normal branches to the start of the clause branch to the new bblock */
4631 bblocks
[bb
->block_num
].bblock
= target_bb
;
4634 //Wasm requires us to canonicalize NaNs.
4636 get_double_const (MonoCompile
*cfg
, double val
)
4639 if (mono_isnan (val
))
4640 *(gint64
*)&val
= 0x7FF8000000000000ll
;
4642 return LLVMConstReal (LLVMDoubleType (), val
);
4646 get_float_const (MonoCompile
*cfg
, float val
)
4649 if (mono_isnan (val
))
4650 *(int *)&val
= 0x7FC00000;
4653 return LLVMConstReal (LLVMFloatType (), val
);
4655 return LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), val
), LLVMDoubleType ());
4659 process_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
4661 MonoCompile
*cfg
= ctx
->cfg
;
4662 MonoMethodSignature
*sig
= ctx
->sig
;
4663 LLVMValueRef method
= ctx
->lmethod
;
4664 LLVMValueRef
*values
= ctx
->values
;
4665 LLVMValueRef
*addresses
= ctx
->addresses
;
4666 LLVMCallInfo
*linfo
= ctx
->linfo
;
4667 BBInfo
*bblocks
= ctx
->bblocks
;
4669 LLVMBasicBlockRef cbb
;
4670 LLVMBuilderRef builder
, starting_builder
;
4671 gboolean has_terminator
;
4673 LLVMValueRef lhs
, rhs
;
4676 cbb
= get_end_bb (ctx
, bb
);
4678 builder
= create_builder (ctx
);
4679 ctx
->builder
= builder
;
4680 LLVMPositionBuilderAtEnd (builder
, cbb
);
4685 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
4686 if (!ctx
->llvm_only
&& !bblocks
[bb
->block_num
].invoke_target
) {
4687 set_failure (ctx
, "handler without invokes");
4692 emit_llvmonly_handler_start (ctx
, bb
, cbb
);
4694 emit_handler_start (ctx
, bb
, builder
);
4697 builder
= ctx
->builder
;
4700 has_terminator
= FALSE
;
4701 starting_builder
= builder
;
4702 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
4703 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
4705 char dname_buf
[128];
4707 emit_dbg_loc (ctx
, builder
, ins
->cil_code
);
4712 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4713 * Start a new bblock.
4714 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4715 * from localloc-ed memory.
4717 if (!cfg
->llvm_only
)
4718 ;//set_failure (ctx, "basic block too long");
4720 if (!ctx
->long_bb_break_var
) {
4721 ctx
->long_bb_break_var
= build_alloca_llvm_type_name (ctx
, LLVMInt32Type (), 0, "long_bb_break");
4722 mono_llvm_build_store (ctx
->alloca_builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), ctx
->long_bb_break_var
, TRUE
, LLVM_BARRIER_NONE
);
4725 cbb
= gen_bb (ctx
, "CONT_LONG_BB");
4726 LLVMBasicBlockRef dummy_bb
= gen_bb (ctx
, "CONT_LONG_BB_DUMMY");
4728 LLVMValueRef load
= mono_llvm_build_load (builder
, ctx
->long_bb_break_var
, "", TRUE
);
4730 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4731 * but llvm doesn't know that, so the branch is not going to be eliminated.
4733 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, load
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
4735 LLVMBuildCondBr (builder
, cmp
, cbb
, dummy_bb
);
4737 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4738 ctx
->builder
= builder
= create_builder (ctx
);
4739 LLVMPositionBuilderAtEnd (builder
, dummy_bb
);
4740 mono_llvm_build_store (builder
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), ctx
->long_bb_break_var
, TRUE
, LLVM_BARRIER_NONE
);
4741 LLVMBuildBr (builder
, cbb
);
4743 ctx
->builder
= builder
= create_builder (ctx
);
4744 LLVMPositionBuilderAtEnd (builder
, cbb
);
4745 ctx
->bblocks
[bb
->block_num
].end_bblock
= cbb
;
4748 emit_dbg_loc (ctx
, builder
, ins
->cil_code
);
4752 /* There could be instructions after a terminator, skip them */
4755 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
4756 sprintf (dname_buf
, "t%d", ins
->dreg
);
4760 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
4761 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
4763 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) && var
->opcode
!= OP_GSHAREDVT_ARG_REGOFFSET
) {
4764 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
4766 /* It is ok for SETRET to have an uninitialized argument */
4767 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
) {
4768 set_failure (ctx
, "sreg1");
4771 lhs
= values
[ins
->sreg1
];
4777 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
4778 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
4779 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
4780 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
4782 if (!values
[ins
->sreg2
]) {
4783 set_failure (ctx
, "sreg2");
4786 rhs
= values
[ins
->sreg2
];
4792 //mono_print_ins (ins);
4793 switch (ins
->opcode
) {
4796 case OP_LIVERANGE_START
:
4797 case OP_LIVERANGE_END
:
4800 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
4803 #if TARGET_SIZEOF_VOID_P == 4
4804 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4806 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
4810 values
[ins
->dreg
] = get_double_const (cfg
, *(double*)ins
->inst_p0
);
4813 values
[ins
->dreg
] = get_float_const (cfg
, *(float*)ins
->inst_p0
);
4815 case OP_DUMMY_ICONST
:
4816 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4818 case OP_DUMMY_I8CONST
:
4819 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
4821 case OP_DUMMY_R8CONST
:
4822 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), 0.0f
);
4825 LLVMBasicBlockRef target_bb
= get_bb (ctx
, ins
->inst_target_bb
);
4826 LLVMBuildBr (builder
, target_bb
);
4827 has_terminator
= TRUE
;
4834 LLVMBasicBlockRef new_bb
;
4835 LLVMBuilderRef new_builder
;
4837 // The default branch is already handled
4838 // FIXME: Handle it here
4840 /* Start new bblock */
4841 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
4842 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
4844 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4845 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
4846 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
4847 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
4849 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
4852 new_builder
= create_builder (ctx
);
4853 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
4854 LLVMBuildUnreachable (new_builder
);
4856 has_terminator
= TRUE
;
4857 g_assert (!ins
->next
);
4863 switch (linfo
->ret
.storage
) {
4864 case LLVMArgVtypeInReg
: {
4865 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4866 LLVMValueRef val
, addr
, retval
;
4869 retval
= LLVMGetUndef (ret_type
);
4871 if (!addresses
[ins
->sreg1
]) {
4873 * The return type is an LLVM vector type, have to convert between it and the
4874 * real return type which is a struct type.
4876 g_assert (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (sig
->ret
)));
4877 /* Convert to 2xi64 first */
4878 val
= LLVMBuildBitCast (builder
, values
[ins
->sreg1
], LLVMVectorType (IntPtrType (), 2), "");
4880 for (i
= 0; i
< 2; ++i
) {
4881 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4882 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildExtractElement (builder
, val
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), ""), i
, "");
4884 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4888 addr
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), "");
4889 for (i
= 0; i
< 2; ++i
) {
4890 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4891 LLVMValueRef indexes
[2], part_addr
;
4893 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4894 indexes
[1] = LLVMConstInt (LLVMInt32Type (), i
, FALSE
);
4895 part_addr
= LLVMBuildGEP (builder
, addr
, indexes
, 2, "");
4897 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildLoad (builder
, part_addr
, ""), i
, "");
4899 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4903 LLVMBuildRet (builder
, retval
);
4906 case LLVMArgVtypeAsScalar
: {
4907 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4908 LLVMValueRef retval
;
4910 g_assert (addresses
[ins
->sreg1
]);
4912 retval
= LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), ""), "");
4913 LLVMBuildRet (builder
, retval
);
4916 case LLVMArgVtypeByVal
: {
4917 LLVMValueRef retval
;
4919 g_assert (addresses
[ins
->sreg1
]);
4920 retval
= LLVMBuildLoad (builder
, addresses
[ins
->sreg1
], "");
4921 LLVMBuildRet (builder
, retval
);
4924 case LLVMArgVtypeByRef
: {
4925 LLVMBuildRetVoid (builder
);
4928 case LLVMArgGsharedvtFixed
: {
4929 LLVMTypeRef ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
4930 /* The return value is in lhs, need to store to the vret argument */
4931 /* sreg1 might not be set */
4933 g_assert (cfg
->vret_addr
);
4934 g_assert (values
[cfg
->vret_addr
->dreg
]);
4935 LLVMBuildStore (builder
, convert (ctx
, lhs
, ret_type
), convert (ctx
, values
[cfg
->vret_addr
->dreg
], LLVMPointerType (ret_type
, 0)));
4937 LLVMBuildRetVoid (builder
);
4940 case LLVMArgGsharedvtFixedVtype
: {
4942 LLVMBuildRetVoid (builder
);
4945 case LLVMArgGsharedvtVariable
: {
4947 LLVMBuildRetVoid (builder
);
4950 case LLVMArgVtypeRetAddr
: {
4951 LLVMBuildRetVoid (builder
);
4954 case LLVMArgAsIArgs
:
4955 case LLVMArgFpStruct
: {
4956 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4957 LLVMValueRef retval
;
4959 g_assert (addresses
[ins
->sreg1
]);
4960 retval
= LLVMBuildLoad (builder
, convert (ctx
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0)), "");
4961 LLVMBuildRet (builder
, retval
);
4965 case LLVMArgNormal
: {
4966 if (!lhs
|| ctx
->is_dead
[ins
->sreg1
]) {
4968 * The method did not set its return value, probably because it
4969 * ends with a throw.
4972 LLVMBuildRetVoid (builder
);
4974 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
4976 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
4978 has_terminator
= TRUE
;
4982 g_assert_not_reached ();
4991 case OP_ICOMPARE_IMM
:
4992 case OP_LCOMPARE_IMM
:
4993 case OP_COMPARE_IMM
: {
4995 LLVMValueRef cmp
, args
[16];
4996 gboolean likely
= (ins
->flags
& MONO_INST_LIKELY
) != 0;
4997 gboolean unlikely
= FALSE
;
4999 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
5000 if (ins
->next
->inst_false_bb
->out_of_line
)
5002 else if (ins
->next
->inst_true_bb
->out_of_line
)
5006 if (ins
->next
->opcode
== OP_NOP
)
5009 if (ins
->next
->opcode
== OP_BR
)
5010 /* The comparison result is not needed */
5013 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
5015 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
5016 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
5017 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
5019 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
5020 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5021 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
5023 if (ins
->opcode
== OP_LCOMPARE
) {
5024 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5025 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
5027 if (ins
->opcode
== OP_ICOMPARE
) {
5028 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
5029 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
5033 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
5034 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
5035 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
5036 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
5039 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
5040 if (ins
->opcode
== OP_FCOMPARE
) {
5041 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
5042 } else if (ins
->opcode
== OP_RCOMPARE
) {
5043 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
5044 } else if (ins
->opcode
== OP_COMPARE_IMM
) {
5045 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& ins
->inst_imm
== 0)
5046 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), "");
5048 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
5049 } else if (ins
->opcode
== OP_LCOMPARE_IMM
) {
5050 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
5052 else if (ins
->opcode
== OP_COMPARE
) {
5053 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& LLVMTypeOf (lhs
) == LLVMTypeOf (rhs
))
5054 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
5056 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
5058 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
5060 if (likely
|| unlikely
) {
5062 args
[1] = LLVMConstInt (LLVMInt1Type (), likely
? 1 : 0, FALSE
);
5063 cmp
= LLVMBuildCall (ctx
->builder
, get_intrins (ctx
, INTRINS_EXPECT_I1
), args
, 2, "");
5066 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
5067 if (ins
->next
->inst_true_bb
== ins
->next
->inst_false_bb
) {
5069 * If the target bb contains PHI instructions, LLVM requires
5070 * two PHI entries for this bblock, while we only generate one.
5071 * So convert this to an unconditional bblock. (bxc #171).
5073 LLVMBuildBr (builder
, get_bb (ctx
, ins
->next
->inst_true_bb
));
5075 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
5077 has_terminator
= TRUE
;
5078 } else if (MONO_IS_SETCC (ins
->next
)) {
5079 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
5081 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
5083 /* Add stores for volatile variables */
5084 emit_volatile_store (ctx
, ins
->next
->dreg
);
5085 } else if (MONO_IS_COND_EXC (ins
->next
)) {
5086 emit_cond_system_exception (ctx
, bb
, (const char*)ins
->next
->inst_p1
, cmp
);
5089 builder
= ctx
->builder
;
5091 set_failure (ctx
, "next");
5109 rel
= mono_opcode_to_cond (ins
->opcode
);
5111 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
5112 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
5124 rel
= mono_opcode_to_cond (ins
->opcode
);
5126 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
5127 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
5135 gboolean empty
= TRUE
;
5137 /* Check that all input bblocks really branch to us */
5138 for (i
= 0; i
< bb
->in_count
; ++i
) {
5139 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
5140 ins
->inst_phi_args
[i
+ 1] = -1;
5146 /* LLVM doesn't like phi instructions with zero operands */
5147 ctx
->is_dead
[ins
->dreg
] = TRUE
;
5151 /* Created earlier, insert it now */
5152 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
5154 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
5155 int sreg1
= ins
->inst_phi_args
[i
+ 1];
5159 * Count the number of times the incoming bblock branches to us,
5160 * since llvm requires a separate entry for each.
5162 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
5163 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
5166 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
5167 if (switch_ins
->inst_many_bb
[j
] == bb
)
5174 /* Remember for later */
5175 for (j
= 0; j
< count
; ++j
) {
5176 PhiNode
*node
= (PhiNode
*)mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
5179 node
->in_bb
= bb
->in_bb
[i
];
5181 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
);
5191 values
[ins
->dreg
] = lhs
;
5195 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
5198 values
[ins
->dreg
] = lhs
;
5200 if (var
&& m_class_get_byval_arg (var
->klass
)->type
== MONO_TYPE_R4
) {
5202 * This is added by the spilling pass in case of the JIT,
5203 * but we have to do it ourselves.
5205 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
5209 case OP_MOVE_F_TO_I4
: {
5210 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), ""), LLVMInt32Type (), "");
5213 case OP_MOVE_I4_TO_F
: {
5214 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, LLVMBuildBitCast (builder
, lhs
, LLVMFloatType (), ""), LLVMDoubleType (), "");
5217 case OP_MOVE_F_TO_I8
: {
5218 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMInt64Type (), "");
5221 case OP_MOVE_I8_TO_F
: {
5222 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMDoubleType (), "");
5255 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5256 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5258 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, rhs
);
5261 builder
= ctx
->builder
;
5263 switch (ins
->opcode
) {
5266 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
5270 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
5274 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
5278 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
5282 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
5286 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
5290 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
5294 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
5298 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
5302 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
5306 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
5310 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
5314 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
5318 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
5322 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
5325 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
5328 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
5332 g_assert_not_reached ();
5339 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
5340 rhs
= convert (ctx
, rhs
, LLVMFloatType ());
5341 switch (ins
->opcode
) {
5343 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
5346 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
5349 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
5352 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
5355 g_assert_not_reached ();
5364 case OP_IREM_UN_IMM
:
5366 case OP_IDIV_UN_IMM
:
5372 case OP_ISHR_UN_IMM
:
5382 case OP_LSHR_UN_IMM
:
5388 case OP_SHR_UN_IMM
: {
5391 if (spec
[MONO_INST_SRC1
] == 'l') {
5392 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
5394 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
5397 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, imm
);
5400 builder
= ctx
->builder
;
5402 #if TARGET_SIZEOF_VOID_P == 4
5403 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
5404 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
5407 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
5408 lhs
= convert (ctx
, lhs
, IntPtrType ());
5409 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
5410 switch (ins
->opcode
) {
5414 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
5418 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
5423 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
5427 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
5429 case OP_IDIV_UN_IMM
:
5430 case OP_LDIV_UN_IMM
:
5431 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
5435 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
5437 case OP_IREM_UN_IMM
:
5438 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
5443 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
5447 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
5451 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
5455 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
5458 if (TARGET_SIZEOF_VOID_P
== 8) {
5459 /* The IL is not regular */
5460 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5461 imm
= convert (ctx
, imm
, LLVMInt64Type ());
5463 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
5468 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
5470 case OP_ISHR_UN_IMM
:
5471 /* This is used to implement conv.u4, so the lhs could be an i8 */
5472 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
5473 imm
= convert (ctx
, imm
, LLVMInt32Type ());
5474 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
5476 case OP_LSHR_UN_IMM
:
5478 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
5481 g_assert_not_reached ();
5486 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
5489 if (LLVMTypeOf (lhs
) != LLVMInt64Type ())
5490 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5491 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
5494 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
5495 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
5498 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
5499 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMFloatType (), 0.0), lhs
, dname
);
5502 guint32 v
= 0xffffffff;
5503 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
5507 if (LLVMTypeOf (lhs
) != LLVMInt64Type ())
5508 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5509 guint64 v
= 0xffffffffffffffffLL
;
5510 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
5513 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5515 LLVMValueRef v1
, v2
;
5517 rhs
= LLVMBuildSExt (builder
, convert (ctx
, rhs
, LLVMInt32Type ()), LLVMInt64Type (), "");
5519 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ((unsigned long long)1 << ins
->backend
.shift_amount
), FALSE
), "");
5520 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
5521 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
5526 case OP_ICONV_TO_I1
:
5527 case OP_ICONV_TO_I2
:
5528 case OP_ICONV_TO_I4
:
5529 case OP_ICONV_TO_U1
:
5530 case OP_ICONV_TO_U2
:
5531 case OP_ICONV_TO_U4
:
5532 case OP_LCONV_TO_I1
:
5533 case OP_LCONV_TO_I2
:
5534 case OP_LCONV_TO_U1
:
5535 case OP_LCONV_TO_U2
:
5536 case OP_LCONV_TO_U4
: {
5539 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
);
5541 /* Have to do two casts since our vregs have type int */
5542 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
5544 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
5546 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
5549 case OP_ICONV_TO_I8
:
5550 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
5552 case OP_ICONV_TO_U8
:
5553 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
5555 case OP_FCONV_TO_I4
:
5556 case OP_RCONV_TO_I4
:
5557 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
5559 case OP_FCONV_TO_I1
:
5560 case OP_RCONV_TO_I1
:
5561 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
5563 case OP_FCONV_TO_U1
:
5564 case OP_RCONV_TO_U1
:
5565 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildTrunc (builder
, LLVMBuildFPToUI (builder
, lhs
, IntPtrType (), dname
), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5567 case OP_FCONV_TO_I2
:
5568 case OP_RCONV_TO_I2
:
5569 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
5571 case OP_FCONV_TO_U2
:
5572 case OP_RCONV_TO_U2
:
5573 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
5575 case OP_RCONV_TO_U4
:
5576 values
[ins
->dreg
] = LLVMBuildFPToUI (builder
, lhs
, LLVMInt32Type (), dname
);
5578 case OP_FCONV_TO_I8
:
5579 case OP_RCONV_TO_I8
:
5580 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
5583 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
5585 case OP_ICONV_TO_R8
:
5586 case OP_LCONV_TO_R8
:
5587 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
5589 case OP_ICONV_TO_R_UN
:
5590 case OP_LCONV_TO_R_UN
:
5591 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
5593 #if TARGET_SIZEOF_VOID_P == 4
5596 case OP_LCONV_TO_I4
:
5597 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5599 case OP_ICONV_TO_R4
:
5600 case OP_LCONV_TO_R4
:
5601 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
5603 values
[ins
->dreg
] = v
;
5605 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5607 case OP_FCONV_TO_R4
:
5608 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
5610 values
[ins
->dreg
] = v
;
5612 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5614 case OP_RCONV_TO_R8
:
5615 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, lhs
, LLVMDoubleType (), dname
);
5617 case OP_RCONV_TO_R4
:
5618 values
[ins
->dreg
] = lhs
;
5621 values
[ins
->dreg
] = LLVMBuildSExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5624 values
[ins
->dreg
] = LLVMBuildZExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5627 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5629 case OP_LOCALLOC_IMM
: {
5632 guint32 size
= ins
->inst_imm
;
5633 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
5635 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
5637 if (ins
->flags
& MONO_INST_INIT
) {
5638 LLVMValueRef args
[5];
5641 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5642 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
5643 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5644 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5645 LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_MEMSET
), args
, 5, "");
5648 values
[ins
->dreg
] = v
;
5652 LLVMValueRef v
, size
;
5654 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
), "");
5656 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
5658 if (ins
->flags
& MONO_INST_INIT
) {
5659 LLVMValueRef args
[5];
5662 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5664 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5665 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5666 LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_MEMSET
), args
, 5, "");
5668 values
[ins
->dreg
] = v
;
5672 case OP_LOADI1_MEMBASE
:
5673 case OP_LOADU1_MEMBASE
:
5674 case OP_LOADI2_MEMBASE
:
5675 case OP_LOADU2_MEMBASE
:
5676 case OP_LOADI4_MEMBASE
:
5677 case OP_LOADU4_MEMBASE
:
5678 case OP_LOADI8_MEMBASE
:
5679 case OP_LOADR4_MEMBASE
:
5680 case OP_LOADR8_MEMBASE
:
5681 case OP_LOAD_MEMBASE
:
5689 LLVMValueRef base
, index
, addr
;
5691 gboolean sext
= FALSE
, zext
= FALSE
;
5692 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
5694 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5699 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
)) {
5700 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
5706 if (ins
->inst_offset
== 0) {
5708 } else if (ins
->inst_offset
% size
!= 0) {
5709 /* Unaligned load */
5710 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5711 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5713 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5714 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5718 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
5720 values
[ins
->dreg
] = emit_load_general (ctx
, bb
, &builder
, size
, addr
, base
, dname
, is_volatile
, LLVM_BARRIER_NONE
);
5722 if (!is_volatile
&& (ins
->flags
& MONO_INST_INVARIANT_LOAD
)) {
5724 * These will signal LLVM that these loads do not alias any stores, and
5725 * they can't fail, allowing them to be hoisted out of loops.
5727 set_invariant_load_flag (values
[ins
->dreg
]);
5728 #if LLVM_API_VERSION < 100
5729 set_metadata_flag (values
[ins
->dreg
], "mono.nofail.load");
5734 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5736 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5737 else if (!cfg
->r4fp
&& ins
->opcode
== OP_LOADR4_MEMBASE
)
5738 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
5742 case OP_STOREI1_MEMBASE_REG
:
5743 case OP_STOREI2_MEMBASE_REG
:
5744 case OP_STOREI4_MEMBASE_REG
:
5745 case OP_STOREI8_MEMBASE_REG
:
5746 case OP_STORER4_MEMBASE_REG
:
5747 case OP_STORER8_MEMBASE_REG
:
5748 case OP_STORE_MEMBASE_REG
: {
5750 LLVMValueRef index
, addr
, base
;
5752 gboolean sext
= FALSE
, zext
= FALSE
;
5753 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
5755 if (!values
[ins
->inst_destbasereg
]) {
5756 set_failure (ctx
, "inst_destbasereg");
5760 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5762 base
= values
[ins
->inst_destbasereg
];
5763 if (ins
->inst_offset
% size
!= 0) {
5764 /* Unaligned store */
5765 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5766 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5768 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5769 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5771 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5775 case OP_STOREI1_MEMBASE_IMM
:
5776 case OP_STOREI2_MEMBASE_IMM
:
5777 case OP_STOREI4_MEMBASE_IMM
:
5778 case OP_STOREI8_MEMBASE_IMM
:
5779 case OP_STORE_MEMBASE_IMM
: {
5781 LLVMValueRef index
, addr
, base
;
5783 gboolean sext
= FALSE
, zext
= FALSE
;
5784 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
5786 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5788 base
= values
[ins
->inst_destbasereg
];
5789 if (ins
->inst_offset
% size
!= 0) {
5790 /* Unaligned store */
5791 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5792 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5794 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5795 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5797 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5802 emit_load_general (ctx
, bb
, &builder
, TARGET_SIZEOF_VOID_P
, convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), lhs
, "", TRUE
, LLVM_BARRIER_NONE
);
5804 case OP_OUTARG_VTRETADDR
:
5812 case OP_VOIDCALL_MEMBASE
:
5813 case OP_CALL_MEMBASE
:
5814 case OP_LCALL_MEMBASE
:
5815 case OP_FCALL_MEMBASE
:
5816 case OP_RCALL_MEMBASE
:
5817 case OP_VCALL_MEMBASE
:
5818 case OP_VOIDCALL_REG
:
5823 case OP_VCALL_REG
: {
5824 process_call (ctx
, bb
, &builder
, ins
);
5829 LLVMValueRef indexes
[2];
5830 MonoJumpInfo
*tmp_ji
, *ji
;
5831 LLVMValueRef got_entry_addr
;
5835 * FIXME: Can't allocate from the cfg mempool since that is freed if
5836 * the LLVM compile fails.
5838 tmp_ji
= g_new0 (MonoJumpInfo
, 1);
5839 tmp_ji
->type
= (MonoJumpInfoType
)ins
->inst_c1
;
5840 tmp_ji
->data
.target
= ins
->inst_p0
;
5842 ji
= mono_aot_patch_info_dup (tmp_ji
);
5845 if (ji
->type
== MONO_PATCH_INFO_ICALL_ADDR
) {
5846 char *symbol
= mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL
, ji
->data
.target
);
5849 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5850 * resolvable at runtime using dlsym ().
5853 values
[ins
->dreg
] = LLVMConstInt (IntPtrType (), 0, FALSE
);
5858 ji
->next
= cfg
->patch_info
;
5859 cfg
->patch_info
= ji
;
5861 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5862 got_offset
= compute_aot_got_offset (ctx
->module
, cfg
->patch_info
, NULL
);
5864 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
5865 if (!mono_aot_is_shared_got_offset (got_offset
)) {
5866 //mono_print_ji (ji);
5868 ctx
->cfg
->got_access_count
++;
5871 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5872 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
5873 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
5875 name
= get_aotconst_name (ji
->type
, ji
->data
.target
, got_offset
);
5876 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, name
);
5878 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5879 if (!cfg
->llvm_only
|| mono_aot_is_shared_got_offset (got_offset
))
5880 set_invariant_load_flag (values
[ins
->dreg
]);
5883 case OP_NOT_REACHED
:
5884 LLVMBuildUnreachable (builder
);
5885 has_terminator
= TRUE
;
5886 g_assert (bb
->block_num
< cfg
->max_block_num
);
5887 ctx
->unreachable
[bb
->block_num
] = TRUE
;
5888 /* Might have instructions after this */
5890 MonoInst
*next
= ins
->next
;
5892 * FIXME: If later code uses the regs defined by these instructions,
5893 * compilation will fail.
5895 MONO_DELETE_INS (bb
, next
);
5899 MonoInst
*var
= ins
->inst_i0
;
5901 if (var
->opcode
== OP_VTARG_ADDR
) {
5902 /* The variable contains the vtype address */
5903 values
[ins
->dreg
] = values
[var
->dreg
];
5904 } else if (var
->opcode
== OP_GSHAREDVT_LOCAL
) {
5905 values
[ins
->dreg
] = emit_gsharedvt_ldaddr (ctx
, var
->dreg
);
5907 values
[ins
->dreg
] = addresses
[var
->dreg
];
5912 LLVMValueRef args
[1];
5914 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5915 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_SIN
), args
, 1, dname
);
5919 LLVMValueRef args
[1];
5921 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5922 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_SINF
), args
, 1, dname
);
5926 LLVMValueRef args
[1];
5928 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5929 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_COS
), args
, 1, dname
);
5933 LLVMValueRef args
[1];
5935 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5936 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_COSF
), args
, 1, dname
);
5940 LLVMValueRef args
[1];
5942 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5943 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_SQRT
), args
, 1, dname
);
5947 LLVMValueRef args
[1];
5949 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5950 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_SQRTF
), args
, 1, dname
);
5954 LLVMValueRef args
[1];
5956 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5957 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_FABS
), args
, 1, dname
);
5961 LLVMValueRef args
[1];
5964 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5965 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_ABSF
), args
, 1, dname
);
5967 /* llvm.fabs not supported on all platforms */
5968 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5969 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_FABS
), args
, 1, dname
);
5970 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
5975 LLVMValueRef args
[2];
5977 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5978 args
[1] = convert (ctx
, rhs
, LLVMFloatType ());
5979 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_POWF
), args
, 2, dname
);
5994 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5995 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5997 switch (ins
->opcode
) {
6000 v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
6004 v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
6008 v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
6012 v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
6015 v
= LLVMBuildFCmp (builder
, LLVMRealUGE
, lhs
, rhs
, "");
6018 g_assert_not_reached ();
6021 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
6026 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
6027 * hack is necessary (for now).
6030 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
6032 #define ARM64_ATOMIC_FENCE_FIX
6035 case OP_ATOMIC_EXCHANGE_I4
:
6036 case OP_ATOMIC_EXCHANGE_I8
: {
6037 LLVMValueRef args
[2];
6040 if (ins
->opcode
== OP_ATOMIC_EXCHANGE_I4
)
6041 t
= LLVMInt32Type ();
6043 t
= LLVMInt64Type ();
6045 g_assert (ins
->inst_offset
== 0);
6047 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
6048 args
[1] = convert (ctx
, rhs
, t
);
6050 ARM64_ATOMIC_FENCE_FIX
;
6051 values
[ins
->dreg
] = mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_XCHG
, args
[0], args
[1]);
6052 ARM64_ATOMIC_FENCE_FIX
;
6055 case OP_ATOMIC_ADD_I4
:
6056 case OP_ATOMIC_ADD_I8
: {
6057 LLVMValueRef args
[2];
6060 if (ins
->opcode
== OP_ATOMIC_ADD_I4
)
6061 t
= LLVMInt32Type ();
6063 t
= LLVMInt64Type ();
6065 g_assert (ins
->inst_offset
== 0);
6067 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
6068 args
[1] = convert (ctx
, rhs
, t
);
6069 ARM64_ATOMIC_FENCE_FIX
;
6070 values
[ins
->dreg
] = LLVMBuildAdd (builder
, mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_ADD
, args
[0], args
[1]), args
[1], dname
);
6071 ARM64_ATOMIC_FENCE_FIX
;
6074 case OP_ATOMIC_CAS_I4
:
6075 case OP_ATOMIC_CAS_I8
: {
6076 LLVMValueRef args
[3], val
;
6079 if (ins
->opcode
== OP_ATOMIC_CAS_I4
)
6080 t
= LLVMInt32Type ();
6082 t
= LLVMInt64Type ();
6084 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
6086 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
6088 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
6089 ARM64_ATOMIC_FENCE_FIX
;
6090 val
= mono_llvm_build_cmpxchg (builder
, args
[0], args
[1], args
[2]);
6091 ARM64_ATOMIC_FENCE_FIX
;
6092 /* cmpxchg returns a pair */
6093 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, "");
6096 case OP_MEMORY_BARRIER
: {
6097 mono_llvm_build_fence (builder
, (BarrierKind
) ins
->backend
.memory_barrier_kind
);
6100 case OP_ATOMIC_LOAD_I1
:
6101 case OP_ATOMIC_LOAD_I2
:
6102 case OP_ATOMIC_LOAD_I4
:
6103 case OP_ATOMIC_LOAD_I8
:
6104 case OP_ATOMIC_LOAD_U1
:
6105 case OP_ATOMIC_LOAD_U2
:
6106 case OP_ATOMIC_LOAD_U4
:
6107 case OP_ATOMIC_LOAD_U8
:
6108 case OP_ATOMIC_LOAD_R4
:
6109 case OP_ATOMIC_LOAD_R8
: {
6110 #if LLVM_API_VERSION > 100
6112 gboolean sext
, zext
;
6114 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
6115 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
6116 LLVMValueRef index
, addr
;
6118 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
6123 if (ins
->inst_offset
!= 0) {
6124 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
6125 addr
= LLVMBuildGEP (builder
, convert (ctx
, lhs
, LLVMPointerType (t
, 0)), &index
, 1, "");
6130 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
6132 ARM64_ATOMIC_FENCE_FIX
;
6133 values
[ins
->dreg
] = emit_load_general (ctx
, bb
, &builder
, size
, addr
, lhs
, dname
, is_volatile
, barrier
);
6134 ARM64_ATOMIC_FENCE_FIX
;
6137 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
6139 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
6142 set_failure (ctx
, "atomic mono.load intrinsic");
6146 case OP_ATOMIC_STORE_I1
:
6147 case OP_ATOMIC_STORE_I2
:
6148 case OP_ATOMIC_STORE_I4
:
6149 case OP_ATOMIC_STORE_I8
:
6150 case OP_ATOMIC_STORE_U1
:
6151 case OP_ATOMIC_STORE_U2
:
6152 case OP_ATOMIC_STORE_U4
:
6153 case OP_ATOMIC_STORE_U8
:
6154 case OP_ATOMIC_STORE_R4
:
6155 case OP_ATOMIC_STORE_R8
: {
6157 gboolean sext
, zext
;
6159 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
6160 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
6161 LLVMValueRef index
, addr
, value
, base
;
6163 #if LLVM_API_VERSION < 100
6164 if (!cfg
->llvm_only
) {
6165 set_failure (ctx
, "atomic mono.store intrinsic");
6170 if (!values
[ins
->inst_destbasereg
]) {
6171 set_failure (ctx
, "inst_destbasereg");
6175 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
6177 base
= values
[ins
->inst_destbasereg
];
6178 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
6179 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
6180 value
= convert (ctx
, values
[ins
->sreg1
], t
);
6182 ARM64_ATOMIC_FENCE_FIX
;
6183 emit_store_general (ctx
, bb
, &builder
, size
, value
, addr
, base
, is_volatile
, barrier
);
6184 ARM64_ATOMIC_FENCE_FIX
;
6187 case OP_RELAXED_NOP
: {
6188 #if defined(TARGET_AMD64) || defined(TARGET_X86)
6189 emit_call (ctx
, bb
, &builder
, get_intrins_by_name (ctx
, "llvm.x86.sse2.pause"), NULL
, 0);
6196 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
6198 // 257 == FS segment register
6199 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
6201 // 256 == GS segment register
6202 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
6205 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
6206 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
6207 /* See mono_amd64_emit_tls_get () */
6208 int offset
= mono_amd64_get_tls_gs_offset () + (ins
->inst_offset
* 8);
6210 // 256 == GS segment register
6211 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
6212 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), offset
, TRUE
), ptrtype
, ""), "");
6214 set_failure (ctx
, "opcode tls-get");
6220 case OP_GC_SAFE_POINT
: {
6221 LLVMValueRef val
, cmp
, callee
;
6222 LLVMBasicBlockRef poll_bb
, cont_bb
;
6223 LLVMValueRef args
[2];
6224 static LLVMTypeRef sig
;
6225 const char *icall_name
= "mono_threads_state_poll";
6228 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
6232 * mono_threads_state_poll ();
6233 * FIXME: Use a preserveall wrapper
6235 val
= mono_llvm_build_load (builder
, convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
6236 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, val
, LLVMConstNull (LLVMTypeOf (val
)), "");
6237 poll_bb
= gen_bb (ctx
, "POLL_BB");
6238 cont_bb
= gen_bb (ctx
, "CONT_BB");
6241 args
[1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
6242 cmp
= LLVMBuildCall (ctx
->builder
, get_intrins (ctx
, INTRINS_EXPECT_I1
), args
, 2, "");
6244 LLVMBuildCondBr (builder
, cmp
, cont_bb
, poll_bb
);
6246 ctx
->builder
= builder
= create_builder (ctx
);
6247 LLVMPositionBuilderAtEnd (builder
, poll_bb
);
6249 if (ctx
->cfg
->compile_aot
) {
6250 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
6252 gpointer target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_JIT_ICALL
, icall_name
);
6253 callee
= emit_jit_callee (ctx
, icall_name
, sig
, target
);
6255 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
6256 LLVMBuildBr (builder
, cont_bb
);
6258 ctx
->builder
= builder
= create_builder (ctx
);
6259 LLVMPositionBuilderAtEnd (builder
, cont_bb
);
6260 ctx
->bblocks
[bb
->block_num
].end_bblock
= cont_bb
;
6268 case OP_IADD_OVF_UN
:
6270 case OP_ISUB_OVF_UN
:
6272 case OP_IMUL_OVF_UN
:
6274 case OP_LADD_OVF_UN
:
6276 case OP_LSUB_OVF_UN
:
6278 case OP_LMUL_OVF_UN
:
6280 LLVMValueRef args
[2], val
, ovf
, func
;
6282 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
6283 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
6284 func
= get_intrins_by_name (ctx
, ovf_op_to_intrins (ins
->opcode
));
6286 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
6287 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
6288 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
6289 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
6292 builder
= ctx
->builder
;
6298 * We currently model them using arrays. Promotion to local vregs is
6299 * disabled for them in mono_handle_global_vregs () in the LLVM case,
6300 * so we always have an entry in cfg->varinfo for them.
6301 * FIXME: Is this needed ?
6304 MonoClass
*klass
= ins
->klass
;
6305 LLVMValueRef args
[5];
6309 set_failure (ctx
, "!klass");
6313 if (!addresses
[ins
->dreg
])
6314 addresses
[ins
->dreg
] = build_alloca (ctx
, m_class_get_byval_arg (klass
));
6315 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
6316 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
6317 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
6319 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6320 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
6321 LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_MEMSET
), args
, 5, "");
6324 case OP_DUMMY_VZERO
:
6327 case OP_STOREV_MEMBASE
:
6328 case OP_LOADV_MEMBASE
:
6330 MonoClass
*klass
= ins
->klass
;
6331 LLVMValueRef src
= NULL
, dst
, args
[5];
6332 gboolean done
= FALSE
;
6336 set_failure (ctx
, "!klass");
6340 if (mini_is_gsharedvt_klass (klass
)) {
6342 set_failure (ctx
, "gsharedvt");
6346 switch (ins
->opcode
) {
6347 case OP_STOREV_MEMBASE
:
6348 if (cfg
->gen_write_barriers
&& m_class_has_references (klass
) && ins
->inst_destbasereg
!= cfg
->frame_reg
&&
6349 LLVMGetInstructionOpcode (values
[ins
->inst_destbasereg
]) != LLVMAlloca
) {
6350 /* Decomposed earlier */
6351 g_assert_not_reached ();
6354 if (!addresses
[ins
->sreg1
]) {
6356 g_assert (values
[ins
->sreg1
]);
6357 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (type_to_llvm_type (ctx
, m_class_get_byval_arg (klass
)), 0));
6358 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
6361 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
6362 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
6365 case OP_LOADV_MEMBASE
:
6366 if (!addresses
[ins
->dreg
])
6367 addresses
[ins
->dreg
] = build_alloca (ctx
, m_class_get_byval_arg (klass
));
6368 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
6369 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
6372 if (!addresses
[ins
->sreg1
])
6373 addresses
[ins
->sreg1
] = build_alloca (ctx
, m_class_get_byval_arg (klass
));
6374 if (!addresses
[ins
->dreg
])
6375 addresses
[ins
->dreg
] = build_alloca (ctx
, m_class_get_byval_arg (klass
));
6376 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
6377 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
6380 g_assert_not_reached ();
6390 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
6391 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6393 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6394 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
6395 LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_MEMCPY
), args
, 5, "");
6398 case OP_LLVM_OUTARG_VT
: {
6399 LLVMArgInfo
*ainfo
= (LLVMArgInfo
*)ins
->inst_p0
;
6400 MonoType
*t
= mini_get_underlying_type (ins
->inst_vtype
);
6402 if (ainfo
->storage
== LLVMArgGsharedvtVariable
) {
6403 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
6405 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
6406 addresses
[ins
->dreg
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), LLVMPointerType (IntPtrType (), 0));
6408 g_assert (addresses
[ins
->sreg1
]);
6409 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
6411 } else if (ainfo
->storage
== LLVMArgGsharedvtFixed
) {
6412 if (!addresses
[ins
->sreg1
]) {
6413 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
6414 g_assert (values
[ins
->sreg1
]);
6416 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (LLVMTypeOf (addresses
[ins
->sreg1
]))), addresses
[ins
->sreg1
]);
6417 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
6419 if (!addresses
[ins
->sreg1
]) {
6420 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
6421 g_assert (values
[ins
->sreg1
]);
6422 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, t
)), addresses
[ins
->sreg1
]);
6423 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
6424 } else if (values
[ins
->sreg1
] == addresses
[ins
->sreg1
]) {
6425 /* LLVMArgVtypeByRef, have to make a copy */
6426 addresses
[ins
->dreg
] = build_alloca (ctx
, t
);
6427 LLVMValueRef v
= LLVMBuildLoad (builder
, addresses
[ins
->sreg1
], "");
6428 LLVMBuildStore (builder
, convert (ctx
, v
, type_to_llvm_type (ctx
, t
)), addresses
[ins
->dreg
]);
6430 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
6435 case OP_OBJC_GET_SELECTOR
: {
6436 const char *name
= (const char*)ins
->inst_p0
;
6439 if (!ctx
->module
->objc_selector_to_var
) {
6440 ctx
->module
->objc_selector_to_var
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
6442 LLVMValueRef info_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
6443 int32_t objc_imageinfo
[] = { 0, 16 };
6444 LLVMSetInitializer (info_var
, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo
, 8));
6445 LLVMSetLinkage (info_var
, LLVMPrivateLinkage
);
6446 LLVMSetExternallyInitialized (info_var
, TRUE
);
6447 LLVMSetSection (info_var
, "__DATA, __objc_imageinfo,regular,no_dead_strip");
6448 LLVMSetAlignment (info_var
, sizeof (target_mgreg_t
));
6449 mark_as_used (ctx
->module
, info_var
);
6452 var
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->objc_selector_to_var
, name
);
6454 LLVMValueRef indexes
[16];
6456 LLVMValueRef name_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMArrayType (LLVMInt8Type (), strlen (name
) + 1), "@OBJC_METH_VAR_NAME_");
6457 LLVMSetInitializer (name_var
, mono_llvm_create_constant_data_array ((const uint8_t*)name
, strlen (name
) + 1));
6458 LLVMSetLinkage (name_var
, LLVMPrivateLinkage
);
6459 LLVMSetSection (name_var
, "__TEXT,__objc_methname,cstring_literals");
6460 mark_as_used (ctx
->module
, name_var
);
6462 LLVMValueRef ref_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
6464 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
6465 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
6466 LLVMSetInitializer (ref_var
, LLVMConstGEP (name_var
, indexes
, 2));
6467 LLVMSetLinkage (ref_var
, LLVMPrivateLinkage
);
6468 LLVMSetExternallyInitialized (ref_var
, TRUE
);
6469 LLVMSetSection (ref_var
, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6470 LLVMSetAlignment (ref_var
, sizeof (target_mgreg_t
));
6471 mark_as_used (ctx
->module
, ref_var
);
6473 g_hash_table_insert (ctx
->module
->objc_selector_to_var
, g_strdup (name
), ref_var
);
6477 values
[ins
->dreg
] = LLVMBuildLoad (builder
, var
, "");
6484 #if defined(TARGET_X86) || defined(TARGET_AMD64)
6486 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, m_class_get_byval_arg (ins
->klass
)));
6489 case OP_LOADX_MEMBASE
: {
6490 LLVMTypeRef t
= type_to_llvm_type (ctx
, m_class_get_byval_arg (ins
->klass
));
6493 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
6494 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
6497 case OP_STOREX_MEMBASE
: {
6498 LLVMTypeRef t
= LLVMTypeOf (values
[ins
->sreg1
]);
6501 dest
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
6502 mono_llvm_build_aligned_store (builder
, values
[ins
->sreg1
], dest
, FALSE
, 1);
6509 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
6513 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
6519 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
6523 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
6527 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
6531 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
6534 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
6537 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
6540 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
6544 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, "");
6555 LLVMValueRef v
= NULL
;
6557 switch (ins
->opcode
) {
6562 t
= LLVMVectorType (LLVMInt32Type (), 4);
6563 rt
= LLVMVectorType (LLVMFloatType (), 4);
6569 t
= LLVMVectorType (LLVMInt64Type (), 2);
6570 rt
= LLVMVectorType (LLVMDoubleType (), 2);
6573 t
= LLVMInt32Type ();
6574 rt
= LLVMInt32Type ();
6575 g_assert_not_reached ();
6578 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
6579 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
6580 switch (ins
->opcode
) {
6583 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
6587 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
6591 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
6595 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
6598 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
6604 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntULT
, lhs
, rhs
, "");
6605 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6611 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntUGT
, lhs
, rhs
, "");
6612 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6616 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntSLT
, lhs
, rhs
, "");
6617 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6634 case OP_PADDB_SAT_UN
:
6635 case OP_PADDW_SAT_UN
:
6636 case OP_PSUBB_SAT_UN
:
6637 case OP_PSUBW_SAT_UN
:
6643 case OP_PMULW_HIGH_UN
: {
6644 LLVMValueRef args
[2];
6649 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6654 LLVMValueRef ones_vec
;
6655 LLVMValueRef ones
[32];
6656 int vector_size
= LLVMGetVectorSize (LLVMTypeOf (lhs
));
6657 LLVMTypeRef ext_elem_type
= vector_size
== 16 ? LLVMInt16Type () : LLVMInt32Type ();
6659 for (int i
= 0; i
< 32; ++i
)
6660 ones
[i
] = LLVMConstInt (ext_elem_type
, 1, FALSE
);
6661 ones_vec
= LLVMConstVector (ones
, vector_size
);
6663 #if LLVM_API_VERSION >= 500
6665 LLVMTypeRef ext_type
= LLVMVectorType (ext_elem_type
, vector_size
);
6667 /* Have to increase the vector element size to prevent overflows */
6668 /* res = trunc ((zext (lhs) + zext (rhs) + 1) >> 1) */
6669 val
= LLVMBuildAdd (builder
, LLVMBuildZExt (builder
, lhs
, ext_type
, ""), LLVMBuildZExt (builder
, rhs
, ext_type
, ""), "");
6670 val
= LLVMBuildAdd (builder
, val
, ones_vec
, "");
6671 val
= LLVMBuildLShr (builder
, val
, ones_vec
, "");
6672 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, val
, LLVMTypeOf (lhs
), "");
6674 LLVMValueRef args
[2];
6679 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6687 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
6691 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntSGT
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
6699 case OP_EXTRACTX_U2
:
6701 case OP_EXTRACT_U1
: {
6703 gboolean zext
= FALSE
;
6705 t
= simd_op_to_llvm_type (ins
->opcode
);
6707 switch (ins
->opcode
) {
6715 case OP_EXTRACTX_U2
:
6720 t
= LLVMInt32Type ();
6721 g_assert_not_reached ();
6724 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
6725 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
6727 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
6736 case OP_EXPAND_R8
: {
6737 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6738 LLVMValueRef mask
[16], v
;
6741 for (i
= 0; i
< 16; ++i
)
6742 mask
[i
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6744 v
= convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (t
));
6746 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (t
), v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6747 values
[ins
->dreg
] = LLVMBuildShuffleVector (builder
, values
[ins
->dreg
], LLVMGetUndef (t
), LLVMConstVector (mask
, LLVMGetVectorSize (t
)), "");
6752 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6755 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6758 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6761 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6764 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6767 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6770 #if LLVM_API_VERSION > 100
6772 LLVMValueRef indexes
[16];
6774 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6775 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
6776 LLVMValueRef mask
= LLVMConstVector (indexes
, 2);
6777 LLVMValueRef shuffle
= LLVMBuildShuffleVector (builder
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), mask
, "");
6778 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, shuffle
, LLVMVectorType (LLVMDoubleType (), 2), dname
);
6782 LLVMValueRef indexes
[16];
6784 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6785 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
6786 LLVMValueRef mask
= LLVMConstVector (indexes
, 2);
6787 LLVMValueRef shuffle
= LLVMBuildShuffleVector (builder
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), mask
, "");
6788 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, shuffle
, LLVMVectorType (LLVMDoubleType (), 2), dname
);
6792 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMVectorType (LLVMInt32Type (), 4), dname
);
6796 #if LLVM_API_VERSION <= 100
6806 case OP_EXTRACT_MASK
:
6813 v
= convert (ctx
, values
[ins
->sreg1
], simd_op_to_llvm_type (ins
->opcode
));
6815 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), &v
, 1, dname
);
6820 LLVMRealPredicate op
;
6822 switch (ins
->inst_c0
) {
6832 case SIMD_COMP_UNORD
:
6848 g_assert_not_reached ();
6851 LLVMValueRef cmp
= LLVMBuildFCmp (builder
, op
, lhs
, rhs
, "");
6852 if (ins
->opcode
== OP_COMPPD
)
6853 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs
), "");
6855 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs
), "");
6859 /* This is only used for implementing shifts by non-immediate */
6860 values
[ins
->dreg
] = lhs
;
6871 LLVMValueRef args
[3];
6874 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
6876 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6887 case OP_PSHLQ_REG
: {
6888 LLVMValueRef args
[3];
6891 args
[1] = values
[ins
->sreg2
];
6893 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6900 case OP_PSHUFLEW_LOW
:
6901 case OP_PSHUFLEW_HIGH
: {
6903 LLVMValueRef v1
= NULL
, v2
= NULL
, mask_values
[16];
6904 int i
, mask_size
= 0;
6905 int imask
= ins
->inst_c0
;
6907 /* Convert the x86 shuffle mask to LLVM's */
6908 switch (ins
->opcode
) {
6911 mask
[0] = ((imask
>> 0) & 3);
6912 mask
[1] = ((imask
>> 2) & 3);
6913 mask
[2] = ((imask
>> 4) & 3) + 4;
6914 mask
[3] = ((imask
>> 6) & 3) + 4;
6915 v1
= values
[ins
->sreg1
];
6916 v2
= values
[ins
->sreg2
];
6920 mask
[0] = ((imask
>> 0) & 1);
6921 mask
[1] = ((imask
>> 1) & 1) + 2;
6922 v1
= values
[ins
->sreg1
];
6923 v2
= values
[ins
->sreg2
];
6925 case OP_PSHUFLEW_LOW
:
6927 mask
[0] = ((imask
>> 0) & 3);
6928 mask
[1] = ((imask
>> 2) & 3);
6929 mask
[2] = ((imask
>> 4) & 3);
6930 mask
[3] = ((imask
>> 6) & 3);
6935 v1
= values
[ins
->sreg1
];
6936 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6938 case OP_PSHUFLEW_HIGH
:
6944 mask
[4] = 4 + ((imask
>> 0) & 3);
6945 mask
[5] = 4 + ((imask
>> 2) & 3);
6946 mask
[6] = 4 + ((imask
>> 4) & 3);
6947 mask
[7] = 4 + ((imask
>> 6) & 3);
6948 v1
= values
[ins
->sreg1
];
6949 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6953 mask
[0] = ((imask
>> 0) & 3);
6954 mask
[1] = ((imask
>> 2) & 3);
6955 mask
[2] = ((imask
>> 4) & 3);
6956 mask
[3] = ((imask
>> 6) & 3);
6957 v1
= values
[ins
->sreg1
];
6958 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6961 g_assert_not_reached ();
6963 for (i
= 0; i
< mask_size
; ++i
)
6964 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
6966 values
[ins
->dreg
] =
6967 LLVMBuildShuffleVector (builder
, v1
, v2
,
6968 LLVMConstVector (mask_values
, mask_size
), dname
);
6972 case OP_UNPACK_LOWB
:
6973 case OP_UNPACK_LOWW
:
6974 case OP_UNPACK_LOWD
:
6975 case OP_UNPACK_LOWQ
:
6976 case OP_UNPACK_LOWPS
:
6977 case OP_UNPACK_LOWPD
:
6978 case OP_UNPACK_HIGHB
:
6979 case OP_UNPACK_HIGHW
:
6980 case OP_UNPACK_HIGHD
:
6981 case OP_UNPACK_HIGHQ
:
6982 case OP_UNPACK_HIGHPS
:
6983 case OP_UNPACK_HIGHPD
: {
6985 LLVMValueRef mask_values
[16];
6986 int i
, mask_size
= 0;
6987 gboolean low
= FALSE
;
6989 switch (ins
->opcode
) {
6990 case OP_UNPACK_LOWB
:
6994 case OP_UNPACK_LOWW
:
6998 case OP_UNPACK_LOWD
:
6999 case OP_UNPACK_LOWPS
:
7003 case OP_UNPACK_LOWQ
:
7004 case OP_UNPACK_LOWPD
:
7008 case OP_UNPACK_HIGHB
:
7011 case OP_UNPACK_HIGHW
:
7014 case OP_UNPACK_HIGHD
:
7015 case OP_UNPACK_HIGHPS
:
7018 case OP_UNPACK_HIGHQ
:
7019 case OP_UNPACK_HIGHPD
:
7023 g_assert_not_reached ();
7027 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
7029 mask
[(i
* 2) + 1] = mask_size
+ i
;
7032 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
7033 mask
[(i
* 2)] = (mask_size
/ 2) + i
;
7034 mask
[(i
* 2) + 1] = mask_size
+ (mask_size
/ 2) + i
;
7038 for (i
= 0; i
< mask_size
; ++i
)
7039 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
7041 values
[ins
->dreg
] =
7042 LLVMBuildShuffleVector (builder
, values
[ins
->sreg1
], values
[ins
->sreg2
],
7043 LLVMConstVector (mask_values
, mask_size
), dname
);
7048 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
7049 LLVMValueRef v
, val
;
7051 v
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7052 val
= LLVMConstNull (t
);
7053 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7054 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), dname
);
7056 values
[ins
->dreg
] = val
;
7060 case OP_DUPPS_HIGH
: {
7061 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
7062 LLVMValueRef v1
, v2
, val
;
7065 if (ins
->opcode
== OP_DUPPS_LOW
) {
7066 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7067 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
7069 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
7070 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
7072 val
= LLVMConstNull (t
);
7073 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7074 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
7075 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
7076 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
7078 values
[ins
->dreg
] = val
;
7083 LLVMValueRef args
[3];
7087 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
7088 #if LLVM_API_VERSION >= 500
7089 args
[2] = LLVMConstInt (LLVMInt8Type (), 0xf1, FALSE
);
7091 args
[2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE
);
7094 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 3, dname
);
7098 case OP_FCONV_TO_R8_X
: {
7099 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (type_to_simd_type (MONO_TYPE_R8
)), lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7103 case OP_SSE41_ROUNDPD
: {
7104 LLVMValueRef args
[3];
7107 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
7109 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, "llvm.x86.sse41.round.pd"), args
, 2, dname
);
7119 * EXCEPTION HANDLING
7121 case OP_IMPLICIT_EXCEPTION
:
7122 /* This marks a place where an implicit exception can happen */
7123 if (bb
->region
!= -1)
7124 set_failure (ctx
, "implicit-exception");
7128 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
7129 if (ctx
->llvm_only
) {
7130 emit_llvmonly_throw (ctx
, bb
, rethrow
, lhs
);
7131 has_terminator
= TRUE
;
7132 ctx
->unreachable
[bb
->block_num
] = TRUE
;
7134 emit_throw (ctx
, bb
, rethrow
, lhs
);
7135 builder
= ctx
->builder
;
7139 case OP_CALL_HANDLER
: {
7141 * We don't 'call' handlers, but instead simply branch to them.
7142 * The code generated by ENDFINALLY will branch back to us.
7144 LLVMBasicBlockRef noex_bb
;
7146 BBInfo
*info
= &bblocks
[ins
->inst_target_bb
->block_num
];
7148 bb_list
= info
->call_handler_return_bbs
;
7151 * Set the indicator variable for the finally clause.
7153 lhs
= info
->finally_ind
;
7155 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
7157 /* Branch to the finally clause */
7158 LLVMBuildBr (builder
, info
->call_handler_target_bb
);
7160 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
7161 info
->call_handler_return_bbs
= g_slist_append_mempool (cfg
->mempool
, info
->call_handler_return_bbs
, noex_bb
);
7163 builder
= ctx
->builder
= create_builder (ctx
);
7164 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
7166 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
7169 case OP_START_HANDLER
: {
7172 case OP_ENDFINALLY
: {
7173 LLVMBasicBlockRef resume_bb
;
7174 MonoBasicBlock
*handler_bb
;
7175 LLVMValueRef val
, switch_ins
, callee
;
7178 gboolean is_fault
= MONO_REGION_FLAGS (bb
->region
) == MONO_EXCEPTION_CLAUSE_FAULT
;
7181 * Fault clauses are like finally clauses, but they are only called if an exception is thrown.
7184 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
7185 g_assert (handler_bb
);
7186 info
= &bblocks
[handler_bb
->block_num
];
7187 lhs
= info
->finally_ind
;
7190 bb_list
= info
->call_handler_return_bbs
;
7192 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
7194 /* Load the finally variable */
7195 val
= LLVMBuildLoad (builder
, lhs
, "");
7197 /* Reset the variable */
7198 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
7200 /* Branch to either resume_bb, or to the bblocks in bb_list */
7201 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
7203 * The other targets are added at the end to handle OP_CALL_HANDLER
7204 * opcodes processed later.
7206 info
->endfinally_switch_ins_list
= g_slist_append_mempool (cfg
->mempool
, info
->endfinally_switch_ins_list
, switch_ins
);
7208 builder
= ctx
->builder
= create_builder (ctx
);
7209 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
7212 if (ctx
->llvm_only
) {
7213 emit_resume_eh (ctx
, bb
);
7215 if (ctx
->cfg
->compile_aot
) {
7216 callee
= get_callee (ctx
, LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
), MONO_PATCH_INFO_JIT_ICALL
, "llvm_resume_unwind_trampoline");
7218 #if LLVM_API_VERSION > 100
7219 MonoJitICallInfo
*info
;
7221 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7223 gpointer target
= (void*)info
->func
;
7224 LLVMTypeRef icall_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
7225 callee
= emit_jit_callee (ctx
, "llvm_resume_unwind_trampoline", icall_sig
, target
);
7227 g_assert_not_reached ();
7231 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
7232 LLVMBuildUnreachable (builder
);
7235 has_terminator
= TRUE
;
7238 case OP_IL_SEQ_POINT
:
7243 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
7244 set_failure (ctx
, reason
);
7252 /* Convert the value to the type required by phi nodes */
7253 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && ctx
->vreg_types
[ins
->dreg
]) {
7254 if (ctx
->is_vphi
[ins
->dreg
])
7256 values
[ins
->dreg
] = addresses
[ins
->dreg
];
7258 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], ctx
->vreg_types
[ins
->dreg
]);
7261 /* Add stores for volatile variables */
7262 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
7263 emit_volatile_store (ctx
, ins
->dreg
);
7269 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0)) {
7270 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
7273 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
) {
7274 emit_dbg_loc (ctx
, builder
, cfg
->header
->code
+ cfg
->header
->code_size
- 1);
7275 LLVMBuildRetVoid (builder
);
7278 if (bb
== cfg
->bb_entry
)
7279 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
7283 * mono_llvm_check_method_supported:
7285 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
7286 * compiling a method twice.
7289 mono_llvm_check_method_supported (MonoCompile
*cfg
)
7294 if (mono_method_signature_internal (cfg
->method
)->call_convention
== MONO_CALL_VARARG
) {
7295 cfg
->exception_message
= g_strdup ("vararg callconv");
7296 cfg
->disable_llvm
= TRUE
;
7304 if (cfg
->method
->save_lmf
) {
7305 cfg
->exception_message
= g_strdup ("lmf");
7306 cfg
->disable_llvm
= TRUE
;
7308 if (cfg
->disable_llvm
)
7312 * Nested clauses where one of the clauses is a finally clause is
7313 * not supported, because LLVM can't figure out the control flow,
7314 * probably because we resume exception handling by calling our
7315 * own function instead of using the 'resume' llvm instruction.
7317 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
7318 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
7319 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
7320 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
7322 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
7323 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
7324 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
7325 cfg
->exception_message
= g_strdup ("nested clauses");
7326 cfg
->disable_llvm
= TRUE
;
7331 if (cfg
->disable_llvm
)
7335 if (cfg
->method
->dynamic
) {
7336 cfg
->exception_message
= g_strdup ("dynamic.");
7337 cfg
->disable_llvm
= TRUE
;
7339 if (cfg
->disable_llvm
)
7343 static LLVMCallInfo
*
7344 get_llvm_call_info (MonoCompile
*cfg
, MonoMethodSignature
*sig
)
7346 LLVMCallInfo
*linfo
;
7349 if (cfg
->gsharedvt
&& cfg
->llvm_only
&& mini_is_gsharedvt_variable_signature (sig
)) {
7353 * Gsharedvt methods have the following calling convention:
7354 * - all arguments are passed by ref, even non generic ones
7355 * - the return value is returned by ref too, using a vret
7356 * argument passed after 'this'.
7358 n
= sig
->param_count
+ sig
->hasthis
;
7359 linfo
= (LLVMCallInfo
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMCallInfo
) + (sizeof (LLVMArgInfo
) * n
));
7363 linfo
->args
[pindex
++].storage
= LLVMArgNormal
;
7365 if (sig
->ret
->type
!= MONO_TYPE_VOID
) {
7366 if (mini_is_gsharedvt_variable_type (sig
->ret
))
7367 linfo
->ret
.storage
= LLVMArgGsharedvtVariable
;
7368 else if (mini_type_is_vtype (sig
->ret
))
7369 linfo
->ret
.storage
= LLVMArgGsharedvtFixedVtype
;
7371 linfo
->ret
.storage
= LLVMArgGsharedvtFixed
;
7372 linfo
->vret_arg_index
= pindex
;
7374 linfo
->ret
.storage
= LLVMArgNone
;
7377 for (i
= 0; i
< sig
->param_count
; ++i
) {
7378 if (sig
->params
[i
]->byref
)
7379 linfo
->args
[pindex
].storage
= LLVMArgNormal
;
7380 else if (mini_is_gsharedvt_variable_type (sig
->params
[i
]))
7381 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtVariable
;
7382 else if (mini_type_is_vtype (sig
->params
[i
]))
7383 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixedVtype
;
7385 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixed
;
7386 linfo
->args
[pindex
].type
= sig
->params
[i
];
7392 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
7393 linfo
->dummy_arg_pindex
= -1;
7394 for (i
= 0; i
< sig
->param_count
; ++i
)
7395 linfo
->args
[i
+ sig
->hasthis
].type
= sig
->params
[i
];
7401 emit_method_inner (EmitContext
*ctx
);
7404 free_ctx (EmitContext
*ctx
)
7408 g_free (ctx
->values
);
7409 g_free (ctx
->addresses
);
7410 g_free (ctx
->vreg_types
);
7411 g_free (ctx
->is_vphi
);
7412 g_free (ctx
->vreg_cli_types
);
7413 g_free (ctx
->is_dead
);
7414 g_free (ctx
->unreachable
);
7415 g_ptr_array_free (ctx
->phi_values
, TRUE
);
7416 g_free (ctx
->bblocks
);
7417 g_hash_table_destroy (ctx
->region_to_handler
);
7418 g_hash_table_destroy (ctx
->clause_to_handler
);
7419 g_hash_table_destroy (ctx
->jit_callees
);
7421 g_ptr_array_free (ctx
->callsite_list
, TRUE
);
7423 g_free (ctx
->method_name
);
7424 g_ptr_array_free (ctx
->bblock_list
, TRUE
);
7426 for (l
= ctx
->builders
; l
; l
= l
->next
) {
7427 LLVMBuilderRef builder
= (LLVMBuilderRef
)l
->data
;
7428 LLVMDisposeBuilder (builder
);
7435 is_externally_callable (EmitContext
*ctx
, MonoMethod
*method
)
7437 if (ctx
->module
->llvm_only
&& ctx
->module
->static_link
&& (method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_NATIVE
|| method_is_direct_callable (method
)))
7443 * mono_llvm_emit_method:
7445 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
7448 mono_llvm_emit_method (MonoCompile
*cfg
)
7457 /* The code below might acquire the loader lock, so use it for global locking */
7458 mono_loader_lock ();
7460 /* Used to communicate with the callbacks */
7461 mono_native_tls_set_value (current_cfg_tls_id
, cfg
);
7463 ctx
= g_new0 (EmitContext
, 1);
7465 ctx
->mempool
= cfg
->mempool
;
7468 * This maps vregs to the LLVM instruction defining them
7470 ctx
->values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
7472 * This maps vregs for volatile variables to the LLVM instruction defining their
7475 ctx
->addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
7476 ctx
->vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
7477 ctx
->is_vphi
= g_new0 (gboolean
, cfg
->next_vreg
);
7478 ctx
->vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
7479 ctx
->phi_values
= g_ptr_array_sized_new (256);
7481 * This signals whenever the vreg was defined by a phi node with no input vars
7482 * (i.e. all its input bblocks end with NOT_REACHABLE).
7484 ctx
->is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
7485 /* Whenever the bblock is unreachable */
7486 ctx
->unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
7487 ctx
->bblock_list
= g_ptr_array_sized_new (256);
7489 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
7490 ctx
->clause_to_handler
= g_hash_table_new (NULL
, NULL
);
7491 ctx
->callsite_list
= g_ptr_array_new ();
7492 ctx
->jit_callees
= g_hash_table_new (NULL
, NULL
);
7493 if (cfg
->compile_aot
) {
7494 ctx
->module
= &aot_module
;
7496 if (is_externally_callable (ctx
, cfg
->method
))
7497 method_name
= mono_aot_get_mangled_method_name (cfg
->method
);
7499 method_name
= mono_aot_get_method_name (cfg
);
7500 cfg
->llvm_method_name
= g_strdup (method_name
);
7502 init_jit_module (cfg
->domain
);
7503 ctx
->module
= (MonoLLVMModule
*)domain_jit_info (cfg
->domain
)->llvm_module
;
7504 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
7506 ctx
->method_name
= method_name
;
7508 #if LLVM_API_VERSION > 100
7509 if (cfg
->compile_aot
)
7510 ctx
->lmodule
= ctx
->module
->lmodule
;
7512 ctx
->lmodule
= LLVMModuleCreateWithName (g_strdup_printf ("jit-module-%s", cfg
->method
->name
));
7514 ctx
->lmodule
= ctx
->module
->lmodule
;
7516 ctx
->llvm_only
= ctx
->module
->llvm_only
;
7518 ctx
->emit_dummy_arg
= TRUE
;
7521 emit_method_inner (ctx
);
7523 if (!ctx_ok (ctx
)) {
7525 /* Need to add unused phi nodes as they can be referenced by other values */
7526 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, "PHI_BB");
7527 LLVMBuilderRef builder
;
7529 builder
= create_builder (ctx
);
7530 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
7532 for (i
= 0; i
< ctx
->phi_values
->len
; ++i
) {
7533 LLVMValueRef v
= (LLVMValueRef
)g_ptr_array_index (ctx
->phi_values
, i
);
7534 if (LLVMGetInstructionParent (v
) == NULL
)
7535 LLVMInsertIntoBuilder (builder
, v
);
7538 if (ctx
->module
->llvm_only
&& ctx
->module
->static_link
) {
7539 // Keep a stub for the function since it might be called directly
7540 int nbbs
= LLVMCountBasicBlocks (ctx
->lmethod
);
7541 LLVMBasicBlockRef
*bblocks
= g_new0 (LLVMBasicBlockRef
, nbbs
);
7542 LLVMGetBasicBlocks (ctx
->lmethod
, bblocks
);
7543 for (int i
= 0; i
< nbbs
; ++i
)
7544 LLVMDeleteBasicBlock (bblocks
[i
]);
7546 LLVMBasicBlockRef entry_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, "ENTRY");
7547 builder
= create_builder (ctx
);
7548 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
7549 ctx
->builder
= builder
;
7551 LLVMTypeRef sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
7552 LLVMValueRef callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, "mini_llvmonly_throw_nullref_exception");
7553 emit_call (ctx
, cfg
->bb_entry
, &builder
, callee
, NULL
, 0);
7554 LLVMBuildUnreachable (builder
);
7556 LLVMDeleteFunction (ctx
->lmethod
);
7563 mono_native_tls_set_value (current_cfg_tls_id
, NULL
);
7565 mono_loader_unlock ();
7569 emit_method_inner (EmitContext
*ctx
)
7571 MonoCompile
*cfg
= ctx
->cfg
;
7572 MonoMethodSignature
*sig
;
7574 LLVMTypeRef method_type
;
7575 LLVMValueRef method
= NULL
;
7576 LLVMValueRef
*values
= ctx
->values
;
7577 int i
, max_block_num
, bb_index
;
7578 gboolean last
= FALSE
;
7579 LLVMCallInfo
*linfo
;
7580 LLVMModuleRef lmodule
= ctx
->lmodule
;
7582 GPtrArray
*bblock_list
= ctx
->bblock_list
;
7583 MonoMethodHeader
*header
;
7584 MonoExceptionClause
*clause
;
7586 LLVMBuilderRef entry_builder
= NULL
;
7587 LLVMBasicBlockRef entry_bb
= NULL
;
7589 if (cfg
->gsharedvt
&& !cfg
->llvm_only
) {
7590 set_failure (ctx
, "gsharedvt");
7596 static int count
= 0;
7599 char *llvm_count_str
= g_getenv ("LLVM_COUNT");
7600 if (llvm_count_str
) {
7601 int lcount
= atoi (llvm_count_str
);
7602 g_free (llvm_count_str
);
7603 if (count
== lcount
) {
7604 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
7608 if (count
> lcount
) {
7609 set_failure (ctx
, "count");
7616 // If we come upon one of the init_method wrappers, we need to find
7617 // the method that we have already emitted and tell LLVM that this
7618 // managed method info for the wrapper is associated with this method
7619 // we constructed ourselves from LLVM IR.
7621 // This is necessary to unwind through the init_method, in the case that
7622 // it has to run a static cctor that throws an exception
7623 if (cfg
->method
->wrapper_type
== MONO_WRAPPER_OTHER
) {
7624 WrapperInfo
*info
= mono_marshal_get_wrapper_info (cfg
->method
);
7625 if (info
->subtype
== WRAPPER_SUBTYPE_AOT_INIT
) {
7626 method
= get_init_icall_wrapper (ctx
->module
, info
->d
.aot_init
.subtype
);
7627 ctx
->lmethod
= method
;
7628 ctx
->module
->max_method_idx
= MAX (ctx
->module
->max_method_idx
, cfg
->method_index
);
7630 const char *init_name
= mono_marshal_get_aot_init_wrapper_name (info
->d
.aot_init
.subtype
);
7631 ctx
->method_name
= g_strdup_printf ("%s%s", ctx
->module
->global_prefix
, init_name
);
7632 ctx
->cfg
->asm_symbol
= g_strdup (ctx
->method_name
);
7634 if (!cfg
->llvm_only
&& ctx
->module
->external_symbols
) {
7635 LLVMSetLinkage (method
, LLVMExternalLinkage
);
7636 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
7643 sig
= mono_method_signature_internal (cfg
->method
);
7646 linfo
= get_llvm_call_info (cfg
, sig
);
7652 linfo
->rgctx_arg
= TRUE
;
7653 else if (needs_extra_arg (ctx
, cfg
->method
))
7654 linfo
->dummy_arg
= TRUE
;
7655 ctx
->method_type
= method_type
= sig_to_llvm_sig_full (ctx
, sig
, linfo
);
7659 method
= LLVMAddFunction (lmodule
, ctx
->method_name
, method_type
);
7660 ctx
->lmethod
= method
;
7662 if (!cfg
->llvm_only
)
7663 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
7665 /* if the method doesn't contain
7666 * (1) a call (so it's a leaf method)
7668 * we can skip the GC safepoint on method entry. */
7669 gboolean requires_safepoint
= cfg
->has_calls
;
7670 if (!requires_safepoint
) {
7671 for (bb
= cfg
->bb_entry
->next_bb
; bb
; bb
= bb
->next_bb
) {
7672 if (bb
->loop_body_start
|| (bb
->flags
& BB_EXCEPTION_HANDLER
)) {
7673 requires_safepoint
= TRUE
;
7678 if (!cfg
->llvm_only
&& cfg
->compile_aot
&& mono_threads_are_safepoints_enabled () && requires_safepoint
)
7679 LLVMSetGC (method
, "mono");
7680 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
7682 mono_llvm_add_func_attr (method
, LLVM_ATTR_UW_TABLE
);
7684 if (cfg
->compile_aot
) {
7685 if (is_externally_callable (ctx
, cfg
->method
)) {
7686 LLVMSetLinkage (method
, LLVMExternalLinkage
);
7688 LLVMSetLinkage (method
, LLVMInternalLinkage
);
7689 //all methods have internal visibility when doing llvm_only
7690 if (!cfg
->llvm_only
&& ctx
->module
->external_symbols
) {
7691 LLVMSetLinkage (method
, LLVMExternalLinkage
);
7692 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
7696 LLVMSetLinkage (method
, LLVMExternalLinkage
);
7699 if (cfg
->method
->save_lmf
&& !cfg
->llvm_only
) {
7700 set_failure (ctx
, "lmf");
7704 if (sig
->pinvoke
&& cfg
->method
->wrapper_type
!= MONO_WRAPPER_RUNTIME_INVOKE
&& !cfg
->llvm_only
) {
7705 set_failure (ctx
, "pinvoke signature");
7709 header
= cfg
->header
;
7710 for (i
= 0; i
< header
->num_clauses
; ++i
) {
7711 clause
= &header
->clauses
[i
];
7712 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_FAULT
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
) {
7713 set_failure (ctx
, "non-finally/catch/fault clause.");
7717 if (header
->num_clauses
|| (cfg
->method
->iflags
& METHOD_IMPL_ATTRIBUTE_NOINLINING
) || cfg
->no_inline
)
7718 /* We can't handle inlined methods with clauses */
7719 mono_llvm_add_func_attr (method
, LLVM_ATTR_NO_INLINE
);
7721 if (linfo
->rgctx_arg
) {
7722 ctx
->rgctx_arg
= LLVMGetParam (method
, linfo
->rgctx_arg_pindex
);
7723 ctx
->rgctx_arg_pindex
= linfo
->rgctx_arg_pindex
;
7725 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7726 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7727 * CC_X86_64_Mono in X86CallingConv.td.
7729 if (!ctx
->llvm_only
)
7730 mono_llvm_add_param_attr (ctx
->rgctx_arg
, LLVM_ATTR_IN_REG
);
7731 LLVMSetValueName (ctx
->rgctx_arg
, "rgctx");
7733 ctx
->rgctx_arg_pindex
= -1;
7735 if (cfg
->vret_addr
) {
7736 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, linfo
->vret_arg_pindex
);
7737 LLVMSetValueName (values
[cfg
->vret_addr
->dreg
], "vret");
7738 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
7739 mono_llvm_add_param_attr (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVM_ATTR_STRUCT_RET
);
7740 mono_llvm_add_param_attr (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVM_ATTR_NO_ALIAS
);
7745 ctx
->this_arg_pindex
= linfo
->this_arg_pindex
;
7746 ctx
->this_arg
= LLVMGetParam (method
, linfo
->this_arg_pindex
);
7747 values
[cfg
->args
[0]->dreg
] = ctx
->this_arg
;
7748 LLVMSetValueName (values
[cfg
->args
[0]->dreg
], "this");
7750 if (linfo
->dummy_arg
)
7751 LLVMSetValueName (LLVMGetParam (method
, linfo
->dummy_arg_pindex
), "dummy_arg");
7753 names
= g_new (char *, sig
->param_count
);
7754 mono_method_get_param_names (cfg
->method
, (const char **) names
);
7756 /* Set parameter names/attributes */
7757 for (i
= 0; i
< sig
->param_count
; ++i
) {
7758 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
7760 int pindex
= ainfo
->pindex
+ ainfo
->ndummy_fpargs
;
7763 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
) {
7764 name
= g_strdup_printf ("dummy_%d_%d", i
, j
);
7765 LLVMSetValueName (LLVMGetParam (method
, ainfo
->pindex
+ j
), name
);
7769 if (ainfo
->storage
== LLVMArgVtypeInReg
&& ainfo
->pair_storage
[0] == LLVMArgNone
&& ainfo
->pair_storage
[1] == LLVMArgNone
)
7772 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, pindex
);
7773 if (ainfo
->storage
== LLVMArgGsharedvtFixed
|| ainfo
->storage
== LLVMArgGsharedvtFixedVtype
) {
7774 if (names
[i
] && names
[i
][0] != '\0')
7775 name
= g_strdup_printf ("p_arg_%s", names
[i
]);
7777 name
= g_strdup_printf ("p_arg_%d", i
);
7779 if (names
[i
] && names
[i
][0] != '\0')
7780 name
= g_strdup_printf ("arg_%s", names
[i
]);
7782 name
= g_strdup_printf ("arg_%d", i
);
7784 LLVMSetValueName (LLVMGetParam (method
, pindex
), name
);
7786 if (ainfo
->storage
== LLVMArgVtypeByVal
)
7787 mono_llvm_add_param_attr (LLVMGetParam (method
, pindex
), LLVM_ATTR_BY_VAL
);
7789 if (ainfo
->storage
== LLVMArgVtypeByRef
) {
7791 cfg
->args
[i
+ sig
->hasthis
]->opcode
= OP_VTARG_ADDR
;
7796 if (ctx
->module
->emit_dwarf
&& cfg
->compile_aot
&& mono_debug_enabled ()) {
7797 ctx
->minfo
= mono_debug_lookup_method (cfg
->method
);
7798 ctx
->dbg_md
= emit_dbg_subprogram (ctx
, cfg
, method
, ctx
->method_name
);
7802 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
7803 max_block_num
= MAX (max_block_num
, bb
->block_num
);
7804 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
7806 /* Add branches between non-consecutive bblocks */
7807 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7808 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
7809 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
7811 MonoInst
*inst
= (MonoInst
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
7812 inst
->opcode
= OP_BR
;
7813 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
7814 mono_bblock_add_inst (bb
, inst
);
7819 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7821 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7823 LLVMBuilderRef builder
;
7825 char dname_buf
[128];
7827 builder
= create_builder (ctx
);
7829 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
7830 switch (ins
->opcode
) {
7835 LLVMTypeRef phi_type
= llvm_type_to_stack_type (cfg
, type_to_llvm_type (ctx
, m_class_get_byval_arg (ins
->klass
)));
7840 if (ins
->opcode
== OP_VPHI
) {
7841 /* Treat valuetype PHI nodes as operating on the address itself */
7842 g_assert (ins
->klass
);
7843 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, m_class_get_byval_arg (ins
->klass
)), 0);
7847 * Have to precreate these, as they can be referenced by
7848 * earlier instructions.
7850 sprintf (dname_buf
, "t%d", ins
->dreg
);
7852 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
7854 if (ins
->opcode
== OP_VPHI
)
7855 ctx
->addresses
[ins
->dreg
] = values
[ins
->dreg
];
7857 g_ptr_array_add (ctx
->phi_values
, values
[ins
->dreg
]);
7860 * Set the expected type of the incoming arguments since these have
7861 * to have the same type.
7863 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
7864 int sreg1
= ins
->inst_phi_args
[i
+ 1];
7867 if (ins
->opcode
== OP_VPHI
)
7868 ctx
->is_vphi
[sreg1
] = TRUE
;
7869 ctx
->vreg_types
[sreg1
] = phi_type
;
7875 ((MonoInst
*)ins
->inst_p0
)->flags
|= MONO_INST_INDIRECT
;
7884 * Create an ordering for bblocks, use the depth first order first, then
7885 * put the exception handling bblocks last.
7887 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
7888 bb
= cfg
->bblocks
[bb_index
];
7889 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
7890 g_ptr_array_add (bblock_list
, bb
);
7891 bblocks
[bb
->block_num
].added
= TRUE
;
7895 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7896 if (!bblocks
[bb
->block_num
].added
)
7897 g_ptr_array_add (bblock_list
, bb
);
7901 * Second pass: generate code.
7904 entry_builder
= create_builder (ctx
);
7905 entry_bb
= get_bb (ctx
, cfg
->bb_entry
);
7906 LLVMPositionBuilderAtEnd (entry_builder
, entry_bb
);
7907 emit_entry_bb (ctx
, entry_builder
);
7909 // Make landing pads first
7910 ctx
->exc_meta
= g_hash_table_new_full (NULL
, NULL
, NULL
, NULL
);
7912 if (ctx
->llvm_only
) {
7913 size_t group_index
= 0;
7914 while (group_index
< cfg
->header
->num_clauses
) {
7916 size_t cursor
= group_index
;
7917 while (cursor
< cfg
->header
->num_clauses
&&
7918 CLAUSE_START (&cfg
->header
->clauses
[cursor
]) == CLAUSE_START (&cfg
->header
->clauses
[group_index
]) &&
7919 CLAUSE_END (&cfg
->header
->clauses
[cursor
]) == CLAUSE_END (&cfg
->header
->clauses
[group_index
])) {
7924 LLVMBasicBlockRef lpad_bb
= emit_landing_pad (ctx
, group_index
, count
);
7925 intptr_t key
= CLAUSE_END (&cfg
->header
->clauses
[group_index
]);
7926 g_hash_table_insert (ctx
->exc_meta
, (gpointer
)key
, lpad_bb
);
7928 group_index
= cursor
;
7932 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
7933 bb
= (MonoBasicBlock
*)g_ptr_array_index (bblock_list
, bb_index
);
7935 // Prune unreachable mono BBs.
7936 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
7939 process_bb (ctx
, bb
);
7943 g_hash_table_destroy (ctx
->exc_meta
);
7945 mono_memory_barrier ();
7947 /* Add incoming phi values */
7948 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7949 GSList
*l
, *ins_list
;
7951 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7953 for (l
= ins_list
; l
; l
= l
->next
) {
7954 PhiNode
*node
= (PhiNode
*)l
->data
;
7955 MonoInst
*phi
= node
->phi
;
7956 int sreg1
= node
->sreg
;
7957 LLVMBasicBlockRef in_bb
;
7962 in_bb
= get_end_bb (ctx
, node
->in_bb
);
7964 if (ctx
->unreachable
[node
->in_bb
->block_num
])
7967 if (phi
->opcode
== OP_VPHI
) {
7968 g_assert (LLVMTypeOf (ctx
->addresses
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
7969 LLVMAddIncoming (values
[phi
->dreg
], &ctx
->addresses
[sreg1
], &in_bb
, 1);
7971 if (!values
[sreg1
]) {
7972 /* Can happen with values in EH clauses */
7973 set_failure (ctx
, "incoming phi sreg1");
7976 if (LLVMTypeOf (values
[sreg1
]) != LLVMTypeOf (values
[phi
->dreg
])) {
7977 set_failure (ctx
, "incoming phi arg type mismatch");
7980 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
7981 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
7986 /* Nullify empty phi instructions */
7987 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7988 GSList
*l
, *ins_list
;
7990 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7992 for (l
= ins_list
; l
; l
= l
->next
) {
7993 PhiNode
*node
= (PhiNode
*)l
->data
;
7994 MonoInst
*phi
= node
->phi
;
7995 LLVMValueRef phi_ins
= values
[phi
->dreg
];
7998 /* Already removed */
8001 if (LLVMCountIncoming (phi_ins
) == 0) {
8002 mono_llvm_replace_uses_of (phi_ins
, LLVMConstNull (LLVMTypeOf (phi_ins
)));
8003 LLVMInstructionEraseFromParent (phi_ins
);
8004 values
[phi
->dreg
] = NULL
;
8009 /* Create the SWITCH statements for ENDFINALLY instructions */
8010 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
8011 BBInfo
*info
= &bblocks
[bb
->block_num
];
8013 for (l
= info
->endfinally_switch_ins_list
; l
; l
= l
->next
) {
8014 LLVMValueRef switch_ins
= (LLVMValueRef
)l
->data
;
8015 GSList
*bb_list
= info
->call_handler_return_bbs
;
8017 GSList
*bb_list_iter
;
8019 for (bb_list_iter
= bb_list
; bb_list_iter
; bb_list_iter
= g_slist_next (bb_list_iter
)) {
8020 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), (LLVMBasicBlockRef
)bb_list_iter
->data
);
8026 /* Initialize the method if needed */
8027 if (cfg
->compile_aot
&& !ctx
->module
->llvm_disable_self_init
) {
8028 // FIXME: Add more shared got entries
8029 ctx
->builder
= create_builder (ctx
);
8030 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->init_bb
);
8032 ctx
->module
->max_method_idx
= MAX (ctx
->module
->max_method_idx
, cfg
->method_index
);
8034 // FIXME: beforefieldinit
8036 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
8037 * in load_method ().
8039 gboolean needs_init
= ctx
->cfg
->got_access_count
> 0;
8040 MonoMethod
*cctor
= NULL
;
8041 if (!needs_init
&& (cctor
= mono_class_get_cctor (cfg
->method
->klass
))) {
8042 /* Needs init to run the cctor */
8043 if (cfg
->method
->flags
& METHOD_ATTRIBUTE_STATIC
)
8045 if (cctor
== cfg
->method
)
8048 // If we are a constructor, we need to init so the static
8049 // constructor gets called.
8050 if (!strcmp (cfg
->method
->name
, ".ctor"))
8053 if (cfg
->method
->wrapper_type
== MONO_WRAPPER_NATIVE_TO_MANAGED
)
8056 emit_init_method (ctx
);
8058 LLVMBuildBr (ctx
->builder
, ctx
->inited_bb
);
8060 // Was observing LLVM moving field accesses into the caller's method
8061 // body before the init call (the inlined one), leading to NULL derefs
8062 // after the init_method returns (GOT is filled out though)
8064 mono_llvm_add_func_attr (method
, LLVM_ATTR_NO_INLINE
);
8068 if (cfg
->compile_aot
&& !ctx
->module
->llvm_disable_self_init
) {
8069 g_ptr_array_add (ctx
->module
->cfgs
, cfg
);
8072 * Add the contents of ctx->callsite_list to module->callsite_list.
8073 * We can't do this earlier, as it contains llvm instructions which can be
8074 * freed if compilation fails.
8075 * FIXME: Get rid of this when all methods can be llvm compiled.
8077 for (int i
= 0; i
< ctx
->callsite_list
->len
; ++i
)
8078 g_ptr_array_add (ctx
->module
->callsite_list
, g_ptr_array_index (ctx
->callsite_list
, i
));
8081 if (cfg
->verbose_level
> 1)
8082 mono_llvm_dump_value (method
);
8084 if (cfg
->compile_aot
&& !cfg
->llvm_only
)
8085 mark_as_used (ctx
->module
, method
);
8087 if (!cfg
->llvm_only
) {
8088 LLVMValueRef md_args
[16];
8089 LLVMValueRef md_node
;
8092 if (cfg
->compile_aot
)
8093 method_index
= mono_aot_get_method_index (cfg
->orig_method
);
8096 md_args
[0] = LLVMMDString (ctx
->method_name
, strlen (ctx
->method_name
));
8097 md_args
[1] = LLVMConstInt (LLVMInt32Type (), method_index
, FALSE
);
8098 md_node
= LLVMMDNode (md_args
, 2);
8099 LLVMAddNamedMetadataOperand (lmodule
, "mono.function_indexes", md_node
);
8100 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
8103 if (cfg
->compile_aot
) {
8104 /* Don't generate native code, keep the LLVM IR */
8105 if (cfg
->verbose_level
) {
8106 char *name
= mono_method_get_full_name (cfg
->method
);
8107 printf ("%s emitted as %s\n", name
, ctx
->method_name
);
8111 //LLVMDumpValue (ctx->lmethod);
8112 #if LLVM_API_VERSION < 100
8113 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
8114 int err
= LLVMVerifyFunction(ctx
->lmethod
, LLVMPrintMessageAction
);
8115 g_assert (err
== 0);
8118 //LLVMVerifyFunction (method, 0);
8119 llvm_jit_finalize_method (ctx
);
8122 if (ctx
->module
->method_to_lmethod
)
8123 g_hash_table_insert (ctx
->module
->method_to_lmethod
, cfg
->method
, ctx
->lmethod
);
8124 if (ctx
->module
->idx_to_lmethod
)
8125 g_hash_table_insert (ctx
->module
->idx_to_lmethod
, GINT_TO_POINTER (cfg
->method_index
), ctx
->lmethod
);
8127 if (ctx
->llvm_only
&& m_class_is_valuetype (cfg
->orig_method
->klass
) && !(cfg
->orig_method
->flags
& METHOD_ATTRIBUTE_STATIC
))
8128 emit_unbox_tramp (ctx
, ctx
->method_name
, ctx
->method_type
, ctx
->lmethod
, cfg
->method_index
);
8132 * mono_llvm_create_vars:
8134 * Same as mono_arch_create_vars () for LLVM.
8137 mono_llvm_create_vars (MonoCompile
*cfg
)
8139 MonoMethodSignature
*sig
;
8141 sig
= mono_method_signature_internal (cfg
->method
);
8142 if (cfg
->gsharedvt
&& cfg
->llvm_only
) {
8143 gboolean vretaddr
= FALSE
;
8145 if (mini_is_gsharedvt_variable_signature (sig
) && sig
->ret
->type
!= MONO_TYPE_VOID
) {
8148 MonoMethodSignature
*sig
= mono_method_signature_internal (cfg
->method
);
8149 LLVMCallInfo
*linfo
;
8151 linfo
= get_llvm_call_info (cfg
, sig
);
8152 vretaddr
= (linfo
->ret
.storage
== LLVMArgVtypeRetAddr
|| linfo
->ret
.storage
== LLVMArgVtypeByRef
|| linfo
->ret
.storage
== LLVMArgGsharedvtFixed
|| linfo
->ret
.storage
== LLVMArgGsharedvtVariable
|| linfo
->ret
.storage
== LLVMArgGsharedvtFixedVtype
);
8156 * Creating vret_addr forces CEE_SETRET to store the result into it,
8157 * so we don't have to generate any code in our OP_SETRET case.
8159 cfg
->vret_addr
= mono_compile_create_var (cfg
, m_class_get_byval_arg (mono_get_intptr_class ()), OP_ARG
);
8160 if (G_UNLIKELY (cfg
->verbose_level
> 1)) {
8161 printf ("vret_addr = ");
8162 mono_print_ins (cfg
->vret_addr
);
8166 mono_arch_create_vars (cfg
);
8171 * mono_llvm_emit_call:
8173 * Same as mono_arch_emit_call () for LLVM.
8176 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
8179 MonoMethodSignature
*sig
;
8180 int i
, n
, stack_size
;
8185 sig
= call
->signature
;
8186 n
= sig
->param_count
+ sig
->hasthis
;
8188 call
->cinfo
= get_llvm_call_info (cfg
, sig
);
8190 if (cfg
->disable_llvm
)
8193 if (sig
->call_convention
== MONO_CALL_VARARG
) {
8194 cfg
->exception_message
= g_strdup ("varargs");
8195 cfg
->disable_llvm
= TRUE
;
8198 for (i
= 0; i
< n
; ++i
) {
8201 ainfo
= call
->cinfo
->args
+ i
;
8203 in
= call
->args
[i
];
8205 /* Simply remember the arguments */
8206 switch (ainfo
->storage
) {
8207 case LLVMArgNormal
: {
8208 MonoType
*t
= (sig
->hasthis
&& i
== 0) ? m_class_get_byval_arg (mono_get_intptr_class ()) : ainfo
->type
;
8211 opcode
= mono_type_to_regmove (cfg
, t
);
8212 if (opcode
== OP_FMOVE
) {
8213 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
8214 ins
->dreg
= mono_alloc_freg (cfg
);
8215 } else if (opcode
== OP_LMOVE
) {
8216 MONO_INST_NEW (cfg
, ins
, OP_LMOVE
);
8217 ins
->dreg
= mono_alloc_lreg (cfg
);
8218 } else if (opcode
== OP_RMOVE
) {
8219 MONO_INST_NEW (cfg
, ins
, OP_RMOVE
);
8220 ins
->dreg
= mono_alloc_freg (cfg
);
8222 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
8223 ins
->dreg
= mono_alloc_ireg (cfg
);
8225 ins
->sreg1
= in
->dreg
;
8228 case LLVMArgVtypeByVal
:
8229 case LLVMArgVtypeByRef
:
8230 case LLVMArgVtypeInReg
:
8231 case LLVMArgVtypeAsScalar
:
8232 case LLVMArgAsIArgs
:
8233 case LLVMArgAsFpArgs
:
8234 case LLVMArgGsharedvtVariable
:
8235 case LLVMArgGsharedvtFixed
:
8236 case LLVMArgGsharedvtFixedVtype
:
8237 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
8238 ins
->dreg
= mono_alloc_ireg (cfg
);
8239 ins
->sreg1
= in
->dreg
;
8240 ins
->inst_p0
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMArgInfo
));
8241 memcpy (ins
->inst_p0
, ainfo
, sizeof (LLVMArgInfo
));
8242 ins
->inst_vtype
= ainfo
->type
;
8243 ins
->klass
= mono_class_from_mono_type_internal (ainfo
->type
);
8246 cfg
->exception_message
= g_strdup ("ainfo->storage");
8247 cfg
->disable_llvm
= TRUE
;
8251 if (!cfg
->disable_llvm
) {
8252 MONO_ADD_INS (cfg
->cbb
, ins
);
8253 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
8259 AddFunc (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef
*param_types
, int nparams
)
8261 LLVMAddFunction (module
, name
, LLVMFunctionType (ret_type
, param_types
, nparams
, FALSE
));
8265 AddFunc2 (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef param_type1
, LLVMTypeRef param_type2
)
8267 LLVMTypeRef param_types
[4];
8269 param_types
[0] = param_type1
;
8270 param_types
[1] = param_type2
;
8272 AddFunc (module
, name
, ret_type
, param_types
, 2);
8280 static IntrinsicDesc intrinsics
[] = {
8281 {INTRINS_MEMSET
, "llvm.memset.p0i8.i32"},
8282 {INTRINS_MEMCPY
, "llvm.memcpy.p0i8.p0i8.i32"},
8283 {INTRINS_SADD_OVF_I32
, "llvm.sadd.with.overflow.i32"},
8284 {INTRINS_UADD_OVF_I32
, "llvm.uadd.with.overflow.i32"},
8285 {INTRINS_SSUB_OVF_I32
, "llvm.ssub.with.overflow.i32"},
8286 {INTRINS_USUB_OVF_I32
, "llvm.usub.with.overflow.i32"},
8287 {INTRINS_SMUL_OVF_I32
, "llvm.smul.with.overflow.i32"},
8288 {INTRINS_UMUL_OVF_I32
, "llvm.umul.with.overflow.i32"},
8289 {INTRINS_SADD_OVF_I64
, "llvm.sadd.with.overflow.i64"},
8290 {INTRINS_UADD_OVF_I64
, "llvm.uadd.with.overflow.i64"},
8291 {INTRINS_SSUB_OVF_I64
, "llvm.ssub.with.overflow.i64"},
8292 {INTRINS_USUB_OVF_I64
, "llvm.usub.with.overflow.i64"},
8293 {INTRINS_SMUL_OVF_I64
, "llvm.smul.with.overflow.i64"},
8294 {INTRINS_UMUL_OVF_I64
, "llvm.umul.with.overflow.i64"},
8295 {INTRINS_SIN
, "llvm.sin.f64"},
8296 {INTRINS_COS
, "llvm.cos.f64"},
8297 {INTRINS_SQRT
, "llvm.sqrt.f64"},
8298 /* This isn't an intrinsic, instead llvm seems to special case it by name */
8299 {INTRINS_FABS
, "fabs"},
8300 {INTRINS_ABSF
, "llvm.fabs.f32"},
8301 {INTRINS_SINF
, "llvm.sin.f32"},
8302 {INTRINS_COSF
, "llvm.cos.f32"},
8303 {INTRINS_SQRTF
, "llvm.sqrt.f32"},
8304 {INTRINS_POWF
, "llvm.pow.f32"},
8305 {INTRINS_EXPECT_I8
, "llvm.expect.i8"},
8306 {INTRINS_EXPECT_I1
, "llvm.expect.i1"},
8307 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8308 {INTRINS_SSE_PMOVMSKB
, "llvm.x86.sse2.pmovmskb.128"},
8309 {INTRINS_SSE_PSRLI_W
, "llvm.x86.sse2.psrli.w"},
8310 {INTRINS_SSE_PSRAI_W
, "llvm.x86.sse2.psrai.w"},
8311 {INTRINS_SSE_PSLLI_W
, "llvm.x86.sse2.pslli.w"},
8312 {INTRINS_SSE_PSRLI_D
, "llvm.x86.sse2.psrli.d"},
8313 {INTRINS_SSE_PSRAI_D
, "llvm.x86.sse2.psrai.d"},
8314 {INTRINS_SSE_PSLLI_D
, "llvm.x86.sse2.pslli.d"},
8315 {INTRINS_SSE_PSRLI_Q
, "llvm.x86.sse2.psrli.q"},
8316 {INTRINS_SSE_PSLLI_Q
, "llvm.x86.sse2.pslli.q"},
8317 {INTRINS_SSE_SQRT_PD
, "llvm.x86.sse2.sqrt.pd"},
8318 {INTRINS_SSE_SQRT_PS
, "llvm.x86.sse.sqrt.ps"},
8319 {INTRINS_SSE_RSQRT_PS
, "llvm.x86.sse.rsqrt.ps"},
8320 {INTRINS_SSE_RCP_PS
, "llvm.x86.sse.rcp.ps"},
8321 {INTRINS_SSE_CVTTPD2DQ
, "llvm.x86.sse2.cvttpd2dq"},
8322 {INTRINS_SSE_CVTTPS2DQ
, "llvm.x86.sse2.cvttps2dq"},
8323 {INTRINS_SSE_CVTDQ2PD
, "llvm.x86.sse2.cvtdq2pd"},
8324 {INTRINS_SSE_CVTDQ2PS
, "llvm.x86.sse2.cvtdq2ps"},
8325 {INTRINS_SSE_CVTPD2DQ
, "llvm.x86.sse2.cvtpd2dq"},
8326 {INTRINS_SSE_CVTPS2DQ
, "llvm.x86.sse2.cvtps2dq"},
8327 {INTRINS_SSE_CVTPD2PS
, "llvm.x86.sse2.cvtpd2ps"},
8328 {INTRINS_SSE_CVTPS2PD
, "llvm.x86.sse2.cvtps2pd"},
8329 {INTRINS_SSE_CMPPD
, "llvm.x86.sse2.cmp.pd"},
8330 {INTRINS_SSE_CMPPS
, "llvm.x86.sse.cmp.ps"},
8331 {INTRINS_SSE_PACKSSWB
, "llvm.x86.sse2.packsswb.128"},
8332 {INTRINS_SSE_PACKUSWB
, "llvm.x86.sse2.packuswb.128"},
8333 {INTRINS_SSE_PACKSSDW
, "llvm.x86.sse2.packssdw.128"},
8334 {INTRINS_SSE_PACKUSDW
, "llvm.x86.sse41.packusdw"},
8335 {INTRINS_SSE_MINPS
, "llvm.x86.sse.min.ps"},
8336 {INTRINS_SSE_MAXPS
, "llvm.x86.sse.max.ps"},
8337 {INTRINS_SSE_HADDPS
, "llvm.x86.sse3.hadd.ps"},
8338 {INTRINS_SSE_HSUBPS
, "llvm.x86.sse3.hsub.ps"},
8339 {INTRINS_SSE_ADDSUBPS
, "llvm.x86.sse3.addsub.ps"},
8340 {INTRINS_SSE_MINPD
, "llvm.x86.sse2.min.pd"},
8341 {INTRINS_SSE_MAXPD
, "llvm.x86.sse2.max.pd"},
8342 {INTRINS_SSE_HADDPD
, "llvm.x86.sse3.hadd.pd"},
8343 {INTRINS_SSE_HSUBPD
, "llvm.x86.sse3.hsub.pd"},
8344 {INTRINS_SSE_ADDSUBPD
, "llvm.x86.sse3.addsub.pd"},
8345 {INTRINS_SSE_PADDSW
, "llvm.x86.sse2.padds.w"},
8346 {INTRINS_SSE_PSUBSW
, "llvm.x86.sse2.psubs.w"},
8347 {INTRINS_SSE_PADDUSW
, "llvm.x86.sse2.paddus.w"},
8348 {INTRINS_SSE_PSUBUSW
, "llvm.x86.sse2.psubus.w"},
8349 {INTRINS_SSE_PAVGW
, "llvm.x86.sse2.pavg.w"},
8350 {INTRINS_SSE_PMULHW
, "llvm.x86.sse2.pmulh.w"},
8351 {INTRINS_SSE_PMULHU
, "llvm.x86.sse2.pmulhu.w"},
8352 {INTRINS_SE_PADDSB
, "llvm.x86.sse2.padds.b"},
8353 {INTRINS_SSE_PSUBSB
, "llvm.x86.sse2.psubs.b"},
8354 {INTRINS_SSE_PADDUSB
, "llvm.x86.sse2.paddus.b"},
8355 {INTRINS_SSE_PSUBUSB
, "llvm.x86.sse2.psubus.b"},
8356 {INTRINS_SSE_PAVGB
, "llvm.x86.sse2.pavg.b"},
8357 {INTRINS_SSE_PAUSE
, "llvm.x86.sse2.pause"},
8358 {INTRINS_SSE_DPPS
, "llvm.x86.sse41.dpps"},
8359 {INTRINS_SSE_ROUNDPD
, "llvm.x86.sse41.round.pd"}
8364 add_sse_binary (LLVMModuleRef module
, const char *name
, int type
)
8366 LLVMTypeRef ret_type
= type_to_simd_type (type
);
8367 AddFunc2 (module
, name
, ret_type
, ret_type
, ret_type
);
8371 add_intrinsic (LLVMModuleRef module
, int id
)
8374 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8375 LLVMTypeRef ret_type
, arg_types
[16];
8378 name
= (const char*)g_hash_table_lookup (intrins_id_to_name
, GINT_TO_POINTER (id
));
8382 case INTRINS_MEMSET
: {
8383 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8385 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
8388 case INTRINS_MEMCPY
: {
8389 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8391 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
8394 case INTRINS_SADD_OVF_I32
:
8395 case INTRINS_UADD_OVF_I32
:
8396 case INTRINS_SSUB_OVF_I32
:
8397 case INTRINS_USUB_OVF_I32
:
8398 case INTRINS_SMUL_OVF_I32
:
8399 case INTRINS_UMUL_OVF_I32
: {
8400 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
8401 LLVMTypeRef params
[] = { LLVMInt32Type (), LLVMInt32Type () };
8402 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i32
, 2, FALSE
);
8404 AddFunc (module
, name
, ret_type
, params
, 2);
8407 case INTRINS_SADD_OVF_I64
:
8408 case INTRINS_UADD_OVF_I64
:
8409 case INTRINS_SSUB_OVF_I64
:
8410 case INTRINS_USUB_OVF_I64
:
8411 case INTRINS_SMUL_OVF_I64
:
8412 case INTRINS_UMUL_OVF_I64
: {
8413 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
8414 LLVMTypeRef params
[] = { LLVMInt64Type (), LLVMInt64Type () };
8415 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i64
, 2, FALSE
);
8417 AddFunc (module
, name
, ret_type
, params
, 2);
8423 case INTRINS_FABS
: {
8424 LLVMTypeRef params
[] = { LLVMDoubleType () };
8426 AddFunc (module
, name
, LLVMDoubleType (), params
, 1);
8432 case INTRINS_ABSF
: {
8433 LLVMTypeRef params
[] = { LLVMFloatType () };
8435 AddFunc (module
, name
, LLVMFloatType (), params
, 1);
8438 case INTRINS_POWF
: {
8439 LLVMTypeRef params
[] = { LLVMFloatType (), LLVMFloatType () };
8441 AddFunc (module
, name
, LLVMFloatType (), params
, 2);
8444 case INTRINS_EXPECT_I8
:
8445 AddFunc2 (module
, name
, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8447 case INTRINS_EXPECT_I1
:
8448 AddFunc2 (module
, name
, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8450 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8451 case INTRINS_SSE_PMOVMSKB
:
8453 ret_type
= LLVMInt32Type ();
8454 arg_types
[0] = type_to_simd_type (MONO_TYPE_I1
);
8455 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8457 case INTRINS_SSE_PSRLI_W
:
8458 case INTRINS_SSE_PSRAI_W
:
8459 case INTRINS_SSE_PSLLI_W
:
8461 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8462 arg_types
[0] = ret_type
;
8463 arg_types
[1] = LLVMInt32Type ();
8464 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8466 case INTRINS_SSE_PSRLI_D
:
8467 case INTRINS_SSE_PSRAI_D
:
8468 case INTRINS_SSE_PSLLI_D
:
8469 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8470 arg_types
[0] = ret_type
;
8471 arg_types
[1] = LLVMInt32Type ();
8472 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8474 case INTRINS_SSE_PSRLI_Q
:
8475 case INTRINS_SSE_PSLLI_Q
:
8476 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
8477 arg_types
[0] = ret_type
;
8478 arg_types
[1] = LLVMInt32Type ();
8479 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8481 case INTRINS_SSE_SQRT_PD
:
8483 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8484 arg_types
[0] = ret_type
;
8485 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8487 case INTRINS_SSE_SQRT_PS
:
8488 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8489 arg_types
[0] = ret_type
;
8490 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8492 case INTRINS_SSE_RSQRT_PS
:
8493 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8494 arg_types
[0] = ret_type
;
8495 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8497 case INTRINS_SSE_RCP_PS
:
8498 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8499 arg_types
[0] = ret_type
;
8500 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8502 case INTRINS_SSE_CVTTPD2DQ
:
8503 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8504 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8505 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8507 case INTRINS_SSE_CVTTPS2DQ
:
8508 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8509 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8510 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8512 case INTRINS_SSE_CVTDQ2PD
:
8513 /* Conversion ops */
8514 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8515 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8516 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8518 case INTRINS_SSE_CVTDQ2PS
:
8519 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8520 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8521 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8523 case INTRINS_SSE_CVTPD2DQ
:
8524 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8525 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8526 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8528 case INTRINS_SSE_CVTPS2DQ
:
8529 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8530 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8531 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8533 case INTRINS_SSE_CVTPD2PS
:
8534 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8535 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8536 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8538 case INTRINS_SSE_CVTPS2PD
:
8539 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8540 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8541 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8543 case INTRINS_SSE_CMPPD
:
8545 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8546 arg_types
[0] = ret_type
;
8547 arg_types
[1] = ret_type
;
8548 arg_types
[2] = LLVMInt8Type ();
8549 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8551 case INTRINS_SSE_CMPPS
:
8552 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8553 arg_types
[0] = ret_type
;
8554 arg_types
[1] = ret_type
;
8555 arg_types
[2] = LLVMInt8Type ();
8556 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8558 case INTRINS_SSE_PACKSSWB
:
8559 case INTRINS_SSE_PACKUSWB
:
8560 case INTRINS_SSE_PACKSSDW
:
8562 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
8563 arg_types
[0] = type_to_simd_type (MONO_TYPE_I2
);
8564 arg_types
[1] = type_to_simd_type (MONO_TYPE_I2
);
8565 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8567 case INTRINS_SSE_PACKUSDW
:
8568 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8569 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8570 arg_types
[1] = type_to_simd_type (MONO_TYPE_I4
);
8571 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8573 /* SSE Binary ops */
8574 case INTRINS_SSE_PADDSW
:
8575 case INTRINS_SSE_PSUBSW
:
8576 case INTRINS_SSE_PADDUSW
:
8577 case INTRINS_SSE_PSUBUSW
:
8578 case INTRINS_SSE_PAVGW
:
8579 case INTRINS_SSE_PMULHW
:
8580 case INTRINS_SSE_PMULHU
:
8581 add_sse_binary (module
, name
, MONO_TYPE_I2
);
8583 case INTRINS_SSE_MINPS
:
8584 case INTRINS_SSE_MAXPS
:
8585 case INTRINS_SSE_HADDPS
:
8586 case INTRINS_SSE_HSUBPS
:
8587 case INTRINS_SSE_ADDSUBPS
:
8588 add_sse_binary (module
, name
, MONO_TYPE_R4
);
8590 case INTRINS_SSE_MINPD
:
8591 case INTRINS_SSE_MAXPD
:
8592 case INTRINS_SSE_HADDPD
:
8593 case INTRINS_SSE_HSUBPD
:
8594 case INTRINS_SSE_ADDSUBPD
:
8595 add_sse_binary (module
, name
, MONO_TYPE_R8
);
8597 case INTRINS_SE_PADDSB
:
8598 case INTRINS_SSE_PSUBSB
:
8599 case INTRINS_SSE_PADDUSB
:
8600 case INTRINS_SSE_PSUBUSB
:
8601 case INTRINS_SSE_PAVGB
:
8602 add_sse_binary (module
, name
, MONO_TYPE_I1
);
8604 case INTRINS_SSE_PAUSE
:
8605 AddFunc (module
, "llvm.x86.sse2.pause", LLVMVoidType (), NULL
, 0);
8607 case INTRINS_SSE_DPPS
:
8608 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8609 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8610 arg_types
[1] = type_to_simd_type (MONO_TYPE_R4
);
8611 #if LLVM_API_VERSION >= 500
8612 arg_types
[2] = LLVMInt8Type ();
8614 arg_types
[2] = LLVMInt32Type ();
8616 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8618 case INTRINS_SSE_ROUNDPD
:
8619 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8620 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8621 arg_types
[1] = LLVMInt32Type ();
8622 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8624 #endif /* AMD64 || X86 */
8626 g_assert_not_reached ();
8632 get_intrins (EmitContext
*ctx
, int id
)
8634 const char *name
= (const char*)g_hash_table_lookup (intrins_id_to_name
, GINT_TO_POINTER (id
));
8637 #if LLVM_API_VERSION > 100
8641 * Every method is emitted into its own module so
8642 * we can add intrinsics on demand.
8644 res
= ctx
->module
->intrins_by_id
[id
];
8646 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8648 add_intrinsic (ctx
->lmodule
, id
);
8649 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8652 ctx
->module
->intrins_by_id
[id
] = res
;
8658 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8665 get_intrins_by_name (EmitContext
*ctx
, const char *name
)
8667 #if LLVM_API_VERSION > 100
8671 * Every method is emitted into its own module so
8672 * we can add intrinsics on demand.
8674 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8678 /* No locking needed */
8679 id
= GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id
, name
));
8682 printf ("%s\n", name
);
8683 g_assert (id
!= -1);
8684 add_intrinsic (ctx
->lmodule
, id
);
8685 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8693 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8700 add_intrinsics (LLVMModuleRef module
)
8704 /* Emit declarations of instrinsics */
8706 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8707 * type doesn't seem to do any locking.
8709 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8710 add_intrinsic (module
, i
);
8714 AddFunc (module
, "mono_personality", LLVMVoidType (), NULL
, 0);
8716 AddFunc (module
, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL
, 0);
8719 /* Load/Store intrinsics */
8721 LLVMTypeRef arg_types
[5];
8725 for (i
= 1; i
<= 8; i
*= 2) {
8726 arg_types
[0] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8727 arg_types
[1] = LLVMInt32Type ();
8728 arg_types
[2] = LLVMInt1Type ();
8729 arg_types
[3] = LLVMInt32Type ();
8730 sprintf (name
, "llvm.mono.load.i%d.p0i%d", i
* 8, i
* 8);
8731 AddFunc (module
, name
, LLVMIntType (i
* 8), arg_types
, 4);
8733 arg_types
[0] = LLVMIntType (i
* 8);
8734 arg_types
[1] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8735 arg_types
[2] = LLVMInt32Type ();
8736 arg_types
[3] = LLVMInt1Type ();
8737 arg_types
[4] = LLVMInt32Type ();
8738 sprintf (name
, "llvm.mono.store.i%d.p0i%d", i
* 8, i
* 8);
8739 AddFunc (module
, name
, LLVMVoidType (), arg_types
, 5);
8745 add_types (MonoLLVMModule
*module
)
8747 module
->ptr_type
= LLVMPointerType (TARGET_SIZEOF_VOID_P
== 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8751 mono_llvm_init (void)
8756 mono_native_tls_alloc (¤t_cfg_tls_id
, NULL
);
8758 h
= g_hash_table_new (NULL
, NULL
);
8759 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8760 g_hash_table_insert (h
, GINT_TO_POINTER (intrinsics
[i
].id
), (gpointer
)intrinsics
[i
].name
);
8761 intrins_id_to_name
= h
;
8763 h
= g_hash_table_new (g_str_hash
, g_str_equal
);
8764 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8765 g_hash_table_insert (h
, (gpointer
)intrinsics
[i
].name
, GINT_TO_POINTER (intrinsics
[i
].id
+ 1));
8766 intrins_name_to_id
= h
;
8770 mono_llvm_cleanup (void)
8772 MonoLLVMModule
*module
= &aot_module
;
8774 if (module
->lmodule
)
8775 LLVMDisposeModule (module
->lmodule
);
8777 if (module
->context
)
8778 LLVMContextDispose (module
->context
);
8782 mono_llvm_free_domain_info (MonoDomain
*domain
)
8784 MonoJitDomainInfo
*info
= domain_jit_info (domain
);
8785 MonoLLVMModule
*module
= (MonoLLVMModule
*)info
->llvm_module
;
8791 g_hash_table_destroy (module
->llvm_types
);
8793 mono_llvm_dispose_ee (module
->mono_ee
);
8795 if (module
->bb_names
) {
8796 for (i
= 0; i
< module
->bb_names_len
; ++i
)
8797 g_free (module
->bb_names
[i
]);
8798 g_free (module
->bb_names
);
8800 //LLVMDisposeModule (module->module);
8804 info
->llvm_module
= NULL
;
8808 mono_llvm_create_aot_module (MonoAssembly
*assembly
, const char *global_prefix
, int initial_got_size
, LLVMModuleFlags flags
)
8810 MonoLLVMModule
*module
= &aot_module
;
8811 gboolean emit_dwarf
= (flags
& LLVM_MODULE_FLAG_DWARF
) ? 1 : 0;
8812 #ifdef TARGET_WIN32_MSVC
8813 gboolean emit_codeview
= (flags
& LLVM_MODULE_FLAG_CODEVIEW
) ? 1 : 0;
8815 gboolean static_link
= (flags
& LLVM_MODULE_FLAG_STATIC
) ? 1 : 0;
8816 gboolean llvm_only
= (flags
& LLVM_MODULE_FLAG_LLVM_ONLY
) ? 1 : 0;
8817 gboolean interp
= (flags
& LLVM_MODULE_FLAG_INTERP
) ? 1 : 0;
8818 gboolean llvm_disable_self_init
= mini_get_debug_options ()->llvm_disable_self_init
;
8820 /* Delete previous module */
8821 g_hash_table_destroy (module
->plt_entries
);
8822 if (module
->lmodule
)
8823 LLVMDisposeModule (module
->lmodule
);
8825 memset (module
, 0, sizeof (aot_module
));
8827 module
->lmodule
= LLVMModuleCreateWithName ("aot");
8828 module
->assembly
= assembly
;
8829 module
->global_prefix
= g_strdup (global_prefix
);
8830 module
->got_symbol
= g_strdup_printf ("%s_llvm_got", global_prefix
);
8831 module
->eh_frame_symbol
= g_strdup_printf ("%s_eh_frame", global_prefix
);
8832 module
->get_method_symbol
= g_strdup_printf ("%s_get_method", global_prefix
);
8833 module
->get_unbox_tramp_symbol
= g_strdup_printf ("%s_get_unbox_tramp", global_prefix
);
8834 module
->external_symbols
= TRUE
;
8835 module
->emit_dwarf
= emit_dwarf
;
8836 module
->static_link
= static_link
;
8837 module
->llvm_only
= llvm_only
;
8838 module
->llvm_disable_self_init
= llvm_disable_self_init
&& !llvm_only
; // llvm_only implies !llvm_disable_self_init
8839 module
->interp
= interp
;
8840 /* The first few entries are reserved */
8841 module
->max_got_offset
= initial_got_size
;
8842 module
->context
= LLVMGetGlobalContext ();
8843 module
->cfgs
= g_ptr_array_new ();
8844 module
->intrins_by_id
= g_new0 (LLVMValueRef
, INTRINS_NUM
);
8847 /* clang ignores our debug info because it has an invalid version */
8848 module
->emit_dwarf
= FALSE
;
8850 add_intrinsics (module
->lmodule
);
8853 #ifdef MONO_ARCH_LLVM_TARGET_LAYOUT
8854 LLVMSetDataLayout (module
->lmodule
, MONO_ARCH_LLVM_TARGET_LAYOUT
);
8857 #ifdef MONO_ARCH_LLVM_TARGET_TRIPLE
8858 LLVMSetTarget (module
->lmodule
, MONO_ARCH_LLVM_TARGET_TRIPLE
);
8861 #if LLVM_API_VERSION > 100
8862 if (module
->emit_dwarf
) {
8863 char *dir
, *build_info
, *s
, *cu_name
;
8865 module
->di_builder
= mono_llvm_create_di_builder (module
->lmodule
);
8868 dir
= g_strdup (".");
8869 build_info
= mono_get_runtime_build_info ();
8870 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
8871 cu_name
= g_path_get_basename (assembly
->image
->name
);
8872 module
->cu
= mono_llvm_di_create_compile_unit (module
->di_builder
, cu_name
, dir
, s
);
8874 g_free (build_info
);
8879 #ifdef TARGET_WIN32_MSVC
8880 if (emit_codeview
) {
8881 LLVMValueRef codeview_option_args
[3];
8883 codeview_option_args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8884 codeview_option_args
[1] = LLVMMDString ("CodeView", 8);
8885 codeview_option_args
[2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8887 LLVMAddNamedMetadataOperand (module
->lmodule
, "llvm.module.flags", LLVMMDNode (codeview_option_args
, G_N_ELEMENTS (codeview_option_args
)));
8891 const char linker_options
[] = "Linker Options";
8892 const char *default_dynamic_lib_names
[] = { "/DEFAULTLIB:msvcrt",
8893 "/DEFAULTLIB:ucrt.lib",
8894 "/DEFAULTLIB:vcruntime.lib" };
8896 LLVMValueRef linker_option_args
[3];
8897 LLVMValueRef default_lib_args
[G_N_ELEMENTS (default_dynamic_lib_names
)];
8898 LLVMValueRef default_lib_nodes
[G_N_ELEMENTS(default_dynamic_lib_names
)];
8900 const char *default_lib_name
= NULL
;
8901 for (int i
= 0; i
< G_N_ELEMENTS (default_dynamic_lib_names
); ++i
) {
8902 const char *default_lib_name
= default_dynamic_lib_names
[i
];
8903 default_lib_args
[i
] = LLVMMDString (default_lib_name
, strlen (default_lib_name
));
8904 default_lib_nodes
[i
] = LLVMMDNode (default_lib_args
+ i
, 1);
8907 #if LLVM_API_VERSION < 600
8908 linker_option_args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8909 linker_option_args
[1] = LLVMMDString (linker_options
, G_N_ELEMENTS (linker_options
) - 1);
8910 linker_option_args
[2] = LLVMMDNode (default_lib_nodes
, G_N_ELEMENTS (default_lib_nodes
));
8912 LLVMAddNamedMetadataOperand (module
->lmodule
, "llvm.module.flags", LLVMMDNode (linker_option_args
, G_N_ELEMENTS (linker_option_args
)));
8914 LLVMAddNamedMetadataOperand (module
->lmodule
, "llvm.linker.options", LLVMMDNode (default_lib_args
, G_N_ELEMENTS (default_lib_args
)));
8921 * We couldn't compute the type of the LLVM global representing the got because
8922 * its size is only known after all the methods have been emitted. So create
8923 * a dummy variable, and replace all uses it with the real got variable when
8924 * its size is known in mono_llvm_emit_aot_module ().
8927 LLVMTypeRef got_type
= LLVMArrayType (module
->ptr_type
, 0);
8929 module
->got_var
= LLVMAddGlobal (module
->lmodule
, got_type
, "mono_dummy_got");
8930 module
->got_idx_to_type
= g_hash_table_new (NULL
, NULL
);
8931 LLVMSetInitializer (module
->got_var
, LLVMConstNull (got_type
));
8934 /* Add initialization array */
8935 if (!llvm_disable_self_init
) {
8936 LLVMTypeRef inited_type
= LLVMArrayType (LLVMInt8Type (), 0);
8938 module
->inited_var
= LLVMAddGlobal (aot_module
.lmodule
, inited_type
, "mono_inited_tmp");
8939 LLVMSetInitializer (module
->inited_var
, LLVMConstNull (inited_type
));
8943 emit_gc_safepoint_poll (module
);
8945 emit_llvm_code_start (module
);
8947 // Needs idx_to_lmethod
8948 if (!llvm_disable_self_init
)
8949 emit_init_icall_wrappers (module
);
8951 /* Add a dummy personality function */
8952 if (!use_debug_personality
) {
8953 LLVMValueRef personality
= LLVMAddFunction (module
->lmodule
, default_personality_name
, LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
));
8954 LLVMSetLinkage (personality
, LLVMExternalLinkage
);
8956 //EMCC chockes if the personality function is referenced in the 'used' array
8958 mark_as_used (module
, personality
);
8962 /* Add a reference to the c++ exception we throw/catch */
8964 LLVMTypeRef exc
= LLVMPointerType (LLVMInt8Type (), 0);
8965 module
->sentinel_exception
= LLVMAddGlobal (module
->lmodule
, exc
, "_ZTIPi");
8966 LLVMSetLinkage (module
->sentinel_exception
, LLVMExternalLinkage
);
8967 mono_llvm_set_is_constant (module
->sentinel_exception
);
8970 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
8971 module
->plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
8972 module
->plt_entries_ji
= g_hash_table_new (NULL
, NULL
);
8973 module
->direct_callables
= g_hash_table_new (g_str_hash
, g_str_equal
);
8974 module
->method_to_lmethod
= g_hash_table_new (NULL
, NULL
);
8975 module
->idx_to_lmethod
= g_hash_table_new (NULL
, NULL
);
8976 module
->idx_to_unbox_tramp
= g_hash_table_new (NULL
, NULL
);
8977 module
->callsite_list
= g_ptr_array_new ();
8981 mono_llvm_fixup_aot_module (void)
8983 MonoLLVMModule
*module
= &aot_module
;
8986 if (module
->llvm_disable_self_init
)
8990 * Replace GOT entries for directly callable methods with the methods themselves.
8991 * It would be easier to implement this by predefining all methods before compiling
8992 * their bodies, but that couldn't handle the case when a method fails to compile
8996 GHashTable
*patches_to_null
= g_hash_table_new (mono_patch_info_hash
, mono_patch_info_equal
);
8997 for (int sindex
= 0; sindex
< module
->callsite_list
->len
; ++sindex
) {
8998 CallSite
*site
= (CallSite
*)g_ptr_array_index (module
->callsite_list
, sindex
);
8999 method
= site
->method
;
9000 LLVMValueRef lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, method
);
9002 LLVMValueRef placeholder
= (LLVMValueRef
)site
->load
;
9003 LLVMValueRef indexes
[2], got_entry_addr
, load
;
9006 if (lmethod
&& !(method
->iflags
& METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED
)) {
9007 mono_llvm_replace_uses_of (placeholder
, lmethod
);
9008 g_hash_table_insert (patches_to_null
, site
->ji
, site
->ji
);
9010 int got_offset
= compute_aot_got_offset (module
, site
->ji
, site
->type
);
9012 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
9014 LLVMBuilderRef builder
= LLVMCreateBuilder ();
9015 LLVMPositionBuilderBefore (builder
, placeholder
);
9016 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9017 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
9018 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
9020 name
= get_aotconst_name (site
->ji
->type
, site
->ji
->data
.target
, got_offset
);
9021 load
= LLVMBuildLoad (builder
, got_entry_addr
, "");
9022 load
= LLVMBuildBitCast (builder
, load
, site
->type
, name
? name
: "");
9023 LLVMReplaceAllUsesWith (placeholder
, load
);
9028 for (int i
= 0; i
< module
->cfgs
->len
; ++i
) {
9030 * Nullify the patches pointing to direct calls. This is needed to
9031 * avoid allocating extra got slots, which is a perf problem and it
9032 * makes module->max_got_offset invalid.
9033 * It would be better to just store the patch_info in CallSite, but
9034 * cfg->patch_info is copied in aot-compiler.c.
9036 MonoCompile
*cfg
= (MonoCompile
*)g_ptr_array_index (module
->cfgs
, i
);
9037 for (MonoJumpInfo
*patch_info
= cfg
->patch_info
; patch_info
; patch_info
= patch_info
->next
) {
9038 if (patch_info
->type
== MONO_PATCH_INFO_METHOD
) {
9039 if (g_hash_table_lookup (patches_to_null
, patch_info
)) {
9040 patch_info
->type
= MONO_PATCH_INFO_NONE
;
9041 /* Nullify the call to init_method () if possible */
9042 g_assert (cfg
->got_access_count
);
9043 cfg
->got_access_count
--;
9044 #if LLVM_API_VERSION >= 600
9045 if (cfg
->got_access_count
== 0) {
9046 LLVMValueRef br
= (LLVMValueRef
)cfg
->llvmonly_init_cond
;
9048 LLVMSetSuccessor (br
, 0, LLVMGetSuccessor (br
, 1));
9056 g_hash_table_destroy (patches_to_null
);
9060 llvm_array_from_uints (LLVMTypeRef el_type
, guint32
*values
, int nvalues
)
9063 LLVMValueRef res
, *vals
;
9065 vals
= g_new0 (LLVMValueRef
, nvalues
);
9066 for (i
= 0; i
< nvalues
; ++i
)
9067 vals
[i
] = LLVMConstInt (LLVMInt32Type (), values
[i
], FALSE
);
9068 res
= LLVMConstArray (LLVMInt32Type (), vals
, nvalues
);
9074 llvm_array_from_bytes (guint8
*values
, int nvalues
)
9077 LLVMValueRef res
, *vals
;
9079 vals
= g_new0 (LLVMValueRef
, nvalues
);
9080 for (i
= 0; i
< nvalues
; ++i
)
9081 vals
[i
] = LLVMConstInt (LLVMInt8Type (), values
[i
], FALSE
);
9082 res
= LLVMConstArray (LLVMInt8Type (), vals
, nvalues
);
9087 * mono_llvm_emit_aot_file_info:
9089 * Emit the MonoAotFileInfo structure.
9090 * Same as emit_aot_file_info () in aot-compiler.c.
9093 mono_llvm_emit_aot_file_info (MonoAotFileInfo
*info
, gboolean has_jitted_code
)
9095 MonoLLVMModule
*module
= &aot_module
;
9097 /* Save these for later */
9098 memcpy (&module
->aot_info
, info
, sizeof (MonoAotFileInfo
));
9099 module
->has_jitted_code
= has_jitted_code
;
9103 * mono_llvm_emit_aot_data:
9105 * Emit the binary data DATA pointed to by symbol SYMBOL.
9108 mono_llvm_emit_aot_data (const char *symbol
, guint8
*data
, int data_len
)
9110 MonoLLVMModule
*module
= &aot_module
;
9114 type
= LLVMArrayType (LLVMInt8Type (), data_len
);
9115 d
= LLVMAddGlobal (module
->lmodule
, type
, symbol
);
9116 LLVMSetVisibility (d
, LLVMHiddenVisibility
);
9117 LLVMSetLinkage (d
, LLVMInternalLinkage
);
9118 LLVMSetInitializer (d
, mono_llvm_create_constant_data_array (data
, data_len
));
9119 LLVMSetAlignment (d
, 8);
9120 mono_llvm_set_is_constant (d
);
9123 /* Add a reference to a global defined in JITted code */
9125 AddJitGlobal (MonoLLVMModule
*module
, LLVMTypeRef type
, const char *name
)
9130 s
= g_strdup_printf ("%s%s", module
->global_prefix
, name
);
9131 v
= LLVMAddGlobal (module
->lmodule
, LLVMInt8Type (), s
);
9132 LLVMSetVisibility (v
, LLVMHiddenVisibility
);
9138 emit_aot_file_info (MonoLLVMModule
*module
)
9140 LLVMTypeRef file_info_type
;
9141 LLVMTypeRef
*eltypes
, eltype
;
9142 LLVMValueRef info_var
;
9143 LLVMValueRef
*fields
;
9144 int i
, nfields
, tindex
;
9145 MonoAotFileInfo
*info
;
9146 LLVMModuleRef lmodule
= module
->lmodule
;
9148 info
= &module
->aot_info
;
9150 /* Create an LLVM type to represent MonoAotFileInfo */
9151 nfields
= 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS
+ 21 + 5;
9152 eltypes
= g_new (LLVMTypeRef
, nfields
);
9154 eltypes
[tindex
++] = LLVMInt32Type ();
9155 eltypes
[tindex
++] = LLVMInt32Type ();
9157 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
)
9158 eltypes
[tindex
++] = LLVMPointerType (LLVMInt8Type (), 0);
9160 for (i
= 0; i
< 20; ++i
)
9161 eltypes
[tindex
++] = LLVMInt32Type ();
9163 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM
);
9164 for (i
= 0; i
< 4; ++i
)
9165 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM
);
9166 eltypes
[tindex
++] = LLVMArrayType (LLVMInt8Type (), 16);
9167 g_assert (tindex
== nfields
);
9168 file_info_type
= LLVMStructCreateNamed (module
->context
, "MonoAotFileInfo");
9169 LLVMStructSetBody (file_info_type
, eltypes
, nfields
, FALSE
);
9171 info_var
= LLVMAddGlobal (lmodule
, file_info_type
, "mono_aot_file_info");
9172 if (module
->static_link
) {
9173 LLVMSetVisibility (info_var
, LLVMHiddenVisibility
);
9174 LLVMSetLinkage (info_var
, LLVMInternalLinkage
);
9178 if (!module
->static_link
) {
9179 LLVMSetDLLStorageClass (info_var
, LLVMDLLExportStorageClass
);
9183 fields
= g_new (LLVMValueRef
, nfields
);
9185 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->version
, FALSE
);
9186 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->dummy
, FALSE
);
9190 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
9191 * for symbols defined in the .s file emitted by the aot compiler.
9193 eltype
= eltypes
[tindex
];
9194 if (module
->llvm_only
)
9195 fields
[tindex
++] = LLVMConstNull (eltype
);
9197 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_got");
9198 fields
[tindex
++] = module
->got_var
;
9199 /* llc defines this directly */
9200 if (!module
->llvm_only
) {
9201 fields
[tindex
++] = LLVMAddGlobal (lmodule
, eltype
, module
->eh_frame_symbol
);
9202 fields
[tindex
++] = module
->get_method
;
9203 fields
[tindex
++] = LLVMConstNull (eltype
);
9205 fields
[tindex
++] = LLVMConstNull (eltype
);
9206 fields
[tindex
++] = module
->get_method
;
9207 fields
[tindex
++] = module
->get_unbox_tramp
? module
->get_unbox_tramp
: LLVMConstNull (eltype
);
9209 if (module
->has_jitted_code
) {
9210 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_start");
9211 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_end");
9213 fields
[tindex
++] = LLVMConstNull (eltype
);
9214 fields
[tindex
++] = LLVMConstNull (eltype
);
9216 if (!module
->llvm_only
)
9217 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "method_addresses");
9219 fields
[tindex
++] = LLVMConstNull (eltype
);
9220 if (module
->llvm_only
&& module
->unbox_tramp_indexes
) {
9221 fields
[tindex
++] = module
->unbox_tramp_indexes
;
9222 fields
[tindex
++] = module
->unbox_trampolines
;
9224 fields
[tindex
++] = LLVMConstNull (eltype
);
9225 fields
[tindex
++] = LLVMConstNull (eltype
);
9227 if (info
->flags
& MONO_AOT_FILE_FLAG_SEPARATE_DATA
) {
9228 for (i
= 0; i
< MONO_AOT_TABLE_NUM
; ++i
)
9229 fields
[tindex
++] = LLVMConstNull (eltype
);
9231 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "blob");
9232 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_name_table");
9233 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_info_offsets");
9234 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "method_info_offsets");
9235 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "ex_info_offsets");
9236 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_info_offsets");
9237 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_table");
9238 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "got_info_offsets");
9239 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "llvm_got_info_offsets");
9240 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "image_table");
9241 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "weak_field_indexes");
9243 /* Not needed (mem_end) */
9244 fields
[tindex
++] = LLVMConstNull (eltype
);
9245 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_guid");
9246 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "runtime_version");
9247 if (info
->trampoline_size
[0]) {
9248 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "specific_trampolines");
9249 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "static_rgctx_trampolines");
9250 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "imt_trampolines");
9251 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "gsharedvt_arg_trampolines");
9252 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "ftnptr_arg_trampolines");
9253 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_arbitrary_trampolines");
9255 fields
[tindex
++] = LLVMConstNull (eltype
);
9256 fields
[tindex
++] = LLVMConstNull (eltype
);
9257 fields
[tindex
++] = LLVMConstNull (eltype
);
9258 fields
[tindex
++] = LLVMConstNull (eltype
);
9259 fields
[tindex
++] = LLVMConstNull (eltype
);
9260 fields
[tindex
++] = LLVMConstNull (eltype
);
9262 if (module
->static_link
&& !module
->llvm_only
)
9263 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "globals");
9265 fields
[tindex
++] = LLVMConstNull (eltype
);
9266 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_name");
9267 if (!module
->llvm_only
) {
9268 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt");
9269 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt_end");
9270 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unwind_info");
9271 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines");
9272 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines_end");
9273 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampoline_addresses");
9275 fields
[tindex
++] = LLVMConstNull (eltype
);
9276 fields
[tindex
++] = LLVMConstNull (eltype
);
9277 fields
[tindex
++] = LLVMConstNull (eltype
);
9278 fields
[tindex
++] = LLVMConstNull (eltype
);
9279 fields
[tindex
++] = LLVMConstNull (eltype
);
9280 fields
[tindex
++] = LLVMConstNull (eltype
);
9283 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
) {
9284 g_assert (fields
[2 + i
]);
9285 fields
[2 + i
] = LLVMConstBitCast (fields
[2 + i
], eltype
);
9289 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_got_offset_base
, FALSE
);
9290 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->got_size
, FALSE
);
9291 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_size
, FALSE
);
9292 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nmethods
, FALSE
);
9293 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nextra_methods
, FALSE
);
9294 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->flags
, FALSE
);
9295 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->opts
, FALSE
);
9296 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->simd_opts
, FALSE
);
9297 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->gc_name_index
, FALSE
);
9298 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->num_rgctx_fetch_trampolines
, FALSE
);
9299 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->double_align
, FALSE
);
9300 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->long_align
, FALSE
);
9301 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->generic_tramp_num
, FALSE
);
9302 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->card_table_shift_bits
, FALSE
);
9303 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->card_table_mask
, FALSE
);
9304 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->tramp_page_size
, FALSE
);
9305 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nshared_got_entries
, FALSE
);
9306 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->datafile_size
, FALSE
);
9307 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), module
->unbox_tramp_num
, FALSE
);
9308 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), module
->unbox_tramp_elemsize
, FALSE
);
9310 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->table_offsets
, MONO_AOT_TABLE_NUM
);
9311 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->num_trampolines
, MONO_AOT_TRAMP_NUM
);
9312 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_got_offset_base
, MONO_AOT_TRAMP_NUM
);
9313 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_size
, MONO_AOT_TRAMP_NUM
);
9314 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->tramp_page_code_offsets
, MONO_AOT_TRAMP_NUM
);
9316 fields
[tindex
++] = llvm_array_from_bytes (info
->aotid
, 16);
9317 g_assert (tindex
== nfields
);
9319 LLVMSetInitializer (info_var
, LLVMConstNamedStruct (file_info_type
, fields
, nfields
));
9321 if (module
->static_link
) {
9325 s
= g_strdup_printf ("mono_aot_module_%s_info", module
->assembly
->aname
.name
);
9326 /* Get rid of characters which cannot occur in symbols */
9328 for (p
= s
; *p
; ++p
) {
9329 if (!(isalnum (*p
) || *p
== '_'))
9332 var
= LLVMAddGlobal (module
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), s
);
9334 LLVMSetInitializer (var
, LLVMConstBitCast (LLVMGetNamedGlobal (module
->lmodule
, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
9335 LLVMSetLinkage (var
, LLVMExternalLinkage
);
9340 * Emit the aot module into the LLVM bitcode file FILENAME.
9343 mono_llvm_emit_aot_module (const char *filename
, const char *cu_name
)
9345 LLVMTypeRef got_type
, inited_type
;
9346 LLVMValueRef real_got
, real_inited
;
9347 MonoLLVMModule
*module
= &aot_module
;
9349 emit_llvm_code_end (module
);
9352 * Create the real got variable and replace all uses of the dummy variable with
9355 int size
= module
->max_got_offset
+ 1;
9356 LLVMTypeRef
*members
= g_malloc0 (sizeof (LLVMValueRef
) * size
);
9357 for (int i
= 0; i
< size
; i
++) {
9358 LLVMTypeRef lookup_type
= NULL
;
9360 lookup_type
= g_hash_table_lookup (module
->got_idx_to_type
, GINT_TO_POINTER (i
));
9363 lookup_type
= module
->ptr_type
;
9365 members
[i
] = LLVMPointerType (lookup_type
, 0);
9368 got_type
= LLVMStructCreateNamed (module
->context
, g_strdup_printf ("MONO_GOT_%s", cu_name
));
9369 LLVMStructSetBody (got_type
, members
, size
, FALSE
);
9370 real_got
= LLVMAddGlobal (module
->lmodule
, got_type
, module
->got_symbol
);
9372 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
9373 if (module
->external_symbols
) {
9374 LLVMSetLinkage (real_got
, LLVMExternalLinkage
);
9375 LLVMSetVisibility (real_got
, LLVMHiddenVisibility
);
9377 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
9379 mono_llvm_replace_uses_of (module
->got_var
, real_got
);
9381 mark_as_used (&aot_module
, real_got
);
9383 /* Delete the dummy got so it doesn't become a global */
9384 LLVMDeleteGlobal (module
->got_var
);
9385 module
->got_var
= real_got
;
9388 * Same for the init_var
9390 if (!module
->llvm_disable_self_init
) {
9391 inited_type
= LLVMArrayType (LLVMInt8Type (), module
->max_inited_idx
+ 1);
9392 real_inited
= LLVMAddGlobal (module
->lmodule
, inited_type
, "mono_inited");
9393 LLVMSetInitializer (real_inited
, LLVMConstNull (inited_type
));
9394 LLVMSetLinkage (real_inited
, LLVMInternalLinkage
);
9395 mono_llvm_replace_uses_of (module
->inited_var
, real_inited
);
9396 LLVMDeleteGlobal (module
->inited_var
);
9398 emit_get_method (&aot_module
);
9399 emit_get_unbox_tramp (&aot_module
);
9402 emit_llvm_used (&aot_module
);
9403 emit_dbg_info (&aot_module
, filename
, cu_name
);
9404 emit_aot_file_info (&aot_module
);
9406 /* Replace PLT entries for directly callable methods with the methods themselves */
9408 GHashTableIter iter
;
9410 LLVMValueRef callee
;
9412 g_hash_table_iter_init (&iter
, module
->plt_entries_ji
);
9413 while (g_hash_table_iter_next (&iter
, (void**)&ji
, (void**)&callee
)) {
9414 if (mono_aot_is_direct_callable (ji
)) {
9415 LLVMValueRef lmethod
;
9417 lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, ji
->data
.method
);
9418 /* The types might not match because the caller might pass an rgctx */
9419 if (lmethod
&& LLVMTypeOf (callee
) == LLVMTypeOf (lmethod
)) {
9420 mono_llvm_replace_uses_of (callee
, lmethod
);
9421 mono_aot_mark_unused_llvm_plt_entry (ji
);
9427 /* Note: You can still dump an invalid bitcode file by running `llvm-dis`
9428 * in a debugger, set a breakpoint on `LLVMVerifyModule` and fake its
9429 * result to 0 (indicating success). */
9430 LLVMWriteBitcodeToFile (module
->lmodule
, filename
);
9436 if (LLVMVerifyModule (module
->lmodule
, LLVMReturnStatusAction
, &verifier_err
)) {
9437 printf ("%s\n", verifier_err
);
9438 g_assert_not_reached ();
9446 md_string (const char *s
)
9448 return LLVMMDString (s
, strlen (s
));
9451 /* Debugging support */
9454 emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
)
9456 LLVMModuleRef lmodule
= module
->lmodule
;
9457 LLVMValueRef args
[16], ver
;
9460 * This can only be enabled when LLVM code is emitted into a separate object
9461 * file, since the AOT compiler also emits dwarf info,
9462 * and the abbrev indexes will not be correct since llvm has added its own
9465 if (!module
->emit_dwarf
)
9468 #if LLVM_API_VERSION > 100
9469 mono_llvm_di_builder_finalize (module
->di_builder
);
9471 LLVMValueRef cu_args
[16], cu
;
9473 char *build_info
, *s
, *dir
;
9476 * Emit dwarf info in the form of LLVM metadata. There is some
9477 * out-of-date documentation at:
9478 * http://llvm.org/docs/SourceLevelDebugging.html
9479 * but most of this was gathered from the llvm and
9484 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit
, FALSE
);
9485 /* CU name/compilation dir */
9486 dir
= g_path_get_dirname (filename
);
9487 args
[0] = LLVMMDString (cu_name
, strlen (cu_name
));
9488 args
[1] = LLVMMDString (dir
, strlen (dir
));
9489 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 2);
9492 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99
, FALSE
);
9494 build_info
= mono_get_runtime_build_info ();
9495 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
9496 cu_args
[n_cuargs
++] = LLVMMDString (s
, strlen (s
));
9497 g_free (build_info
);
9499 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9501 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
9502 /* Runtime version */
9503 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9505 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9506 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9508 if (module
->subprogram_mds
) {
9512 mds
= g_new0 (LLVMValueRef
, module
->subprogram_mds
->len
);
9513 for (i
= 0; i
< module
->subprogram_mds
->len
; ++i
)
9514 mds
[i
] = (LLVMValueRef
)g_ptr_array_index (module
->subprogram_mds
, i
);
9515 cu_args
[n_cuargs
++] = LLVMMDNode (mds
, module
->subprogram_mds
->len
);
9517 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9520 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9521 /* Imported modules */
9522 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9524 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
9525 /* DebugEmissionKind = FullDebug */
9526 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9527 cu
= LLVMMDNode (cu_args
, n_cuargs
);
9528 LLVMAddNamedMetadataOperand (lmodule
, "llvm.dbg.cu", cu
);
9531 #if LLVM_API_VERSION > 100
9532 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9533 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9534 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9535 ver
= LLVMMDNode (args
, 3);
9536 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9538 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9539 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9540 args
[2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE
);
9541 ver
= LLVMMDNode (args
, 3);
9542 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9544 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9545 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9546 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9547 ver
= LLVMMDNode (args
, 3);
9548 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9550 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9551 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9552 args
[2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9553 ver
= LLVMMDNode (args
, 3);
9554 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9559 emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
)
9561 MonoLLVMModule
*module
= ctx
->module
;
9562 MonoDebugMethodInfo
*minfo
= ctx
->minfo
;
9563 char *source_file
, *dir
, *filename
;
9564 LLVMValueRef md
, args
[16], ctx_args
[16], md_args
[64], type_args
[16], ctx_md
, type_md
;
9565 MonoSymSeqPoint
*sym_seq_points
;
9571 mono_debug_get_seq_points (minfo
, &source_file
, NULL
, NULL
, &sym_seq_points
, &n_seq_points
);
9573 source_file
= g_strdup ("<unknown>");
9574 dir
= g_path_get_dirname (source_file
);
9575 filename
= g_path_get_basename (source_file
);
9577 #if LLVM_API_VERSION > 100
9578 return (LLVMValueRef
)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);
9581 ctx_args
[0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE
);
9582 args
[0] = md_string (filename
);
9583 args
[1] = md_string (dir
);
9584 ctx_args
[1] = LLVMMDNode (args
, 2);
9585 ctx_md
= LLVMMDNode (ctx_args
, 2);
9587 type_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type
, FALSE
);
9588 type_args
[1] = NULL
;
9589 type_args
[2] = NULL
;
9590 type_args
[3] = LLVMMDString ("", 0);
9591 type_args
[4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9592 type_args
[5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9593 type_args
[6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9594 type_args
[7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9595 type_args
[8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9596 type_args
[9] = NULL
;
9597 type_args
[10] = NULL
;
9598 type_args
[11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9599 type_args
[12] = NULL
;
9600 type_args
[13] = NULL
;
9601 type_args
[14] = NULL
;
9602 type_md
= LLVMMDNode (type_args
, 14);
9604 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9605 md_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram
, FALSE
);
9606 /* Source directory + file pair */
9607 args
[0] = md_string (filename
);
9608 args
[1] = md_string (dir
);
9609 md_args
[1] = LLVMMDNode (args
,2);
9610 md_args
[2] = ctx_md
;
9611 md_args
[3] = md_string (cfg
->method
->name
);
9612 md_args
[4] = md_string (name
);
9613 md_args
[5] = md_string (name
);
9616 md_args
[6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points
[0].line
, FALSE
);
9618 md_args
[6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9620 md_args
[7] = type_md
;
9622 md_args
[8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
9624 md_args
[9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
9626 md_args
[10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9627 /* Index into a virtual function */
9628 md_args
[11] = NULL
;
9629 md_args
[12] = NULL
;
9631 md_args
[13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
9633 md_args
[14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
9634 /* Pointer to LLVM function */
9635 md_args
[15] = method
;
9636 /* Function template parameter */
9637 md_args
[16] = NULL
;
9638 /* Function declaration descriptor */
9639 md_args
[17] = NULL
;
9640 /* List of function variables */
9641 md_args
[18] = LLVMMDNode (args
, 0);
9643 md_args
[19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9644 md
= LLVMMDNode (md_args
, 20);
9646 if (!module
->subprogram_mds
)
9647 module
->subprogram_mds
= g_ptr_array_new ();
9648 g_ptr_array_add (module
->subprogram_mds
, md
);
9652 g_free (source_file
);
9653 g_free (sym_seq_points
);
9659 emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
)
9661 MonoCompile
*cfg
= ctx
->cfg
;
9663 if (ctx
->minfo
&& cil_code
&& cil_code
>= cfg
->header
->code
&& cil_code
< cfg
->header
->code
+ cfg
->header
->code_size
) {
9664 MonoDebugSourceLocation
*loc
;
9665 LLVMValueRef loc_md
;
9667 loc
= mono_debug_method_lookup_location (ctx
->minfo
, cil_code
- cfg
->header
->code
);
9670 #if LLVM_API_VERSION > 100
9671 loc_md
= (LLVMValueRef
)mono_llvm_di_create_location (ctx
->module
->di_builder
, ctx
->dbg_md
, loc
->row
, loc
->column
);
9672 mono_llvm_di_set_location (builder
, loc_md
);
9674 LLVMValueRef md_args
[16];
9678 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->row
, FALSE
);
9679 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->column
, FALSE
);
9680 md_args
[nmd_args
++] = ctx
->dbg_md
;
9681 md_args
[nmd_args
++] = NULL
;
9682 loc_md
= LLVMMDNode (md_args
, nmd_args
);
9683 LLVMSetCurrentDebugLocation (builder
, loc_md
);
9685 mono_debug_free_source_location (loc
);
9691 emit_default_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
)
9693 #if LLVM_API_VERSION > 100
9695 LLVMValueRef loc_md
;
9696 loc_md
= (LLVMValueRef
)mono_llvm_di_create_location (ctx
->module
->di_builder
, ctx
->dbg_md
, 0, 0);
9697 mono_llvm_di_set_location (builder
, loc_md
);
9700 /* Older llvm versions don't require this */
9705 default_mono_llvm_unhandled_exception (void)
9707 MonoJitTlsData
*jit_tls
= mono_get_jit_tls ();
9708 MonoObject
*target
= mono_gchandle_get_target_internal (jit_tls
->thrown_exc
);
9710 mono_unhandled_exception_internal (target
);
9711 mono_invoke_unhandled_exception_hook (target
);
9712 g_assert_not_reached ();
9717 - Emit LLVM IR from the mono IR using the LLVM C API.
9718 - The original arch specific code remains, so we can fall back to it if we run
9719 into something we can't handle.
9723 A partial list of issues:
9724 - Handling of opcodes which can throw exceptions.
9726 In the mono JIT, these are implemented using code like this:
9733 push throw_pos - method
9734 call <exception trampoline>
9736 The problematic part is push throw_pos - method, which cannot be represented
9737 in the LLVM IR, since it does not support label values.
9738 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9739 be implemented in JIT mode ?
9740 -> a possible but slower implementation would use the normal exception
9741 throwing code but it would need to control the placement of the throw code
9742 (it needs to be exactly after the compare+branch).
9743 -> perhaps add a PC offset intrinsics ?
9745 - efficient implementation of .ovf opcodes.
9747 These are currently implemented as:
9748 <ins which sets the condition codes>
9751 Some overflow opcodes are now supported by LLVM SVN.
9753 - exception handling, unwinding.
9754 - SSA is disabled for methods with exception handlers
9755 - How to obtain unwind info for LLVM compiled methods ?
9756 -> this is now solved by converting the unwind info generated by LLVM
9758 - LLVM uses the c++ exception handling framework, while we use our home grown
9759 code, and couldn't use the c++ one:
9760 - its not supported under VC++, other exotic platforms.
9761 - it might be impossible to support filter clauses with it.
9765 The trampolines need a predictable call sequence, since they need to disasm
9766 the calling code to obtain register numbers / offsets.
9768 LLVM currently generates this code in non-JIT mode:
9769 mov -0x98(%rax),%eax
9771 Here, the vtable pointer is lost.
9772 -> solution: use one vtable trampoline per class.
9774 - passing/receiving the IMT pointer/RGCTX.
9775 -> solution: pass them as normal arguments ?
9779 LLVM does not allow the specification of argument registers etc. This means
9780 that all calls are made according to the platform ABI.
9782 - passing/receiving vtypes.
9784 Vtypes passed/received in registers are handled by the front end by using
9785 a signature with scalar arguments, and loading the parts of the vtype into those
9788 Vtypes passed on the stack are handled using the 'byval' attribute.
9792 Supported though alloca, we need to emit the load/store code.
9796 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9797 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9798 This is made easier because the IR is already in SSA form.
9799 An additional problem is that our IR is not consistent with types, i.e. i32/i64
9800 types are frequently used incorrectly.
9805 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9806 it with the file containing the methods emitted by the JIT and the AOT data
9810 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9811 * - each bblock should end with a branch
9812 * - setting the return value, making cfg->ret non-volatile
9813 * - avoid some transformations in the JIT which make it harder for us to generate
9815 * - use pointer types to help optimizations.
9818 #else /* DISABLE_JIT */
9821 mono_llvm_cleanup (void)
9826 mono_llvm_free_domain_info (MonoDomain
*domain
)
9831 mono_llvm_init (void)
9836 default_mono_llvm_unhandled_exception (void)
9840 #endif /* DISABLE_JIT */
9842 #if !defined(DISABLE_JIT) && !defined(MONO_CROSS_COMPILE)
9844 /* LLVM JIT support */
9846 static unsigned char*
9847 alloc_cb (LLVMValueRef function
, int size
)
9851 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
9855 return (unsigned char*)mono_domain_code_reserve (cfg
->domain
, size
);
9857 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size
);
9862 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
9866 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
9868 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
9872 exception_cb (void *data
)
9875 MonoJitExceptionInfo
*ei
;
9876 guint32 ei_len
, i
, j
, nested_len
, nindex
;
9877 gpointer
*type_info
;
9878 int this_reg
, this_offset
;
9880 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
9884 * data points to a DWARF FDE structure, convert it to our unwind format and
9886 * An alternative would be to save it directly, and modify our unwinder to work
9889 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
);
9890 if (cfg
->verbose_level
> 1)
9891 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
9893 /* Count nested clauses */
9895 for (i
= 0; i
< ei_len
; ++i
) {
9896 gint32 cindex1
= *(gint32
*)type_info
[i
];
9897 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
9899 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
9901 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
9903 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
9909 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
9910 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
9911 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
9912 /* Fill the rest of the information from the type info */
9913 for (i
= 0; i
< ei_len
; ++i
) {
9914 gint32 clause_index
= *(gint32
*)type_info
[i
];
9915 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
9917 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
9918 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
9919 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
9923 * For nested clauses, the LLVM produced exception info associates the try interval with
9924 * the innermost handler, while mono expects it to be associated with all nesting clauses.
9925 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
9926 * and everything else from the nested clause.
9929 for (i
= 0; i
< ei_len
; ++i
) {
9930 gint32 cindex1
= *(gint32
*)type_info
[i
];
9931 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
9933 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
9935 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
9936 MonoJitExceptionInfo
*nesting_ei
, *nested_ei
;
9938 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
9939 /* clause1 is the nested clause */
9940 nested_ei
= &cfg
->llvm_ex_info
[i
];
9941 nesting_ei
= &cfg
->llvm_ex_info
[nindex
];
9944 memcpy (nesting_ei
, nested_ei
, sizeof (MonoJitExceptionInfo
));
9946 nesting_ei
->flags
= clause2
->flags
;
9947 nesting_ei
->data
.catch_class
= clause2
->data
.catch_class
;
9948 nesting_ei
->clause_index
= cindex2
;
9952 g_assert (nindex
== ei_len
+ nested_len
);
9953 cfg
->llvm_this_reg
= this_reg
;
9954 cfg
->llvm_this_offset
= this_offset
;
9956 /* type_info [i] is cfg mempool allocated, no need to free it */
9963 dlsym_cb (const char *name
, void **symbol
)
9969 if (!strcmp (name
, "__bzero")) {
9970 *symbol
= (void*)bzero
;
9972 current
= mono_dl_open (NULL
, 0, NULL
);
9975 err
= mono_dl_symbol (current
, name
, symbol
);
9977 mono_dl_close (current
);
9979 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
9980 *symbol
= (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8
*)(*symbol
));
9986 * decode_llvm_eh_info:
9988 * Decode the EH table emitted by llvm in jit mode, and store
9989 * the result into cfg.
9992 decode_llvm_eh_info (EmitContext
*ctx
, gpointer eh_frame
)
9994 MonoCompile
*cfg
= ctx
->cfg
;
9997 MonoLLVMFDEInfo info
;
9998 MonoJitExceptionInfo
*ei
;
9999 guint8
*p
= (guint8
*)eh_frame
;
10000 int version
, fde_count
, fde_offset
;
10001 guint32 ei_len
, i
, nested_len
;
10002 gpointer
*type_info
;
10007 * Decode the one element EH table emitted by the MonoException class
10011 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
10014 g_assert (version
== 3);
10017 p
= (guint8
*)ALIGN_PTR_TO (p
, 4);
10019 fde_count
= *(guint32
*)p
;
10021 table
= (gint32
*)p
;
10023 g_assert (fde_count
<= 2);
10025 /* The first entry is the real method */
10026 g_assert (table
[0] == 1);
10027 fde_offset
= table
[1];
10028 table
+= fde_count
* 2;
10030 cfg
->code_len
= table
[0];
10031 fde_len
= table
[1] - fde_offset
;
10034 fde
= (guint8
*)eh_frame
+ fde_offset
;
10035 cie
= (guint8
*)table
;
10037 /* Compute lengths */
10038 mono_unwind_decode_llvm_mono_fde (fde
, fde_len
, cie
, cfg
->native_code
, &info
, NULL
, NULL
, NULL
);
10040 ei
= (MonoJitExceptionInfo
*)g_malloc0 (info
.ex_info_len
* sizeof (MonoJitExceptionInfo
));
10041 type_info
= (gpointer
*)g_malloc0 (info
.ex_info_len
* sizeof (gpointer
));
10042 unw_info
= (guint8
*)g_malloc0 (info
.unw_info_len
);
10044 mono_unwind_decode_llvm_mono_fde (fde
, fde_len
, cie
, cfg
->native_code
, &info
, ei
, type_info
, unw_info
);
10046 cfg
->encoded_unwind_ops
= unw_info
;
10047 cfg
->encoded_unwind_ops_len
= info
.unw_info_len
;
10048 if (cfg
->verbose_level
> 1)
10049 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
10050 if (info
.this_reg
!= -1) {
10051 cfg
->llvm_this_reg
= info
.this_reg
;
10052 cfg
->llvm_this_offset
= info
.this_offset
;
10055 ei_len
= info
.ex_info_len
;
10057 // Nested clauses are currently disabled
10060 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
10061 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
10062 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
10063 /* Fill the rest of the information from the type info */
10064 for (i
= 0; i
< ei_len
; ++i
) {
10065 gint32 clause_index
= *(gint32
*)type_info
[i
];
10066 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
10068 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
10069 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
10070 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
10075 init_jit_module (MonoDomain
*domain
)
10077 MonoJitDomainInfo
*dinfo
;
10078 MonoLLVMModule
*module
;
10081 dinfo
= domain_jit_info (domain
);
10082 if (dinfo
->llvm_module
)
10085 mono_loader_lock ();
10087 if (dinfo
->llvm_module
) {
10088 mono_loader_unlock ();
10092 module
= g_new0 (MonoLLVMModule
, 1);
10094 name
= g_strdup_printf ("mono-%s", domain
->friendly_name
);
10095 module
->lmodule
= LLVMModuleCreateWithName (name
);
10096 module
->context
= LLVMGetGlobalContext ();
10097 module
->intrins_by_id
= g_new0 (LLVMValueRef
, INTRINS_NUM
);
10099 module
->mono_ee
= (MonoEERef
*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module
->lmodule
), alloc_cb
, emitted_cb
, exception_cb
, dlsym_cb
, &module
->ee
);
10101 add_intrinsics (module
->lmodule
);
10102 add_types (module
);
10104 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
10106 mono_memory_barrier ();
10108 dinfo
->llvm_module
= module
;
10110 mono_loader_unlock ();
10114 llvm_jit_finalize_method (EmitContext
*ctx
)
10116 MonoCompile
*cfg
= ctx
->cfg
;
10118 #if LLVM_API_VERSION > 100
10119 MonoDomain
*domain
= mono_domain_get ();
10120 MonoJitDomainInfo
*domain_info
;
10121 int nvars
= g_hash_table_size (ctx
->jit_callees
);
10122 LLVMValueRef
*callee_vars
= g_new0 (LLVMValueRef
, nvars
);
10123 gpointer
*callee_addrs
= g_new0 (gpointer
, nvars
);
10124 GHashTableIter iter
;
10126 MonoMethod
*callee
;
10131 * Compute the addresses of the LLVM globals pointing to the
10132 * methods called by the current method. Pass it to the trampoline
10133 * code so it can update them after their corresponding method was
10136 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
10138 while (g_hash_table_iter_next (&iter
, NULL
, (void**)&var
))
10139 callee_vars
[i
++] = var
;
10141 cfg
->native_code
= (guint8
*)mono_llvm_compile_method (ctx
->module
->mono_ee
, ctx
->lmethod
, nvars
, callee_vars
, callee_addrs
, &eh_frame
);
10143 decode_llvm_eh_info (ctx
, eh_frame
);
10145 mono_domain_lock (domain
);
10146 domain_info
= domain_jit_info (domain
);
10147 if (!domain_info
->llvm_jit_callees
)
10148 domain_info
->llvm_jit_callees
= g_hash_table_new (NULL
, NULL
);
10149 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
10151 while (g_hash_table_iter_next (&iter
, (void**)&callee
, (void**)&var
)) {
10152 GSList
*addrs
= (GSList
*)g_hash_table_lookup (domain_info
->llvm_jit_callees
, callee
);
10153 addrs
= g_slist_prepend (addrs
, callee_addrs
[i
]);
10154 g_hash_table_insert (domain_info
->llvm_jit_callees
, callee
, addrs
);
10157 mono_domain_unlock (domain
);
10159 g_assert_not_reached ();
10166 init_jit_module (MonoDomain
*domain
)
10168 g_assert_not_reached ();
10172 llvm_jit_finalize_method (EmitContext
*ctx
)
10174 g_assert_not_reached ();