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
*method_to_call_info
;
69 GHashTable
*lvalue_to_lcalls
;
70 GHashTable
*direct_callables
;
75 GPtrArray
*subprogram_mds
;
77 LLVMExecutionEngineRef ee
;
78 gboolean external_symbols
;
81 LLVMValueRef personality
;
82 LLVMValueRef
*intrins_by_id
;
85 MonoAssembly
*assembly
;
87 MonoAotFileInfo aot_info
;
88 const char *jit_got_symbol
;
89 const char *eh_frame_symbol
;
90 LLVMValueRef get_method
, get_unbox_tramp
;
91 LLVMValueRef init_method
, init_method_gshared_mrgctx
, init_method_gshared_this
, init_method_gshared_vtable
;
92 LLVMValueRef code_start
, code_end
;
93 LLVMValueRef inited_var
;
94 LLVMValueRef unbox_tramp_indexes
;
95 LLVMValueRef unbox_trampolines
;
96 int max_inited_idx
, max_method_idx
;
97 gboolean has_jitted_code
;
100 gboolean llvm_disable_self_init
;
102 GHashTable
*idx_to_lmethod
;
103 GHashTable
*idx_to_unbox_tramp
;
104 GPtrArray
*callsite_list
;
105 LLVMContextRef context
;
106 LLVMValueRef sentinel_exception
;
107 void *di_builder
, *cu
;
108 GHashTable
*objc_selector_to_var
;
110 int unbox_tramp_num
, unbox_tramp_elemsize
;
111 GHashTable
*got_idx_to_type
;
115 * Information associated by the backend with mono basic blocks.
118 LLVMBasicBlockRef bblock
, end_bblock
;
119 LLVMValueRef finally_ind
;
120 gboolean added
, invoke_target
;
122 * If this bblock is the start of a finally clause, this is a list of bblocks it
123 * needs to branch to in ENDFINALLY.
125 GSList
*call_handler_return_bbs
;
127 * If this bblock is the start of a finally clause, this is the bblock that
128 * CALL_HANDLER needs to branch to.
130 LLVMBasicBlockRef call_handler_target_bb
;
131 /* The list of switch statements generated by ENDFINALLY instructions */
132 GSList
*endfinally_switch_ins_list
;
137 * Structure containing emit state
140 MonoMemPool
*mempool
;
142 /* Maps method names to the corresponding LLVMValueRef */
143 GHashTable
*emitted_method_decls
;
146 LLVMValueRef lmethod
;
147 MonoLLVMModule
*module
;
148 LLVMModuleRef lmodule
;
150 int sindex
, default_index
, ex_index
;
151 LLVMBuilderRef builder
;
152 LLVMValueRef
*values
, *addresses
;
153 MonoType
**vreg_cli_types
;
155 MonoMethodSignature
*sig
;
157 GHashTable
*region_to_handler
;
158 GHashTable
*clause_to_handler
;
159 LLVMBuilderRef alloca_builder
;
160 LLVMValueRef last_alloca
;
161 LLVMValueRef rgctx_arg
;
162 LLVMValueRef this_arg
;
163 LLVMTypeRef
*vreg_types
;
165 LLVMTypeRef method_type
;
166 LLVMBasicBlockRef init_bb
, inited_bb
;
168 gboolean
*unreachable
;
170 gboolean has_got_access
;
171 gboolean emit_dummy_arg
;
172 int this_arg_pindex
, rgctx_arg_pindex
;
173 LLVMValueRef imt_rgctx_loc
;
174 GHashTable
*llvm_types
;
176 MonoDebugMethodInfo
*minfo
;
177 /* For every clause, the clauses it is nested in */
180 GHashTable
*exc_meta
;
181 GPtrArray
*callsite_list
;
182 GPtrArray
*phi_values
;
183 GPtrArray
*bblock_list
;
185 GHashTable
*jit_callees
;
186 LLVMValueRef long_bb_break_var
;
192 MonoBasicBlock
*in_bb
;
197 * Instruction metadata
198 * This is the same as ins_info, but LREG != IREG.
206 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
207 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
214 /* keep in sync with the enum in mini.h */
216 mini_llvm_ins_info
[] = {
217 #include "mini-ops.h"
222 #if TARGET_SIZEOF_VOID_P == 4
223 #define GET_LONG_IMM(ins) ((ins)->inst_l)
225 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
228 #define LLVM_INS_INFO(opcode) (&mini_llvm_ins_info [((opcode) - OP_START - 1) * 4])
231 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
233 #define TRACE_FAILURE(msg)
237 #define IS_TARGET_X86 1
239 #define IS_TARGET_X86 0
243 #define IS_TARGET_AMD64 1
245 #define IS_TARGET_AMD64 0
248 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
250 static LLVMIntPredicate cond_to_llvm_cond
[] = {
263 static LLVMRealPredicate fpcond_to_llvm_cond
[] = {
279 INTRINS_SADD_OVF_I32
,
280 INTRINS_UADD_OVF_I32
,
281 INTRINS_SSUB_OVF_I32
,
282 INTRINS_USUB_OVF_I32
,
283 INTRINS_SMUL_OVF_I32
,
284 INTRINS_UMUL_OVF_I32
,
285 INTRINS_SADD_OVF_I64
,
286 INTRINS_UADD_OVF_I64
,
287 INTRINS_SSUB_OVF_I64
,
288 INTRINS_USUB_OVF_I64
,
289 INTRINS_SMUL_OVF_I64
,
290 INTRINS_UMUL_OVF_I64
,
302 #if defined(TARGET_AMD64) || defined(TARGET_X86)
303 INTRINS_SSE_PMOVMSKB
,
314 INTRINS_SSE_RSQRT_PS
,
316 INTRINS_SSE_CVTTPD2DQ
,
317 INTRINS_SSE_CVTTPS2DQ
,
318 INTRINS_SSE_CVTDQ2PD
,
319 INTRINS_SSE_CVTDQ2PS
,
320 INTRINS_SSE_CVTPD2DQ
,
321 INTRINS_SSE_CVTPS2DQ
,
322 INTRINS_SSE_CVTPD2PS
,
323 INTRINS_SSE_CVTPS2PD
,
326 INTRINS_SSE_PACKSSWB
,
327 INTRINS_SSE_PACKUSWB
,
328 INTRINS_SSE_PACKSSDW
,
329 INTRINS_SSE_PACKUSDW
,
334 INTRINS_SSE_ADDSUBPS
,
339 INTRINS_SSE_ADDSUBPD
,
359 static MonoNativeTlsKey current_cfg_tls_id
;
361 static MonoLLVMModule aot_module
;
363 static GHashTable
*intrins_id_to_name
;
364 static GHashTable
*intrins_name_to_id
;
366 static void init_jit_module (MonoDomain
*domain
);
368 static void emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
);
369 static void emit_default_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
);
370 static LLVMValueRef
emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
);
371 static void emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
);
372 static void emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
);
373 static LLVMValueRef
get_intrins_by_name (EmitContext
*ctx
, const char *name
);
374 static LLVMValueRef
get_intrins (EmitContext
*ctx
, int id
);
375 static void llvm_jit_finalize_method (EmitContext
*ctx
);
376 static void mono_llvm_nonnull_state_update (EmitContext
*ctx
, LLVMValueRef lcall
, MonoMethod
*call_method
, LLVMValueRef
*args
, int num_params
);
377 static void mono_llvm_propagate_nonnull_final (GHashTable
*all_specializable
, MonoLLVMModule
*module
);
380 set_failure (EmitContext
*ctx
, const char *message
)
382 TRACE_FAILURE (reason
);
383 ctx
->cfg
->exception_message
= g_strdup (message
);
384 ctx
->cfg
->disable_llvm
= TRUE
;
390 * The LLVM type with width == TARGET_SIZEOF_VOID_P
395 return TARGET_SIZEOF_VOID_P
== 8 ? LLVMInt64Type () : LLVMInt32Type ();
401 return TARGET_SIZEOF_VOID_P
== 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
407 return TARGET_SIZEOF_VOID_P
== 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
413 * Return the size of the LLVM representation of the vtype T.
416 get_vtype_size (MonoType
*t
)
420 size
= mono_class_value_size (mono_class_from_mono_type_internal (t
), NULL
);
422 /* LLVMArgAsIArgs depends on this since it stores whole words */
423 while (size
< 2 * TARGET_SIZEOF_VOID_P
&& mono_is_power_of_two (size
) == -1)
430 * simd_class_to_llvm_type:
432 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
435 simd_class_to_llvm_type (EmitContext
*ctx
, MonoClass
*klass
)
437 const char *klass_name
= m_class_get_name (klass
);
438 if (!strcmp (klass_name
, "Vector2d")) {
439 return LLVMVectorType (LLVMDoubleType (), 2);
440 } else if (!strcmp (klass_name
, "Vector2l")) {
441 return LLVMVectorType (LLVMInt64Type (), 2);
442 } else if (!strcmp (klass_name
, "Vector2ul")) {
443 return LLVMVectorType (LLVMInt64Type (), 2);
444 } else if (!strcmp (klass_name
, "Vector4i")) {
445 return LLVMVectorType (LLVMInt32Type (), 4);
446 } else if (!strcmp (klass_name
, "Vector4ui")) {
447 return LLVMVectorType (LLVMInt32Type (), 4);
448 } else if (!strcmp (klass_name
, "Vector4f")) {
449 return LLVMVectorType (LLVMFloatType (), 4);
450 } else if (!strcmp (klass_name
, "Vector8s")) {
451 return LLVMVectorType (LLVMInt16Type (), 8);
452 } else if (!strcmp (klass_name
, "Vector8us")) {
453 return LLVMVectorType (LLVMInt16Type (), 8);
454 } else if (!strcmp (klass_name
, "Vector16sb")) {
455 return LLVMVectorType (LLVMInt8Type (), 16);
456 } else if (!strcmp (klass_name
, "Vector16b")) {
457 return LLVMVectorType (LLVMInt8Type (), 16);
458 } else if (!strcmp (klass_name
, "Vector2")) {
459 /* System.Numerics */
460 return LLVMVectorType (LLVMFloatType (), 4);
461 } else if (!strcmp (klass_name
, "Vector3")) {
462 return LLVMVectorType (LLVMFloatType (), 4);
463 } else if (!strcmp (klass_name
, "Vector4")) {
464 return LLVMVectorType (LLVMFloatType (), 4);
465 } else if (!strcmp (klass_name
, "Vector`1")) {
466 MonoType
*etype
= mono_class_get_generic_class (klass
)->context
.class_inst
->type_argv
[0];
467 switch (etype
->type
) {
470 return LLVMVectorType (LLVMInt8Type (), 16);
473 return LLVMVectorType (LLVMInt16Type (), 8);
476 return LLVMVectorType (LLVMInt32Type (), 4);
479 return LLVMVectorType (LLVMInt64Type (), 2);
481 return LLVMVectorType (LLVMFloatType (), 4);
483 return LLVMVectorType (LLVMDoubleType (), 2);
485 g_assert_not_reached ();
489 printf ("%s\n", klass_name
);
495 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
496 static inline G_GNUC_UNUSED LLVMTypeRef
497 type_to_simd_type (int type
)
501 return LLVMVectorType (LLVMInt8Type (), 16);
503 return LLVMVectorType (LLVMInt16Type (), 8);
505 return LLVMVectorType (LLVMInt32Type (), 4);
507 return LLVMVectorType (LLVMInt64Type (), 2);
509 return LLVMVectorType (LLVMDoubleType (), 2);
511 return LLVMVectorType (LLVMFloatType (), 4);
513 g_assert_not_reached ();
519 create_llvm_type_for_type (MonoLLVMModule
*module
, MonoClass
*klass
)
521 int i
, size
, nfields
, esize
;
522 LLVMTypeRef
*eltypes
;
527 t
= m_class_get_byval_arg (klass
);
529 if (mini_type_is_hfa (t
, &nfields
, &esize
)) {
531 * This is needed on arm64 where HFAs are returned in
534 /* SIMD types have size 16 in mono_class_value_size () */
535 if (m_class_is_simd_type (klass
))
538 eltypes
= g_new (LLVMTypeRef
, size
);
539 for (i
= 0; i
< size
; ++i
)
540 eltypes
[i
] = esize
== 4 ? LLVMFloatType () : LLVMDoubleType ();
542 size
= get_vtype_size (t
);
544 eltypes
= g_new (LLVMTypeRef
, size
);
545 for (i
= 0; i
< size
; ++i
)
546 eltypes
[i
] = LLVMInt8Type ();
549 name
= mono_type_full_name (m_class_get_byval_arg (klass
));
550 ltype
= LLVMStructCreateNamed (module
->context
, name
);
551 LLVMStructSetBody (ltype
, eltypes
, size
, FALSE
);
561 * Return the LLVM type corresponding to T.
564 type_to_llvm_type (EmitContext
*ctx
, MonoType
*t
)
569 t
= mini_get_underlying_type (t
);
573 return LLVMVoidType ();
575 return LLVMInt8Type ();
577 return LLVMInt16Type ();
579 return LLVMInt32Type ();
581 return LLVMInt8Type ();
583 return LLVMInt16Type ();
585 return LLVMInt32Type ();
588 return LLVMInt64Type ();
590 return LLVMFloatType ();
592 return LLVMDoubleType ();
595 return IntPtrType ();
596 case MONO_TYPE_OBJECT
:
598 return ObjRefType ();
601 /* Because of generic sharing */
602 return ObjRefType ();
603 case MONO_TYPE_GENERICINST
:
604 if (!mono_type_generic_inst_is_valuetype (t
))
605 return ObjRefType ();
607 case MONO_TYPE_VALUETYPE
:
608 case MONO_TYPE_TYPEDBYREF
: {
612 klass
= mono_class_from_mono_type_internal (t
);
614 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
615 return simd_class_to_llvm_type (ctx
, klass
);
617 if (m_class_is_enumtype (klass
))
618 return type_to_llvm_type (ctx
, mono_class_enum_basetype_internal (klass
));
620 ltype
= (LLVMTypeRef
)g_hash_table_lookup (ctx
->module
->llvm_types
, klass
);
622 ltype
= create_llvm_type_for_type (ctx
->module
, klass
);
623 g_hash_table_insert (ctx
->module
->llvm_types
, klass
, ltype
);
629 printf ("X: %d\n", t
->type
);
630 ctx
->cfg
->exception_message
= g_strdup_printf ("type %s", mono_type_full_name (t
));
631 ctx
->cfg
->disable_llvm
= TRUE
;
639 * Return whenever T is an unsigned int type.
642 type_is_unsigned (EmitContext
*ctx
, MonoType
*t
)
644 t
= mini_get_underlying_type (t
);
660 * type_to_llvm_arg_type:
662 * Same as type_to_llvm_type, but treat i8/i16 as i32.
665 type_to_llvm_arg_type (EmitContext
*ctx
, MonoType
*t
)
667 LLVMTypeRef ptype
= type_to_llvm_type (ctx
, t
);
669 if (ctx
->cfg
->llvm_only
)
673 * This works on all abis except arm64/ios which passes multiple
674 * arguments in one stack slot.
677 if (ptype
== LLVMInt8Type () || ptype
== LLVMInt16Type ()) {
679 * LLVM generates code which only sets the lower bits, while JITted
680 * code expects all the bits to be set.
682 ptype
= LLVMInt32Type ();
690 * llvm_type_to_stack_type:
692 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
695 static G_GNUC_UNUSED LLVMTypeRef
696 llvm_type_to_stack_type (MonoCompile
*cfg
, LLVMTypeRef type
)
700 if (type
== LLVMInt8Type ())
701 return LLVMInt32Type ();
702 else if (type
== LLVMInt16Type ())
703 return LLVMInt32Type ();
704 else if (!cfg
->r4fp
&& type
== LLVMFloatType ())
705 return LLVMDoubleType ();
711 * regtype_to_llvm_type:
713 * Return the LLVM type corresponding to the regtype C used in instruction
717 regtype_to_llvm_type (char c
)
721 return LLVMInt32Type ();
723 return LLVMInt64Type ();
725 return LLVMDoubleType ();
734 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
737 op_to_llvm_type (int opcode
)
742 return LLVMInt8Type ();
745 return LLVMInt8Type ();
748 return LLVMInt16Type ();
751 return LLVMInt16Type ();
754 return LLVMInt32Type ();
757 return LLVMInt32Type ();
759 return LLVMInt64Type ();
761 return LLVMFloatType ();
763 return LLVMDoubleType ();
765 return LLVMInt64Type ();
767 return LLVMInt32Type ();
769 return LLVMInt64Type ();
774 return LLVMInt8Type ();
779 return LLVMInt16Type ();
781 return LLVMInt32Type ();
784 return TARGET_SIZEOF_VOID_P
== 8 ? LLVMInt64Type () : LLVMInt32Type ();
791 return LLVMInt32Type ();
798 return LLVMInt64Type ();
800 printf ("%s\n", mono_inst_name (opcode
));
801 g_assert_not_reached ();
806 #define CLAUSE_START(clause) ((clause)->try_offset)
807 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
810 * load_store_to_llvm_type:
812 * Return the size/sign/zero extension corresponding to the load/store opcode
816 load_store_to_llvm_type (int opcode
, int *size
, gboolean
*sext
, gboolean
*zext
)
822 case OP_LOADI1_MEMBASE
:
823 case OP_STOREI1_MEMBASE_REG
:
824 case OP_STOREI1_MEMBASE_IMM
:
825 case OP_ATOMIC_LOAD_I1
:
826 case OP_ATOMIC_STORE_I1
:
829 return LLVMInt8Type ();
830 case OP_LOADU1_MEMBASE
:
832 case OP_ATOMIC_LOAD_U1
:
833 case OP_ATOMIC_STORE_U1
:
836 return LLVMInt8Type ();
837 case OP_LOADI2_MEMBASE
:
838 case OP_STOREI2_MEMBASE_REG
:
839 case OP_STOREI2_MEMBASE_IMM
:
840 case OP_ATOMIC_LOAD_I2
:
841 case OP_ATOMIC_STORE_I2
:
844 return LLVMInt16Type ();
845 case OP_LOADU2_MEMBASE
:
847 case OP_ATOMIC_LOAD_U2
:
848 case OP_ATOMIC_STORE_U2
:
851 return LLVMInt16Type ();
852 case OP_LOADI4_MEMBASE
:
853 case OP_LOADU4_MEMBASE
:
856 case OP_STOREI4_MEMBASE_REG
:
857 case OP_STOREI4_MEMBASE_IMM
:
858 case OP_ATOMIC_LOAD_I4
:
859 case OP_ATOMIC_STORE_I4
:
860 case OP_ATOMIC_LOAD_U4
:
861 case OP_ATOMIC_STORE_U4
:
863 return LLVMInt32Type ();
864 case OP_LOADI8_MEMBASE
:
866 case OP_STOREI8_MEMBASE_REG
:
867 case OP_STOREI8_MEMBASE_IMM
:
868 case OP_ATOMIC_LOAD_I8
:
869 case OP_ATOMIC_STORE_I8
:
870 case OP_ATOMIC_LOAD_U8
:
871 case OP_ATOMIC_STORE_U8
:
873 return LLVMInt64Type ();
874 case OP_LOADR4_MEMBASE
:
875 case OP_STORER4_MEMBASE_REG
:
876 case OP_ATOMIC_LOAD_R4
:
877 case OP_ATOMIC_STORE_R4
:
879 return LLVMFloatType ();
880 case OP_LOADR8_MEMBASE
:
881 case OP_STORER8_MEMBASE_REG
:
882 case OP_ATOMIC_LOAD_R8
:
883 case OP_ATOMIC_STORE_R8
:
885 return LLVMDoubleType ();
886 case OP_LOAD_MEMBASE
:
888 case OP_STORE_MEMBASE_REG
:
889 case OP_STORE_MEMBASE_IMM
:
890 *size
= TARGET_SIZEOF_VOID_P
;
891 return IntPtrType ();
893 g_assert_not_reached ();
901 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
904 ovf_op_to_intrins (int opcode
)
908 return "llvm.sadd.with.overflow.i32";
910 return "llvm.uadd.with.overflow.i32";
912 return "llvm.ssub.with.overflow.i32";
914 return "llvm.usub.with.overflow.i32";
916 return "llvm.smul.with.overflow.i32";
918 return "llvm.umul.with.overflow.i32";
920 return "llvm.sadd.with.overflow.i64";
922 return "llvm.uadd.with.overflow.i64";
924 return "llvm.ssub.with.overflow.i64";
926 return "llvm.usub.with.overflow.i64";
928 return "llvm.smul.with.overflow.i64";
930 return "llvm.umul.with.overflow.i64";
932 g_assert_not_reached ();
938 simd_op_to_intrins (int opcode
)
941 #if defined(TARGET_X86) || defined(TARGET_AMD64)
943 return "llvm.x86.sse2.min.pd";
945 return "llvm.x86.sse.min.ps";
947 return "llvm.x86.sse2.max.pd";
949 return "llvm.x86.sse.max.ps";
951 return "llvm.x86.sse3.hadd.pd";
953 return "llvm.x86.sse3.hadd.ps";
955 return "llvm.x86.sse3.hsub.pd";
957 return "llvm.x86.sse3.hsub.ps";
959 return "llvm.x86.sse3.addsub.ps";
961 return "llvm.x86.sse3.addsub.pd";
962 case OP_EXTRACT_MASK
:
963 return "llvm.x86.sse2.pmovmskb.128";
966 return "llvm.x86.sse2.psrli.w";
969 return "llvm.x86.sse2.psrli.d";
972 return "llvm.x86.sse2.psrli.q";
975 return "llvm.x86.sse2.pslli.w";
978 return "llvm.x86.sse2.pslli.d";
981 return "llvm.x86.sse2.pslli.q";
984 return "llvm.x86.sse2.psrai.w";
987 return "llvm.x86.sse2.psrai.d";
989 return "llvm.x86.sse2.padds.b";
991 return "llvm.x86.sse2.padds.w";
993 return "llvm.x86.sse2.psubs.b";
995 return "llvm.x86.sse2.psubs.w";
996 case OP_PADDB_SAT_UN
:
997 return "llvm.x86.sse2.paddus.b";
998 case OP_PADDW_SAT_UN
:
999 return "llvm.x86.sse2.paddus.w";
1000 case OP_PSUBB_SAT_UN
:
1001 return "llvm.x86.sse2.psubus.b";
1002 case OP_PSUBW_SAT_UN
:
1003 return "llvm.x86.sse2.psubus.w";
1005 return "llvm.x86.sse2.pavg.b";
1007 return "llvm.x86.sse2.pavg.w";
1009 return "llvm.x86.sse.sqrt.ps";
1011 return "llvm.x86.sse2.sqrt.pd";
1013 return "llvm.x86.sse.rsqrt.ps";
1015 return "llvm.x86.sse.rcp.ps";
1017 return "llvm.x86.sse2.cvtdq2pd";
1019 return "llvm.x86.sse2.cvtdq2ps";
1021 return "llvm.x86.sse2.cvtpd2dq";
1023 return "llvm.x86.sse2.cvtps2dq";
1025 return "llvm.x86.sse2.cvtpd2ps";
1027 return "llvm.x86.sse2.cvtps2pd";
1029 return "llvm.x86.sse2.cvttpd2dq";
1031 return "llvm.x86.sse2.cvttps2dq";
1033 return "llvm.x86.sse2.packsswb.128";
1035 return "llvm.x86.sse2.packssdw.128";
1037 return "llvm.x86.sse2.packuswb.128";
1039 return "llvm.x86.sse41.packusdw";
1041 return "llvm.x86.sse2.pmulh.w";
1042 case OP_PMULW_HIGH_UN
:
1043 return "llvm.x86.sse2.pmulhu.w";
1045 return "llvm.x86.sse41.dpps";
1048 g_assert_not_reached ();
1054 simd_op_to_llvm_type (int opcode
)
1056 #if defined(TARGET_X86) || defined(TARGET_AMD64)
1060 return type_to_simd_type (MONO_TYPE_R8
);
1063 return type_to_simd_type (MONO_TYPE_I8
);
1066 return type_to_simd_type (MONO_TYPE_I4
);
1069 case OP_EXTRACTX_U2
:
1071 return type_to_simd_type (MONO_TYPE_I2
);
1075 return type_to_simd_type (MONO_TYPE_I1
);
1077 return type_to_simd_type (MONO_TYPE_R4
);
1080 return type_to_simd_type (MONO_TYPE_I4
);
1084 return type_to_simd_type (MONO_TYPE_R8
);
1088 return type_to_simd_type (MONO_TYPE_R4
);
1089 case OP_EXTRACT_MASK
:
1090 return type_to_simd_type (MONO_TYPE_I1
);
1096 return type_to_simd_type (MONO_TYPE_R4
);
1099 return type_to_simd_type (MONO_TYPE_R8
);
1101 g_assert_not_reached ();
1110 set_preserveall_cc (LLVMValueRef func
)
1113 * xcode10 (watchOS) and ARM/ARM64 doesn't seem to support preserveall, it fails with:
1114 * fatal error: error in backend: Unsupported calling convention
1116 #if !defined(TARGET_WATCHOS) && !defined(TARGET_ARM) && !defined(TARGET_ARM64)
1117 mono_llvm_set_preserveall_cc (func
);
1122 set_call_preserveall_cc (LLVMValueRef func
)
1124 #if !defined(TARGET_WATCHOS) && !defined(TARGET_ARM) && !defined(TARGET_ARM64)
1125 mono_llvm_set_call_preserveall_cc (func
);
1132 * Return the LLVM basic block corresponding to BB.
1134 static LLVMBasicBlockRef
1135 get_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
1137 char bb_name_buf
[128];
1140 if (ctx
->bblocks
[bb
->block_num
].bblock
== NULL
) {
1141 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
1142 int clause_index
= (mono_get_block_region_notry (ctx
->cfg
, bb
->region
) >> 8) - 1;
1143 sprintf (bb_name_buf
, "EH_CLAUSE%d_BB%d", clause_index
, bb
->block_num
);
1144 bb_name
= bb_name_buf
;
1145 } else if (bb
->block_num
< 256) {
1146 if (!ctx
->module
->bb_names
) {
1147 ctx
->module
->bb_names_len
= 256;
1148 ctx
->module
->bb_names
= g_new0 (char*, ctx
->module
->bb_names_len
);
1150 if (!ctx
->module
->bb_names
[bb
->block_num
]) {
1153 n
= g_strdup_printf ("BB%d", bb
->block_num
);
1154 mono_memory_barrier ();
1155 ctx
->module
->bb_names
[bb
->block_num
] = n
;
1157 bb_name
= ctx
->module
->bb_names
[bb
->block_num
];
1159 sprintf (bb_name_buf
, "BB%d", bb
->block_num
);
1160 bb_name
= bb_name_buf
;
1163 ctx
->bblocks
[bb
->block_num
].bblock
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1164 ctx
->bblocks
[bb
->block_num
].end_bblock
= ctx
->bblocks
[bb
->block_num
].bblock
;
1167 return ctx
->bblocks
[bb
->block_num
].bblock
;
1173 * Return the last LLVM bblock corresponding to BB.
1174 * This might not be equal to the bb returned by get_bb () since we need to generate
1175 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1177 static LLVMBasicBlockRef
1178 get_end_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
1181 return ctx
->bblocks
[bb
->block_num
].end_bblock
;
1184 static LLVMBasicBlockRef
1185 gen_bb (EmitContext
*ctx
, const char *prefix
)
1189 sprintf (bb_name
, "%s%d", prefix
, ++ ctx
->ex_index
);
1190 return LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1196 * Return the target of the patch identified by TYPE and TARGET.
1199 resolve_patch (MonoCompile
*cfg
, MonoJumpInfoType type
, gconstpointer target
)
1205 memset (&ji
, 0, sizeof (ji
));
1207 ji
.data
.target
= target
;
1209 res
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, &ji
, FALSE
, error
);
1210 mono_error_assert_ok (error
);
1218 * Emit code to convert the LLVM value V to DTYPE.
1221 convert_full (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
, gboolean is_unsigned
)
1223 LLVMTypeRef stype
= LLVMTypeOf (v
);
1225 if (stype
!= dtype
) {
1226 gboolean ext
= FALSE
;
1229 if (dtype
== LLVMInt64Type () && (stype
== LLVMInt32Type () || stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
1231 else if (dtype
== LLVMInt32Type () && (stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
1233 else if (dtype
== LLVMInt16Type () && (stype
== LLVMInt8Type ()))
1237 return is_unsigned
? LLVMBuildZExt (ctx
->builder
, v
, dtype
, "") : LLVMBuildSExt (ctx
->builder
, v
, dtype
, "");
1239 if (dtype
== LLVMDoubleType () && stype
== LLVMFloatType ())
1240 return LLVMBuildFPExt (ctx
->builder
, v
, dtype
, "");
1243 if (stype
== LLVMInt64Type () && (dtype
== LLVMInt32Type () || dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
1244 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1245 if (stype
== LLVMInt32Type () && (dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
1246 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1247 if (stype
== LLVMInt16Type () && dtype
== LLVMInt8Type ())
1248 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1249 if (stype
== LLVMDoubleType () && dtype
== LLVMFloatType ())
1250 return LLVMBuildFPTrunc (ctx
->builder
, v
, dtype
, "");
1252 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
1253 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1254 if (LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
1255 return LLVMBuildIntToPtr (ctx
->builder
, v
, dtype
, "");
1256 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
)
1257 return LLVMBuildPtrToInt (ctx
->builder
, v
, dtype
, "");
1259 if (mono_arch_is_soft_float ()) {
1260 if (stype
== LLVMInt32Type () && dtype
== LLVMFloatType ())
1261 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1262 if (stype
== LLVMInt32Type () && dtype
== LLVMDoubleType ())
1263 return LLVMBuildBitCast (ctx
->builder
, LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), ""), dtype
, "");
1266 if (LLVMGetTypeKind (stype
) == LLVMVectorTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMVectorTypeKind
)
1267 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1270 LLVMDumpValue (LLVMConstNull (dtype
));
1271 g_assert_not_reached ();
1279 convert (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
)
1281 return convert_full (ctx
, v
, dtype
, FALSE
);
1285 * emit_volatile_load:
1287 * If vreg is volatile, emit a load from its address.
1290 emit_volatile_load (EmitContext
*ctx
, int vreg
)
1295 // On arm64, we pass the rgctx in a callee saved
1296 // register on arm64 (x15), and llvm might keep the value in that register
1297 // even through the register is marked as 'reserved' inside llvm.
1299 v
= mono_llvm_build_load (ctx
->builder
, ctx
->addresses
[vreg
], "", TRUE
);
1300 t
= ctx
->vreg_cli_types
[vreg
];
1301 if (t
&& !t
->byref
) {
1303 * Might have to zero extend since llvm doesn't have
1306 if (t
->type
== MONO_TYPE_U1
|| t
->type
== MONO_TYPE_U2
|| t
->type
== MONO_TYPE_CHAR
|| t
->type
== MONO_TYPE_BOOLEAN
)
1307 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt32Type (), "");
1308 else if (t
->type
== MONO_TYPE_I1
|| t
->type
== MONO_TYPE_I2
)
1309 v
= LLVMBuildSExt (ctx
->builder
, v
, LLVMInt32Type (), "");
1310 else if (t
->type
== MONO_TYPE_U8
)
1311 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), "");
1318 * emit_volatile_store:
1320 * If VREG is volatile, emit a store from its value to its address.
1323 emit_volatile_store (EmitContext
*ctx
, int vreg
)
1325 MonoInst
*var
= get_vreg_to_inst (ctx
->cfg
, vreg
);
1327 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1328 g_assert (ctx
->addresses
[vreg
]);
1329 LLVMBuildStore (ctx
->builder
, convert (ctx
, ctx
->values
[vreg
], type_to_llvm_type (ctx
, var
->inst_vtype
)), ctx
->addresses
[vreg
]);
1334 sig_to_llvm_sig_no_cinfo (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1336 LLVMTypeRef ret_type
;
1337 LLVMTypeRef
*param_types
= NULL
;
1342 ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
1345 rtype
= mini_get_underlying_type (sig
->ret
);
1347 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 8) + 3);
1351 param_types
[pindex
++] = ThisType ();
1352 for (i
= 0; i
< sig
->param_count
; ++i
)
1353 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1355 if (!ctx_ok (ctx
)) {
1356 g_free (param_types
);
1360 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1361 g_free (param_types
);
1367 * sig_to_llvm_sig_full:
1369 * Return the LLVM signature corresponding to the mono signature SIG using the
1370 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1373 sig_to_llvm_sig_full (EmitContext
*ctx
, MonoMethodSignature
*sig
, LLVMCallInfo
*cinfo
)
1375 LLVMTypeRef ret_type
;
1376 LLVMTypeRef
*param_types
= NULL
;
1378 int i
, j
, pindex
, vret_arg_pindex
= 0;
1379 gboolean vretaddr
= FALSE
;
1383 return sig_to_llvm_sig_no_cinfo (ctx
, sig
);
1385 ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
1388 rtype
= mini_get_underlying_type (sig
->ret
);
1390 switch (cinfo
->ret
.storage
) {
1391 case LLVMArgVtypeInReg
:
1392 /* LLVM models this by returning an aggregate value */
1393 if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1394 LLVMTypeRef members
[2];
1396 members
[0] = IntPtrType ();
1397 ret_type
= LLVMStructType (members
, 1, FALSE
);
1398 } else if (cinfo
->ret
.pair_storage
[0] == LLVMArgNone
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1400 ret_type
= LLVMVoidType ();
1401 } else if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgInIReg
) {
1402 LLVMTypeRef members
[2];
1404 members
[0] = IntPtrType ();
1405 members
[1] = IntPtrType ();
1406 ret_type
= LLVMStructType (members
, 2, FALSE
);
1408 g_assert_not_reached ();
1411 case LLVMArgVtypeByVal
:
1412 /* Vtype returned normally by val */
1414 case LLVMArgVtypeAsScalar
: {
1415 int size
= mono_class_value_size (mono_class_from_mono_type_internal (rtype
), NULL
);
1416 /* LLVM models this by returning an int */
1417 if (size
< TARGET_SIZEOF_VOID_P
) {
1418 g_assert (cinfo
->ret
.nslots
== 1);
1419 ret_type
= LLVMIntType (size
* 8);
1421 g_assert (cinfo
->ret
.nslots
== 1 || cinfo
->ret
.nslots
== 2);
1422 ret_type
= LLVMIntType (cinfo
->ret
.nslots
* sizeof (target_mgreg_t
) * 8);
1426 case LLVMArgAsIArgs
:
1427 ret_type
= LLVMArrayType (IntPtrType (), cinfo
->ret
.nslots
);
1429 case LLVMArgFpStruct
: {
1430 /* Vtype returned as a fp struct */
1431 LLVMTypeRef members
[16];
1433 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1434 for (i
= 0; i
< cinfo
->ret
.nslots
; ++i
)
1435 members
[i
] = cinfo
->ret
.esize
== 8 ? LLVMDoubleType () : LLVMFloatType ();
1436 ret_type
= LLVMStructType (members
, cinfo
->ret
.nslots
, FALSE
);
1439 case LLVMArgVtypeByRef
:
1440 /* Vtype returned using a hidden argument */
1441 ret_type
= LLVMVoidType ();
1443 case LLVMArgVtypeRetAddr
:
1444 case LLVMArgGsharedvtFixed
:
1445 case LLVMArgGsharedvtFixedVtype
:
1446 case LLVMArgGsharedvtVariable
:
1448 ret_type
= LLVMVoidType ();
1454 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 8) + 3);
1456 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
) {
1458 * Has to be the first argument because of the sret argument attribute
1459 * FIXME: This might conflict with passing 'this' as the first argument, but
1460 * this is only used on arm64 which has a dedicated struct return register.
1462 cinfo
->vret_arg_pindex
= pindex
;
1463 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, sig
->ret
);
1464 if (!ctx_ok (ctx
)) {
1465 g_free (param_types
);
1468 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1471 if (!ctx
->llvm_only
&& cinfo
->rgctx_arg
) {
1472 cinfo
->rgctx_arg_pindex
= pindex
;
1473 param_types
[pindex
] = ctx
->module
->ptr_type
;
1476 if (cinfo
->imt_arg
) {
1477 cinfo
->imt_arg_pindex
= pindex
;
1478 param_types
[pindex
] = ctx
->module
->ptr_type
;
1482 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1483 vret_arg_pindex
= pindex
;
1484 if (cinfo
->vret_arg_index
== 1) {
1485 /* Add the slots consumed by the first argument */
1486 LLVMArgInfo
*ainfo
= &cinfo
->args
[0];
1487 switch (ainfo
->storage
) {
1488 case LLVMArgVtypeInReg
:
1489 for (j
= 0; j
< 2; ++j
) {
1490 if (ainfo
->pair_storage
[j
] == LLVMArgInIReg
)
1499 cinfo
->vret_arg_pindex
= vret_arg_pindex
;
1502 if (vretaddr
&& vret_arg_pindex
== pindex
)
1503 param_types
[pindex
++] = IntPtrType ();
1505 cinfo
->this_arg_pindex
= pindex
;
1506 param_types
[pindex
++] = ThisType ();
1507 cinfo
->args
[0].pindex
= cinfo
->this_arg_pindex
;
1509 if (vretaddr
&& vret_arg_pindex
== pindex
)
1510 param_types
[pindex
++] = IntPtrType ();
1511 for (i
= 0; i
< sig
->param_count
; ++i
) {
1512 LLVMArgInfo
*ainfo
= &cinfo
->args
[i
+ sig
->hasthis
];
1514 if (vretaddr
&& vret_arg_pindex
== pindex
)
1515 param_types
[pindex
++] = IntPtrType ();
1516 ainfo
->pindex
= pindex
;
1518 switch (ainfo
->storage
) {
1519 case LLVMArgVtypeInReg
:
1520 for (j
= 0; j
< 2; ++j
) {
1521 switch (ainfo
->pair_storage
[j
]) {
1523 param_types
[pindex
++] = LLVMIntType (TARGET_SIZEOF_VOID_P
* 8);
1528 g_assert_not_reached ();
1532 case LLVMArgVtypeByVal
:
1533 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1536 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1539 case LLVMArgAsIArgs
:
1540 if (ainfo
->esize
== 8)
1541 param_types
[pindex
] = LLVMArrayType (LLVMInt64Type (), ainfo
->nslots
);
1543 param_types
[pindex
] = LLVMArrayType (IntPtrType (), ainfo
->nslots
);
1546 case LLVMArgVtypeByRef
:
1547 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1550 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1553 case LLVMArgAsFpArgs
: {
1556 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1557 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
1558 param_types
[pindex
++] = LLVMDoubleType ();
1559 for (j
= 0; j
< ainfo
->nslots
; ++j
)
1560 param_types
[pindex
++] = ainfo
->esize
== 8 ? LLVMDoubleType () : LLVMFloatType ();
1563 case LLVMArgVtypeAsScalar
:
1564 g_assert_not_reached ();
1566 case LLVMArgGsharedvtFixed
:
1567 case LLVMArgGsharedvtFixedVtype
:
1568 param_types
[pindex
++] = LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0);
1570 case LLVMArgGsharedvtVariable
:
1571 param_types
[pindex
++] = LLVMPointerType (IntPtrType (), 0);
1574 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1578 if (!ctx_ok (ctx
)) {
1579 g_free (param_types
);
1582 if (vretaddr
&& vret_arg_pindex
== pindex
)
1583 param_types
[pindex
++] = IntPtrType ();
1584 if (ctx
->llvm_only
&& cinfo
->rgctx_arg
) {
1585 /* Pass the rgctx as the last argument */
1586 cinfo
->rgctx_arg_pindex
= pindex
;
1587 param_types
[pindex
] = ctx
->module
->ptr_type
;
1589 } else if (ctx
->llvm_only
&& cinfo
->dummy_arg
) {
1590 /* Pass a dummy arg last */
1591 cinfo
->dummy_arg_pindex
= pindex
;
1592 param_types
[pindex
] = ctx
->module
->ptr_type
;
1596 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1597 g_free (param_types
);
1603 sig_to_llvm_sig (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1605 return sig_to_llvm_sig_full (ctx
, sig
, NULL
);
1609 * LLVMFunctionType1:
1611 * Create an LLVM function type from the arguments.
1613 static G_GNUC_UNUSED LLVMTypeRef
1614 LLVMFunctionType0 (LLVMTypeRef ReturnType
,
1617 return LLVMFunctionType (ReturnType
, NULL
, 0, IsVarArg
);
1621 * LLVMFunctionType1:
1623 * Create an LLVM function type from the arguments.
1625 static G_GNUC_UNUSED LLVMTypeRef
1626 LLVMFunctionType1 (LLVMTypeRef ReturnType
,
1627 LLVMTypeRef ParamType1
,
1630 LLVMTypeRef param_types
[1];
1632 param_types
[0] = ParamType1
;
1634 return LLVMFunctionType (ReturnType
, param_types
, 1, IsVarArg
);
1638 * LLVMFunctionType2:
1640 * Create an LLVM function type from the arguments.
1642 static G_GNUC_UNUSED LLVMTypeRef
1643 LLVMFunctionType2 (LLVMTypeRef ReturnType
,
1644 LLVMTypeRef ParamType1
,
1645 LLVMTypeRef ParamType2
,
1648 LLVMTypeRef param_types
[2];
1650 param_types
[0] = ParamType1
;
1651 param_types
[1] = ParamType2
;
1653 return LLVMFunctionType (ReturnType
, param_types
, 2, IsVarArg
);
1657 * LLVMFunctionType3:
1659 * Create an LLVM function type from the arguments.
1661 static G_GNUC_UNUSED LLVMTypeRef
1662 LLVMFunctionType3 (LLVMTypeRef ReturnType
,
1663 LLVMTypeRef ParamType1
,
1664 LLVMTypeRef ParamType2
,
1665 LLVMTypeRef ParamType3
,
1668 LLVMTypeRef param_types
[3];
1670 param_types
[0] = ParamType1
;
1671 param_types
[1] = ParamType2
;
1672 param_types
[2] = ParamType3
;
1674 return LLVMFunctionType (ReturnType
, param_types
, 3, IsVarArg
);
1677 static G_GNUC_UNUSED LLVMTypeRef
1678 LLVMFunctionType5 (LLVMTypeRef ReturnType
,
1679 LLVMTypeRef ParamType1
,
1680 LLVMTypeRef ParamType2
,
1681 LLVMTypeRef ParamType3
,
1682 LLVMTypeRef ParamType4
,
1683 LLVMTypeRef ParamType5
,
1686 LLVMTypeRef param_types
[5];
1688 param_types
[0] = ParamType1
;
1689 param_types
[1] = ParamType2
;
1690 param_types
[2] = ParamType3
;
1691 param_types
[3] = ParamType4
;
1692 param_types
[4] = ParamType5
;
1694 return LLVMFunctionType (ReturnType
, param_types
, 5, IsVarArg
);
1700 * Create an LLVM builder and remember it so it can be freed later.
1702 static LLVMBuilderRef
1703 create_builder (EmitContext
*ctx
)
1705 LLVMBuilderRef builder
= LLVMCreateBuilder ();
1707 ctx
->builders
= g_slist_prepend_mempool (ctx
->cfg
->mempool
, ctx
->builders
, builder
);
1709 emit_default_dbg_loc (ctx
, builder
);
1715 get_aotconst_name (MonoJumpInfoType type
, gconstpointer data
, int got_offset
)
1720 case MONO_PATCH_INFO_JIT_ICALL_ID
:
1721 name
= g_strdup_printf ("jit_icall_%s", mono_find_jit_icall_info ((MonoJitICallId
)(gsize
)data
)->name
);
1723 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX
: {
1724 MonoJumpInfoRgctxEntry
*entry
= (MonoJumpInfoRgctxEntry
*)data
;
1725 name
= g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry
->info_type
));
1729 name
= g_strdup_printf ("%s_%d", mono_ji_type_to_string (type
), got_offset
);
1737 compute_aot_got_offset (MonoLLVMModule
*module
, MonoJumpInfo
*ji
, LLVMTypeRef llvm_type
)
1739 guint32 got_offset
= mono_aot_get_got_offset (ji
);
1741 LLVMTypeRef lookup_type
= (LLVMTypeRef
) g_hash_table_lookup (module
->got_idx_to_type
, GINT_TO_POINTER (got_offset
));
1744 lookup_type
= llvm_type
;
1745 } else if (llvm_type
!= lookup_type
) {
1746 lookup_type
= module
->ptr_type
;
1751 g_hash_table_insert (module
->got_idx_to_type
, GINT_TO_POINTER (got_offset
), lookup_type
);
1756 get_aotconst_typed (EmitContext
*ctx
, MonoJumpInfoType type
, gconstpointer data
, LLVMTypeRef llvm_type
)
1760 LLVMValueRef indexes
[2];
1761 LLVMValueRef got_entry_addr
, load
;
1762 LLVMBuilderRef builder
= ctx
->builder
;
1767 MonoJumpInfo tmp_ji
;
1769 tmp_ji
.data
.target
= data
;
1771 MonoJumpInfo
*ji
= mono_aot_patch_info_dup (&tmp_ji
);
1773 ji
->next
= cfg
->patch_info
;
1774 cfg
->patch_info
= ji
;
1776 got_offset
= compute_aot_got_offset (ctx
->module
, cfg
->patch_info
, llvm_type
);
1777 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
1779 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1780 * explicitly initialize it.
1782 if (!mono_aot_is_shared_got_offset (got_offset
)) {
1783 //mono_print_ji (ji);
1785 ctx
->cfg
->got_access_count
++;
1788 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1789 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
1790 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
1792 name
= get_aotconst_name (type
, data
, got_offset
);
1794 load
= LLVMBuildLoad (builder
, got_entry_addr
, "");
1795 load
= convert (ctx
, load
, llvm_type
);
1796 LLVMSetValueName (load
, name
? name
: "");
1798 load
= LLVMBuildLoad (builder
, got_entry_addr
, name
? name
: "");
1801 //set_invariant_load_flag (load);
1807 get_aotconst (EmitContext
*ctx
, MonoJumpInfoType type
, gconstpointer data
)
1809 return get_aotconst_typed (ctx
, type
, data
, NULL
);
1820 method_is_direct_callable (MonoMethod
*method
)
1822 if (method
->wrapper_type
== MONO_WRAPPER_ALLOC
)
1824 if (method
->string_ctor
)
1826 if (method
->wrapper_type
)
1828 if ((method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) || (method
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
))
1830 /* Can't enable this as the callee might fail llvm compilation */
1832 if (!method->is_inflated && (mono_class_get_flags (method->klass) & TYPE_ATTRIBUTE_PUBLIC) && (method->flags & METHOD_ATTRIBUTE_PUBLIC))
1839 get_callee_llvmonly (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1841 LLVMValueRef callee
;
1842 char *callee_name
= NULL
;
1844 if (ctx
->module
->static_link
&& ctx
->module
->assembly
->image
!= mono_get_corlib ()) {
1845 if (type
== MONO_PATCH_INFO_JIT_ICALL_ID
) {
1846 MonoJitICallInfo
* const info
= mono_find_jit_icall_info ((MonoJitICallId
)(gsize
)data
);
1848 if (info
->func
!= info
->wrapper
) {
1849 type
= MONO_PATCH_INFO_METHOD
;
1850 data
= mono_icall_get_wrapper_method (info
);
1851 callee_name
= mono_aot_get_mangled_method_name ((MonoMethod
*)data
);
1853 } else if (type
== MONO_PATCH_INFO_METHOD
) {
1854 MonoMethod
*method
= (MonoMethod
*)data
;
1855 if (m_class_get_image (method
->klass
) != ctx
->module
->assembly
->image
&& method_is_direct_callable (method
))
1856 callee_name
= mono_aot_get_mangled_method_name (method
);
1861 callee_name
= mono_aot_get_direct_call_symbol (type
, data
);
1863 /* Directly callable */
1865 callee
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->direct_callables
, callee_name
);
1867 callee
= LLVMAddFunction (ctx
->lmodule
, callee_name
, llvm_sig
);
1869 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1871 g_hash_table_insert (ctx
->module
->direct_callables
, (char*)callee_name
, callee
);
1873 /* LLVMTypeRef's are uniqued */
1874 if (LLVMGetElementType (LLVMTypeOf (callee
)) != llvm_sig
)
1875 return LLVMConstBitCast (callee
, LLVMPointerType (llvm_sig
, 0));
1877 g_free (callee_name
);
1883 * Change references to jit icalls to the icall wrappers when in corlib, so
1884 * they can be called directly.
1886 if (ctx
->module
->assembly
->image
== mono_get_corlib () && type
== MONO_PATCH_INFO_JIT_ICALL_ID
) {
1887 MonoJitICallInfo
* const info
= mono_find_jit_icall_info ((MonoJitICallId
)(gsize
)data
);
1889 if (info
->func
!= info
->wrapper
) {
1890 type
= MONO_PATCH_INFO_METHOD
;
1891 data
= mono_icall_get_wrapper_method (info
);
1896 * Instead of emitting an indirect call through a got slot, emit a placeholder, and
1897 * replace it with a direct call or an indirect call in mono_llvm_fixup_aot_module ()
1898 * after all methods have been emitted.
1900 if (type
== MONO_PATCH_INFO_METHOD
) {
1901 MonoMethod
*method
= (MonoMethod
*)data
;
1902 if (m_class_get_image (method
->klass
)->assembly
== ctx
->module
->assembly
) {
1903 MonoJumpInfo tmp_ji
;
1905 tmp_ji
.data
.target
= data
;
1907 MonoJumpInfo
*ji
= mono_aot_patch_info_dup (&tmp_ji
);
1908 ji
->next
= ctx
->cfg
->patch_info
;
1909 ctx
->cfg
->patch_info
= ji
;
1910 LLVMTypeRef llvm_type
= LLVMPointerType (llvm_sig
, 0);
1912 ctx
->cfg
->got_access_count
++;
1914 CallSite
*info
= g_new0 (CallSite
, 1);
1915 info
->method
= method
;
1917 info
->type
= llvm_type
;
1920 * Emit a dummy load to represent the callee, and either replace it with
1921 * a reference to the llvm method for the callee, or from a load from the
1924 LLVMValueRef indexes
[2];
1925 LLVMValueRef got_entry_addr
, load
;
1927 LLVMBuilderRef builder
= ctx
->builder
;
1928 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1929 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1930 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
1932 load
= LLVMBuildLoad (builder
, got_entry_addr
, "");
1933 load
= convert (ctx
, load
, llvm_type
);
1936 g_ptr_array_add (ctx
->callsite_list
, info
);
1943 * Calls are made through the GOT.
1945 callee
= get_aotconst_typed (ctx
, type
, data
, LLVMPointerType (llvm_sig
, 0));
1953 * Return an llvm value representing the callee given by the arguments.
1956 get_callee (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1958 LLVMValueRef callee
;
1960 MonoJumpInfo
*ji
= NULL
;
1963 return get_callee_llvmonly (ctx
, llvm_sig
, type
, data
);
1965 callee_name
= mono_aot_get_plt_symbol (type
, data
);
1969 if (ctx
->cfg
->compile_aot
)
1970 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1971 mono_add_patch_info (ctx
->cfg
, 0, type
, data
);
1974 callee
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->plt_entries
, callee_name
);
1976 callee
= LLVMAddFunction (ctx
->lmodule
, callee_name
, llvm_sig
);
1978 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1980 g_hash_table_insert (ctx
->module
->plt_entries
, (char*)callee_name
, callee
);
1983 if (ctx
->cfg
->compile_aot
) {
1984 ji
= g_new0 (MonoJumpInfo
, 1);
1986 ji
->data
.target
= data
;
1988 g_hash_table_insert (ctx
->module
->plt_entries_ji
, ji
, callee
);
1995 get_jit_callee (EmitContext
*ctx
, const char *name
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1999 // This won't be patched so compile the wrapper immediately
2000 if (type
== MONO_PATCH_INFO_JIT_ICALL_ID
) {
2001 MonoJitICallInfo
* const info
= mono_find_jit_icall_info ((MonoJitICallId
)(gsize
)data
);
2002 target
= (gpointer
)mono_icall_get_wrapper_full (info
, TRUE
);
2004 target
= resolve_patch (ctx
->cfg
, type
, data
);
2007 #if LLVM_API_VERSION > 100
2008 LLVMValueRef tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
2009 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
2010 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
2011 LLVMValueRef callee
= LLVMBuildLoad (ctx
->builder
, tramp_var
, "");
2014 g_assert_not_reached ();
2020 get_handler_clause (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
2022 MonoMethodHeader
*header
= cfg
->header
;
2023 MonoExceptionClause
*clause
;
2027 if (bb
->region
!= -1 && MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))
2028 return (bb
->region
>> 8) - 1;
2031 for (i
= 0; i
< header
->num_clauses
; ++i
) {
2032 clause
= &header
->clauses
[i
];
2034 if (MONO_OFFSET_IN_CLAUSE (clause
, bb
->real_offset
) && clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
)
2041 static MonoExceptionClause
*
2042 get_most_deep_clause (MonoCompile
*cfg
, EmitContext
*ctx
, MonoBasicBlock
*bb
)
2044 if (bb
== cfg
->bb_init
)
2046 // Since they're sorted by nesting we just need
2047 // the first one that the bb is a member of
2048 for (int i
= 0; i
< cfg
->header
->num_clauses
; i
++) {
2049 MonoExceptionClause
*curr
= &cfg
->header
->clauses
[i
];
2051 if (MONO_OFFSET_IN_CLAUSE (curr
, bb
->real_offset
))
2059 set_metadata_flag (LLVMValueRef v
, const char *flag_name
)
2061 LLVMValueRef md_arg
;
2064 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
2065 md_arg
= LLVMMDString ("mono", 4);
2066 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
2070 set_nonnull_load_flag (LLVMValueRef v
)
2072 LLVMValueRef md_arg
;
2074 const char *flag_name
;
2076 flag_name
= "nonnull";
2077 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
2078 md_arg
= LLVMMDString ("<index>", strlen ("<index>"));
2079 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
2083 set_invariant_load_flag (LLVMValueRef v
)
2085 LLVMValueRef md_arg
;
2087 const char *flag_name
;
2089 // FIXME: Cache this
2090 flag_name
= "invariant.load";
2091 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
2092 md_arg
= LLVMMDString ("<index>", strlen ("<index>"));
2093 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
2099 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
2103 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
2105 MonoCompile
*cfg
= ctx
->cfg
;
2106 LLVMValueRef lcall
= NULL
;
2107 LLVMBuilderRef builder
= *builder_ref
;
2108 MonoExceptionClause
*clause
;
2110 if (ctx
->llvm_only
) {
2111 clause
= get_most_deep_clause (cfg
, ctx
, bb
);
2114 g_assert (clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| clause
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
|| clause
->flags
== MONO_EXCEPTION_CLAUSE_FAULT
);
2117 * Have to use an invoke instead of a call, branching to the
2118 * handler bblock of the clause containing this bblock.
2120 intptr_t key
= CLAUSE_END(clause
);
2122 LLVMBasicBlockRef lpad_bb
= (LLVMBasicBlockRef
)g_hash_table_lookup (ctx
->exc_meta
, (gconstpointer
)key
);
2124 // FIXME: Find the one that has the lowest end bound for the right start address
2125 // FIXME: Finally + nesting
2128 LLVMBasicBlockRef noex_bb
= gen_bb (ctx
, "CALL_NOEX_BB");
2131 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, lpad_bb
, "");
2133 builder
= ctx
->builder
= create_builder (ctx
);
2134 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2136 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2140 int clause_index
= get_handler_clause (cfg
, bb
);
2142 if (clause_index
!= -1) {
2143 MonoMethodHeader
*header
= cfg
->header
;
2144 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
2145 MonoBasicBlock
*tblock
;
2146 LLVMBasicBlockRef ex_bb
, noex_bb
;
2149 * Have to use an invoke instead of a call, branching to the
2150 * handler bblock of the clause containing this bblock.
2153 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FAULT
);
2155 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
2158 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
2160 ex_bb
= get_bb (ctx
, tblock
);
2162 noex_bb
= gen_bb (ctx
, "NOEX_BB");
2165 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
2167 builder
= ctx
->builder
= create_builder (ctx
);
2168 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2170 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2175 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
2176 ctx
->builder
= builder
;
2180 *builder_ref
= ctx
->builder
;
2186 emit_load (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, LLVMValueRef base
, const char *name
, gboolean is_faulting
, BarrierKind barrier
)
2188 const char *intrins_name
;
2189 LLVMValueRef args
[16], res
;
2190 LLVMTypeRef addr_type
;
2191 gboolean use_intrinsics
= TRUE
;
2193 #if LLVM_API_VERSION > 100
2194 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
2195 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2198 cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
2199 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
2200 *builder_ref
= ctx
->builder
;
2201 use_intrinsics
= FALSE
;
2205 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
2206 LLVMAtomicOrdering ordering
;
2209 case LLVM_BARRIER_NONE
:
2210 ordering
= LLVMAtomicOrderingNotAtomic
;
2212 case LLVM_BARRIER_ACQ
:
2213 ordering
= LLVMAtomicOrderingAcquire
;
2215 case LLVM_BARRIER_SEQ
:
2216 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
2219 g_assert_not_reached ();
2224 * We handle loads which can fault by calling a mono specific intrinsic
2225 * using an invoke, so they are handled properly inside try blocks.
2226 * We can't use this outside clauses, since LLVM optimizes intrinsics which
2227 * are marked with IntrReadArgMem.
2231 intrins_name
= "llvm.mono.load.i8.p0i8";
2234 intrins_name
= "llvm.mono.load.i16.p0i16";
2237 intrins_name
= "llvm.mono.load.i32.p0i32";
2240 intrins_name
= "llvm.mono.load.i64.p0i64";
2243 g_assert_not_reached ();
2246 addr_type
= LLVMTypeOf (addr
);
2247 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0) || addr_type
== LLVMPointerType (LLVMFloatType (), 0))
2248 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
2251 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2252 args
[2] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
2253 args
[3] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
2254 res
= emit_call (ctx
, bb
, builder_ref
, get_intrins_by_name (ctx
, intrins_name
), args
, 4);
2256 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0))
2257 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMDoubleType (), "");
2258 else if (addr_type
== LLVMPointerType (LLVMFloatType (), 0))
2259 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMFloatType (), "");
2266 * We emit volatile loads for loads which can fault, because otherwise
2267 * LLVM will generate invalid code when encountering a load from a
2270 if (barrier
!= LLVM_BARRIER_NONE
)
2271 res
= mono_llvm_build_atomic_load (*builder_ref
, addr
, name
, is_faulting
, size
, barrier
);
2273 res
= mono_llvm_build_load (*builder_ref
, addr
, name
, is_faulting
);
2275 /* Mark it with a custom metadata */
2278 set_metadata_flag (res, "mono.faulting.load");
2286 emit_store_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
, BarrierKind barrier
)
2288 const char *intrins_name
;
2289 LLVMValueRef args
[16];
2290 gboolean use_intrinsics
= TRUE
;
2292 #if LLVM_API_VERSION > 100
2293 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
2294 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2295 LLVMValueRef cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
2296 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
2297 *builder_ref
= ctx
->builder
;
2298 use_intrinsics
= FALSE
;
2302 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
2303 LLVMAtomicOrdering ordering
;
2306 case LLVM_BARRIER_NONE
:
2307 ordering
= LLVMAtomicOrderingNotAtomic
;
2309 case LLVM_BARRIER_REL
:
2310 ordering
= LLVMAtomicOrderingRelease
;
2312 case LLVM_BARRIER_SEQ
:
2313 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
2316 g_assert_not_reached ();
2322 intrins_name
= "llvm.mono.store.i8.p0i8";
2325 intrins_name
= "llvm.mono.store.i16.p0i16";
2328 intrins_name
= "llvm.mono.store.i32.p0i32";
2331 intrins_name
= "llvm.mono.store.i64.p0i64";
2334 g_assert_not_reached ();
2337 if (LLVMTypeOf (value
) == LLVMDoubleType () || LLVMTypeOf (value
) == LLVMFloatType ()) {
2338 value
= LLVMBuildBitCast (*builder_ref
, value
, LLVMIntType (size
* 8), "");
2339 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
2344 args
[2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2345 args
[3] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
2346 args
[4] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
2347 emit_call (ctx
, bb
, builder_ref
, get_intrins_by_name (ctx
, intrins_name
), args
, 5);
2349 if (barrier
!= LLVM_BARRIER_NONE
)
2350 mono_llvm_build_aligned_store (*builder_ref
, value
, addr
, barrier
, size
);
2352 mono_llvm_build_store (*builder_ref
, value
, addr
, is_faulting
, barrier
);
2357 emit_store (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
)
2359 emit_store_general (ctx
, bb
, builder_ref
, size
, value
, addr
, base
, is_faulting
, LLVM_BARRIER_NONE
);
2363 * emit_cond_system_exception:
2365 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2366 * Might set the ctx exception.
2369 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
2371 LLVMBasicBlockRef ex_bb
, ex2_bb
= NULL
, noex_bb
;
2372 LLVMBuilderRef builder
;
2373 MonoClass
*exc_class
;
2374 LLVMValueRef args
[2];
2375 LLVMValueRef callee
;
2376 gboolean no_pc
= FALSE
;
2377 static MonoClass
*exc_classes
[MONO_EXC_INTRINS_NUM
];
2379 if (IS_TARGET_AMD64
)
2380 /* Some platforms don't require the pc argument */
2383 int exc_id
= mini_exception_id_by_name (exc_type
);
2384 if (!exc_classes
[exc_id
])
2385 exc_classes
[exc_id
] = mono_class_load_from_name (mono_get_corlib (), "System", exc_type
);
2386 exc_class
= exc_classes
[exc_id
];
2388 ex_bb
= gen_bb (ctx
, "EX_BB");
2390 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2391 noex_bb
= gen_bb (ctx
, "NOEX_BB");
2393 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
2395 /* Emit exception throwing code */
2396 ctx
->builder
= builder
= create_builder (ctx
);
2397 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
2399 if (ctx
->cfg
->llvm_only
) {
2400 LLVMBuildBr (builder
, ex2_bb
);
2402 ctx
->builder
= builder
= create_builder (ctx
);
2403 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2405 if (exc_id
== MONO_EXC_NULL_REF
) {
2406 static LLVMTypeRef sig
;
2409 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
2410 /* Can't cache this */
2411 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_llvmonly_throw_nullref_exception
));
2412 emit_call (ctx
, bb
, &builder
, callee
, NULL
, 0);
2414 static LLVMTypeRef sig
;
2417 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2418 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_llvm_throw_corlib_exception
));
2419 args
[0] = LLVMConstInt (LLVMInt32Type (), m_class_get_type_token (exc_class
) - MONO_TOKEN_TYPE_DEF
, FALSE
);
2420 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2423 LLVMBuildUnreachable (builder
);
2425 ctx
->builder
= builder
= create_builder (ctx
);
2426 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2428 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2434 callee
= ctx
->module
->throw_corlib_exception
;
2439 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2441 sig
= LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE
);
2443 const MonoJitICallId icall_id
= MONO_JIT_ICALL_mono_llvm_throw_corlib_exception_abs_trampoline
;
2445 if (ctx
->cfg
->compile_aot
) {
2446 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
2449 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2450 * - On x86, LLVM generated code doesn't push the arguments
2451 * - The trampoline takes the throw address as an arguments, not a pc offset.
2453 callee
= get_jit_callee (ctx
, "llvm_throw_corlib_exception_trampoline", sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
2455 #if LLVM_API_VERSION > 100
2457 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2458 * added by get_jit_callee ().
2460 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2461 LLVMBuildBr (builder
, ex2_bb
);
2464 ctx
->builder
= builder
= create_builder (ctx
);
2465 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2467 mono_memory_barrier ();
2468 ctx
->module
->throw_corlib_exception
= callee
;
2473 args
[0] = LLVMConstInt (LLVMInt32Type (), m_class_get_type_token (exc_class
) - MONO_TOKEN_TYPE_DEF
, FALSE
);
2476 * The LLVM mono branch contains changes so a block address can be passed as an
2477 * argument to a call.
2480 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2482 args
[1] = LLVMBlockAddress (ctx
->lmethod
, ex_bb
);
2483 emit_call (ctx
, bb
, &builder
, callee
, args
, 2);
2486 LLVMBuildUnreachable (builder
);
2488 ctx
->builder
= builder
= create_builder (ctx
);
2489 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2491 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2498 * emit_args_to_vtype:
2500 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2503 emit_args_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
)
2505 int j
, size
, nslots
;
2508 t
= mini_get_underlying_type (t
);
2509 klass
= mono_class_from_mono_type_internal (t
);
2510 size
= mono_class_value_size (klass
, NULL
);
2512 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
2513 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2515 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2516 nslots
= ainfo
->nslots
;
2520 for (j
= 0; j
< nslots
; ++j
) {
2521 LLVMValueRef index
[2], addr
, daddr
;
2522 int part_size
= size
> TARGET_SIZEOF_VOID_P
? TARGET_SIZEOF_VOID_P
: size
;
2523 LLVMTypeRef part_type
;
2525 while (part_size
!= 1 && part_size
!= 2 && part_size
!= 4 && part_size
< 8)
2528 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2531 switch (ainfo
->pair_storage
[j
]) {
2532 case LLVMArgInIReg
: {
2533 part_type
= LLVMIntType (part_size
* 8);
2534 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
)) {
2535 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* TARGET_SIZEOF_VOID_P
, FALSE
);
2536 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2538 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2539 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2540 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2542 LLVMBuildStore (builder
, convert (ctx
, args
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
2545 case LLVMArgInFPReg
: {
2546 LLVMTypeRef arg_type
;
2548 if (ainfo
->esize
== 8)
2549 arg_type
= LLVMDoubleType ();
2551 arg_type
= LLVMFloatType ();
2553 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2554 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2555 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2556 LLVMBuildStore (builder
, args
[j
], addr
);
2562 g_assert_not_reached ();
2565 size
-= TARGET_SIZEOF_VOID_P
;
2570 * emit_vtype_to_args:
2572 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2573 * into ARGS, and the number of arguments into NARGS.
2576 emit_vtype_to_args (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
, guint32
*nargs
)
2579 int j
, size
, nslots
;
2580 LLVMTypeRef arg_type
;
2582 t
= mini_get_underlying_type (t
);
2583 size
= get_vtype_size (t
);
2585 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (t
)))
2586 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2588 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2589 nslots
= ainfo
->nslots
;
2592 for (j
= 0; j
< nslots
; ++j
) {
2593 LLVMValueRef index
[2], addr
, daddr
;
2594 int partsize
= size
> TARGET_SIZEOF_VOID_P
? TARGET_SIZEOF_VOID_P
: size
;
2596 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2599 switch (ainfo
->pair_storage
[j
]) {
2601 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (t
))) {
2602 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* TARGET_SIZEOF_VOID_P
, FALSE
);
2603 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2605 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2606 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2607 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2609 args
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
2611 case LLVMArgInFPReg
:
2612 if (ainfo
->esize
== 8)
2613 arg_type
= LLVMDoubleType ();
2615 arg_type
= LLVMFloatType ();
2616 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2617 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2618 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2619 args
[pindex
++] = LLVMBuildLoad (builder
, addr
, "");
2624 g_assert_not_reached ();
2626 size
-= TARGET_SIZEOF_VOID_P
;
2633 build_alloca_llvm_type_name (EmitContext
*ctx
, LLVMTypeRef t
, int align
, const char *name
)
2636 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2637 * get executed every time control reaches them.
2639 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
2641 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, t
, NULL
, align
, name
);
2642 return ctx
->last_alloca
;
2646 build_alloca_llvm_type (EmitContext
*ctx
, LLVMTypeRef t
, int align
)
2648 return build_alloca_llvm_type_name (ctx
, t
, align
, "");
2652 build_alloca (EmitContext
*ctx
, MonoType
*t
)
2654 MonoClass
*k
= mono_class_from_mono_type_internal (t
);
2657 g_assert (!mini_is_gsharedvt_variable_type (t
));
2659 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
2662 align
= mono_class_min_align (k
);
2664 /* Sometimes align is not a power of 2 */
2665 while (mono_is_power_of_two (align
) == -1)
2668 return build_alloca_llvm_type (ctx
, type_to_llvm_type (ctx
, t
), align
);
2672 emit_gsharedvt_ldaddr (EmitContext
*ctx
, int vreg
)
2676 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2678 MonoCompile
*cfg
= ctx
->cfg
;
2679 LLVMBuilderRef builder
= ctx
->builder
;
2680 LLVMValueRef offset
, offset_var
;
2681 LLVMValueRef info_var
= ctx
->values
[cfg
->gsharedvt_info_var
->dreg
];
2682 LLVMValueRef locals_var
= ctx
->values
[cfg
->gsharedvt_locals_var
->dreg
];
2686 g_assert (info_var
);
2687 g_assert (locals_var
);
2689 int idx
= cfg
->gsharedvt_vreg_to_idx
[vreg
] - 1;
2691 offset
= LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo
, entries
) + (idx
* TARGET_SIZEOF_VOID_P
), FALSE
);
2692 ptr
= LLVMBuildAdd (builder
, convert (ctx
, info_var
, IntPtrType ()), convert (ctx
, offset
, IntPtrType ()), "");
2694 name
= g_strdup_printf ("gsharedvt_local_%d_offset", vreg
);
2695 offset_var
= LLVMBuildLoad (builder
, convert (ctx
, ptr
, LLVMPointerType (LLVMInt32Type (), 0)), name
);
2697 return LLVMBuildAdd (builder
, convert (ctx
, locals_var
, IntPtrType ()), convert (ctx
, offset_var
, IntPtrType ()), "");
2701 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2704 mark_as_used (MonoLLVMModule
*module
, LLVMValueRef global
)
2707 module
->used
= g_ptr_array_sized_new (16);
2708 g_ptr_array_add (module
->used
, global
);
2712 emit_llvm_used (MonoLLVMModule
*module
)
2714 LLVMModuleRef lmodule
= module
->lmodule
;
2715 LLVMTypeRef used_type
;
2716 LLVMValueRef used
, *used_elem
;
2722 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module
->used
->len
);
2723 used
= LLVMAddGlobal (lmodule
, used_type
, "llvm.used");
2724 used_elem
= g_new0 (LLVMValueRef
, module
->used
->len
);
2725 for (i
= 0; i
< module
->used
->len
; ++i
)
2726 used_elem
[i
] = LLVMConstBitCast ((LLVMValueRef
)g_ptr_array_index (module
->used
, i
), LLVMPointerType (LLVMInt8Type (), 0));
2727 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem
, module
->used
->len
));
2728 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
2729 LLVMSetSection (used
, "llvm.metadata");
2735 * Emit a function mapping method indexes to their code
2738 emit_get_method (MonoLLVMModule
*module
)
2740 LLVMModuleRef lmodule
= module
->lmodule
;
2741 LLVMValueRef func
, switch_ins
, m
;
2742 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
, code_start_bb
, code_end_bb
;
2743 LLVMBasicBlockRef
*bbs
= NULL
;
2745 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2746 LLVMValueRef table
= NULL
;
2749 gboolean emit_table
= FALSE
;
2753 * Emit a table of functions instead of a switch statement,
2754 * its very efficient on wasm. This might be usable on
2755 * other platforms too.
2760 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2763 LLVMTypeRef table_type
;
2764 LLVMValueRef
*table_elems
;
2767 int table_len
= module
->max_method_idx
+ 1;
2768 table_type
= LLVMArrayType (rtype
, table_len
);
2769 table_name
= g_strdup_printf ("%s_method_table", module
->assembly
->aname
.name
);
2770 table
= LLVMAddGlobal (lmodule
, table_type
, table_name
);
2771 table_elems
= g_new0 (LLVMValueRef
, table_len
);
2772 for (i
= 0; i
< table_len
; ++i
) {
2773 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_lmethod
, GINT_TO_POINTER (i
));
2775 table_elems
[i
] = LLVMBuildBitCast (builder
, m
, rtype
, "");
2777 table_elems
[i
] = LLVMConstNull (rtype
);
2779 LLVMSetInitializer (table
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), table_elems
, table_len
));
2783 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2784 * but generating code seems safer.
2786 func
= LLVMAddFunction (lmodule
, module
->get_method_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2787 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2788 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2789 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
2790 module
->get_method
= func
;
2792 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2795 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2796 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2797 * then we will have to find another solution.
2800 name
= g_strdup_printf ("BB_CODE_START");
2801 code_start_bb
= LLVMAppendBasicBlock (func
, name
);
2803 LLVMPositionBuilderAtEnd (builder
, code_start_bb
);
2804 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_start
, rtype
, ""));
2806 name
= g_strdup_printf ("BB_CODE_END");
2807 code_end_bb
= LLVMAppendBasicBlock (func
, name
);
2809 LLVMPositionBuilderAtEnd (builder
, code_end_bb
);
2810 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_end
, rtype
, ""));
2815 * case -1: return code_start;
2816 * case -2: return code_end;
2817 * default: return method_table [index];
2819 LLVMBasicBlockRef default_bb
= LLVMAppendBasicBlock (func
, "DEFAULT");
2820 LLVMPositionBuilderAtEnd (builder
, default_bb
);
2821 LLVMValueRef base
= table
;
2822 LLVMValueRef indexes
[2];
2823 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2824 indexes
[1] = LLVMGetParam (func
, 0);
2825 LLVMValueRef addr
= LLVMBuildGEP (builder
, base
, indexes
, 2, "");
2826 LLVMValueRef res
= mono_llvm_build_load (builder
, addr
, "", FALSE
);
2827 LLVMBuildRet (builder
, res
);
2829 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2831 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), default_bb
, 0);
2832 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -1, FALSE
), code_start_bb
);
2833 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -2, FALSE
), code_end_bb
);
2835 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2836 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2837 name
= g_strdup_printf ("BB_%d", i
);
2838 bb
= LLVMAppendBasicBlock (func
, name
);
2842 LLVMPositionBuilderAtEnd (builder
, bb
);
2844 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_lmethod
, GINT_TO_POINTER (i
));
2846 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2848 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2851 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2852 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2853 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2855 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2857 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2858 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -1, FALSE
), code_start_bb
);
2859 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -2, FALSE
), code_end_bb
);
2860 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2861 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2865 mark_as_used (module
, func
);
2867 LLVMDisposeBuilder (builder
);
2871 * emit_get_unbox_tramp:
2873 * Emit a function mapping method indexes to their unbox trampoline
2876 emit_get_unbox_tramp (MonoLLVMModule
*module
)
2878 LLVMModuleRef lmodule
= module
->lmodule
;
2879 LLVMValueRef func
, switch_ins
, m
;
2880 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
;
2881 LLVMBasicBlockRef
*bbs
;
2883 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2886 gboolean emit_table
= FALSE
;
2888 /* Similar to emit_get_method () */
2890 #ifndef TARGET_WATCHOS
2894 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2897 // About 10% of methods have an unbox tramp, so emit a table of indexes for them
2898 // that the runtime can search using a binary search
2900 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2901 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2906 LLVMTypeRef table_type
, elemtype
;
2907 LLVMValueRef
*table_elems
;
2914 elemsize
= module
->max_method_idx
< 65000 ? 2 : 4;
2917 elemtype
= elemsize
== 2 ? LLVMInt16Type () : LLVMInt32Type ();
2918 table_type
= LLVMArrayType (elemtype
, table_len
);
2919 table_name
= g_strdup_printf ("%s_unbox_tramp_indexes", module
->assembly
->aname
.name
);
2920 table
= LLVMAddGlobal (lmodule
, table_type
, table_name
);
2921 table_elems
= g_new0 (LLVMValueRef
, table_len
);
2923 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2924 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2926 table_elems
[idx
++] = LLVMConstInt (elemtype
, i
, FALSE
);
2928 LLVMSetInitializer (table
, LLVMConstArray (elemtype
, table_elems
, table_len
));
2929 module
->unbox_tramp_indexes
= table
;
2931 // The trampoline table
2933 table_type
= LLVMArrayType (elemtype
, table_len
);
2934 table_name
= g_strdup_printf ("%s_unbox_trampolines", module
->assembly
->aname
.name
);
2935 table
= LLVMAddGlobal (lmodule
, table_type
, table_name
);
2936 table_elems
= g_new0 (LLVMValueRef
, table_len
);
2938 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2939 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2941 table_elems
[idx
++] = LLVMBuildBitCast (builder
, m
, rtype
, "");
2943 LLVMSetInitializer (table
, LLVMConstArray (elemtype
, table_elems
, table_len
));
2944 module
->unbox_trampolines
= table
;
2946 module
->unbox_tramp_num
= table_len
;
2947 module
->unbox_tramp_elemsize
= elemsize
;
2951 func
= LLVMAddFunction (lmodule
, module
->get_unbox_tramp_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2952 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2953 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2954 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
2955 module
->get_unbox_tramp
= func
;
2957 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2959 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2960 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2961 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2965 name
= g_strdup_printf ("BB_%d", i
);
2966 bb
= LLVMAppendBasicBlock (func
, name
);
2970 LLVMPositionBuilderAtEnd (builder
, bb
);
2972 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2975 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2976 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2977 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2979 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2981 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2982 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2983 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2987 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2990 mark_as_used (module
, func
);
2991 LLVMDisposeBuilder (builder
);
2994 /* Add a function to mark the beginning of LLVM code */
2996 emit_llvm_code_start (MonoLLVMModule
*module
)
2998 LLVMModuleRef lmodule
= module
->lmodule
;
3000 LLVMBasicBlockRef entry_bb
;
3001 LLVMBuilderRef builder
;
3003 func
= LLVMAddFunction (lmodule
, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
3004 LLVMSetLinkage (func
, LLVMInternalLinkage
);
3005 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
3006 module
->code_start
= func
;
3007 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
3008 builder
= LLVMCreateBuilder ();
3009 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
3010 LLVMBuildRetVoid (builder
);
3011 LLVMDisposeBuilder (builder
);
3015 emit_init_icall_wrapper (MonoLLVMModule
*module
, MonoAotInitSubtype subtype
)
3017 LLVMModuleRef lmodule
= module
->lmodule
;
3018 LLVMValueRef func
, indexes
[2], got_entry_addr
, args
[16], callee
;
3019 LLVMBasicBlockRef entry_bb
;
3020 LLVMBuilderRef builder
;
3024 const char *wrapper_name
= mono_marshal_get_aot_init_wrapper_name (subtype
);
3025 char *name
= g_strdup_printf ("%s%s", module
->global_prefix
, wrapper_name
);
3026 MonoJitICallId icall_id
= MONO_JIT_ICALL_ZeroIsReserved
;
3029 case AOT_INIT_METHOD
:
3030 icall_id
= MONO_JIT_ICALL_mini_llvm_init_method
;
3031 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
));
3032 sig
= LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE
);
3034 case AOT_INIT_METHOD_GSHARED_MRGCTX
:
3035 icall_id
= MONO_JIT_ICALL_mini_llvm_init_gshared_method_mrgctx
; // Deliberate fall-through
3036 case AOT_INIT_METHOD_GSHARED_VTABLE
:
3039 icall_id
= MONO_JIT_ICALL_mini_llvm_init_gshared_method_vtable
;
3040 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE
));
3041 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE
);
3043 case AOT_INIT_METHOD_GSHARED_THIS
:
3044 icall_id
= MONO_JIT_ICALL_mini_llvm_init_gshared_method_this
;
3045 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE
));
3046 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE
);
3049 g_assert_not_reached ();
3052 g_assert (icall_id
);
3053 LLVMSetLinkage (func
, LLVMInternalLinkage
);
3055 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_INLINE
);
3057 // FIXME? Using this with mono debug info causes unwind.c to explode when
3058 // parsing some of these registers saved by this call. Can't unwind through it.
3059 // Not an issue with llvmonly because it doesn't use that DWARF
3060 if (module
->llvm_only
)
3061 set_preserveall_cc (func
);
3063 LLVMSetFunctionCallConv (func
, LLVMMono1CallConv
);
3065 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
3066 builder
= LLVMCreateBuilder ();
3067 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
3070 ji
= g_new0 (MonoJumpInfo
, 1);
3071 ji
->type
= MONO_PATCH_INFO_AOT_MODULE
;
3072 ji
= mono_aot_patch_info_dup (ji
);
3073 got_offset
= compute_aot_got_offset (module
, ji
, IntPtrType ());
3074 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
3075 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3076 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
3077 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
3078 args
[0] = LLVMBuildPtrToInt (builder
, LLVMBuildLoad (builder
, got_entry_addr
, ""), IntPtrType (), "");
3079 args
[1] = LLVMGetParam (func
, 0);
3081 args
[2] = LLVMGetParam (func
, 1);
3083 ji
= g_new0 (MonoJumpInfo
, 1);
3084 ji
->type
= MONO_PATCH_INFO_JIT_ICALL_ID
;
3085 ji
->data
.jit_icall_id
= icall_id
;
3086 ji
= mono_aot_patch_info_dup (ji
);
3087 got_offset
= compute_aot_got_offset (module
, ji
, sig
);
3088 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
3089 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3090 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
3091 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
3092 callee
= LLVMBuildLoad (builder
, got_entry_addr
, "");
3093 callee
= LLVMBuildBitCast (builder
, callee
, LLVMPointerType (sig
, 0), "");
3094 LLVMBuildCall (builder
, callee
, args
, LLVMCountParamTypes (sig
), "");
3096 // Set the inited flag
3097 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3098 indexes
[1] = LLVMGetParam (func
, 0);
3099 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt8Type (), 1, FALSE
), LLVMBuildGEP (builder
, module
->inited_var
, indexes
, 2, ""));
3101 LLVMBuildRetVoid (builder
);
3103 LLVMVerifyFunction(func
, LLVMAbortProcessAction
);
3104 LLVMDisposeBuilder (builder
);
3109 * Emit wrappers around the C icalls used to initialize llvm methods, to
3110 * make the calling code smaller and to enable usage of the llvm
3111 * PreserveAll calling convention.
3114 emit_init_icall_wrappers (MonoLLVMModule
*module
)
3116 module
->init_method
= emit_init_icall_wrapper (module
, AOT_INIT_METHOD
);
3117 module
->init_method_gshared_mrgctx
= emit_init_icall_wrapper (module
, AOT_INIT_METHOD_GSHARED_MRGCTX
);
3118 module
->init_method_gshared_this
= emit_init_icall_wrapper (module
, AOT_INIT_METHOD_GSHARED_THIS
);
3119 module
->init_method_gshared_vtable
= emit_init_icall_wrapper (module
, AOT_INIT_METHOD_GSHARED_VTABLE
);
3123 get_init_icall_wrapper (MonoLLVMModule
*module
, MonoAotInitSubtype subtype
)
3126 case AOT_INIT_METHOD
:
3127 return module
->init_method
;
3128 case AOT_INIT_METHOD_GSHARED_MRGCTX
:
3129 return module
->init_method_gshared_mrgctx
;
3130 case AOT_INIT_METHOD_GSHARED_THIS
:
3131 return module
->init_method_gshared_this
;
3132 case AOT_INIT_METHOD_GSHARED_VTABLE
:
3133 return module
->init_method_gshared_vtable
;
3135 g_assert_not_reached ();
3140 emit_gc_safepoint_poll (MonoLLVMModule
*module
)
3142 LLVMModuleRef lmodule
= module
->lmodule
;
3143 LLVMValueRef func
, indexes
[2], got_entry_addr
, flag_addr
, val_ptr
, callee
, val
, cmp
;
3144 LLVMBasicBlockRef entry_bb
, poll_bb
, exit_bb
;
3145 LLVMBuilderRef builder
;
3150 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
3151 func
= mono_llvm_get_or_insert_gc_safepoint_poll (lmodule
);
3152 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
3153 LLVMSetLinkage (func
, LLVMWeakODRLinkage
);
3154 // set_preserveall_cc (func);
3156 entry_bb
= LLVMAppendBasicBlock (func
, "gc.safepoint_poll.entry");
3157 poll_bb
= LLVMAppendBasicBlock (func
, "gc.safepoint_poll.poll");
3158 exit_bb
= LLVMAppendBasicBlock (func
, "gc.safepoint_poll.exit");
3160 builder
= LLVMCreateBuilder ();
3163 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
3166 ji
= g_new0 (MonoJumpInfo
, 1);
3167 ji
->type
= MONO_PATCH_INFO_GC_SAFE_POINT_FLAG
;
3168 ji
= mono_aot_patch_info_dup (ji
);
3169 got_offset
= compute_aot_got_offset (module
, ji
, IntPtrType ());
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 flag_addr
= LLVMBuildLoad (builder
, got_entry_addr
, "");
3175 val_ptr
= LLVMBuildLoad (builder
, flag_addr
, "");
3176 val
= LLVMBuildPtrToInt (builder
, val_ptr
, IntPtrType (), "");
3177 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, val
, LLVMConstNull (LLVMTypeOf (val
)), "");
3178 LLVMBuildCondBr (builder
, cmp
, exit_bb
, poll_bb
);
3181 LLVMPositionBuilderAtEnd(builder
, poll_bb
);
3183 ji
= g_new0 (MonoJumpInfo
, 1);
3184 ji
->type
= MONO_PATCH_INFO_JIT_ICALL_ID
;
3185 ji
->data
.jit_icall_id
= MONO_JIT_ICALL_mono_threads_state_poll
;
3186 ji
= mono_aot_patch_info_dup (ji
);
3187 got_offset
= compute_aot_got_offset (module
, ji
, sig
);
3188 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
3189 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3190 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
3191 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
3192 callee
= LLVMBuildLoad (builder
, got_entry_addr
, "");
3193 callee
= LLVMBuildBitCast (builder
, callee
, LLVMPointerType (sig
, 0), "");
3194 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
3195 LLVMBuildBr(builder
, exit_bb
);
3198 LLVMPositionBuilderAtEnd(builder
, exit_bb
);
3200 LLVMBuildRetVoid (builder
);
3202 LLVMVerifyFunction(func
, LLVMAbortProcessAction
);
3203 LLVMDisposeBuilder (builder
);
3207 emit_llvm_code_end (MonoLLVMModule
*module
)
3209 LLVMModuleRef lmodule
= module
->lmodule
;
3211 LLVMBasicBlockRef entry_bb
;
3212 LLVMBuilderRef builder
;
3214 func
= LLVMAddFunction (lmodule
, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
3215 LLVMSetLinkage (func
, LLVMInternalLinkage
);
3216 mono_llvm_add_func_attr (func
, LLVM_ATTR_NO_UNWIND
);
3217 module
->code_end
= func
;
3218 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
3219 builder
= LLVMCreateBuilder ();
3220 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
3221 LLVMBuildRetVoid (builder
);
3222 LLVMDisposeBuilder (builder
);
3226 emit_div_check (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoBasicBlock
*bb
, MonoInst
*ins
, LLVMValueRef lhs
, LLVMValueRef rhs
)
3228 gboolean need_div_check
= ctx
->cfg
->backend
->need_div_check
;
3231 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
3232 need_div_check
= TRUE
;
3234 if (!need_div_check
)
3237 switch (ins
->opcode
) {
3250 case OP_IDIV_UN_IMM
:
3251 case OP_LDIV_UN_IMM
:
3252 case OP_IREM_UN_IMM
:
3253 case OP_LREM_UN_IMM
: {
3255 gboolean is_signed
= (ins
->opcode
== OP_IDIV
|| ins
->opcode
== OP_LDIV
|| ins
->opcode
== OP_IREM
|| ins
->opcode
== OP_LREM
||
3256 ins
->opcode
== OP_IDIV_IMM
|| ins
->opcode
== OP_LDIV_IMM
|| ins
->opcode
== OP_IREM_IMM
|| ins
->opcode
== OP_LREM_IMM
);
3258 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), 0, FALSE
), "");
3259 emit_cond_system_exception (ctx
, bb
, "DivideByZeroException", cmp
);
3262 builder
= ctx
->builder
;
3264 /* b == -1 && a == 0x80000000 */
3266 LLVMValueRef c
= (LLVMTypeOf (lhs
) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs
), 0x80000000, FALSE
) : LLVMConstInt (LLVMTypeOf (lhs
), 0x8000000000000000LL
, FALSE
);
3267 LLVMValueRef cond1
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), -1, FALSE
), "");
3268 LLVMValueRef cond2
= LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, c
, "");
3270 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, LLVMBuildAnd (builder
, cond1
, cond2
, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE
), "");
3271 emit_cond_system_exception (ctx
, bb
, "OverflowException", cmp
);
3274 builder
= ctx
->builder
;
3286 * Emit code to initialize the GOT slots used by the method.
3289 emit_init_method (EmitContext
*ctx
)
3291 LLVMValueRef indexes
[16], args
[16], callee
;
3292 LLVMValueRef inited_var
, cmp
, call
;
3293 LLVMBasicBlockRef inited_bb
, notinited_bb
;
3294 LLVMBuilderRef builder
= ctx
->builder
;
3295 MonoCompile
*cfg
= ctx
->cfg
;
3297 ctx
->module
->max_inited_idx
= MAX (ctx
->module
->max_inited_idx
, cfg
->method_index
);
3299 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3300 indexes
[1] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, FALSE
);
3301 inited_var
= LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, ctx
->module
->inited_var
, indexes
, 2, ""), "is_inited");
3303 //WASM doesn't support the "llvm.expect.i8" intrinsic
3305 args
[0] = inited_var
;
3306 args
[1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE
);
3307 inited_var
= LLVMBuildCall (ctx
->builder
, get_intrins (ctx
, INTRINS_EXPECT_I8
), args
, 2, "");
3310 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, inited_var
, LLVMConstInt (LLVMTypeOf (inited_var
), 0, FALSE
), "");
3312 inited_bb
= ctx
->inited_bb
;
3313 notinited_bb
= gen_bb (ctx
, "NOTINITED_BB");
3315 ctx
->cfg
->llvmonly_init_cond
= LLVMBuildCondBr (ctx
->builder
, cmp
, notinited_bb
, inited_bb
);
3317 builder
= ctx
->builder
= create_builder (ctx
);
3318 LLVMPositionBuilderAtEnd (ctx
->builder
, notinited_bb
);
3321 if (ctx
->rgctx_arg
&& ((cfg
->method
->is_inflated
&& mono_method_get_context (cfg
->method
)->method_inst
) ||
3322 mini_method_is_default_method (cfg
->method
))) {
3323 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
3324 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
3325 callee
= ctx
->module
->init_method_gshared_mrgctx
;
3326 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
3327 } else if (ctx
->rgctx_arg
) {
3328 /* A vtable is passed as the rgctx argument */
3329 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
3330 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
3331 callee
= ctx
->module
->init_method_gshared_vtable
;
3332 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
3333 } else if (cfg
->gshared
) {
3334 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
3335 args
[1] = convert (ctx
, ctx
->this_arg
, ObjRefType ());
3336 callee
= ctx
->module
->init_method_gshared_this
;
3337 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
3339 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
3340 callee
= ctx
->module
->init_method
;
3341 call
= LLVMBuildCall (builder
, callee
, args
, 1, "");
3345 * This enables llvm to keep arguments in their original registers/
3346 * scratch registers, since the call will not clobber them.
3350 set_call_preserveall_cc (call
);
3352 LLVMSetInstructionCallConv (call
, LLVMMono1CallConv
);
3354 LLVMBuildBr (builder
, inited_bb
);
3355 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= inited_bb
;
3357 builder
= ctx
->builder
= create_builder (ctx
);
3358 LLVMPositionBuilderAtEnd (ctx
->builder
, inited_bb
);
3362 emit_unbox_tramp (EmitContext
*ctx
, const char *method_name
, LLVMTypeRef method_type
, LLVMValueRef method
, int method_index
)
3365 * Emit unbox trampoline using a tailcall
3367 LLVMValueRef tramp
, call
, *args
;
3368 LLVMBuilderRef builder
;
3369 LLVMBasicBlockRef lbb
;
3370 LLVMCallInfo
*linfo
;
3374 tramp_name
= g_strdup_printf ("ut_%s", method_name
);
3375 tramp
= LLVMAddFunction (ctx
->module
->lmodule
, tramp_name
, method_type
);
3376 LLVMSetLinkage (tramp
, LLVMInternalLinkage
);
3377 mono_llvm_add_func_attr (tramp
, LLVM_ATTR_OPTIMIZE_FOR_SIZE
);
3378 //mono_llvm_add_func_attr (tramp, LLVM_ATTR_NO_UNWIND);
3380 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
3381 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
3382 mono_llvm_add_param_attr (LLVMGetParam (tramp
, ctx
->rgctx_arg_pindex
), LLVM_ATTR_IN_REG
);
3383 if (ctx
->cfg
->vret_addr
) {
3384 LLVMSetValueName (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), "vret");
3385 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
3386 mono_llvm_add_param_attr (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVM_ATTR_STRUCT_RET
);
3387 mono_llvm_add_param_attr (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVM_ATTR_NO_ALIAS
);
3391 lbb
= LLVMAppendBasicBlock (tramp
, "");
3392 builder
= LLVMCreateBuilder ();
3393 LLVMPositionBuilderAtEnd (builder
, lbb
);
3395 nargs
= LLVMCountParamTypes (method_type
);
3396 args
= g_new0 (LLVMValueRef
, nargs
);
3397 for (i
= 0; i
< nargs
; ++i
) {
3398 args
[i
] = LLVMGetParam (tramp
, i
);
3399 if (i
== ctx
->this_arg_pindex
) {
3400 LLVMTypeRef arg_type
= LLVMTypeOf (args
[i
]);
3402 args
[i
] = LLVMBuildPtrToInt (builder
, args
[i
], IntPtrType (), "");
3403 args
[i
] = LLVMBuildAdd (builder
, args
[i
], LLVMConstInt (IntPtrType (), MONO_ABI_SIZEOF (MonoObject
), FALSE
), "");
3404 args
[i
] = LLVMBuildIntToPtr (builder
, args
[i
], arg_type
, "");
3407 call
= LLVMBuildCall (builder
, method
, args
, nargs
, "");
3408 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
3409 mono_llvm_add_instr_attr (call
, 1 + ctx
->rgctx_arg_pindex
, LLVM_ATTR_IN_REG
);
3410 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
)
3411 mono_llvm_add_instr_attr (call
, 1 + linfo
->vret_arg_pindex
, LLVM_ATTR_STRUCT_RET
);
3413 // FIXME: This causes assertions in clang
3414 //mono_llvm_set_must_tailcall (call);
3415 if (LLVMGetReturnType (method_type
) == LLVMVoidType ())
3416 LLVMBuildRetVoid (builder
);
3418 LLVMBuildRet (builder
, call
);
3420 g_hash_table_insert (ctx
->module
->idx_to_unbox_tramp
, GINT_TO_POINTER (method_index
), tramp
);
3421 LLVMDisposeBuilder (builder
);
3427 * Emit code to load/convert arguments.
3430 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
)
3433 MonoCompile
*cfg
= ctx
->cfg
;
3434 MonoMethodSignature
*sig
= ctx
->sig
;
3435 LLVMCallInfo
*linfo
= ctx
->linfo
;
3439 LLVMBuilderRef old_builder
= ctx
->builder
;
3440 ctx
->builder
= builder
;
3442 ctx
->alloca_builder
= create_builder (ctx
);
3445 * Handle indirect/volatile variables by allocating memory for them
3446 * using 'alloca', and storing their address in a temporary.
3448 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
3449 MonoInst
*var
= cfg
->varinfo
[i
];
3452 if (var
->opcode
== OP_GSHAREDVT_LOCAL
|| var
->opcode
== OP_GSHAREDVT_ARG_REGOFFSET
) {
3453 } 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
))) {
3454 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
3457 /* Could be already created by an OP_VPHI */
3458 if (!ctx
->addresses
[var
->dreg
]) {
3459 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
3460 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
3462 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
3466 names
= g_new (char *, sig
->param_count
);
3467 mono_method_get_param_names (cfg
->method
, (const char **) names
);
3469 for (i
= 0; i
< sig
->param_count
; ++i
) {
3470 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
3471 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
3474 pindex
= ainfo
->pindex
;
3476 switch (ainfo
->storage
) {
3477 case LLVMArgVtypeInReg
:
3478 case LLVMArgAsFpArgs
: {
3479 LLVMValueRef args
[8];
3482 pindex
+= ainfo
->ndummy_fpargs
;
3484 /* The argument is received as a set of int/fp arguments, store them into the real argument */
3485 memset (args
, 0, sizeof (args
));
3486 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
3487 args
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
3488 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
3489 args
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
3491 g_assert (ainfo
->nslots
<= 8);
3492 for (j
= 0; j
< ainfo
->nslots
; ++j
)
3493 args
[j
] = LLVMGetParam (ctx
->lmethod
, pindex
+ j
);
3495 ctx
->addresses
[reg
] = build_alloca (ctx
, ainfo
->type
);
3497 emit_args_to_vtype (ctx
, builder
, ainfo
->type
, ctx
->addresses
[reg
], ainfo
, args
);
3499 if (ainfo
->storage
== LLVMArgVtypeInReg
&& MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (ainfo
->type
))) {
3500 /* Treat these as normal values */
3501 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
3505 case LLVMArgVtypeByVal
: {
3506 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3508 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (ainfo
->type
))) {
3509 /* Treat these as normal values */
3510 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
3514 case LLVMArgVtypeByRef
: {
3515 /* The argument is passed by ref */
3516 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3519 case LLVMArgAsIArgs
: {
3520 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3522 MonoType
*t
= mini_get_underlying_type (ainfo
->type
);
3524 /* The argument is received as an array of ints, store it into the real argument */
3525 ctx
->addresses
[reg
] = build_alloca (ctx
, t
);
3527 size
= mono_class_value_size (mono_class_from_mono_type_internal (t
), NULL
);
3529 } else if (size
< TARGET_SIZEOF_VOID_P
) {
3530 /* The upper bits of the registers might not be valid */
3531 LLVMValueRef val
= LLVMBuildExtractValue (builder
, arg
, 0, "");
3532 LLVMValueRef dest
= convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMIntType (size
* 8), 0));
3533 LLVMBuildStore (ctx
->builder
, LLVMBuildTrunc (builder
, val
, LLVMIntType (size
* 8), ""), dest
);
3535 LLVMBuildStore (ctx
->builder
, arg
, convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMTypeOf (arg
), 0)));
3539 case LLVMArgVtypeAsScalar
:
3540 g_assert_not_reached ();
3542 case LLVMArgGsharedvtFixed
: {
3543 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3544 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3547 name
= g_strdup_printf ("arg_%s", names
[i
]);
3549 name
= g_strdup_printf ("arg_%d", i
);
3551 ctx
->values
[reg
] = LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), name
);
3554 case LLVMArgGsharedvtFixedVtype
: {
3555 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3558 name
= g_strdup_printf ("vtype_arg_%s", names
[i
]);
3560 name
= g_strdup_printf ("vtype_arg_%d", i
);
3562 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3563 g_assert (ctx
->addresses
[reg
]);
3564 LLVMSetValueName (ctx
->addresses
[reg
], name
);
3565 LLVMBuildStore (builder
, LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), ""), ctx
->addresses
[reg
]);
3568 case LLVMArgGsharedvtVariable
:
3569 /* The IR treats these as variables with addresses */
3570 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3573 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
));
3580 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
3582 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
3583 for (i
= 0; i
< sig
->param_count
; ++i
)
3584 if (!mini_type_is_vtype (sig
->params
[i
]))
3585 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
3587 if (sig
->hasthis
&& !cfg
->rgctx_var
&& cfg
->gshared
) {
3588 LLVMValueRef this_alloc
;
3591 * The exception handling code needs the location where the this argument was
3592 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3593 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3594 * location into the LSDA.
3596 this_alloc
= mono_llvm_build_alloca (builder
, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
3597 /* This volatile store will keep the alloca alive */
3598 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3600 set_metadata_flag (this_alloc
, "mono.this");
3603 if (cfg
->rgctx_var
) {
3604 LLVMValueRef rgctx_alloc
, store
;
3607 * We handle the rgctx arg similarly to the this pointer.
3609 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
3610 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
3611 /* This volatile store will keep the alloca alive */
3612 store
= mono_llvm_build_store (builder
, convert (ctx
, ctx
->rgctx_arg
, IntPtrType ()), rgctx_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3614 set_metadata_flag (rgctx_alloc
, "mono.this");
3617 /* Initialize the method if needed */
3618 if (cfg
->compile_aot
&& !ctx
->module
->llvm_disable_self_init
) {
3619 /* Emit a location for the initialization code */
3620 ctx
->init_bb
= gen_bb (ctx
, "INIT_BB");
3621 ctx
->inited_bb
= gen_bb (ctx
, "INITED_BB");
3623 LLVMBuildBr (ctx
->builder
, ctx
->init_bb
);
3624 builder
= ctx
->builder
= create_builder (ctx
);
3625 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->inited_bb
);
3626 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= ctx
->inited_bb
;
3629 /* Compute nesting between clauses */
3630 ctx
->nested_in
= (GSList
**)mono_mempool_alloc0 (cfg
->mempool
, sizeof (GSList
*) * cfg
->header
->num_clauses
);
3631 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
3632 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
3633 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
3634 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
3636 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
)
3637 ctx
->nested_in
[i
] = g_slist_prepend_mempool (cfg
->mempool
, ctx
->nested_in
[i
], GINT_TO_POINTER (j
));
3642 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3643 * it needs to continue normally, or return back to the exception handling system.
3645 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
3649 if (!(bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
)))
3652 clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
3653 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
3654 g_hash_table_insert (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
), bb
);
3656 if (bb
->in_scount
== 0) {
3659 sprintf (name
, "finally_ind_bb%d", bb
->block_num
);
3660 val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), name
);
3661 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
3663 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
3665 /* Create a variable to hold the exception var */
3667 ctx
->ex_var
= LLVMBuildAlloca (builder
, ObjRefType (), "exvar");
3671 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3672 * LLVM bblock containing a landing pad causes problems for the
3673 * LLVM optimizer passes.
3675 sprintf (name
, "BB%d_CALL_HANDLER_TARGET", bb
->block_num
);
3676 ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, name
);
3678 ctx
->builder
= old_builder
;
3682 needs_extra_arg (EmitContext
*ctx
, MonoMethod
*method
)
3684 WrapperInfo
*info
= NULL
;
3687 * When targeting wasm, the caller and callee signature has to match exactly. This means
3688 * that every method which can be called indirectly need an extra arg since the caller
3689 * will call it through an ftnptr and will pass an extra arg.
3691 if (!ctx
->cfg
->llvm_only
|| !ctx
->emit_dummy_arg
)
3693 if (method
->wrapper_type
)
3694 info
= mono_marshal_get_wrapper_info (method
);
3696 switch (method
->wrapper_type
) {
3697 case MONO_WRAPPER_OTHER
:
3698 if (info
->subtype
== WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG
|| info
->subtype
== WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG
)
3699 /* Already have an explicit extra arg */
3702 case MONO_WRAPPER_MANAGED_TO_NATIVE
:
3703 if (strstr (method
->name
, "icall_wrapper"))
3704 /* These are JIT icall wrappers which are only called from JITted code directly */
3706 /* Normal icalls can be virtual methods which need an extra arg */
3708 case MONO_WRAPPER_RUNTIME_INVOKE
:
3709 case MONO_WRAPPER_ALLOC
:
3710 case MONO_WRAPPER_CASTCLASS
:
3711 case MONO_WRAPPER_WRITE_BARRIER
:
3713 case MONO_WRAPPER_STELEMREF
:
3714 if (info
->subtype
!= WRAPPER_SUBTYPE_VIRTUAL_STELEMREF
)
3717 case MONO_WRAPPER_MANAGED_TO_MANAGED
:
3718 if (info
->subtype
== WRAPPER_SUBTYPE_STRING_CTOR
)
3724 if (method
->string_ctor
)
3727 /* These are called from gsharedvt code with an indirect call which doesn't pass an extra arg */
3728 if (method
->klass
== mono_get_string_class () && (strstr (method
->name
, "memcpy") || strstr (method
->name
, "bzero")))
3733 static inline gboolean
3734 is_supported_callconv (EmitContext
*ctx
, MonoCallInst
*call
)
3736 #if defined(TARGET_WIN32) && defined(TARGET_AMD64)
3737 gboolean result
= (call
->signature
->call_convention
== MONO_CALL_DEFAULT
) ||
3738 (call
->signature
->call_convention
== MONO_CALL_C
) ||
3739 (call
->signature
->call_convention
== MONO_CALL_STDCALL
);
3741 gboolean result
= (call
->signature
->call_convention
== MONO_CALL_DEFAULT
) || ((call
->signature
->call_convention
== MONO_CALL_C
) && ctx
->llvm_only
);
3747 process_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, MonoInst
*ins
)
3749 MonoCompile
*cfg
= ctx
->cfg
;
3750 LLVMValueRef
*values
= ctx
->values
;
3751 LLVMValueRef
*addresses
= ctx
->addresses
;
3752 MonoCallInst
*call
= (MonoCallInst
*)ins
;
3753 MonoMethodSignature
*sig
= call
->signature
;
3754 LLVMValueRef callee
= NULL
, lcall
;
3756 LLVMCallInfo
*cinfo
;
3760 LLVMTypeRef llvm_sig
;
3762 gboolean is_virtual
, calli
, preserveall
;
3763 LLVMBuilderRef builder
= *builder_ref
;
3765 /* If both imt and rgctx arg are required, only pass the imt arg, the rgctx trampoline will pass the rgctx */
3766 if (call
->imt_arg_reg
)
3767 call
->rgctx_arg_reg
= 0;
3769 if (!is_supported_callconv (ctx
, call
)) {
3770 set_failure (ctx
, "non-default callconv");
3774 cinfo
= call
->cinfo
;
3776 if (call
->rgctx_arg_reg
)
3777 cinfo
->rgctx_arg
= TRUE
;
3778 if (call
->imt_arg_reg
)
3779 cinfo
->imt_arg
= TRUE
;
3780 if (!call
->rgctx_arg_reg
&& call
->method
&& needs_extra_arg (ctx
, call
->method
))
3781 cinfo
->dummy_arg
= TRUE
;
3783 vretaddr
= (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
|| cinfo
->ret
.storage
== LLVMArgVtypeByRef
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixed
|| cinfo
->ret
.storage
== LLVMArgGsharedvtVariable
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixedVtype
);
3785 llvm_sig
= sig_to_llvm_sig_full (ctx
, sig
, cinfo
);
3789 int const opcode
= ins
->opcode
;
3791 is_virtual
= opcode
== OP_VOIDCALL_MEMBASE
|| opcode
== OP_CALL_MEMBASE
3792 || opcode
== OP_VCALL_MEMBASE
|| opcode
== OP_LCALL_MEMBASE
3793 || opcode
== OP_FCALL_MEMBASE
|| opcode
== OP_RCALL_MEMBASE
3794 || opcode
== OP_TAILCALL_MEMBASE
;
3795 calli
= !call
->fptr_is_patch
&& (opcode
== OP_VOIDCALL_REG
|| opcode
== OP_CALL_REG
3796 || opcode
== OP_VCALL_REG
|| opcode
== OP_LCALL_REG
|| opcode
== OP_FCALL_REG
3797 || opcode
== OP_RCALL_REG
|| opcode
== OP_TAILCALL_REG
);
3800 preserveall
= FALSE
;
3802 /* FIXME: Avoid creating duplicate methods */
3804 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3808 if (cfg
->compile_aot
) {
3809 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
3811 set_failure (ctx
, "can't encode patch");
3816 static int tramp_index
;
3819 name
= g_strdup_printf ("tramp_%d", tramp_index
);
3822 #if LLVM_API_VERSION > 100
3824 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3825 * Make all calls through a global. The address of the global will be saved in
3826 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3829 LLVMValueRef tramp_var
= (LLVMValueRef
)g_hash_table_lookup (ctx
->jit_callees
, call
->method
);
3832 mono_create_jit_trampoline (mono_domain_get (),
3833 call
->method
, error
);
3834 if (!is_ok (error
)) {
3835 set_failure (ctx
, mono_error_get_message (error
));
3836 mono_error_cleanup (error
);
3840 tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
3841 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
3842 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
3843 g_hash_table_insert (ctx
->jit_callees
, call
->method
, tramp_var
);
3845 callee
= LLVMBuildLoad (builder
, tramp_var
, "");
3847 g_assert_not_reached ();
3852 if (!cfg
->llvm_only
&& call
->method
&& strstr (m_class_get_name (call
->method
->klass
), "AsyncVoidMethodBuilder")) {
3853 /* LLVM miscompiles async methods */
3854 set_failure (ctx
, "#13734");
3859 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
3862 if (cfg
->compile_aot
) {
3863 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (mono_jit_icall_info_id (info
)));
3865 set_failure (ctx
, "can't encode patch");
3869 callee
= get_jit_callee (ctx
, "", llvm_sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (mono_jit_icall_info_id (info
)));
3872 if (cfg
->compile_aot
) {
3874 if (cfg
->abs_patches
) {
3875 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3877 callee
= get_callee (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
3879 set_failure (ctx
, "can't encode patch");
3885 set_failure (ctx
, "aot");
3889 #if LLVM_API_VERSION > 100
3890 if (cfg
->abs_patches
) {
3891 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3895 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
, error
);
3896 mono_error_assert_ok (error
);
3897 callee
= get_jit_callee (ctx
, "", llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
3899 g_assert_not_reached ();
3902 g_assert_not_reached ();
3905 g_assert_not_reached ();
3912 int size
= TARGET_SIZEOF_VOID_P
;
3915 g_assert (ins
->inst_offset
% size
== 0);
3916 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3918 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
3920 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
3922 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3927 * Collect and convert arguments
3929 nargs
= (sig
->param_count
* 16) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
+ call
->imt_arg_reg
+ call
->cinfo
->dummy_arg
+ 1;
3930 len
= sizeof (LLVMValueRef
) * nargs
;
3931 args
= g_newa (LLVMValueRef
, nargs
);
3932 memset (args
, 0, len
);
3933 l
= call
->out_ireg_args
;
3935 if (call
->rgctx_arg_reg
) {
3936 g_assert (values
[call
->rgctx_arg_reg
]);
3937 g_assert (cinfo
->rgctx_arg_pindex
< nargs
);
3939 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3940 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3941 * it using a volatile load.
3944 if (!ctx
->imt_rgctx_loc
)
3945 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, TARGET_SIZEOF_VOID_P
);
3946 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3947 args
[cinfo
->rgctx_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3949 args
[cinfo
->rgctx_arg_pindex
] = convert (ctx
, values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
);
3952 if (call
->imt_arg_reg
) {
3953 g_assert (!ctx
->llvm_only
);
3954 g_assert (values
[call
->imt_arg_reg
]);
3955 g_assert (cinfo
->imt_arg_pindex
< nargs
);
3957 if (!ctx
->imt_rgctx_loc
)
3958 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, TARGET_SIZEOF_VOID_P
);
3959 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3960 args
[cinfo
->imt_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3962 args
[cinfo
->imt_arg_pindex
] = convert (ctx
, values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
);
3965 switch (cinfo
->ret
.storage
) {
3966 case LLVMArgGsharedvtVariable
: {
3967 MonoInst
*var
= get_vreg_to_inst (cfg
, call
->inst
.dreg
);
3969 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
3970 args
[cinfo
->vret_arg_pindex
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), IntPtrType ());
3972 g_assert (addresses
[call
->inst
.dreg
]);
3973 args
[cinfo
->vret_arg_pindex
] = convert (ctx
, addresses
[call
->inst
.dreg
], IntPtrType ());
3979 if (!addresses
[call
->inst
.dreg
])
3980 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3981 g_assert (cinfo
->vret_arg_pindex
< nargs
);
3982 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
3983 args
[cinfo
->vret_arg_pindex
] = addresses
[call
->inst
.dreg
];
3985 args
[cinfo
->vret_arg_pindex
] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
3991 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3992 * use the real callee for argument type conversion.
3994 LLVMTypeRef callee_type
= LLVMGetElementType (LLVMTypeOf (callee
));
3995 LLVMTypeRef
*param_types
= (LLVMTypeRef
*)g_alloca (sizeof (LLVMTypeRef
) * LLVMCountParamTypes (callee_type
));
3996 LLVMGetParamTypes (callee_type
, param_types
);
3998 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
4001 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
];
4003 pindex
= ainfo
->pindex
;
4005 regpair
= (guint32
)(gssize
)(l
->data
);
4006 reg
= regpair
& 0xffffff;
4007 args
[pindex
] = values
[reg
];
4008 switch (ainfo
->storage
) {
4009 case LLVMArgVtypeInReg
:
4010 case LLVMArgAsFpArgs
: {
4014 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
4015 args
[pindex
+ j
] = LLVMConstNull (LLVMDoubleType ());
4016 pindex
+= ainfo
->ndummy_fpargs
;
4018 g_assert (addresses
[reg
]);
4019 emit_vtype_to_args (ctx
, builder
, ainfo
->type
, addresses
[reg
], ainfo
, args
+ pindex
, &nargs
);
4023 // FIXME: Get rid of the VMOVE
4026 case LLVMArgVtypeByVal
:
4027 g_assert (addresses
[reg
]);
4028 args
[pindex
] = addresses
[reg
];
4030 case LLVMArgVtypeByRef
: {
4031 g_assert (addresses
[reg
]);
4032 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
4035 case LLVMArgAsIArgs
:
4036 g_assert (addresses
[reg
]);
4037 if (ainfo
->esize
== 8)
4038 args
[pindex
] = LLVMBuildLoad (ctx
->builder
, convert (ctx
, addresses
[reg
], LLVMPointerType (LLVMArrayType (LLVMInt64Type (), ainfo
->nslots
), 0)), "");
4040 args
[pindex
] = LLVMBuildLoad (ctx
->builder
, convert (ctx
, addresses
[reg
], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo
->nslots
), 0)), "");
4042 case LLVMArgVtypeAsScalar
:
4043 g_assert_not_reached ();
4045 case LLVMArgGsharedvtFixed
:
4046 case LLVMArgGsharedvtFixedVtype
:
4047 g_assert (addresses
[reg
]);
4048 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
4050 case LLVMArgGsharedvtVariable
:
4051 g_assert (addresses
[reg
]);
4052 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (IntPtrType (), 0));
4055 g_assert (args
[pindex
]);
4056 if (i
== 0 && sig
->hasthis
)
4057 args
[pindex
] = convert (ctx
, args
[pindex
], param_types
[pindex
]);
4059 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, ainfo
->type
));
4062 g_assert (pindex
<= nargs
);
4068 if (call
->cinfo
->dummy_arg
) {
4069 g_assert (call
->cinfo
->dummy_arg_pindex
< nargs
);
4070 args
[call
->cinfo
->dummy_arg_pindex
] = LLVMConstNull (ctx
->module
->ptr_type
);
4073 // FIXME: Align call sites
4078 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, LLVMCountParamTypes (llvm_sig
));
4080 mono_llvm_nonnull_state_update (ctx
, lcall
, call
->method
, args
, LLVMCountParamTypes (llvm_sig
));
4082 // If we just allocated an object, it's not null.
4083 if (call
->method
&& call
->method
->wrapper_type
== MONO_WRAPPER_ALLOC
) {
4084 mono_llvm_set_call_nonnull_ret (lcall
);
4087 if (ins
->opcode
!= OP_TAILCALL
&& ins
->opcode
!= OP_TAILCALL_MEMBASE
&& LLVMGetInstructionOpcode (lcall
) == LLVMCall
)
4088 mono_llvm_set_call_notailcall (lcall
);
4090 // As per the LLVM docs, a function has a noalias return value if and only if
4091 // it is an allocation function. This is an allocation function.
4092 if (call
->method
&& call
->method
->wrapper_type
== MONO_WRAPPER_ALLOC
)
4093 mono_llvm_set_call_noalias_ret (lcall
);
4096 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
4098 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
4099 g_assert (MONO_ARCH_IMT_REG
== MONO_ARCH_RGCTX_REG
);
4101 /* The two can't be used together, so use only one LLVM calling conv to pass them */
4102 g_assert (!(call
->rgctx_arg_reg
&& call
->imt_arg_reg
));
4103 if (!sig
->pinvoke
&& !cfg
->llvm_only
)
4104 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
4106 set_call_preserveall_cc (lcall
);
4108 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
4109 mono_llvm_add_instr_attr (lcall
, 1 + cinfo
->vret_arg_pindex
, LLVM_ATTR_STRUCT_RET
);
4110 if (!ctx
->llvm_only
&& call
->rgctx_arg_reg
)
4111 mono_llvm_add_instr_attr (lcall
, 1 + cinfo
->rgctx_arg_pindex
, LLVM_ATTR_IN_REG
);
4112 if (call
->imt_arg_reg
)
4113 mono_llvm_add_instr_attr (lcall
, 1 + cinfo
->imt_arg_pindex
, LLVM_ATTR_IN_REG
);
4115 /* Add byval attributes if needed */
4116 for (i
= 0; i
< sig
->param_count
; ++i
) {
4117 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
+ sig
->hasthis
];
4119 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
)
4120 mono_llvm_add_instr_attr (lcall
, 1 + ainfo
->pindex
, LLVM_ATTR_BY_VAL
);
4124 * Convert the result
4126 switch (cinfo
->ret
.storage
) {
4127 case LLVMArgVtypeInReg
: {
4128 LLVMValueRef regs
[2];
4130 if (LLVMTypeOf (lcall
) == LLVMVoidType ())
4134 if (!addresses
[ins
->dreg
])
4135 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
4137 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
4138 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
4139 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
4140 emit_args_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
4143 case LLVMArgVtypeByVal
:
4144 if (!addresses
[call
->inst
.dreg
])
4145 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
4146 LLVMBuildStore (builder
, lcall
, addresses
[call
->inst
.dreg
]);
4148 case LLVMArgAsIArgs
:
4149 case LLVMArgFpStruct
:
4150 if (!addresses
[call
->inst
.dreg
])
4151 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
4152 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
4154 case LLVMArgVtypeAsScalar
:
4155 if (!addresses
[call
->inst
.dreg
])
4156 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
4157 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
4159 case LLVMArgVtypeRetAddr
:
4160 case LLVMArgVtypeByRef
:
4161 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (sig
->ret
))) {
4162 /* Some opcodes like STOREX_MEMBASE access these by value */
4163 g_assert (addresses
[call
->inst
.dreg
]);
4164 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
4167 case LLVMArgGsharedvtVariable
:
4169 case LLVMArgGsharedvtFixed
:
4170 case LLVMArgGsharedvtFixedVtype
:
4171 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
4174 if (sig
->ret
->type
!= MONO_TYPE_VOID
)
4175 /* If the method returns an unsigned value, need to zext it */
4176 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
));
4180 *builder_ref
= ctx
->builder
;
4184 emit_llvmonly_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
4186 MonoJitICallId icall_id
= rethrow
? MONO_JIT_ICALL_mono_llvm_rethrow_exception
: MONO_JIT_ICALL_mono_llvm_throw_exception
;
4187 LLVMValueRef callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
4189 LLVMTypeRef exc_type
= type_to_llvm_type (ctx
, m_class_get_byval_arg (mono_get_exception_class ()));
4192 LLVMTypeRef fun_sig
= LLVMFunctionType1 (LLVMVoidType (), exc_type
, FALSE
);
4194 g_assert (ctx
->cfg
->compile_aot
);
4195 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, GUINT_TO_POINTER (icall_id
));
4198 LLVMValueRef args
[2];
4200 args
[0] = convert (ctx
, exc
, exc_type
);
4201 emit_call (ctx
, bb
, &ctx
->builder
, callee
, args
, 1);
4203 LLVMBuildUnreachable (ctx
->builder
);
4205 ctx
->builder
= create_builder (ctx
);
4209 emit_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
4211 MonoMethodSignature
*throw_sig
;
4213 LLVMValueRef
* const pcallee
= rethrow
? &ctx
->module
->rethrow
: &ctx
->module
->throw_icall
;
4214 LLVMValueRef callee
= *pcallee
;
4215 char const * const icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4219 MonoJitICallId icall_id
= rethrow
? MONO_JIT_ICALL_mono_arch_rethrow_exception
: MONO_JIT_ICALL_mono_arch_throw_exception
;
4222 throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 1);
4223 throw_sig
->ret
= m_class_get_byval_arg (mono_get_void_class ());
4224 throw_sig
->params
[0] = m_class_get_byval_arg (mono_get_object_class ());
4225 if (ctx
->cfg
->compile_aot
) {
4226 callee
= get_callee (ctx
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
4230 * LLVM doesn't push the exception argument, so we need a different
4233 icall_id
= rethrow
? MONO_JIT_ICALL_mono_llvm_rethrow_exception_trampoline
: MONO_JIT_ICALL_mono_llvm_throw_exception_trampoline
;
4235 callee
= get_jit_callee (ctx
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
4238 mono_memory_barrier ();
4239 #if LLVM_API_VERSION < 100
4244 arg
= convert (ctx
, exc
, type_to_llvm_type (ctx
, m_class_get_byval_arg (mono_get_object_class ())));
4245 emit_call (ctx
, bb
, &ctx
->builder
, callee
, &arg
, 1);
4249 emit_resume_eh (EmitContext
*ctx
, MonoBasicBlock
*bb
)
4251 const MonoJitICallId icall_id
= MONO_JIT_ICALL_mono_llvm_resume_exception
;
4252 LLVMValueRef callee
;
4254 LLVMTypeRef fun_sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
4256 g_assert (ctx
->cfg
->compile_aot
);
4257 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
4259 emit_call (ctx
, bb
, &ctx
->builder
, callee
, NULL
, 0);
4261 LLVMBuildUnreachable (ctx
->builder
);
4263 ctx
->builder
= create_builder (ctx
);
4267 mono_llvm_emit_clear_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
4269 const char *icall_name
= "mono_llvm_clear_exception";
4270 const MonoJitICallId icall_id
= MONO_JIT_ICALL_mono_llvm_clear_exception
;
4272 LLVMTypeRef call_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
4273 LLVMValueRef callee
= NULL
;
4276 if (ctx
->cfg
->compile_aot
) {
4277 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
4279 // FIXME: This is broken.
4280 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
4284 g_assert (builder
&& callee
);
4286 return LLVMBuildCall (builder
, callee
, NULL
, 0, "");
4290 mono_llvm_emit_load_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
4292 const char *icall_name
= "mono_llvm_load_exception";
4293 const MonoJitICallId icall_id
= MONO_JIT_ICALL_mono_llvm_load_exception
;
4295 LLVMTypeRef call_sig
= LLVMFunctionType (ObjRefType (), NULL
, 0, FALSE
);
4296 LLVMValueRef callee
= NULL
;
4299 if (ctx
->cfg
->compile_aot
) {
4300 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
4302 // FIXME: This is broken.
4303 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
4307 g_assert (builder
&& callee
);
4309 return LLVMBuildCall (builder
, callee
, NULL
, 0, icall_name
);
4314 mono_llvm_emit_match_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
, gint32 region_start
, gint32 region_end
)
4316 const char *icall_name
= "mono_llvm_match_exception";
4317 const MonoJitICallId icall_id
= MONO_JIT_ICALL_mono_llvm_match_exception
;
4319 ctx
->builder
= builder
;
4321 LLVMValueRef args
[5];
4322 const int num_args
= G_N_ELEMENTS (args
);
4324 args
[0] = convert (ctx
, get_aotconst (ctx
, MONO_PATCH_INFO_AOT_JIT_INFO
, GINT_TO_POINTER (ctx
->cfg
->method_index
)), IntPtrType ());
4325 args
[1] = LLVMConstInt (LLVMInt32Type (), region_start
, 0);
4326 args
[2] = LLVMConstInt (LLVMInt32Type (), region_end
, 0);
4327 if (ctx
->cfg
->rgctx_var
) {
4328 LLVMValueRef rgctx_alloc
= ctx
->addresses
[ctx
->cfg
->rgctx_var
->dreg
];
4329 g_assert (rgctx_alloc
);
4330 args
[3] = LLVMBuildLoad (builder
, convert (ctx
, rgctx_alloc
, LLVMPointerType (IntPtrType (), 0)), "");
4332 args
[3] = LLVMConstInt (IntPtrType (), 0, 0);
4335 args
[4] = convert (ctx
, ctx
->this_arg
, IntPtrType ());
4337 args
[4] = LLVMConstInt (IntPtrType (), 0, 0);
4339 LLVMTypeRef match_sig
= LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE
);
4340 LLVMValueRef callee
;
4341 g_assert (ctx
->cfg
->compile_aot
);
4342 ctx
->builder
= builder
;
4343 // get_callee expects ctx->builder to be the emitting builder
4344 callee
= get_callee (ctx
, match_sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
4346 g_assert (builder
&& callee
);
4348 g_assert (ctx
->ex_var
);
4350 return LLVMBuildCall (builder
, callee
, args
, num_args
, icall_name
);
4353 // FIXME: This won't work because the code-finding makes this
4355 /*#define MONO_PERSONALITY_DEBUG*/
4357 #ifdef MONO_PERSONALITY_DEBUG
4358 static const gboolean use_mono_personality_debug
= TRUE
;
4359 static const char *default_personality_name
= "mono_debug_personality";
4361 static const gboolean use_mono_personality_debug
= FALSE
;
4362 static const char *default_personality_name
= "__gxx_personality_v0";
4366 default_cpp_lpad_exc_signature (void)
4368 static gboolean inited
= FALSE
;
4369 static LLVMTypeRef sig
;
4372 LLVMTypeRef signature
[2];
4373 signature
[0] = LLVMPointerType (LLVMInt8Type (), 0);
4374 signature
[1] = LLVMInt32Type ();
4375 sig
= LLVMStructType (signature
, 2, FALSE
);
4383 get_mono_personality (EmitContext
*ctx
)
4385 LLVMValueRef personality
= NULL
;
4386 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
4388 g_assert (ctx
->cfg
->compile_aot
);
4389 if (!use_mono_personality_debug
) {
4390 personality
= get_intrins_by_name (ctx
, default_personality_name
);
4392 personality
= get_callee (ctx
, personality_type
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_debug_personality
));
4395 g_assert (personality
);
4399 static LLVMBasicBlockRef
4400 emit_landing_pad (EmitContext
*ctx
, int group_index
, int group_size
)
4402 MonoCompile
*cfg
= ctx
->cfg
;
4403 LLVMBuilderRef old_builder
= ctx
->builder
;
4404 MonoExceptionClause
*group_start
= cfg
->header
->clauses
+ group_index
;
4406 LLVMBuilderRef lpadBuilder
= create_builder (ctx
);
4407 ctx
->builder
= lpadBuilder
;
4409 MonoBasicBlock
*handler_bb
= cfg
->cil_offset_to_bb
[CLAUSE_START (group_start
)];
4410 g_assert (handler_bb
);
4412 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4413 LLVMValueRef personality
= get_mono_personality (ctx
);
4414 g_assert (personality
);
4416 char *bb_name
= g_strdup_printf ("LPAD%d_BB", group_index
);
4417 LLVMBasicBlockRef lpad_bb
= gen_bb (ctx
, bb_name
);
4419 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
4420 LLVMValueRef landing_pad
= LLVMBuildLandingPad (lpadBuilder
, default_cpp_lpad_exc_signature (), personality
, 0, "");
4421 g_assert (landing_pad
);
4423 LLVMValueRef cast
= LLVMBuildBitCast (lpadBuilder
, ctx
->module
->sentinel_exception
, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
4424 LLVMAddClause (landing_pad
, cast
);
4426 LLVMBasicBlockRef resume_bb
= gen_bb (ctx
, "RESUME_BB");
4427 LLVMBuilderRef resume_builder
= create_builder (ctx
);
4428 ctx
->builder
= resume_builder
;
4429 LLVMPositionBuilderAtEnd (resume_builder
, resume_bb
);
4431 emit_resume_eh (ctx
, handler_bb
);
4434 ctx
->builder
= lpadBuilder
;
4435 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
4437 gboolean finally_only
= TRUE
;
4439 MonoExceptionClause
*group_cursor
= group_start
;
4441 for (int i
= 0; i
< group_size
; i
++) {
4442 if (!(group_cursor
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
|| group_cursor
->flags
& MONO_EXCEPTION_CLAUSE_FAULT
))
4443 finally_only
= FALSE
;
4449 // Handle landing pad inlining
4451 if (!finally_only
) {
4452 // So at each level of the exception stack we will match the exception again.
4453 // During that match, we need to compare against the handler types for the current
4454 // protected region. We send the try start and end so that we can only check against
4455 // handlers for this lexical protected region.
4456 LLVMValueRef match
= mono_llvm_emit_match_exception_call (ctx
, lpadBuilder
, group_start
->try_offset
, group_start
->try_offset
+ group_start
->try_len
);
4458 // if returns -1, resume
4459 LLVMValueRef switch_ins
= LLVMBuildSwitch (lpadBuilder
, match
, resume_bb
, group_size
);
4461 // else move to that target bb
4462 for (int i
= 0; i
< group_size
; i
++) {
4463 MonoExceptionClause
*clause
= group_start
+ i
;
4464 int clause_index
= clause
- cfg
->header
->clauses
;
4465 MonoBasicBlock
*handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
4466 g_assert (handler_bb
);
4467 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4468 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4471 int clause_index
= group_start
- cfg
->header
->clauses
;
4472 MonoBasicBlock
*finally_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
4473 g_assert (finally_bb
);
4475 LLVMBuildBr (ctx
->builder
, ctx
->bblocks
[finally_bb
->block_num
].call_handler_target_bb
);
4478 ctx
->builder
= old_builder
;
4485 emit_llvmonly_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBasicBlockRef cbb
)
4487 int clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
4488 MonoExceptionClause
*clause
= &ctx
->cfg
->header
->clauses
[clause_index
];
4490 // Make exception available to catch blocks
4491 if (!(clause
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
|| clause
->flags
& MONO_EXCEPTION_CLAUSE_FAULT
)) {
4492 LLVMValueRef mono_exc
= mono_llvm_emit_load_exception_call (ctx
, ctx
->builder
);
4494 g_assert (ctx
->ex_var
);
4495 LLVMBuildStore (ctx
->builder
, LLVMBuildBitCast (ctx
->builder
, mono_exc
, ObjRefType (), ""), ctx
->ex_var
);
4497 if (bb
->in_scount
== 1) {
4498 MonoInst
*exvar
= bb
->in_stack
[0];
4499 g_assert (!ctx
->values
[exvar
->dreg
]);
4500 g_assert (ctx
->ex_var
);
4501 ctx
->values
[exvar
->dreg
] = LLVMBuildLoad (ctx
->builder
, ctx
->ex_var
, "save_exception");
4502 emit_volatile_store (ctx
, exvar
->dreg
);
4505 mono_llvm_emit_clear_exception_call (ctx
, ctx
->builder
);
4508 LLVMBuilderRef handler_builder
= create_builder (ctx
);
4509 LLVMBasicBlockRef target_bb
= ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
;
4510 LLVMPositionBuilderAtEnd (handler_builder
, target_bb
);
4512 // Make the handler code end with a jump to cbb
4513 LLVMBuildBr (handler_builder
, cbb
);
4517 emit_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef builder
)
4519 MonoCompile
*cfg
= ctx
->cfg
;
4520 LLVMValueRef
*values
= ctx
->values
;
4521 LLVMModuleRef lmodule
= ctx
->lmodule
;
4522 BBInfo
*bblocks
= ctx
->bblocks
;
4524 LLVMValueRef personality
;
4525 LLVMValueRef landing_pad
;
4526 LLVMBasicBlockRef target_bb
;
4528 static int ti_generator
;
4530 LLVMValueRef type_info
;
4534 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4536 if (cfg
->compile_aot
) {
4537 /* Use a dummy personality function */
4538 personality
= LLVMGetNamedFunction (lmodule
, "mono_personality");
4539 g_assert (personality
);
4541 #if LLVM_API_VERSION > 100
4542 /* Can't cache this as each method is in its own llvm module */
4543 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
4544 personality
= LLVMAddFunction (ctx
->lmodule
, "mono_personality", personality_type
);
4545 mono_llvm_add_func_attr (personality
, LLVM_ATTR_NO_UNWIND
);
4546 LLVMBasicBlockRef entry_bb
= LLVMAppendBasicBlock (personality
, "ENTRY");
4547 LLVMBuilderRef builder2
= LLVMCreateBuilder ();
4548 LLVMPositionBuilderAtEnd (builder2
, entry_bb
);
4549 LLVMBuildRet (builder2
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
));
4550 LLVMDisposeBuilder (builder2
);
4552 g_assert_not_reached ();
4556 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
4558 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
4561 * Create the type info
4563 sprintf (ti_name
, "type_info_%d", ti_generator
);
4566 if (cfg
->compile_aot
) {
4567 /* decode_eh_frame () in aot-runtime.c will decode this */
4568 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4569 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4572 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4574 LLVMSetLinkage (type_info
, LLVMInternalLinkage
);
4576 #if LLVM_API_VERSION > 100
4577 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4578 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4580 g_assert_not_reached ();
4585 LLVMTypeRef members
[2], ret_type
;
4587 members
[0] = i8ptr
;
4588 members
[1] = LLVMInt32Type ();
4589 ret_type
= LLVMStructType (members
, 2, FALSE
);
4591 landing_pad
= LLVMBuildLandingPad (builder
, ret_type
, personality
, 1, "");
4592 LLVMAddClause (landing_pad
, type_info
);
4594 /* Store the exception into the exvar */
4596 LLVMBuildStore (builder
, convert (ctx
, LLVMBuildExtractValue (builder
, landing_pad
, 0, "ex_obj"), ObjRefType ()), ctx
->ex_var
);
4600 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4601 * code expects control to be transferred to this landing pad even in the
4602 * presence of nested clauses. The landing pad needs to branch to the landing
4603 * pads belonging to nested clauses based on the selector value returned by
4604 * the landing pad instruction, which is passed to the landing pad in a
4605 * register by the EH code.
4607 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
4608 g_assert (target_bb
);
4611 * Branch to the correct landing pad
4613 LLVMValueRef ex_selector
= LLVMBuildExtractValue (builder
, landing_pad
, 1, "ex_selector");
4614 LLVMValueRef switch_ins
= LLVMBuildSwitch (builder
, ex_selector
, target_bb
, 0);
4616 for (l
= ctx
->nested_in
[clause_index
]; l
; l
= l
->next
) {
4617 int nesting_clause_index
= GPOINTER_TO_INT (l
->data
);
4618 MonoBasicBlock
*handler_bb
;
4620 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (nesting_clause_index
));
4621 g_assert (handler_bb
);
4623 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4624 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), nesting_clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4627 /* Start a new bblock which CALL_HANDLER can branch to */
4628 ctx
->builder
= builder
= create_builder (ctx
);
4629 LLVMPositionBuilderAtEnd (ctx
->builder
, target_bb
);
4631 ctx
->bblocks
[bb
->block_num
].end_bblock
= target_bb
;
4633 /* Store the exception into the IL level exvar */
4634 if (bb
->in_scount
== 1) {
4635 g_assert (bb
->in_scount
== 1);
4636 exvar
= bb
->in_stack
[0];
4638 // FIXME: This is shared with filter clauses ?
4639 g_assert (!values
[exvar
->dreg
]);
4641 g_assert (ctx
->ex_var
);
4642 values
[exvar
->dreg
] = LLVMBuildLoad (builder
, ctx
->ex_var
, "");
4643 emit_volatile_store (ctx
, exvar
->dreg
);
4646 /* Make normal branches to the start of the clause branch to the new bblock */
4647 bblocks
[bb
->block_num
].bblock
= target_bb
;
4650 //Wasm requires us to canonicalize NaNs.
4652 get_double_const (MonoCompile
*cfg
, double val
)
4655 if (mono_isnan (val
))
4656 *(gint64
*)&val
= 0x7FF8000000000000ll
;
4658 return LLVMConstReal (LLVMDoubleType (), val
);
4662 get_float_const (MonoCompile
*cfg
, float val
)
4665 if (mono_isnan (val
))
4666 *(int *)&val
= 0x7FC00000;
4669 return LLVMConstReal (LLVMFloatType (), val
);
4671 return LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), val
), LLVMDoubleType ());
4675 process_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
4677 MonoCompile
*cfg
= ctx
->cfg
;
4678 MonoMethodSignature
*sig
= ctx
->sig
;
4679 LLVMValueRef method
= ctx
->lmethod
;
4680 LLVMValueRef
*values
= ctx
->values
;
4681 LLVMValueRef
*addresses
= ctx
->addresses
;
4682 LLVMCallInfo
*linfo
= ctx
->linfo
;
4683 BBInfo
*bblocks
= ctx
->bblocks
;
4685 LLVMBasicBlockRef cbb
;
4686 LLVMBuilderRef builder
, starting_builder
;
4687 gboolean has_terminator
;
4689 LLVMValueRef lhs
, rhs
;
4692 cbb
= get_end_bb (ctx
, bb
);
4694 builder
= create_builder (ctx
);
4695 ctx
->builder
= builder
;
4696 LLVMPositionBuilderAtEnd (builder
, cbb
);
4701 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
4702 if (!ctx
->llvm_only
&& !bblocks
[bb
->block_num
].invoke_target
) {
4703 set_failure (ctx
, "handler without invokes");
4708 emit_llvmonly_handler_start (ctx
, bb
, cbb
);
4710 emit_handler_start (ctx
, bb
, builder
);
4713 builder
= ctx
->builder
;
4716 has_terminator
= FALSE
;
4717 starting_builder
= builder
;
4718 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
4719 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
4721 char dname_buf
[128];
4723 emit_dbg_loc (ctx
, builder
, ins
->cil_code
);
4728 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4729 * Start a new bblock.
4730 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4731 * from localloc-ed memory.
4733 if (!cfg
->llvm_only
)
4734 ;//set_failure (ctx, "basic block too long");
4736 if (!ctx
->long_bb_break_var
) {
4737 ctx
->long_bb_break_var
= build_alloca_llvm_type_name (ctx
, LLVMInt32Type (), 0, "long_bb_break");
4738 mono_llvm_build_store (ctx
->alloca_builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), ctx
->long_bb_break_var
, TRUE
, LLVM_BARRIER_NONE
);
4741 cbb
= gen_bb (ctx
, "CONT_LONG_BB");
4742 LLVMBasicBlockRef dummy_bb
= gen_bb (ctx
, "CONT_LONG_BB_DUMMY");
4744 LLVMValueRef load
= mono_llvm_build_load (builder
, ctx
->long_bb_break_var
, "", TRUE
);
4746 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4747 * but llvm doesn't know that, so the branch is not going to be eliminated.
4749 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, load
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
4751 LLVMBuildCondBr (builder
, cmp
, cbb
, dummy_bb
);
4753 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4754 ctx
->builder
= builder
= create_builder (ctx
);
4755 LLVMPositionBuilderAtEnd (builder
, dummy_bb
);
4756 mono_llvm_build_store (builder
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), ctx
->long_bb_break_var
, TRUE
, LLVM_BARRIER_NONE
);
4757 LLVMBuildBr (builder
, cbb
);
4759 ctx
->builder
= builder
= create_builder (ctx
);
4760 LLVMPositionBuilderAtEnd (builder
, cbb
);
4761 ctx
->bblocks
[bb
->block_num
].end_bblock
= cbb
;
4764 emit_dbg_loc (ctx
, builder
, ins
->cil_code
);
4768 /* There could be instructions after a terminator, skip them */
4771 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
4772 sprintf (dname_buf
, "t%d", ins
->dreg
);
4776 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
4777 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
4779 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) && var
->opcode
!= OP_GSHAREDVT_ARG_REGOFFSET
) {
4780 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
4782 /* It is ok for SETRET to have an uninitialized argument */
4783 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
) {
4784 set_failure (ctx
, "sreg1");
4787 lhs
= values
[ins
->sreg1
];
4793 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
4794 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
4795 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
4796 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
4798 if (!values
[ins
->sreg2
]) {
4799 set_failure (ctx
, "sreg2");
4802 rhs
= values
[ins
->sreg2
];
4808 //mono_print_ins (ins);
4809 switch (ins
->opcode
) {
4812 case OP_LIVERANGE_START
:
4813 case OP_LIVERANGE_END
:
4816 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
4819 #if TARGET_SIZEOF_VOID_P == 4
4820 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4822 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
4826 values
[ins
->dreg
] = get_double_const (cfg
, *(double*)ins
->inst_p0
);
4829 values
[ins
->dreg
] = get_float_const (cfg
, *(float*)ins
->inst_p0
);
4831 case OP_DUMMY_ICONST
:
4832 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4834 case OP_DUMMY_I8CONST
:
4835 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
4837 case OP_DUMMY_R8CONST
:
4838 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), 0.0f
);
4841 LLVMBasicBlockRef target_bb
= get_bb (ctx
, ins
->inst_target_bb
);
4842 LLVMBuildBr (builder
, target_bb
);
4843 has_terminator
= TRUE
;
4850 LLVMBasicBlockRef new_bb
;
4851 LLVMBuilderRef new_builder
;
4853 // The default branch is already handled
4854 // FIXME: Handle it here
4856 /* Start new bblock */
4857 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
4858 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
4860 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4861 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
4862 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
4863 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
4865 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
4868 new_builder
= create_builder (ctx
);
4869 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
4870 LLVMBuildUnreachable (new_builder
);
4872 has_terminator
= TRUE
;
4873 g_assert (!ins
->next
);
4879 switch (linfo
->ret
.storage
) {
4880 case LLVMArgVtypeInReg
: {
4881 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4882 LLVMValueRef val
, addr
, retval
;
4885 retval
= LLVMGetUndef (ret_type
);
4887 if (!addresses
[ins
->sreg1
]) {
4889 * The return type is an LLVM vector type, have to convert between it and the
4890 * real return type which is a struct type.
4892 g_assert (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type_internal (sig
->ret
)));
4893 /* Convert to 2xi64 first */
4894 val
= LLVMBuildBitCast (builder
, values
[ins
->sreg1
], LLVMVectorType (IntPtrType (), 2), "");
4896 for (i
= 0; i
< 2; ++i
) {
4897 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4898 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildExtractElement (builder
, val
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), ""), i
, "");
4900 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4904 addr
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), "");
4905 for (i
= 0; i
< 2; ++i
) {
4906 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4907 LLVMValueRef indexes
[2], part_addr
;
4909 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4910 indexes
[1] = LLVMConstInt (LLVMInt32Type (), i
, FALSE
);
4911 part_addr
= LLVMBuildGEP (builder
, addr
, indexes
, 2, "");
4913 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildLoad (builder
, part_addr
, ""), i
, "");
4915 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4919 LLVMBuildRet (builder
, retval
);
4922 case LLVMArgVtypeAsScalar
: {
4923 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4924 LLVMValueRef retval
;
4926 g_assert (addresses
[ins
->sreg1
]);
4928 retval
= LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), ""), "");
4929 LLVMBuildRet (builder
, retval
);
4932 case LLVMArgVtypeByVal
: {
4933 LLVMValueRef retval
;
4935 g_assert (addresses
[ins
->sreg1
]);
4936 retval
= LLVMBuildLoad (builder
, addresses
[ins
->sreg1
], "");
4937 LLVMBuildRet (builder
, retval
);
4940 case LLVMArgVtypeByRef
: {
4941 LLVMBuildRetVoid (builder
);
4944 case LLVMArgGsharedvtFixed
: {
4945 LLVMTypeRef ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
4946 /* The return value is in lhs, need to store to the vret argument */
4947 /* sreg1 might not be set */
4949 g_assert (cfg
->vret_addr
);
4950 g_assert (values
[cfg
->vret_addr
->dreg
]);
4951 LLVMBuildStore (builder
, convert (ctx
, lhs
, ret_type
), convert (ctx
, values
[cfg
->vret_addr
->dreg
], LLVMPointerType (ret_type
, 0)));
4953 LLVMBuildRetVoid (builder
);
4956 case LLVMArgGsharedvtFixedVtype
: {
4958 LLVMBuildRetVoid (builder
);
4961 case LLVMArgGsharedvtVariable
: {
4963 LLVMBuildRetVoid (builder
);
4966 case LLVMArgVtypeRetAddr
: {
4967 LLVMBuildRetVoid (builder
);
4970 case LLVMArgAsIArgs
:
4971 case LLVMArgFpStruct
: {
4972 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4973 LLVMValueRef retval
;
4975 g_assert (addresses
[ins
->sreg1
]);
4976 retval
= LLVMBuildLoad (builder
, convert (ctx
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0)), "");
4977 LLVMBuildRet (builder
, retval
);
4981 case LLVMArgNormal
: {
4982 if (!lhs
|| ctx
->is_dead
[ins
->sreg1
]) {
4984 * The method did not set its return value, probably because it
4985 * ends with a throw.
4988 LLVMBuildRetVoid (builder
);
4990 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
4992 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
4994 has_terminator
= TRUE
;
4998 g_assert_not_reached ();
5007 case OP_ICOMPARE_IMM
:
5008 case OP_LCOMPARE_IMM
:
5009 case OP_COMPARE_IMM
: {
5011 LLVMValueRef cmp
, args
[16];
5012 gboolean likely
= (ins
->flags
& MONO_INST_LIKELY
) != 0;
5013 gboolean unlikely
= FALSE
;
5015 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
5016 if (ins
->next
->inst_false_bb
->out_of_line
)
5018 else if (ins
->next
->inst_true_bb
->out_of_line
)
5022 if (ins
->next
->opcode
== OP_NOP
)
5025 if (ins
->next
->opcode
== OP_BR
)
5026 /* The comparison result is not needed */
5029 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
5031 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
5032 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
5033 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
5035 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
5036 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5037 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
5039 if (ins
->opcode
== OP_LCOMPARE
) {
5040 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5041 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
5043 if (ins
->opcode
== OP_ICOMPARE
) {
5044 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
5045 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
5049 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
5050 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
5051 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
5052 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
5055 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
5056 if (ins
->opcode
== OP_FCOMPARE
) {
5057 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
5058 } else if (ins
->opcode
== OP_RCOMPARE
) {
5059 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
5060 } else if (ins
->opcode
== OP_COMPARE_IMM
) {
5061 LLVMIntPredicate llvm_pred
= cond_to_llvm_cond
[rel
];
5062 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& ins
->inst_imm
== 0) {
5063 // We are emitting a NULL check for a pointer
5064 gboolean nonnull
= mono_llvm_is_nonnull (lhs
);
5066 if (nonnull
&& llvm_pred
== LLVMIntEQ
)
5067 cmp
= LLVMConstInt (LLVMInt1Type (), FALSE
, FALSE
);
5068 else if (nonnull
&& llvm_pred
== LLVMIntNE
)
5069 cmp
= LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
5071 cmp
= LLVMBuildICmp (builder
, llvm_pred
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), "");
5074 cmp
= LLVMBuildICmp (builder
, llvm_pred
, convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
5076 } else if (ins
->opcode
== OP_LCOMPARE_IMM
) {
5077 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
5079 else if (ins
->opcode
== OP_COMPARE
) {
5080 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& LLVMTypeOf (lhs
) == LLVMTypeOf (rhs
))
5081 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
5083 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
5085 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
5087 if (likely
|| unlikely
) {
5089 args
[1] = LLVMConstInt (LLVMInt1Type (), likely
? 1 : 0, FALSE
);
5090 cmp
= LLVMBuildCall (ctx
->builder
, get_intrins (ctx
, INTRINS_EXPECT_I1
), args
, 2, "");
5093 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
5094 if (ins
->next
->inst_true_bb
== ins
->next
->inst_false_bb
) {
5096 * If the target bb contains PHI instructions, LLVM requires
5097 * two PHI entries for this bblock, while we only generate one.
5098 * So convert this to an unconditional bblock. (bxc #171).
5100 LLVMBuildBr (builder
, get_bb (ctx
, ins
->next
->inst_true_bb
));
5102 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
5104 has_terminator
= TRUE
;
5105 } else if (MONO_IS_SETCC (ins
->next
)) {
5106 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
5108 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
5110 /* Add stores for volatile variables */
5111 emit_volatile_store (ctx
, ins
->next
->dreg
);
5112 } else if (MONO_IS_COND_EXC (ins
->next
)) {
5113 emit_cond_system_exception (ctx
, bb
, (const char*)ins
->next
->inst_p1
, cmp
);
5116 builder
= ctx
->builder
;
5118 set_failure (ctx
, "next");
5136 rel
= mono_opcode_to_cond (ins
->opcode
);
5138 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
5139 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
5151 rel
= mono_opcode_to_cond (ins
->opcode
);
5153 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
5154 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
5162 gboolean empty
= TRUE
;
5164 /* Check that all input bblocks really branch to us */
5165 for (i
= 0; i
< bb
->in_count
; ++i
) {
5166 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
5167 ins
->inst_phi_args
[i
+ 1] = -1;
5173 /* LLVM doesn't like phi instructions with zero operands */
5174 ctx
->is_dead
[ins
->dreg
] = TRUE
;
5178 /* Created earlier, insert it now */
5179 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
5181 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
5182 int sreg1
= ins
->inst_phi_args
[i
+ 1];
5186 * Count the number of times the incoming bblock branches to us,
5187 * since llvm requires a separate entry for each.
5189 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
5190 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
5193 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
5194 if (switch_ins
->inst_many_bb
[j
] == bb
)
5201 /* Remember for later */
5202 for (j
= 0; j
< count
; ++j
) {
5203 PhiNode
*node
= (PhiNode
*)mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
5206 node
->in_bb
= bb
->in_bb
[i
];
5208 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
);
5218 values
[ins
->dreg
] = lhs
;
5222 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
5225 values
[ins
->dreg
] = lhs
;
5227 if (var
&& m_class_get_byval_arg (var
->klass
)->type
== MONO_TYPE_R4
) {
5229 * This is added by the spilling pass in case of the JIT,
5230 * but we have to do it ourselves.
5232 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
5236 case OP_MOVE_F_TO_I4
: {
5237 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), ""), LLVMInt32Type (), "");
5240 case OP_MOVE_I4_TO_F
: {
5241 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, LLVMBuildBitCast (builder
, lhs
, LLVMFloatType (), ""), LLVMDoubleType (), "");
5244 case OP_MOVE_F_TO_I8
: {
5245 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMInt64Type (), "");
5248 case OP_MOVE_I8_TO_F
: {
5249 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMDoubleType (), "");
5282 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5283 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5285 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, rhs
);
5288 builder
= ctx
->builder
;
5290 switch (ins
->opcode
) {
5293 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
5297 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
5301 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
5305 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
5309 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
5313 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
5317 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
5321 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
5325 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
5329 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
5333 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
5337 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
5341 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
5345 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
5349 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
5352 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
5355 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
5359 g_assert_not_reached ();
5366 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
5367 rhs
= convert (ctx
, rhs
, LLVMFloatType ());
5368 switch (ins
->opcode
) {
5370 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
5373 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
5376 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
5379 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
5382 g_assert_not_reached ();
5391 case OP_IREM_UN_IMM
:
5393 case OP_IDIV_UN_IMM
:
5399 case OP_ISHR_UN_IMM
:
5409 case OP_LSHR_UN_IMM
:
5415 case OP_SHR_UN_IMM
: {
5418 if (spec
[MONO_INST_SRC1
] == 'l') {
5419 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
5421 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
5424 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, imm
);
5427 builder
= ctx
->builder
;
5429 #if TARGET_SIZEOF_VOID_P == 4
5430 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
5431 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
5434 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
5435 lhs
= convert (ctx
, lhs
, IntPtrType ());
5436 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
5437 switch (ins
->opcode
) {
5441 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
5445 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
5450 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
5454 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
5456 case OP_IDIV_UN_IMM
:
5457 case OP_LDIV_UN_IMM
:
5458 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
5462 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
5464 case OP_IREM_UN_IMM
:
5465 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
5470 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
5474 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
5478 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
5482 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
5485 if (TARGET_SIZEOF_VOID_P
== 8) {
5486 /* The IL is not regular */
5487 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5488 imm
= convert (ctx
, imm
, LLVMInt64Type ());
5490 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
5495 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
5497 case OP_ISHR_UN_IMM
:
5498 /* This is used to implement conv.u4, so the lhs could be an i8 */
5499 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
5500 imm
= convert (ctx
, imm
, LLVMInt32Type ());
5501 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
5503 case OP_LSHR_UN_IMM
:
5505 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
5508 g_assert_not_reached ();
5513 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
5516 if (LLVMTypeOf (lhs
) != LLVMInt64Type ())
5517 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5518 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
5521 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
5522 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
5525 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
5526 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMFloatType (), 0.0), lhs
, dname
);
5529 guint32 v
= 0xffffffff;
5530 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
5534 if (LLVMTypeOf (lhs
) != LLVMInt64Type ())
5535 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
5536 guint64 v
= 0xffffffffffffffffLL
;
5537 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
5540 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5542 LLVMValueRef v1
, v2
;
5544 rhs
= LLVMBuildSExt (builder
, convert (ctx
, rhs
, LLVMInt32Type ()), LLVMInt64Type (), "");
5546 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ((unsigned long long)1 << ins
->backend
.shift_amount
), FALSE
), "");
5547 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
5548 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
5553 case OP_ICONV_TO_I1
:
5554 case OP_ICONV_TO_I2
:
5555 case OP_ICONV_TO_I4
:
5556 case OP_ICONV_TO_U1
:
5557 case OP_ICONV_TO_U2
:
5558 case OP_ICONV_TO_U4
:
5559 case OP_LCONV_TO_I1
:
5560 case OP_LCONV_TO_I2
:
5561 case OP_LCONV_TO_U1
:
5562 case OP_LCONV_TO_U2
:
5563 case OP_LCONV_TO_U4
: {
5566 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
);
5568 /* Have to do two casts since our vregs have type int */
5569 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
5571 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
5573 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
5576 case OP_ICONV_TO_I8
:
5577 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
5579 case OP_ICONV_TO_U8
:
5580 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
5582 case OP_FCONV_TO_I4
:
5583 case OP_RCONV_TO_I4
:
5584 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
5586 case OP_FCONV_TO_I1
:
5587 case OP_RCONV_TO_I1
:
5588 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
5590 case OP_FCONV_TO_U1
:
5591 case OP_RCONV_TO_U1
:
5592 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildTrunc (builder
, LLVMBuildFPToUI (builder
, lhs
, IntPtrType (), dname
), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5594 case OP_FCONV_TO_I2
:
5595 case OP_RCONV_TO_I2
:
5596 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
5598 case OP_FCONV_TO_U2
:
5599 case OP_RCONV_TO_U2
:
5600 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
5602 case OP_RCONV_TO_U4
:
5603 values
[ins
->dreg
] = LLVMBuildFPToUI (builder
, lhs
, LLVMInt32Type (), dname
);
5605 case OP_FCONV_TO_I8
:
5606 case OP_RCONV_TO_I8
:
5607 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
5610 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
5612 case OP_ICONV_TO_R8
:
5613 case OP_LCONV_TO_R8
:
5614 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
5616 case OP_ICONV_TO_R_UN
:
5617 case OP_LCONV_TO_R_UN
:
5618 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
5620 #if TARGET_SIZEOF_VOID_P == 4
5623 case OP_LCONV_TO_I4
:
5624 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5626 case OP_ICONV_TO_R4
:
5627 case OP_LCONV_TO_R4
:
5628 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
5630 values
[ins
->dreg
] = v
;
5632 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5634 case OP_FCONV_TO_R4
:
5635 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
5637 values
[ins
->dreg
] = v
;
5639 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5641 case OP_RCONV_TO_R8
:
5642 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, lhs
, LLVMDoubleType (), dname
);
5644 case OP_RCONV_TO_R4
:
5645 values
[ins
->dreg
] = lhs
;
5648 values
[ins
->dreg
] = LLVMBuildSExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5651 values
[ins
->dreg
] = LLVMBuildZExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5654 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5656 case OP_LOCALLOC_IMM
: {
5659 guint32 size
= ins
->inst_imm
;
5660 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
5662 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
5664 if (ins
->flags
& MONO_INST_INIT
) {
5665 LLVMValueRef args
[5];
5668 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5669 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
5670 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5671 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5672 LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_MEMSET
), args
, 5, "");
5675 values
[ins
->dreg
] = v
;
5679 LLVMValueRef v
, size
;
5681 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
), "");
5683 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
5685 if (ins
->flags
& MONO_INST_INIT
) {
5686 LLVMValueRef args
[5];
5689 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5691 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5692 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5693 LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_MEMSET
), args
, 5, "");
5695 values
[ins
->dreg
] = v
;
5699 case OP_LOADI1_MEMBASE
:
5700 case OP_LOADU1_MEMBASE
:
5701 case OP_LOADI2_MEMBASE
:
5702 case OP_LOADU2_MEMBASE
:
5703 case OP_LOADI4_MEMBASE
:
5704 case OP_LOADU4_MEMBASE
:
5705 case OP_LOADI8_MEMBASE
:
5706 case OP_LOADR4_MEMBASE
:
5707 case OP_LOADR8_MEMBASE
:
5708 case OP_LOAD_MEMBASE
:
5716 LLVMValueRef base
, index
, addr
;
5718 gboolean sext
= FALSE
, zext
= FALSE
;
5719 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
5721 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5726 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
)) {
5727 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
5733 if (ins
->inst_offset
== 0) {
5735 } else if (ins
->inst_offset
% size
!= 0) {
5736 /* Unaligned load */
5737 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5738 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5740 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5741 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5745 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
5747 values
[ins
->dreg
] = emit_load (ctx
, bb
, &builder
, size
, addr
, base
, dname
, is_volatile
, LLVM_BARRIER_NONE
);
5749 if (!is_volatile
&& (ins
->flags
& MONO_INST_INVARIANT_LOAD
)) {
5751 * These will signal LLVM that these loads do not alias any stores, and
5752 * they can't fail, allowing them to be hoisted out of loops.
5754 set_invariant_load_flag (values
[ins
->dreg
]);
5755 #if LLVM_API_VERSION < 100
5756 set_metadata_flag (values
[ins
->dreg
], "mono.nofail.load");
5761 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5763 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5764 else if (!cfg
->r4fp
&& ins
->opcode
== OP_LOADR4_MEMBASE
)
5765 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
5769 case OP_STOREI1_MEMBASE_REG
:
5770 case OP_STOREI2_MEMBASE_REG
:
5771 case OP_STOREI4_MEMBASE_REG
:
5772 case OP_STOREI8_MEMBASE_REG
:
5773 case OP_STORER4_MEMBASE_REG
:
5774 case OP_STORER8_MEMBASE_REG
:
5775 case OP_STORE_MEMBASE_REG
: {
5777 LLVMValueRef index
, addr
, base
;
5779 gboolean sext
= FALSE
, zext
= FALSE
;
5780 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
5782 if (!values
[ins
->inst_destbasereg
]) {
5783 set_failure (ctx
, "inst_destbasereg");
5787 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5789 base
= values
[ins
->inst_destbasereg
];
5790 if (ins
->inst_offset
% size
!= 0) {
5791 /* Unaligned store */
5792 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5793 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5795 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5796 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5798 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5802 case OP_STOREI1_MEMBASE_IMM
:
5803 case OP_STOREI2_MEMBASE_IMM
:
5804 case OP_STOREI4_MEMBASE_IMM
:
5805 case OP_STOREI8_MEMBASE_IMM
:
5806 case OP_STORE_MEMBASE_IMM
: {
5808 LLVMValueRef index
, addr
, base
;
5810 gboolean sext
= FALSE
, zext
= FALSE
;
5811 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
5813 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5815 base
= values
[ins
->inst_destbasereg
];
5816 if (ins
->inst_offset
% size
!= 0) {
5817 /* Unaligned store */
5818 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5819 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5821 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5822 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5824 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5829 emit_load (ctx
, bb
, &builder
, TARGET_SIZEOF_VOID_P
, convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), lhs
, "", TRUE
, LLVM_BARRIER_NONE
);
5831 case OP_OUTARG_VTRETADDR
:
5839 case OP_VOIDCALL_MEMBASE
:
5840 case OP_CALL_MEMBASE
:
5841 case OP_LCALL_MEMBASE
:
5842 case OP_FCALL_MEMBASE
:
5843 case OP_RCALL_MEMBASE
:
5844 case OP_VCALL_MEMBASE
:
5845 case OP_VOIDCALL_REG
:
5850 case OP_VCALL_REG
: {
5851 process_call (ctx
, bb
, &builder
, ins
);
5856 LLVMValueRef indexes
[2];
5857 MonoJumpInfo
*tmp_ji
, *ji
;
5858 LLVMValueRef got_entry_addr
;
5862 * FIXME: Can't allocate from the cfg mempool since that is freed if
5863 * the LLVM compile fails.
5865 tmp_ji
= g_new0 (MonoJumpInfo
, 1);
5866 tmp_ji
->type
= (MonoJumpInfoType
)ins
->inst_c1
;
5867 tmp_ji
->data
.target
= ins
->inst_p0
;
5869 ji
= mono_aot_patch_info_dup (tmp_ji
);
5872 if (ji
->type
== MONO_PATCH_INFO_ICALL_ADDR
) {
5873 char *symbol
= mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL
, ji
->data
.target
);
5876 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5877 * resolvable at runtime using dlsym ().
5880 values
[ins
->dreg
] = LLVMConstInt (IntPtrType (), 0, FALSE
);
5885 ji
->next
= cfg
->patch_info
;
5886 cfg
->patch_info
= ji
;
5888 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5889 got_offset
= compute_aot_got_offset (ctx
->module
, cfg
->patch_info
, NULL
);
5891 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
5892 if (!mono_aot_is_shared_got_offset (got_offset
)) {
5893 //mono_print_ji (ji);
5895 ctx
->cfg
->got_access_count
++;
5898 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5899 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
5900 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
5902 name
= get_aotconst_name (ji
->type
, ji
->data
.target
, got_offset
);
5903 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, name
);
5905 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5906 if (!cfg
->llvm_only
|| mono_aot_is_shared_got_offset (got_offset
)) {
5907 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5908 set_invariant_load_flag (values
[ins
->dreg
]);
5911 if (ji
->type
== MONO_PATCH_INFO_LDSTR
)
5912 set_nonnull_load_flag (values
[ins
->dreg
]);
5915 case OP_NOT_REACHED
:
5916 LLVMBuildUnreachable (builder
);
5917 has_terminator
= TRUE
;
5918 g_assert (bb
->block_num
< cfg
->max_block_num
);
5919 ctx
->unreachable
[bb
->block_num
] = TRUE
;
5920 /* Might have instructions after this */
5922 MonoInst
*next
= ins
->next
;
5924 * FIXME: If later code uses the regs defined by these instructions,
5925 * compilation will fail.
5927 MONO_DELETE_INS (bb
, next
);
5931 MonoInst
*var
= ins
->inst_i0
;
5933 if (var
->opcode
== OP_VTARG_ADDR
) {
5934 /* The variable contains the vtype address */
5935 values
[ins
->dreg
] = values
[var
->dreg
];
5936 } else if (var
->opcode
== OP_GSHAREDVT_LOCAL
) {
5937 values
[ins
->dreg
] = emit_gsharedvt_ldaddr (ctx
, var
->dreg
);
5939 values
[ins
->dreg
] = addresses
[var
->dreg
];
5944 LLVMValueRef args
[1];
5946 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5947 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_SIN
), args
, 1, dname
);
5951 LLVMValueRef args
[1];
5953 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5954 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_SINF
), args
, 1, dname
);
5958 LLVMValueRef args
[1];
5960 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5961 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_COS
), args
, 1, dname
);
5965 LLVMValueRef args
[1];
5967 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5968 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_COSF
), args
, 1, dname
);
5972 LLVMValueRef args
[1];
5974 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5975 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_SQRT
), args
, 1, dname
);
5979 LLVMValueRef args
[1];
5981 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5982 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_SQRTF
), args
, 1, dname
);
5986 LLVMValueRef args
[1];
5988 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5989 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_FABS
), args
, 1, dname
);
5993 LLVMValueRef args
[1];
5996 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
5997 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_ABSF
), args
, 1, dname
);
5999 /* llvm.fabs not supported on all platforms */
6000 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
6001 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_FABS
), args
, 1, dname
);
6002 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
6007 LLVMValueRef args
[2];
6009 args
[0] = convert (ctx
, lhs
, LLVMFloatType ());
6010 args
[1] = convert (ctx
, rhs
, LLVMFloatType ());
6011 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_POWF
), args
, 2, dname
);
6026 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
6027 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
6029 switch (ins
->opcode
) {
6032 v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
6036 v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
6040 v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
6044 v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
6047 v
= LLVMBuildFCmp (builder
, LLVMRealUGE
, lhs
, rhs
, "");
6050 g_assert_not_reached ();
6053 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
6058 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
6059 * hack is necessary (for now).
6062 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
6064 #define ARM64_ATOMIC_FENCE_FIX
6067 case OP_ATOMIC_EXCHANGE_I4
:
6068 case OP_ATOMIC_EXCHANGE_I8
: {
6069 LLVMValueRef args
[2];
6072 if (ins
->opcode
== OP_ATOMIC_EXCHANGE_I4
)
6073 t
= LLVMInt32Type ();
6075 t
= LLVMInt64Type ();
6077 g_assert (ins
->inst_offset
== 0);
6079 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
6080 args
[1] = convert (ctx
, rhs
, t
);
6082 ARM64_ATOMIC_FENCE_FIX
;
6083 values
[ins
->dreg
] = mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_XCHG
, args
[0], args
[1]);
6084 ARM64_ATOMIC_FENCE_FIX
;
6087 case OP_ATOMIC_ADD_I4
:
6088 case OP_ATOMIC_ADD_I8
: {
6089 LLVMValueRef args
[2];
6092 if (ins
->opcode
== OP_ATOMIC_ADD_I4
)
6093 t
= LLVMInt32Type ();
6095 t
= LLVMInt64Type ();
6097 g_assert (ins
->inst_offset
== 0);
6099 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
6100 args
[1] = convert (ctx
, rhs
, t
);
6101 ARM64_ATOMIC_FENCE_FIX
;
6102 values
[ins
->dreg
] = LLVMBuildAdd (builder
, mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_ADD
, args
[0], args
[1]), args
[1], dname
);
6103 ARM64_ATOMIC_FENCE_FIX
;
6106 case OP_ATOMIC_CAS_I4
:
6107 case OP_ATOMIC_CAS_I8
: {
6108 LLVMValueRef args
[3], val
;
6111 if (ins
->opcode
== OP_ATOMIC_CAS_I4
)
6112 t
= LLVMInt32Type ();
6114 t
= LLVMInt64Type ();
6116 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
6118 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
6120 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
6121 ARM64_ATOMIC_FENCE_FIX
;
6122 val
= mono_llvm_build_cmpxchg (builder
, args
[0], args
[1], args
[2]);
6123 ARM64_ATOMIC_FENCE_FIX
;
6124 /* cmpxchg returns a pair */
6125 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, "");
6128 case OP_MEMORY_BARRIER
: {
6129 mono_llvm_build_fence (builder
, (BarrierKind
) ins
->backend
.memory_barrier_kind
);
6132 case OP_ATOMIC_LOAD_I1
:
6133 case OP_ATOMIC_LOAD_I2
:
6134 case OP_ATOMIC_LOAD_I4
:
6135 case OP_ATOMIC_LOAD_I8
:
6136 case OP_ATOMIC_LOAD_U1
:
6137 case OP_ATOMIC_LOAD_U2
:
6138 case OP_ATOMIC_LOAD_U4
:
6139 case OP_ATOMIC_LOAD_U8
:
6140 case OP_ATOMIC_LOAD_R4
:
6141 case OP_ATOMIC_LOAD_R8
: {
6142 #if LLVM_API_VERSION > 100
6144 gboolean sext
, zext
;
6146 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
6147 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
6148 LLVMValueRef index
, addr
;
6150 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
6155 if (ins
->inst_offset
!= 0) {
6156 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
6157 addr
= LLVMBuildGEP (builder
, convert (ctx
, lhs
, LLVMPointerType (t
, 0)), &index
, 1, "");
6162 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
6164 ARM64_ATOMIC_FENCE_FIX
;
6165 values
[ins
->dreg
] = emit_load (ctx
, bb
, &builder
, size
, addr
, lhs
, dname
, is_volatile
, barrier
);
6166 ARM64_ATOMIC_FENCE_FIX
;
6169 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
6171 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
6174 set_failure (ctx
, "atomic mono.load intrinsic");
6178 case OP_ATOMIC_STORE_I1
:
6179 case OP_ATOMIC_STORE_I2
:
6180 case OP_ATOMIC_STORE_I4
:
6181 case OP_ATOMIC_STORE_I8
:
6182 case OP_ATOMIC_STORE_U1
:
6183 case OP_ATOMIC_STORE_U2
:
6184 case OP_ATOMIC_STORE_U4
:
6185 case OP_ATOMIC_STORE_U8
:
6186 case OP_ATOMIC_STORE_R4
:
6187 case OP_ATOMIC_STORE_R8
: {
6189 gboolean sext
, zext
;
6191 gboolean is_volatile
= (ins
->flags
& (MONO_INST_FAULT
| MONO_INST_VOLATILE
)) != 0;
6192 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
6193 LLVMValueRef index
, addr
, value
, base
;
6195 #if LLVM_API_VERSION < 100
6196 if (!cfg
->llvm_only
) {
6197 set_failure (ctx
, "atomic mono.store intrinsic");
6202 if (!values
[ins
->inst_destbasereg
]) {
6203 set_failure (ctx
, "inst_destbasereg");
6207 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
6209 base
= values
[ins
->inst_destbasereg
];
6210 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
6211 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
6212 value
= convert (ctx
, values
[ins
->sreg1
], t
);
6214 ARM64_ATOMIC_FENCE_FIX
;
6215 emit_store_general (ctx
, bb
, &builder
, size
, value
, addr
, base
, is_volatile
, barrier
);
6216 ARM64_ATOMIC_FENCE_FIX
;
6219 case OP_RELAXED_NOP
: {
6220 #if defined(TARGET_AMD64) || defined(TARGET_X86)
6221 emit_call (ctx
, bb
, &builder
, get_intrins_by_name (ctx
, "llvm.x86.sse2.pause"), NULL
, 0);
6228 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
6230 // 257 == FS segment register
6231 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
6233 // 256 == GS segment register
6234 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
6237 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
6238 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
6239 /* See mono_amd64_emit_tls_get () */
6240 int offset
= mono_amd64_get_tls_gs_offset () + (ins
->inst_offset
* 8);
6242 // 256 == GS segment register
6243 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
6244 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), offset
, TRUE
), ptrtype
, ""), "");
6246 set_failure (ctx
, "opcode tls-get");
6252 case OP_GC_SAFE_POINT
: {
6253 LLVMValueRef val
, cmp
, callee
;
6254 LLVMBasicBlockRef poll_bb
, cont_bb
;
6255 LLVMValueRef args
[2];
6256 static LLVMTypeRef sig
;
6257 MonoJitICallId
const icall_id
= MONO_JIT_ICALL_mono_threads_state_poll
;
6258 const char *icall_name
= "mono_threads_state_poll";
6261 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
6265 * mono_threads_state_poll ();
6266 * FIXME: Use a preserveall wrapper
6268 val
= mono_llvm_build_load (builder
, convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
6269 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, val
, LLVMConstNull (LLVMTypeOf (val
)), "");
6270 poll_bb
= gen_bb (ctx
, "POLL_BB");
6271 cont_bb
= gen_bb (ctx
, "CONT_BB");
6274 args
[1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
6275 cmp
= LLVMBuildCall (ctx
->builder
, get_intrins (ctx
, INTRINS_EXPECT_I1
), args
, 2, "");
6277 LLVMBuildCondBr (builder
, cmp
, cont_bb
, poll_bb
);
6279 ctx
->builder
= builder
= create_builder (ctx
);
6280 LLVMPositionBuilderAtEnd (builder
, poll_bb
);
6282 if (ctx
->cfg
->compile_aot
) {
6283 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
6285 callee
= get_jit_callee (ctx
, icall_name
, sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (icall_id
));
6287 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
6288 LLVMBuildBr (builder
, cont_bb
);
6290 ctx
->builder
= builder
= create_builder (ctx
);
6291 LLVMPositionBuilderAtEnd (builder
, cont_bb
);
6292 ctx
->bblocks
[bb
->block_num
].end_bblock
= cont_bb
;
6300 case OP_IADD_OVF_UN
:
6302 case OP_ISUB_OVF_UN
:
6304 case OP_IMUL_OVF_UN
:
6306 case OP_LADD_OVF_UN
:
6308 case OP_LSUB_OVF_UN
:
6310 case OP_LMUL_OVF_UN
:
6312 LLVMValueRef args
[2], val
, ovf
, func
;
6314 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
6315 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
6316 func
= get_intrins_by_name (ctx
, ovf_op_to_intrins (ins
->opcode
));
6318 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
6319 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
6320 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
6321 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
6324 builder
= ctx
->builder
;
6330 * We currently model them using arrays. Promotion to local vregs is
6331 * disabled for them in mono_handle_global_vregs () in the LLVM case,
6332 * so we always have an entry in cfg->varinfo for them.
6333 * FIXME: Is this needed ?
6336 MonoClass
*klass
= ins
->klass
;
6337 LLVMValueRef args
[5];
6341 set_failure (ctx
, "!klass");
6345 if (!addresses
[ins
->dreg
])
6346 addresses
[ins
->dreg
] = build_alloca (ctx
, m_class_get_byval_arg (klass
));
6347 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
6348 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
6349 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
6351 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6352 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
6353 LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_MEMSET
), args
, 5, "");
6356 case OP_DUMMY_VZERO
:
6359 case OP_STOREV_MEMBASE
:
6360 case OP_LOADV_MEMBASE
:
6362 MonoClass
*klass
= ins
->klass
;
6363 LLVMValueRef src
= NULL
, dst
, args
[5];
6364 gboolean done
= FALSE
;
6368 set_failure (ctx
, "!klass");
6372 if (mini_is_gsharedvt_klass (klass
)) {
6374 set_failure (ctx
, "gsharedvt");
6378 switch (ins
->opcode
) {
6379 case OP_STOREV_MEMBASE
:
6380 if (cfg
->gen_write_barriers
&& m_class_has_references (klass
) && ins
->inst_destbasereg
!= cfg
->frame_reg
&&
6381 LLVMGetInstructionOpcode (values
[ins
->inst_destbasereg
]) != LLVMAlloca
) {
6382 /* Decomposed earlier */
6383 g_assert_not_reached ();
6386 if (!addresses
[ins
->sreg1
]) {
6388 g_assert (values
[ins
->sreg1
]);
6389 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));
6390 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
6393 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
6394 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
6397 case OP_LOADV_MEMBASE
:
6398 if (!addresses
[ins
->dreg
])
6399 addresses
[ins
->dreg
] = build_alloca (ctx
, m_class_get_byval_arg (klass
));
6400 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
6401 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
6404 if (!addresses
[ins
->sreg1
])
6405 addresses
[ins
->sreg1
] = build_alloca (ctx
, m_class_get_byval_arg (klass
));
6406 if (!addresses
[ins
->dreg
])
6407 addresses
[ins
->dreg
] = build_alloca (ctx
, m_class_get_byval_arg (klass
));
6408 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
6409 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
6412 g_assert_not_reached ();
6422 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
6423 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6425 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6426 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
6427 LLVMBuildCall (builder
, get_intrins (ctx
, INTRINS_MEMCPY
), args
, 5, "");
6430 case OP_LLVM_OUTARG_VT
: {
6431 LLVMArgInfo
*ainfo
= (LLVMArgInfo
*)ins
->inst_p0
;
6432 MonoType
*t
= mini_get_underlying_type (ins
->inst_vtype
);
6434 if (ainfo
->storage
== LLVMArgGsharedvtVariable
) {
6435 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
6437 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
6438 addresses
[ins
->dreg
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), LLVMPointerType (IntPtrType (), 0));
6440 g_assert (addresses
[ins
->sreg1
]);
6441 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
6443 } else if (ainfo
->storage
== LLVMArgGsharedvtFixed
) {
6444 if (!addresses
[ins
->sreg1
]) {
6445 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
6446 g_assert (values
[ins
->sreg1
]);
6448 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (LLVMTypeOf (addresses
[ins
->sreg1
]))), addresses
[ins
->sreg1
]);
6449 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
6451 if (!addresses
[ins
->sreg1
]) {
6452 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
6453 g_assert (values
[ins
->sreg1
]);
6454 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, t
)), addresses
[ins
->sreg1
]);
6455 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
6456 } else if (values
[ins
->sreg1
] == addresses
[ins
->sreg1
]) {
6457 /* LLVMArgVtypeByRef, have to make a copy */
6458 addresses
[ins
->dreg
] = build_alloca (ctx
, t
);
6459 LLVMValueRef v
= LLVMBuildLoad (builder
, addresses
[ins
->sreg1
], "");
6460 LLVMBuildStore (builder
, convert (ctx
, v
, type_to_llvm_type (ctx
, t
)), addresses
[ins
->dreg
]);
6462 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
6467 case OP_OBJC_GET_SELECTOR
: {
6468 const char *name
= (const char*)ins
->inst_p0
;
6471 if (!ctx
->module
->objc_selector_to_var
) {
6472 ctx
->module
->objc_selector_to_var
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
6474 LLVMValueRef info_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
6475 int32_t objc_imageinfo
[] = { 0, 16 };
6476 LLVMSetInitializer (info_var
, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo
, 8));
6477 LLVMSetLinkage (info_var
, LLVMPrivateLinkage
);
6478 LLVMSetExternallyInitialized (info_var
, TRUE
);
6479 LLVMSetSection (info_var
, "__DATA, __objc_imageinfo,regular,no_dead_strip");
6480 LLVMSetAlignment (info_var
, sizeof (target_mgreg_t
));
6481 mark_as_used (ctx
->module
, info_var
);
6484 var
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->objc_selector_to_var
, name
);
6486 LLVMValueRef indexes
[16];
6488 LLVMValueRef name_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMArrayType (LLVMInt8Type (), strlen (name
) + 1), "@OBJC_METH_VAR_NAME_");
6489 LLVMSetInitializer (name_var
, mono_llvm_create_constant_data_array ((const uint8_t*)name
, strlen (name
) + 1));
6490 LLVMSetLinkage (name_var
, LLVMPrivateLinkage
);
6491 LLVMSetSection (name_var
, "__TEXT,__objc_methname,cstring_literals");
6492 mark_as_used (ctx
->module
, name_var
);
6494 LLVMValueRef ref_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
6496 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
6497 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
6498 LLVMSetInitializer (ref_var
, LLVMConstGEP (name_var
, indexes
, 2));
6499 LLVMSetLinkage (ref_var
, LLVMPrivateLinkage
);
6500 LLVMSetExternallyInitialized (ref_var
, TRUE
);
6501 LLVMSetSection (ref_var
, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6502 LLVMSetAlignment (ref_var
, sizeof (target_mgreg_t
));
6503 mark_as_used (ctx
->module
, ref_var
);
6505 g_hash_table_insert (ctx
->module
->objc_selector_to_var
, g_strdup (name
), ref_var
);
6509 values
[ins
->dreg
] = LLVMBuildLoad (builder
, var
, "");
6516 #if defined(TARGET_X86) || defined(TARGET_AMD64)
6518 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, m_class_get_byval_arg (ins
->klass
)));
6521 case OP_LOADX_MEMBASE
: {
6522 LLVMTypeRef t
= type_to_llvm_type (ctx
, m_class_get_byval_arg (ins
->klass
));
6525 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
6526 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
6529 case OP_STOREX_MEMBASE
: {
6530 LLVMTypeRef t
= LLVMTypeOf (values
[ins
->sreg1
]);
6533 dest
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
6534 mono_llvm_build_aligned_store (builder
, values
[ins
->sreg1
], dest
, FALSE
, 1);
6541 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
6545 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
6551 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
6555 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
6559 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
6563 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
6566 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
6569 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
6572 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
6576 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, "");
6587 LLVMValueRef v
= NULL
;
6589 switch (ins
->opcode
) {
6594 t
= LLVMVectorType (LLVMInt32Type (), 4);
6595 rt
= LLVMVectorType (LLVMFloatType (), 4);
6601 t
= LLVMVectorType (LLVMInt64Type (), 2);
6602 rt
= LLVMVectorType (LLVMDoubleType (), 2);
6605 t
= LLVMInt32Type ();
6606 rt
= LLVMInt32Type ();
6607 g_assert_not_reached ();
6610 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
6611 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
6612 switch (ins
->opcode
) {
6615 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
6619 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
6623 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
6627 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
6630 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
6636 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntULT
, lhs
, rhs
, "");
6637 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6643 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntUGT
, lhs
, rhs
, "");
6644 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6648 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntSLT
, lhs
, rhs
, "");
6649 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6666 case OP_PADDB_SAT_UN
:
6667 case OP_PADDW_SAT_UN
:
6668 case OP_PSUBB_SAT_UN
:
6669 case OP_PSUBW_SAT_UN
:
6675 case OP_PMULW_HIGH_UN
: {
6676 LLVMValueRef args
[2];
6681 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6686 LLVMValueRef ones_vec
;
6687 LLVMValueRef ones
[32];
6688 int vector_size
= LLVMGetVectorSize (LLVMTypeOf (lhs
));
6689 LLVMTypeRef ext_elem_type
= vector_size
== 16 ? LLVMInt16Type () : LLVMInt32Type ();
6691 for (int i
= 0; i
< 32; ++i
)
6692 ones
[i
] = LLVMConstInt (ext_elem_type
, 1, FALSE
);
6693 ones_vec
= LLVMConstVector (ones
, vector_size
);
6695 #if LLVM_API_VERSION >= 500
6697 LLVMTypeRef ext_type
= LLVMVectorType (ext_elem_type
, vector_size
);
6699 /* Have to increase the vector element size to prevent overflows */
6700 /* res = trunc ((zext (lhs) + zext (rhs) + 1) >> 1) */
6701 val
= LLVMBuildAdd (builder
, LLVMBuildZExt (builder
, lhs
, ext_type
, ""), LLVMBuildZExt (builder
, rhs
, ext_type
, ""), "");
6702 val
= LLVMBuildAdd (builder
, val
, ones_vec
, "");
6703 val
= LLVMBuildLShr (builder
, val
, ones_vec
, "");
6704 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, val
, LLVMTypeOf (lhs
), "");
6706 LLVMValueRef args
[2];
6711 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6721 LLVMTypeRef retType
;
6724 if (ins
->opcode
== OP_PCMPGTB
)
6729 if (LLVMTypeOf (lhs
) == LLVMTypeOf (rhs
)) {
6730 pcmp
= LLVMBuildICmp (builder
, cmpOp
, lhs
, rhs
, "");
6731 retType
= LLVMTypeOf (lhs
);
6733 LLVMTypeRef flatType
= LLVMVectorType (LLVMInt8Type (), 16);
6734 LLVMValueRef flatRHS
= convert (ctx
, rhs
, flatType
);
6735 LLVMValueRef flatLHS
= convert (ctx
, lhs
, flatType
);
6737 pcmp
= LLVMBuildICmp (builder
, cmpOp
, flatLHS
, flatRHS
, "");
6741 values
[ins
->dreg
] = LLVMBuildSExt (builder
, pcmp
, retType
, "");
6749 case OP_EXTRACTX_U2
:
6751 case OP_EXTRACT_U1
: {
6753 gboolean zext
= FALSE
;
6755 t
= simd_op_to_llvm_type (ins
->opcode
);
6757 switch (ins
->opcode
) {
6765 case OP_EXTRACTX_U2
:
6770 t
= LLVMInt32Type ();
6771 g_assert_not_reached ();
6774 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
6775 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
6777 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
6786 case OP_EXPAND_R8
: {
6787 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6788 LLVMValueRef mask
[16], v
;
6791 for (i
= 0; i
< 16; ++i
)
6792 mask
[i
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6794 v
= convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (t
));
6796 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (t
), v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6797 values
[ins
->dreg
] = LLVMBuildShuffleVector (builder
, values
[ins
->dreg
], LLVMGetUndef (t
), LLVMConstVector (mask
, LLVMGetVectorSize (t
)), "");
6802 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6805 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6808 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6811 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6814 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6817 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6820 #if LLVM_API_VERSION > 100
6822 LLVMValueRef indexes
[16];
6824 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6825 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
6826 LLVMValueRef mask
= LLVMConstVector (indexes
, 2);
6827 LLVMValueRef shuffle
= LLVMBuildShuffleVector (builder
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), mask
, "");
6828 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, shuffle
, LLVMVectorType (LLVMDoubleType (), 2), dname
);
6832 LLVMValueRef indexes
[16];
6834 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6835 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
6836 LLVMValueRef mask
= LLVMConstVector (indexes
, 2);
6837 LLVMValueRef shuffle
= LLVMBuildShuffleVector (builder
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), mask
, "");
6838 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, shuffle
, LLVMVectorType (LLVMDoubleType (), 2), dname
);
6842 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMVectorType (LLVMInt32Type (), 4), dname
);
6846 #if LLVM_API_VERSION <= 100
6856 case OP_EXTRACT_MASK
:
6863 v
= convert (ctx
, values
[ins
->sreg1
], simd_op_to_llvm_type (ins
->opcode
));
6865 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), &v
, 1, dname
);
6870 LLVMRealPredicate op
;
6872 switch (ins
->inst_c0
) {
6882 case SIMD_COMP_UNORD
:
6898 g_assert_not_reached ();
6901 LLVMValueRef cmp
= LLVMBuildFCmp (builder
, op
, lhs
, rhs
, "");
6902 if (ins
->opcode
== OP_COMPPD
)
6903 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs
), "");
6905 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs
), "");
6909 /* This is only used for implementing shifts by non-immediate */
6910 values
[ins
->dreg
] = lhs
;
6921 LLVMValueRef args
[3];
6924 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
6926 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6937 case OP_PSHLQ_REG
: {
6938 LLVMValueRef args
[3];
6941 args
[1] = values
[ins
->sreg2
];
6943 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6950 case OP_PSHUFLEW_LOW
:
6951 case OP_PSHUFLEW_HIGH
: {
6953 LLVMValueRef v1
= NULL
, v2
= NULL
, mask_values
[16];
6954 int i
, mask_size
= 0;
6955 int imask
= ins
->inst_c0
;
6957 /* Convert the x86 shuffle mask to LLVM's */
6958 switch (ins
->opcode
) {
6961 mask
[0] = ((imask
>> 0) & 3);
6962 mask
[1] = ((imask
>> 2) & 3);
6963 mask
[2] = ((imask
>> 4) & 3) + 4;
6964 mask
[3] = ((imask
>> 6) & 3) + 4;
6965 v1
= values
[ins
->sreg1
];
6966 v2
= values
[ins
->sreg2
];
6970 mask
[0] = ((imask
>> 0) & 1);
6971 mask
[1] = ((imask
>> 1) & 1) + 2;
6972 v1
= values
[ins
->sreg1
];
6973 v2
= values
[ins
->sreg2
];
6975 case OP_PSHUFLEW_LOW
:
6977 mask
[0] = ((imask
>> 0) & 3);
6978 mask
[1] = ((imask
>> 2) & 3);
6979 mask
[2] = ((imask
>> 4) & 3);
6980 mask
[3] = ((imask
>> 6) & 3);
6985 v1
= values
[ins
->sreg1
];
6986 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6988 case OP_PSHUFLEW_HIGH
:
6994 mask
[4] = 4 + ((imask
>> 0) & 3);
6995 mask
[5] = 4 + ((imask
>> 2) & 3);
6996 mask
[6] = 4 + ((imask
>> 4) & 3);
6997 mask
[7] = 4 + ((imask
>> 6) & 3);
6998 v1
= values
[ins
->sreg1
];
6999 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
7003 mask
[0] = ((imask
>> 0) & 3);
7004 mask
[1] = ((imask
>> 2) & 3);
7005 mask
[2] = ((imask
>> 4) & 3);
7006 mask
[3] = ((imask
>> 6) & 3);
7007 v1
= values
[ins
->sreg1
];
7008 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
7011 g_assert_not_reached ();
7013 for (i
= 0; i
< mask_size
; ++i
)
7014 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
7016 values
[ins
->dreg
] =
7017 LLVMBuildShuffleVector (builder
, v1
, v2
,
7018 LLVMConstVector (mask_values
, mask_size
), dname
);
7022 case OP_UNPACK_LOWB
:
7023 case OP_UNPACK_LOWW
:
7024 case OP_UNPACK_LOWD
:
7025 case OP_UNPACK_LOWQ
:
7026 case OP_UNPACK_LOWPS
:
7027 case OP_UNPACK_LOWPD
:
7028 case OP_UNPACK_HIGHB
:
7029 case OP_UNPACK_HIGHW
:
7030 case OP_UNPACK_HIGHD
:
7031 case OP_UNPACK_HIGHQ
:
7032 case OP_UNPACK_HIGHPS
:
7033 case OP_UNPACK_HIGHPD
: {
7035 LLVMValueRef mask_values
[16];
7036 int i
, mask_size
= 0;
7037 gboolean low
= FALSE
;
7039 switch (ins
->opcode
) {
7040 case OP_UNPACK_LOWB
:
7044 case OP_UNPACK_LOWW
:
7048 case OP_UNPACK_LOWD
:
7049 case OP_UNPACK_LOWPS
:
7053 case OP_UNPACK_LOWQ
:
7054 case OP_UNPACK_LOWPD
:
7058 case OP_UNPACK_HIGHB
:
7061 case OP_UNPACK_HIGHW
:
7064 case OP_UNPACK_HIGHD
:
7065 case OP_UNPACK_HIGHPS
:
7068 case OP_UNPACK_HIGHQ
:
7069 case OP_UNPACK_HIGHPD
:
7073 g_assert_not_reached ();
7077 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
7079 mask
[(i
* 2) + 1] = mask_size
+ i
;
7082 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
7083 mask
[(i
* 2)] = (mask_size
/ 2) + i
;
7084 mask
[(i
* 2) + 1] = mask_size
+ (mask_size
/ 2) + i
;
7088 for (i
= 0; i
< mask_size
; ++i
)
7089 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
7091 values
[ins
->dreg
] =
7092 LLVMBuildShuffleVector (builder
, values
[ins
->sreg1
], values
[ins
->sreg2
],
7093 LLVMConstVector (mask_values
, mask_size
), dname
);
7098 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
7099 LLVMValueRef v
, val
;
7101 v
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7102 val
= LLVMConstNull (t
);
7103 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7104 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), dname
);
7106 values
[ins
->dreg
] = val
;
7110 case OP_DUPPS_HIGH
: {
7111 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
7112 LLVMValueRef v1
, v2
, val
;
7115 if (ins
->opcode
== OP_DUPPS_LOW
) {
7116 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7117 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
7119 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
7120 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
7122 val
= LLVMConstNull (t
);
7123 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7124 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
7125 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
7126 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
7128 values
[ins
->dreg
] = val
;
7133 LLVMValueRef args
[3];
7137 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
7138 #if LLVM_API_VERSION >= 500
7139 args
[2] = LLVMConstInt (LLVMInt8Type (), 0xf1, FALSE
);
7141 args
[2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE
);
7144 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 3, dname
);
7148 case OP_FCONV_TO_R8_X
: {
7149 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (type_to_simd_type (MONO_TYPE_R8
)), lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
7153 case OP_SSE41_ROUNDPD
: {
7154 LLVMValueRef args
[3];
7157 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
7159 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrins_by_name (ctx
, "llvm.x86.sse41.round.pd"), args
, 2, dname
);
7169 * EXCEPTION HANDLING
7171 case OP_IMPLICIT_EXCEPTION
:
7172 /* This marks a place where an implicit exception can happen */
7173 if (bb
->region
!= -1)
7174 set_failure (ctx
, "implicit-exception");
7178 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
7179 if (ctx
->llvm_only
) {
7180 emit_llvmonly_throw (ctx
, bb
, rethrow
, lhs
);
7181 has_terminator
= TRUE
;
7182 ctx
->unreachable
[bb
->block_num
] = TRUE
;
7184 emit_throw (ctx
, bb
, rethrow
, lhs
);
7185 builder
= ctx
->builder
;
7189 case OP_CALL_HANDLER
: {
7191 * We don't 'call' handlers, but instead simply branch to them.
7192 * The code generated by ENDFINALLY will branch back to us.
7194 LLVMBasicBlockRef noex_bb
;
7196 BBInfo
*info
= &bblocks
[ins
->inst_target_bb
->block_num
];
7198 bb_list
= info
->call_handler_return_bbs
;
7201 * Set the indicator variable for the finally clause.
7203 lhs
= info
->finally_ind
;
7205 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
7207 /* Branch to the finally clause */
7208 LLVMBuildBr (builder
, info
->call_handler_target_bb
);
7210 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
7211 info
->call_handler_return_bbs
= g_slist_append_mempool (cfg
->mempool
, info
->call_handler_return_bbs
, noex_bb
);
7213 builder
= ctx
->builder
= create_builder (ctx
);
7214 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
7216 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
7219 case OP_START_HANDLER
: {
7222 case OP_ENDFINALLY
: {
7223 LLVMBasicBlockRef resume_bb
;
7224 MonoBasicBlock
*handler_bb
;
7225 LLVMValueRef val
, switch_ins
, callee
;
7228 gboolean is_fault
= MONO_REGION_FLAGS (bb
->region
) == MONO_EXCEPTION_CLAUSE_FAULT
;
7231 * Fault clauses are like finally clauses, but they are only called if an exception is thrown.
7234 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
7235 g_assert (handler_bb
);
7236 info
= &bblocks
[handler_bb
->block_num
];
7237 lhs
= info
->finally_ind
;
7240 bb_list
= info
->call_handler_return_bbs
;
7242 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
7244 /* Load the finally variable */
7245 val
= LLVMBuildLoad (builder
, lhs
, "");
7247 /* Reset the variable */
7248 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
7250 /* Branch to either resume_bb, or to the bblocks in bb_list */
7251 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
7253 * The other targets are added at the end to handle OP_CALL_HANDLER
7254 * opcodes processed later.
7256 info
->endfinally_switch_ins_list
= g_slist_append_mempool (cfg
->mempool
, info
->endfinally_switch_ins_list
, switch_ins
);
7258 builder
= ctx
->builder
= create_builder (ctx
);
7259 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
7262 if (ctx
->llvm_only
) {
7263 emit_resume_eh (ctx
, bb
);
7265 LLVMTypeRef icall_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
7266 if (ctx
->cfg
->compile_aot
) {
7267 callee
= get_callee (ctx
, icall_sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_llvm_resume_unwind_trampoline
));
7269 #if LLVM_API_VERSION > 100
7270 callee
= get_jit_callee (ctx
, "llvm_resume_unwind_trampoline", icall_sig
, MONO_PATCH_INFO_JIT_ICALL_ID
, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_llvm_resume_unwind_trampoline
));
7272 g_assert_not_reached ();
7276 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
7277 LLVMBuildUnreachable (builder
);
7280 has_terminator
= TRUE
;
7283 case OP_IL_SEQ_POINT
:
7288 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
7289 set_failure (ctx
, reason
);
7297 /* Convert the value to the type required by phi nodes */
7298 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && ctx
->vreg_types
[ins
->dreg
]) {
7299 if (ctx
->is_vphi
[ins
->dreg
])
7301 values
[ins
->dreg
] = addresses
[ins
->dreg
];
7303 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], ctx
->vreg_types
[ins
->dreg
]);
7306 /* Add stores for volatile variables */
7307 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
7308 emit_volatile_store (ctx
, ins
->dreg
);
7314 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0)) {
7315 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
7318 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
) {
7319 emit_dbg_loc (ctx
, builder
, cfg
->header
->code
+ cfg
->header
->code_size
- 1);
7320 LLVMBuildRetVoid (builder
);
7323 if (bb
== cfg
->bb_entry
)
7324 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
7328 * mono_llvm_check_method_supported:
7330 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
7331 * compiling a method twice.
7334 mono_llvm_check_method_supported (MonoCompile
*cfg
)
7339 if (mono_method_signature_internal (cfg
->method
)->call_convention
== MONO_CALL_VARARG
) {
7340 cfg
->exception_message
= g_strdup ("vararg callconv");
7341 cfg
->disable_llvm
= TRUE
;
7349 if (cfg
->method
->save_lmf
) {
7350 cfg
->exception_message
= g_strdup ("lmf");
7351 cfg
->disable_llvm
= TRUE
;
7353 if (cfg
->disable_llvm
)
7357 * Nested clauses where one of the clauses is a finally clause is
7358 * not supported, because LLVM can't figure out the control flow,
7359 * probably because we resume exception handling by calling our
7360 * own function instead of using the 'resume' llvm instruction.
7362 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
7363 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
7364 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
7365 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
7367 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
7368 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
7369 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
7370 cfg
->exception_message
= g_strdup ("nested clauses");
7371 cfg
->disable_llvm
= TRUE
;
7376 if (cfg
->disable_llvm
)
7380 if (cfg
->method
->dynamic
) {
7381 cfg
->exception_message
= g_strdup ("dynamic.");
7382 cfg
->disable_llvm
= TRUE
;
7384 if (cfg
->disable_llvm
)
7388 static LLVMCallInfo
*
7389 get_llvm_call_info (MonoCompile
*cfg
, MonoMethodSignature
*sig
)
7391 LLVMCallInfo
*linfo
;
7394 if (cfg
->gsharedvt
&& cfg
->llvm_only
&& mini_is_gsharedvt_variable_signature (sig
)) {
7398 * Gsharedvt methods have the following calling convention:
7399 * - all arguments are passed by ref, even non generic ones
7400 * - the return value is returned by ref too, using a vret
7401 * argument passed after 'this'.
7403 n
= sig
->param_count
+ sig
->hasthis
;
7404 linfo
= (LLVMCallInfo
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMCallInfo
) + (sizeof (LLVMArgInfo
) * n
));
7408 linfo
->args
[pindex
++].storage
= LLVMArgNormal
;
7410 if (sig
->ret
->type
!= MONO_TYPE_VOID
) {
7411 if (mini_is_gsharedvt_variable_type (sig
->ret
))
7412 linfo
->ret
.storage
= LLVMArgGsharedvtVariable
;
7413 else if (mini_type_is_vtype (sig
->ret
))
7414 linfo
->ret
.storage
= LLVMArgGsharedvtFixedVtype
;
7416 linfo
->ret
.storage
= LLVMArgGsharedvtFixed
;
7417 linfo
->vret_arg_index
= pindex
;
7419 linfo
->ret
.storage
= LLVMArgNone
;
7422 for (i
= 0; i
< sig
->param_count
; ++i
) {
7423 if (sig
->params
[i
]->byref
)
7424 linfo
->args
[pindex
].storage
= LLVMArgNormal
;
7425 else if (mini_is_gsharedvt_variable_type (sig
->params
[i
]))
7426 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtVariable
;
7427 else if (mini_type_is_vtype (sig
->params
[i
]))
7428 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixedVtype
;
7430 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixed
;
7431 linfo
->args
[pindex
].type
= sig
->params
[i
];
7437 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
7438 linfo
->dummy_arg_pindex
= -1;
7439 for (i
= 0; i
< sig
->param_count
; ++i
)
7440 linfo
->args
[i
+ sig
->hasthis
].type
= sig
->params
[i
];
7446 emit_method_inner (EmitContext
*ctx
);
7449 free_ctx (EmitContext
*ctx
)
7453 g_free (ctx
->values
);
7454 g_free (ctx
->addresses
);
7455 g_free (ctx
->vreg_types
);
7456 g_free (ctx
->is_vphi
);
7457 g_free (ctx
->vreg_cli_types
);
7458 g_free (ctx
->is_dead
);
7459 g_free (ctx
->unreachable
);
7460 g_ptr_array_free (ctx
->phi_values
, TRUE
);
7461 g_free (ctx
->bblocks
);
7462 g_hash_table_destroy (ctx
->region_to_handler
);
7463 g_hash_table_destroy (ctx
->clause_to_handler
);
7464 g_hash_table_destroy (ctx
->jit_callees
);
7466 g_ptr_array_free (ctx
->callsite_list
, TRUE
);
7468 g_free (ctx
->method_name
);
7469 g_ptr_array_free (ctx
->bblock_list
, TRUE
);
7471 for (l
= ctx
->builders
; l
; l
= l
->next
) {
7472 LLVMBuilderRef builder
= (LLVMBuilderRef
)l
->data
;
7473 LLVMDisposeBuilder (builder
);
7480 is_externally_callable (EmitContext
*ctx
, MonoMethod
*method
)
7482 if (ctx
->module
->llvm_only
&& ctx
->module
->static_link
&& (method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_NATIVE
|| method_is_direct_callable (method
)))
7488 * mono_llvm_emit_method:
7490 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
7493 mono_llvm_emit_method (MonoCompile
*cfg
)
7502 /* The code below might acquire the loader lock, so use it for global locking */
7503 mono_loader_lock ();
7505 /* Used to communicate with the callbacks */
7506 mono_native_tls_set_value (current_cfg_tls_id
, cfg
);
7508 ctx
= g_new0 (EmitContext
, 1);
7510 ctx
->mempool
= cfg
->mempool
;
7513 * This maps vregs to the LLVM instruction defining them
7515 ctx
->values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
7517 * This maps vregs for volatile variables to the LLVM instruction defining their
7520 ctx
->addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
7521 ctx
->vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
7522 ctx
->is_vphi
= g_new0 (gboolean
, cfg
->next_vreg
);
7523 ctx
->vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
7524 ctx
->phi_values
= g_ptr_array_sized_new (256);
7526 * This signals whenever the vreg was defined by a phi node with no input vars
7527 * (i.e. all its input bblocks end with NOT_REACHABLE).
7529 ctx
->is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
7530 /* Whenever the bblock is unreachable */
7531 ctx
->unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
7532 ctx
->bblock_list
= g_ptr_array_sized_new (256);
7534 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
7535 ctx
->clause_to_handler
= g_hash_table_new (NULL
, NULL
);
7536 ctx
->callsite_list
= g_ptr_array_new ();
7537 ctx
->jit_callees
= g_hash_table_new (NULL
, NULL
);
7538 if (cfg
->compile_aot
) {
7539 ctx
->module
= &aot_module
;
7541 if (is_externally_callable (ctx
, cfg
->method
))
7542 method_name
= mono_aot_get_mangled_method_name (cfg
->method
);
7544 method_name
= mono_aot_get_method_name (cfg
);
7545 cfg
->llvm_method_name
= g_strdup (method_name
);
7547 init_jit_module (cfg
->domain
);
7548 ctx
->module
= (MonoLLVMModule
*)domain_jit_info (cfg
->domain
)->llvm_module
;
7549 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
7551 ctx
->method_name
= method_name
;
7553 #if LLVM_API_VERSION > 100
7554 if (cfg
->compile_aot
)
7555 ctx
->lmodule
= ctx
->module
->lmodule
;
7557 ctx
->lmodule
= LLVMModuleCreateWithName (g_strdup_printf ("jit-module-%s", cfg
->method
->name
));
7559 ctx
->lmodule
= ctx
->module
->lmodule
;
7561 ctx
->llvm_only
= ctx
->module
->llvm_only
;
7563 ctx
->emit_dummy_arg
= TRUE
;
7566 emit_method_inner (ctx
);
7568 if (!ctx_ok (ctx
)) {
7570 /* Need to add unused phi nodes as they can be referenced by other values */
7571 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, "PHI_BB");
7572 LLVMBuilderRef builder
;
7574 builder
= create_builder (ctx
);
7575 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
7577 for (i
= 0; i
< ctx
->phi_values
->len
; ++i
) {
7578 LLVMValueRef v
= (LLVMValueRef
)g_ptr_array_index (ctx
->phi_values
, i
);
7579 if (LLVMGetInstructionParent (v
) == NULL
)
7580 LLVMInsertIntoBuilder (builder
, v
);
7583 if (ctx
->module
->llvm_only
&& ctx
->module
->static_link
) {
7584 // Keep a stub for the function since it might be called directly
7585 int nbbs
= LLVMCountBasicBlocks (ctx
->lmethod
);
7586 LLVMBasicBlockRef
*bblocks
= g_new0 (LLVMBasicBlockRef
, nbbs
);
7587 LLVMGetBasicBlocks (ctx
->lmethod
, bblocks
);
7588 for (int i
= 0; i
< nbbs
; ++i
)
7589 LLVMDeleteBasicBlock (bblocks
[i
]);
7591 LLVMBasicBlockRef entry_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, "ENTRY");
7592 builder
= create_builder (ctx
);
7593 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
7594 ctx
->builder
= builder
;
7596 LLVMTypeRef sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
7597 LLVMValueRef callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_llvmonly_throw_nullref_exception
));
7598 emit_call (ctx
, cfg
->bb_entry
, &builder
, callee
, NULL
, 0);
7599 LLVMBuildUnreachable (builder
);
7601 LLVMDeleteFunction (ctx
->lmethod
);
7608 mono_native_tls_set_value (current_cfg_tls_id
, NULL
);
7610 mono_loader_unlock ();
7614 emit_method_inner (EmitContext
*ctx
)
7616 MonoCompile
*cfg
= ctx
->cfg
;
7617 MonoMethodSignature
*sig
;
7619 LLVMTypeRef method_type
;
7620 LLVMValueRef method
= NULL
;
7621 LLVMValueRef
*values
= ctx
->values
;
7622 int i
, max_block_num
, bb_index
;
7623 gboolean last
= FALSE
;
7624 LLVMCallInfo
*linfo
;
7625 LLVMModuleRef lmodule
= ctx
->lmodule
;
7627 GPtrArray
*bblock_list
= ctx
->bblock_list
;
7628 MonoMethodHeader
*header
;
7629 MonoExceptionClause
*clause
;
7631 LLVMBuilderRef entry_builder
= NULL
;
7632 LLVMBasicBlockRef entry_bb
= NULL
;
7634 if (cfg
->gsharedvt
&& !cfg
->llvm_only
) {
7635 set_failure (ctx
, "gsharedvt");
7641 static int count
= 0;
7644 char *llvm_count_str
= g_getenv ("LLVM_COUNT");
7645 if (llvm_count_str
) {
7646 int lcount
= atoi (llvm_count_str
);
7647 g_free (llvm_count_str
);
7648 if (count
== lcount
) {
7649 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
7653 if (count
> lcount
) {
7654 set_failure (ctx
, "count");
7661 // If we come upon one of the init_method wrappers, we need to find
7662 // the method that we have already emitted and tell LLVM that this
7663 // managed method info for the wrapper is associated with this method
7664 // we constructed ourselves from LLVM IR.
7666 // This is necessary to unwind through the init_method, in the case that
7667 // it has to run a static cctor that throws an exception
7668 if (cfg
->method
->wrapper_type
== MONO_WRAPPER_OTHER
) {
7669 WrapperInfo
*info
= mono_marshal_get_wrapper_info (cfg
->method
);
7670 if (info
->subtype
== WRAPPER_SUBTYPE_AOT_INIT
) {
7671 method
= get_init_icall_wrapper (ctx
->module
, info
->d
.aot_init
.subtype
);
7672 ctx
->lmethod
= method
;
7673 ctx
->module
->max_method_idx
= MAX (ctx
->module
->max_method_idx
, cfg
->method_index
);
7675 const char *init_name
= mono_marshal_get_aot_init_wrapper_name (info
->d
.aot_init
.subtype
);
7676 ctx
->method_name
= g_strdup_printf ("%s%s", ctx
->module
->global_prefix
, init_name
);
7677 ctx
->cfg
->asm_symbol
= g_strdup (ctx
->method_name
);
7679 if (!cfg
->llvm_only
&& ctx
->module
->external_symbols
) {
7680 LLVMSetLinkage (method
, LLVMExternalLinkage
);
7681 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
7688 sig
= mono_method_signature_internal (cfg
->method
);
7691 linfo
= get_llvm_call_info (cfg
, sig
);
7697 linfo
->rgctx_arg
= TRUE
;
7698 else if (needs_extra_arg (ctx
, cfg
->method
))
7699 linfo
->dummy_arg
= TRUE
;
7700 ctx
->method_type
= method_type
= sig_to_llvm_sig_full (ctx
, sig
, linfo
);
7704 method
= LLVMAddFunction (lmodule
, ctx
->method_name
, method_type
);
7705 ctx
->lmethod
= method
;
7707 if (!cfg
->llvm_only
)
7708 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
7710 /* if the method doesn't contain
7711 * (1) a call (so it's a leaf method)
7713 * we can skip the GC safepoint on method entry. */
7714 gboolean requires_safepoint
= cfg
->has_calls
;
7715 if (!requires_safepoint
) {
7716 for (bb
= cfg
->bb_entry
->next_bb
; bb
; bb
= bb
->next_bb
) {
7717 if (bb
->loop_body_start
|| (bb
->flags
& BB_EXCEPTION_HANDLER
)) {
7718 requires_safepoint
= TRUE
;
7723 if (!cfg
->llvm_only
&& cfg
->compile_aot
&& mono_threads_are_safepoints_enabled () && requires_safepoint
)
7724 LLVMSetGC (method
, "coreclr");
7725 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
7727 mono_llvm_add_func_attr (method
, LLVM_ATTR_UW_TABLE
);
7729 if (cfg
->compile_aot
) {
7730 if (is_externally_callable (ctx
, cfg
->method
)) {
7731 LLVMSetLinkage (method
, LLVMExternalLinkage
);
7733 LLVMSetLinkage (method
, LLVMInternalLinkage
);
7734 //all methods have internal visibility when doing llvm_only
7735 if (!cfg
->llvm_only
&& ctx
->module
->external_symbols
) {
7736 LLVMSetLinkage (method
, LLVMExternalLinkage
);
7737 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
7741 LLVMSetLinkage (method
, LLVMExternalLinkage
);
7744 if (cfg
->method
->save_lmf
&& !cfg
->llvm_only
) {
7745 set_failure (ctx
, "lmf");
7749 if (sig
->pinvoke
&& cfg
->method
->wrapper_type
!= MONO_WRAPPER_RUNTIME_INVOKE
&& !cfg
->llvm_only
) {
7750 set_failure (ctx
, "pinvoke signature");
7754 header
= cfg
->header
;
7755 for (i
= 0; i
< header
->num_clauses
; ++i
) {
7756 clause
= &header
->clauses
[i
];
7757 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_FAULT
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
) {
7758 set_failure (ctx
, "non-finally/catch/fault clause.");
7762 if (header
->num_clauses
|| (cfg
->method
->iflags
& METHOD_IMPL_ATTRIBUTE_NOINLINING
) || cfg
->no_inline
)
7763 /* We can't handle inlined methods with clauses */
7764 mono_llvm_add_func_attr (method
, LLVM_ATTR_NO_INLINE
);
7766 if (linfo
->rgctx_arg
) {
7767 ctx
->rgctx_arg
= LLVMGetParam (method
, linfo
->rgctx_arg_pindex
);
7768 ctx
->rgctx_arg_pindex
= linfo
->rgctx_arg_pindex
;
7770 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7771 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7772 * CC_X86_64_Mono in X86CallingConv.td.
7774 if (!ctx
->llvm_only
)
7775 mono_llvm_add_param_attr (ctx
->rgctx_arg
, LLVM_ATTR_IN_REG
);
7776 LLVMSetValueName (ctx
->rgctx_arg
, "rgctx");
7778 ctx
->rgctx_arg_pindex
= -1;
7780 if (cfg
->vret_addr
) {
7781 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, linfo
->vret_arg_pindex
);
7782 LLVMSetValueName (values
[cfg
->vret_addr
->dreg
], "vret");
7783 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
7784 mono_llvm_add_param_attr (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVM_ATTR_STRUCT_RET
);
7785 mono_llvm_add_param_attr (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVM_ATTR_NO_ALIAS
);
7790 ctx
->this_arg_pindex
= linfo
->this_arg_pindex
;
7791 ctx
->this_arg
= LLVMGetParam (method
, linfo
->this_arg_pindex
);
7792 values
[cfg
->args
[0]->dreg
] = ctx
->this_arg
;
7793 LLVMSetValueName (values
[cfg
->args
[0]->dreg
], "this");
7795 if (linfo
->dummy_arg
)
7796 LLVMSetValueName (LLVMGetParam (method
, linfo
->dummy_arg_pindex
), "dummy_arg");
7798 names
= g_new (char *, sig
->param_count
);
7799 mono_method_get_param_names (cfg
->method
, (const char **) names
);
7801 /* Set parameter names/attributes */
7802 for (i
= 0; i
< sig
->param_count
; ++i
) {
7803 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
7805 int pindex
= ainfo
->pindex
+ ainfo
->ndummy_fpargs
;
7808 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
) {
7809 name
= g_strdup_printf ("dummy_%d_%d", i
, j
);
7810 LLVMSetValueName (LLVMGetParam (method
, ainfo
->pindex
+ j
), name
);
7814 if (ainfo
->storage
== LLVMArgVtypeInReg
&& ainfo
->pair_storage
[0] == LLVMArgNone
&& ainfo
->pair_storage
[1] == LLVMArgNone
)
7817 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, pindex
);
7818 if (ainfo
->storage
== LLVMArgGsharedvtFixed
|| ainfo
->storage
== LLVMArgGsharedvtFixedVtype
) {
7819 if (names
[i
] && names
[i
][0] != '\0')
7820 name
= g_strdup_printf ("p_arg_%s", names
[i
]);
7822 name
= g_strdup_printf ("p_arg_%d", i
);
7824 if (names
[i
] && names
[i
][0] != '\0')
7825 name
= g_strdup_printf ("arg_%s", names
[i
]);
7827 name
= g_strdup_printf ("arg_%d", i
);
7829 LLVMSetValueName (LLVMGetParam (method
, pindex
), name
);
7831 if (ainfo
->storage
== LLVMArgVtypeByVal
)
7832 mono_llvm_add_param_attr (LLVMGetParam (method
, pindex
), LLVM_ATTR_BY_VAL
);
7834 if (ainfo
->storage
== LLVMArgVtypeByRef
) {
7836 cfg
->args
[i
+ sig
->hasthis
]->opcode
= OP_VTARG_ADDR
;
7841 if (ctx
->module
->emit_dwarf
&& cfg
->compile_aot
&& mono_debug_enabled ()) {
7842 ctx
->minfo
= mono_debug_lookup_method (cfg
->method
);
7843 ctx
->dbg_md
= emit_dbg_subprogram (ctx
, cfg
, method
, ctx
->method_name
);
7847 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
7848 max_block_num
= MAX (max_block_num
, bb
->block_num
);
7849 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
7851 /* Add branches between non-consecutive bblocks */
7852 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7853 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
7854 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
7856 MonoInst
*inst
= (MonoInst
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
7857 inst
->opcode
= OP_BR
;
7858 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
7859 mono_bblock_add_inst (bb
, inst
);
7864 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7866 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7868 LLVMBuilderRef builder
;
7870 char dname_buf
[128];
7872 builder
= create_builder (ctx
);
7874 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
7875 switch (ins
->opcode
) {
7880 LLVMTypeRef phi_type
= llvm_type_to_stack_type (cfg
, type_to_llvm_type (ctx
, m_class_get_byval_arg (ins
->klass
)));
7885 if (ins
->opcode
== OP_VPHI
) {
7886 /* Treat valuetype PHI nodes as operating on the address itself */
7887 g_assert (ins
->klass
);
7888 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, m_class_get_byval_arg (ins
->klass
)), 0);
7892 * Have to precreate these, as they can be referenced by
7893 * earlier instructions.
7895 sprintf (dname_buf
, "t%d", ins
->dreg
);
7897 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
7899 if (ins
->opcode
== OP_VPHI
)
7900 ctx
->addresses
[ins
->dreg
] = values
[ins
->dreg
];
7902 g_ptr_array_add (ctx
->phi_values
, values
[ins
->dreg
]);
7905 * Set the expected type of the incoming arguments since these have
7906 * to have the same type.
7908 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
7909 int sreg1
= ins
->inst_phi_args
[i
+ 1];
7912 if (ins
->opcode
== OP_VPHI
)
7913 ctx
->is_vphi
[sreg1
] = TRUE
;
7914 ctx
->vreg_types
[sreg1
] = phi_type
;
7920 ((MonoInst
*)ins
->inst_p0
)->flags
|= MONO_INST_INDIRECT
;
7929 * Create an ordering for bblocks, use the depth first order first, then
7930 * put the exception handling bblocks last.
7932 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
7933 bb
= cfg
->bblocks
[bb_index
];
7934 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
7935 g_ptr_array_add (bblock_list
, bb
);
7936 bblocks
[bb
->block_num
].added
= TRUE
;
7940 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7941 if (!bblocks
[bb
->block_num
].added
)
7942 g_ptr_array_add (bblock_list
, bb
);
7946 * Second pass: generate code.
7949 entry_builder
= create_builder (ctx
);
7950 entry_bb
= get_bb (ctx
, cfg
->bb_entry
);
7951 LLVMPositionBuilderAtEnd (entry_builder
, entry_bb
);
7952 emit_entry_bb (ctx
, entry_builder
);
7954 // Make landing pads first
7955 ctx
->exc_meta
= g_hash_table_new_full (NULL
, NULL
, NULL
, NULL
);
7957 if (ctx
->llvm_only
) {
7958 size_t group_index
= 0;
7959 while (group_index
< cfg
->header
->num_clauses
) {
7961 size_t cursor
= group_index
;
7962 while (cursor
< cfg
->header
->num_clauses
&&
7963 CLAUSE_START (&cfg
->header
->clauses
[cursor
]) == CLAUSE_START (&cfg
->header
->clauses
[group_index
]) &&
7964 CLAUSE_END (&cfg
->header
->clauses
[cursor
]) == CLAUSE_END (&cfg
->header
->clauses
[group_index
])) {
7969 LLVMBasicBlockRef lpad_bb
= emit_landing_pad (ctx
, group_index
, count
);
7970 intptr_t key
= CLAUSE_END (&cfg
->header
->clauses
[group_index
]);
7971 g_hash_table_insert (ctx
->exc_meta
, (gpointer
)key
, lpad_bb
);
7973 group_index
= cursor
;
7977 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
7978 bb
= (MonoBasicBlock
*)g_ptr_array_index (bblock_list
, bb_index
);
7980 // Prune unreachable mono BBs.
7981 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
7984 process_bb (ctx
, bb
);
7988 g_hash_table_destroy (ctx
->exc_meta
);
7990 mono_memory_barrier ();
7992 /* Add incoming phi values */
7993 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7994 GSList
*l
, *ins_list
;
7996 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7998 for (l
= ins_list
; l
; l
= l
->next
) {
7999 PhiNode
*node
= (PhiNode
*)l
->data
;
8000 MonoInst
*phi
= node
->phi
;
8001 int sreg1
= node
->sreg
;
8002 LLVMBasicBlockRef in_bb
;
8007 in_bb
= get_end_bb (ctx
, node
->in_bb
);
8009 if (ctx
->unreachable
[node
->in_bb
->block_num
])
8012 if (phi
->opcode
== OP_VPHI
) {
8013 g_assert (LLVMTypeOf (ctx
->addresses
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
8014 LLVMAddIncoming (values
[phi
->dreg
], &ctx
->addresses
[sreg1
], &in_bb
, 1);
8016 if (!values
[sreg1
]) {
8017 /* Can happen with values in EH clauses */
8018 set_failure (ctx
, "incoming phi sreg1");
8021 if (LLVMTypeOf (values
[sreg1
]) != LLVMTypeOf (values
[phi
->dreg
])) {
8022 set_failure (ctx
, "incoming phi arg type mismatch");
8025 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
8026 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
8031 /* Nullify empty phi instructions */
8032 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
8033 GSList
*l
, *ins_list
;
8035 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
8037 for (l
= ins_list
; l
; l
= l
->next
) {
8038 PhiNode
*node
= (PhiNode
*)l
->data
;
8039 MonoInst
*phi
= node
->phi
;
8040 LLVMValueRef phi_ins
= values
[phi
->dreg
];
8043 /* Already removed */
8046 if (LLVMCountIncoming (phi_ins
) == 0) {
8047 mono_llvm_replace_uses_of (phi_ins
, LLVMConstNull (LLVMTypeOf (phi_ins
)));
8048 LLVMInstructionEraseFromParent (phi_ins
);
8049 values
[phi
->dreg
] = NULL
;
8054 /* Create the SWITCH statements for ENDFINALLY instructions */
8055 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
8056 BBInfo
*info
= &bblocks
[bb
->block_num
];
8058 for (l
= info
->endfinally_switch_ins_list
; l
; l
= l
->next
) {
8059 LLVMValueRef switch_ins
= (LLVMValueRef
)l
->data
;
8060 GSList
*bb_list
= info
->call_handler_return_bbs
;
8062 GSList
*bb_list_iter
;
8064 for (bb_list_iter
= bb_list
; bb_list_iter
; bb_list_iter
= g_slist_next (bb_list_iter
)) {
8065 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), (LLVMBasicBlockRef
)bb_list_iter
->data
);
8071 /* Initialize the method if needed */
8072 if (cfg
->compile_aot
&& !ctx
->module
->llvm_disable_self_init
) {
8073 // FIXME: Add more shared got entries
8074 ctx
->builder
= create_builder (ctx
);
8075 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->init_bb
);
8077 ctx
->module
->max_method_idx
= MAX (ctx
->module
->max_method_idx
, cfg
->method_index
);
8079 // FIXME: beforefieldinit
8081 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
8082 * in load_method ().
8084 gboolean needs_init
= ctx
->cfg
->got_access_count
> 0;
8085 MonoMethod
*cctor
= NULL
;
8086 if (!needs_init
&& (cctor
= mono_class_get_cctor (cfg
->method
->klass
))) {
8087 /* Needs init to run the cctor */
8088 if (cfg
->method
->flags
& METHOD_ATTRIBUTE_STATIC
)
8090 if (cctor
== cfg
->method
)
8093 // If we are a constructor, we need to init so the static
8094 // constructor gets called.
8095 if (!strcmp (cfg
->method
->name
, ".ctor"))
8098 if (cfg
->method
->wrapper_type
== MONO_WRAPPER_NATIVE_TO_MANAGED
)
8101 emit_init_method (ctx
);
8103 LLVMBuildBr (ctx
->builder
, ctx
->inited_bb
);
8105 // Was observing LLVM moving field accesses into the caller's method
8106 // body before the init call (the inlined one), leading to NULL derefs
8107 // after the init_method returns (GOT is filled out though)
8109 mono_llvm_add_func_attr (method
, LLVM_ATTR_NO_INLINE
);
8113 if (cfg
->compile_aot
&& !ctx
->module
->llvm_disable_self_init
) {
8114 g_ptr_array_add (ctx
->module
->cfgs
, cfg
);
8117 * Add the contents of ctx->callsite_list to module->callsite_list.
8118 * We can't do this earlier, as it contains llvm instructions which can be
8119 * freed if compilation fails.
8120 * FIXME: Get rid of this when all methods can be llvm compiled.
8122 for (int i
= 0; i
< ctx
->callsite_list
->len
; ++i
)
8123 g_ptr_array_add (ctx
->module
->callsite_list
, g_ptr_array_index (ctx
->callsite_list
, i
));
8126 if (cfg
->verbose_level
> 1)
8127 mono_llvm_dump_value (method
);
8129 if (cfg
->compile_aot
&& !cfg
->llvm_only
)
8130 mark_as_used (ctx
->module
, method
);
8132 if (!cfg
->llvm_only
) {
8133 LLVMValueRef md_args
[16];
8134 LLVMValueRef md_node
;
8137 if (cfg
->compile_aot
)
8138 method_index
= mono_aot_get_method_index (cfg
->orig_method
);
8141 md_args
[0] = LLVMMDString (ctx
->method_name
, strlen (ctx
->method_name
));
8142 md_args
[1] = LLVMConstInt (LLVMInt32Type (), method_index
, FALSE
);
8143 md_node
= LLVMMDNode (md_args
, 2);
8144 LLVMAddNamedMetadataOperand (lmodule
, "mono.function_indexes", md_node
);
8145 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
8148 if (cfg
->compile_aot
) {
8149 /* Don't generate native code, keep the LLVM IR */
8150 if (cfg
->verbose_level
) {
8151 char *name
= mono_method_get_full_name (cfg
->method
);
8152 printf ("%s emitted as %s\n", name
, ctx
->method_name
);
8156 //LLVMDumpValue (ctx->lmethod);
8157 #if LLVM_API_VERSION < 100
8158 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
8159 int err
= LLVMVerifyFunction(ctx
->lmethod
, LLVMPrintMessageAction
);
8160 g_assert (err
== 0);
8163 //LLVMVerifyFunction (method, 0);
8164 llvm_jit_finalize_method (ctx
);
8167 if (ctx
->module
->method_to_lmethod
)
8168 g_hash_table_insert (ctx
->module
->method_to_lmethod
, cfg
->method
, ctx
->lmethod
);
8170 if (ctx
->module
->idx_to_lmethod
)
8171 g_hash_table_insert (ctx
->module
->idx_to_lmethod
, GINT_TO_POINTER (cfg
->method_index
), ctx
->lmethod
);
8173 if (ctx
->llvm_only
&& m_class_is_valuetype (cfg
->orig_method
->klass
) && !(cfg
->orig_method
->flags
& METHOD_ATTRIBUTE_STATIC
))
8174 emit_unbox_tramp (ctx
, ctx
->method_name
, ctx
->method_type
, ctx
->lmethod
, cfg
->method_index
);
8178 * mono_llvm_create_vars:
8180 * Same as mono_arch_create_vars () for LLVM.
8183 mono_llvm_create_vars (MonoCompile
*cfg
)
8185 MonoMethodSignature
*sig
;
8187 sig
= mono_method_signature_internal (cfg
->method
);
8188 if (cfg
->gsharedvt
&& cfg
->llvm_only
) {
8189 gboolean vretaddr
= FALSE
;
8191 if (mini_is_gsharedvt_variable_signature (sig
) && sig
->ret
->type
!= MONO_TYPE_VOID
) {
8194 MonoMethodSignature
*sig
= mono_method_signature_internal (cfg
->method
);
8195 LLVMCallInfo
*linfo
;
8197 linfo
= get_llvm_call_info (cfg
, sig
);
8198 vretaddr
= (linfo
->ret
.storage
== LLVMArgVtypeRetAddr
|| linfo
->ret
.storage
== LLVMArgVtypeByRef
|| linfo
->ret
.storage
== LLVMArgGsharedvtFixed
|| linfo
->ret
.storage
== LLVMArgGsharedvtVariable
|| linfo
->ret
.storage
== LLVMArgGsharedvtFixedVtype
);
8202 * Creating vret_addr forces CEE_SETRET to store the result into it,
8203 * so we don't have to generate any code in our OP_SETRET case.
8205 cfg
->vret_addr
= mono_compile_create_var (cfg
, m_class_get_byval_arg (mono_get_intptr_class ()), OP_ARG
);
8206 if (G_UNLIKELY (cfg
->verbose_level
> 1)) {
8207 printf ("vret_addr = ");
8208 mono_print_ins (cfg
->vret_addr
);
8212 mono_arch_create_vars (cfg
);
8217 * mono_llvm_emit_call:
8219 * Same as mono_arch_emit_call () for LLVM.
8222 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
8225 MonoMethodSignature
*sig
;
8226 int i
, n
, stack_size
;
8231 sig
= call
->signature
;
8232 n
= sig
->param_count
+ sig
->hasthis
;
8234 call
->cinfo
= get_llvm_call_info (cfg
, sig
);
8236 if (cfg
->disable_llvm
)
8239 if (sig
->call_convention
== MONO_CALL_VARARG
) {
8240 cfg
->exception_message
= g_strdup ("varargs");
8241 cfg
->disable_llvm
= TRUE
;
8244 for (i
= 0; i
< n
; ++i
) {
8247 ainfo
= call
->cinfo
->args
+ i
;
8249 in
= call
->args
[i
];
8251 /* Simply remember the arguments */
8252 switch (ainfo
->storage
) {
8253 case LLVMArgNormal
: {
8254 MonoType
*t
= (sig
->hasthis
&& i
== 0) ? m_class_get_byval_arg (mono_get_intptr_class ()) : ainfo
->type
;
8257 opcode
= mono_type_to_regmove (cfg
, t
);
8258 if (opcode
== OP_FMOVE
) {
8259 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
8260 ins
->dreg
= mono_alloc_freg (cfg
);
8261 } else if (opcode
== OP_LMOVE
) {
8262 MONO_INST_NEW (cfg
, ins
, OP_LMOVE
);
8263 ins
->dreg
= mono_alloc_lreg (cfg
);
8264 } else if (opcode
== OP_RMOVE
) {
8265 MONO_INST_NEW (cfg
, ins
, OP_RMOVE
);
8266 ins
->dreg
= mono_alloc_freg (cfg
);
8268 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
8269 ins
->dreg
= mono_alloc_ireg (cfg
);
8271 ins
->sreg1
= in
->dreg
;
8274 case LLVMArgVtypeByVal
:
8275 case LLVMArgVtypeByRef
:
8276 case LLVMArgVtypeInReg
:
8277 case LLVMArgVtypeAsScalar
:
8278 case LLVMArgAsIArgs
:
8279 case LLVMArgAsFpArgs
:
8280 case LLVMArgGsharedvtVariable
:
8281 case LLVMArgGsharedvtFixed
:
8282 case LLVMArgGsharedvtFixedVtype
:
8283 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
8284 ins
->dreg
= mono_alloc_ireg (cfg
);
8285 ins
->sreg1
= in
->dreg
;
8286 ins
->inst_p0
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMArgInfo
));
8287 memcpy (ins
->inst_p0
, ainfo
, sizeof (LLVMArgInfo
));
8288 ins
->inst_vtype
= ainfo
->type
;
8289 ins
->klass
= mono_class_from_mono_type_internal (ainfo
->type
);
8292 cfg
->exception_message
= g_strdup ("ainfo->storage");
8293 cfg
->disable_llvm
= TRUE
;
8297 if (!cfg
->disable_llvm
) {
8298 MONO_ADD_INS (cfg
->cbb
, ins
);
8299 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
8305 AddFunc (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef
*param_types
, int nparams
)
8307 LLVMAddFunction (module
, name
, LLVMFunctionType (ret_type
, param_types
, nparams
, FALSE
));
8311 AddFunc2 (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef param_type1
, LLVMTypeRef param_type2
)
8313 LLVMTypeRef param_types
[4];
8315 param_types
[0] = param_type1
;
8316 param_types
[1] = param_type2
;
8318 AddFunc (module
, name
, ret_type
, param_types
, 2);
8326 static IntrinsicDesc intrinsics
[] = {
8327 {INTRINS_MEMSET
, "llvm.memset.p0i8.i32"},
8328 {INTRINS_MEMCPY
, "llvm.memcpy.p0i8.p0i8.i32"},
8329 {INTRINS_SADD_OVF_I32
, "llvm.sadd.with.overflow.i32"},
8330 {INTRINS_UADD_OVF_I32
, "llvm.uadd.with.overflow.i32"},
8331 {INTRINS_SSUB_OVF_I32
, "llvm.ssub.with.overflow.i32"},
8332 {INTRINS_USUB_OVF_I32
, "llvm.usub.with.overflow.i32"},
8333 {INTRINS_SMUL_OVF_I32
, "llvm.smul.with.overflow.i32"},
8334 {INTRINS_UMUL_OVF_I32
, "llvm.umul.with.overflow.i32"},
8335 {INTRINS_SADD_OVF_I64
, "llvm.sadd.with.overflow.i64"},
8336 {INTRINS_UADD_OVF_I64
, "llvm.uadd.with.overflow.i64"},
8337 {INTRINS_SSUB_OVF_I64
, "llvm.ssub.with.overflow.i64"},
8338 {INTRINS_USUB_OVF_I64
, "llvm.usub.with.overflow.i64"},
8339 {INTRINS_SMUL_OVF_I64
, "llvm.smul.with.overflow.i64"},
8340 {INTRINS_UMUL_OVF_I64
, "llvm.umul.with.overflow.i64"},
8341 {INTRINS_SIN
, "llvm.sin.f64"},
8342 {INTRINS_COS
, "llvm.cos.f64"},
8343 {INTRINS_SQRT
, "llvm.sqrt.f64"},
8344 /* This isn't an intrinsic, instead llvm seems to special case it by name */
8345 {INTRINS_FABS
, "fabs"},
8346 {INTRINS_ABSF
, "llvm.fabs.f32"},
8347 {INTRINS_SINF
, "llvm.sin.f32"},
8348 {INTRINS_COSF
, "llvm.cos.f32"},
8349 {INTRINS_SQRTF
, "llvm.sqrt.f32"},
8350 {INTRINS_POWF
, "llvm.pow.f32"},
8351 {INTRINS_EXPECT_I8
, "llvm.expect.i8"},
8352 {INTRINS_EXPECT_I1
, "llvm.expect.i1"},
8353 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8354 {INTRINS_SSE_PMOVMSKB
, "llvm.x86.sse2.pmovmskb.128"},
8355 {INTRINS_SSE_PSRLI_W
, "llvm.x86.sse2.psrli.w"},
8356 {INTRINS_SSE_PSRAI_W
, "llvm.x86.sse2.psrai.w"},
8357 {INTRINS_SSE_PSLLI_W
, "llvm.x86.sse2.pslli.w"},
8358 {INTRINS_SSE_PSRLI_D
, "llvm.x86.sse2.psrli.d"},
8359 {INTRINS_SSE_PSRAI_D
, "llvm.x86.sse2.psrai.d"},
8360 {INTRINS_SSE_PSLLI_D
, "llvm.x86.sse2.pslli.d"},
8361 {INTRINS_SSE_PSRLI_Q
, "llvm.x86.sse2.psrli.q"},
8362 {INTRINS_SSE_PSLLI_Q
, "llvm.x86.sse2.pslli.q"},
8363 {INTRINS_SSE_SQRT_PD
, "llvm.x86.sse2.sqrt.pd"},
8364 {INTRINS_SSE_SQRT_PS
, "llvm.x86.sse.sqrt.ps"},
8365 {INTRINS_SSE_RSQRT_PS
, "llvm.x86.sse.rsqrt.ps"},
8366 {INTRINS_SSE_RCP_PS
, "llvm.x86.sse.rcp.ps"},
8367 {INTRINS_SSE_CVTTPD2DQ
, "llvm.x86.sse2.cvttpd2dq"},
8368 {INTRINS_SSE_CVTTPS2DQ
, "llvm.x86.sse2.cvttps2dq"},
8369 {INTRINS_SSE_CVTDQ2PD
, "llvm.x86.sse2.cvtdq2pd"},
8370 {INTRINS_SSE_CVTDQ2PS
, "llvm.x86.sse2.cvtdq2ps"},
8371 {INTRINS_SSE_CVTPD2DQ
, "llvm.x86.sse2.cvtpd2dq"},
8372 {INTRINS_SSE_CVTPS2DQ
, "llvm.x86.sse2.cvtps2dq"},
8373 {INTRINS_SSE_CVTPD2PS
, "llvm.x86.sse2.cvtpd2ps"},
8374 {INTRINS_SSE_CVTPS2PD
, "llvm.x86.sse2.cvtps2pd"},
8375 {INTRINS_SSE_CMPPD
, "llvm.x86.sse2.cmp.pd"},
8376 {INTRINS_SSE_CMPPS
, "llvm.x86.sse.cmp.ps"},
8377 {INTRINS_SSE_PACKSSWB
, "llvm.x86.sse2.packsswb.128"},
8378 {INTRINS_SSE_PACKUSWB
, "llvm.x86.sse2.packuswb.128"},
8379 {INTRINS_SSE_PACKSSDW
, "llvm.x86.sse2.packssdw.128"},
8380 {INTRINS_SSE_PACKUSDW
, "llvm.x86.sse41.packusdw"},
8381 {INTRINS_SSE_MINPS
, "llvm.x86.sse.min.ps"},
8382 {INTRINS_SSE_MAXPS
, "llvm.x86.sse.max.ps"},
8383 {INTRINS_SSE_HADDPS
, "llvm.x86.sse3.hadd.ps"},
8384 {INTRINS_SSE_HSUBPS
, "llvm.x86.sse3.hsub.ps"},
8385 {INTRINS_SSE_ADDSUBPS
, "llvm.x86.sse3.addsub.ps"},
8386 {INTRINS_SSE_MINPD
, "llvm.x86.sse2.min.pd"},
8387 {INTRINS_SSE_MAXPD
, "llvm.x86.sse2.max.pd"},
8388 {INTRINS_SSE_HADDPD
, "llvm.x86.sse3.hadd.pd"},
8389 {INTRINS_SSE_HSUBPD
, "llvm.x86.sse3.hsub.pd"},
8390 {INTRINS_SSE_ADDSUBPD
, "llvm.x86.sse3.addsub.pd"},
8391 {INTRINS_SSE_PADDSW
, "llvm.x86.sse2.padds.w"},
8392 {INTRINS_SSE_PSUBSW
, "llvm.x86.sse2.psubs.w"},
8393 {INTRINS_SSE_PADDUSW
, "llvm.x86.sse2.paddus.w"},
8394 {INTRINS_SSE_PSUBUSW
, "llvm.x86.sse2.psubus.w"},
8395 {INTRINS_SSE_PAVGW
, "llvm.x86.sse2.pavg.w"},
8396 {INTRINS_SSE_PMULHW
, "llvm.x86.sse2.pmulh.w"},
8397 {INTRINS_SSE_PMULHU
, "llvm.x86.sse2.pmulhu.w"},
8398 {INTRINS_SE_PADDSB
, "llvm.x86.sse2.padds.b"},
8399 {INTRINS_SSE_PSUBSB
, "llvm.x86.sse2.psubs.b"},
8400 {INTRINS_SSE_PADDUSB
, "llvm.x86.sse2.paddus.b"},
8401 {INTRINS_SSE_PSUBUSB
, "llvm.x86.sse2.psubus.b"},
8402 {INTRINS_SSE_PAVGB
, "llvm.x86.sse2.pavg.b"},
8403 {INTRINS_SSE_PAUSE
, "llvm.x86.sse2.pause"},
8404 {INTRINS_SSE_DPPS
, "llvm.x86.sse41.dpps"},
8405 {INTRINS_SSE_ROUNDPD
, "llvm.x86.sse41.round.pd"}
8410 add_sse_binary (LLVMModuleRef module
, const char *name
, int type
)
8412 LLVMTypeRef ret_type
= type_to_simd_type (type
);
8413 AddFunc2 (module
, name
, ret_type
, ret_type
, ret_type
);
8417 add_intrinsic (LLVMModuleRef module
, int id
)
8420 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8421 LLVMTypeRef ret_type
, arg_types
[16];
8424 name
= (const char*)g_hash_table_lookup (intrins_id_to_name
, GINT_TO_POINTER (id
));
8428 case INTRINS_MEMSET
: {
8429 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8431 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
8434 case INTRINS_MEMCPY
: {
8435 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8437 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
8440 case INTRINS_SADD_OVF_I32
:
8441 case INTRINS_UADD_OVF_I32
:
8442 case INTRINS_SSUB_OVF_I32
:
8443 case INTRINS_USUB_OVF_I32
:
8444 case INTRINS_SMUL_OVF_I32
:
8445 case INTRINS_UMUL_OVF_I32
: {
8446 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
8447 LLVMTypeRef params
[] = { LLVMInt32Type (), LLVMInt32Type () };
8448 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i32
, 2, FALSE
);
8450 AddFunc (module
, name
, ret_type
, params
, 2);
8453 case INTRINS_SADD_OVF_I64
:
8454 case INTRINS_UADD_OVF_I64
:
8455 case INTRINS_SSUB_OVF_I64
:
8456 case INTRINS_USUB_OVF_I64
:
8457 case INTRINS_SMUL_OVF_I64
:
8458 case INTRINS_UMUL_OVF_I64
: {
8459 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
8460 LLVMTypeRef params
[] = { LLVMInt64Type (), LLVMInt64Type () };
8461 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i64
, 2, FALSE
);
8463 AddFunc (module
, name
, ret_type
, params
, 2);
8469 case INTRINS_FABS
: {
8470 LLVMTypeRef params
[] = { LLVMDoubleType () };
8472 AddFunc (module
, name
, LLVMDoubleType (), params
, 1);
8478 case INTRINS_ABSF
: {
8479 LLVMTypeRef params
[] = { LLVMFloatType () };
8481 AddFunc (module
, name
, LLVMFloatType (), params
, 1);
8484 case INTRINS_POWF
: {
8485 LLVMTypeRef params
[] = { LLVMFloatType (), LLVMFloatType () };
8487 AddFunc (module
, name
, LLVMFloatType (), params
, 2);
8490 case INTRINS_EXPECT_I8
:
8491 AddFunc2 (module
, name
, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8493 case INTRINS_EXPECT_I1
:
8494 AddFunc2 (module
, name
, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8496 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8497 case INTRINS_SSE_PMOVMSKB
:
8499 ret_type
= LLVMInt32Type ();
8500 arg_types
[0] = type_to_simd_type (MONO_TYPE_I1
);
8501 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8503 case INTRINS_SSE_PSRLI_W
:
8504 case INTRINS_SSE_PSRAI_W
:
8505 case INTRINS_SSE_PSLLI_W
:
8507 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8508 arg_types
[0] = ret_type
;
8509 arg_types
[1] = LLVMInt32Type ();
8510 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8512 case INTRINS_SSE_PSRLI_D
:
8513 case INTRINS_SSE_PSRAI_D
:
8514 case INTRINS_SSE_PSLLI_D
:
8515 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8516 arg_types
[0] = ret_type
;
8517 arg_types
[1] = LLVMInt32Type ();
8518 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8520 case INTRINS_SSE_PSRLI_Q
:
8521 case INTRINS_SSE_PSLLI_Q
:
8522 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
8523 arg_types
[0] = ret_type
;
8524 arg_types
[1] = LLVMInt32Type ();
8525 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8527 case INTRINS_SSE_SQRT_PD
:
8529 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8530 arg_types
[0] = ret_type
;
8531 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8533 case INTRINS_SSE_SQRT_PS
:
8534 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8535 arg_types
[0] = ret_type
;
8536 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8538 case INTRINS_SSE_RSQRT_PS
:
8539 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8540 arg_types
[0] = ret_type
;
8541 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8543 case INTRINS_SSE_RCP_PS
:
8544 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8545 arg_types
[0] = ret_type
;
8546 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8548 case INTRINS_SSE_CVTTPD2DQ
:
8549 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8550 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8551 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8553 case INTRINS_SSE_CVTTPS2DQ
:
8554 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8555 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8556 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8558 case INTRINS_SSE_CVTDQ2PD
:
8559 /* Conversion ops */
8560 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8561 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8562 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8564 case INTRINS_SSE_CVTDQ2PS
:
8565 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8566 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8567 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8569 case INTRINS_SSE_CVTPD2DQ
:
8570 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8571 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8572 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8574 case INTRINS_SSE_CVTPS2DQ
:
8575 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8576 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8577 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8579 case INTRINS_SSE_CVTPD2PS
:
8580 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8581 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8582 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8584 case INTRINS_SSE_CVTPS2PD
:
8585 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8586 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8587 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8589 case INTRINS_SSE_CMPPD
:
8591 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8592 arg_types
[0] = ret_type
;
8593 arg_types
[1] = ret_type
;
8594 arg_types
[2] = LLVMInt8Type ();
8595 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8597 case INTRINS_SSE_CMPPS
:
8598 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8599 arg_types
[0] = ret_type
;
8600 arg_types
[1] = ret_type
;
8601 arg_types
[2] = LLVMInt8Type ();
8602 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8604 case INTRINS_SSE_PACKSSWB
:
8605 case INTRINS_SSE_PACKUSWB
:
8606 case INTRINS_SSE_PACKSSDW
:
8608 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
8609 arg_types
[0] = type_to_simd_type (MONO_TYPE_I2
);
8610 arg_types
[1] = type_to_simd_type (MONO_TYPE_I2
);
8611 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8613 case INTRINS_SSE_PACKUSDW
:
8614 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8615 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8616 arg_types
[1] = type_to_simd_type (MONO_TYPE_I4
);
8617 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8619 /* SSE Binary ops */
8620 case INTRINS_SSE_PADDSW
:
8621 case INTRINS_SSE_PSUBSW
:
8622 case INTRINS_SSE_PADDUSW
:
8623 case INTRINS_SSE_PSUBUSW
:
8624 case INTRINS_SSE_PAVGW
:
8625 case INTRINS_SSE_PMULHW
:
8626 case INTRINS_SSE_PMULHU
:
8627 add_sse_binary (module
, name
, MONO_TYPE_I2
);
8629 case INTRINS_SSE_MINPS
:
8630 case INTRINS_SSE_MAXPS
:
8631 case INTRINS_SSE_HADDPS
:
8632 case INTRINS_SSE_HSUBPS
:
8633 case INTRINS_SSE_ADDSUBPS
:
8634 add_sse_binary (module
, name
, MONO_TYPE_R4
);
8636 case INTRINS_SSE_MINPD
:
8637 case INTRINS_SSE_MAXPD
:
8638 case INTRINS_SSE_HADDPD
:
8639 case INTRINS_SSE_HSUBPD
:
8640 case INTRINS_SSE_ADDSUBPD
:
8641 add_sse_binary (module
, name
, MONO_TYPE_R8
);
8643 case INTRINS_SE_PADDSB
:
8644 case INTRINS_SSE_PSUBSB
:
8645 case INTRINS_SSE_PADDUSB
:
8646 case INTRINS_SSE_PSUBUSB
:
8647 case INTRINS_SSE_PAVGB
:
8648 add_sse_binary (module
, name
, MONO_TYPE_I1
);
8650 case INTRINS_SSE_PAUSE
:
8651 AddFunc (module
, "llvm.x86.sse2.pause", LLVMVoidType (), NULL
, 0);
8653 case INTRINS_SSE_DPPS
:
8654 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8655 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8656 arg_types
[1] = type_to_simd_type (MONO_TYPE_R4
);
8657 #if LLVM_API_VERSION >= 500
8658 arg_types
[2] = LLVMInt8Type ();
8660 arg_types
[2] = LLVMInt32Type ();
8662 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8664 case INTRINS_SSE_ROUNDPD
:
8665 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8666 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8667 arg_types
[1] = LLVMInt32Type ();
8668 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8670 #endif /* AMD64 || X86 */
8672 g_assert_not_reached ();
8678 get_intrins (EmitContext
*ctx
, int id
)
8680 const char *name
= (const char*)g_hash_table_lookup (intrins_id_to_name
, GINT_TO_POINTER (id
));
8683 #if LLVM_API_VERSION > 100
8687 * Every method is emitted into its own module so
8688 * we can add intrinsics on demand.
8690 res
= ctx
->module
->intrins_by_id
[id
];
8692 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8694 add_intrinsic (ctx
->lmodule
, id
);
8695 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8698 ctx
->module
->intrins_by_id
[id
] = res
;
8704 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8711 get_intrins_by_name (EmitContext
*ctx
, const char *name
)
8713 #if LLVM_API_VERSION > 100
8717 * Every method is emitted into its own module so
8718 * we can add intrinsics on demand.
8720 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8724 /* No locking needed */
8725 id
= GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id
, name
));
8728 printf ("%s\n", name
);
8729 g_assert (id
!= -1);
8730 add_intrinsic (ctx
->lmodule
, id
);
8731 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8739 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8746 add_intrinsics (LLVMModuleRef module
)
8750 /* Emit declarations of instrinsics */
8752 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8753 * type doesn't seem to do any locking.
8755 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8756 add_intrinsic (module
, i
);
8760 AddFunc (module
, "mono_personality", LLVMVoidType (), NULL
, 0);
8762 AddFunc (module
, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL
, 0);
8765 /* Load/Store intrinsics */
8767 LLVMTypeRef arg_types
[5];
8771 for (i
= 1; i
<= 8; i
*= 2) {
8772 arg_types
[0] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8773 arg_types
[1] = LLVMInt32Type ();
8774 arg_types
[2] = LLVMInt1Type ();
8775 arg_types
[3] = LLVMInt32Type ();
8776 sprintf (name
, "llvm.mono.load.i%d.p0i%d", i
* 8, i
* 8);
8777 AddFunc (module
, name
, LLVMIntType (i
* 8), arg_types
, 4);
8779 arg_types
[0] = LLVMIntType (i
* 8);
8780 arg_types
[1] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8781 arg_types
[2] = LLVMInt32Type ();
8782 arg_types
[3] = LLVMInt1Type ();
8783 arg_types
[4] = LLVMInt32Type ();
8784 sprintf (name
, "llvm.mono.store.i%d.p0i%d", i
* 8, i
* 8);
8785 AddFunc (module
, name
, LLVMVoidType (), arg_types
, 5);
8791 add_types (MonoLLVMModule
*module
)
8793 module
->ptr_type
= LLVMPointerType (TARGET_SIZEOF_VOID_P
== 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8797 mono_llvm_init (void)
8802 mono_native_tls_alloc (¤t_cfg_tls_id
, NULL
);
8804 h
= g_hash_table_new (NULL
, NULL
);
8805 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8806 g_hash_table_insert (h
, GINT_TO_POINTER (intrinsics
[i
].id
), (gpointer
)intrinsics
[i
].name
);
8807 intrins_id_to_name
= h
;
8809 h
= g_hash_table_new (g_str_hash
, g_str_equal
);
8810 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8811 g_hash_table_insert (h
, (gpointer
)intrinsics
[i
].name
, GINT_TO_POINTER (intrinsics
[i
].id
+ 1));
8812 intrins_name_to_id
= h
;
8816 mono_llvm_cleanup (void)
8818 MonoLLVMModule
*module
= &aot_module
;
8820 if (module
->lmodule
)
8821 LLVMDisposeModule (module
->lmodule
);
8823 if (module
->context
)
8824 LLVMContextDispose (module
->context
);
8828 mono_llvm_free_domain_info (MonoDomain
*domain
)
8830 MonoJitDomainInfo
*info
= domain_jit_info (domain
);
8831 MonoLLVMModule
*module
= (MonoLLVMModule
*)info
->llvm_module
;
8837 g_hash_table_destroy (module
->llvm_types
);
8839 mono_llvm_dispose_ee (module
->mono_ee
);
8841 if (module
->bb_names
) {
8842 for (i
= 0; i
< module
->bb_names_len
; ++i
)
8843 g_free (module
->bb_names
[i
]);
8844 g_free (module
->bb_names
);
8846 //LLVMDisposeModule (module->module);
8850 info
->llvm_module
= NULL
;
8854 mono_llvm_create_aot_module (MonoAssembly
*assembly
, const char *global_prefix
, int initial_got_size
, LLVMModuleFlags flags
)
8856 MonoLLVMModule
*module
= &aot_module
;
8857 gboolean emit_dwarf
= (flags
& LLVM_MODULE_FLAG_DWARF
) ? 1 : 0;
8858 #ifdef TARGET_WIN32_MSVC
8859 gboolean emit_codeview
= (flags
& LLVM_MODULE_FLAG_CODEVIEW
) ? 1 : 0;
8861 gboolean static_link
= (flags
& LLVM_MODULE_FLAG_STATIC
) ? 1 : 0;
8862 gboolean llvm_only
= (flags
& LLVM_MODULE_FLAG_LLVM_ONLY
) ? 1 : 0;
8863 gboolean interp
= (flags
& LLVM_MODULE_FLAG_INTERP
) ? 1 : 0;
8864 gboolean llvm_disable_self_init
= mini_get_debug_options ()->llvm_disable_self_init
;
8866 /* Delete previous module */
8867 g_hash_table_destroy (module
->plt_entries
);
8868 if (module
->lmodule
)
8869 LLVMDisposeModule (module
->lmodule
);
8871 memset (module
, 0, sizeof (aot_module
));
8873 module
->lmodule
= LLVMModuleCreateWithName ("aot");
8874 module
->assembly
= assembly
;
8875 module
->global_prefix
= g_strdup (global_prefix
);
8876 module
->got_symbol
= g_strdup_printf ("%s_llvm_got", global_prefix
);
8877 module
->eh_frame_symbol
= g_strdup_printf ("%s_eh_frame", global_prefix
);
8878 module
->get_method_symbol
= g_strdup_printf ("%s_get_method", global_prefix
);
8879 module
->get_unbox_tramp_symbol
= g_strdup_printf ("%s_get_unbox_tramp", global_prefix
);
8880 module
->external_symbols
= TRUE
;
8881 module
->emit_dwarf
= emit_dwarf
;
8882 module
->static_link
= static_link
;
8883 module
->llvm_only
= llvm_only
;
8884 module
->llvm_disable_self_init
= llvm_disable_self_init
&& !llvm_only
; // llvm_only implies !llvm_disable_self_init
8885 module
->interp
= interp
;
8886 /* The first few entries are reserved */
8887 module
->max_got_offset
= initial_got_size
;
8888 module
->context
= LLVMGetGlobalContext ();
8889 module
->cfgs
= g_ptr_array_new ();
8890 module
->intrins_by_id
= g_new0 (LLVMValueRef
, INTRINS_NUM
);
8893 /* clang ignores our debug info because it has an invalid version */
8894 module
->emit_dwarf
= FALSE
;
8896 add_intrinsics (module
->lmodule
);
8899 #ifdef MONO_ARCH_LLVM_TARGET_LAYOUT
8900 LLVMSetDataLayout (module
->lmodule
, MONO_ARCH_LLVM_TARGET_LAYOUT
);
8902 g_assert_not_reached ();
8905 #ifdef MONO_ARCH_LLVM_TARGET_TRIPLE
8906 LLVMSetTarget (module
->lmodule
, MONO_ARCH_LLVM_TARGET_TRIPLE
);
8909 #if LLVM_API_VERSION > 100
8910 if (module
->emit_dwarf
) {
8911 char *dir
, *build_info
, *s
, *cu_name
;
8913 module
->di_builder
= mono_llvm_create_di_builder (module
->lmodule
);
8916 dir
= g_strdup (".");
8917 build_info
= mono_get_runtime_build_info ();
8918 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
8919 cu_name
= g_path_get_basename (assembly
->image
->name
);
8920 module
->cu
= mono_llvm_di_create_compile_unit (module
->di_builder
, cu_name
, dir
, s
);
8922 g_free (build_info
);
8927 #ifdef TARGET_WIN32_MSVC
8928 if (emit_codeview
) {
8929 LLVMValueRef codeview_option_args
[3];
8931 codeview_option_args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8932 codeview_option_args
[1] = LLVMMDString ("CodeView", 8);
8933 codeview_option_args
[2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8935 LLVMAddNamedMetadataOperand (module
->lmodule
, "llvm.module.flags", LLVMMDNode (codeview_option_args
, G_N_ELEMENTS (codeview_option_args
)));
8939 const char linker_options
[] = "Linker Options";
8940 const char *default_dynamic_lib_names
[] = { "/DEFAULTLIB:msvcrt",
8941 "/DEFAULTLIB:ucrt.lib",
8942 "/DEFAULTLIB:vcruntime.lib" };
8944 LLVMValueRef linker_option_args
[3];
8945 LLVMValueRef default_lib_args
[G_N_ELEMENTS (default_dynamic_lib_names
)];
8946 LLVMValueRef default_lib_nodes
[G_N_ELEMENTS(default_dynamic_lib_names
)];
8948 const char *default_lib_name
= NULL
;
8949 for (int i
= 0; i
< G_N_ELEMENTS (default_dynamic_lib_names
); ++i
) {
8950 const char *default_lib_name
= default_dynamic_lib_names
[i
];
8951 default_lib_args
[i
] = LLVMMDString (default_lib_name
, strlen (default_lib_name
));
8952 default_lib_nodes
[i
] = LLVMMDNode (default_lib_args
+ i
, 1);
8955 #if LLVM_API_VERSION < 600
8956 linker_option_args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8957 linker_option_args
[1] = LLVMMDString (linker_options
, G_N_ELEMENTS (linker_options
) - 1);
8958 linker_option_args
[2] = LLVMMDNode (default_lib_nodes
, G_N_ELEMENTS (default_lib_nodes
));
8960 LLVMAddNamedMetadataOperand (module
->lmodule
, "llvm.module.flags", LLVMMDNode (linker_option_args
, G_N_ELEMENTS (linker_option_args
)));
8962 LLVMAddNamedMetadataOperand (module
->lmodule
, "llvm.linker.options", LLVMMDNode (default_lib_args
, G_N_ELEMENTS (default_lib_args
)));
8969 * We couldn't compute the type of the LLVM global representing the got because
8970 * its size is only known after all the methods have been emitted. So create
8971 * a dummy variable, and replace all uses it with the real got variable when
8972 * its size is known in mono_llvm_emit_aot_module ().
8975 LLVMTypeRef got_type
= LLVMArrayType (module
->ptr_type
, 0);
8977 module
->got_var
= LLVMAddGlobal (module
->lmodule
, got_type
, "mono_dummy_got");
8978 module
->got_idx_to_type
= g_hash_table_new (NULL
, NULL
);
8979 LLVMSetInitializer (module
->got_var
, LLVMConstNull (got_type
));
8982 /* Add initialization array */
8983 if (!llvm_disable_self_init
) {
8984 LLVMTypeRef inited_type
= LLVMArrayType (LLVMInt8Type (), 0);
8986 module
->inited_var
= LLVMAddGlobal (aot_module
.lmodule
, inited_type
, "mono_inited_tmp");
8987 LLVMSetInitializer (module
->inited_var
, LLVMConstNull (inited_type
));
8991 emit_gc_safepoint_poll (module
);
8993 emit_llvm_code_start (module
);
8995 // Needs idx_to_lmethod
8996 if (!llvm_disable_self_init
)
8997 emit_init_icall_wrappers (module
);
8999 /* Add a dummy personality function */
9000 if (!use_mono_personality_debug
) {
9001 LLVMValueRef personality
= LLVMAddFunction (module
->lmodule
, default_personality_name
, LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
));
9002 LLVMSetLinkage (personality
, LLVMExternalLinkage
);
9004 //EMCC chockes if the personality function is referenced in the 'used' array
9006 mark_as_used (module
, personality
);
9010 /* Add a reference to the c++ exception we throw/catch */
9012 LLVMTypeRef exc
= LLVMPointerType (LLVMInt8Type (), 0);
9013 module
->sentinel_exception
= LLVMAddGlobal (module
->lmodule
, exc
, "_ZTIPi");
9014 LLVMSetLinkage (module
->sentinel_exception
, LLVMExternalLinkage
);
9015 mono_llvm_set_is_constant (module
->sentinel_exception
);
9018 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
9019 module
->plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
9020 module
->plt_entries_ji
= g_hash_table_new (NULL
, NULL
);
9021 module
->direct_callables
= g_hash_table_new (g_str_hash
, g_str_equal
);
9022 module
->idx_to_lmethod
= g_hash_table_new (NULL
, NULL
);
9023 module
->method_to_lmethod
= g_hash_table_new (NULL
, NULL
);
9024 module
->method_to_call_info
= g_hash_table_new (NULL
, NULL
);
9025 module
->idx_to_unbox_tramp
= g_hash_table_new (NULL
, NULL
);
9026 module
->callsite_list
= g_ptr_array_new ();
9030 mono_llvm_fixup_aot_module (void)
9032 MonoLLVMModule
*module
= &aot_module
;
9035 if (module
->llvm_disable_self_init
)
9039 * Replace GOT entries for directly callable methods with the methods themselves.
9040 * It would be easier to implement this by predefining all methods before compiling
9041 * their bodies, but that couldn't handle the case when a method fails to compile
9045 GHashTable
*specializable
= g_hash_table_new (NULL
, NULL
);
9047 GHashTable
*patches_to_null
= g_hash_table_new (mono_patch_info_hash
, mono_patch_info_equal
);
9048 for (int sindex
= 0; sindex
< module
->callsite_list
->len
; ++sindex
) {
9049 CallSite
*site
= (CallSite
*)g_ptr_array_index (module
->callsite_list
, sindex
);
9050 method
= site
->method
;
9051 LLVMValueRef lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, method
);
9053 LLVMValueRef placeholder
= (LLVMValueRef
)site
->load
;
9054 LLVMValueRef indexes
[2], got_entry_addr
, load
;
9057 if (lmethod
&& !(method
->iflags
& METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED
)) {
9058 mono_llvm_replace_uses_of (placeholder
, lmethod
);
9060 if (mono_aot_can_specialize (method
))
9061 g_hash_table_insert (specializable
, lmethod
, method
);
9063 g_hash_table_insert (patches_to_null
, site
->ji
, site
->ji
);
9065 int got_offset
= compute_aot_got_offset (module
, site
->ji
, site
->type
);
9067 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
9069 LLVMBuilderRef builder
= LLVMCreateBuilder ();
9070 LLVMPositionBuilderBefore (builder
, placeholder
);
9071 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9072 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
9073 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
9075 name
= get_aotconst_name (site
->ji
->type
, site
->ji
->data
.target
, got_offset
);
9076 load
= LLVMBuildLoad (builder
, got_entry_addr
, "");
9077 load
= LLVMBuildBitCast (builder
, load
, site
->type
, name
? name
: "");
9078 LLVMReplaceAllUsesWith (placeholder
, load
);
9083 mono_llvm_propagate_nonnull_final (specializable
, module
);
9084 g_hash_table_destroy (specializable
);
9086 for (int i
= 0; i
< module
->cfgs
->len
; ++i
) {
9088 * Nullify the patches pointing to direct calls. This is needed to
9089 * avoid allocating extra got slots, which is a perf problem and it
9090 * makes module->max_got_offset invalid.
9091 * It would be better to just store the patch_info in CallSite, but
9092 * cfg->patch_info is copied in aot-compiler.c.
9094 MonoCompile
*cfg
= (MonoCompile
*)g_ptr_array_index (module
->cfgs
, i
);
9095 for (MonoJumpInfo
*patch_info
= cfg
->patch_info
; patch_info
; patch_info
= patch_info
->next
) {
9096 if (patch_info
->type
== MONO_PATCH_INFO_METHOD
) {
9097 if (g_hash_table_lookup (patches_to_null
, patch_info
)) {
9098 patch_info
->type
= MONO_PATCH_INFO_NONE
;
9099 /* Nullify the call to init_method () if possible */
9100 g_assert (cfg
->got_access_count
);
9101 cfg
->got_access_count
--;
9102 #if LLVM_API_VERSION >= 600
9103 if (cfg
->got_access_count
== 0) {
9104 LLVMValueRef br
= (LLVMValueRef
)cfg
->llvmonly_init_cond
;
9106 LLVMSetSuccessor (br
, 0, LLVMGetSuccessor (br
, 1));
9114 g_hash_table_destroy (patches_to_null
);
9118 llvm_array_from_uints (LLVMTypeRef el_type
, guint32
*values
, int nvalues
)
9121 LLVMValueRef res
, *vals
;
9123 vals
= g_new0 (LLVMValueRef
, nvalues
);
9124 for (i
= 0; i
< nvalues
; ++i
)
9125 vals
[i
] = LLVMConstInt (LLVMInt32Type (), values
[i
], FALSE
);
9126 res
= LLVMConstArray (LLVMInt32Type (), vals
, nvalues
);
9132 llvm_array_from_bytes (guint8
*values
, int nvalues
)
9135 LLVMValueRef res
, *vals
;
9137 vals
= g_new0 (LLVMValueRef
, nvalues
);
9138 for (i
= 0; i
< nvalues
; ++i
)
9139 vals
[i
] = LLVMConstInt (LLVMInt8Type (), values
[i
], FALSE
);
9140 res
= LLVMConstArray (LLVMInt8Type (), vals
, nvalues
);
9145 * mono_llvm_emit_aot_file_info:
9147 * Emit the MonoAotFileInfo structure.
9148 * Same as emit_aot_file_info () in aot-compiler.c.
9151 mono_llvm_emit_aot_file_info (MonoAotFileInfo
*info
, gboolean has_jitted_code
)
9153 MonoLLVMModule
*module
= &aot_module
;
9155 /* Save these for later */
9156 memcpy (&module
->aot_info
, info
, sizeof (MonoAotFileInfo
));
9157 module
->has_jitted_code
= has_jitted_code
;
9161 * mono_llvm_emit_aot_data:
9163 * Emit the binary data DATA pointed to by symbol SYMBOL.
9166 mono_llvm_emit_aot_data (const char *symbol
, guint8
*data
, int data_len
)
9168 MonoLLVMModule
*module
= &aot_module
;
9172 type
= LLVMArrayType (LLVMInt8Type (), data_len
);
9173 d
= LLVMAddGlobal (module
->lmodule
, type
, symbol
);
9174 LLVMSetVisibility (d
, LLVMHiddenVisibility
);
9175 LLVMSetLinkage (d
, LLVMInternalLinkage
);
9176 LLVMSetInitializer (d
, mono_llvm_create_constant_data_array (data
, data_len
));
9177 LLVMSetAlignment (d
, 8);
9178 mono_llvm_set_is_constant (d
);
9181 /* Add a reference to a global defined in JITted code */
9183 AddJitGlobal (MonoLLVMModule
*module
, LLVMTypeRef type
, const char *name
)
9188 s
= g_strdup_printf ("%s%s", module
->global_prefix
, name
);
9189 v
= LLVMAddGlobal (module
->lmodule
, LLVMInt8Type (), s
);
9190 LLVMSetVisibility (v
, LLVMHiddenVisibility
);
9196 emit_aot_file_info (MonoLLVMModule
*module
)
9198 LLVMTypeRef file_info_type
;
9199 LLVMTypeRef
*eltypes
, eltype
;
9200 LLVMValueRef info_var
;
9201 LLVMValueRef
*fields
;
9202 int i
, nfields
, tindex
;
9203 MonoAotFileInfo
*info
;
9204 LLVMModuleRef lmodule
= module
->lmodule
;
9206 info
= &module
->aot_info
;
9208 /* Create an LLVM type to represent MonoAotFileInfo */
9209 nfields
= 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS
+ 21 + 5;
9210 eltypes
= g_new (LLVMTypeRef
, nfields
);
9212 eltypes
[tindex
++] = LLVMInt32Type ();
9213 eltypes
[tindex
++] = LLVMInt32Type ();
9215 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
)
9216 eltypes
[tindex
++] = LLVMPointerType (LLVMInt8Type (), 0);
9218 for (i
= 0; i
< 20; ++i
)
9219 eltypes
[tindex
++] = LLVMInt32Type ();
9221 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM
);
9222 for (i
= 0; i
< 4; ++i
)
9223 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM
);
9224 eltypes
[tindex
++] = LLVMArrayType (LLVMInt8Type (), 16);
9225 g_assert (tindex
== nfields
);
9226 file_info_type
= LLVMStructCreateNamed (module
->context
, "MonoAotFileInfo");
9227 LLVMStructSetBody (file_info_type
, eltypes
, nfields
, FALSE
);
9229 info_var
= LLVMAddGlobal (lmodule
, file_info_type
, "mono_aot_file_info");
9230 if (module
->static_link
) {
9231 LLVMSetVisibility (info_var
, LLVMHiddenVisibility
);
9232 LLVMSetLinkage (info_var
, LLVMInternalLinkage
);
9236 if (!module
->static_link
) {
9237 LLVMSetDLLStorageClass (info_var
, LLVMDLLExportStorageClass
);
9241 fields
= g_new (LLVMValueRef
, nfields
);
9243 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->version
, FALSE
);
9244 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->dummy
, FALSE
);
9248 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
9249 * for symbols defined in the .s file emitted by the aot compiler.
9251 eltype
= eltypes
[tindex
];
9252 if (module
->llvm_only
)
9253 fields
[tindex
++] = LLVMConstNull (eltype
);
9255 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_got");
9256 fields
[tindex
++] = module
->got_var
;
9257 /* llc defines this directly */
9258 if (!module
->llvm_only
) {
9259 fields
[tindex
++] = LLVMAddGlobal (lmodule
, eltype
, module
->eh_frame_symbol
);
9260 fields
[tindex
++] = module
->get_method
;
9261 fields
[tindex
++] = LLVMConstNull (eltype
);
9263 fields
[tindex
++] = LLVMConstNull (eltype
);
9264 fields
[tindex
++] = module
->get_method
;
9265 fields
[tindex
++] = module
->get_unbox_tramp
? module
->get_unbox_tramp
: LLVMConstNull (eltype
);
9267 if (module
->has_jitted_code
) {
9268 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_start");
9269 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_end");
9271 fields
[tindex
++] = LLVMConstNull (eltype
);
9272 fields
[tindex
++] = LLVMConstNull (eltype
);
9274 if (!module
->llvm_only
)
9275 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "method_addresses");
9277 fields
[tindex
++] = LLVMConstNull (eltype
);
9278 if (module
->llvm_only
&& module
->unbox_tramp_indexes
) {
9279 fields
[tindex
++] = module
->unbox_tramp_indexes
;
9280 fields
[tindex
++] = module
->unbox_trampolines
;
9282 fields
[tindex
++] = LLVMConstNull (eltype
);
9283 fields
[tindex
++] = LLVMConstNull (eltype
);
9285 if (info
->flags
& MONO_AOT_FILE_FLAG_SEPARATE_DATA
) {
9286 for (i
= 0; i
< MONO_AOT_TABLE_NUM
; ++i
)
9287 fields
[tindex
++] = LLVMConstNull (eltype
);
9289 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "blob");
9290 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_name_table");
9291 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_info_offsets");
9292 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "method_info_offsets");
9293 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "ex_info_offsets");
9294 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_info_offsets");
9295 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_table");
9296 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "got_info_offsets");
9297 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "llvm_got_info_offsets");
9298 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "image_table");
9299 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "weak_field_indexes");
9301 /* Not needed (mem_end) */
9302 fields
[tindex
++] = LLVMConstNull (eltype
);
9303 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_guid");
9304 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "runtime_version");
9305 if (info
->trampoline_size
[0]) {
9306 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "specific_trampolines");
9307 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "static_rgctx_trampolines");
9308 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "imt_trampolines");
9309 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "gsharedvt_arg_trampolines");
9310 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "ftnptr_arg_trampolines");
9311 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_arbitrary_trampolines");
9313 fields
[tindex
++] = LLVMConstNull (eltype
);
9314 fields
[tindex
++] = LLVMConstNull (eltype
);
9315 fields
[tindex
++] = LLVMConstNull (eltype
);
9316 fields
[tindex
++] = LLVMConstNull (eltype
);
9317 fields
[tindex
++] = LLVMConstNull (eltype
);
9318 fields
[tindex
++] = LLVMConstNull (eltype
);
9320 if (module
->static_link
&& !module
->llvm_only
)
9321 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "globals");
9323 fields
[tindex
++] = LLVMConstNull (eltype
);
9324 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_name");
9325 if (!module
->llvm_only
) {
9326 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt");
9327 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt_end");
9328 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unwind_info");
9329 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines");
9330 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines_end");
9331 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampoline_addresses");
9333 fields
[tindex
++] = LLVMConstNull (eltype
);
9334 fields
[tindex
++] = LLVMConstNull (eltype
);
9335 fields
[tindex
++] = LLVMConstNull (eltype
);
9336 fields
[tindex
++] = LLVMConstNull (eltype
);
9337 fields
[tindex
++] = LLVMConstNull (eltype
);
9338 fields
[tindex
++] = LLVMConstNull (eltype
);
9341 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
) {
9342 g_assert (fields
[2 + i
]);
9343 fields
[2 + i
] = LLVMConstBitCast (fields
[2 + i
], eltype
);
9347 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_got_offset_base
, FALSE
);
9348 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->got_size
, FALSE
);
9349 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_size
, FALSE
);
9350 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nmethods
, FALSE
);
9351 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nextra_methods
, FALSE
);
9352 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->flags
, FALSE
);
9353 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->opts
, FALSE
);
9354 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->simd_opts
, FALSE
);
9355 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->gc_name_index
, FALSE
);
9356 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->num_rgctx_fetch_trampolines
, FALSE
);
9357 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->double_align
, FALSE
);
9358 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->long_align
, FALSE
);
9359 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->generic_tramp_num
, FALSE
);
9360 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->card_table_shift_bits
, FALSE
);
9361 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->card_table_mask
, FALSE
);
9362 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->tramp_page_size
, FALSE
);
9363 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nshared_got_entries
, FALSE
);
9364 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->datafile_size
, FALSE
);
9365 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), module
->unbox_tramp_num
, FALSE
);
9366 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), module
->unbox_tramp_elemsize
, FALSE
);
9368 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->table_offsets
, MONO_AOT_TABLE_NUM
);
9369 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->num_trampolines
, MONO_AOT_TRAMP_NUM
);
9370 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_got_offset_base
, MONO_AOT_TRAMP_NUM
);
9371 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_size
, MONO_AOT_TRAMP_NUM
);
9372 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->tramp_page_code_offsets
, MONO_AOT_TRAMP_NUM
);
9374 fields
[tindex
++] = llvm_array_from_bytes (info
->aotid
, 16);
9375 g_assert (tindex
== nfields
);
9377 LLVMSetInitializer (info_var
, LLVMConstNamedStruct (file_info_type
, fields
, nfields
));
9379 if (module
->static_link
) {
9383 s
= g_strdup_printf ("mono_aot_module_%s_info", module
->assembly
->aname
.name
);
9384 /* Get rid of characters which cannot occur in symbols */
9386 for (p
= s
; *p
; ++p
) {
9387 if (!(isalnum (*p
) || *p
== '_'))
9390 var
= LLVMAddGlobal (module
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), s
);
9392 LLVMSetInitializer (var
, LLVMConstBitCast (LLVMGetNamedGlobal (module
->lmodule
, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
9393 LLVMSetLinkage (var
, LLVMExternalLinkage
);
9398 LLVMValueRef lmethod
;
9400 } NonnullPropWorkItem
;
9403 mono_llvm_nonnull_state_update (EmitContext
*ctx
, LLVMValueRef lcall
, MonoMethod
*call_method
, LLVMValueRef
*args
, int num_params
)
9405 #if LLVM_API_VERSION > 100
9406 if (!ctx
->module
->llvm_disable_self_init
&& mono_aot_can_specialize (call_method
)) {
9407 int num_passed
= LLVMGetNumArgOperands (lcall
);
9408 g_assert (num_params
<= num_passed
);
9410 g_assert (ctx
->module
->method_to_call_info
);
9411 GArray
*call_site_union
= (GArray
*) g_hash_table_lookup (ctx
->module
->method_to_call_info
, call_method
);
9413 if (!call_site_union
) {
9414 call_site_union
= g_array_sized_new (FALSE
, TRUE
, sizeof (gint32
), num_params
);
9416 for (int i
= 0; i
< num_params
; i
++)
9417 g_array_insert_val (call_site_union
, i
, zero
);
9420 for (int i
= 0; i
< num_params
; i
++) {
9421 if (mono_llvm_is_nonnull (args
[i
])) {
9422 g_assert (i
< LLVMGetNumArgOperands (lcall
));
9423 mono_llvm_set_call_nonnull_arg (lcall
, i
);
9425 gint32
*nullable_count
= &g_array_index (call_site_union
, gint32
, i
);
9426 *nullable_count
= *nullable_count
+ 1;
9430 g_hash_table_insert (ctx
->module
->method_to_call_info
, call_method
, call_site_union
);
9436 mono_llvm_propagate_nonnull_final (GHashTable
*all_specializable
, MonoLLVMModule
*module
)
9438 #if LLVM_API_VERSION > 100
9439 // When we first traverse the mini IL, we mark the things that are
9440 // nonnull (the roots). Then, for all of the methods that can be specialized, we
9441 // see if their call sites have nonnull attributes.
9443 // If so, we mark the function's param. This param has uses to propagate
9444 // the attribute to. This propagation can trigger a need to mark more attributes
9445 // non-null, and so on and so forth.
9446 GSList
*queue
= NULL
;
9448 GHashTableIter iter
;
9449 LLVMValueRef lmethod
;
9451 g_hash_table_iter_init (&iter
, all_specializable
);
9452 while (g_hash_table_iter_next (&iter
, (void**)&lmethod
, (void**)&method
)) {
9453 GArray
*call_site_union
= (GArray
*) g_hash_table_lookup (module
->method_to_call_info
, method
);
9455 // Basic sanity checking
9456 if (call_site_union
)
9457 g_assert (call_site_union
->len
== LLVMCountParams (lmethod
));
9459 // Add root to work queue
9460 for (int i
= 0; call_site_union
&& i
< call_site_union
->len
; i
++) {
9461 if (g_array_index (call_site_union
, gint32
, i
) == 0) {
9462 NonnullPropWorkItem
*item
= g_malloc (sizeof (NonnullPropWorkItem
));
9463 item
->lmethod
= lmethod
;
9465 queue
= g_slist_prepend (queue
, item
);
9470 // This is essentially reference counting, and we are propagating
9471 // the refcount decrement here. We have less work to do than we may otherwise
9472 // because we are only working with a set of subgraphs of specializable functions.
9474 // We rely on being able to see all of the references in the graph.
9475 // This is ensured by the function mono_aot_can_specialize. Everything in
9476 // all_specializable is a function that can be specialized, and is the resulting
9477 // node in the graph after all of the subsitutions are done.
9479 // Anything disrupting the direct calls made with self-init will break this optimization.
9482 // Update the queue state.
9483 // Our only other per-iteration responsibility is now to free current
9484 NonnullPropWorkItem
*current
= (NonnullPropWorkItem
*) queue
->data
;
9485 queue
= queue
->next
;
9486 g_assert (current
->argument
< LLVMCountParams (current
->lmethod
));
9488 // Does the actual leaf-node work here
9489 // Mark the function argument as nonnull for LLVM
9490 mono_llvm_set_func_nonnull_arg (current
->lmethod
, current
->argument
);
9492 // The rest of this is for propagating forward nullability changes
9493 // to calls that use the argument that is now nullable.
9495 // Get the actual LLVM value of the argument, so we can see which call instructions
9496 // used that argument
9497 LLVMValueRef caller_argument
= LLVMGetParam (current
->lmethod
, current
->argument
);
9499 // Iterate over the calls using the newly-non-nullable argument
9500 GSList
*calls
= mono_llvm_calls_using (caller_argument
);
9501 for (GSList
*cursor
= calls
; cursor
!= NULL
; cursor
= cursor
->next
) {
9503 LLVMValueRef lcall
= (LLVMValueRef
) cursor
->data
;
9504 LLVMValueRef callee_lmethod
= LLVMGetCalledValue (lcall
);
9506 // If this wasn't a direct call for which mono_aot_can_specialize is true,
9507 // this lookup won't find a MonoMethod.
9508 MonoMethod
*callee_method
= (MonoMethod
*) g_hash_table_lookup (all_specializable
, callee_lmethod
);
9512 // Decrement number of nullable refs at that func's arg offset
9513 GArray
*call_site_union
= (GArray
*) g_hash_table_lookup (module
->method_to_call_info
, callee_method
);
9515 // It has module-local callers and is specializable, should have seen this call site
9517 g_assert (call_site_union
);
9519 // The function *definition* parameter arity should always be consistent
9520 int max_params
= LLVMCountParams (callee_lmethod
);
9521 if (call_site_union
->len
!= max_params
) {
9522 mono_llvm_dump_value (callee_lmethod
);
9523 g_assert_not_reached ();
9526 // Get the values that correspond to the parameters passed to the call
9527 // that used our argument
9528 LLVMValueRef
*operands
= mono_llvm_call_args (lcall
);
9529 for (int call_argument
= 0; call_argument
< max_params
; call_argument
++) {
9530 // Every time we used the newly-non-nullable argument, decrement the nullable
9531 // refcount for that function.
9532 if (caller_argument
== operands
[call_argument
]) {
9533 gint32
*nullable_count
= &g_array_index (call_site_union
, gint32
, call_argument
);
9534 g_assert (*nullable_count
> 0);
9535 *nullable_count
= *nullable_count
- 1;
9537 // If we caused that callee's parameter to become newly nullable, add to work queue
9538 if (*nullable_count
== 0) {
9539 NonnullPropWorkItem
*item
= g_malloc (sizeof (NonnullPropWorkItem
));
9540 item
->lmethod
= callee_lmethod
;
9541 item
->argument
= call_argument
;
9542 queue
= g_slist_prepend (queue
, item
);
9548 // Update nullability refcount information for the callee now
9549 g_hash_table_insert (module
->method_to_call_info
, callee_method
, call_site_union
);
9551 g_slist_free (calls
);
9559 * Emit the aot module into the LLVM bitcode file FILENAME.
9562 mono_llvm_emit_aot_module (const char *filename
, const char *cu_name
)
9564 LLVMTypeRef got_type
, inited_type
;
9565 LLVMValueRef real_got
, real_inited
;
9566 MonoLLVMModule
*module
= &aot_module
;
9568 emit_llvm_code_end (module
);
9571 * Create the real got variable and replace all uses of the dummy variable with
9574 int size
= module
->max_got_offset
+ 1;
9575 LLVMTypeRef
*members
= g_malloc0 (sizeof (LLVMValueRef
) * size
);
9576 for (int i
= 0; i
< size
; i
++) {
9577 LLVMTypeRef lookup_type
= NULL
;
9579 lookup_type
= g_hash_table_lookup (module
->got_idx_to_type
, GINT_TO_POINTER (i
));
9582 lookup_type
= module
->ptr_type
;
9584 members
[i
] = LLVMPointerType (lookup_type
, 0);
9587 got_type
= LLVMStructCreateNamed (module
->context
, g_strdup_printf ("MONO_GOT_%s", cu_name
));
9588 LLVMStructSetBody (got_type
, members
, size
, FALSE
);
9589 real_got
= LLVMAddGlobal (module
->lmodule
, got_type
, module
->got_symbol
);
9591 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
9592 if (module
->external_symbols
) {
9593 LLVMSetLinkage (real_got
, LLVMExternalLinkage
);
9594 LLVMSetVisibility (real_got
, LLVMHiddenVisibility
);
9596 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
9598 mono_llvm_replace_uses_of (module
->got_var
, real_got
);
9600 mark_as_used (&aot_module
, real_got
);
9602 /* Delete the dummy got so it doesn't become a global */
9603 LLVMDeleteGlobal (module
->got_var
);
9604 module
->got_var
= real_got
;
9607 * Same for the init_var
9609 if (!module
->llvm_disable_self_init
) {
9610 inited_type
= LLVMArrayType (LLVMInt8Type (), module
->max_inited_idx
+ 1);
9611 real_inited
= LLVMAddGlobal (module
->lmodule
, inited_type
, "mono_inited");
9612 LLVMSetInitializer (real_inited
, LLVMConstNull (inited_type
));
9613 LLVMSetLinkage (real_inited
, LLVMInternalLinkage
);
9614 mono_llvm_replace_uses_of (module
->inited_var
, real_inited
);
9615 LLVMDeleteGlobal (module
->inited_var
);
9617 emit_get_method (&aot_module
);
9618 emit_get_unbox_tramp (&aot_module
);
9621 emit_llvm_used (&aot_module
);
9622 emit_dbg_info (&aot_module
, filename
, cu_name
);
9623 emit_aot_file_info (&aot_module
);
9625 /* Replace PLT entries for directly callable methods with the methods themselves */
9627 GHashTableIter iter
;
9629 LLVMValueRef callee
;
9631 GHashTable
*specializable
= g_hash_table_new (NULL
, NULL
);
9633 g_hash_table_iter_init (&iter
, module
->plt_entries_ji
);
9634 while (g_hash_table_iter_next (&iter
, (void**)&ji
, (void**)&callee
)) {
9635 if (mono_aot_is_direct_callable (ji
)) {
9636 LLVMValueRef lmethod
;
9638 lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, ji
->data
.method
);
9639 /* The types might not match because the caller might pass an rgctx */
9640 if (lmethod
&& LLVMTypeOf (callee
) == LLVMTypeOf (lmethod
)) {
9641 mono_llvm_replace_uses_of (callee
, lmethod
);
9643 if (!module
->llvm_disable_self_init
&& mono_aot_can_specialize (ji
->data
.method
))
9644 g_hash_table_insert (specializable
, lmethod
, ji
->data
.method
);
9645 mono_aot_mark_unused_llvm_plt_entry (ji
);
9650 mono_llvm_propagate_nonnull_final (specializable
, module
);
9652 g_hash_table_destroy (specializable
);
9655 /* Note: You can still dump an invalid bitcode file by running `llvm-dis`
9656 * in a debugger, set a breakpoint on `LLVMVerifyModule` and fake its
9657 * result to 0 (indicating success). */
9658 LLVMWriteBitcodeToFile (module
->lmodule
, filename
);
9664 if (LLVMVerifyModule (module
->lmodule
, LLVMReturnStatusAction
, &verifier_err
)) {
9665 printf ("%s\n", verifier_err
);
9666 g_assert_not_reached ();
9674 md_string (const char *s
)
9676 return LLVMMDString (s
, strlen (s
));
9679 /* Debugging support */
9682 emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
)
9684 LLVMModuleRef lmodule
= module
->lmodule
;
9685 LLVMValueRef args
[16], ver
;
9688 * This can only be enabled when LLVM code is emitted into a separate object
9689 * file, since the AOT compiler also emits dwarf info,
9690 * and the abbrev indexes will not be correct since llvm has added its own
9693 if (!module
->emit_dwarf
)
9696 #if LLVM_API_VERSION > 100
9697 mono_llvm_di_builder_finalize (module
->di_builder
);
9699 LLVMValueRef cu_args
[16], cu
;
9701 char *build_info
, *s
, *dir
;
9704 * Emit dwarf info in the form of LLVM metadata. There is some
9705 * out-of-date documentation at:
9706 * http://llvm.org/docs/SourceLevelDebugging.html
9707 * but most of this was gathered from the llvm and
9712 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit
, FALSE
);
9713 /* CU name/compilation dir */
9714 dir
= g_path_get_dirname (filename
);
9715 args
[0] = LLVMMDString (cu_name
, strlen (cu_name
));
9716 args
[1] = LLVMMDString (dir
, strlen (dir
));
9717 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 2);
9720 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99
, FALSE
);
9722 build_info
= mono_get_runtime_build_info ();
9723 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
9724 cu_args
[n_cuargs
++] = LLVMMDString (s
, strlen (s
));
9725 g_free (build_info
);
9727 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9729 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
9730 /* Runtime version */
9731 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9733 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9734 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9736 if (module
->subprogram_mds
) {
9740 mds
= g_new0 (LLVMValueRef
, module
->subprogram_mds
->len
);
9741 for (i
= 0; i
< module
->subprogram_mds
->len
; ++i
)
9742 mds
[i
] = (LLVMValueRef
)g_ptr_array_index (module
->subprogram_mds
, i
);
9743 cu_args
[n_cuargs
++] = LLVMMDNode (mds
, module
->subprogram_mds
->len
);
9745 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9748 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9749 /* Imported modules */
9750 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
9752 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
9753 /* DebugEmissionKind = FullDebug */
9754 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9755 cu
= LLVMMDNode (cu_args
, n_cuargs
);
9756 LLVMAddNamedMetadataOperand (lmodule
, "llvm.dbg.cu", cu
);
9759 #if LLVM_API_VERSION > 100
9760 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9761 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9762 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9763 ver
= LLVMMDNode (args
, 3);
9764 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9766 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9767 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9768 args
[2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE
);
9769 ver
= LLVMMDNode (args
, 3);
9770 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9772 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9773 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9774 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9775 ver
= LLVMMDNode (args
, 3);
9776 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9778 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9779 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9780 args
[2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9781 ver
= LLVMMDNode (args
, 3);
9782 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9787 emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
)
9789 MonoLLVMModule
*module
= ctx
->module
;
9790 MonoDebugMethodInfo
*minfo
= ctx
->minfo
;
9791 char *source_file
, *dir
, *filename
;
9792 LLVMValueRef md
, args
[16], ctx_args
[16], md_args
[64], type_args
[16], ctx_md
, type_md
;
9793 MonoSymSeqPoint
*sym_seq_points
;
9799 mono_debug_get_seq_points (minfo
, &source_file
, NULL
, NULL
, &sym_seq_points
, &n_seq_points
);
9801 source_file
= g_strdup ("<unknown>");
9802 dir
= g_path_get_dirname (source_file
);
9803 filename
= g_path_get_basename (source_file
);
9805 #if LLVM_API_VERSION > 100
9806 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);
9809 ctx_args
[0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE
);
9810 args
[0] = md_string (filename
);
9811 args
[1] = md_string (dir
);
9812 ctx_args
[1] = LLVMMDNode (args
, 2);
9813 ctx_md
= LLVMMDNode (ctx_args
, 2);
9815 type_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type
, FALSE
);
9816 type_args
[1] = NULL
;
9817 type_args
[2] = NULL
;
9818 type_args
[3] = LLVMMDString ("", 0);
9819 type_args
[4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9820 type_args
[5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9821 type_args
[6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9822 type_args
[7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9823 type_args
[8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9824 type_args
[9] = NULL
;
9825 type_args
[10] = NULL
;
9826 type_args
[11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9827 type_args
[12] = NULL
;
9828 type_args
[13] = NULL
;
9829 type_args
[14] = NULL
;
9830 type_md
= LLVMMDNode (type_args
, 14);
9832 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9833 md_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram
, FALSE
);
9834 /* Source directory + file pair */
9835 args
[0] = md_string (filename
);
9836 args
[1] = md_string (dir
);
9837 md_args
[1] = LLVMMDNode (args
,2);
9838 md_args
[2] = ctx_md
;
9839 md_args
[3] = md_string (cfg
->method
->name
);
9840 md_args
[4] = md_string (name
);
9841 md_args
[5] = md_string (name
);
9844 md_args
[6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points
[0].line
, FALSE
);
9846 md_args
[6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9848 md_args
[7] = type_md
;
9850 md_args
[8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
9852 md_args
[9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
9854 md_args
[10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9855 /* Index into a virtual function */
9856 md_args
[11] = NULL
;
9857 md_args
[12] = NULL
;
9859 md_args
[13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
9861 md_args
[14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
9862 /* Pointer to LLVM function */
9863 md_args
[15] = method
;
9864 /* Function template parameter */
9865 md_args
[16] = NULL
;
9866 /* Function declaration descriptor */
9867 md_args
[17] = NULL
;
9868 /* List of function variables */
9869 md_args
[18] = LLVMMDNode (args
, 0);
9871 md_args
[19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9872 md
= LLVMMDNode (md_args
, 20);
9874 if (!module
->subprogram_mds
)
9875 module
->subprogram_mds
= g_ptr_array_new ();
9876 g_ptr_array_add (module
->subprogram_mds
, md
);
9880 g_free (source_file
);
9881 g_free (sym_seq_points
);
9887 emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
)
9889 MonoCompile
*cfg
= ctx
->cfg
;
9891 if (ctx
->minfo
&& cil_code
&& cil_code
>= cfg
->header
->code
&& cil_code
< cfg
->header
->code
+ cfg
->header
->code_size
) {
9892 MonoDebugSourceLocation
*loc
;
9893 LLVMValueRef loc_md
;
9895 loc
= mono_debug_method_lookup_location (ctx
->minfo
, cil_code
- cfg
->header
->code
);
9898 #if LLVM_API_VERSION > 100
9899 loc_md
= (LLVMValueRef
)mono_llvm_di_create_location (ctx
->module
->di_builder
, ctx
->dbg_md
, loc
->row
, loc
->column
);
9900 mono_llvm_di_set_location (builder
, loc_md
);
9902 LLVMValueRef md_args
[16];
9906 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->row
, FALSE
);
9907 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->column
, FALSE
);
9908 md_args
[nmd_args
++] = ctx
->dbg_md
;
9909 md_args
[nmd_args
++] = NULL
;
9910 loc_md
= LLVMMDNode (md_args
, nmd_args
);
9911 LLVMSetCurrentDebugLocation (builder
, loc_md
);
9913 mono_debug_free_source_location (loc
);
9919 emit_default_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
)
9921 #if LLVM_API_VERSION > 100
9923 LLVMValueRef loc_md
;
9924 loc_md
= (LLVMValueRef
)mono_llvm_di_create_location (ctx
->module
->di_builder
, ctx
->dbg_md
, 0, 0);
9925 mono_llvm_di_set_location (builder
, loc_md
);
9928 /* Older llvm versions don't require this */
9934 - Emit LLVM IR from the mono IR using the LLVM C API.
9935 - The original arch specific code remains, so we can fall back to it if we run
9936 into something we can't handle.
9940 A partial list of issues:
9941 - Handling of opcodes which can throw exceptions.
9943 In the mono JIT, these are implemented using code like this:
9950 push throw_pos - method
9951 call <exception trampoline>
9953 The problematic part is push throw_pos - method, which cannot be represented
9954 in the LLVM IR, since it does not support label values.
9955 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9956 be implemented in JIT mode ?
9957 -> a possible but slower implementation would use the normal exception
9958 throwing code but it would need to control the placement of the throw code
9959 (it needs to be exactly after the compare+branch).
9960 -> perhaps add a PC offset intrinsics ?
9962 - efficient implementation of .ovf opcodes.
9964 These are currently implemented as:
9965 <ins which sets the condition codes>
9968 Some overflow opcodes are now supported by LLVM SVN.
9970 - exception handling, unwinding.
9971 - SSA is disabled for methods with exception handlers
9972 - How to obtain unwind info for LLVM compiled methods ?
9973 -> this is now solved by converting the unwind info generated by LLVM
9975 - LLVM uses the c++ exception handling framework, while we use our home grown
9976 code, and couldn't use the c++ one:
9977 - its not supported under VC++, other exotic platforms.
9978 - it might be impossible to support filter clauses with it.
9982 The trampolines need a predictable call sequence, since they need to disasm
9983 the calling code to obtain register numbers / offsets.
9985 LLVM currently generates this code in non-JIT mode:
9986 mov -0x98(%rax),%eax
9988 Here, the vtable pointer is lost.
9989 -> solution: use one vtable trampoline per class.
9991 - passing/receiving the IMT pointer/RGCTX.
9992 -> solution: pass them as normal arguments ?
9996 LLVM does not allow the specification of argument registers etc. This means
9997 that all calls are made according to the platform ABI.
9999 - passing/receiving vtypes.
10001 Vtypes passed/received in registers are handled by the front end by using
10002 a signature with scalar arguments, and loading the parts of the vtype into those
10005 Vtypes passed on the stack are handled using the 'byval' attribute.
10009 Supported though alloca, we need to emit the load/store code.
10013 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
10014 typed registers, so we have to keep track of the precise LLVM type of each vreg.
10015 This is made easier because the IR is already in SSA form.
10016 An additional problem is that our IR is not consistent with types, i.e. i32/i64
10017 types are frequently used incorrectly.
10022 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
10023 it with the file containing the methods emitted by the JIT and the AOT data
10027 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
10028 * - each bblock should end with a branch
10029 * - setting the return value, making cfg->ret non-volatile
10030 * - avoid some transformations in the JIT which make it harder for us to generate
10032 * - use pointer types to help optimizations.
10035 #else /* DISABLE_JIT */
10038 mono_llvm_cleanup (void)
10043 mono_llvm_free_domain_info (MonoDomain
*domain
)
10048 mono_llvm_init (void)
10052 #endif /* DISABLE_JIT */
10054 #if !defined(DISABLE_JIT) && !defined(MONO_CROSS_COMPILE)
10056 /* LLVM JIT support */
10058 static unsigned char*
10059 alloc_cb (LLVMValueRef function
, int size
)
10063 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
10067 return (unsigned char*)mono_domain_code_reserve (cfg
->domain
, size
);
10069 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size
);
10074 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
10078 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
10080 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
10084 exception_cb (void *data
)
10087 MonoJitExceptionInfo
*ei
;
10088 guint32 ei_len
, i
, j
, nested_len
, nindex
;
10089 gpointer
*type_info
;
10090 int this_reg
, this_offset
;
10092 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
10096 * data points to a DWARF FDE structure, convert it to our unwind format and
10098 * An alternative would be to save it directly, and modify our unwinder to work
10101 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
);
10102 if (cfg
->verbose_level
> 1)
10103 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
10105 /* Count nested clauses */
10107 for (i
= 0; i
< ei_len
; ++i
) {
10108 gint32 cindex1
= *(gint32
*)type_info
[i
];
10109 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
10111 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
10113 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
10115 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
10121 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
10122 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
10123 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
10124 /* Fill the rest of the information from the type info */
10125 for (i
= 0; i
< ei_len
; ++i
) {
10126 gint32 clause_index
= *(gint32
*)type_info
[i
];
10127 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
10129 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
10130 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
10131 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
10135 * For nested clauses, the LLVM produced exception info associates the try interval with
10136 * the innermost handler, while mono expects it to be associated with all nesting clauses.
10137 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
10138 * and everything else from the nested clause.
10141 for (i
= 0; i
< ei_len
; ++i
) {
10142 gint32 cindex1
= *(gint32
*)type_info
[i
];
10143 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
10145 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
10147 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
10148 MonoJitExceptionInfo
*nesting_ei
, *nested_ei
;
10150 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
10151 /* clause1 is the nested clause */
10152 nested_ei
= &cfg
->llvm_ex_info
[i
];
10153 nesting_ei
= &cfg
->llvm_ex_info
[nindex
];
10156 memcpy (nesting_ei
, nested_ei
, sizeof (MonoJitExceptionInfo
));
10158 nesting_ei
->flags
= clause2
->flags
;
10159 nesting_ei
->data
.catch_class
= clause2
->data
.catch_class
;
10160 nesting_ei
->clause_index
= cindex2
;
10164 g_assert (nindex
== ei_len
+ nested_len
);
10165 cfg
->llvm_this_reg
= this_reg
;
10166 cfg
->llvm_this_offset
= this_offset
;
10168 /* type_info [i] is cfg mempool allocated, no need to free it */
10171 g_free (type_info
);
10175 * decode_llvm_eh_info:
10177 * Decode the EH table emitted by llvm in jit mode, and store
10178 * the result into cfg.
10181 decode_llvm_eh_info (EmitContext
*ctx
, gpointer eh_frame
)
10183 MonoCompile
*cfg
= ctx
->cfg
;
10186 MonoLLVMFDEInfo info
;
10187 MonoJitExceptionInfo
*ei
;
10188 guint8
*p
= (guint8
*)eh_frame
;
10189 int version
, fde_count
, fde_offset
;
10190 guint32 ei_len
, i
, nested_len
;
10191 gpointer
*type_info
;
10196 * Decode the one element EH table emitted by the MonoException class
10200 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
10203 g_assert (version
== 3);
10206 p
= (guint8
*)ALIGN_PTR_TO (p
, 4);
10208 fde_count
= *(guint32
*)p
;
10210 table
= (gint32
*)p
;
10212 g_assert (fde_count
<= 2);
10214 /* The first entry is the real method */
10215 g_assert (table
[0] == 1);
10216 fde_offset
= table
[1];
10217 table
+= fde_count
* 2;
10219 cfg
->code_len
= table
[0];
10220 fde_len
= table
[1] - fde_offset
;
10223 fde
= (guint8
*)eh_frame
+ fde_offset
;
10224 cie
= (guint8
*)table
;
10226 /* Compute lengths */
10227 mono_unwind_decode_llvm_mono_fde (fde
, fde_len
, cie
, cfg
->native_code
, &info
, NULL
, NULL
, NULL
);
10229 ei
= (MonoJitExceptionInfo
*)g_malloc0 (info
.ex_info_len
* sizeof (MonoJitExceptionInfo
));
10230 type_info
= (gpointer
*)g_malloc0 (info
.ex_info_len
* sizeof (gpointer
));
10231 unw_info
= (guint8
*)g_malloc0 (info
.unw_info_len
);
10233 mono_unwind_decode_llvm_mono_fde (fde
, fde_len
, cie
, cfg
->native_code
, &info
, ei
, type_info
, unw_info
);
10235 cfg
->encoded_unwind_ops
= unw_info
;
10236 cfg
->encoded_unwind_ops_len
= info
.unw_info_len
;
10237 if (cfg
->verbose_level
> 1)
10238 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
10239 if (info
.this_reg
!= -1) {
10240 cfg
->llvm_this_reg
= info
.this_reg
;
10241 cfg
->llvm_this_offset
= info
.this_offset
;
10244 ei_len
= info
.ex_info_len
;
10246 // Nested clauses are currently disabled
10249 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
10250 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
10251 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
10252 /* Fill the rest of the information from the type info */
10253 for (i
= 0; i
< ei_len
; ++i
) {
10254 gint32 clause_index
= *(gint32
*)type_info
[i
];
10255 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
10257 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
10258 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
10259 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
10264 init_jit_module (MonoDomain
*domain
)
10266 MonoJitDomainInfo
*dinfo
;
10267 MonoLLVMModule
*module
;
10270 dinfo
= domain_jit_info (domain
);
10271 if (dinfo
->llvm_module
)
10274 mono_loader_lock ();
10276 if (dinfo
->llvm_module
) {
10277 mono_loader_unlock ();
10281 module
= g_new0 (MonoLLVMModule
, 1);
10283 name
= g_strdup_printf ("mono-%s", domain
->friendly_name
);
10284 module
->lmodule
= LLVMModuleCreateWithName (name
);
10285 module
->context
= LLVMGetGlobalContext ();
10286 module
->intrins_by_id
= g_new0 (LLVMValueRef
, INTRINS_NUM
);
10288 module
->mono_ee
= (MonoEERef
*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module
->lmodule
), alloc_cb
, emitted_cb
, exception_cb
, &module
->ee
);
10290 add_intrinsics (module
->lmodule
);
10291 add_types (module
);
10293 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
10295 mono_memory_barrier ();
10297 dinfo
->llvm_module
= module
;
10299 mono_loader_unlock ();
10303 llvm_jit_finalize_method (EmitContext
*ctx
)
10305 MonoCompile
*cfg
= ctx
->cfg
;
10306 MonoDomain
*domain
= mono_domain_get ();
10307 MonoJitDomainInfo
*domain_info
;
10308 int nvars
= g_hash_table_size (ctx
->jit_callees
);
10309 LLVMValueRef
*callee_vars
= g_new0 (LLVMValueRef
, nvars
);
10310 gpointer
*callee_addrs
= g_new0 (gpointer
, nvars
);
10311 GHashTableIter iter
;
10313 MonoMethod
*callee
;
10318 * Compute the addresses of the LLVM globals pointing to the
10319 * methods called by the current method. Pass it to the trampoline
10320 * code so it can update them after their corresponding method was
10323 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
10325 while (g_hash_table_iter_next (&iter
, NULL
, (void**)&var
))
10326 callee_vars
[i
++] = var
;
10328 cfg
->native_code
= (guint8
*)mono_llvm_compile_method (ctx
->module
->mono_ee
, ctx
->lmethod
, nvars
, callee_vars
, callee_addrs
, &eh_frame
);
10330 decode_llvm_eh_info (ctx
, eh_frame
);
10332 mono_domain_lock (domain
);
10333 domain_info
= domain_jit_info (domain
);
10334 if (!domain_info
->llvm_jit_callees
)
10335 domain_info
->llvm_jit_callees
= g_hash_table_new (NULL
, NULL
);
10336 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
10338 while (g_hash_table_iter_next (&iter
, (void**)&callee
, (void**)&var
)) {
10339 GSList
*addrs
= (GSList
*)g_hash_table_lookup (domain_info
->llvm_jit_callees
, callee
);
10340 addrs
= g_slist_prepend (addrs
, callee_addrs
[i
]);
10341 g_hash_table_insert (domain_info
->llvm_jit_callees
, callee
, addrs
);
10344 mono_domain_unlock (domain
);
10350 init_jit_module (MonoDomain
*domain
)
10352 g_assert_not_reached ();
10356 llvm_jit_finalize_method (EmitContext
*ctx
)
10358 g_assert_not_reached ();