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)
9 // We need to override some stuff in LLVM, but this cannot be done using the C
10 // interface, so we have to use some C++ code here.
11 // The things which we override are:
12 // - the default JIT code manager used by LLVM doesn't allocate memory using
13 // MAP_32BIT, we require it.
14 // - add some callbacks so we can obtain the size of methods and their exception
19 // Mono's internal header files are not C++ clean, so avoid including them if
27 #include <llvm/Support/raw_ostream.h>
28 #include <llvm/IR/Function.h>
29 #include <llvm/IR/IRBuilder.h>
30 #include <llvm/IR/Module.h>
32 #include "mini-llvm-cpp.h"
37 mono_llvm_dump_value (LLVMValueRef value)
39 /* Same as LLVMDumpValue (), but print to stdout */
41 outs () << (*unwrap<Value> (value));
44 /* Missing overload for building an alloca with an alignment */
46 mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty,
47 LLVMValueRef ArraySize,
48 int alignment, const char *Name)
50 return wrap (unwrap (builder)->Insert (new AllocaInst (unwrap (Ty), unwrap (ArraySize), alignment), Name));
54 mono_llvm_build_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
55 const char *Name, gboolean is_volatile, BarrierKind barrier)
57 LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
60 case LLVM_BARRIER_NONE:
62 case LLVM_BARRIER_ACQ:
63 ins->setOrdering(Acquire);
65 case LLVM_BARRIER_SEQ:
66 ins->setOrdering(SequentiallyConsistent);
69 g_assert_not_reached ();
77 mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
78 const char *Name, gboolean is_volatile, int alignment)
82 ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
83 ins->setAlignment (alignment);
89 mono_llvm_build_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
90 gboolean is_volatile, BarrierKind barrier)
92 StoreInst *ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
95 case LLVM_BARRIER_NONE:
97 case LLVM_BARRIER_REL:
98 ins->setOrdering(Release);
100 case LLVM_BARRIER_SEQ:
101 ins->setOrdering(SequentiallyConsistent);
104 g_assert_not_reached ();
112 mono_llvm_build_aligned_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
113 gboolean is_volatile, int alignment)
117 ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
118 ins->setAlignment (alignment);
124 mono_llvm_build_cmpxchg (LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp, LLVMValueRef val)
126 AtomicCmpXchgInst *ins;
128 ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent, SequentiallyConsistent);
133 mono_llvm_build_atomic_rmw (LLVMBuilderRef builder, AtomicRMWOp op, LLVMValueRef ptr, LLVMValueRef val)
135 AtomicRMWInst::BinOp aop = AtomicRMWInst::Xchg;
139 case LLVM_ATOMICRMW_OP_XCHG:
140 aop = AtomicRMWInst::Xchg;
142 case LLVM_ATOMICRMW_OP_ADD:
143 aop = AtomicRMWInst::Add;
146 g_assert_not_reached ();
150 ins = unwrap (builder)->CreateAtomicRMW (aop, unwrap (ptr), unwrap (val), SequentiallyConsistent);
155 mono_llvm_build_fence (LLVMBuilderRef builder, BarrierKind kind)
158 AtomicOrdering ordering;
160 g_assert (kind != LLVM_BARRIER_NONE);
163 case LLVM_BARRIER_ACQ:
166 case LLVM_BARRIER_REL:
169 case LLVM_BARRIER_SEQ:
170 ordering = SequentiallyConsistent;
173 g_assert_not_reached ();
177 ins = unwrap (builder)->CreateFence (ordering);
182 mono_llvm_set_must_tail (LLVMValueRef call_ins)
184 CallInst *ins = (CallInst*)unwrap (call_ins);
186 ins->setTailCallKind (CallInst::TailCallKind::TCK_MustTail);
190 mono_llvm_replace_uses_of (LLVMValueRef var, LLVMValueRef v)
192 Value *V = ConstantExpr::getTruncOrBitCast (unwrap<Constant> (v), unwrap (var)->getType ());
193 unwrap (var)->replaceAllUsesWith (V);
197 mono_llvm_create_constant_data_array (const uint8_t *data, int len)
199 return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data, len)));
203 mono_llvm_set_is_constant (LLVMValueRef global_var)
205 unwrap<GlobalVariable>(global_var)->setConstant (true);
209 mono_llvm_set_preserveall_cc (LLVMValueRef func)
211 unwrap<Function>(func)->setCallingConv (CallingConv::PreserveAll);
215 mono_llvm_set_call_preserveall_cc (LLVMValueRef func)
217 unwrap<CallInst>(func)->setCallingConv (CallingConv::PreserveAll);