From a4db065405df0861145f29efcdfa52b228a43b86 Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Thu, 16 Apr 2015 00:08:17 +0200 Subject: [PATCH 1/4] Define runtime functions with a helper function that checks whether to use sret or not. --- gen/abi-ppc64.cpp | 6 +- gen/abi-win64.cpp | 9 +- gen/abi-x86-64.cpp | 8 +- gen/abi-x86.cpp | 15 ++ gen/abi.cpp | 21 +- gen/abi.h | 3 +- gen/runtime.cpp | 584 ++++++++++++++------------------------------- 7 files changed, 218 insertions(+), 428 deletions(-) diff --git a/gen/abi-ppc64.cpp b/gen/abi-ppc64.cpp index c2f1c894e43..13e00b66fc1 100644 --- a/gen/abi-ppc64.cpp +++ b/gen/abi-ppc64.cpp @@ -44,16 +44,12 @@ struct PPC64TargetABI : TargetABI { } } - bool returnInArg(TypeFunction* tf) + bool returnInArg(Type* rt, LINK /*linkage*/) { - if (tf->isref) - return false; - // Return structs and static arrays on the stack. The latter is needed // because otherwise LLVM tries to actually return the array in a number // of physical registers, which leads, depending on the target, to // either horrendous codegen or backend crashes. - Type* rt = tf->next->toBasetype(); return (rt->ty == Tstruct || rt->ty == Tsarray); } diff --git a/gen/abi-win64.cpp b/gen/abi-win64.cpp index a150aeb5dbe..9ae69f30537 100644 --- a/gen/abi-win64.cpp +++ b/gen/abi-win64.cpp @@ -38,7 +38,7 @@ struct Win64TargetABI : TargetABI llvm::CallingConv::ID callingConv(LINK l); - bool returnInArg(TypeFunction* tf); + bool returnInArg(Type* rt, LINK linkage); bool passByVal(Type* t); @@ -112,13 +112,8 @@ llvm::CallingConv::ID Win64TargetABI::callingConv(LINK l) } } -bool Win64TargetABI::returnInArg(TypeFunction* tf) +bool Win64TargetABI::returnInArg(Type* rt, LINK /*linkage*/) { - if (tf->isref) - return false; - - Type* rt = tf->next->toBasetype(); - // * let LLVM return 80-bit real/ireal on the x87 stack, for DMD compliance if (realIs80bits() && (rt->ty == Tfloat80 || rt->ty == Timaginary80)) return false; diff --git a/gen/abi-x86-64.cpp b/gen/abi-x86-64.cpp index 452d24967eb..f09720645b3 100644 --- a/gen/abi-x86-64.cpp +++ b/gen/abi-x86-64.cpp @@ -221,7 +221,7 @@ struct X86_64TargetABI : TargetABI { llvm::CallingConv::ID callingConv(LINK l); - bool returnInArg(TypeFunction* tf); + bool returnInArg(Type* tf, LINK linkage); bool passByVal(Type* t); @@ -262,11 +262,7 @@ llvm::CallingConv::ID X86_64TargetABI::callingConv(LINK l) { } } -bool X86_64TargetABI::returnInArg(TypeFunction* tf) { - if (tf->isref) - return false; - - Type* rt = tf->next; +bool X86_64TargetABI::returnInArg(Type* rt, LINK /*linkage*/) { return passByVal(rt); } diff --git a/gen/abi-x86.cpp b/gen/abi-x86.cpp index be09fb9dd52..b4f50d4316a 100644 --- a/gen/abi-x86.cpp +++ b/gen/abi-x86.cpp @@ -83,6 +83,21 @@ struct X86TargetABI : TargetABI return (rt->ty == Tstruct || rt->ty == Tcomplex64 || rt->ty == Tcomplex80); } + bool returnInArg(Type* rt, LINK linkage) + { + // D only returns structs on the stack + if (linkage == LINKd) + { + return rt->ty == Tstruct + || rt->ty == Tsarray + ; + } + // other ABI's follow C, which is cdouble and creal returned on the stack + // as well as structs + else + return (rt->ty == Tstruct || rt->ty == Tcomplex64 || rt->ty == Tcomplex80); + } + bool passByVal(Type* t) { return t->toBasetype()->ty == Tstruct || t->toBasetype()->ty == Tsarray; diff --git a/gen/abi.cpp b/gen/abi.cpp index 2a854f9ef7b..a0a642aac6f 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -103,6 +103,16 @@ LLValue* ABIRewrite::loadFromMemory(LLValue* address, LLType* asType, const char ////////////////////////////////////////////////////////////////////////////// +bool TargetABI::returnInArg(TypeFunction* tf) +{ + if (tf->isref) + return false; + + return returnInArg(tf->next->toBasetype(), tf->linkage); +} + +////////////////////////////////////////////////////////////////////////////// + void TargetABI::rewriteVarargs(IrFuncTy& fty, std::vector& args) { for (unsigned i = 0; i < args.size(); ++i) @@ -159,16 +169,12 @@ struct UnknownTargetABI : TargetABI } } - bool returnInArg(TypeFunction* tf) + bool returnInArg(Type* rt, LINK /*linkage*/) { - if (tf->isref) - return false; - // Return structs and static arrays on the stack. The latter is needed // because otherwise LLVM tries to actually return the array in a number // of physical registers, which leads, depending on the target, to // either horrendous codegen or backend crashes. - Type* rt = tf->next->toBasetype(); return (rt->ty == Tstruct || rt->ty == Tsarray); } @@ -224,6 +230,11 @@ struct IntrinsicABI : TargetABI return false; } + bool returnInArg(Type* /*t*/, LINK /*linkage*/) + { + return false; + } + bool passByVal(Type* t) { return false; diff --git a/gen/abi.h b/gen/abi.h index ff0c9483d48..505870043c4 100644 --- a/gen/abi.h +++ b/gen/abi.h @@ -101,7 +101,8 @@ struct TargetABI /// Returns true if the function uses sret (struct return), /// meaning that it gets a hidden pointer to a struct which has been pre- /// allocated by the caller. - virtual bool returnInArg(TypeFunction* tf) = 0; + virtual bool returnInArg(TypeFunction* tf); + virtual bool returnInArg(Type* returntype, LINK linkage) = 0; /// Returns true if the type is passed by value virtual bool passByVal(Type* t) = 0; diff --git a/gen/runtime.cpp b/gen/runtime.cpp index 2dbc5061bec..fe567eb4e92 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -139,6 +139,9 @@ llvm::Function* LLVM_D_GetRuntimeFunction(const Loc &loc, llvm::Module* target, return fn; fn = M->getFunction(name); + + std::cout << name << std::endl; + assert(fn && "Runtime function not found."); LLFunctionType* fnty = fn->getFunctionType(); @@ -226,6 +229,40 @@ static void ensureDecl(DECL *decl, const char *msg) } } +static LLFunction *LLVM_D_BuildFunctionFwdDecl(Type *returntype, + llvm::StringRef fname, + std::vector params, + bool isVarArg, + llvm::Module *M, + LINK linkage = LINKc) +{ + LLType *rt = DtoType(returntype); + bool sret = gABI->returnInArg(returntype, linkage); + LLFunctionType *fty; // Initialized below + if (sret) + { + params.insert(params.begin(), rt->getPointerTo()); + LLType* voidTy = DtoType(Type::tvoid); + fty = LLFunctionType::get(voidTy, params, isVarArg); + } + else if (!params.empty()) + { + fty = LLFunctionType::get(rt, params, isVarArg); + } + else + { + fty = LLFunctionType::get(rt, isVarArg); + } + + LLFunction *fn = LLFunction::Create(fty, LLGlobalValue::ExternalLinkage, fname, M); + if (sret) { + fn->addAttribute(1, LDC_ATTRIBUTE(StructRet)); + fn->addAttribute(1, LDC_ATTRIBUTE(NoAlias)); + } + fn->setCallingConv(gABI->callingConv(linkage)); + return fn; +} + static void LLVM_D_BuildRuntimeModule() { Logger::println("building runtime module"); @@ -357,35 +394,16 @@ static void LLVM_D_BuildRuntimeModule() ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// - // void _d_assert( char[] file, uint line ) - // void _d_arraybounds(ModuleInfo* m, uint line) - { - llvm::StringRef fname("_d_assert"); - llvm::StringRef fname2("_d_arraybounds"); - LLType *types[] = { stringTy, intTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - } + // void _d_assert(string file, uint line) + // void _d_arraybounds(string file, uint line) + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_assert", { stringTy, intTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_arraybounds", { stringTy, intTy }, false, M); // void _d_switch_error(ModuleInfo* m, uint line) - { - llvm::StringRef fname("_d_switch_error"); - LLType *types[] = { - moduleInfoPtrTy, - intTy - }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_switch_error", { moduleInfoPtrTy, intTy }, false, M); // void _d_assert_msg(string msg, string file, uint line) - { - llvm::StringRef fname("_d_assert_msg"); - LLType *types[] = { stringTy, stringTy, intTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_assert_msg", { stringTy, stringTy, intTy }, false, M); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -393,144 +411,71 @@ static void LLVM_D_BuildRuntimeModule() // void* _d_allocmemory(size_t sz) - { - llvm::StringRef fname("_d_allocmemory"); - LLType *types[] = { sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_allocmemory", { sizeTy }, false, M) + ->setAttributes(Attr_NoAlias); // void* _d_allocmemoryT(TypeInfo ti) - { - llvm::StringRef fname("_d_allocmemoryT"); - LLType *types[] = { typeInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_allocmemoryT", { typeInfoTy }, false, M) + ->setAttributes(Attr_NoAlias); + // void[] _d_newarrayT(TypeInfo ti, size_t length) // void[] _d_newarrayiT(TypeInfo ti, size_t length) // void[] _d_newarrayU(TypeInfo ti, size_t length) - { - llvm::StringRef fname("_d_newarrayT"); - llvm::StringRef fname2("_d_newarrayiT"); - llvm::StringRef fname3("_d_newarrayU"); - LLType *types[] = { typeInfoTy, sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayT", { typeInfoTy, sizeTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayiT", { typeInfoTy, sizeTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayU", { typeInfoTy, sizeTy }, false, M); + // void[] _d_newarraymT(TypeInfo ti, size_t length, size_t* dims) // void[] _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims) - { - llvm::StringRef fname("_d_newarraymT"); - llvm::StringRef fname2("_d_newarraymiT"); - LLType *types[] = { typeInfoTy, sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarraymT", { typeInfoTy, sizeTy }, true, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarraymiT", { typeInfoTy, sizeTy }, true, M); // void[] _d_arraysetlengthT(TypeInfo ti, size_t newlength, void[] *array) // void[] _d_arraysetlengthiT(TypeInfo ti, size_t newlength, void[] *array) - { - llvm::StringRef fname("_d_arraysetlengthT"); - llvm::StringRef fname2("_d_arraysetlengthiT"); - LLType *types[] = { - typeInfoTy, - sizeTy, - voidArrayPtrTy - }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arraysetlengthT", + { typeInfoTy, sizeTy, voidArrayPtrTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arraysetlengthiT", + { typeInfoTy, sizeTy, voidArrayPtrTy }, false, M); // byte[] _d_arrayappendcTX(TypeInfo ti, ref byte[] px, size_t n) - { - llvm::StringRef fname("_d_arrayappendcTX"); - LLType *types[] = { typeInfoTy, voidArrayPtrTy, sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arrayappendcTX", + { typeInfoTy, voidArrayPtrTy, sizeTy }, false, M); + // void[] _d_arrayappendT(TypeInfo ti, byte[]* px, byte[] y) - { - llvm::StringRef fname("_d_arrayappendT"); - LLType *types[] = { typeInfoTy, voidArrayPtrTy, voidArrayTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendT", + { typeInfoTy, voidArrayPtrTy, voidArrayTy }, false, M); + // void[] _d_arrayappendcd(ref char[] x, dchar c) - { - llvm::StringRef fname("_d_arrayappendcd"); - LLType *types[] = { getPtrToType(stringTy), intTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } // void[] _d_arrayappendwd(ref wchar[] x, dchar c) - { - llvm::StringRef fname("_d_arrayappendwd"); - LLType *types[] = { getPtrToType(wstringTy), intTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendcd", + { getPtrToType(stringTy), intTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendwd", + { getPtrToType(wstringTy), intTy }, false, M); + // byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y) - { - llvm::StringRef fname("_d_arraycatT"); - LLType *types[] = { typeInfoTy, voidArrayTy, voidArrayTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arraycatT", + { typeInfoTy, voidArrayTy, voidArrayTy }, false, M); + // byte[] _d_arraycatnT(TypeInfo ti, uint n, ...) - { - llvm::StringRef fname("_d_arraycatnT"); - LLType *types[] = { typeInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arraycatnT", { typeInfoTy }, true, M); // Object _d_newclass(const ClassInfo ci) - { - llvm::StringRef fname("_d_newclass"); - LLType *types[] = { classInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias); - } + LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_newclass", + { classInfoTy }, false, M) + ->setAttributes(Attr_NoAlias); // void _d_delarray_t(Array *p, TypeInfo ti) - { - llvm::StringRef fname("_d_delarray_t"); - LLType *types[] = { voidArrayPtrTy, typeInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delarray_t", { voidArrayPtrTy, typeInfoTy }, false, M); // void _d_delmemory(void **p) // void _d_delinterface(void **p) // void _d_callfinalizer(void *p) - { - llvm::StringRef fname("_d_delmemory"); - llvm::StringRef fname2("_d_delinterface"); - llvm::StringRef fname3("_d_callfinalizer"); - LLType *types[] = { voidPtrTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delmemory", { voidPtrTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delinterface", { voidPtrTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_callfinalizer", { voidPtrTy }, false, M); - // D2: void _d_delclass(Object* p) - { - llvm::StringRef fname("_d_delclass"); - LLType *types[] = { - rt_ptr(objectTy) - }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + // void _d_delclass(Object* p) + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delclass", { rt_ptr(objectTy) }, false, M); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -538,13 +483,9 @@ static void LLVM_D_BuildRuntimeModule() // array slice copy when assertions are on! // void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen) - { - llvm::StringRef fname("_d_array_slice_copy"); - LLType *types[] = { voidPtrTy, sizeTy, voidPtrTy, sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_1_3_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_array_slice_copy", + { voidPtrTy, sizeTy, voidPtrTy, sizeTy }, false, M) + ->setAttributes(Attr_1_3_NoCapture); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -553,12 +494,8 @@ static void LLVM_D_BuildRuntimeModule() // int _aApplycd1(char[] aa, dg_t dg) #define STR_APPLY1(TY,a,b) \ { \ - llvm::StringRef fname(a); \ - llvm::StringRef fname2(b); \ - LLType *types[] = { TY, rt_dg1() }; \ - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, { TY, rt_dg1() }, false, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, { TY, rt_dg1() }, false, M); \ } STR_APPLY1(stringTy, "_aApplycw1", "_aApplycd1") STR_APPLY1(wstringTy, "_aApplywc1", "_aApplywd1") @@ -568,12 +505,8 @@ static void LLVM_D_BuildRuntimeModule() // int _aApplycd2(char[] aa, dg2_t dg) #define STR_APPLY2(TY,a,b) \ { \ - llvm::StringRef fname(a); \ - llvm::StringRef fname2(b); \ - LLType *types[] = { TY, rt_dg2() }; \ - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, { TY, rt_dg2() }, false, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, { TY, rt_dg2() }, false, M); \ } STR_APPLY2(stringTy, "_aApplycw2", "_aApplycd2") STR_APPLY2(wstringTy, "_aApplywc2", "_aApplywd2") @@ -582,12 +515,8 @@ static void LLVM_D_BuildRuntimeModule() #define STR_APPLY_R1(TY,a,b) \ { \ - llvm::StringRef fname(a); \ - llvm::StringRef fname2(b); \ - LLType *types[] = { TY, rt_dg1() }; \ - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, { TY, rt_dg1() }, false, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, { TY, rt_dg1() }, false, M); \ } STR_APPLY_R1(stringTy, "_aApplyRcw1", "_aApplyRcd1") STR_APPLY_R1(wstringTy, "_aApplyRwc1", "_aApplyRwd1") @@ -596,12 +525,8 @@ static void LLVM_D_BuildRuntimeModule() #define STR_APPLY_R2(TY,a,b) \ { \ - llvm::StringRef fname(a); \ - llvm::StringRef fname2(b); \ - LLType *types[] = { TY, rt_dg2() }; \ - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, { TY, rt_dg2() }, false, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, { TY, rt_dg2() }, false, M); \ } STR_APPLY_R2(stringTy, "_aApplyRcw2", "_aApplyRcd2") STR_APPLY_R2(wstringTy, "_aApplyRwc2", "_aApplyRwd2") @@ -614,13 +539,8 @@ static void LLVM_D_BuildRuntimeModule() // fixes the length for dynamic array casts // size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz) - { - llvm::StringRef fname("_d_array_cast_len"); - LLType *types[] = { sizeTy, sizeTy, sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(sizeTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadNone); - } + LLVM_D_BuildFunctionFwdDecl(Type::tsize_t, "_d_array_cast_len", { sizeTy, sizeTy, sizeTy }, false, M) + ->setAttributes(Attr_ReadNone); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -628,27 +548,19 @@ static void LLVM_D_BuildRuntimeModule() // void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to) // void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to) - { - llvm::StringRef fname("_d_arrayassign"); - llvm::StringRef fname2("_d_arrayctor"); - LLType *types[] = { typeInfoTy, voidArrayTy, voidArrayTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayassign", + { typeInfoTy, voidArrayTy, voidArrayTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayctor", + { typeInfoTy, voidArrayTy, voidArrayTy }, false, M); // void* _d_arraysetassign(void* p, void* value, size_t count, TypeInfo ti) // void* _d_arraysetctor(void* p, void* value, size_t count, TypeInfo ti) - { - llvm::StringRef fname("_d_arraysetassign"); - llvm::StringRef fname2("_d_arraysetctor"); - LLType *types[] = { voidPtrTy, voidPtrTy, sizeTy, typeInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M) - ->setAttributes(Attr_NoAlias); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_arraysetassign", + { voidPtrTy, voidPtrTy, sizeTy, typeInfoTy }, false, M) + ->setAttributes(Attr_NoAlias); + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_arraysetctor", + { voidPtrTy, voidPtrTy, sizeTy, typeInfoTy }, false, M) + ->setAttributes(Attr_NoAlias); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -656,33 +568,20 @@ static void LLVM_D_BuildRuntimeModule() // cast to object // Object _d_toObject(void* p) - { - llvm::StringRef fname("_d_toObject"); - LLType *types[] = { voidPtrTy }; - LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); - } + LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_toObject", { voidPtrTy }, false, M) + ->setAttributes(Attr_ReadOnly_NoUnwind); // cast interface // Object _d_interface_cast(void* p, ClassInfo c) - { - llvm::StringRef fname("_d_interface_cast"); - LLType *types[] = { voidPtrTy, classInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); - } + LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_interface_cast", + { voidPtrTy, classInfoTy }, false, M) + ->setAttributes(Attr_ReadOnly_NoUnwind); // dynamic cast // Object _d_dynamic_cast(Object o, ClassInfo c) - { - llvm::StringRef fname("_d_dynamic_cast"); - LLType *types[] = { objectTy, classInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); - } + LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_dynamic_cast", + { objectTy, classInfoTy }, false, M) + ->setAttributes(Attr_ReadOnly_NoUnwind); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -690,173 +589,95 @@ static void LLVM_D_BuildRuntimeModule() // char[] _adReverseChar(char[] a) // char[] _adSortChar(char[] a) - { - llvm::StringRef fname("_adReverseChar"); - llvm::StringRef fname2("_adSortChar"); - LLType *types[] = { stringTy }; - LLFunctionType* fty = llvm::FunctionType::get(stringTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tchar->arrayOf(), "_adReverseChar", { stringTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tchar->arrayOf(), "_adSortChar", { stringTy }, false, M); // wchar[] _adReverseWchar(wchar[] a) // wchar[] _adSortWchar(wchar[] a) - { - llvm::StringRef fname("_adReverseWchar"); - llvm::StringRef fname2("_adSortWchar"); - LLType *types[] = { wstringTy }; - LLFunctionType* fty = llvm::FunctionType::get(wstringTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::twchar->arrayOf(), "_adReverseWchar", { wstringTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::twchar->arrayOf(), "_adSortWChar", { wstringTy }, false, M); // void[] _adReverse(void[] a, size_t szelem) - { - llvm::StringRef fname("_adReverse"); - LLType *types[] = { rt_array(byteTy), sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoUnwind); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adReverse", + { rt_array(byteTy), sizeTy }, false, M) + ->setAttributes(Attr_NoUnwind); // void[] _adDupT(TypeInfo ti, void[] a) - { - llvm::StringRef fname("_adDupT"); - LLType *types[] = { typeInfoTy, rt_array(byteTy) }; - LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adDupT", + { typeInfoTy, rt_array(byteTy) }, false, M); // int _adEq(void[] a1, void[] a2, TypeInfo ti) // int _adCmp(void[] a1, void[] a2, TypeInfo ti) - { - llvm::StringRef fname(_adEq); - llvm::StringRef fname2(_adCmp); - LLType *types[] = { rt_array(byteTy), rt_array(byteTy), typeInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M) - ->setAttributes(Attr_ReadOnly); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint32, _adEq, + { rt_array(byteTy), rt_array(byteTy), typeInfoTy }, false, M) + ->setAttributes(Attr_ReadOnly); + LLVM_D_BuildFunctionFwdDecl(Type::tint32, _adCmp, + { rt_array(byteTy), rt_array(byteTy), typeInfoTy }, false, M) + ->setAttributes(Attr_ReadOnly); // int _adCmpChar(void[] a1, void[] a2) - { - llvm::StringRef fname("_adCmpChar"); - LLType *types[] = { rt_array(byteTy), rt_array(byteTy) }; - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_adCmpChar", + {rt_array(byteTy), rt_array(byteTy)}, false,M) + ->setAttributes(Attr_ReadOnly_NoUnwind); // void[] _adSort(void[] a, TypeInfo ti) - { - llvm::StringRef fname("_adSort"); - LLType *types[] = { rt_array(byteTy), typeInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adSort", + { rt_array(byteTy), typeInfoTy }, false, M); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // size_t _aaLen(AA aa) - { - llvm::StringRef fname("_aaLen"); - LLType *types[] = { aaTy }; - LLFunctionType* fty = llvm::FunctionType::get(sizeTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_NoUnwind_1_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tsize_t, "_aaLen", { aaTy }, false, M) + ->setAttributes(Attr_ReadOnly_NoUnwind_1_NoCapture); // void* _aaGetX(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey) - { - llvm::StringRef fname("_aaGetX"); - LLType *types[] = { aaTy, typeInfoTy, sizeTy, voidPtrTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_1_4_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaGetX", + { aaTy, typeInfoTy, sizeTy, voidPtrTy }, false, M) + ->setAttributes(Attr_1_4_NoCapture); // void* _aaInX(AA aa, TypeInfo keyti, void* pkey) - { - llvm::StringRef fname("_aaInX"); - LLType *types[] = { aaTy, typeInfoTy, voidPtrTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_1_3_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaInX", + { aaTy, typeInfoTy, voidPtrTy }, false, M) + ->setAttributes(Attr_ReadOnly_1_3_NoCapture); // bool _aaDelX(AA aa, TypeInfo keyti, void* pkey) - { - llvm::StringRef fname("_aaDelX"); - LLType *retType = boolTy; - LLType *types[] = { aaTy, typeInfoTy, voidPtrTy }; - LLFunctionType* fty = llvm::FunctionType::get(retType, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_1_3_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tbool, "_aaDelX", + { aaTy, typeInfoTy, voidPtrTy }, false, M) + ->setAttributes(Attr_1_3_NoCapture); // void[] _aaValues(AA aa, size_t keysize, size_t valuesize) - { - llvm::StringRef fname("_aaValues"); - LLType *types[] = { aaTy, sizeTy, sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias_1_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_aaValues", + { aaTy, sizeTy, sizeTy }, false, M) + ->setAttributes(Attr_NoAlias_1_NoCapture); // void* _aaRehash(AA* paa, TypeInfo keyti) - { - llvm::StringRef fname("_aaRehash"); - LLType *types[] = { aaTy, typeInfoTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaRehash", { aaTy, typeInfoTy }, false, M); // void[] _aaKeys(AA aa, size_t keysize) - { - llvm::StringRef fname("_aaKeys"); - LLType *types[] = { aaTy, sizeTy }; - LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias_1_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_aaKeys", + { aaTy, sizeTy }, false, M) + ->setAttributes(Attr_NoAlias_1_NoCapture); // int _aaApply(AA aa, size_t keysize, dg_t dg) - { - llvm::StringRef fname("_aaApply"); - LLType *types[] = { aaTy, sizeTy, rt_dg1() }; - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_1_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaApply", + { aaTy, sizeTy, rt_dg1() }, false, M) + ->setAttributes(Attr_1_NoCapture); // int _aaApply2(AA aa, size_t keysize, dg2_t dg) - { - llvm::StringRef fname("_aaApply2"); - LLType *types[] = { aaTy, sizeTy, rt_dg2() }; - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_1_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaApply2", + { aaTy, sizeTy, rt_dg2() }, false, M) + ->setAttributes(Attr_1_NoCapture); // int _aaEqual(in TypeInfo tiRaw, in AA e1, in AA e2) - { - llvm::StringRef fname("_aaEqual"); - LLType *types[] = { typeInfoTy, aaTy, aaTy }; - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_1_2_NoCapture); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaEqual", + { typeInfoTy, aaTy, aaTy }, false, M) + ->setAttributes(Attr_1_2_NoCapture); + // BB* _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values) - { - llvm::StringRef fname("_d_assocarrayliteralTX"); - LLType *types[] = { aaTypeInfoTy, voidArrayTy, voidArrayTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_assocarrayliteralTX", + { aaTypeInfoTy, voidArrayTy, voidArrayTy }, false, M); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -864,56 +685,34 @@ static void LLVM_D_BuildRuntimeModule() // void _moduleCtor() // void _moduleDtor() - { - llvm::StringRef fname("_moduleCtor"); - llvm::StringRef fname2("_moduleDtor"); - LLFunctionType* fty = llvm::FunctionType::get(voidTy, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_moduleCtor", { }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_moduleDtor", { }, false, M); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // void _d_throw_exception(Object e) - { - llvm::StringRef fname("_d_throw_exception"); - LLType *types[] = { objectTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_throw_exception", { objectTy }, false, M); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // int _d_switch_string(char[][] table, char[] ca) - { - llvm::StringRef fname("_d_switch_string"); - LLType *types[] = { rt_array(stringTy), stringTy }; - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_string", + { rt_array(stringTy), stringTy }, false, M) + ->setAttributes(Attr_ReadOnly); // int _d_switch_ustring(wchar[][] table, wchar[] ca) - { - llvm::StringRef fname("_d_switch_ustring"); - LLType *types[] = { rt_array(wstringTy), wstringTy }; - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_ustring", + { rt_array(wstringTy), wstringTy }, false, M) + ->setAttributes(Attr_ReadOnly); // int _d_switch_dstring(dchar[][] table, dchar[] ca) - { - llvm::StringRef fname("_d_switch_dstring"); - LLType *types[] = { rt_array(dstringTy), dstringTy }; - LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly); - } + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_dstring", + { rt_array(dstringTy), dstringTy }, false, M) + ->setAttributes(Attr_ReadOnly); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -996,17 +795,10 @@ static void LLVM_D_BuildRuntimeModule() } // void _d_hidden_func(Object o) - { - llvm::StringRef fname("_d_hidden_func"); - LLType *types[] = { voidPtrTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_hidden_func", { voidPtrTy }, false, M); // void _d_dso_registry(CompilerDSOData* data) if (global.params.isLinux) { - llvm::StringRef fname("_d_dso_registry"); - llvm::StructType* dsoDataTy = llvm::StructType::get( sizeTy, // version getPtrToType(voidPtrTy), // slot @@ -1014,28 +806,12 @@ static void LLVM_D_BuildRuntimeModule() getPtrToType(moduleInfoPtrTy), // _minfo_end NULL ); - - llvm::Type* params[] = { - getPtrToType(dsoDataTy) - }; - llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, params, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_dso_registry", { getPtrToType(dsoDataTy) }, false, M); } - // extern (C) void _d_cover_register2(string filename, size_t[] valid, uint[] data, ubyte minPercent) - // as defined in druntime/rt/cover.d. + // void _d_cover_register2(string filename, size_t[] valid, uint[] data, ubyte minPercent) if (global.params.cov) { - llvm::StringRef fname("_d_cover_register2"); - - LLType* params[] = { - stringTy, - rt_array(sizeTy), - rt_array(intTy), - byteTy - }; - - LLFunctionType* fty = LLFunctionType::get(voidTy, params, false); - llvm::Function* fn = LLFunction::Create(fty, LLGlobalValue::ExternalLinkage, fname, M); - fn->setCallingConv(gABI->callingConv(LINKc)); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_cover_register2", + { stringTy, rt_array(sizeTy), rt_array(intTy), byteTy }, false, M); } } From 0846c274b76eb7fc0415a64176bf9df98d52de45 Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Sat, 18 Apr 2015 14:26:42 +0200 Subject: [PATCH 2/4] Fix C++03 compilation, fix druntime calls to check for sret using helperfunction. Enable sret-arrays for Win64 --- gen/aa.cpp | 3 +- gen/abi-win64.cpp | 2 +- gen/abi-x86-64.cpp | 2 +- gen/arrays.cpp | 79 +++++----- gen/classes.cpp | 34 ++--- gen/runtime.cpp | 374 ++++++++++++++++++++++++++++----------------- gen/runtime.h | 5 + gen/tocall.cpp | 10 +- 8 files changed, 294 insertions(+), 215 deletions(-) diff --git a/gen/aa.cpp b/gen/aa.cpp index 067bb3c8f17..b5bdaea2f17 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -101,8 +101,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) }; // call - llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arraybounds"); - gIR->CreateCallOrInvoke(errorfn, args); + LLVM_D_CallRuntimeFunction(loc, "_d_arraybounds", args); // the function does not return gIR->ir->CreateUnreachable(); diff --git a/gen/abi-win64.cpp b/gen/abi-win64.cpp index 9ae69f30537..c6c6784b374 100644 --- a/gen/abi-win64.cpp +++ b/gen/abi-win64.cpp @@ -55,7 +55,7 @@ struct Win64TargetABI : TargetABI bool isAggregate(Type* t) { TY ty = t->ty; - return ty == Tstruct || ty == Tsarray || /*ty == Tarray ||*/ ty == Tdelegate + return ty == Tstruct || ty == Tsarray || ty == Tarray || ty == Tdelegate || t->iscomplex(); } diff --git a/gen/abi-x86-64.cpp b/gen/abi-x86-64.cpp index f09720645b3..b372931527d 100644 --- a/gen/abi-x86-64.cpp +++ b/gen/abi-x86-64.cpp @@ -221,7 +221,7 @@ struct X86_64TargetABI : TargetABI { llvm::CallingConv::ID callingConv(LINK l); - bool returnInArg(Type* tf, LINK linkage); + bool returnInArg(Type* rt, LINK linkage); bool passByVal(Type* t); diff --git a/gen/arrays.cpp b/gen/arrays.cpp index b8dda90aad4..f3c46cf4c6c 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -213,15 +213,14 @@ void DtoArrayAssign(Loc& loc, DValue *array, DValue *value, int op) assert(t->nextOf()); Type *elemType = t->nextOf()->toBasetype(); - LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, op == TOKconstruct ? "_d_arrayctor" : "_d_arrayassign"); LLValue* args[] = { DtoTypeInfoOf(elemType), - DtoAggrPaint(DtoSlice(value), fn->getFunctionType()->getParamType(1)), - DtoAggrPaint(DtoSlice(array), fn->getFunctionType()->getParamType(2)) + DtoAggrPaint(DtoSlice(value), DtoType(Type::tvoid->arrayOf())), + DtoAggrPaint(DtoSlice(array), DtoType(Type::tvoid->arrayOf())) }; - LLCallSite call = gIR->CreateCallOrInvoke(fn, args, ".array"); - call.setCallingConv(llvm::CallingConv::C); + LLVM_D_CallRuntimeFunction(loc, (op == TOKconstruct) ? "_d_arrayctor" : "_d_arrayassign", + args, ".array"); } // If op is TOKconstruct, does construction of an array; @@ -237,7 +236,6 @@ void DtoArraySetAssign(Loc& loc, DValue *array, DValue *value, int op) LLValue *ptr = DtoArrayPtr(array); LLValue *len = DtoArrayLen(array); - LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, op == TOKconstruct ? "_d_arraysetctor" : "_d_arraysetassign"); LLValue* args[] = { DtoBitCast(ptr, getVoidPtrType()), DtoBitCast(makeLValue(loc, value), getVoidPtrType()), @@ -245,8 +243,8 @@ void DtoArraySetAssign(Loc& loc, DValue *array, DValue *value, int op) DtoTypeInfoOf(array->type->toBasetype()->nextOf()->toBasetype()) }; - LLCallSite call = gIR->CreateCallOrInvoke(fn, args, ".newptr"); - call.setCallingConv(llvm::CallingConv::C); + LLVM_D_CallRuntimeFunction(loc, (op == TOKconstruct) ? "_d_arraysetctor" : "_d_arraysetassign", + args, ".newptr"); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -510,8 +508,8 @@ static void copySlice(Loc& loc, LLValue* dstarr, LLValue* sz1, LLValue* srcarr, { if (global.params.useAssert || gIR->emitArrayBoundsChecks()) { - LLValue* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_array_slice_copy"); - gIR->CreateCallOrInvoke4(fn, dstarr, sz1, srcarr, sz2); + LLValue* args[] = { dstarr, sz1, srcarr, sz2 }; + LLVM_D_CallRuntimeFunction(loc, "_d_array_slice_copy", args); } else { @@ -624,10 +622,9 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default const char* fnname = defaultInit ? (zeroInit ? "_d_newarrayT" : "_d_newarrayiT") : "_d_newarrayU"; - LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, fnname); - // call allocator - LLValue* newArray = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction(); + LLValue* args[] = { arrayTypeInfo, arrayLen }; + LLValue* newArray = LLVM_D_CallRuntimeFunction(loc, fnname, args, ".gc_mem"); return getSlice(arrayType, newArray); } @@ -653,9 +650,7 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size const char* fnname = zeroInit ? "_d_newarraymT" : "_d_newarraymiT"; - LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, fnname); - - std::vector args; + llvm::SmallVector args; args.reserve(ndims+2); args.push_back(arrayTypeInfo); args.push_back(DtoConstSize_t(ndims)); @@ -665,7 +660,7 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size args.push_back(dims[i]->getRVal()); // call allocator - LLValue* newptr = gIR->CreateCallOrInvoke(fn, args, ".gc_mem").getInstruction(); + LLValue* newptr = LLVM_D_CallRuntimeFunction(loc, fnname, args, ".gc_mem"); IF_LOG Logger::cout() << "final ptr = " << *newptr << '\n'; @@ -687,14 +682,13 @@ DSliceValue* DtoResizeDynArray(Loc& loc, Type* arrayType, DValue* array, LLValue bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit(); // call runtime - LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" ); - + const char* fnname = zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT"; LLValue* args[] = { DtoTypeInfoOf(arrayType), newdim, - DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(2)) + DtoBitCast(array->getLVal(), DtoType(Type::tvoid->arrayOf()->pointerTo())) }; - LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".gc_mem").getInstruction(); + LLValue* newArray = LLVM_D_CallRuntimeFunction(loc, fnname, args, ".gc_mem"); return getSlice(arrayType, newArray); } @@ -714,14 +708,13 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e // otherwise a ~= a[$-i] won't work correctly DValue *expVal = toElem(exp); - LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arrayappendcTX"); LLValue* args[] = { DtoTypeInfoOf(arrayType), - DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(1)), + DtoBitCast(array->getLVal(), DtoType(Type::tint8->arrayOf()->pointerTo())), DtoConstSize_t(1) }; + LLValue* appendedArray = LLVM_D_CallRuntimeFunction(loc, "_d_arrayappendcTX", args, ".appendedArray"); - LLValue* appendedArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction(); appendedArray = DtoAggrPaint(appendedArray, DtoType(arrayType)); LLValue* val = DtoArrayPtr(array); @@ -739,19 +732,18 @@ DSliceValue* DtoCatAssignArray(Loc& loc, DValue* arr, Expression* exp) Type *arrayType = arr->getType(); // Prepare arguments - LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arrayappendT"); LLSmallVector args; // TypeInfo ti args.push_back(DtoTypeInfoOf(arrayType)); // byte[] *px - args.push_back(DtoBitCast(arr->getLVal(), fn->getFunctionType()->getParamType(1))); + args.push_back(DtoBitCast(arr->getLVal(), DtoType(Type::tint8->arrayOf()->pointerTo()))); // byte[] y LLValue *y = DtoSlice(toElem(exp)); - y = DtoAggrPaint(y, fn->getFunctionType()->getParamType(2)); + y = DtoAggrPaint(y, DtoType(Type::tint8->arrayOf())); args.push_back(y); // Call _d_arrayappendT - LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction(); + LLValue* newArray = LLVM_D_CallRuntimeFunction(loc, "_d_arrayappendT", args, ".appendedArray"); return getSlice(arrayType, newArray); } @@ -765,10 +757,11 @@ DSliceValue* DtoCatArrays(Loc& loc, Type* arrayType, Expression* exp1, Expressio std::vector args; LLFunction* fn = 0; + const char* fname = NULL; if (exp1->op == TOKcat) { // handle multiple concat - fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arraycatnT"); + fname = "_d_arraycatnT"; args.push_back(DtoSlicePtr(toElem(exp2))); CatExp *ce = static_cast(exp1); @@ -788,21 +781,21 @@ DSliceValue* DtoCatArrays(Loc& loc, Type* arrayType, Expression* exp1, Expressio } else { - fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arraycatT"); + fname = "_d_arraycatT"; // TypeInfo ti args.push_back(DtoTypeInfoOf(arrayType)); // byte[] x LLValue *val = DtoLoad(DtoSlicePtr(toElem(exp1))); - val = DtoAggrPaint(val, fn->getFunctionType()->getParamType(1)); + val = DtoAggrPaint(val, DtoType(Type::tint8->arrayOf())); args.push_back(val); // byte[] y val = DtoLoad(DtoSlicePtr(toElem(exp2))); - val = DtoAggrPaint(val, fn->getFunctionType()->getParamType(2)); + val = DtoAggrPaint(val, DtoType(Type::tint8->arrayOf())); args.push_back(val); } - LLValue *newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction(); + LLValue *newArray = LLVM_D_CallRuntimeFunction(loc, fname, args, ".appendedArray"); return getSlice(arrayType, newArray); } @@ -815,15 +808,16 @@ DSliceValue* DtoAppendDChar(Loc& loc, DValue* arr, Expression* exp, const char * // Prepare arguments LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, func); + unsigned arg_offset = fn->hasStructRetAttr() ? 1 : 0; // argument numbering offset due to sret LLValue* args[] = { // ref string x - DtoBitCast(arr->getLVal(), fn->getFunctionType()->getParamType(0)), + DtoBitCast(arr->getLVal(), fn->getFunctionType()->getParamType(arg_offset + 0)), // dchar c - DtoBitCast(valueToAppend->getRVal(), fn->getFunctionType()->getParamType(1)) + DtoBitCast(valueToAppend->getRVal(), fn->getFunctionType()->getParamType(arg_offset + 1)) }; // Call function - LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction(); + LLValue* newArray = LLVM_D_CallRuntimeFunction(loc, func, args, ".appendedArray"); return getSlice(arrayType, newArray); } @@ -853,6 +847,7 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue IF_LOG Logger::println("comparing arrays"); LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, func); assert(fn); + unsigned arg_offset = fn->hasStructRetAttr() ? 1 : 0; // argument numbering offset due to sret // find common dynamic array type Type* commonType = l->getType()->toBasetype()->nextOf()->arrayOf(); @@ -862,7 +857,7 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue l = DtoCastArray(loc, l, commonType); r = DtoCastArray(loc, r, commonType); - LLSmallVector args; + LLSmallVector args; // get values, reinterpret cast to void[] args.push_back(DtoAggrPaint(l->getRVal(), DtoArrayType(LLType::getInt8Ty(gIR->context())))); @@ -872,10 +867,10 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue if (useti) { Type* t = l->getType(); LLValue* tival = DtoTypeInfoOf(t); - args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(2))); + args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(arg_offset + 2))); } - LLCallSite call = gIR->CreateCallOrInvoke(fn, args); + LLCallSite call = LLVM_D_CallRuntimeFunction(loc, func, args); return call.getInstruction(); } @@ -933,8 +928,7 @@ LLValue* DtoArrayCastLength(Loc& loc, LLValue* len, LLType* elemty, LLType* newe LLConstantInt::get(DtoSize_t(), nsz, false) }; - LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_array_cast_len"); - return gIR->CreateCallOrInvoke(fn, args).getInstruction(); + return LLVM_D_CallRuntimeFunction(loc, "_d_array_cast_len", args); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1182,8 +1176,7 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun args.push_back(c); // call - llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arraybounds"); - gIR->CreateCallOrInvoke(errorfn, args); + LLVM_D_CallRuntimeFunction(loc, "_d_arraybounds", args); // the function does not return gIR->ir->CreateUnreachable(); diff --git a/gen/classes.cpp b/gen/classes.cpp index c652edb7828..bf41ada4a6a 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -103,9 +103,8 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp) // default allocator else { - llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_newclass"); LLConstant* ci = DtoBitCast(getIrAggr(tc->sym)->getClassInfoSymbol(), DtoType(Type::typeinfoclass->type)); - mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction(); + mem = LLVM_D_CallRuntimeFunction(loc, "_d_newclass", ci, ".newclass_gc_alloc"); mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc"); } @@ -185,14 +184,12 @@ void DtoInitClass(TypeClass* tc, LLValue* dst) void DtoFinalizeClass(Loc& loc, LLValue* inst) { - // get runtime function - llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_callfinalizer"); // build args LLValue* arg[] = { - DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp") + DtoBitCast(inst, DtoType(Type::tvoidptr), ".tmp") }; - // call - gIR->CreateCallOrInvoke(fn, arg, ""); + // call runtime function + LLVM_D_CallRuntimeFunction(loc, "_d_callfinalizer", arg); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -352,18 +349,14 @@ DValue* DtoDynamicCastObject(Loc& loc, DValue* val, Type* _to) DValue* DtoCastInterfaceToObject(Loc& loc, DValue* val, Type* to) { - // call: - // Object _d_toObject(void* p) - - llvm::Function* func = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_toObject"); - LLFunctionType* funcTy = func->getFunctionType(); + // call: Object _d_toObject(void* p) // void* p LLValue* tmp = val->getRVal(); - tmp = DtoBitCast(tmp, funcTy->getParamType(0)); + tmp = DtoBitCast(tmp, DtoType(Type::tvoidptr)); // call it - LLValue* ret = gIR->CreateCallOrInvoke(func, tmp).getInstruction(); + LLValue* ret = LLVM_D_CallRuntimeFunction(loc, "_d_toObject", tmp); // cast return value if (to != NULL) @@ -378,18 +371,14 @@ DValue* DtoCastInterfaceToObject(Loc& loc, DValue* val, Type* to) DValue* DtoDynamicCastInterface(Loc& loc, DValue* val, Type* _to) { - // call: - // Object _d_interface_cast(void* p, ClassInfo c) + // call: Object _d_interface_cast(void* p, ClassInfo c) DtoResolveClass(ClassDeclaration::object); DtoResolveClass(Type::typeinfoclass); - llvm::Function* func = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_interface_cast"); - LLFunctionType* funcTy = func->getFunctionType(); - // void* p LLValue* ptr = val->getRVal(); - ptr = DtoBitCast(ptr, funcTy->getParamType(0)); + ptr = DtoBitCast(ptr, DtoType(Type::tvoidptr)); // ClassInfo c TypeClass* to = static_cast(_to->toBasetype()); @@ -397,10 +386,11 @@ DValue* DtoDynamicCastInterface(Loc& loc, DValue* val, Type* _to) LLValue* cinfo = getIrAggr(to->sym)->getClassInfoSymbol(); // unfortunately this is needed as the implementation of object differs somehow from the declaration // this could happen in user code as well :/ - cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); + cinfo = DtoBitCast(cinfo, DtoType(Type::typeinfoclass->type)); // call it - LLValue* ret = gIR->CreateCallOrInvoke2(func, ptr, cinfo).getInstruction(); + LLValue* args[] = { ptr, cinfo }; + LLValue* ret = LLVM_D_CallRuntimeFunction(loc, "_d_interface_cast", args); // cast return value ret = DtoBitCast(ret, DtoType(_to)); diff --git a/gen/runtime.cpp b/gen/runtime.cpp index fe567eb4e92..1165867acf8 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -140,8 +140,6 @@ llvm::Function* LLVM_D_GetRuntimeFunction(const Loc &loc, llvm::Module* target, fn = M->getFunction(name); - std::cout << name << std::endl; - assert(fn && "Runtime function not found."); LLFunctionType* fnty = fn->getFunctionType(); @@ -153,6 +151,31 @@ llvm::Function* LLVM_D_GetRuntimeFunction(const Loc &loc, llvm::Module* target, ////////////////////////////////////////////////////////////////////////////////////////////////// +LLValue* LLVM_D_CallRuntimeFunction(const Loc &loc, const char* name, + llvm::ArrayRef args, const char* invokename) +{ + LLFunction* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, name); + + bool sret = fn->hasStructRetAttr(); + if (sret) { + size_t alignsize = 8; // FIXME: alignment size of return type + LLValue* sret_storage = DtoRawAlloca(fn->getArgumentList().front().getType()->getPointerElementType(), + alignsize, invokename ? invokename : ".srettmp"); + + llvm::SmallVector vec; + vec.push_back(sret_storage); + vec.insert(vec.end(), args.begin(), args.end()); + + gIR->CreateCallOrInvoke(fn, vec); + + return DtoLoad(sret_storage); + } else { + return gIR->CreateCallOrInvoke(fn, args, invokename ? invokename : "").getInstruction(); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////// + llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(Loc& loc, llvm::Module* target, const char* name) { LLGlobalVariable* gv = target->getNamedGlobal(name); @@ -231,7 +254,7 @@ static void ensureDecl(DECL *decl, const char *msg) static LLFunction *LLVM_D_BuildFunctionFwdDecl(Type *returntype, llvm::StringRef fname, - std::vector params, + llvm::ArrayRef params, bool isVarArg, llvm::Module *M, LINK linkage = LINKc) @@ -241,9 +264,11 @@ static LLFunction *LLVM_D_BuildFunctionFwdDecl(Type *returntype, LLFunctionType *fty; // Initialized below if (sret) { - params.insert(params.begin(), rt->getPointerTo()); + llvm::SmallVector vec; + vec.push_back(rt->getPointerTo()); + vec.insert(vec.end(), params.begin(), params.end()); LLType* voidTy = DtoType(Type::tvoid); - fty = LLFunctionType::get(voidTy, params, isVarArg); + fty = LLFunctionType::get(voidTy, vec, isVarArg); } else if (!params.empty()) { @@ -396,14 +421,23 @@ static void LLVM_D_BuildRuntimeModule() // void _d_assert(string file, uint line) // void _d_arraybounds(string file, uint line) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_assert", { stringTy, intTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_arraybounds", { stringTy, intTy }, false, M); + { + LLType* args[] = { stringTy, intTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_assert", args, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_arraybounds", args, false, M); + } // void _d_switch_error(ModuleInfo* m, uint line) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_switch_error", { moduleInfoPtrTy, intTy }, false, M); - + { + LLType* args[] = { moduleInfoPtrTy, intTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_switch_error", args, false, M); + } + // void _d_assert_msg(string msg, string file, uint line) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_assert_msg", { stringTy, stringTy, intTy }, false, M); + { + LLType* args[] = { stringTy, stringTy, intTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_assert_msg", args, false, M); + } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -411,71 +445,88 @@ static void LLVM_D_BuildRuntimeModule() // void* _d_allocmemory(size_t sz) - LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_allocmemory", { sizeTy }, false, M) + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_allocmemory", sizeTy, false, M) ->setAttributes(Attr_NoAlias); // void* _d_allocmemoryT(TypeInfo ti) - LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_allocmemoryT", { typeInfoTy }, false, M) + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_allocmemoryT", typeInfoTy, false, M) ->setAttributes(Attr_NoAlias); // void[] _d_newarrayT(TypeInfo ti, size_t length) // void[] _d_newarrayiT(TypeInfo ti, size_t length) // void[] _d_newarrayU(TypeInfo ti, size_t length) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayT", { typeInfoTy, sizeTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayiT", { typeInfoTy, sizeTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayU", { typeInfoTy, sizeTy }, false, M); + { + LLType* args[] = { typeInfoTy, sizeTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayT", args, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayiT", args, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarrayU", args, false, M); // void[] _d_newarraymT(TypeInfo ti, size_t length, size_t* dims) // void[] _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarraymT", { typeInfoTy, sizeTy }, true, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarraymiT", { typeInfoTy, sizeTy }, true, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarraymT", args, true, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_newarraymiT", args, true, M); + } // void[] _d_arraysetlengthT(TypeInfo ti, size_t newlength, void[] *array) // void[] _d_arraysetlengthiT(TypeInfo ti, size_t newlength, void[] *array) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arraysetlengthT", - { typeInfoTy, sizeTy, voidArrayPtrTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arraysetlengthiT", - { typeInfoTy, sizeTy, voidArrayPtrTy }, false, M); + { + LLType* args[] = { typeInfoTy, sizeTy, voidArrayPtrTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arraysetlengthT", args, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arraysetlengthiT", args, false, M); + } // byte[] _d_arrayappendcTX(TypeInfo ti, ref byte[] px, size_t n) - LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arrayappendcTX", - { typeInfoTy, voidArrayPtrTy, sizeTy }, false, M); + { + LLType* args[] = { typeInfoTy, voidArrayPtrTy, sizeTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arrayappendcTX", args, false, M); + } // void[] _d_arrayappendT(TypeInfo ti, byte[]* px, byte[] y) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendT", - { typeInfoTy, voidArrayPtrTy, voidArrayTy }, false, M); + { + LLType* args[] = { typeInfoTy, voidArrayPtrTy, voidArrayTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendT", args, false, M); + } // void[] _d_arrayappendcd(ref char[] x, dchar c) + { + LLType* args[] = { getPtrToType(stringTy), intTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendcd", args, false, M); + } + // void[] _d_arrayappendwd(ref wchar[] x, dchar c) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendcd", - { getPtrToType(stringTy), intTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendwd", - { getPtrToType(wstringTy), intTy }, false, M); + { + LLType* args[] = { getPtrToType(wstringTy), intTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayappendwd", args, false, M); + } // byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y) - LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arraycatT", - { typeInfoTy, voidArrayTy, voidArrayTy }, false, M); + { + LLType* args[] = { typeInfoTy, voidArrayTy, voidArrayTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arraycatT", args, false, M); + } // byte[] _d_arraycatnT(TypeInfo ti, uint n, ...) - LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arraycatnT", { typeInfoTy }, true, M); + LLVM_D_BuildFunctionFwdDecl(Type::tint8->arrayOf(), "_d_arraycatnT", typeInfoTy, true, M); // Object _d_newclass(const ClassInfo ci) - LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_newclass", - { classInfoTy }, false, M) + LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_newclass", classInfoTy, false, M) ->setAttributes(Attr_NoAlias); // void _d_delarray_t(Array *p, TypeInfo ti) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delarray_t", { voidArrayPtrTy, typeInfoTy }, false, M); + { + LLType* args[] = { voidArrayPtrTy, typeInfoTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delarray_t", args, false, M); + } // void _d_delmemory(void **p) // void _d_delinterface(void **p) // void _d_callfinalizer(void *p) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delmemory", { voidPtrTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delinterface", { voidPtrTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_callfinalizer", { voidPtrTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delmemory", voidPtrTy, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delinterface", voidPtrTy, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_callfinalizer", voidPtrTy, false, M); // void _d_delclass(Object* p) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delclass", { rt_ptr(objectTy) }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_delclass", rt_ptr(objectTy), false, M); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -483,9 +534,11 @@ static void LLVM_D_BuildRuntimeModule() // array slice copy when assertions are on! // void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_array_slice_copy", - { voidPtrTy, sizeTy, voidPtrTy, sizeTy }, false, M) - ->setAttributes(Attr_1_3_NoCapture); + { + LLType* args[] = { voidPtrTy, sizeTy, voidPtrTy, sizeTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_array_slice_copy", args, false, M) + ->setAttributes(Attr_1_3_NoCapture); + } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -494,8 +547,9 @@ static void LLVM_D_BuildRuntimeModule() // int _aApplycd1(char[] aa, dg_t dg) #define STR_APPLY1(TY,a,b) \ { \ - LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, { TY, rt_dg1() }, false, M); \ - LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, { TY, rt_dg1() }, false, M); \ + LLType* args[] = { TY, rt_dg1() }; \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, args, false, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, args, false, M); \ } STR_APPLY1(stringTy, "_aApplycw1", "_aApplycd1") STR_APPLY1(wstringTy, "_aApplywc1", "_aApplywd1") @@ -505,8 +559,9 @@ static void LLVM_D_BuildRuntimeModule() // int _aApplycd2(char[] aa, dg2_t dg) #define STR_APPLY2(TY,a,b) \ { \ - LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, { TY, rt_dg2() }, false, M); \ - LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, { TY, rt_dg2() }, false, M); \ + LLType* args[] = { TY, rt_dg2() }; \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, args, false, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, args, false, M); \ } STR_APPLY2(stringTy, "_aApplycw2", "_aApplycd2") STR_APPLY2(wstringTy, "_aApplywc2", "_aApplywd2") @@ -515,8 +570,9 @@ static void LLVM_D_BuildRuntimeModule() #define STR_APPLY_R1(TY,a,b) \ { \ - LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, { TY, rt_dg1() }, false, M); \ - LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, { TY, rt_dg1() }, false, M); \ + LLType* args[] = { TY, rt_dg1() }; \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, args, false, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, args, false, M); \ } STR_APPLY_R1(stringTy, "_aApplyRcw1", "_aApplyRcd1") STR_APPLY_R1(wstringTy, "_aApplyRwc1", "_aApplyRwd1") @@ -525,8 +581,9 @@ static void LLVM_D_BuildRuntimeModule() #define STR_APPLY_R2(TY,a,b) \ { \ - LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, { TY, rt_dg2() }, false, M); \ - LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, { TY, rt_dg2() }, false, M); \ + LLType* args[] = { TY, rt_dg2() }; \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, a, args, false, M); \ + LLVM_D_BuildFunctionFwdDecl(Type::tint32, b, args, false, M); \ } STR_APPLY_R2(stringTy, "_aApplyRcw2", "_aApplyRcd2") STR_APPLY_R2(wstringTy, "_aApplyRwc2", "_aApplyRwd2") @@ -539,8 +596,11 @@ static void LLVM_D_BuildRuntimeModule() // fixes the length for dynamic array casts // size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz) - LLVM_D_BuildFunctionFwdDecl(Type::tsize_t, "_d_array_cast_len", { sizeTy, sizeTy, sizeTy }, false, M) - ->setAttributes(Attr_ReadNone); + { + LLType* args[] = { sizeTy, sizeTy, sizeTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tsize_t, "_d_array_cast_len", args, false, M) + ->setAttributes(Attr_ReadNone); + } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -548,19 +608,21 @@ static void LLVM_D_BuildRuntimeModule() // void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to) // void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayassign", - { typeInfoTy, voidArrayTy, voidArrayTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayctor", - { typeInfoTy, voidArrayTy, voidArrayTy }, false, M); + { + LLType* args[] = { typeInfoTy, voidArrayTy, voidArrayTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayassign", args, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_d_arrayctor", args, false, M); + } // void* _d_arraysetassign(void* p, void* value, size_t count, TypeInfo ti) // void* _d_arraysetctor(void* p, void* value, size_t count, TypeInfo ti) - LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_arraysetassign", - { voidPtrTy, voidPtrTy, sizeTy, typeInfoTy }, false, M) - ->setAttributes(Attr_NoAlias); - LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_arraysetctor", - { voidPtrTy, voidPtrTy, sizeTy, typeInfoTy }, false, M) - ->setAttributes(Attr_NoAlias); + { + LLType* args[] = { voidPtrTy, voidPtrTy, sizeTy, typeInfoTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_arraysetassign", args, false, M) + ->setAttributes(Attr_NoAlias); + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_arraysetctor", args, false, M) + ->setAttributes(Attr_NoAlias); + } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -568,20 +630,24 @@ static void LLVM_D_BuildRuntimeModule() // cast to object // Object _d_toObject(void* p) - LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_toObject", { voidPtrTy }, false, M) + LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_toObject", voidPtrTy, false, M) ->setAttributes(Attr_ReadOnly_NoUnwind); // cast interface // Object _d_interface_cast(void* p, ClassInfo c) - LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_interface_cast", - { voidPtrTy, classInfoTy }, false, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); + { + LLType* args[] = { voidPtrTy, classInfoTy }; + LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_interface_cast", args, false, M) + ->setAttributes(Attr_ReadOnly_NoUnwind); + } // dynamic cast // Object _d_dynamic_cast(Object o, ClassInfo c) - LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_dynamic_cast", - { objectTy, classInfoTy }, false, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); + { + LLType* args[] = { objectTy, classInfoTy }; + LLVM_D_BuildFunctionFwdDecl(ClassDeclaration::object->type, "_d_dynamic_cast", args, false, M) + ->setAttributes(Attr_ReadOnly_NoUnwind); + } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -589,95 +655,122 @@ static void LLVM_D_BuildRuntimeModule() // char[] _adReverseChar(char[] a) // char[] _adSortChar(char[] a) - LLVM_D_BuildFunctionFwdDecl(Type::tchar->arrayOf(), "_adReverseChar", { stringTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::tchar->arrayOf(), "_adSortChar", { stringTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tchar->arrayOf(), "_adReverseChar", stringTy, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tchar->arrayOf(), "_adSortChar", stringTy, false, M); // wchar[] _adReverseWchar(wchar[] a) // wchar[] _adSortWchar(wchar[] a) - LLVM_D_BuildFunctionFwdDecl(Type::twchar->arrayOf(), "_adReverseWchar", { wstringTy }, false, M); - LLVM_D_BuildFunctionFwdDecl(Type::twchar->arrayOf(), "_adSortWChar", { wstringTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::twchar->arrayOf(), "_adReverseWchar", wstringTy, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::twchar->arrayOf(), "_adSortWChar", wstringTy, false, M); // void[] _adReverse(void[] a, size_t szelem) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adReverse", - { rt_array(byteTy), sizeTy }, false, M) - ->setAttributes(Attr_NoUnwind); + { + LLType* args[] = { rt_array(byteTy), sizeTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adReverse", args, false, M) + ->setAttributes(Attr_NoUnwind); + } // void[] _adDupT(TypeInfo ti, void[] a) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adDupT", - { typeInfoTy, rt_array(byteTy) }, false, M); + { + LLType* args[] = { typeInfoTy, rt_array(byteTy) }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adDupT", args, false, M); + } // int _adEq(void[] a1, void[] a2, TypeInfo ti) // int _adCmp(void[] a1, void[] a2, TypeInfo ti) - LLVM_D_BuildFunctionFwdDecl(Type::tint32, _adEq, - { rt_array(byteTy), rt_array(byteTy), typeInfoTy }, false, M) - ->setAttributes(Attr_ReadOnly); - LLVM_D_BuildFunctionFwdDecl(Type::tint32, _adCmp, - { rt_array(byteTy), rt_array(byteTy), typeInfoTy }, false, M) - ->setAttributes(Attr_ReadOnly); + { + LLType* args[] = { rt_array(byteTy), rt_array(byteTy), typeInfoTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tint32, _adEq, args, false, M) + ->setAttributes(Attr_ReadOnly); + LLVM_D_BuildFunctionFwdDecl(Type::tint32, _adCmp, args, false, M) + ->setAttributes(Attr_ReadOnly); + } // int _adCmpChar(void[] a1, void[] a2) - LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_adCmpChar", - {rt_array(byteTy), rt_array(byteTy)}, false,M) - ->setAttributes(Attr_ReadOnly_NoUnwind); + { + LLType* args[] = { rt_array(byteTy), rt_array(byteTy) } ; + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_adCmpChar", args, false,M) + ->setAttributes(Attr_ReadOnly_NoUnwind); + } // void[] _adSort(void[] a, TypeInfo ti) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adSort", - { rt_array(byteTy), typeInfoTy }, false, M); + { + LLType* args[] = { rt_array(byteTy), typeInfoTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_adSort", args, false, M); + } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // size_t _aaLen(AA aa) - LLVM_D_BuildFunctionFwdDecl(Type::tsize_t, "_aaLen", { aaTy }, false, M) + LLVM_D_BuildFunctionFwdDecl(Type::tsize_t, "_aaLen", aaTy, false, M) ->setAttributes(Attr_ReadOnly_NoUnwind_1_NoCapture); // void* _aaGetX(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey) - LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaGetX", - { aaTy, typeInfoTy, sizeTy, voidPtrTy }, false, M) - ->setAttributes(Attr_1_4_NoCapture); + { + LLType* args[] = { aaTy, typeInfoTy, sizeTy, voidPtrTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaGetX", args, false, M) + ->setAttributes(Attr_1_4_NoCapture); + } // void* _aaInX(AA aa, TypeInfo keyti, void* pkey) - LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaInX", - { aaTy, typeInfoTy, voidPtrTy }, false, M) - ->setAttributes(Attr_ReadOnly_1_3_NoCapture); + { + LLType* args[] = { aaTy, typeInfoTy, voidPtrTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaInX", args, false, M) + ->setAttributes(Attr_ReadOnly_1_3_NoCapture); // bool _aaDelX(AA aa, TypeInfo keyti, void* pkey) - LLVM_D_BuildFunctionFwdDecl(Type::tbool, "_aaDelX", - { aaTy, typeInfoTy, voidPtrTy }, false, M) - ->setAttributes(Attr_1_3_NoCapture); + LLVM_D_BuildFunctionFwdDecl(Type::tbool, "_aaDelX", args, false, M) + ->setAttributes(Attr_1_3_NoCapture); + } // void[] _aaValues(AA aa, size_t keysize, size_t valuesize) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_aaValues", - { aaTy, sizeTy, sizeTy }, false, M) - ->setAttributes(Attr_NoAlias_1_NoCapture); + { + LLType* args[] = { aaTy, sizeTy, sizeTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_aaValues", args, false, M) + ->setAttributes(Attr_NoAlias_1_NoCapture); + } // void* _aaRehash(AA* paa, TypeInfo keyti) - LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaRehash", { aaTy, typeInfoTy }, false, M); + { + LLType* args[] = { aaTy, typeInfoTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_aaRehash", args, false, M); + } // void[] _aaKeys(AA aa, size_t keysize) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_aaKeys", - { aaTy, sizeTy }, false, M) - ->setAttributes(Attr_NoAlias_1_NoCapture); + { + LLType* args[] = { aaTy, sizeTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid->arrayOf(), "_aaKeys", args, false, M) + ->setAttributes(Attr_NoAlias_1_NoCapture); + } // int _aaApply(AA aa, size_t keysize, dg_t dg) - LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaApply", - { aaTy, sizeTy, rt_dg1() }, false, M) - ->setAttributes(Attr_1_NoCapture); + { + LLType* args[] = { aaTy, sizeTy, rt_dg1() }; + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaApply", args, false, M) + ->setAttributes(Attr_1_NoCapture); + } // int _aaApply2(AA aa, size_t keysize, dg2_t dg) - LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaApply2", - { aaTy, sizeTy, rt_dg2() }, false, M) - ->setAttributes(Attr_1_NoCapture); + { + LLType* args[] = { aaTy, sizeTy, rt_dg2() }; + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaApply2", args, false, M) + ->setAttributes(Attr_1_NoCapture); + } // int _aaEqual(in TypeInfo tiRaw, in AA e1, in AA e2) - LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaEqual", - { typeInfoTy, aaTy, aaTy }, false, M) - ->setAttributes(Attr_1_2_NoCapture); + { + LLType* args[] = { typeInfoTy, aaTy, aaTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_aaEqual", args, false, M) + ->setAttributes(Attr_1_2_NoCapture); + } // BB* _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values) - LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_assocarrayliteralTX", - { aaTypeInfoTy, voidArrayTy, voidArrayTy }, false, M); + { + LLType* args[] = { aaTypeInfoTy, voidArrayTy, voidArrayTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoidptr, "_d_assocarrayliteralTX", args, false, M); + } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -693,26 +786,32 @@ static void LLVM_D_BuildRuntimeModule() ///////////////////////////////////////////////////////////////////////////////////// // void _d_throw_exception(Object e) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_throw_exception", { objectTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_throw_exception", objectTy, false, M); ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // int _d_switch_string(char[][] table, char[] ca) - LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_string", - { rt_array(stringTy), stringTy }, false, M) - ->setAttributes(Attr_ReadOnly); + { + LLType* args[] = { rt_array(stringTy), stringTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_string", args, false, M) + ->setAttributes(Attr_ReadOnly); + } // int _d_switch_ustring(wchar[][] table, wchar[] ca) - LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_ustring", - { rt_array(wstringTy), wstringTy }, false, M) - ->setAttributes(Attr_ReadOnly); + { + LLType* args[] = { rt_array(wstringTy), wstringTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_ustring", args, false, M) + ->setAttributes(Attr_ReadOnly); + } // int _d_switch_dstring(dchar[][] table, dchar[] ca) - LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_dstring", - { rt_array(dstringTy), dstringTy }, false, M) - ->setAttributes(Attr_ReadOnly); + { + LLType* args[] = { rt_array(dstringTy), dstringTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tint32, "_d_switch_dstring", args, false, M) + ->setAttributes(Attr_ReadOnly); + } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -748,19 +847,12 @@ static void LLVM_D_BuildRuntimeModule() } // void _d_eh_resume_unwind(ptr exc_struct) - { - llvm::StringRef fname("_d_eh_resume_unwind"); - LLType *types[] = { voidPtrTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_eh_resume_unwind", voidPtrTy, false, M); // void _d_eh_handle_collision(ptr exc_struct, ptr exc_struct) { - llvm::StringRef fname("_d_eh_handle_collision"); - LLType *types[] = { voidPtrTy, voidPtrTy }; - LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + LLType* args[] = { voidPtrTy, voidPtrTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_eh_handle_collision", args, false, M); } ///////////////////////////////////////////////////////////////////////////////////// @@ -795,7 +887,7 @@ static void LLVM_D_BuildRuntimeModule() } // void _d_hidden_func(Object o) - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_hidden_func", { voidPtrTy }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_hidden_func", voidPtrTy, false, M); // void _d_dso_registry(CompilerDSOData* data) if (global.params.isLinux) { @@ -806,12 +898,12 @@ static void LLVM_D_BuildRuntimeModule() getPtrToType(moduleInfoPtrTy), // _minfo_end NULL ); - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_dso_registry", { getPtrToType(dsoDataTy) }, false, M); + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_dso_registry", getPtrToType(dsoDataTy), false, M); } // void _d_cover_register2(string filename, size_t[] valid, uint[] data, ubyte minPercent) if (global.params.cov) { - LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_cover_register2", - { stringTy, rt_array(sizeTy), rt_array(intTy), byteTy }, false, M); + LLType* args[] = { stringTy, rt_array(sizeTy), rt_array(intTy), byteTy }; + LLVM_D_BuildFunctionFwdDecl(Type::tvoid, "_d_cover_register2", args, false, M); } } diff --git a/gen/runtime.h b/gen/runtime.h index 44a24d6b827..404b164b102 100644 --- a/gen/runtime.h +++ b/gen/runtime.h @@ -19,16 +19,21 @@ namespace llvm class Function; class GlobalVariable; class Module; + class Value; } struct Loc; +#include "llvm/ADT/ArrayRef.h" + // D runtime support helpers bool LLVM_D_InitRuntime(); void LLVM_D_FreeRuntime(); llvm::Function* LLVM_D_GetRuntimeFunction(const Loc &loc, llvm::Module* target, const char* name); +llvm::Value* LLVM_D_CallRuntimeFunction(const Loc &loc, const char* name, + llvm::ArrayRef args, const char* invokename = NULL); llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(const Loc &loc, llvm::Module* target, const char* name); diff --git a/gen/tocall.cpp b/gen/tocall.cpp index afdc6c43c1f..dfe29042c5f 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -502,10 +502,10 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* switch(rbase->ty) { case Tarray: - if (tf->isref) + if (tf->isref || retinptr) retllval = DtoBitCast(retllval, DtoType(rbase->pointerTo())); else - retllval = DtoAggrPaint(retllval, DtoType(rbase)); + retllval = DtoAggrPaint(retllval, DtoType(rbase)); break; case Tsarray: @@ -515,14 +515,14 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* case Tclass: case Taarray: case Tpointer: - if (tf->isref) + if (tf->isref || retinptr) retllval = DtoBitCast(retllval, DtoType(rbase->pointerTo())); else - retllval = DtoBitCast(retllval, DtoType(rbase)); + retllval = DtoBitCast(retllval, DtoType(rbase)); break; case Tstruct: - if (nextbase->ty == Taarray && !tf->isref) + if (nextbase->ty == Taarray && !(tf->isref || retinptr)) { // In the D2 frontend, the associative array type and its // object.AssociativeArray representation are used From d85361c9e17f4d8f14be7a0ef2a6e4b917eb7641 Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Sat, 18 Apr 2015 15:44:33 +0200 Subject: [PATCH 3/4] fix bug --- gen/arrays.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index f3c46cf4c6c..1d543024953 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -870,9 +870,7 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(arg_offset + 2))); } - LLCallSite call = LLVM_D_CallRuntimeFunction(loc, func, args); - - return call.getInstruction(); + return LLVM_D_CallRuntimeFunction(loc, func, args); } ////////////////////////////////////////////////////////////////////////////////////////// From 555b8ba7bdc3b32458d560c9a6615a7a883d595f Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Sun, 19 Apr 2015 22:03:27 +0200 Subject: [PATCH 4/4] Only _return_ arrays byref (sret), but don't pass them byref yet (code must be changed in a number of places for that) --- gen/abi-win64.cpp | 4 ++-- gen/arrays.cpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gen/abi-win64.cpp b/gen/abi-win64.cpp index c6c6784b374..257d3649190 100644 --- a/gen/abi-win64.cpp +++ b/gen/abi-win64.cpp @@ -55,7 +55,7 @@ struct Win64TargetABI : TargetABI bool isAggregate(Type* t) { TY ty = t->ty; - return ty == Tstruct || ty == Tsarray || ty == Tarray || ty == Tdelegate + return ty == Tstruct || ty == Tsarray || /*ty == Tarray ||*/ ty == Tdelegate || t->iscomplex(); } @@ -123,7 +123,7 @@ bool Win64TargetABI::returnInArg(Type* rt, LINK /*linkage*/) // XMM0 for single float/ifloat/double/idouble) // * all other types are returned via struct-return (sret) return (rt->ty == Tstruct && !((TypeStruct*)rt)->sym->isPOD()) - || isPassedWithByvalSemantics(rt); + || isPassedWithByvalSemantics(rt) || (rt->ty == Tarray); } bool Win64TargetABI::passByVal(Type* t) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 1d543024953..94c53b34f23 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -756,7 +756,6 @@ DSliceValue* DtoCatArrays(Loc& loc, Type* arrayType, Expression* exp1, Expressio LOG_SCOPE; std::vector args; - LLFunction* fn = 0; const char* fname = NULL; if (exp1->op == TOKcat)