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_set_implicit_branch (LLVMBuilderRef builder
, LLVMValueRef branch
)
227 auto b
= unwrap (builder
);
228 auto &ctx
= b
->getContext ();
229 auto ins
= unwrap
<Instruction
> (branch
);
230 ins
->setMetadata (LLVMContext::MD_make_implicit
, MDNode::get (ctx
, {}));
234 mono_llvm_set_must_tailcall (LLVMValueRef call_ins
)
236 CallInst
*ins
= (CallInst
*)unwrap (call_ins
);
238 ins
->setTailCallKind (CallInst::TailCallKind::TCK_MustTail
);
242 mono_llvm_replace_uses_of (LLVMValueRef var
, LLVMValueRef v
)
244 Value
*V
= ConstantExpr::getTruncOrBitCast (unwrap
<Constant
> (v
), unwrap (var
)->getType ());
245 unwrap (var
)->replaceAllUsesWith (V
);
249 mono_llvm_create_constant_data_array (const uint8_t *data
, int len
)
251 return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data
, len
)));
255 mono_llvm_set_is_constant (LLVMValueRef global_var
)
257 unwrap
<GlobalVariable
>(global_var
)->setConstant (true);
260 // Note that in future versions of LLVM, CallInst and InvokeInst
261 // share a CallBase parent class that would make the below methods
265 mono_llvm_set_call_nonnull_arg (LLVMValueRef wrapped_calli
, int argNo
)
267 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
269 if (isa
<CallInst
> (calli
))
270 dyn_cast
<CallInst
>(calli
)->addParamAttr (argNo
, Attribute::NonNull
);
272 dyn_cast
<InvokeInst
>(calli
)->addParamAttr (argNo
, Attribute::NonNull
);
276 mono_llvm_set_call_nonnull_ret (LLVMValueRef wrapped_calli
)
278 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
280 if (isa
<CallInst
> (calli
))
281 dyn_cast
<CallInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NonNull
);
283 dyn_cast
<InvokeInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NonNull
);
287 mono_llvm_set_func_nonnull_arg (LLVMValueRef func
, int argNo
)
289 unwrap
<Function
>(func
)->addParamAttr (argNo
, Attribute::NonNull
);
293 mono_llvm_is_nonnull (LLVMValueRef wrapped
)
295 // Argument to function
296 Value
*val
= unwrap (wrapped
);
299 if (Argument
*arg
= dyn_cast
<Argument
> (val
)) {
300 return arg
->hasNonNullAttr ();
301 } else if (CallInst
*calli
= dyn_cast
<CallInst
> (val
)) {
302 return calli
->hasRetAttr (Attribute::NonNull
);
303 } else if (InvokeInst
*calli
= dyn_cast
<InvokeInst
> (val
)) {
304 return calli
->hasRetAttr (Attribute::NonNull
);
305 } else if (LoadInst
*loadi
= dyn_cast
<LoadInst
> (val
)) {
306 return loadi
->getMetadata("nonnull") != nullptr; // nonnull <index>
307 } else if (Instruction
*inst
= dyn_cast
<Instruction
> (val
)) {
308 // If not a load or a function argument, the only case for us to
309 // consider is that it's a bitcast. If so, recurse on what was casted.
310 if (inst
->getOpcode () == LLVMBitCast
) {
311 val
= inst
->getOperand (0);
324 mono_llvm_calls_using (LLVMValueRef wrapped_local
)
326 GSList
*usages
= NULL
;
327 Value
*local
= unwrap (wrapped_local
);
329 for (User
*user
: local
->users ()) {
330 if (isa
<CallInst
> (user
) || isa
<InvokeInst
> (user
)) {
331 usages
= g_slist_prepend (usages
, wrap (user
));
339 mono_llvm_call_args (LLVMValueRef wrapped_calli
)
341 Value
*calli
= unwrap(wrapped_calli
);
342 CallInst
*call
= dyn_cast
<CallInst
> (calli
);
343 InvokeInst
*invoke
= dyn_cast
<InvokeInst
> (calli
);
344 g_assert (call
|| invoke
);
346 unsigned int numOperands
= 0;
349 numOperands
= call
->getNumArgOperands ();
351 numOperands
= invoke
->getNumArgOperands ();
353 LLVMValueRef
*ret
= g_malloc (sizeof (LLVMValueRef
) * numOperands
);
355 for (int i
=0; i
< numOperands
; i
++) {
357 ret
[i
] = wrap (call
->getArgOperand (i
));
359 ret
[i
] = wrap (invoke
->getArgOperand (i
));
366 mono_llvm_set_call_notailcall (LLVMValueRef func
)
368 unwrap
<CallInst
>(func
)->setTailCallKind (CallInst::TailCallKind::TCK_NoTail
);
372 mono_llvm_set_call_noalias_ret (LLVMValueRef wrapped_calli
)
374 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
376 if (isa
<CallInst
> (calli
))
377 dyn_cast
<CallInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NoAlias
);
379 dyn_cast
<InvokeInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NoAlias
);
382 static Attribute::AttrKind
383 convert_attr (AttrKind kind
)
386 case LLVM_ATTR_NO_UNWIND
:
387 return Attribute::NoUnwind
;
388 case LLVM_ATTR_NO_INLINE
:
389 return Attribute::NoInline
;
390 case LLVM_ATTR_OPTIMIZE_FOR_SIZE
:
391 return Attribute::OptimizeForSize
;
392 case LLVM_ATTR_IN_REG
:
393 return Attribute::InReg
;
394 case LLVM_ATTR_STRUCT_RET
:
395 return Attribute::StructRet
;
396 case LLVM_ATTR_NO_ALIAS
:
397 return Attribute::NoAlias
;
398 case LLVM_ATTR_BY_VAL
:
399 return Attribute::ByVal
;
400 case LLVM_ATTR_UW_TABLE
:
401 return Attribute::UWTable
;
404 return Attribute::NoUnwind
;
409 mono_llvm_add_func_attr (LLVMValueRef func
, AttrKind kind
)
411 unwrap
<Function
> (func
)->addAttribute (AttributeList::FunctionIndex
, convert_attr (kind
));
415 mono_llvm_add_param_attr (LLVMValueRef param
, AttrKind kind
)
417 Function
*func
= unwrap
<Argument
> (param
)->getParent ();
418 int n
= unwrap
<Argument
> (param
)->getArgNo ();
419 func
->addParamAttr (n
, convert_attr (kind
));
423 mono_llvm_add_instr_attr (LLVMValueRef val
, int index
, AttrKind kind
)
425 CallSite (unwrap
<Instruction
> (val
)).addAttribute (index
, convert_attr (kind
));
429 mono_llvm_create_di_builder (LLVMModuleRef module
)
431 return new DIBuilder (*unwrap(module
));
435 mono_llvm_di_create_compile_unit (void *di_builder
, const char *cu_name
, const char *dir
, const char *producer
)
437 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
441 di_file
= builder
->createFile (cu_name
, dir
);
442 return builder
->createCompileUnit (dwarf::DW_LANG_C99
, di_file
, producer
, true, "", 0);
446 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
)
448 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
450 DISubroutineType
*type
;
451 DISubprogram
*di_func
;
453 // FIXME: Share DIFile
454 di_file
= builder
->createFile (file
, dir
);
455 type
= builder
->createSubroutineType (builder
->getOrCreateTypeArray (ArrayRef
<Metadata
*> ()));
456 #if LLVM_API_VERSION >= 900
457 di_func
= builder
->createFunction (di_file
, name
, mangled_name
, di_file
, line
, type
, 0);
459 di_func
= builder
->createFunction (di_file
, name
, mangled_name
, di_file
, line
, type
, true, true, 0);
462 unwrap
<Function
>(func
)->setMetadata ("dbg", di_func
);
468 mono_llvm_di_create_file (void *di_builder
, const char *dir
, const char *file
)
470 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
472 return builder
->createFile (file
, dir
);
476 mono_llvm_di_create_location (void *di_builder
, void *scope
, int row
, int column
)
478 return DILocation::get (*unwrap(LLVMGetGlobalContext ()), row
, column
, (Metadata
*)scope
);
482 mono_llvm_set_fast_math (LLVMBuilderRef builder
)
486 unwrap(builder
)->setFastMathFlags (flags
);
490 mono_llvm_di_set_location (LLVMBuilderRef builder
, void *loc_md
)
492 unwrap(builder
)->SetCurrentDebugLocation ((DILocation
*)loc_md
);
496 mono_llvm_di_builder_finalize (void *di_builder
)
498 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
500 builder
->finalize ();
504 mono_llvm_get_or_insert_gc_safepoint_poll (LLVMModuleRef module
)
506 #if LLVM_API_VERSION >= 900
508 llvm::FunctionCallee callee
= unwrap(module
)->getOrInsertFunction("gc.safepoint_poll", FunctionType::get(unwrap(LLVMVoidType()), false));
509 return wrap (dyn_cast
<llvm::Function
> (callee
.getCallee ()));
511 llvm::Function
*SafepointPoll
;
512 llvm::Constant
*SafepointPollConstant
;
514 SafepointPollConstant
= unwrap(module
)->getOrInsertFunction("gc.safepoint_poll", FunctionType::get(unwrap(LLVMVoidType()), false));
515 g_assert (SafepointPollConstant
);
517 SafepointPoll
= dyn_cast
<llvm::Function
>(SafepointPollConstant
);
518 g_assert (SafepointPoll
);
519 g_assert (SafepointPoll
->empty());
521 return wrap(SafepointPoll
);