2 // mini-llvm-cpp.cpp: C++ support classes for the mono LLVM integration
4 // (C) 2009-2011 Novell, Inc.
5 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
6 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 // We need to override some stuff in LLVM, but this cannot be done using the C
11 // interface, so we have to use some C++ code here.
12 // The things which we override are:
13 // - the default JIT code manager used by LLVM doesn't allocate memory using
14 // MAP_32BIT, we require it.
15 // - add some callbacks so we can obtain the size of methods and their exception
20 // Mono's internal header files are not C++ clean, so avoid including them if
25 // Disable warnings generated by LLVM headers.
26 #pragma warning(disable:4141) // modifier' : used more than once
27 #pragma warning(disable:4800) // type' : forcing value to bool 'true' or 'false' (performance warning)
34 #include <llvm/Support/raw_ostream.h>
35 #include <llvm/IR/Function.h>
36 #include <llvm/IR/IRBuilder.h>
37 #include <llvm/IR/Module.h>
38 #include <llvm/IR/DIBuilder.h>
39 #include <llvm/IR/CallSite.h>
40 #include <llvm/IR/MDBuilder.h>
42 #include "mini-llvm-cpp.h"
46 #define Acquire AtomicOrdering::Acquire
47 #define Release AtomicOrdering::Release
48 #define SequentiallyConsistent AtomicOrdering::SequentiallyConsistent
51 mono_llvm_dump_value (LLVMValueRef value
)
53 /* Same as LLVMDumpValue (), but print to stdout */
54 outs () << (*unwrap
<Value
> (value
)) << "\n";
59 mono_llvm_dump_module (LLVMModuleRef module
)
61 /* Same as LLVMDumpModule (), but print to stdout */
62 outs () << (*unwrap (module
));
66 /* Missing overload for building an alloca with an alignment */
68 mono_llvm_build_alloca (LLVMBuilderRef builder
, LLVMTypeRef Ty
,
69 LLVMValueRef ArraySize
,
70 int alignment
, const char *Name
)
72 return wrap (unwrap (builder
)->Insert (new AllocaInst (unwrap (Ty
), 0, unwrap (ArraySize
), alignment
), Name
));
76 mono_llvm_build_load (LLVMBuilderRef builder
, LLVMValueRef PointerVal
,
77 const char *Name
, gboolean is_volatile
)
79 LoadInst
*ins
= unwrap(builder
)->CreateLoad(unwrap(PointerVal
), is_volatile
, Name
);
85 mono_llvm_build_atomic_load (LLVMBuilderRef builder
, LLVMValueRef PointerVal
,
86 const char *Name
, gboolean is_volatile
, int alignment
, BarrierKind barrier
)
88 LoadInst
*ins
= unwrap(builder
)->CreateLoad(unwrap(PointerVal
), is_volatile
, Name
);
90 ins
->setAlignment (alignment
);
92 case LLVM_BARRIER_NONE
:
94 case LLVM_BARRIER_ACQ
:
95 ins
->setOrdering(Acquire
);
97 case LLVM_BARRIER_SEQ
:
98 ins
->setOrdering(SequentiallyConsistent
);
101 g_assert_not_reached ();
109 mono_llvm_build_aligned_load (LLVMBuilderRef builder
, LLVMValueRef PointerVal
,
110 const char *Name
, gboolean is_volatile
, int alignment
)
114 ins
= unwrap(builder
)->CreateLoad(unwrap(PointerVal
), is_volatile
, Name
);
115 ins
->setAlignment (alignment
);
121 mono_llvm_build_store (LLVMBuilderRef builder
, LLVMValueRef Val
, LLVMValueRef PointerVal
,
122 gboolean is_volatile
, BarrierKind barrier
)
124 StoreInst
*ins
= unwrap(builder
)->CreateStore(unwrap(Val
), unwrap(PointerVal
), is_volatile
);
127 case LLVM_BARRIER_NONE
:
129 case LLVM_BARRIER_REL
:
130 ins
->setOrdering(Release
);
132 case LLVM_BARRIER_SEQ
:
133 ins
->setOrdering(SequentiallyConsistent
);
136 g_assert_not_reached ();
144 mono_llvm_build_aligned_store (LLVMBuilderRef builder
, LLVMValueRef Val
, LLVMValueRef PointerVal
,
145 gboolean is_volatile
, int alignment
)
149 ins
= unwrap(builder
)->CreateStore(unwrap(Val
), unwrap(PointerVal
), is_volatile
);
150 ins
->setAlignment (alignment
);
156 mono_llvm_build_cmpxchg (LLVMBuilderRef builder
, LLVMValueRef ptr
, LLVMValueRef cmp
, LLVMValueRef val
)
158 AtomicCmpXchgInst
*ins
;
160 ins
= unwrap(builder
)->CreateAtomicCmpXchg (unwrap(ptr
), unwrap (cmp
), unwrap (val
), SequentiallyConsistent
, SequentiallyConsistent
);
165 mono_llvm_build_atomic_rmw (LLVMBuilderRef builder
, AtomicRMWOp op
, LLVMValueRef ptr
, LLVMValueRef val
)
167 AtomicRMWInst::BinOp aop
= AtomicRMWInst::Xchg
;
171 case LLVM_ATOMICRMW_OP_XCHG
:
172 aop
= AtomicRMWInst::Xchg
;
174 case LLVM_ATOMICRMW_OP_ADD
:
175 aop
= AtomicRMWInst::Add
;
178 g_assert_not_reached ();
182 ins
= unwrap (builder
)->CreateAtomicRMW (aop
, unwrap (ptr
), unwrap (val
), SequentiallyConsistent
);
187 mono_llvm_build_fence (LLVMBuilderRef builder
, BarrierKind kind
)
190 AtomicOrdering ordering
;
192 g_assert (kind
!= LLVM_BARRIER_NONE
);
195 case LLVM_BARRIER_ACQ
:
198 case LLVM_BARRIER_REL
:
201 case LLVM_BARRIER_SEQ
:
202 ordering
= SequentiallyConsistent
;
205 g_assert_not_reached ();
209 ins
= unwrap (builder
)->CreateFence (ordering
);
214 mono_llvm_build_weighted_branch (LLVMBuilderRef builder
, LLVMValueRef cond
, LLVMBasicBlockRef t
, LLVMBasicBlockRef f
, uint32_t t_weight
, uint32_t f_weight
)
216 auto b
= unwrap (builder
);
217 auto &ctx
= b
->getContext ();
219 auto weights
= mdb
.createBranchWeights (t_weight
, f_weight
);
220 auto ins
= b
->CreateCondBr (unwrap (cond
), unwrap (t
), unwrap (f
), weights
);
225 mono_llvm_add_string_metadata (LLVMValueRef insref
, const char* label
, const char* text
)
227 auto ins
= unwrap
<Instruction
> (insref
);
228 auto &ctx
= ins
->getContext ();
229 ins
->setMetadata (label
, MDNode::get (ctx
, MDString::get (ctx
, text
)));
233 mono_llvm_add_range_metadata_i32 (LLVMValueRef insref
, uint64_t min_value
, uint64_t max_value
)
235 auto ins
= unwrap
<Instruction
> (insref
);
236 auto &ctx
= ins
->getContext ();
237 IntegerType
*Int32Ty
= Type::getInt32Ty (ctx
);
238 Metadata
*range_md
[] = {
239 ConstantAsMetadata::get (ConstantInt::get(Int32Ty
, min_value
)),
240 ConstantAsMetadata::get (ConstantInt::get(Int32Ty
, max_value
))};
241 ins
->setMetadata (LLVMContext::MD_range
, MDNode::get (ctx
, range_md
));
245 mono_llvm_set_implicit_branch (LLVMBuilderRef builder
, LLVMValueRef branch
)
247 auto b
= unwrap (builder
);
248 auto &ctx
= b
->getContext ();
249 auto ins
= unwrap
<Instruction
> (branch
);
250 ins
->setMetadata (LLVMContext::MD_make_implicit
, MDNode::get (ctx
, {}));
254 mono_llvm_set_must_tailcall (LLVMValueRef call_ins
)
256 CallInst
*ins
= (CallInst
*)unwrap (call_ins
);
258 ins
->setTailCallKind (CallInst::TailCallKind::TCK_MustTail
);
262 mono_llvm_replace_uses_of (LLVMValueRef var
, LLVMValueRef v
)
264 Value
*V
= ConstantExpr::getTruncOrBitCast (unwrap
<Constant
> (v
), unwrap (var
)->getType ());
265 unwrap (var
)->replaceAllUsesWith (V
);
269 mono_llvm_create_constant_data_array (const uint8_t *data
, int len
)
271 return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data
, len
)));
275 mono_llvm_set_is_constant (LLVMValueRef global_var
)
277 unwrap
<GlobalVariable
>(global_var
)->setConstant (true);
280 // Note that in future versions of LLVM, CallInst and InvokeInst
281 // share a CallBase parent class that would make the below methods
285 mono_llvm_set_call_nonnull_arg (LLVMValueRef wrapped_calli
, int argNo
)
287 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
289 if (isa
<CallInst
> (calli
))
290 dyn_cast
<CallInst
>(calli
)->addParamAttr (argNo
, Attribute::NonNull
);
292 dyn_cast
<InvokeInst
>(calli
)->addParamAttr (argNo
, Attribute::NonNull
);
296 mono_llvm_set_call_nonnull_ret (LLVMValueRef wrapped_calli
)
298 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
300 if (isa
<CallInst
> (calli
))
301 dyn_cast
<CallInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NonNull
);
303 dyn_cast
<InvokeInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NonNull
);
307 mono_llvm_set_func_nonnull_arg (LLVMValueRef func
, int argNo
)
309 unwrap
<Function
>(func
)->addParamAttr (argNo
, Attribute::NonNull
);
313 mono_llvm_can_be_gep (LLVMValueRef base
, LLVMValueRef
* gep_base
, LLVMValueRef
* gep_offset
)
315 #ifdef ENABLE_NETCORE
316 // Look for a pattern like this:
317 // %1 = ptrtoint i8* %gep_base to i64
318 // %2 = add i64 %1, %gep_offset
319 if (Instruction
*base_inst
= dyn_cast
<Instruction
> (unwrap (base
))) {
320 if (base_inst
->getOpcode () == Instruction::Add
) {
321 if (Instruction
*base_ptr_ins
= dyn_cast
<Instruction
> (base_inst
->getOperand (0))) {
322 if (base_ptr_ins
->getOpcode () == Instruction::PtrToInt
) {
323 *gep_base
= wrap (base_ptr_ins
->getOperand (0));
324 *gep_offset
= wrap (base_inst
->getOperand (1));
335 mono_llvm_is_nonnull (LLVMValueRef wrapped
)
337 // Argument to function
338 Value
*val
= unwrap (wrapped
);
341 if (Argument
*arg
= dyn_cast
<Argument
> (val
)) {
342 return arg
->hasNonNullAttr ();
343 } else if (CallInst
*calli
= dyn_cast
<CallInst
> (val
)) {
344 return calli
->hasRetAttr (Attribute::NonNull
);
345 } else if (InvokeInst
*calli
= dyn_cast
<InvokeInst
> (val
)) {
346 return calli
->hasRetAttr (Attribute::NonNull
);
347 } else if (LoadInst
*loadi
= dyn_cast
<LoadInst
> (val
)) {
348 return loadi
->getMetadata("nonnull") != nullptr; // nonnull <index>
349 } else if (Instruction
*inst
= dyn_cast
<Instruction
> (val
)) {
350 // If not a load or a function argument, the only case for us to
351 // consider is that it's a bitcast. If so, recurse on what was casted.
352 if (inst
->getOpcode () == LLVMBitCast
) {
353 val
= inst
->getOperand (0);
366 mono_llvm_calls_using (LLVMValueRef wrapped_local
)
368 GSList
*usages
= NULL
;
369 Value
*local
= unwrap (wrapped_local
);
371 for (User
*user
: local
->users ()) {
372 if (isa
<CallInst
> (user
) || isa
<InvokeInst
> (user
)) {
373 usages
= g_slist_prepend (usages
, wrap (user
));
381 mono_llvm_call_args (LLVMValueRef wrapped_calli
)
383 Value
*calli
= unwrap(wrapped_calli
);
384 CallInst
*call
= dyn_cast
<CallInst
> (calli
);
385 InvokeInst
*invoke
= dyn_cast
<InvokeInst
> (calli
);
386 g_assert (call
|| invoke
);
388 unsigned int numOperands
= 0;
391 numOperands
= call
->getNumArgOperands ();
393 numOperands
= invoke
->getNumArgOperands ();
395 LLVMValueRef
*ret
= g_malloc (sizeof (LLVMValueRef
) * numOperands
);
397 for (int i
=0; i
< numOperands
; i
++) {
399 ret
[i
] = wrap (call
->getArgOperand (i
));
401 ret
[i
] = wrap (invoke
->getArgOperand (i
));
408 mono_llvm_set_call_notailcall (LLVMValueRef func
)
410 unwrap
<CallInst
>(func
)->setTailCallKind (CallInst::TailCallKind::TCK_NoTail
);
414 mono_llvm_set_call_noalias_ret (LLVMValueRef wrapped_calli
)
416 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
418 if (isa
<CallInst
> (calli
))
419 dyn_cast
<CallInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NoAlias
);
421 dyn_cast
<InvokeInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NoAlias
);
424 static Attribute::AttrKind
425 convert_attr (AttrKind kind
)
428 case LLVM_ATTR_NO_UNWIND
:
429 return Attribute::NoUnwind
;
430 case LLVM_ATTR_NO_INLINE
:
431 return Attribute::NoInline
;
432 case LLVM_ATTR_OPTIMIZE_FOR_SIZE
:
433 return Attribute::OptimizeForSize
;
434 case LLVM_ATTR_OPTIMIZE_NONE
:
435 return Attribute::OptimizeNone
;
436 case LLVM_ATTR_IN_REG
:
437 return Attribute::InReg
;
438 case LLVM_ATTR_STRUCT_RET
:
439 return Attribute::StructRet
;
440 case LLVM_ATTR_NO_ALIAS
:
441 return Attribute::NoAlias
;
442 case LLVM_ATTR_BY_VAL
:
443 return Attribute::ByVal
;
444 case LLVM_ATTR_UW_TABLE
:
445 return Attribute::UWTable
;
448 return Attribute::NoUnwind
;
453 mono_llvm_add_func_attr (LLVMValueRef func
, AttrKind kind
)
455 unwrap
<Function
> (func
)->addAttribute (AttributeList::FunctionIndex
, convert_attr (kind
));
459 mono_llvm_add_param_attr (LLVMValueRef param
, AttrKind kind
)
461 Function
*func
= unwrap
<Argument
> (param
)->getParent ();
462 int n
= unwrap
<Argument
> (param
)->getArgNo ();
463 func
->addParamAttr (n
, convert_attr (kind
));
467 mono_llvm_add_instr_attr (LLVMValueRef val
, int index
, AttrKind kind
)
469 CallSite (unwrap
<Instruction
> (val
)).addAttribute (index
, convert_attr (kind
));
473 mono_llvm_create_di_builder (LLVMModuleRef module
)
475 return new DIBuilder (*unwrap(module
));
479 mono_llvm_di_create_compile_unit (void *di_builder
, const char *cu_name
, const char *dir
, const char *producer
)
481 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
485 di_file
= builder
->createFile (cu_name
, dir
);
486 return builder
->createCompileUnit (dwarf::DW_LANG_C99
, di_file
, producer
, true, "", 0);
490 mono_llvm_di_create_function (void *di_builder
, void *cu
, LLVMValueRef func
, const char *name
, const char *mangled_name
, const char *dir
, const char *file
, int line
)
492 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
494 DISubroutineType
*type
;
495 DISubprogram
*di_func
;
497 // FIXME: Share DIFile
498 di_file
= builder
->createFile (file
, dir
);
499 type
= builder
->createSubroutineType (builder
->getOrCreateTypeArray (ArrayRef
<Metadata
*> ()));
500 #if LLVM_API_VERSION >= 900
501 di_func
= builder
->createFunction (di_file
, name
, mangled_name
, di_file
, line
, type
, 0);
503 di_func
= builder
->createFunction (di_file
, name
, mangled_name
, di_file
, line
, type
, true, true, 0);
506 unwrap
<Function
>(func
)->setMetadata ("dbg", di_func
);
512 mono_llvm_di_create_file (void *di_builder
, const char *dir
, const char *file
)
514 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
516 return builder
->createFile (file
, dir
);
520 mono_llvm_di_create_location (void *di_builder
, void *scope
, int row
, int column
)
522 return DILocation::get (*unwrap(LLVMGetGlobalContext ()), row
, column
, (Metadata
*)scope
);
526 mono_llvm_set_fast_math (LLVMBuilderRef builder
)
530 unwrap(builder
)->setFastMathFlags (flags
);
534 mono_llvm_di_set_location (LLVMBuilderRef builder
, void *loc_md
)
536 unwrap(builder
)->SetCurrentDebugLocation ((DILocation
*)loc_md
);
540 mono_llvm_di_builder_finalize (void *di_builder
)
542 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
544 builder
->finalize ();
548 mono_llvm_get_or_insert_gc_safepoint_poll (LLVMModuleRef module
)
550 #if LLVM_API_VERSION >= 900
552 llvm::FunctionCallee callee
= unwrap(module
)->getOrInsertFunction("gc.safepoint_poll", FunctionType::get(unwrap(LLVMVoidType()), false));
553 return wrap (dyn_cast
<llvm::Function
> (callee
.getCallee ()));
555 llvm::Function
*SafepointPoll
;
556 llvm::Constant
*SafepointPollConstant
;
558 SafepointPollConstant
= unwrap(module
)->getOrInsertFunction("gc.safepoint_poll", FunctionType::get(unwrap(LLVMVoidType()), false));
559 g_assert (SafepointPollConstant
);
561 SafepointPoll
= dyn_cast
<llvm::Function
>(SafepointPollConstant
);
562 g_assert (SafepointPoll
);
563 g_assert (SafepointPoll
->empty());
565 return wrap(SafepointPoll
);
570 mono_llvm_remove_gc_safepoint_poll (LLVMModuleRef module
)
572 llvm::Function
*func
= unwrap (module
)->getFunction ("gc.safepoint_poll");
575 func
->eraseFromParent ();
580 mono_llvm_check_cpu_features (const CpuFeatureAliasFlag
*features
, int length
)
583 llvm::StringMap
<bool> HostFeatures
;
584 if (llvm::sys::getHostCPUFeatures (HostFeatures
)) {
585 for (int i
=0; i
<length
; i
++) {
586 CpuFeatureAliasFlag feature
= features
[i
];
587 if (HostFeatures
[feature
.alias
])
588 flags
|= feature
.flag
;
591 for (auto &F : HostFeatures)
593 outs () << "X: " << F.first () << "\n";