From 554d0a203330ffd47e04f2dfd5b91dc4225a22ca Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Thu, 12 Nov 2015 19:21:18 +0100 Subject: [PATCH] Cleanup runtime fwd decls and use ABI functiontype rewriting --- driver/main.cpp | 2 +- gen/aa.cpp | 10 +- gen/arrays.cpp | 30 +- gen/classes.cpp | 8 +- gen/functions.cpp | 22 +- gen/functions.h | 4 + gen/llvmhelpers.cpp | 18 +- gen/module.cpp | 6 +- gen/runtime.cpp | 761 +++++++++++++++----------------------------- gen/runtime.h | 9 +- gen/statements.cpp | 8 +- gen/toir.cpp | 4 +- ir/irfunction.cpp | 6 +- 13 files changed, 323 insertions(+), 565 deletions(-) diff --git a/driver/main.cpp b/driver/main.cpp index 001a6aa0799..d94a85b61a2 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -1279,7 +1279,7 @@ int main(int argc, char **argv) { emitJson(modules); } - LLVM_D_FreeRuntime(); + freeRuntime(); llvm::llvm_shutdown(); if (global.errors) { diff --git a/gen/aa.cpp b/gen/aa.cpp index 6be466eb128..fd861eae1ee 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -41,7 +41,7 @@ DValue *DtoAAIndex(Loc &loc, Type *type, DValue *aa, DValue *key, bool lvalue) { // extern(C) void* _aaInX(AA aa*, TypeInfo keyti, void* pkey) // first get the runtime function - llvm::Function *func = LLVM_D_GetRuntimeFunction( + llvm::Function *func = getRuntimeFunction( loc, gIR->module, lvalue ? "_aaGetY" : "_aaInX"); LLFunctionType *funcTy = func->getFunctionType(); @@ -92,7 +92,7 @@ DValue *DtoAAIndex(Loc &loc, Type *type, DValue *aa, DValue *key, bool lvalue) { gIR->scope() = IRScope(failbb); llvm::Function *errorfn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arraybounds"); + getRuntimeFunction(loc, gIR->module, "_d_arraybounds"); gIR->CreateCallOrInvoke( errorfn, DtoModuleFileName(gIR->func()->decl->getModule(), loc), DtoConstUint(loc.linnum)); @@ -118,7 +118,7 @@ DValue *DtoAAIn(Loc &loc, Type *type, DValue *aa, DValue *key) { // extern(C) void* _aaInX(AA aa*, TypeInfo keyti, void* pkey) // first get the runtime function - llvm::Function *func = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_aaInX"); + llvm::Function *func = getRuntimeFunction(loc, gIR->module, "_aaInX"); LLFunctionType *funcTy = func->getFunctionType(); IF_LOG Logger::cout() << "_aaIn = " << *func << '\n'; @@ -164,7 +164,7 @@ DValue *DtoAARemove(Loc &loc, DValue *aa, DValue *key) { // extern(C) bool _aaDelX(AA aa, TypeInfo keyti, void* pkey) // first get the runtime function - llvm::Function *func = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_aaDelX"); + llvm::Function *func = getRuntimeFunction(loc, gIR->module, "_aaDelX"); LLFunctionType *funcTy = func->getFunctionType(); IF_LOG Logger::cout() << "_aaDel = " << *func << '\n'; @@ -198,7 +198,7 @@ LLValue *DtoAAEquals(Loc &loc, TOK op, DValue *l, DValue *r) { assert(t == r->getType()->toBasetype() && "aa equality is only defined for aas of same type"); llvm::Function *func = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_aaEqual"); + getRuntimeFunction(loc, gIR->module, "_aaEqual"); LLFunctionType *funcTy = func->getFunctionType(); LLValue *aaval = DtoBitCast(l->getRVal(), funcTy->getParamType(1)); diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 599dc43161d..3924d54f89b 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -200,7 +200,7 @@ static void copySlice(Loc &loc, LLValue *dstarr, LLValue *sz1, LLValue *srcarr, global.params.useAssert || gIR->emitArrayBoundsChecks(); if (checksEnabled && !knownInBounds) { LLValue *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_array_slice_copy"); + getRuntimeFunction(loc, gIR->module, "_d_array_slice_copy"); gIR->CreateCallOrInvoke(fn, dstarr, sz1, srcarr, sz2); } else { // We might have dstarr == srcarr at compile time, but as long as @@ -285,7 +285,7 @@ void DtoArrayAssign(Loc &loc, DValue *lhs, DValue *rhs, int op, } } else if (isConstructing) { LLFunction *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arrayctor"); + getRuntimeFunction(loc, gIR->module, "_d_arrayctor"); LLCallSite call = gIR->CreateCallOrInvoke(fn, DtoTypeInfoOf(elemType), DtoSlice(rhsPtr, rhsLength), DtoSlice(lhsPtr, lhsLength)); @@ -293,7 +293,7 @@ void DtoArrayAssign(Loc &loc, DValue *lhs, DValue *rhs, int op, } else // assigning { LLValue *tmpSwap = DtoAlloca(elemType, "arrayAssign.tmpSwap"); - LLFunction *fn = LLVM_D_GetRuntimeFunction( + LLFunction *fn = getRuntimeFunction( loc, gIR->module, !canSkipPostblit ? "_d_arrayassign_l" : "_d_arrayassign_r"); LLCallSite call = gIR->CreateCallOrInvoke( @@ -316,7 +316,7 @@ void DtoArrayAssign(Loc &loc, DValue *lhs, DValue *rhs, int op, LLValue *actualLength = gIR->ir->CreateExactUDiv(lhsSize, rhsSize); DtoArrayInit(loc, actualPtr, actualLength, rhs, op); } else { - LLFunction *fn = LLVM_D_GetRuntimeFunction( + LLFunction *fn = getRuntimeFunction( loc, gIR->module, isConstructing ? "_d_arraysetctor" : "_d_arraysetassign"); LLCallSite call = gIR->CreateCallOrInvoke( @@ -625,7 +625,7 @@ DSliceValue *DtoNewDynArray(Loc &loc, Type *arrayType, DValue *dim, const char *fnname = defaultInit ? (zeroInit ? "_d_newarrayT" : "_d_newarrayiT") : "_d_newarrayU"; - LLFunction *fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, fnname); + LLFunction *fn = getRuntimeFunction(loc, gIR->module, fnname); // call allocator LLValue *newArray = @@ -653,7 +653,7 @@ DSliceValue *DtoNewMulDimDynArray(Loc &loc, Type *arrayType, DValue **dims, // get runtime function const char *fnname = vtype->isZeroInit() ? "_d_newarraymTX" : "_d_newarraymiTX"; - LLFunction *fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, fnname); + LLFunction *fn = getRuntimeFunction(loc, gIR->module, fnname); // Check if constant bool allDimsConst = true; @@ -720,7 +720,7 @@ DSliceValue *DtoResizeDynArray(Loc &loc, Type *arrayType, DValue *array, bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit(); // call runtime - LLFunction *fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, + LLFunction *fn = getRuntimeFunction(loc, gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT"); @@ -750,7 +750,7 @@ void DtoCatAssignElement(Loc &loc, Type *arrayType, DValue *array, DValue *expVal = toElem(exp); LLFunction *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arrayappendcTX"); + getRuntimeFunction(loc, gIR->module, "_d_arrayappendcTX"); LLValue *appendedArray = gIR->CreateCallOrInvoke( fn, DtoTypeInfoOf(arrayType), @@ -774,7 +774,7 @@ DSliceValue *DtoCatAssignArray(Loc &loc, DValue *arr, Expression *exp) { Type *arrayType = arr->getType(); LLFunction *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arrayappendT"); + getRuntimeFunction(loc, gIR->module, "_d_arrayappendT"); // Call _d_arrayappendT(TypeInfo ti, byte[] *px, byte[] y) LLValue *newArray = gIR->CreateCallOrInvoke( @@ -799,7 +799,7 @@ DSliceValue *DtoCatArrays(Loc &loc, Type *arrayType, Expression *exp1, LLFunction *fn = nullptr; if (exp1->op == TOKcat) { // handle multiple concat - fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arraycatnTX"); + fn = getRuntimeFunction(loc, gIR->module, "_d_arraycatnTX"); // Create array of slices typedef llvm::SmallVector ArgVector; @@ -839,7 +839,7 @@ DSliceValue *DtoCatArrays(Loc &loc, Type *arrayType, Expression *exp1, // byte[][] arrs args.push_back(val); } else { - fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_arraycatT"); + fn = getRuntimeFunction(loc, gIR->module, "_d_arraycatT"); // TypeInfo ti args.push_back(DtoTypeInfoOf(arrayType)); @@ -867,7 +867,7 @@ DSliceValue *DtoAppendDChar(Loc &loc, DValue *arr, Expression *exp, DValue *valueToAppend = toElem(exp); // Prepare arguments - LLFunction *fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, func); + LLFunction *fn = getRuntimeFunction(loc, gIR->module, func); // Call function (ref string x, dchar c) LLValue *newArray = @@ -904,7 +904,7 @@ DSliceValue *DtoAppendDCharToUnicodeString(Loc &loc, DValue *arr, static LLValue *DtoArrayEqCmp_impl(Loc &loc, const char *func, DValue *l, DValue *r, bool useti) { IF_LOG Logger::println("comparing arrays"); - LLFunction *fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, func); + LLFunction *fn = getRuntimeFunction(loc, gIR->module, func); assert(fn); // find common dynamic array type @@ -981,7 +981,7 @@ LLValue *DtoArrayCastLength(Loc &loc, LLValue *len, LLType *elemty, } LLFunction *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_array_cast_len"); + getRuntimeFunction(loc, gIR->module, "_d_array_cast_len"); return gIR->CreateCallOrInvoke(fn, len, LLConstantInt::get(DtoSize_t(), esz, false), LLConstantInt::get(DtoSize_t(), nsz, false)) @@ -1213,7 +1213,7 @@ void DtoIndexBoundsCheck(Loc &loc, DValue *arr, DValue *index) { void DtoBoundsCheckFailCall(IRState *irs, Loc &loc) { llvm::Function *errorfn = - LLVM_D_GetRuntimeFunction(loc, irs->module, "_d_arraybounds"); + getRuntimeFunction(loc, irs->module, "_d_arraybounds"); irs->CreateCallOrInvoke( errorfn, DtoModuleFileName(irs->func()->decl->getModule(), loc), DtoConstUint(loc.linnum)); diff --git a/gen/classes.cpp b/gen/classes.cpp index b2271f148da..5907ccf1328 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -97,7 +97,7 @@ DValue *DtoNewClass(Loc &loc, TypeClass *tc, NewExp *newexp) { // default allocator else { llvm::Function *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_newclass"); + getRuntimeFunction(loc, gIR->module, "_d_newclass"); LLConstant *ci = DtoBitCast(getIrAggr(tc->sym)->getClassInfoSymbol(), DtoType(Type::typeinfoclass->type)); mem = @@ -186,7 +186,7 @@ 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"); + getRuntimeFunction(loc, gIR->module, "_d_callfinalizer"); gIR->CreateCallOrInvoke( fn, DtoBitCast(inst, fn->getFunctionType()->getParamType(0)), ""); @@ -330,7 +330,7 @@ DValue *DtoDynamicCastObject(Loc &loc, DValue *val, Type *_to) { DtoResolveClass(Type::typeinfoclass); llvm::Function *func = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_dynamic_cast"); + getRuntimeFunction(loc, gIR->module, "_d_dynamic_cast"); LLFunctionType *funcTy = func->getFunctionType(); // Object o @@ -368,7 +368,7 @@ DValue *DtoDynamicCastInterface(Loc &loc, DValue *val, Type *_to) { DtoResolveClass(Type::typeinfoclass); llvm::Function *func = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_interface_cast"); + getRuntimeFunction(loc, gIR->module, "_d_interface_cast"); LLFunctionType *funcTy = func->getFunctionType(); // void* p diff --git a/gen/functions.cpp b/gen/functions.cpp index 60dc19ff6d0..b56503c7a87 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -378,10 +378,8 @@ void DtoResolveFunction(FuncDeclaration *fdecl) { //////////////////////////////////////////////////////////////////////////////// -static void set_param_attrs(TypeFunction *f, llvm::Function *func, - FuncDeclaration *fdecl) { - IrFuncTy &irFty = getIrFunc(fdecl)->irFty; - AttrSet newAttrs = AttrSet::extractFunctionAndReturnAttributes(func); +AttrSet getParamAttrs(TypeFunction *f, IrFuncTy &irFty) { + AttrSet newAttrs; int idx = 0; @@ -414,7 +412,13 @@ static void set_param_attrs(TypeFunction *f, llvm::Function *func, newAttrs.add(i, irFty.args[k]->attrs); } - // Store the final attribute set + return newAttrs; +} + +void applyParamAttrsToLLFunc(TypeFunction *f, IrFuncTy &irFty, + llvm::Function *func) { + AttrSet newAttrs = AttrSet::extractFunctionAndReturnAttributes(func); + newAttrs.merge(getParamAttrs(f, irFty)); func->setAttributes(newAttrs); } @@ -499,7 +503,7 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) { // parameter attributes if (!DtoIsIntrinsic(fdecl)) { - set_param_attrs(f, func, fdecl); + applyParamAttrsToLLFunc(f, getIrFunc(fdecl)->irFty, func); if (global.params.disableRedZone) { func->addFnAttr(LLAttribute::NoRedZone); } @@ -735,7 +739,8 @@ void DtoDefineFunction(FuncDeclaration *fd) { } } - // if this function is naked, we take over right away! no standard processing! + // if this function is naked, we take over right away! no standard + // processing! if (fd->naked) { DtoDefineNakedFunction(fd); return; @@ -927,7 +932,8 @@ void DtoDefineFunction(FuncDeclaration *fd) { // is the last statement in a function) bb->eraseFromParent(); } else if (!gIR->scopereturned()) { - // llvm requires all basic blocks to end with a TerminatorInst but DMD does + // llvm requires all basic blocks to end with a TerminatorInst but DMD + // does // not put a return statement // in automatically, so we do it here. diff --git a/gen/functions.h b/gen/functions.h index ce0d2d868ba..9e01e69bd84 100644 --- a/gen/functions.h +++ b/gen/functions.h @@ -16,6 +16,7 @@ #include "mars.h" +class AttrSet; class DValue; class Expression; class FuncDeclaration; @@ -23,11 +24,14 @@ struct IRAsmBlock; struct IrFuncTy; class Parameter; class Type; +class TypeFunction; namespace llvm { class FunctionType; class Value; } +AttrSet getParamAttrs(TypeFunction *f, IrFuncTy &irFty); + llvm::FunctionType *DtoFunctionType(Type *t, IrFuncTy &irFty, Type *thistype, Type *nesttype, bool isMain = false, bool isCtor = false, diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index e888188a47f..ffdea3f923f 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -63,7 +63,7 @@ Type *getTypeInfoType(Type *t, Scope *sc); LLValue *DtoNew(Loc &loc, Type *newtype) { // get runtime function llvm::Function *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_allocmemoryT"); + getRuntimeFunction(loc, gIR->module, "_d_allocmemoryT"); // get type info LLConstant *ti = DtoTypeInfoOf(newtype); assert(isaPointer(ti)); @@ -74,7 +74,7 @@ LLValue *DtoNew(Loc &loc, Type *newtype) { } LLValue *DtoNewStruct(Loc &loc, TypeStruct *newtype) { - llvm::Function *fn = LLVM_D_GetRuntimeFunction( + llvm::Function *fn = getRuntimeFunction( loc, gIR->module, newtype->isZeroInit(newtype->sym->loc) ? "_d_newitemT" : "_d_newitemiT"); LLConstant *ti = DtoTypeInfoOf(newtype); @@ -84,7 +84,7 @@ LLValue *DtoNewStruct(Loc &loc, TypeStruct *newtype) { void DtoDeleteMemory(Loc &loc, DValue *ptr) { llvm::Function *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delmemory"); + getRuntimeFunction(loc, gIR->module, "_d_delmemory"); LLValue *lval = (ptr->isLVal() ? ptr->getLVal() : makeLValue(loc, ptr)); gIR->CreateCallOrInvoke( fn, DtoBitCast(lval, fn->getFunctionType()->getParamType(0))); @@ -92,7 +92,7 @@ void DtoDeleteMemory(Loc &loc, DValue *ptr) { void DtoDeleteStruct(Loc &loc, DValue *ptr) { llvm::Function *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delstruct"); + getRuntimeFunction(loc, gIR->module, "_d_delstruct"); LLValue *lval = (ptr->isLVal() ? ptr->getLVal() : makeLValue(loc, ptr)); gIR->CreateCallOrInvoke( fn, DtoBitCast(lval, fn->getFunctionType()->getParamType(0)), @@ -102,7 +102,7 @@ void DtoDeleteStruct(Loc &loc, DValue *ptr) { void DtoDeleteClass(Loc &loc, DValue *inst) { llvm::Function *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delclass"); + getRuntimeFunction(loc, gIR->module, "_d_delclass"); LLValue *lval = (inst->isLVal() ? inst->getLVal() : makeLValue(loc, inst)); gIR->CreateCallOrInvoke( fn, DtoBitCast(lval, fn->getFunctionType()->getParamType(0))); @@ -110,7 +110,7 @@ void DtoDeleteClass(Loc &loc, DValue *inst) { void DtoDeleteInterface(Loc &loc, DValue *inst) { llvm::Function *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delinterface"); + getRuntimeFunction(loc, gIR->module, "_d_delinterface"); LLValue *lval = (inst->isLVal() ? inst->getLVal() : makeLValue(loc, inst)); gIR->CreateCallOrInvoke( fn, DtoBitCast(lval, fn->getFunctionType()->getParamType(0))); @@ -118,7 +118,7 @@ void DtoDeleteInterface(Loc &loc, DValue *inst) { void DtoDeleteArray(Loc &loc, DValue *arr) { llvm::Function *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delarray_t"); + getRuntimeFunction(loc, gIR->module, "_d_delarray_t"); llvm::FunctionType *fty = fn->getFunctionType(); // the TypeInfo argument must be null if the type has no dtor @@ -183,7 +183,7 @@ llvm::AllocaInst *DtoRawAlloca(LLType *lltype, size_t alignment, LLValue *DtoGcMalloc(Loc &loc, LLType *lltype, const char *name) { // get runtime function llvm::Function *fn = - LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_allocmemory"); + getRuntimeFunction(loc, gIR->module, "_d_allocmemory"); // parameters LLValue *size = DtoConstSize_t(getTypeAllocSize(lltype)); // call runtime allocator @@ -232,7 +232,7 @@ LLValue *DtoAllocaDump(LLValue *val, LLType *asType, int alignment, void DtoAssert(Module *M, Loc &loc, DValue *msg) { // func const char *fname = msg ? "_d_assert_msg" : "_d_assert"; - llvm::Function *fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, fname); + llvm::Function *fn = getRuntimeFunction(loc, gIR->module, fname); // Arguments llvm::SmallVector args; diff --git a/gen/module.cpp b/gen/module.cpp index 32af4ad6afd..b0ed4c9943b 100644 --- a/gen/module.cpp +++ b/gen/module.cpp @@ -378,7 +378,7 @@ static void build_dso_ctor_dtor_body( llvm::Value *dsoSlot, llvm::Value *minfoBeg, llvm::Value *minfoEnd, llvm::Value *minfoUsedPointer, bool executeWhenInitialized) { llvm::Function *const dsoRegistry = - LLVM_D_GetRuntimeFunction(Loc(), gIR->module, "_d_dso_registry"); + getRuntimeFunction(Loc(), gIR->module, "_d_dso_registry"); llvm::Type *const recordPtrTy = dsoRegistry->getFunctionType()->getContainedType(1); @@ -670,7 +670,7 @@ static void addCoverageAnalysis(Module *m) { // Set up call to _d_cover_register2 llvm::Function *fn = - LLVM_D_GetRuntimeFunction(Loc(), gIR->module, "_d_cover_register2"); + getRuntimeFunction(Loc(), gIR->module, "_d_cover_register2"); LLValue *args[] = {DtoConstString(m->srcfile->name->toChars()), d_cover_valid_slice, d_cover_data_slice, DtoConstUbyte(global.params.covPercent)}; @@ -723,7 +723,7 @@ void codegenModule(IRState *irs, Module *m, bool emitFullModuleInfo) { assert(!gIR && "gIR not null, codegen already in progress?!"); gIR = irs; - LLVM_D_InitRuntime(); + initRuntime(); // Skip pseudo-modules for coverage analysis std::string name = m->toChars(); diff --git a/gen/runtime.cpp b/gen/runtime.cpp index f5e2a519e2a..0d4a1f7a54c 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -16,6 +16,8 @@ #include "mtype.h" #include "root.h" #include "gen/abi.h" +#include "gen/attributes.h" +#include "gen/functions.h" #include "gen/irstate.h" #include "gen/llvm.h" #include "gen/llvmhelpers.h" @@ -41,9 +43,10 @@ static llvm::cl::opt nogc( //////////////////////////////////////////////////////////////////////////////// +// Internal LLVM module containing runtime declarations (functions and globals) static llvm::Module *M = nullptr; -static void LLVM_D_BuildRuntimeModule(); +static void buildRuntimeModule(); //////////////////////////////////////////////////////////////////////////////// @@ -96,18 +99,18 @@ static void checkForImplicitGCCall(const Loc &loc, const char *name) { //////////////////////////////////////////////////////////////////////////////// -bool LLVM_D_InitRuntime() { +bool initRuntime() { Logger::println("*** Initializing D runtime declarations ***"); LOG_SCOPE; if (!M) { - LLVM_D_BuildRuntimeModule(); + buildRuntimeModule(); } return true; } -void LLVM_D_FreeRuntime() { +void freeRuntime() { if (M) { Logger::println("*** Freeing D runtime declarations ***"); delete M; @@ -117,12 +120,12 @@ void LLVM_D_FreeRuntime() { //////////////////////////////////////////////////////////////////////////////// -llvm::Function *LLVM_D_GetRuntimeFunction(const Loc &loc, llvm::Module &target, - const char *name) { +llvm::Function *getRuntimeFunction(const Loc &loc, llvm::Module &target, + const char *name) { checkForImplicitGCCall(loc, name); if (!M) { - LLVM_D_InitRuntime(); + initRuntime(); } LLFunction *fn = target.getFunction(name); @@ -131,7 +134,10 @@ llvm::Function *LLVM_D_GetRuntimeFunction(const Loc &loc, llvm::Module &target, } fn = M->getFunction(name); - assert(fn && "Runtime function not found."); + if (!fn) { + error(loc, "Runtime function '%s' was not found", name); + fatal(); + } LLFunctionType *fnty = fn->getFunctionType(); LLFunction *resfn = @@ -143,8 +149,8 @@ llvm::Function *LLVM_D_GetRuntimeFunction(const Loc &loc, llvm::Module &target, //////////////////////////////////////////////////////////////////////////////// -llvm::GlobalVariable *LLVM_D_GetRuntimeGlobal(Loc &loc, llvm::Module &target, - const char *name) { +llvm::GlobalVariable *getRuntimeGlobal(Loc &loc, llvm::Module &target, + const char *name) { LLGlobalVariable *gv = target.getNamedGlobal(name); if (gv) { return gv; @@ -153,7 +159,7 @@ llvm::GlobalVariable *LLVM_D_GetRuntimeGlobal(Loc &loc, llvm::Module &target, checkForImplicitGCCall(loc, name); if (!M) { - LLVM_D_InitRuntime(); + initRuntime(); } LLGlobalVariable *g = M->getNamedGlobal(name); @@ -170,31 +176,31 @@ llvm::GlobalVariable *LLVM_D_GetRuntimeGlobal(Loc &loc, llvm::Module &target, //////////////////////////////////////////////////////////////////////////////// -static LLType *rt_ptr(LLType *t) { return getPtrToType(t); } - -static LLType *rt_array(LLType *elemty) { - LLType *types[] = {DtoSize_t(), rt_ptr(elemty)}; - return LLStructType::get(gIR->context(), types, false); +// extern (D) alias dg_t = int delegate(void*); +static Type *rt_dg1() { + static Type *dg_t = nullptr; + if (dg_t) + return dg_t; + + auto params = new Parameters(); + params->push(new Parameter(0, Type::tvoidptr, nullptr, nullptr)); + auto fty = new TypeFunction(params, Type::tint32, 0, LINKd); + dg_t = new TypeDelegate(fty); + return dg_t; } -static LLType *rt_dg1() { - LLType *types1[] = {rt_ptr(LLType::getInt8Ty(gIR->context())), - rt_ptr(LLType::getInt8Ty(gIR->context()))}; - LLFunctionType *fty = - LLFunctionType::get(LLType::getInt32Ty(gIR->context()), types1, false); - - LLType *types[] = {rt_ptr(LLType::getInt8Ty(gIR->context())), rt_ptr(fty)}; - return LLStructType::get(gIR->context(), types, false); -} - -static LLType *rt_dg2() { - LLType *Int8PtrTy = rt_ptr(LLType::getInt8Ty(gIR->context())); - LLType *types1[] = {Int8PtrTy, Int8PtrTy, Int8PtrTy}; - LLFunctionType *fty = - LLFunctionType::get(LLType::getInt32Ty(gIR->context()), types1, false); - - LLType *types[] = {rt_ptr(LLType::getInt8Ty(gIR->context())), rt_ptr(fty)}; - return LLStructType::get(gIR->context(), types, false); +// extern (D) alias dg2_t = int delegate(void*, void*); +static Type *rt_dg2() { + static Type *dg2_t = nullptr; + if (dg2_t) + return dg2_t; + + auto params = new Parameters(); + params->push(new Parameter(0, Type::tvoidptr, nullptr, nullptr)); + params->push(new Parameter(0, Type::tvoidptr, nullptr, nullptr)); + auto fty = new TypeFunction(params, Type::tint32, 0, LINKd); + dg2_t = new TypeDelegate(fty); + return dg2_t; } template static void ensureDecl(DECL *decl, const char *msg) { @@ -207,23 +213,67 @@ template static void ensureDecl(DECL *decl, const char *msg) { } } -static void LLVM_D_BuildRuntimeModule() { +// We need a vector type with initializer_list support: +#if LDC_LLVM_VER >= 307 +template using ArrayParam = llvm::ArrayRef; +#else +template using ArrayParam = std::vector; +#endif + +// Parameters fnames are assumed to be already mangled! +static void createFwdDecl(LINK linkage, Type *returntype, + ArrayParam fnames, + ArrayParam paramtypes, + ArrayParam paramsSTC = {}, + AttrSet attribset = AttrSet()) { + + Parameters *params = nullptr; + if (!paramtypes.empty()) { + params = new Parameters(); + for (size_t i = 0, e = paramtypes.size(); i < e; ++i) { + StorageClass stc = paramsSTC.empty() ? 0 : paramsSTC[i]; + params->push(new Parameter(stc, paramtypes[i], nullptr, nullptr)); + } + } + int varargs = 0; + auto dty = new TypeFunction(params, returntype, varargs, linkage); + + // the call to DtoType performs many actions such as rewriting the function + // type and storing it in dty + auto llfunctype = llvm::cast(DtoType(dty)); + assert(dty->ctype); + auto attrs = getParamAttrs(dty, dty->ctype->getIrFuncTy()); + attrs.merge(attribset); + + for (auto fname : fnames) { + llvm::Function *fn = llvm::Function::Create( + llfunctype, llvm::GlobalValue::ExternalLinkage, fname, M); + + fn->setAttributes(attrs); + + fn->setCallingConv(gABI->callingConv(fn->getFunctionType(), linkage)); + } +} + +static void buildRuntimeModule() { Logger::println("building runtime module"); M = new llvm::Module("ldc internal runtime", gIR->context()); - LLType *voidTy = LLType::getVoidTy(gIR->context()); - LLType *boolTy = LLType::getInt1Ty(gIR->context()); - LLType *byteTy = LLType::getInt8Ty(gIR->context()); - LLType *intTy = LLType::getInt32Ty(gIR->context()); - LLType *longTy = LLType::getInt64Ty(gIR->context()); - LLType *sizeTy = DtoSize_t(); - - LLType *voidPtrTy = rt_ptr(byteTy); - LLType *voidArrayTy = rt_array(byteTy); - LLType *voidArrayPtrTy = rt_ptr(voidArrayTy); - LLType *stringTy = DtoType(Type::tchar->arrayOf()); - LLType *wstringTy = DtoType(Type::twchar->arrayOf()); - LLType *dstringTy = DtoType(Type::tdchar->arrayOf()); + Type *voidTy = Type::tvoid; + Type *boolTy = Type::tbool; + Type *ubyteTy = Type::tuns8; + Type *intTy = Type::tint32; + Type *uintTy = Type::tuns32; + Type *ulongTy = Type::tuns64; + Type *sizeTy = Type::tsize_t; + Type *dcharTy = Type::tdchar; + + Type *voidPtrTy = Type::tvoidptr; + Type *voidArrayTy = Type::tvoid->arrayOf(); + Type *voidArrayPtrTy = voidArrayTy->pointerTo(); + Type *stringTy = Type::tchar->arrayOf(); + Type *wstringTy = Type::twchar->arrayOf(); + Type *dstringTy = Type::tdchar->arrayOf(); // Ensure that the declarations exist before creating llvm types for them. ensureDecl(ClassDeclaration::object, "Object"); @@ -232,12 +282,13 @@ static void LLVM_D_BuildRuntimeModule() { ensureDecl(Type::typeinfoassociativearray, "TypeInfo_AssociativeArray"); ensureDecl(Module::moduleinfo, "ModuleInfo"); - LLType *objectTy = DtoType(ClassDeclaration::object->type); - LLType *classInfoTy = DtoType(Type::typeinfoclass->type); - LLType *typeInfoTy = DtoType(Type::dtypeinfo->type); - LLType *aaTypeInfoTy = DtoType(Type::typeinfoassociativearray->type); - LLType *moduleInfoPtrTy = rt_ptr(DtoType(Module::moduleinfo->type)); - LLType *aaTy = voidPtrTy; + Type *objectTy = ClassDeclaration::object->type; + Type *classInfoTy = Type::typeinfoclass->type; + Type *typeInfoTy = Type::dtypeinfo->type; + Type *aaTypeInfoTy = Type::typeinfoassociativearray->type; + Type *moduleInfoPtrTy = Module::moduleinfo->type->pointerTo(); + // The AA type is a struct that only contains a ptr + Type *aaTy = voidPtrTy; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -266,205 +317,97 @@ static void LLVM_D_BuildRuntimeModule() { // void _d_assert(string file, uint line) // void _d_arraybounds(string file, 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); - } + createFwdDecl(LINKc, Type::tvoid, {"_d_assert", "_d_arraybounds"}, + {stringTy, uintTy}); // 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); - } + createFwdDecl(LINKc, voidTy, {"_d_assert_msg"}, {stringTy, stringTy, uintTy}); // void _d_assertm(immutable(ModuleInfo)* m, uint line) // void _d_array_bounds(immutable(ModuleInfo)* m, uint line) - { - llvm::StringRef fname("_d_assertm"); - llvm::StringRef fname2("_d_array_bounds"); - LLType *types[] = {moduleInfoPtrTy, 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_switch_error(immutable(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); - } + createFwdDecl(LINKc, voidTy, + {"_d_assertm", "_d_array_bounds", "_d_switch_error"}, + {moduleInfoPtrTy, uintTy}, {STCimmutable, 0}); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // 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); - } + createFwdDecl(LINKc, voidPtrTy, {"_d_allocmemory"}, {sizeTy}, {}, + 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); - } + createFwdDecl(LINKc, voidPtrTy, {"_d_allocmemoryT"}, {typeInfoTy}, {}, + Attr_NoAlias); + // void[] _d_newarrayT (const TypeInfo ti, size_t length) // void[] _d_newarrayiT(const TypeInfo ti, size_t length) // void[] _d_newarrayU (const 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); - } + createFwdDecl(LINKc, voidArrayTy, + {"_d_newarrayT", "_d_newarrayiT", "_d_newarrayU"}, + {typeInfoTy, sizeTy}, {STCconst, 0}); + // void[] _d_newarraymTX (const TypeInfo ti, size_t[] dims) // void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims) - { - llvm::StringRef fname("_d_newarraymTX"); - llvm::StringRef fname2("_d_newarraymiTX"); - LLType *types[] = {typeInfoTy, rt_array(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); - } + createFwdDecl(LINKc, voidArrayTy, {"_d_newarraymTX", "_d_newarraymiTX"}, + {typeInfoTy, sizeTy->arrayOf()}, {STCconst, 0}); // void[] _d_arraysetlengthT (const TypeInfo ti, size_t newlength, void[]* p) // void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p) - { - 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); - } + createFwdDecl(LINKc, voidArrayTy, + {"_d_arraysetlengthT", "_d_arraysetlengthiT"}, + {typeInfoTy, sizeTy, voidArrayPtrTy}, {STCconst, 0, 0}); // byte[] _d_arrayappendcTX(const 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); - } + createFwdDecl(LINKc, voidArrayTy, {"_d_arrayappendcTX"}, + {typeInfoTy, voidArrayTy, sizeTy}, {STCconst, STCref, 0}); + // void[] _d_arrayappendT(const TypeInfo ti, ref byte[] x, 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); - } + createFwdDecl(LINKc, voidArrayTy, {"_d_arrayappendT"}, + {typeInfoTy, voidArrayTy, voidArrayTy}, {STCconst, STCref, 0}); + // void[] _d_arrayappendcd(ref byte[] x, dchar c) - { - llvm::StringRef fname("_d_arrayappendcd"); - LLType *types[] = {voidArrayPtrTy, intTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } // void[] _d_arrayappendwd(ref byte[] x, dchar c) - { - llvm::StringRef fname("_d_arrayappendwd"); - LLType *types[] = {voidArrayPtrTy, intTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, voidArrayTy, {"_d_arrayappendcd", "_d_arrayappendwd"}, + {voidArrayTy, dcharTy}, {STCref, 0}); + // byte[] _d_arraycatT(const 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); - } + createFwdDecl(LINKc, voidArrayTy, {"_d_arraycatT"}, + {typeInfoTy, voidArrayTy, voidArrayTy}, {STCconst, 0, 0}); + // void[] _d_arraycatnTX(const TypeInfo ti, byte[][] arrs) - { - llvm::StringRef fname("_d_arraycatnTX"); - LLType *types[] = {typeInfoTy, rt_array(voidArrayTy)}; - LLFunctionType *fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, voidArrayTy, {"_d_arraycatnTX"}, + {typeInfoTy, voidArrayTy->arrayOf()}, {STCconst, 0}); // 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); - } + createFwdDecl(LINKc, objectTy, {"_d_newclass"}, {classInfoTy}, {STCconst}, + Attr_NoAlias); // void* _d_newitemT (TypeInfo ti) // void* _d_newitemiT(TypeInfo ti) - { - llvm::StringRef fname("_d_newitemT"); - llvm::StringRef fname2("_d_newitemiT"); - LLType *types[] = {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); - } + createFwdDecl(LINKc, voidPtrTy, {"_d_newitemT", "_d_newitemiT"}, {typeInfoTy}, + {0}, Attr_NoAlias); // void _d_delarray_t(void[]* p, const TypeInfo_Struct ti) - { - llvm::StringRef fname("_d_delarray_t"); - LLType *types[] = {voidArrayPtrTy, DtoType(Type::typeinfostruct->type)}; - LLFunctionType *fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, voidTy, {"_d_delarray_t"}, + {voidArrayPtrTy, Type::typeinfostruct->type}, {0, STCconst}); // void _d_delmemory(void** p) // void _d_delinterface(void** p) - { - llvm::StringRef fname("_d_delmemory"); - llvm::StringRef fname2("_d_delinterface"); - LLType *types[] = {rt_ptr(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); - } + createFwdDecl(LINKc, voidTy, {"_d_delmemory", "_d_delinterface"}, + {voidPtrTy->pointerTo()}); // void _d_callfinalizer(void* p) - { - llvm::StringRef fname("_d_callfinalizer"); - LLType *types[] = {voidPtrTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, voidTy, {"_d_callfinalizer"}, {voidPtrTy}); // 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); - } + createFwdDecl(LINKc, voidTy, {"_d_delclass"}, {objectTy->pointerTo()}); // void _d_delstruct(void** p, TypeInfo_Struct inf) - { - llvm::StringRef fname("_d_delstruct"); - LLType *types[] = {rt_ptr(voidPtrTy), DtoType(Type::typeinfostruct->type)}; - LLFunctionType *fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, voidTy, {"_d_delstruct"}, + {voidPtrTy->pointerTo(), Type::typeinfostruct->type}); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -473,13 +416,8 @@ 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); - } + createFwdDecl(LINKc, voidTy, {"_d_array_slice_copy"}, + {voidPtrTy, sizeTy, voidPtrTy, sizeTy}, {}, Attr_1_3_NoCapture); //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -493,16 +431,8 @@ static void LLVM_D_BuildRuntimeModule() { std::string fname1 = prefix + (a) + '1', fname2 = prefix + (b) + '1', \ fname3 = prefix + 'R' + (a) + '1', \ fname4 = prefix + 'R' + (b) + '1'; \ - LLType *types[] = {TY, rt_dg1()}; \ - LLFunctionType *fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname1, \ - M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, \ - M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, \ - M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname4, \ - M); \ + createFwdDecl(LINKc, sizeTy, {fname1, fname2, fname3, fname4}, \ + {TY, rt_dg1()}); \ } STR_APPLY1(stringTy, "cw", "cd") STR_APPLY1(wstringTy, "wc", "wd") @@ -517,16 +447,8 @@ static void LLVM_D_BuildRuntimeModule() { std::string fname1 = prefix + (a) + '2', fname2 = prefix + (b) + '2', \ fname3 = prefix + 'R' + (a) + '2', \ fname4 = prefix + 'R' + (b) + '2'; \ - LLType *types[] = {TY, rt_dg2()}; \ - LLFunctionType *fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname1, \ - M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, \ - M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, \ - M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname4, \ - M); \ + createFwdDecl(LINKc, sizeTy, {fname1, fname2, fname3, fname4}, \ + {TY, rt_dg2()}); \ } STR_APPLY2(stringTy, "cw", "cd") STR_APPLY2(wstringTy, "wc", "wd") @@ -539,13 +461,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); - } + createFwdDecl(LINKc, sizeTy, {"_d_array_cast_len"}, {sizeTy, sizeTy, sizeTy}, + {}, Attr_ReadNone); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -553,35 +470,17 @@ static void LLVM_D_BuildRuntimeModule() { // void[] _d_arrayassign_l(TypeInfo ti, void[] src, void[] dst, void* ptmp) // void[] _d_arrayassign_r(TypeInfo ti, void[] src, void[] dst, void* ptmp) - { - llvm::StringRef fname("_d_arrayassign_l"); - llvm::StringRef fname2("_d_arrayassign_r"); - LLType *types[] = {typeInfoTy, voidArrayTy, voidArrayTy, voidPtrTy}; - 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); - } + createFwdDecl(LINKc, voidArrayTy, {"_d_arrayassign_l", "_d_arrayassign_r"}, + {typeInfoTy, voidArrayTy, voidArrayTy, voidPtrTy}); // void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to) - { - llvm::StringRef fname("_d_arrayctor"); - LLType *types[] = {typeInfoTy, voidArrayTy, voidArrayTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, voidArrayTy, {"_d_arrayctor"}, + {typeInfoTy, voidArrayTy, voidArrayTy}); // void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti) // void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti) - { - llvm::StringRef fname("_d_arraysetassign"); - llvm::StringRef fname2("_d_arraysetctor"); - LLType *types[] = {voidPtrTy, voidPtrTy, intTy, 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); - } + createFwdDecl(LINKc, voidPtrTy, {"_d_arraysetassign", "_d_arraysetctor"}, + {voidPtrTy, voidPtrTy, intTy, typeInfoTy}, {}, Attr_NoAlias); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -589,23 +488,13 @@ static void LLVM_D_BuildRuntimeModule() { // cast interface // void* _d_interface_cast(void* p, ClassInfo c) - { - llvm::StringRef fname("_d_interface_cast"); - LLType *types[] = {voidPtrTy, classInfoTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); - } + createFwdDecl(LINKc, voidPtrTy, {"_d_interface_cast"}, + {voidPtrTy, classInfoTy}, {}, Attr_ReadOnly_NoUnwind); // dynamic cast // void* _d_dynamic_cast(Object o, ClassInfo c) - { - llvm::StringRef fname("_d_dynamic_cast"); - LLType *types[] = {objectTy, classInfoTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); - } + createFwdDecl(LINKc, voidPtrTy, {"_d_dynamic_cast"}, {objectTy, classInfoTy}, + {}, Attr_ReadOnly_NoUnwind); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -613,168 +502,83 @@ 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); - } + createFwdDecl(LINKc, stringTy, {"_adReverseChar", "_adSortChar"}, {stringTy}); // 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); - } + createFwdDecl(LINKc, wstringTy, {"_adReverseWchar", "_adSortWchar"}, + {wstringTy}); // void[] _adReverse(void[] a, size_t szelem) - { - llvm::StringRef fname("_adReverse"); - LLType *types[] = {voidArrayTy, sizeTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoUnwind); - } + createFwdDecl(LINKc, wstringTy, {"_adReverse"}, {voidArrayTy, sizeTy}, {}, + Attr_NoUnwind); - // int _adEq(void[] a1, void[] a2, TypeInfo ti) - // int _adCmp(void[] a1, void[] a2, TypeInfo ti) - { - llvm::StringRef fname("_adEq2"); - llvm::StringRef fname2("_adCmp2"); - LLType *types[] = {voidArrayTy, voidArrayTy, 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); - } + // int _adEq2(void[] a1, void[] a2, TypeInfo ti) + // int _adCmp2(void[] a1, void[] a2, TypeInfo ti) + createFwdDecl(LINKc, intTy, {"_adEq2", "_adCmp2"}, + {voidArrayTy, voidArrayTy, typeInfoTy}, {}, Attr_ReadOnly); // int _adCmpChar(void[] a1, void[] a2) - { - llvm::StringRef fname("_adCmpChar"); - LLType *types[] = {voidArrayTy, voidArrayTy}; - LLFunctionType *fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_ReadOnly_NoUnwind); - } + createFwdDecl(LINKc, intTy, {"_adCmpChar"}, {voidArrayTy, voidArrayTy}, {}, + Attr_ReadOnly_NoUnwind); // void[] _adSort(void[] a, TypeInfo ti) - { - llvm::StringRef fname("_adSort"); - LLType *types[] = {voidArrayTy, typeInfoTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, voidArrayTy, {"_adSort"}, {voidArrayTy, typeInfoTy}); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // size_t _aaLen(in 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); - } + createFwdDecl(LINKc, sizeTy, {"_aaLen"}, {aaTy}, {STCin}, + Attr_ReadOnly_NoUnwind_1_NoCapture); - // void* _aaGetY(AA* aa, const TypeInfo aati, in size_t valuesize, in void* - // pkey) - { - llvm::StringRef fname("_aaGetY"); - LLType *types[] = {rt_ptr(aaTy), aaTypeInfoTy, sizeTy, voidPtrTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_1_4_NoCapture); - } + // void* _aaGetY(AA* aa, const TypeInfo aati, in size_t valuesize, + // in void* pkey) + createFwdDecl(LINKc, voidPtrTy, {"_aaGetY"}, + {aaTy->pointerTo(), aaTypeInfoTy, sizeTy, voidPtrTy}, + {0, STCconst, STCin, STCin}, Attr_1_4_NoCapture); // inout(void)* _aaInX(inout AA aa, in TypeInfo keyti, in 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); - } + // FIXME: "inout" storageclass is not applied to return type + createFwdDecl(LINKc, voidPtrTy, {"_aaInX"}, {aaTy, typeInfoTy, voidPtrTy}, + {STCin | STCout, STCin, STCin}, Attr_ReadOnly_1_3_NoCapture); // bool _aaDelX(AA aa, in TypeInfo keyti, in void* pkey) - { - llvm::StringRef fname("_aaDelX"); - LLType *types[] = {aaTy, typeInfoTy, voidPtrTy}; - LLFunctionType *fty = llvm::FunctionType::get(boolTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_1_3_NoCapture); - } + createFwdDecl(LINKc, boolTy, {"_aaDelX"}, {aaTy, typeInfoTy, voidPtrTy}, + {0, STCin, STCin}, Attr_1_3_NoCapture); - // inout(void[]) _aaValues(inout AA aa, in size_t keysize, in size_t - // valuesize, const TypeInfo tiValueArray) - { - llvm::StringRef fname("_aaValues"); - LLType *types[] = {aaTy, sizeTy, sizeTy, typeInfoTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias_1_NoCapture); - } + // inout(void[]) _aaValues(inout AA aa, in size_t keysize, + // in size_t valuesize, const TypeInfo tiValueArray) + createFwdDecl( + LINKc, voidArrayTy, {"_aaValues"}, {aaTy, sizeTy, sizeTy, typeInfoTy}, + {STCin | STCout, STCin, STCin, STCconst}, Attr_ReadOnly_1_3_NoCapture); // void* _aaRehash(AA* paa, in TypeInfo keyti) - { - llvm::StringRef fname("_aaRehash"); - LLType *types[] = {rt_ptr(aaTy), typeInfoTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, voidPtrTy, {"_aaRehash"}, + {aaTy->pointerTo(), typeInfoTy}, {0, STCin}); - // inout(void[]) _aaKeys(inout AA aa, in size_t keysize, const TypeInfo - // tiKeyArray) - { - llvm::StringRef fname("_aaKeys"); - LLType *types[] = {aaTy, sizeTy, typeInfoTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidArrayTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias_1_NoCapture); - } + // inout(void[]) _aaKeys(inout AA aa, in size_t keysize, + // const TypeInfo tiKeyArray) + createFwdDecl(LINKc, voidArrayTy, {"_aaKeys"}, {aaTy, sizeTy, typeInfoTy}, + {STCin | STCout, STCin, STCconst}, Attr_NoAlias_1_NoCapture); // int _aaApply(AA aa, in 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); - } + createFwdDecl(LINKc, intTy, {"_aaApply"}, {aaTy, sizeTy, rt_dg1()}, + {0, STCin, 0}, Attr_1_NoCapture); // int _aaApply2(AA aa, in 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); - } + createFwdDecl(LINKc, intTy, {"_aaApply2"}, {aaTy, sizeTy, rt_dg2()}, + {0, STCin, 0}, 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); - } - // AA _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, void[] keys, - // void[] values) - { - llvm::StringRef fname("_d_assocarrayliteralTX"); - LLType *types[] = {aaTypeInfoTy, voidArrayTy, voidArrayTy}; - LLFunctionType *fty = llvm::FunctionType::get(aaTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - } + createFwdDecl(LINKc, intTy, {"_aaEqual"}, {typeInfoTy, aaTy, aaTy}, + {STCin, STCin, STCin}, Attr_1_2_NoCapture); + + // AA _d_assocarrayliteralTX(const TypeInfo_AssociativeArray ti, + // void[] keys, void[] values) + createFwdDecl(LINKc, aaTy, {"_d_assocarrayliteralTX"}, + {aaTypeInfoTy, voidArrayTy, voidArrayTy}, {STCconst, 0, 0}); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -782,56 +586,30 @@ 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); - } + createFwdDecl(LINKc, voidTy, {"_moduleCtor", "_moduleDtor"}, {}); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // 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); - } + createFwdDecl(LINKc, voidTy, {"_d_throw_exception"}, {objectTy}); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // 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); - } + createFwdDecl(LINKc, intTy, {"_d_switch_string"}, + {stringTy->arrayOf(), stringTy}, {}, 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); - } + createFwdDecl(LINKc, intTy, {"_d_switch_ustring"}, + {wstringTy->arrayOf(), wstringTy}, {}, 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); - } + createFwdDecl(LINKc, intTy, {"_d_switch_dstring"}, + {dstringTy->arrayOf(), dstringTy}, {}, Attr_ReadOnly); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -839,97 +617,68 @@ static void LLVM_D_BuildRuntimeModule() { // int _d_eh_personality(...) { - LLFunctionType *fty = nullptr; if (global.params.targetTriple.isWindowsMSVCEnvironment()) { // (ptr ExceptionRecord, ptr EstablisherFrame, ptr ContextRecord, // ptr DispatcherContext) - LLType *types[] = {voidPtrTy, voidPtrTy, voidPtrTy, voidPtrTy}; - fty = llvm::FunctionType::get(intTy, types, false); + createFwdDecl(LINKc, intTy, {"_d_eh_personality"}, + {voidPtrTy, voidPtrTy, voidPtrTy, voidPtrTy}); } else if (global.params.targetTriple.getArch() == llvm::Triple::arm) { // (int state, ptr ucb, ptr context) - LLType *types[] = {intTy, voidPtrTy, voidPtrTy}; - fty = llvm::FunctionType::get(intTy, types, false); + createFwdDecl(LINKc, intTy, {"_d_eh_personality"}, + {intTy, voidPtrTy, voidPtrTy}); } else { // (int ver, int actions, ulong eh_class, ptr eh_info, ptr context) - LLType *types[] = {intTy, intTy, longTy, voidPtrTy, voidPtrTy}; - fty = llvm::FunctionType::get(intTy, types, false); + createFwdDecl(LINKc, intTy, {"_d_eh_personality"}, + {intTy, intTy, ulongTy, voidPtrTy, voidPtrTy}); } - - llvm::StringRef fname("_d_eh_personality"); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } // 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); - } + createFwdDecl(LINKc, voidTy, {"_d_eh_resume_unwind"}, {voidPtrTy}); // Object _d_eh_enter_catch(ptr exc_struct) - { - llvm::StringRef fname("_d_eh_enter_catch"); - LLType *types[] = {voidPtrTy}; - LLFunctionType *fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoUnwind); - } + createFwdDecl(LINKc, objectTy, {"_d_eh_enter_catch"}, {voidPtrTy}, {}, + Attr_NoUnwind); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // void invariant._d_invariant(Object o) - { - // KLUDGE: _d_invariant is actually extern(D) in the upstream runtime, - // possibly - // for more efficient parameter passing on x86. This complicates our code - // here - // quite a bit, though. - auto params = new Parameters(); - params->push( - new Parameter(STCin, ClassDeclaration::object->type, nullptr, nullptr)); - auto dty = new TypeFunction(params, Type::tvoid, 0, LINKd); - llvm::Function *fn = llvm::Function::Create( - llvm::cast(DtoType(dty)), - llvm::GlobalValue::ExternalLinkage, - gABI->mangleForLLVM("_D9invariant12_d_invariantFC6ObjectZv", LINKd), M); - assert(dty->ctype); - IrFuncTy &irFty = dty->ctype->getIrFuncTy(); - gABI->rewriteFunctionType(dty, irFty); - fn->addAttributes( - 1, llvm::AttributeSet::get(gIR->context(), 1, irFty.args[0]->attrs)); - fn->setCallingConv(gABI->callingConv(fn->getFunctionType(), LINKd)); - } + createFwdDecl( + LINKd, voidTy, + {gABI->mangleForLLVM("_D9invariant12_d_invariantFC6ObjectZv", LINKd)}, + {objectTy}); // void _d_dso_registry(CompilerDSOData* data) if (global.params.isLinux) { llvm::StringRef fname("_d_dso_registry"); + LLType *LLvoidTy = LLType::getVoidTy(gIR->context()); + LLType *LLvoidPtrPtrTy = getPtrToType(getPtrToType(LLvoidTy)); + LLType *moduleInfoPtrPtrTy = + getPtrToType(getPtrToType(DtoType(Module::moduleinfo->type))); + llvm::StructType *dsoDataTy = - llvm::StructType::get(sizeTy, // version - rt_ptr(voidPtrTy), // slot - rt_ptr(moduleInfoPtrTy), // _minfo_beg - rt_ptr(moduleInfoPtrTy), // _minfo_end + llvm::StructType::get(DtoSize_t(), // version + LLvoidPtrPtrTy, // slot + moduleInfoPtrPtrTy, // _minfo_beg + moduleInfoPtrPtrTy, // _minfo_end NULL); - llvm::Type *types[] = {rt_ptr(dsoDataTy)}; - llvm::FunctionType *fty = llvm::FunctionType::get(voidTy, types, false); + llvm::Type *types[] = {getPtrToType(dsoDataTy)}; + llvm::FunctionType *fty = llvm::FunctionType::get(LLvoidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } - // extern (C) void _d_cover_register2(string filename, size_t[] valid, uint[] - // data, ubyte minPercent) - // as defined in druntime/rt/cover.d. - 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(fn->getFunctionType(), LINKc)); + // extern (C) void _d_cover_register2(string filename, size_t[] valid, + // uint[] data, ubyte minPercent) + if (global.params.cov) { + createFwdDecl(LINKc, voidTy, {"_d_cover_register2"}, + {stringTy, sizeTy->arrayOf(), uintTy->arrayOf(), ubyteTy}); } } diff --git a/gen/runtime.h b/gen/runtime.h index 8e9dc925397..3c6118391a5 100644 --- a/gen/runtime.h +++ b/gen/runtime.h @@ -23,14 +23,13 @@ class Module; struct Loc; // D runtime support helpers +bool initRuntime(); +void freeRuntime(); -bool LLVM_D_InitRuntime(); -void LLVM_D_FreeRuntime(); - -llvm::Function *LLVM_D_GetRuntimeFunction(const Loc &loc, llvm::Module &target, +llvm::Function *getRuntimeFunction(const Loc &loc, llvm::Module &target, const char *name); llvm::GlobalVariable * -LLVM_D_GetRuntimeGlobal(const Loc &loc, llvm::Module &target, const char *name); +getRuntimeGlobal(const Loc &loc, llvm::Module &target, const char *name); #endif // LDC_GEN_RUNTIME_H diff --git a/gen/statements.cpp b/gen/statements.cpp index 4d32f6bdc54..165cc4135d5 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -73,7 +73,7 @@ static LLValue *call_string_switch_runtime(llvm::Value *table, Expression *e) { llvm_unreachable("not char/wchar/dchar"); } - llvm::Function *fn = LLVM_D_GetRuntimeFunction(e->loc, gIR->module, fname); + llvm::Function *fn = getRuntimeFunction(e->loc, gIR->module, fname); IF_LOG { Logger::cout() << *table->getType() << '\n'; @@ -745,7 +745,7 @@ class ToIRVisitor : public Visitor { irs->DBuilder.EmitBlockStart((*it)->loc); const auto enterCatchFn = - LLVM_D_GetRuntimeFunction(Loc(), irs->module, "_d_eh_enter_catch"); + getRuntimeFunction(Loc(), irs->module, "_d_eh_enter_catch"); auto exceptionStruct = DtoLoad(irs->func()->getOrCreateEhPtrSlot()); auto throwableObj = irs->ir->CreateCall(enterCatchFn, exceptionStruct); @@ -825,7 +825,7 @@ class ToIRVisitor : public Visitor { DValue *e = toElemDtor(stmt->exp); llvm::Function *fn = - LLVM_D_GetRuntimeFunction(stmt->loc, irs->module, "_d_throw_exception"); + getRuntimeFunction(stmt->loc, irs->module, "_d_throw_exception"); LLValue *arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0)); ; @@ -1507,7 +1507,7 @@ class ToIRVisitor : public Visitor { LOG_SCOPE; llvm::Function *fn = - LLVM_D_GetRuntimeFunction(stmt->loc, irs->module, "_d_switch_error"); + getRuntimeFunction(stmt->loc, irs->module, "_d_switch_error"); LLValue *moduleInfoSymbol = getIrModule(irs->func()->decl->getModule())->moduleInfoSymbol(); diff --git a/gen/toir.cpp b/gen/toir.cpp index c1fcadc21a1..a715ac3c23f 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1912,7 +1912,7 @@ class ToElemVisitor : public Visitor { !(static_cast(condty)->sym->isInterfaceDeclaration()) && !(static_cast(condty)->sym->isCPPclass())) { Logger::println("calling class invariant"); - llvm::Function *fn = LLVM_D_GetRuntimeFunction( + llvm::Function *fn = getRuntimeFunction( e->loc, gIR->module, gABI->mangleForLLVM("_D9invariant12_d_invariantFC6ObjectZv", LINKd) .c_str()); @@ -2668,7 +2668,7 @@ class ToElemVisitor : public Visitor { Type *indexType = static_cast(aatype)->index; assert(indexType && vtype); - llvm::Function *func = LLVM_D_GetRuntimeFunction( + llvm::Function *func = getRuntimeFunction( e->loc, gIR->module, "_d_assocarrayliteralTX"); LLFunctionType *funcTy = func->getFunctionType(); LLValue *aaTypeInfo = diff --git a/ir/irfunction.cpp b/ir/irfunction.cpp index 76d0ff1990c..5ee10bf268d 100644 --- a/ir/irfunction.cpp +++ b/ir/irfunction.cpp @@ -291,13 +291,13 @@ llvm::LandingPadInst *createLandingPadInst(IRState *irs) { LLFunction *currentFunction = irs->func()->func; if (!currentFunction->hasPersonalityFn()) { LLFunction *personalityFn = - LLVM_D_GetRuntimeFunction(Loc(), irs->module, "_d_eh_personality"); + getRuntimeFunction(Loc(), irs->module, "_d_eh_personality"); currentFunction->setPersonalityFn(personalityFn); } return irs->ir->CreateLandingPad(retType, 0); #else LLFunction *personalityFn = - LLVM_D_GetRuntimeFunction(Loc(), irs->module, "_d_eh_personality"); + getRuntimeFunction(Loc(), irs->module, "_d_eh_personality"); return irs->ir->CreateLandingPad(retType, personalityFn, 0); #endif } @@ -424,7 +424,7 @@ llvm::BasicBlock *IrFunction::getOrCreateResumeUnwindBlock() { gIR->scope() = IRScope(resumeUnwindBlock); llvm::Function *resumeFn = - LLVM_D_GetRuntimeFunction(Loc(), gIR->module, "_d_eh_resume_unwind"); + getRuntimeFunction(Loc(), gIR->module, "_d_eh_resume_unwind"); gIR->ir->CreateCall(resumeFn, gIR->ir->CreateLoad(getOrCreateEhPtrSlot())); gIR->ir->CreateUnreachable();