Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / mini-llvm-cpp.cpp
index 8122365cab91355de3aada21aef334d32c2b4dc8..253cd42ff81b93f61cfa49d1a40eac51737e1a82 100644 (file)
@@ -3,6 +3,7 @@
 //
 // (C) 2009-2011 Novell, Inc.
 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 
 //
 #include <llvm/IR/IRBuilder.h>
 #include <llvm/IR/Module.h>
 #include <llvm/IR/DIBuilder.h>
+#include <llvm/IR/CallSite.h>
 
 #include "mini-llvm-cpp.h"
 
 using namespace llvm;
 
+#if LLVM_API_VERSION > 100
+// These are c++11 scoped enums in recent llvm versions
+#define Acquire AtomicOrdering::Acquire
+#define Release AtomicOrdering::Release
+#define SequentiallyConsistent AtomicOrdering::SequentiallyConsistent
+#endif
+
 void
 mono_llvm_dump_value (LLVMValueRef value)
 {
@@ -48,15 +57,29 @@ mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty,
                                                LLVMValueRef ArraySize,
                                                int alignment, const char *Name)
 {
+#if LLVM_API_VERSION >= 500
+       return wrap (unwrap (builder)->Insert (new AllocaInst (unwrap (Ty), 0, unwrap (ArraySize), alignment), Name));
+#else
        return wrap (unwrap (builder)->Insert (new AllocaInst (unwrap (Ty), unwrap (ArraySize), alignment), Name));
+#endif
 }
 
 LLVMValueRef 
 mono_llvm_build_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
-                                         const char *Name, gboolean is_volatile, BarrierKind barrier)
+                                         const char *Name, gboolean is_volatile)
+{
+       LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
+
+       return wrap(ins);
+}
+
+LLVMValueRef
+mono_llvm_build_atomic_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
+                                                        const char *Name, gboolean is_volatile, int alignment, BarrierKind barrier)
 {
        LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
 
+       ins->setAlignment (alignment);
        switch (barrier) {
        case LLVM_BARRIER_NONE:
                break;
@@ -218,6 +241,114 @@ mono_llvm_set_call_preserveall_cc (LLVMValueRef func)
        unwrap<CallInst>(func)->setCallingConv (CallingConv::PreserveAll);
 }
 
+void
+mono_llvm_set_call_notail (LLVMValueRef func)
+{
+#if LLVM_API_VERSION > 100
+       unwrap<CallInst>(func)->setTailCallKind (CallInst::TailCallKind::TCK_NoTail);
+#endif
+}
+
+#if LLVM_API_VERSION > 500
+static Attribute::AttrKind
+convert_attr (AttrKind kind)
+{
+       switch (kind) {
+       case LLVM_ATTR_NO_UNWIND:
+               return Attribute::NoUnwind;
+       case LLVM_ATTR_NO_INLINE:
+               return Attribute::NoInline;
+       case LLVM_ATTR_OPTIMIZE_FOR_SIZE:
+               return Attribute::OptimizeForSize;
+       case LLVM_ATTR_IN_REG:
+               return Attribute::InReg;
+       case LLVM_ATTR_STRUCT_RET:
+               return Attribute::StructRet;
+       case LLVM_ATTR_NO_ALIAS:
+               return Attribute::NoAlias;
+       case LLVM_ATTR_BY_VAL:
+               return Attribute::ByVal;
+       case LLVM_ATTR_UW_TABLE:
+               return Attribute::UWTable;
+       default:
+               assert (0);
+               return Attribute::NoUnwind;
+       }
+}
+#else
+static LLVMAttribute
+convert_attr (AttrKind kind)
+{
+       switch (kind) {
+       case LLVM_ATTR_NO_UNWIND:
+               return LLVMNoUnwindAttribute;
+       case LLVM_ATTR_NO_INLINE:
+               return LLVMNoInlineAttribute;
+       case LLVM_ATTR_OPTIMIZE_FOR_SIZE:
+               return LLVMOptimizeForSizeAttribute;
+       case LLVM_ATTR_IN_REG:
+               return LLVMInRegAttribute;
+       case LLVM_ATTR_STRUCT_RET:
+               return LLVMStructRetAttribute;
+       case LLVM_ATTR_NO_ALIAS:
+               return LLVMNoAliasAttribute;
+       case LLVM_ATTR_BY_VAL:
+               return LLVMByValAttribute;
+       case LLVM_ATTR_UW_TABLE:
+               return LLVMUWTable;
+       default:
+               assert (0);
+               return LLVMNoUnwindAttribute;
+       }
+}
+#endif
+
+void
+mono_llvm_add_func_attr (LLVMValueRef func, AttrKind kind)
+{
+#if LLVM_API_VERSION > 100
+       unwrap<Function> (func)->addAttribute (AttributeList::FunctionIndex, convert_attr (kind));
+#else
+       Function *Func = unwrap<Function>(func);
+       const AttributeSet PAL = Func->getAttributes();
+       AttrBuilder B(convert_attr (kind));
+       const AttributeSet PALnew =
+               PAL.addAttributes(Func->getContext(), AttributeSet::FunctionIndex,
+                                                 AttributeSet::get(Func->getContext(),
+                                                                                       AttributeSet::FunctionIndex, B));
+       Func->setAttributes(PALnew);
+#endif
+}
+
+void
+mono_llvm_add_param_attr (LLVMValueRef param, AttrKind kind)
+{
+#if LLVM_API_VERSION > 100
+       Function *func = unwrap<Argument> (param)->getParent ();
+       int n = unwrap<Argument> (param)->getArgNo ();
+       func->addParamAttr (n, convert_attr (kind));
+#else
+       Argument *A = unwrap<Argument>(param);
+       AttrBuilder B(convert_attr (kind));
+       A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1,  B));
+#endif
+}
+
+void
+mono_llvm_add_instr_attr (LLVMValueRef val, int index, AttrKind kind)
+{
+#if LLVM_API_VERSION > 100
+       CallSite (unwrap<Instruction> (val)).addAttribute (index, convert_attr (kind));
+#else
+  CallSite Call = CallSite(unwrap<Instruction>(val));
+  AttrBuilder B(convert_attr (kind));
+  Call.setAttributes(
+    Call.getAttributes().addAttributes(Call->getContext(), index,
+                                       AttributeSet::get(Call->getContext(),
+                                                         index, B)));
+#endif
+}
+
 #if LLVM_API_VERSION > 100
 
 void*
@@ -231,20 +362,32 @@ mono_llvm_di_create_compile_unit (void *di_builder, const char *cu_name, const c
 {
        DIBuilder *builder = (DIBuilder*)di_builder;
 
+#if LLVM_API_VERSION >= 500
+       DIFile *di_file;
+
+       di_file = builder->createFile (cu_name, dir);
+       return builder->createCompileUnit (dwarf::DW_LANG_C99, di_file, producer, true, "", 0);
+#else
        return builder->createCompileUnit (dwarf::DW_LANG_C99, cu_name, dir, producer, true, "", 0);
+#endif
 }
 
 void*
-mono_llvm_di_create_function (void *di_builder, void *cu, const char *name, const char *mangled_name, const char *dir, const char *file, int line)
+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)
 {
        DIBuilder *builder = (DIBuilder*)di_builder;
        DIFile *di_file;
        DISubroutineType *type;
+       DISubprogram *di_func;
 
        // FIXME: Share DIFile
        di_file = builder->createFile (file, dir);
        type = builder->createSubroutineType (builder->getOrCreateTypeArray (ArrayRef<Metadata*> ()));
-       return builder->createFunction (di_file, name, mangled_name, di_file, line, type, true, true, 0);
+       di_func = builder->createFunction (di_file, name, mangled_name, di_file, line, type, true, true, 0);
+
+       unwrap<Function>(func)->setMetadata ("dbg", di_func);
+
+       return di_func;
 }
 
 void*