Use range metadata (#17956)
[mono-project.git] / mono / mini / mini-llvm-cpp.cpp
blob4941545505e32d9eb89fd6456513d6bcc05cc23a
1 //
2 // mini-llvm-cpp.cpp: C++ support classes for the mono LLVM integration
3 //
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.
7 //
9 //
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
16 // tables.
20 // Mono's internal header files are not C++ clean, so avoid including them if
21 // possible
24 #ifdef _MSC_VER
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)
28 #endif
30 #include "config.h"
32 #include <stdint.h>
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"
44 using namespace llvm;
46 #define Acquire AtomicOrdering::Acquire
47 #define Release AtomicOrdering::Release
48 #define SequentiallyConsistent AtomicOrdering::SequentiallyConsistent
50 void
51 mono_llvm_dump_value (LLVMValueRef value)
53 /* Same as LLVMDumpValue (), but print to stdout */
54 outs () << (*unwrap<Value> (value)) << "\n";
55 fflush (stdout);
58 void
59 mono_llvm_dump_module (LLVMModuleRef module)
61 /* Same as LLVMDumpModule (), but print to stdout */
62 outs () << (*unwrap (module));
63 fflush (stdout);
66 /* Missing overload for building an alloca with an alignment */
67 LLVMValueRef
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));
75 LLVMValueRef
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);
81 return wrap(ins);
84 LLVMValueRef
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);
91 switch (barrier) {
92 case LLVM_BARRIER_NONE:
93 break;
94 case LLVM_BARRIER_ACQ:
95 ins->setOrdering(Acquire);
96 break;
97 case LLVM_BARRIER_SEQ:
98 ins->setOrdering(SequentiallyConsistent);
99 break;
100 default:
101 g_assert_not_reached ();
102 break;
105 return wrap(ins);
108 LLVMValueRef
109 mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
110 const char *Name, gboolean is_volatile, int alignment)
112 LoadInst *ins;
114 ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
115 ins->setAlignment (alignment);
117 return wrap(ins);
120 LLVMValueRef
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);
126 switch (barrier) {
127 case LLVM_BARRIER_NONE:
128 break;
129 case LLVM_BARRIER_REL:
130 ins->setOrdering(Release);
131 break;
132 case LLVM_BARRIER_SEQ:
133 ins->setOrdering(SequentiallyConsistent);
134 break;
135 default:
136 g_assert_not_reached ();
137 break;
140 return wrap(ins);
143 LLVMValueRef
144 mono_llvm_build_aligned_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
145 gboolean is_volatile, int alignment)
147 StoreInst *ins;
149 ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
150 ins->setAlignment (alignment);
152 return wrap (ins);
155 LLVMValueRef
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);
161 return wrap (ins);
164 LLVMValueRef
165 mono_llvm_build_atomic_rmw (LLVMBuilderRef builder, AtomicRMWOp op, LLVMValueRef ptr, LLVMValueRef val)
167 AtomicRMWInst::BinOp aop = AtomicRMWInst::Xchg;
168 AtomicRMWInst *ins;
170 switch (op) {
171 case LLVM_ATOMICRMW_OP_XCHG:
172 aop = AtomicRMWInst::Xchg;
173 break;
174 case LLVM_ATOMICRMW_OP_ADD:
175 aop = AtomicRMWInst::Add;
176 break;
177 default:
178 g_assert_not_reached ();
179 break;
182 ins = unwrap (builder)->CreateAtomicRMW (aop, unwrap (ptr), unwrap (val), SequentiallyConsistent);
183 return wrap (ins);
186 LLVMValueRef
187 mono_llvm_build_fence (LLVMBuilderRef builder, BarrierKind kind)
189 FenceInst *ins;
190 AtomicOrdering ordering;
192 g_assert (kind != LLVM_BARRIER_NONE);
194 switch (kind) {
195 case LLVM_BARRIER_ACQ:
196 ordering = Acquire;
197 break;
198 case LLVM_BARRIER_REL:
199 ordering = Release;
200 break;
201 case LLVM_BARRIER_SEQ:
202 ordering = SequentiallyConsistent;
203 break;
204 default:
205 g_assert_not_reached ();
206 break;
209 ins = unwrap (builder)->CreateFence (ordering);
210 return wrap (ins);
213 LLVMValueRef
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 ();
218 MDBuilder mdb{ctx};
219 auto weights = mdb.createBranchWeights (t_weight, f_weight);
220 auto ins = b->CreateCondBr (unwrap (cond), unwrap (t), unwrap (f), weights);
221 return wrap (ins);
224 void
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)));
232 void
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));
244 void
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, {}));
253 void
254 mono_llvm_set_must_tailcall (LLVMValueRef call_ins)
256 CallInst *ins = (CallInst*)unwrap (call_ins);
258 ins->setTailCallKind (CallInst::TailCallKind::TCK_MustTail);
261 void
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);
268 LLVMValueRef
269 mono_llvm_create_constant_data_array (const uint8_t *data, int len)
271 return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data, len)));
274 void
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
282 // look much better
284 void
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);
291 else
292 dyn_cast<InvokeInst>(calli)->addParamAttr (argNo, Attribute::NonNull);
295 void
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);
302 else
303 dyn_cast<InvokeInst>(calli)->addAttribute (AttributeList::ReturnIndex, Attribute::NonNull);
306 void
307 mono_llvm_set_func_nonnull_arg (LLVMValueRef func, int argNo)
309 unwrap<Function>(func)->addParamAttr (argNo, Attribute::NonNull);
312 gboolean
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));
325 return TRUE;
330 #endif
331 return FALSE;
334 gboolean
335 mono_llvm_is_nonnull (LLVMValueRef wrapped)
337 // Argument to function
338 Value *val = unwrap (wrapped);
340 while (val) {
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);
354 continue;
357 return FALSE;
358 } else {
359 return FALSE;
362 return FALSE;
365 GSList *
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));
377 return usages;
380 LLVMValueRef *
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;
390 if (call)
391 numOperands = call->getNumArgOperands ();
392 else
393 numOperands = invoke->getNumArgOperands ();
395 LLVMValueRef *ret = g_malloc (sizeof (LLVMValueRef) * numOperands);
397 for (int i=0; i < numOperands; i++) {
398 if (call)
399 ret [i] = wrap (call->getArgOperand (i));
400 else
401 ret [i] = wrap (invoke->getArgOperand (i));
404 return ret;
407 void
408 mono_llvm_set_call_notailcall (LLVMValueRef func)
410 unwrap<CallInst>(func)->setTailCallKind (CallInst::TailCallKind::TCK_NoTail);
413 void
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);
420 else
421 dyn_cast<InvokeInst>(calli)->addAttribute (AttributeList::ReturnIndex, Attribute::NoAlias);
424 static Attribute::AttrKind
425 convert_attr (AttrKind kind)
427 switch (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;
446 default:
447 assert (0);
448 return Attribute::NoUnwind;
452 void
453 mono_llvm_add_func_attr (LLVMValueRef func, AttrKind kind)
455 unwrap<Function> (func)->addAttribute (AttributeList::FunctionIndex, convert_attr (kind));
458 void
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));
466 void
467 mono_llvm_add_instr_attr (LLVMValueRef val, int index, AttrKind kind)
469 CallSite (unwrap<Instruction> (val)).addAttribute (index, convert_attr (kind));
472 void*
473 mono_llvm_create_di_builder (LLVMModuleRef module)
475 return new DIBuilder (*unwrap(module));
478 void*
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;
483 DIFile *di_file;
485 di_file = builder->createFile (cu_name, dir);
486 return builder->createCompileUnit (dwarf::DW_LANG_C99, di_file, producer, true, "", 0);
489 void*
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;
493 DIFile *di_file;
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);
502 #else
503 di_func = builder->createFunction (di_file, name, mangled_name, di_file, line, type, true, true, 0);
504 #endif
506 unwrap<Function>(func)->setMetadata ("dbg", di_func);
508 return di_func;
511 void*
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);
519 void*
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);
525 void
526 mono_llvm_set_fast_math (LLVMBuilderRef builder)
528 FastMathFlags flags;
529 flags.setFast ();
530 unwrap(builder)->setFastMathFlags (flags);
533 void
534 mono_llvm_di_set_location (LLVMBuilderRef builder, void *loc_md)
536 unwrap(builder)->SetCurrentDebugLocation ((DILocation*)loc_md);
539 void
540 mono_llvm_di_builder_finalize (void *di_builder)
542 DIBuilder *builder = (DIBuilder*)di_builder;
544 builder->finalize ();
547 LLVMValueRef
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 ()));
554 #else
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);
566 #endif
569 gboolean
570 mono_llvm_remove_gc_safepoint_poll (LLVMModuleRef module)
572 llvm::Function *func = unwrap (module)->getFunction ("gc.safepoint_poll");
573 if (func == nullptr)
574 return FALSE;
575 func->eraseFromParent ();
576 return TRUE;
580 mono_llvm_check_cpu_features (const CpuFeatureAliasFlag *features, int length)
582 int flags = 0;
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)
592 if (F.second)
593 outs () << "X: " << F.first () << "\n";
596 return flags;