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>
41 #include "mini-llvm-cpp.h"
45 #define Acquire AtomicOrdering::Acquire
46 #define Release AtomicOrdering::Release
47 #define SequentiallyConsistent AtomicOrdering::SequentiallyConsistent
50 mono_llvm_dump_value (LLVMValueRef value
)
52 /* Same as LLVMDumpValue (), but print to stdout */
54 outs () << (*unwrap
<Value
> (value
));
57 /* Missing overload for building an alloca with an alignment */
59 mono_llvm_build_alloca (LLVMBuilderRef builder
, LLVMTypeRef Ty
,
60 LLVMValueRef ArraySize
,
61 int alignment
, const char *Name
)
63 return wrap (unwrap (builder
)->Insert (new AllocaInst (unwrap (Ty
), 0, unwrap (ArraySize
), alignment
), Name
));
67 mono_llvm_build_load (LLVMBuilderRef builder
, LLVMValueRef PointerVal
,
68 const char *Name
, gboolean is_volatile
)
70 LoadInst
*ins
= unwrap(builder
)->CreateLoad(unwrap(PointerVal
), is_volatile
, Name
);
76 mono_llvm_build_atomic_load (LLVMBuilderRef builder
, LLVMValueRef PointerVal
,
77 const char *Name
, gboolean is_volatile
, int alignment
, BarrierKind barrier
)
79 LoadInst
*ins
= unwrap(builder
)->CreateLoad(unwrap(PointerVal
), is_volatile
, Name
);
81 ins
->setAlignment (alignment
);
83 case LLVM_BARRIER_NONE
:
85 case LLVM_BARRIER_ACQ
:
86 ins
->setOrdering(Acquire
);
88 case LLVM_BARRIER_SEQ
:
89 ins
->setOrdering(SequentiallyConsistent
);
92 g_assert_not_reached ();
100 mono_llvm_build_aligned_load (LLVMBuilderRef builder
, LLVMValueRef PointerVal
,
101 const char *Name
, gboolean is_volatile
, int alignment
)
105 ins
= unwrap(builder
)->CreateLoad(unwrap(PointerVal
), is_volatile
, Name
);
106 ins
->setAlignment (alignment
);
112 mono_llvm_build_store (LLVMBuilderRef builder
, LLVMValueRef Val
, LLVMValueRef PointerVal
,
113 gboolean is_volatile
, BarrierKind barrier
)
115 StoreInst
*ins
= unwrap(builder
)->CreateStore(unwrap(Val
), unwrap(PointerVal
), is_volatile
);
118 case LLVM_BARRIER_NONE
:
120 case LLVM_BARRIER_REL
:
121 ins
->setOrdering(Release
);
123 case LLVM_BARRIER_SEQ
:
124 ins
->setOrdering(SequentiallyConsistent
);
127 g_assert_not_reached ();
135 mono_llvm_build_aligned_store (LLVMBuilderRef builder
, LLVMValueRef Val
, LLVMValueRef PointerVal
,
136 gboolean is_volatile
, int alignment
)
140 ins
= unwrap(builder
)->CreateStore(unwrap(Val
), unwrap(PointerVal
), is_volatile
);
141 ins
->setAlignment (alignment
);
147 mono_llvm_build_cmpxchg (LLVMBuilderRef builder
, LLVMValueRef ptr
, LLVMValueRef cmp
, LLVMValueRef val
)
149 AtomicCmpXchgInst
*ins
;
151 ins
= unwrap(builder
)->CreateAtomicCmpXchg (unwrap(ptr
), unwrap (cmp
), unwrap (val
), SequentiallyConsistent
, SequentiallyConsistent
);
156 mono_llvm_build_atomic_rmw (LLVMBuilderRef builder
, AtomicRMWOp op
, LLVMValueRef ptr
, LLVMValueRef val
)
158 AtomicRMWInst::BinOp aop
= AtomicRMWInst::Xchg
;
162 case LLVM_ATOMICRMW_OP_XCHG
:
163 aop
= AtomicRMWInst::Xchg
;
165 case LLVM_ATOMICRMW_OP_ADD
:
166 aop
= AtomicRMWInst::Add
;
169 g_assert_not_reached ();
173 ins
= unwrap (builder
)->CreateAtomicRMW (aop
, unwrap (ptr
), unwrap (val
), SequentiallyConsistent
);
178 mono_llvm_build_fence (LLVMBuilderRef builder
, BarrierKind kind
)
181 AtomicOrdering ordering
;
183 g_assert (kind
!= LLVM_BARRIER_NONE
);
186 case LLVM_BARRIER_ACQ
:
189 case LLVM_BARRIER_REL
:
192 case LLVM_BARRIER_SEQ
:
193 ordering
= SequentiallyConsistent
;
196 g_assert_not_reached ();
200 ins
= unwrap (builder
)->CreateFence (ordering
);
205 mono_llvm_set_must_tailcall (LLVMValueRef call_ins
)
207 CallInst
*ins
= (CallInst
*)unwrap (call_ins
);
209 ins
->setTailCallKind (CallInst::TailCallKind::TCK_MustTail
);
213 mono_llvm_replace_uses_of (LLVMValueRef var
, LLVMValueRef v
)
215 Value
*V
= ConstantExpr::getTruncOrBitCast (unwrap
<Constant
> (v
), unwrap (var
)->getType ());
216 unwrap (var
)->replaceAllUsesWith (V
);
220 mono_llvm_create_constant_data_array (const uint8_t *data
, int len
)
222 return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data
, len
)));
226 mono_llvm_set_is_constant (LLVMValueRef global_var
)
228 unwrap
<GlobalVariable
>(global_var
)->setConstant (true);
231 // Note that in future versions of LLVM, CallInst and InvokeInst
232 // share a CallBase parent class that would make the below methods
236 mono_llvm_set_call_nonnull_arg (LLVMValueRef wrapped_calli
, int argNo
)
238 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
240 if (isa
<CallInst
> (calli
))
241 dyn_cast
<CallInst
>(calli
)->addParamAttr (argNo
, Attribute::NonNull
);
243 dyn_cast
<InvokeInst
>(calli
)->addParamAttr (argNo
, Attribute::NonNull
);
247 mono_llvm_set_call_nonnull_ret (LLVMValueRef wrapped_calli
)
249 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
251 if (isa
<CallInst
> (calli
))
252 dyn_cast
<CallInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NonNull
);
254 dyn_cast
<InvokeInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NonNull
);
258 mono_llvm_set_func_nonnull_arg (LLVMValueRef func
, int argNo
)
260 unwrap
<Function
>(func
)->addParamAttr (argNo
, Attribute::NonNull
);
264 mono_llvm_is_nonnull (LLVMValueRef wrapped
)
266 // Argument to function
267 Value
*val
= unwrap (wrapped
);
270 if (Argument
*arg
= dyn_cast
<Argument
> (val
)) {
271 return arg
->hasNonNullAttr ();
272 } else if (CallInst
*calli
= dyn_cast
<CallInst
> (val
)) {
273 return calli
->hasRetAttr (Attribute::NonNull
);
274 } else if (InvokeInst
*calli
= dyn_cast
<InvokeInst
> (val
)) {
275 return calli
->hasRetAttr (Attribute::NonNull
);
276 } else if (LoadInst
*loadi
= dyn_cast
<LoadInst
> (val
)) {
277 return loadi
->getMetadata("nonnull") != nullptr; // nonnull <index>
278 } else if (Instruction
*inst
= dyn_cast
<Instruction
> (val
)) {
279 // If not a load or a function argument, the only case for us to
280 // consider is that it's a bitcast. If so, recurse on what was casted.
281 if (inst
->getOpcode () == LLVMBitCast
) {
282 val
= inst
->getOperand (0);
295 mono_llvm_calls_using (LLVMValueRef wrapped_local
)
297 GSList
*usages
= NULL
;
298 Value
*local
= unwrap (wrapped_local
);
300 for (User
*user
: local
->users ()) {
301 if (isa
<CallInst
> (user
) || isa
<InvokeInst
> (user
)) {
302 usages
= g_slist_prepend (usages
, wrap (user
));
310 mono_llvm_call_args (LLVMValueRef wrapped_calli
)
312 Value
*calli
= unwrap(wrapped_calli
);
313 CallInst
*call
= dyn_cast
<CallInst
> (calli
);
314 InvokeInst
*invoke
= dyn_cast
<InvokeInst
> (calli
);
315 g_assert (call
|| invoke
);
317 unsigned int numOperands
= 0;
320 numOperands
= call
->getNumArgOperands ();
322 numOperands
= invoke
->getNumArgOperands ();
324 LLVMValueRef
*ret
= g_malloc (sizeof (LLVMValueRef
) * numOperands
);
326 for (int i
=0; i
< numOperands
; i
++) {
328 ret
[i
] = wrap (call
->getArgOperand (i
));
330 ret
[i
] = wrap (invoke
->getArgOperand (i
));
337 mono_llvm_set_call_notailcall (LLVMValueRef func
)
339 unwrap
<CallInst
>(func
)->setTailCallKind (CallInst::TailCallKind::TCK_NoTail
);
343 mono_llvm_set_call_noalias_ret (LLVMValueRef wrapped_calli
)
345 Instruction
*calli
= unwrap
<Instruction
> (wrapped_calli
);
347 if (isa
<CallInst
> (calli
))
348 dyn_cast
<CallInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NoAlias
);
350 dyn_cast
<InvokeInst
>(calli
)->addAttribute (AttributeList::ReturnIndex
, Attribute::NoAlias
);
353 static Attribute::AttrKind
354 convert_attr (AttrKind kind
)
357 case LLVM_ATTR_NO_UNWIND
:
358 return Attribute::NoUnwind
;
359 case LLVM_ATTR_NO_INLINE
:
360 return Attribute::NoInline
;
361 case LLVM_ATTR_OPTIMIZE_FOR_SIZE
:
362 return Attribute::OptimizeForSize
;
363 case LLVM_ATTR_IN_REG
:
364 return Attribute::InReg
;
365 case LLVM_ATTR_STRUCT_RET
:
366 return Attribute::StructRet
;
367 case LLVM_ATTR_NO_ALIAS
:
368 return Attribute::NoAlias
;
369 case LLVM_ATTR_BY_VAL
:
370 return Attribute::ByVal
;
371 case LLVM_ATTR_UW_TABLE
:
372 return Attribute::UWTable
;
375 return Attribute::NoUnwind
;
380 mono_llvm_add_func_attr (LLVMValueRef func
, AttrKind kind
)
382 unwrap
<Function
> (func
)->addAttribute (AttributeList::FunctionIndex
, convert_attr (kind
));
386 mono_llvm_add_param_attr (LLVMValueRef param
, AttrKind kind
)
388 Function
*func
= unwrap
<Argument
> (param
)->getParent ();
389 int n
= unwrap
<Argument
> (param
)->getArgNo ();
390 func
->addParamAttr (n
, convert_attr (kind
));
394 mono_llvm_add_instr_attr (LLVMValueRef val
, int index
, AttrKind kind
)
396 CallSite (unwrap
<Instruction
> (val
)).addAttribute (index
, convert_attr (kind
));
400 mono_llvm_create_di_builder (LLVMModuleRef module
)
402 return new DIBuilder (*unwrap(module
));
406 mono_llvm_di_create_compile_unit (void *di_builder
, const char *cu_name
, const char *dir
, const char *producer
)
408 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
412 di_file
= builder
->createFile (cu_name
, dir
);
413 return builder
->createCompileUnit (dwarf::DW_LANG_C99
, di_file
, producer
, true, "", 0);
417 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
)
419 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
421 DISubroutineType
*type
;
422 DISubprogram
*di_func
;
424 // FIXME: Share DIFile
425 di_file
= builder
->createFile (file
, dir
);
426 type
= builder
->createSubroutineType (builder
->getOrCreateTypeArray (ArrayRef
<Metadata
*> ()));
427 #if LLVM_API_VERSION >= 900
428 di_func
= builder
->createFunction (di_file
, name
, mangled_name
, di_file
, line
, type
, 0);
430 di_func
= builder
->createFunction (di_file
, name
, mangled_name
, di_file
, line
, type
, true, true, 0);
433 unwrap
<Function
>(func
)->setMetadata ("dbg", di_func
);
439 mono_llvm_di_create_file (void *di_builder
, const char *dir
, const char *file
)
441 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
443 return builder
->createFile (file
, dir
);
447 mono_llvm_di_create_location (void *di_builder
, void *scope
, int row
, int column
)
449 return DILocation::get (*unwrap(LLVMGetGlobalContext ()), row
, column
, (Metadata
*)scope
);
453 mono_llvm_di_set_location (LLVMBuilderRef builder
, void *loc_md
)
455 unwrap(builder
)->SetCurrentDebugLocation ((DILocation
*)loc_md
);
459 mono_llvm_di_builder_finalize (void *di_builder
)
461 DIBuilder
*builder
= (DIBuilder
*)di_builder
;
463 builder
->finalize ();
467 mono_llvm_get_or_insert_gc_safepoint_poll (LLVMModuleRef module
)
469 #if LLVM_API_VERSION >= 900
471 llvm::FunctionCallee callee
= unwrap(module
)->getOrInsertFunction("gc.safepoint_poll", FunctionType::get(unwrap(LLVMVoidType()), false));
472 return wrap (dyn_cast
<llvm::Function
> (callee
.getCallee ()));
474 llvm::Function
*SafepointPoll
;
475 llvm::Constant
*SafepointPollConstant
;
477 SafepointPollConstant
= unwrap(module
)->getOrInsertFunction("gc.safepoint_poll", FunctionType::get(unwrap(LLVMVoidType()), false));
478 g_assert (SafepointPollConstant
);
480 SafepointPoll
= dyn_cast
<llvm::Function
>(SafepointPollConstant
);
481 g_assert (SafepointPoll
);
482 g_assert (SafepointPoll
->empty());
484 return wrap(SafepointPoll
);