#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)
{
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
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*
{
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*