diff --git a/dmd/expression.c b/dmd/expression.c index 2e7c1255..b4647c12 100644 --- a/dmd/expression.c +++ b/dmd/expression.c @@ -3117,6 +3117,9 @@ StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions * #endif this->soffset = 0; this->fillHoles = 1; +#if IN_LLVM + constType = NULL; +#endif } Expression *StructLiteralExp::syntaxCopy() diff --git a/dmd/expression.h b/dmd/expression.h index 94f07f54..c4536907 100644 --- a/dmd/expression.h +++ b/dmd/expression.h @@ -66,6 +66,7 @@ struct DValue; namespace llvm { class Constant; class ConstantInt; + class StructType; } #endif @@ -537,6 +538,7 @@ struct StructLiteralExp : Expression #elif IN_LLVM DValue* toElem(IRState* irs); llvm::Constant *toConstElem(IRState *irs); + llvm::StructType *constType; #endif }; diff --git a/dmd/init.c b/dmd/init.c index ae3b0848..9d05d4cd 100644 --- a/dmd/init.c +++ b/dmd/init.c @@ -114,6 +114,9 @@ StructInitializer::StructInitializer(Loc loc) : Initializer(loc) { ad = NULL; +#if IN_LLVM + ltype = NULL; +#endif } Initializer *StructInitializer::syntaxCopy() diff --git a/dmd/init.h b/dmd/init.h index aab5d043..1b893882 100644 --- a/dmd/init.h +++ b/dmd/init.h @@ -30,6 +30,12 @@ struct ExpInitializer; struct HdrGenState; #endif +#if IN_LLVM +namespace llvm { + class StructType; +} +#endif + struct Initializer : Object { Loc loc; @@ -91,6 +97,9 @@ struct StructInitializer : Initializer #endif StructInitializer *isStructInitializer() { return this; } +#if IN_LLVM + llvm::StructType *ltype; +#endif }; struct ArrayInitializer : Initializer diff --git a/dmd/module.c b/dmd/module.c index 7fef940f..599dabba 100644 --- a/dmd/module.c +++ b/dmd/module.c @@ -153,7 +153,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen // LDC llvmForceLogging = false; moduleInfoVar = NULL; - moduleInfoType = new llvm::PATypeHolder(llvm::OpaqueType::get(llvm::getGlobalContext())); + moduleInfoType = llvm::StructType::create(llvm::getGlobalContext()); this->doDocComment = doDocComment; this->doHdrGen = doHdrGen; this->isRoot = false; diff --git a/dmd/module.h b/dmd/module.h index c32ddf3f..5ed79b72 100644 --- a/dmd/module.h +++ b/dmd/module.h @@ -35,7 +35,7 @@ namespace llvm { class LLVMContext; class Module; class GlobalVariable; - class PATypeHolder; + class StructType; } #else @@ -202,7 +202,7 @@ struct Module : Package bool llvmForceLogging; llvm::GlobalVariable* moduleInfoVar; - llvm::PATypeHolder* moduleInfoType; + llvm::StructType* moduleInfoType; // array ops emitted in this module already StringTable arrayfuncs; diff --git a/dmd2/attrib.c b/dmd2/attrib.c index baa2122e..01a09a12 100644 --- a/dmd2/attrib.c +++ b/dmd2/attrib.c @@ -1205,7 +1205,64 @@ void PragmaDeclaration::semantic(Scope *sc) } llvm_internal = LLVMva_arg; } - + + // pragma(fence) { templdecl(s) } + else if (ident == Id::fence) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + llvm_internal = LLVMfence; + } + + // pragma(atomic_load) { templdecl(s) } + else if (ident == Id::atomic_load) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + llvm_internal = LLVMatomic_load; + } + + // pragma(atomic_store) { templdecl(s) } + else if (ident == Id::atomic_store) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + llvm_internal = LLVMatomic_store; + } + + // pragma(atomic_cmp_xchg) { templdecl(s) } + else if (ident == Id::atomic_cmp_xchg) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + llvm_internal = LLVMatomic_cmp_xchg; + } + + // pragma(atomic_rmw, "string") { templdecl(s) } + else if (ident == Id::atomic_rmw) + { + Expression* expr = (Expression *)args->data[0]; + expr = expr->semantic(sc); + if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) + { + error("requires exactly 1 string literal parameter"); + fatal(); + } + llvm_internal = LLVMatomic_rmw; + } + // pragma(ldc, "string") { templdecl(s) } else if (ident == Id::ldc) { @@ -1317,8 +1374,24 @@ void PragmaDeclaration::semantic(Scope *sc) } break; + case LLVMatomic_rmw: + if (TemplateDeclaration* td = s->isTemplateDeclaration()) + { + td->llvmInternal = llvm_internal; + td->intrinsicName = arg1str; + } + else + { + error("the '%s' pragma is only allowed on template declarations", ident->toChars()); + fatal(); + } + break; + case LLVMva_start: case LLVMva_arg: + case LLVMatomic_load: + case LLVMatomic_store: + case LLVMatomic_cmp_xchg: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { if (td->parameters->dim != 1) @@ -1347,6 +1420,7 @@ void PragmaDeclaration::semantic(Scope *sc) case LLVMva_copy: case LLVMva_end: + case LLVMfence: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; diff --git a/dmd2/expression.c b/dmd2/expression.c index feea1339..656c7431 100644 --- a/dmd2/expression.c +++ b/dmd2/expression.c @@ -3776,6 +3776,9 @@ StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions * #endif this->soffset = 0; this->fillHoles = 1; +#if IN_LLVM + constType = NULL; +#endif } Expression *StructLiteralExp::syntaxCopy() diff --git a/dmd2/expression.h b/dmd2/expression.h index 4823fc33..37c25e1d 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -74,6 +74,7 @@ struct DValue; namespace llvm { class Constant; class ConstantInt; + class StructType; } #endif @@ -590,6 +591,7 @@ struct StructLiteralExp : Expression #elif IN_LLVM DValue* toElem(IRState* irs); llvm::Constant *toConstElem(IRState *irs); + llvm::StructType *constType; #endif }; diff --git a/dmd2/func.c b/dmd2/func.c index 58be1582..fd768e3c 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -1648,29 +1648,13 @@ void FuncDeclaration::semantic3(Scope *sc) #if STRUCTTHISREF if (ad->isStructDeclaration()) v = v->addressOf(sc); -#endif -#if IN_LLVM - //e = new AssertExp(loc, v, NULL); - - // LDC: check for null this - //v = new ThisExp(0); - //v->type = vthis->type; - //v->var = vthis; // Error: Expression has no property var... in D1 typeof(v) == ThisExp - - //NullExp *nv = new NullExp(0); - //nv->type = v->type; - - //IdentityExp *ie = new IdentityExp(TOKnotidentity, 0, v, nv); - //ie->type = Type::tbool; #endif Expression *se = new StringExp(0, (char *)"null this"); se = se->semantic(sc); +#if !IN_LLVM se->type = Type::tchar->arrayOf(); -//#if IN_LLVM -// ee = new AssertExp(loc, ie, se); -//#else +#endif e = new AssertExp(loc, v, se); -//#endif } if (ee) { diff --git a/dmd2/idgen.c b/dmd2/idgen.c index 05bd4f88..78b50226 100644 --- a/dmd2/idgen.c +++ b/dmd2/idgen.c @@ -282,6 +282,11 @@ Msgtable msgtable[] = { "ldc" }, { "allow_inline" }, { "llvm_inline_asm" }, + { "fence" }, + { "atomic_load" }, + { "atomic_store" }, + { "atomic_cmp_xchg" }, + { "atomic_rmw" }, #endif // For special functions diff --git a/dmd2/init.c b/dmd2/init.c index 521dce6b..6bf2f07a 100644 --- a/dmd2/init.c +++ b/dmd2/init.c @@ -114,6 +114,9 @@ StructInitializer::StructInitializer(Loc loc) : Initializer(loc) { ad = NULL; +#if IN_LLVM + ltype = NULL; +#endif } Initializer *StructInitializer::syntaxCopy() diff --git a/dmd2/init.h b/dmd2/init.h index d9038cca..d038dd9e 100644 --- a/dmd2/init.h +++ b/dmd2/init.h @@ -28,6 +28,12 @@ struct ArrayInitializer; struct ExpInitializer; struct HdrGenState; +#if IN_LLVM +namespace llvm { + class StructType; +} +#endif + struct Initializer : Object { @@ -91,6 +97,9 @@ struct StructInitializer : Initializer #endif StructInitializer *isStructInitializer() { return this; } +#if IN_LLVM + llvm::StructType *ltype; +#endif }; struct ArrayInitializer : Initializer diff --git a/dmd2/module.c b/dmd2/module.c index 87dd0c38..2852cb1b 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -213,7 +213,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen // LDC llvmForceLogging = false; moduleInfoVar = NULL; - moduleInfoType = new llvm::PATypeHolder(llvm::OpaqueType::get(llvm::getGlobalContext())); + moduleInfoType = llvm::StructType::create(llvm::getGlobalContext()); this->doDocComment = doDocComment; this->doHdrGen = doHdrGen; this->isRoot = false; diff --git a/dmd2/module.h b/dmd2/module.h index caf61bf4..22c8de2e 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -35,7 +35,7 @@ namespace llvm { class LLVMContext; class Module; class GlobalVariable; - class PATypeHolder; + class StructType; } #else @@ -208,7 +208,7 @@ struct Module : Package bool llvmForceLogging; llvm::GlobalVariable* moduleInfoVar; - llvm::PATypeHolder* moduleInfoType; + llvm::StructType* moduleInfoType; // array ops emitted in this module already AA *arrayfuncs; diff --git a/dmd2/statement.h b/dmd2/statement.h index da8588d6..69655615 100644 --- a/dmd2/statement.h +++ b/dmd2/statement.h @@ -106,6 +106,7 @@ enum BE struct Statement : Object { Loc loc; + virtual ~Statement() {} Statement(Loc loc); virtual Statement *syntaxCopy(); diff --git a/druntime b/druntime index 406e772a..54cd2ffd 160000 --- a/druntime +++ b/druntime @@ -1 +1 @@ -Subproject commit 406e772aa362e10829aa8eaf3832571001bc6b4b +Subproject commit 54cd2ffd40cba0b4b2264febc9e56f0c477e87fa diff --git a/gen/aa.cpp b/gen/aa.cpp index 434e2f1d..75720f75 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -55,7 +55,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) #else llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaIn"); #endif - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); // aa param LLValue* aaval = lvalue ? aa->getLVal() : aa->getRVal(); @@ -85,7 +85,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) } // cast return value - const LLType* targettype = getPtrToType(DtoType(type)); + LLType* targettype = getPtrToType(DtoType(type)); if (ret->getType() != targettype) ret = DtoBitCast(ret, targettype); @@ -109,7 +109,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) #if DMDV2 // module param LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol(); - const LLType *moduleInfoType = DtoType(Module::moduleinfo->type); + LLType *moduleInfoType = DtoType(Module::moduleinfo->type); args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType))); #else // file param @@ -123,7 +123,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) // call llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds"); - gIR->CreateCallOrInvoke(errorfn, args.begin(), args.end()); + gIR->CreateCallOrInvoke(errorfn, args); // the function does not return gIR->ir->CreateUnreachable(); @@ -152,7 +152,7 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key) #else llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaIn"); #endif - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); if (Logger::enabled()) Logger::cout() << "_aaIn = " << *func << '\n'; @@ -182,7 +182,7 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key) LLValue* ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.in").getInstruction(); // cast return value - const LLType* targettype = DtoType(type); + LLType* targettype = DtoType(type); if (ret->getType() != targettype) ret = DtoBitCast(ret, targettype); @@ -207,7 +207,7 @@ void DtoAARemove(Loc& loc, DValue* aa, DValue* key) #else llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaDel"); #endif - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); if (Logger::enabled()) Logger::cout() << "_aaDel = " << *func << '\n'; @@ -240,7 +240,7 @@ void DtoAARemove(Loc& loc, DValue* aa, DValue* key) args.push_back(pkey); // call runtime - gIR->CreateCallOrInvoke(func, args.begin(), args.end()); + gIR->CreateCallOrInvoke(func, args); } ///////////////////////////////////////////////////////////////////////////////////// @@ -251,7 +251,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"); #if DMDV2 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaEqual"); - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); LLValue* aaval = DtoBitCast(l->getRVal(), funcTy->getParamType(1)); LLValue* abval = DtoBitCast(r->getRVal(), funcTy->getParamType(2)); @@ -259,7 +259,7 @@ LLValue* DtoAAEquals(Loc& loc, TOK op, DValue* l, DValue* r) LLValue* res = gIR->CreateCallOrInvoke3(func, aaTypeInfo, aaval, abval, "aaEqRes").getInstruction(); #else llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaEq"); - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); LLValue* aaval = DtoBitCast(l->getRVal(), funcTy->getParamType(0)); LLValue* abval = DtoBitCast(r->getRVal(), funcTy->getParamType(1)); diff --git a/gen/abi-generic.h b/gen/abi-generic.h index dd8f66c5..a33b3d7d 100644 --- a/gen/abi-generic.h +++ b/gen/abi-generic.h @@ -29,7 +29,7 @@ struct RemoveStructPadding : ABIRewrite { } /// return the transformed type for this rewrite - virtual const LLType* type(Type* dty, const LLType* t) { + virtual LLType* type(Type* dty, LLType* t) { return DtoUnpaddedStructType(dty->toBasetype()); } }; @@ -47,7 +47,7 @@ struct X87_complex_swap : ABIRewrite { return DtoAggrPairSwap(v->getRVal()); } - const LLType* type(Type*, const LLType* t) + LLType* type(Type*, LLType* t) { return t; } @@ -84,10 +84,10 @@ struct X86_struct_to_register : ABIRewrite Logger::println("rewriting struct -> int"); assert(dv->isLVal()); LLValue* mem = dv->getLVal(); - const LLType* t = LLIntegerType::get(gIR->context(), dty->size()*8); + LLType* t = LLIntegerType::get(gIR->context(), dty->size()*8); return DtoLoad(DtoBitCast(mem, getPtrToType(t))); } - const LLType* type(Type* t, const LLType*) + LLType* type(Type* t, LLType*) { size_t sz = t->size()*8; return LLIntegerType::get(gIR->context(), sz); diff --git a/gen/abi-x86-64.cpp b/gen/abi-x86-64.cpp index d0c6a6b9..7c2e97fe 100644 --- a/gen/abi-x86-64.cpp +++ b/gen/abi-x86-64.cpp @@ -218,7 +218,7 @@ namespace { // Okay, we may need to transform. Figure out a canonical type: - std::vector parts; + std::vector parts; unsigned size = ty->size(); @@ -301,14 +301,14 @@ struct X86_64_C_struct_rewrite : ABIRewrite { DtoStore(rval, lval); } - const LLType* pTy = getPtrToType(DtoType(dty)); + LLType* pTy = getPtrToType(DtoType(dty)); return DtoLoad(DtoBitCast(lval, pTy), "get-result"); } // Get struct from ABI-mangled representation, and store in the provided location. void getL(Type* dty, DValue* v, llvm::Value* lval) { LLValue* rval = v->getRVal(); - const LLType* pTy = getPtrToType(rval->getType()); + LLType* pTy = getPtrToType(rval->getType()); DtoStore(rval, DtoBitCast(lval, pTy)); } @@ -328,12 +328,12 @@ struct X86_64_C_struct_rewrite : ABIRewrite { LLType* abiTy = getAbiType(dty); assert(abiTy && "Why are we rewriting a non-rewritten type?"); - const LLType* pTy = getPtrToType(abiTy); + LLType* pTy = getPtrToType(abiTy); return DtoLoad(DtoBitCast(lval, pTy), "put-result"); } /// should return the transformed type for this rewrite - const LLType* type(Type* dty, const LLType* t) + LLType* type(Type* dty, LLType* t) { return getAbiType(dty); } diff --git a/gen/abi.cpp b/gen/abi.cpp index 19c1928a..0ec72e7f 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -76,7 +76,7 @@ struct X86_cfloat_rewrite : ABIRewrite } // {float,float} -> i64 - const LLType* type(Type*, const LLType* t) + LLType* type(Type*, LLType* t) { return LLType::getInt64Ty(gIR->context()); } diff --git a/gen/abi.h b/gen/abi.h index 56f055fb..48a7fe48 100644 --- a/gen/abi.h +++ b/gen/abi.h @@ -27,7 +27,7 @@ struct ABIRewrite virtual LLValue* put(Type* dty, DValue* v) = 0; /// should return the transformed type for this rewrite - virtual const LLType* type(Type* dty, const LLType* t) = 0; + virtual LLType* type(Type* dty, LLType* t) = 0; }; // interface called by codegen diff --git a/gen/arrays.cpp b/gen/arrays.cpp index f18ac8e7..3493fd11 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -15,6 +15,7 @@ #include "gen/logger.h" #include "gen/dvalue.h" #include "ir/irmodule.h" +#include "ir/irtypestruct.h" #include "gen/cl_options.h" @@ -25,7 +26,7 @@ static LLValue *DtoSlice(DValue *dval) LLValue *val = dval->getRVal(); if (dval->getType()->toBasetype()->ty == Tsarray) { // Convert static array to slice - const LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context())); + LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context())); LLValue *array = DtoRawAlloca(type, 0, ".array"); DtoStore(DtoArrayLen(dval), DtoGEPi(array, 0, 0, ".len")); DtoStore(DtoBitCast(val, getVoidPtrType()), DtoGEPi(array, 0, 1, ".ptr")); @@ -39,7 +40,7 @@ static LLValue *DtoSlice(DValue *dval) static LLValue *DtoSlicePtr(DValue *dval) { Loc loc; - const LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context())); + LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context())); Type *vt = dval->getType()->toBasetype(); if (vt->ty == Tarray) return makeLValue(loc, dval); @@ -55,30 +56,37 @@ static LLValue *DtoSlicePtr(DValue *dval) ////////////////////////////////////////////////////////////////////////////////////////// -const LLStructType* DtoArrayType(Type* arrayTy) +LLStructType* DtoArrayType(Type* arrayTy) { assert(arrayTy->nextOf()); - const LLType* elemty = DtoType(arrayTy->nextOf()); + LLType* elemty = DtoType(arrayTy->nextOf()); if (elemty == LLType::getVoidTy(gIR->context())) elemty = LLType::getInt8Ty(gIR->context()); - return LLStructType::get(gIR->context(), DtoSize_t(), getPtrToType(elemty), NULL); + + llvm::SmallVector elems; + elems.push_back(DtoSize_t()); + elems.push_back(getPtrToType(elemty)); + return LLStructType::get(gIR->context(), llvm::makeArrayRef(elems)); } -const LLStructType* DtoArrayType(const LLType* t) +LLStructType* DtoArrayType(LLType* t) { - return LLStructType::get(gIR->context(), DtoSize_t(), getPtrToType(t), NULL); + llvm::SmallVector elems; + elems.push_back(DtoSize_t()); + elems.push_back(getPtrToType(t)); + return LLStructType::get(gIR->context(), llvm::makeArrayRef(elems)); } ////////////////////////////////////////////////////////////////////////////////////////// -const LLArrayType* DtoStaticArrayType(Type* t) +LLArrayType* DtoStaticArrayType(Type* t) { t = t->toBasetype(); assert(t->ty == Tsarray); TypeSArray* tsa = (TypeSArray*)t; Type* tnext = tsa->nextOf(); - const LLType* elemty = DtoType(tnext); + LLType* elemty = DtoType(tnext); if (elemty == LLType::getVoidTy(gIR->context())) elemty = LLType::getInt8Ty(gIR->context()); @@ -93,7 +101,7 @@ void DtoSetArrayToNull(LLValue* v) LOG_SCOPE; assert(isaPointer(v)); - const LLType* t = v->getType()->getContainedType(0); + LLType* t = v->getType()->getContainedType(0); DtoStore(LLConstant::getNullValue(t), v); } @@ -212,7 +220,7 @@ void DtoArrayAssign(DValue *array, DValue *value, int op) args.push_back(DtoAggrPaint(DtoSlice(value), fn->getFunctionType()->getParamType(1))); args.push_back(DtoAggrPaint(DtoSlice(array), fn->getFunctionType()->getParamType(2))); - LLCallSite call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".array"); + LLCallSite call = gIR->CreateCallOrInvoke(fn, args, ".array"); call.setCallingConv(llvm::CallingConv::C); } @@ -236,7 +244,7 @@ void DtoArraySetAssign(Loc &loc, DValue *array, DValue *value, int op) args.push_back(len); args.push_back(DtoTypeInfoOf(array->type->toBasetype()->nextOf()->toBasetype())); - LLCallSite call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".newptr"); + LLCallSite call = gIR->CreateCallOrInvoke(fn, args, ".newptr"); call.setCallingConv(llvm::CallingConv::C); } @@ -255,6 +263,85 @@ void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr) ////////////////////////////////////////////////////////////////////////////////////////// +// The function is almost identical copy of DtoConstArrayInitializer but it returns +// initializer type not the initializer itself. +// FIXME: is there any way to merge this next two functions? +LLType* DtoConstArrayInitializerType(ArrayInitializer* arrinit) +{ + Type* arrty = arrinit->type->toBasetype(); + if (arrty->ty != Tsarray) + return DtoType(arrinit->type); + + TypeSArray* tsa = (TypeSArray*)arrty; + size_t arrlen = (size_t)tsa->dim->toInteger(); + + // get elem type + Type* elemty = arrty->nextOf(); + LLType* llelemty = DtoTypeNotVoid(elemty); + + // make sure the number of initializers is sane + if (arrinit->index.dim > arrlen || arrinit->dim > arrlen) + { + error(arrinit->loc, "too many initializers, %u, for array[%zu]", arrinit->index.dim, arrlen); + fatal(); + } + + // true if array elements differ in type, can happen with array of unions + bool mismatch = false; + + // allocate room for types + std::vector types(arrlen, NULL); + + // go through each initializer, they're not sorted by index by the frontend + size_t j = 0; + for (size_t i = 0; i < arrinit->index.dim; i++) + { + // get index + Expression* idx = (Expression*)arrinit->index.data[i]; + + // idx can be null, then it's just the next element + if (idx) + j = idx->toInteger(); + assert(j < arrlen); + + // get value + Initializer* val = (Initializer*)arrinit->value.data[i]; + assert(val); + + LLType* c = DtoConstInitializerType(elemty, val); + assert(c); + if (c != llelemty) + mismatch = true; + + types[j] = c; + j++; + } + + // fill out any null entries still left with default type + + // element default types + LLType* deftype = DtoConstInitializerType(elemty, 0); + bool mismatch2 = (deftype != llelemty); + + for (size_t i = 0; i < arrlen; i++) + { + if (types[i] != NULL) + continue; + + types[i] = deftype; + + if (mismatch2) + mismatch = true; + } + + if (mismatch) + return LLStructType::get(gIR->context(), types); // FIXME should this pack? + else + return LLArrayType::get(deftype, arrlen); +} + +////////////////////////////////////////////////////////////////////////////////////////// + LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) { Logger::println("DtoConstArrayInitializer: %s | %s", arrinit->toChars(), arrinit->type->toChars()); @@ -283,7 +370,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) // get elem type Type* elemty = arrty->nextOf(); - const LLType* llelemty = DtoTypeNotVoid(elemty); + LLType* llelemty = DtoTypeNotVoid(elemty); // true if array elements differ in type, can happen with array of unions bool mismatch = false; @@ -345,7 +432,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) LLConstant* constarr; if (mismatch) - constarr = LLConstantStruct::get(gIR->context(), initvals, false); // FIXME should this pack? + constarr = LLConstantStruct::getAnon(gIR->context(), initvals); // FIXME should this pack? else constarr = LLConstantArray::get(LLArrayType::get(llelemty, arrlen), initvals); @@ -363,7 +450,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) #if DMDV2 if (arrty->ty == Tpointer) // we need to return pointer to the static array. - return gvar; + return DtoBitCast(gvar, DtoType(arrty)); #endif LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; @@ -371,14 +458,14 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); gep = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(llelemty)); - return DtoConstSlice(DtoConstSize_t(arrlen),gep); + return DtoConstSlice(DtoConstSize_t(arrlen), gep, arrty); } ////////////////////////////////////////////////////////////////////////////////////////// static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz) { assert(e->len != 0); - const LLType* t = e->ptr->getType()->getContainedType(0); + LLType* t = e->ptr->getType()->getContainedType(0); sz = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(t)), e->len, "tmp"); return DtoBitCast(e->ptr, getVoidPtrType()); } @@ -410,7 +497,7 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src) LLValue* dstarr = get_slice_ptr(dst,sz1); LLValue* srcarr = DtoBitCast(DtoArrayPtr(src), getVoidPtrType()); - const LLType* arrayelemty = DtoTypeNotVoid(src->getType()->nextOf()->toBasetype()); + LLType* arrayelemty = DtoTypeNotVoid(src->getType()->nextOf()->toBasetype()); LLValue* sz2 = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(arrayelemty)), DtoArrayLen(src), "tmp"); if (global.params.useAssert || global.params.useArrayBounds) @@ -434,10 +521,14 @@ void DtoStaticArrayCopy(LLValue* dst, LLValue* src) } ////////////////////////////////////////////////////////////////////////////////////////// -LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) +LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr, Type *type) { LLConstant* values[2] = { dim, ptr }; - return LLConstantStruct::get(gIR->context(), values, 2, false); + llvm::ArrayRef valuesRef = llvm::makeArrayRef(values, 2); + LLStructType *lltype = type ? + isaStruct(DtoType(type)) : + LLConstantStruct::getTypeForElements(gIR->context(), valuesRef); + return LLConstantStruct::get(lltype, valuesRef); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -468,7 +559,7 @@ static DSliceValue *getSlice(Type *arrayType, LLValue *array) LLValue* newptr = DtoExtractValue(array, 1, ".ptr"); // cast pointer to wanted type - const LLType* dstType = DtoType(arrayType)->getContainedType(1); + LLType* dstType = DtoType(arrayType)->getContainedType(1); if (newptr->getType() != dstType) newptr = DtoBitCast(newptr, dstType, ".gc_mem"); @@ -513,7 +604,7 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default LLValue* newptr = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction(); // cast to wanted type - const LLType* dstType = DtoType(arrayType)->getContainedType(1); + LLType* dstType = DtoType(arrayType)->getContainedType(1); if (newptr->getType() != dstType) newptr = DtoBitCast(newptr, dstType, ".gc_mem"); @@ -559,7 +650,7 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size args.push_back(dims[i]->getRVal()); // call allocator - LLValue* newptr = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem").getInstruction(); + LLValue* newptr = gIR->CreateCallOrInvoke(fn, args, ".gc_mem").getInstruction(); if (Logger::enabled()) Logger::cout() << "final ptr = " << *newptr << '\n'; @@ -584,7 +675,7 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size LLValue* newptr = gIR->CreateCallOrInvoke3(fn, arrayTypeInfo, DtoConstSize_t(ndims), dimsArg, ".gc_mem").getInstruction(); // cast to wanted type - const LLType* dstType = DtoType(arrayType)->getContainedType(1); + LLType* dstType = DtoType(arrayType)->getContainedType(1); if (newptr->getType() != dstType) newptr = DtoBitCast(newptr, dstType, ".gc_mem"); @@ -620,7 +711,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim) #if DMDV2 args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(2))); - LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem").getInstruction(); + LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".gc_mem").getInstruction(); return getSlice(arrayType, newArray); @@ -633,7 +724,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim) Logger::cout() << "arrPtr = " << *arrPtr << '\n'; args.push_back(DtoBitCast(arrPtr, fn->getFunctionType()->getParamType(3), "tmp")); - LLValue* newptr = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem").getInstruction(); + LLValue* newptr = gIR->CreateCallOrInvoke(fn, args, ".gc_mem").getInstruction(); if (newptr->getType() != arrPtr->getType()) newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem"); @@ -664,7 +755,7 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(1))); args.push_back(DtoConstSize_t(1)); - LLValue* appendedArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction(); + LLValue* appendedArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction(); appendedArray = DtoAggrPaint(appendedArray, DtoType(arrayType)); LLValue* val = DtoExtractValue(appendedArray, 1, ".ptr"); @@ -691,7 +782,7 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(1))); args.push_back(DtoBitCast(valueToAppend, getVoidPtrType())); - gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray"); + gIR->CreateCallOrInvoke(fn, args, ".appendedArray"); } #endif @@ -719,7 +810,7 @@ DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp) args.push_back(y); // Call _d_arrayappendT - LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction(); + LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction(); return getSlice(arrayType, newArray); } @@ -806,7 +897,7 @@ DSliceValue* DtoCatArrays(Type* arrayType, Expression* exp1, Expression* exp2) args.push_back(val); } - LLValue *newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction(); + LLValue *newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction(); return getSlice(arrayType, newArray); } @@ -937,7 +1028,7 @@ DSliceValue* DtoAppendDChar(DValue* arr, Expression* exp, const char *func) args.push_back(DtoBitCast(valueToAppend->getRVal(), fn->getFunctionType()->getParamType(1))); // Call function - LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction(); + LLValue* newArray = gIR->CreateCallOrInvoke(fn, args, ".appendedArray").getInstruction(); return getSlice(arrayType, newArray); } @@ -1002,7 +1093,7 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(2))); } - LLCallSite call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), "tmp"); + LLCallSite call = gIR->CreateCallOrInvoke(fn, args, "tmp"); return call.getInstruction(); } @@ -1078,7 +1169,7 @@ LLValue* DtoArrayCompare(Loc& loc, TOK op, DValue* l, DValue* r) } ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty) +LLValue* DtoArrayCastLength(LLValue* len, LLType* elemty, LLType* newelemty) { Logger::println("DtoArrayCastLength"); LOG_SCOPE; @@ -1098,7 +1189,7 @@ LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* ne args.push_back(LLConstantInt::get(DtoSize_t(), nsz, false)); LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len"); - return gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), "tmp").getInstruction(); + return gIR->CreateCallOrInvoke(fn, args, "tmp").getInstruction(); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1184,7 +1275,7 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to) Logger::println("DtoCastArray"); LOG_SCOPE; - const LLType* tolltype = DtoType(to); + LLType* tolltype = DtoType(to); Type* totype = to->toBasetype(); Type* fromtype = u->getType()->toBasetype(); @@ -1211,8 +1302,8 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to) if (Logger::enabled()) Logger::cout() << "to array" << '\n'; - const LLType* ptrty = DtoArrayType(totype)->getContainedType(1); - const LLType* ety = DtoTypeNotVoid(fromtype->nextOf()); + LLType* ptrty = DtoArrayType(totype)->getContainedType(1); + LLType* ety = DtoTypeNotVoid(fromtype->nextOf()); if (fromtype->ty == Tsarray) { LLValue* uval = u->getRVal(); @@ -1221,7 +1312,7 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to) Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; assert(isaPointer(uval->getType())); - const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); + LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); if(arrty->getNumElements()*fromtype->nextOf()->size() % totype->nextOf()->size() != 0) { @@ -1258,8 +1349,8 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to) Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; assert(isaPointer(uval->getType())); - - /*const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); + + /*LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); if(arrty->getNumElements()*fromtype->nextOf()->size() != tosize*totype->nextOf()->size()) { error(loc, "invalid cast from '%s' to '%s', the sizes are not the same", fromtype->toChars(), totype->toChars()); @@ -1353,7 +1444,7 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun #if DMDV2 // module param LLValue *moduleInfoSymbol = funcmodule->moduleInfoSymbol(); - const LLType *moduleInfoType = DtoType(Module::moduleinfo->type); + LLType *moduleInfoType = DtoType(Module::moduleinfo->type); args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType))); #else // file param @@ -1376,7 +1467,7 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, DValue* lowerBoun // call llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds"); - gIR->CreateCallOrInvoke(errorfn, args.begin(), args.end()); + gIR->CreateCallOrInvoke(errorfn, args); // the function does not return gIR->ir->CreateUnreachable(); diff --git a/gen/arrays.h b/gen/arrays.h index 231b1c52..409cf123 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -5,12 +5,13 @@ struct ArrayInitializer; struct DSliceValue; -const llvm::StructType* DtoArrayType(Type* arrayTy); -const llvm::StructType* DtoArrayType(const LLType* elemTy); -const llvm::ArrayType* DtoStaticArrayType(Type* sarrayTy); +llvm::StructType* DtoArrayType(Type* arrayTy); +llvm::StructType* DtoArrayType(LLType* elemTy); +llvm::ArrayType* DtoStaticArrayType(Type* sarrayTy); +LLType* DtoConstArrayInitializerType(ArrayInitializer* arrinit); LLConstant* DtoConstArrayInitializer(ArrayInitializer* si); -LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr); +LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr, Type *type = 0); void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src); void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src); @@ -45,7 +46,7 @@ LLValue* DtoArrayCompare(Loc& loc, TOK op, DValue* l, DValue* r); LLValue* DtoDynArrayIs(TOK op, DValue* l, DValue* r); -LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty); +LLValue* DtoArrayCastLength(LLValue* len, LLType* elemty, LLType* newelemty); LLValue* DtoArrayLen(DValue* v); LLValue* DtoArrayPtr(DValue* v); diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index dc5c7c58..67123b0d 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -645,8 +645,8 @@ void AsmBlockStatement::toIR(IRState* p) // build asm block std::vector outargs; std::vector inargs; - std::vector outtypes; - std::vector intypes; + std::vector outtypes; + std::vector intypes; std::string out_c; std::string in_c; std::string clobbers; @@ -714,14 +714,14 @@ void AsmBlockStatement::toIR(IRState* p) Logger::println("constraints = \"%s\"", out_c.c_str()); // build return types - const LLType* retty; + LLType* retty; if (asmblock->retn) retty = asmblock->retty; else retty = llvm::Type::getVoidTy(gIR->context()); // build argument types - std::vector types; + std::vector types; types.insert(types.end(), outtypes.begin(), outtypes.end()); types.insert(types.end(), intypes.begin(), intypes.end()); llvm::FunctionType* fty = llvm::FunctionType::get(retty, types, false); @@ -746,7 +746,7 @@ void AsmBlockStatement::toIR(IRState* p) llvm::InlineAsm* ia = llvm::InlineAsm::get(fty, code, out_c, true); - llvm::CallInst* call = p->ir->CreateCall(ia, args.begin(), args.end(), + llvm::CallInst* call = p->ir->CreateCall(ia, args, retty == LLType::getVoidTy(gIR->context()) ? "" : "asm"); if (Logger::enabled()) diff --git a/gen/cl_options.cpp b/gen/cl_options.cpp index 252fc5ca..b6b51261 100644 --- a/gen/cl_options.cpp +++ b/gen/cl_options.cpp @@ -242,6 +242,31 @@ cl::list mAttrs("mattr", cl::opt mTargetTriple("mtriple", cl::desc("Override target triple")); +cl::opt mRelocModel("relocation-model", + cl::desc("Relocation model"), + cl::init(llvm::Reloc::Default), + cl::values( + clEnumValN(llvm::Reloc::Default, "default", + "Target default relocation model"), + clEnumValN(llvm::Reloc::Static, "static", + "Non-relocatable code"), + clEnumValN(llvm::Reloc::PIC_, "pic", + "Fully relocatable, position independent code"), + clEnumValN(llvm::Reloc::DynamicNoPIC, "dynamic-no-pic", + "Relocatable external references, non-relocatable code"), + clEnumValEnd)); + +cl::opt mCodeModel("code-model", + cl::desc("Code model"), + cl::init(llvm::CodeModel::Default), + cl::values( + clEnumValN(llvm::CodeModel::Default, "default", "Target default code model"), + clEnumValN(llvm::CodeModel::Small, "small", "Small code model"), + clEnumValN(llvm::CodeModel::Kernel, "kernel", "Kernel code model"), + clEnumValN(llvm::CodeModel::Medium, "medium", "Medium code model"), + clEnumValN(llvm::CodeModel::Large, "large", "Large code model"), + clEnumValEnd)); + // "Hidden debug switches" // Are these ever used? diff --git a/gen/cl_options.h b/gen/cl_options.h index 8965a20e..c3ffcda9 100644 --- a/gen/cl_options.h +++ b/gen/cl_options.h @@ -7,6 +7,7 @@ #include #include "llvm/Support/CommandLine.h" +#include "llvm/Support/CodeGen.h" namespace opts { namespace cl = llvm::cl; @@ -43,6 +44,8 @@ namespace opts { extern cl::opt mCPU; extern cl::list mAttrs; extern cl::opt mTargetTriple; + extern cl::opt mRelocModel; + extern cl::opt mCodeModel; extern cl::opt singleObj; extern cl::opt linkonceTemplates; diff --git a/gen/classes.cpp b/gen/classes.cpp index 0e1e871a..a8fb39f7 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -165,7 +165,7 @@ DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp) LLValue* dst = DtoGEPi(mem,0,idx,"tmp"); if (Logger::enabled()) Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; - DtoStore(src, dst); + DtoStore(src, DtoBitCast(dst, getPtrToType(src->getType()))); } // set the context for nested classes else if (tc->sym->isNested() && tc->sym->vthis) @@ -230,7 +230,7 @@ void DtoFinalizeClass(LLValue* inst) LLSmallVector arg; arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); // call - gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end(), ""); + gIR->CreateCallOrInvoke(fn, arg, ""); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -245,7 +245,7 @@ DValue* DtoCastClass(DValue* val, Type* _to) // class -> pointer if (to->ty == Tpointer) { IF_LOG Logger::println("to pointer"); - const LLType* tolltype = DtoType(_to); + LLType* tolltype = DtoType(_to); LLValue* rval = DtoBitCast(val->getRVal(), tolltype); return new DImValue(_to, rval); } @@ -304,7 +304,7 @@ DValue* DtoCastClass(DValue* val, Type* _to) LLValue* v = val->getRVal(); LLValue* orig = v; v = DtoGEPi(v, 0, i_index); - const LLType* ifType = DtoType(_to); + LLType* ifType = DtoType(_to); if (Logger::enabled()) { Logger::cout() << "V = " << *v << std::endl; @@ -339,7 +339,7 @@ DValue* DtoCastClass(DValue* val, Type* _to) // class -> class - static down cast else if (tc->sym->isBaseOf(fc->sym,NULL)) { Logger::println("static down cast"); - const LLType* tolltype = DtoType(_to); + LLType* tolltype = DtoType(_to); LLValue* rval = DtoBitCast(val->getRVal(), tolltype); return new DImValue(_to, rval); } @@ -362,7 +362,7 @@ DValue* DtoDynamicCastObject(DValue* val, Type* _to) ClassDeclaration::classinfo->codegen(Type::sir); llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast"); - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); std::vector args; @@ -398,7 +398,7 @@ DValue* DtoCastInterfaceToObject(DValue* val, Type* to) // Object _d_toObject(void* p) llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject"); - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); // void* p LLValue* tmp = val->getRVal(); @@ -427,7 +427,7 @@ DValue* DtoDynamicCastInterface(DValue* val, Type* _to) ClassDeclaration::classinfo->codegen(Type::sir); llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast"); - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); std::vector args; @@ -470,7 +470,7 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd) assert(field); // get the start pointer - const LLType* st = DtoType(cd->type); + LLType* st = DtoType(cd->type); // cast to the struct type src = DtoBitCast(src, st); @@ -575,7 +575,7 @@ static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd) return llvm::ConstantStruct::get(inits); } -static LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT) +static LLConstant* build_offti_array(ClassDeclaration* cd, LLType* arrayT) { IrStruct* irstruct = cd->ir.irStruct; @@ -594,7 +594,7 @@ static LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT) return LLConstant::getNullValue( arrayT ); // array type - const llvm::ArrayType* arrTy = llvm::ArrayType::get(arrayInits[0]->getType(), nvars); + LLArrayType* arrTy = llvm::ArrayType::get(arrayInits[0]->getType(), nvars); LLConstant* arrInit = LLConstantArray::get(arrTy, arrayInits); // mangle @@ -703,8 +703,8 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd) LLConstant* c; - const LLType* voidPtr = getVoidPtrType(); - const LLType* voidPtrPtr = getPtrToType(voidPtr); + LLType* voidPtr = getVoidPtrType(); + LLType* voidPtrPtr = getPtrToType(voidPtr); // byte[] init if (cd->isInterfaceDeclaration()) @@ -713,7 +713,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd) } else { - const LLType* cd_type = stripModifiers(cdty)->irtype->getPA(); + LLType* cd_type = stripModifiers(cdty)->irtype->getType(); size_t initsz = getTypePaddedSize(cd_type); b.push_void_array(initsz, ir->getInitSymbol()); } @@ -809,13 +809,14 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd) }*/ // build the initializer - LLConstant* finalinit = b.get_constant(); + LLType *initType = ir->classInfo->getType()->getContainedType(0); + LLConstant* finalinit = b.get_constant(isaStruct(initType)); //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; ir->constClassInfo = finalinit; // sanity check - assert(finalinit->getType() == ir->classInfo->getType()->getContainedType(0) && + assert(finalinit->getType() == initType && "__ClassZ initializer does not match the ClassInfo type"); // return initializer diff --git a/gen/complex.cpp b/gen/complex.cpp index 170b2154..bffc4965 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -12,14 +12,17 @@ ////////////////////////////////////////////////////////////////////////////////////////// -const llvm::StructType* DtoComplexType(Type* type) +llvm::StructType* DtoComplexType(Type* type) { Type* t = type->toBasetype(); - const LLType* base = DtoComplexBaseType(t); - return llvm::StructType::get(gIR->context(), base, base, NULL); + LLType* base = DtoComplexBaseType(t); + llvm::SmallVector types; + types.push_back(base); + types.push_back(base); + return llvm::StructType::get(gIR->context(), types); } -const LLType* DtoComplexBaseType(Type* t) +LLType* DtoComplexBaseType(Type* t) { TY ty = t->toBasetype()->ty; if (ty == Tcomplex32) { @@ -83,7 +86,7 @@ LLValue* DtoImagPart(DValue* val) DValue* DtoComplex(Loc& loc, Type* to, DValue* val) { - const LLType* complexTy = DtoType(to); + LLType* complexTy = DtoType(to); Type* baserety; Type* baseimty; @@ -444,7 +447,7 @@ DValue* DtoCastComplex(Loc& loc, DValue* val, Type* _to) llvm::Value *re, *im; DtoGetComplexParts(loc, val->getType(), val, re, im); - const LLType* toty = DtoComplexBaseType(to); + LLType* toty = DtoComplexBaseType(to); if (to->size() < vty->size()) { re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); diff --git a/gen/complex.h b/gen/complex.h index 04e84e08..fd3079d1 100644 --- a/gen/complex.h +++ b/gen/complex.h @@ -1,8 +1,8 @@ #ifndef LDC_GEN_COMPLEX_H #define LDC_GEN_COMPLEX_H -const llvm::StructType* DtoComplexType(Type* t); -const LLType* DtoComplexBaseType(Type* t); +llvm::StructType* DtoComplexType(Type* t); +LLType* DtoComplexBaseType(Type* t); LLConstant* DtoConstComplex(Type* t, long double re, long double im); diff --git a/gen/configfile.cpp b/gen/configfile.cpp index 979010b2..eacfeac2 100644 --- a/gen/configfile.cpp +++ b/gen/configfile.cpp @@ -20,7 +20,7 @@ ConfigFile::ConfigFile() ConfigFile::~ConfigFile() { - delete cfg; + // delete cfg; } diff --git a/gen/declarations.cpp b/gen/declarations.cpp index b13cd192..8750dc9b 100644 --- a/gen/declarations.cpp +++ b/gen/declarations.cpp @@ -6,11 +6,13 @@ #include "id.h" #include "rmem.h" #include "template.h" +#include "init.h" #include "gen/irstate.h" #include "gen/tollvm.h" #include "gen/llvmhelpers.h" #include "gen/logger.h" +#include "gen/todebug.h" #include "ir/ir.h" #include "ir/irvar.h" @@ -129,14 +131,17 @@ void VarDeclaration::codegen(Ir* p) bool _isconst = isConst(); #endif - Logger::println("Creating global variable"); - const LLType* _type = this->ir.irGlobal->type.get(); - llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this); + assert(!ir.initialized); + ir.initialized = gIR->dmodule; std::string _name(mangle()); - llvm::GlobalVariable* gvar = new llvm::GlobalVariable(*gIR->module,_type,_isconst,_linkage,NULL,_name,0,isThreadlocal()); + LLType *_type = DtoConstInitializerType(type, init); + + // create the global variable + LLGlobalVariable* gvar = new LLGlobalVariable(*gIR->module, _type, _isconst, + DtoLinkage(this), NULL, _name, 0, isThreadlocal()); this->ir.irGlobal->value = gvar; // set the alignment @@ -150,8 +155,31 @@ void VarDeclaration::codegen(Ir* p) if (nakedUse) gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType())); - // initialize - DtoConstInitGlobal(this); + // assign the initializer + if (!(storage_class & STCextern) && mustDefineSymbol(this)) + { + if (Logger::enabled()) + { + Logger::println("setting initializer"); + Logger::cout() << "global: " << *gvar << '\n'; + #if 0 + Logger::cout() << "init: " << *initVal << '\n'; + #endif + } + // build the initializer + LLConstant *initVal = DtoConstInitializer(loc, type, init); + + // set the initializer + assert(!ir.irGlobal->constInit); + ir.irGlobal->constInit = initVal; + gvar->setInitializer(initVal); + + #ifndef DISABLE_DEBUG_INFO + // do debug info + if (global.params.symdebug) + DtoDwarfGlobalVariable(gvar, this); + #endif + } } } diff --git a/gen/dvalue.cpp b/gen/dvalue.cpp index 549b7aca..cf0a4bdd 100644 --- a/gen/dvalue.cpp +++ b/gen/dvalue.cpp @@ -8,6 +8,7 @@ #include "declaration.h" + ///////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/dvalue.h b/gen/dvalue.h index 26c6b77a..8c431e4e 100644 --- a/gen/dvalue.h +++ b/gen/dvalue.h @@ -9,6 +9,7 @@ handling is necessary, they hold enough information to do-the-right-thing (TM) #include #include "root.h" +#include "mem.h" struct Type; struct Dsymbol; @@ -50,7 +51,6 @@ struct DValue : Object virtual DFieldValue* isField() { return NULL; } virtual DSliceValue* isSlice() { return NULL; } virtual DFuncValue* isFunc() { return NULL; } - protected: DValue() {} DValue(const DValue&) { } diff --git a/gen/enums.h b/gen/enums.h index 78a40fda..6d111c3c 100644 --- a/gen/enums.h +++ b/gen/enums.h @@ -9,5 +9,10 @@ enum LLVMva_copy, LLVMva_end, LLVMva_arg, - LLVMinline_asm + LLVMinline_asm, + LLVMfence, + LLVMatomic_store, + LLVMatomic_load, + LLVMatomic_cmp_xchg, + LLVMatomic_rmw }; diff --git a/gen/functions.cpp b/gen/functions.cpp index 49d066c5..be8b1f11 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -26,7 +26,7 @@ using namespace llvm::Attribute; -const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain) +llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain) { if (Logger::enabled()) Logger::println("DtoFunctionType(%s)", type->toChars()); @@ -187,7 +187,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest abi->doneWithFunctionType(); // build the function type - std::vector argtypes; + std::vector argtypes; argtypes.reserve(lidx); if (f->fty.arg_sret) argtypes.push_back(f->fty.arg_sret->ltype); @@ -209,7 +209,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest std::reverse(argtypes.begin() + beg, argtypes.end()); } - llvm::FunctionType* functype = llvm::FunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg); + LLFunctionType* functype = LLFunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg); Logger::cout() << "Final function type: " << *functype << "\n"; @@ -218,10 +218,10 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest ////////////////////////////////////////////////////////////////////////////////////////// -static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) +static llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) { TypeFunction* f = (TypeFunction*)fdecl->type; - const llvm::FunctionType* fty = 0; + LLFunctionType* fty = 0; // create new ir funcTy f->fty.reset(); @@ -244,7 +244,7 @@ static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) ////////////////////////////////////////////////////////////////////////////////////////// -const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl) +llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl) { // handle for C vararg intrinsics if (fdecl->isVaIntrinsic()) @@ -256,7 +256,7 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl) if (AggregateDeclaration* ad = fdecl->isMember2()) { Logger::println("isMember = this is: %s", ad->type->toChars()); dthis = ad->type; - const LLType* thisty = DtoType(dthis); + LLType* thisty = DtoType(dthis); //Logger::cout() << "this llvm type: " << *thisty << '\n'; if (ad->isStructDeclaration()) thisty = getPtrToType(thisty); @@ -270,7 +270,7 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl) dnest = Type::tvoid->pointerTo(); } - const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, dthis, dnest, fdecl->isMain()); + LLFunctionType* functype = DtoFunctionType(fdecl->type, dthis, dnest, fdecl->isMain()); return functype; } @@ -472,15 +472,15 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) else mangled_name = fdecl->mangle(); - llvm::Function* vafunc = 0; + LLFunction* vafunc = 0; if (fdecl->isVaIntrinsic()) vafunc = DtoDeclareVaFunction(fdecl); // construct function - const llvm::FunctionType* functype = DtoFunctionType(fdecl); - llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name); + LLFunctionType* functype = DtoFunctionType(fdecl); + LLFunction* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name); if (!func) { - func = llvm::Function::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module); + func = LLFunction::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module); } else if (func->getFunctionType() != functype) { error(fdecl->loc, "Function type does not match previously declared function with the same mangled name: %s", fdecl->mangle()); } @@ -756,7 +756,7 @@ void DtoDefineFunction(FuncDeclaration* fd) if (!refout && (!f->fty.args[i]->byref || lazy)) { // alloca a stack slot for this first class value arg - const LLType* argt; + LLType* argt; if (lazy) argt = irloc->value->getType(); else @@ -877,7 +877,7 @@ void DtoDefineFunction(FuncDeclaration* fd) ////////////////////////////////////////////////////////////////////////////////////////// -const llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl) +llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl) { Dsymbol* parent = fdecl->toParent(); ClassDeclaration* cd = parent->isClassDeclaration(); diff --git a/gen/functions.h b/gen/functions.h index bc569e9f..390422f1 100644 --- a/gen/functions.h +++ b/gen/functions.h @@ -13,10 +13,10 @@ namespace llvm class Value; } -const llvm::FunctionType* DtoFunctionType(Type* t, Type* thistype, Type* nesttype, bool ismain = false); -const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl); +llvm::FunctionType* DtoFunctionType(Type* t, Type* thistype, Type* nesttype, bool ismain = false); +llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl); -const llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl); +llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl); void DtoResolveFunction(FuncDeclaration* fdecl); void DtoDeclareFunction(FuncDeclaration* fdecl); diff --git a/gen/irstate.cpp b/gen/irstate.cpp index 6cf3b1d9..e2ca388d 100644 --- a/gen/irstate.cpp +++ b/gen/irstate.cpp @@ -127,14 +127,14 @@ bool IRState::scopereturned() LLCallSite IRState::CreateCallOrInvoke(LLValue* Callee, const char* Name) { LLSmallVector args; - return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name); + return CreateCallOrInvoke(Callee, args, Name); } LLCallSite IRState::CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name) { LLSmallVector args; args.push_back(Arg1); - return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name); + return CreateCallOrInvoke(Callee, args, Name); } LLCallSite IRState::CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name) @@ -142,7 +142,7 @@ LLCallSite IRState::CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* LLSmallVector args; args.push_back(Arg1); args.push_back(Arg2); - return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name); + return CreateCallOrInvoke(Callee, args, Name); } LLCallSite IRState::CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name) @@ -151,7 +151,7 @@ LLCallSite IRState::CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* args.push_back(Arg1); args.push_back(Arg2); args.push_back(Arg3); - return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name); + return CreateCallOrInvoke(Callee, args, Name); } LLCallSite IRState::CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name) @@ -161,7 +161,7 @@ LLCallSite IRState::CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* args.push_back(Arg2); args.push_back(Arg3); args.push_back(Arg4); - return CreateCallOrInvoke(Callee, args.begin(), args.end(), Name); + return CreateCallOrInvoke(Callee, args, Name); } diff --git a/gen/irstate.h b/gen/irstate.h index ca26c8b4..d553a211 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -90,7 +90,7 @@ struct IRAsmBlock std::vector internalLabels; AsmBlockStatement* asmBlock; - const LLType* retty; + LLType* retty; unsigned retn; bool retemu; // emulate abi ret with a temporary LLValue* (*retfixup)(IRBuilderHelper b, LLValue* orig); // Modifies retval @@ -111,9 +111,9 @@ struct IRState llvm::Module* module; // interface info type, used in DtoInterfaceInfoType - const LLStructType* interfaceInfoType; - const LLStructType* mutexType; - const LLStructType* moduleRefType; + LLStructType* interfaceInfoType; + LLStructType* mutexType; + LLStructType* moduleRefType; // helper to get the LLVMContext of the module llvm::LLVMContext& context() const { return module->getContext(); } @@ -148,8 +148,8 @@ struct IRState // create a call or invoke, depending on the landing pad info // the template function is defined further down in this file - template - llvm::CallSite CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name=""); + template + llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const T& args, const char* Name=""); llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const char* Name=""); llvm::CallSite CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name=""); llvm::CallSite CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name=""); @@ -196,8 +196,8 @@ struct IRState std::vector usedArray; }; -template -llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name) +template +llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, const T &args, const char* Name) { llvm::BasicBlock* pad = func()->gen->landingPad; if(pad) @@ -206,13 +206,13 @@ llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBeg LLFunction* funcval = llvm::dyn_cast(Callee); if (funcval && (funcval->isIntrinsic() || funcval->doesNotThrow())) { - llvm::CallInst* call = ir->CreateCall(Callee, ArgBegin, ArgEnd, Name); + llvm::CallInst* call = ir->CreateCall(Callee, args, Name); call->setAttributes(funcval->getAttributes()); return call; } llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create(gIR->context(), "postinvoke", topfunc(), scopeend()); - llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, pad, ArgBegin, ArgEnd, Name); + llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, pad, args, Name); if (LLFunction* fn = llvm::dyn_cast(Callee)) invoke->setAttributes(fn->getAttributes()); scope() = IRScope(postinvoke, scopeend()); @@ -220,7 +220,7 @@ llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBeg } else { - llvm::CallInst* call = ir->CreateCall(Callee, ArgBegin, ArgEnd, Name); + llvm::CallInst* call = ir->CreateCall(Callee, args, Name); if (LLFunction* fn = llvm::dyn_cast(Callee)) call->setAttributes(fn->getAttributes()); return call; diff --git a/gen/llvm.h b/gen/llvm.h index 1221c055..da246f94 100644 --- a/gen/llvm.h +++ b/gen/llvm.h @@ -47,8 +47,6 @@ using llvm::IRBuilder; #define LLConstantInt llvm::ConstantInt #define LLConstantFP llvm::ConstantFP -#define LLPATypeHolder llvm::PATypeHolder - #define LLCallSite llvm::CallSite #define LLSmallVector llvm::SmallVector diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 8344e2b2..5233f428 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -51,7 +51,7 @@ void DtoDeleteMemory(LLValue* ptr) LLSmallVector arg; arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp")); // call - gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end()); + gIR->CreateCallOrInvoke(fn, arg); } void DtoDeleteClass(LLValue* inst) @@ -68,7 +68,7 @@ void DtoDeleteClass(LLValue* inst) #endif arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); // call - gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end()); + gIR->CreateCallOrInvoke(fn, arg); } void DtoDeleteInterface(LLValue* inst) @@ -79,7 +79,7 @@ void DtoDeleteInterface(LLValue* inst) LLSmallVector arg; arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); // call - gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end()); + gIR->CreateCallOrInvoke(fn, arg); } #if DMDV2 @@ -95,7 +95,7 @@ void DtoDeleteArray(DValue* arr) arg.push_back(DtoBitCast(DtoTypeInfoOf(arr->type->nextOf()), fn->getFunctionType()->getParamType(1))); // call - gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end()); + gIR->CreateCallOrInvoke(fn, arg); } #else @@ -111,7 +111,7 @@ void DtoDeleteArray(DValue* arr) arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp")); // call - gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end()); + gIR->CreateCallOrInvoke(fn, arg); } #endif @@ -124,7 +124,7 @@ void DtoDeleteArray(DValue* arr) llvm::AllocaInst* DtoAlloca(Type* type, const char* name) { - const llvm::Type* lltype = DtoType(type); + LLType* lltype = DtoType(type); llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint()); ai->setAlignment(type->alignsize()); return ai; @@ -132,14 +132,14 @@ llvm::AllocaInst* DtoAlloca(Type* type, const char* name) llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name) { - const llvm::Type* lltype = DtoType(type); + LLType* lltype = DtoType(type); llvm::AllocaInst* ai = new llvm::AllocaInst( lltype, DtoConstUint(arraysize), name, gIR->topallocapoint()); ai->setAlignment(type->alignsize()); return ai; } -llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const char* name) +llvm::AllocaInst* DtoRawAlloca(LLType* lltype, size_t alignment, const char* name) { llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint()); if (alignment) @@ -147,16 +147,16 @@ llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const return ai; } -LLValue* DtoGcMalloc(const llvm::Type* lltype, const char* name) +LLValue* DtoGcMalloc(LLType* lltype, const char* name) { - // get runtime function - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemory"); - // parameters - LLValue *size = DtoConstSize_t(getTypeAllocSize(lltype)); - // call runtime allocator - LLValue* mem = gIR->CreateCallOrInvoke(fn, size, name).getInstruction(); - // cast - return DtoBitCast(mem, getPtrToType(lltype), name); + // get runtime function + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemory"); + // parameters + LLValue *size = DtoConstSize_t(getTypeAllocSize(lltype)); + // call runtime allocator + LLValue* mem = gIR->CreateCallOrInvoke(fn, size, name).getInstruction(); + // cast + return DtoBitCast(mem, getPtrToType(lltype), name); } /****************************************************************************************/ @@ -197,7 +197,7 @@ void DtoAssert(Module* M, Loc loc, DValue* msg) args.push_back(c); // call - gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); + gIR->CreateCallOrInvoke(fn, args); #ifndef DISABLE_DEBUG_INFO // end debug info @@ -500,7 +500,7 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op) LLValue* r = rhs->getRVal(); if (Logger::enabled()) Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; - const LLType* lit = l->getType()->getContainedType(0); + LLType* lit = l->getType()->getContainedType(0); if (r->getType() != lit) { r = DtoCast(loc, rhs, lhs->getType())->getRVal(); if (Logger::enabled()) @@ -532,12 +532,12 @@ DValue* DtoNullValue(Type* type) { Type* basetype = type->toBasetype(); TY basety = basetype->ty; - const LLType* lltype = DtoType(basetype); + LLType* lltype = DtoType(basetype); // complex, needs to be first since complex are also floating if (basetype->iscomplex()) { - const LLType* basefp = DtoComplexBaseType(basetype); + LLType* basefp = DtoComplexBaseType(basetype); LLValue* res = DtoAggrPair(DtoType(type), LLConstant::getNullValue(basefp), LLConstant::getNullValue(basefp)); return new DImValue(type, res); } @@ -574,7 +574,7 @@ DValue* DtoNullValue(Type* type) DValue* DtoCastInt(Loc& loc, DValue* val, Type* _to) { - const LLType* tolltype = DtoType(_to); + LLType* tolltype = DtoType(_to); Type* to = _to->toBasetype(); Type* from = val->getType()->toBasetype(); @@ -635,7 +635,7 @@ DValue* DtoCastInt(Loc& loc, DValue* val, Type* _to) DValue* DtoCastPtr(Loc& loc, DValue* val, Type* to) { - const LLType* tolltype = DtoType(to); + LLType* tolltype = DtoType(to); Type* totype = to->toBasetype(); Type* fromtype = val->getType()->toBasetype(); @@ -670,7 +670,7 @@ DValue* DtoCastFloat(Loc& loc, DValue* val, Type* to) if (val->getType() == to) return val; - const LLType* tolltype = DtoType(to); + LLType* tolltype = DtoType(to); Type* totype = to->toBasetype(); Type* fromtype = val->getType()->toBasetype(); @@ -913,8 +913,9 @@ void DtoConstInitGlobal(VarDeclaration* vd) IrGlobal* glob = vd->ir.irGlobal; llvm::GlobalVariable* gvar = llvm::cast(glob->value); - // refine the global's opaque type to the type of the initializer - llvm::cast(glob->type.get())->refineAbstractTypeTo(initVal->getType()); + //if (LLStructType *st = isaStruct(glob->type)) { + // st->setBody(initVal); + //} assert(!glob->constInit); glob->constInit = initVal; @@ -1050,7 +1051,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration) } #endif - const LLType* lltype = DtoType(vd->type); + LLType* lltype = DtoType(vd->type); llvm::Value* allocainst; if(gTargetData->getTypeSizeInBits(lltype) == 0) @@ -1254,6 +1255,60 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr) // INITIALIZER HELPERS ////////////////////////////////////////////////////////////////////////////////////////*/ +LLType* DtoConstInitializerType(Type* type, Initializer* init) +{ + if (type->ty == Ttypedef) { + TypeTypedef *td = (TypeTypedef*)type; + if (td->sym->init) + return DtoConstInitializerType(td->sym->basetype, td->sym->init); + } + + type = type->toBasetype(); + if (type->ty == Tsarray) + { + if (!init) + { + TypeSArray *tsa = (TypeSArray*)type; + LLType *llnext = DtoConstInitializerType(type->nextOf(), init); + return LLArrayType::get(llnext, tsa->dim->toUInteger()); + } + else if (ArrayInitializer* ai = init->isArrayInitializer()) + { + return DtoConstArrayInitializerType(ai); + } + } + else if (type->ty == Tstruct) + { + if (!init) + { + LdefaultInit: + TypeStruct *ts = (TypeStruct*)type; + DtoResolveStruct(ts->sym); + return ts->sym->ir.irStruct->getDefaultInit()->getType(); + } + else if (ExpInitializer* ex = init->isExpInitializer()) + { + if (ex->exp->op == TOKstructliteral) { + StructLiteralExp* le = (StructLiteralExp*)ex->exp; + if (!le->constType) + le->constType = LLStructType::create(gIR->context(), std::string(type->toChars()) + "_init"); + return le->constType; + } else if (ex->exp->op == TOKvar) { + if (((VarExp*)ex->exp)->var->isStaticStructInitDeclaration()) + goto LdefaultInit; + } + } + else if (StructInitializer* si = init->isStructInitializer()) + { + if (!si->ltype) + si->ltype = LLStructType::create(gIR->context(), std::string(type->toChars()) + "_init"); + return si->ltype; + } + } + + return DtoTypeNotVoid(type); +} + LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init) { LLConstant* _init = 0; // may return zero @@ -1265,7 +1320,7 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init) else if (ExpInitializer* ex = init->isExpInitializer()) { Logger::println("const expression initializer"); - _init = DtoConstExpInit(loc, type, ex->exp);; + _init = DtoConstExpInit(loc, type, ex->exp); } else if (StructInitializer* si = init->isStructInitializer()) { @@ -1281,7 +1336,7 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init) else if (init->isVoidInitializer()) { Logger::println("const void initializer"); - const LLType* ty = DtoType(type); + LLType* ty = DtoTypeNotVoid(type); _init = LLConstant::getNullValue(ty); } else { @@ -1325,7 +1380,7 @@ DValue* DtoInitializer(LLValue* target, Initializer* init) static LLConstant* expand_to_sarray(Type *base, Expression* exp) { Logger::println("building type %s from expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars()); - const LLType* dstTy = DtoType(base); + LLType* dstTy = DtoType(base); if (Logger::enabled()) Logger::cout() << "final llvm type requested: " << *dstTy << '\n'; @@ -1355,7 +1410,7 @@ static LLConstant* expand_to_sarray(Type *base, Expression* exp) std::vector inits; while (i--) { - const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]); + LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]); inits.clear(); inits.insert(inits.end(), dims[i], val); val = LLConstantArray::get(arrty, inits); @@ -1623,7 +1678,7 @@ size_t realignOffset(size_t offset, Type* type) // we cannot get the llvm alignment if the type is still opaque, this can happen in some // forward reference situations, so when this happens we fall back to manual padding. // also handle arbitrary "by-value" opaques nested inside aggregates. - const llvm::Type* T = DtoType(type); + LLType* T = DtoType(type); if (!T->isSized()) { return offset; @@ -1652,89 +1707,89 @@ size_t realignOffset(size_t offset, Type* type) Type * stripModifiers( Type * type ) { #if DMDV2 - if (type->ty == Tfunction) - return type; - Type *t = type; - while (t->mod) - { - switch (t->mod) - { - case MODconst: - t = type->cto; - break; - case MODshared: - t = type->sto; - break; - case MODimmutable: - t = type->ito; - break; - case MODshared | MODconst: - t = type->scto; - break; - case MODwild: - t = type->wto; - break; - case MODshared | MODwild: - t = type->swto; - break; - default: - assert(0 && "Unhandled type modifier"); - } + if (type->ty == Tfunction) + return type; + Type *t = type; + while (t->mod) + { + switch (t->mod) + { + case MODconst: + t = type->cto; + break; + case MODshared: + t = type->sto; + break; + case MODimmutable: + t = type->ito; + break; + case MODshared | MODconst: + t = type->scto; + break; + case MODwild: + t = type->wto; + break; + case MODshared | MODwild: + t = type->swto; + break; + default: + assert(0 && "Unhandled type modifier"); + } - if (!t) - { - unsigned sz = type->sizeTy[type->ty]; - t = (Type *)malloc(sz); - memcpy(t, type, sz); - t->mod = 0; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - t = t->merge(); + if (!t) + { + unsigned sz = type->sizeTy[type->ty]; + t = (Type *)malloc(sz); + memcpy(t, type, sz); + t->mod = 0; + t->deco = NULL; + t->arrayof = NULL; + t->pto = NULL; + t->rto = NULL; + t->cto = NULL; + t->ito = NULL; + t->sto = NULL; + t->scto = NULL; + t->wto = NULL; + t->swto = NULL; + t->vtinfo = NULL; + t = t->merge(); - t->fixTo(type); - switch (type->mod) - { - case MODconst: - t->cto = type; - break; + t->fixTo(type); + switch (type->mod) + { + case MODconst: + t->cto = type; + break; - case MODimmutable: - t->ito = type; - break; + case MODimmutable: + t->ito = type; + break; - case MODshared: - t->sto = type; - break; + case MODshared: + t->sto = type; + break; - case MODshared | MODconst: - t->scto = type; - break; + case MODshared | MODconst: + t->scto = type; + break; - case MODwild: - t->wto = type; - break; + case MODwild: + t->wto = type; + break; - case MODshared | MODwild: - t->swto = type; - break; + case MODshared | MODwild: + t->swto = type; + break; - default: - assert(0); - } - } - } - return t; + default: + assert(0); + } + } + } + return t; #else - return type; + return type; #endif } @@ -1796,4 +1851,3 @@ void callPostblit(Loc &loc, Expression *exp, LLValue *val) } } #endif - diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 7d081683..9ca73ce3 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -44,8 +44,8 @@ void DtoDeleteArray(DValue* arr); // emit an alloca llvm::AllocaInst* DtoAlloca(Type* type, const char* name = ""); llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name = ""); -llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const char* name = ""); -LLValue* DtoGcMalloc(const llvm::Type* lltype, const char* name = ""); +llvm::AllocaInst* DtoRawAlloca(LLType* lltype, size_t alignment, const char* name = ""); +LLValue* DtoGcMalloc(LLType* lltype, const char* name = ""); // assertion generator void DtoAssert(Module* M, Loc loc, DValue* msg); @@ -102,6 +102,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration); LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr = 0); // initializer helpers +LLType* DtoConstInitializerType(Type* type, Initializer* init); LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init); LLConstant* DtoConstExpInit(Loc loc, Type* t, Expression* exp); DValue* DtoInitializer(LLValue* target, Initializer* init); @@ -174,7 +175,7 @@ DValue* DtoVaArg(Loc& loc, Type* type, Expression* valistArg); LLValue* DtoCallableValue(DValue* fn); /// -const LLFunctionType* DtoExtractFunctionType(const LLType* type); +LLFunctionType* DtoExtractFunctionType(LLType* type); /// void DtoBuildDVarArgList(std::vector& args, llvm::AttrListPtr& palist, TypeFunction* tf, Expressions* arguments, size_t argidx); diff --git a/gen/logger.cpp b/gen/logger.cpp index 0c10717e..f41fc61f 100644 --- a/gen/logger.cpp +++ b/gen/logger.cpp @@ -20,7 +20,7 @@ void Stream::writeType(std::ostream& OS, const llvm::Type& Ty) { llvm::raw_os_ostream raw(OS); - llvm::WriteTypeSymbolic(raw, &Ty, gIR->module); + Ty.print(raw); } void Stream::writeValue(std::ostream& OS, const llvm::Value& V) { diff --git a/gen/main.cpp b/gen/main.cpp index 500952f8..289f167c 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -7,11 +7,11 @@ #include "llvm/LinkAllVMCore.h" #include "llvm/Linker.h" #include "llvm/LLVMContext.h" -#include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/SubtargetFeature.h" #include #include @@ -448,13 +448,12 @@ int main(int argc, char** argv) // Allocate target machine. - // First initialize the native target and any additionally specified ones. - llvm::InitializeNativeTarget(); - llvm::InitializeNativeTargetAsmPrinter(); -#define LLVM_TARGET(A) LLVMInitialize##A##TargetInfo(); LLVMInitialize##A##Target(); LLVMInitialize##A##AsmPrinter(); -// this is defined to be LLVM_TARGET(target name 1) LLVM_TARGET(target name 2) ... -LDC_TARGETS -#undef LLVM_TARGET + // first initialize llvm + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargets(); + llvm::InitializeAllAsmPrinters(); + llvm::InitializeAllAsmParsers(); + llvm::InitializeAllTargetMCs(); const llvm::Target *theTarget = NULL; // Check whether the user has explicitly specified an architecture to compile for. @@ -492,9 +491,8 @@ LDC_TARGETS if (mCPU.size() || mAttrs.size()) { llvm::SubtargetFeatures Features; - Features.setCPU(mCPU); for (unsigned i = 0; i != mAttrs.size(); ++i) - Features.AddFeature(mAttrs[i]); + Features.AddFeature(mAttrs[i]); FeaturesStr = Features.getString(); } @@ -503,7 +501,8 @@ LDC_TARGETS //assert(target.get() && "Could not allocate target machine!"); //gTargetMachine = target.get(); - llvm::TargetMachine* target = theTarget->createTargetMachine(triple, FeaturesStr); + llvm::TargetMachine* target = theTarget->createTargetMachine(triple, mCPU, FeaturesStr, + mRelocModel, mCodeModel); gTargetMachine = target; gTargetData = target->getTargetData(); diff --git a/gen/naked.cpp b/gen/naked.cpp index 9a3beea2..90213264 100644 --- a/gen/naked.cpp +++ b/gen/naked.cpp @@ -201,7 +201,7 @@ void emitABIReturnAsmStmt(IRAsmBlock* asmblock, Loc loc, FuncDeclaration* fdecl) IRAsmStmt* as = new IRAsmStmt; - const LLType* llretTy = DtoType(fdecl->type->nextOf()); + LLType* llretTy = DtoType(fdecl->type->nextOf()); asmblock->retty = llretTy; asmblock->retn = 1; @@ -388,7 +388,7 @@ DValue * DtoInlineAsmExpr(Loc loc, FuncDeclaration * fd, Expressions * arguments LLSmallVector args; args.reserve(n-2); - std::vector argtypes; + std::vector argtypes; argtypes.reserve(n-2); for (size_t i = 2; i < n; i++) @@ -400,14 +400,14 @@ DValue * DtoInlineAsmExpr(Loc loc, FuncDeclaration * fd, Expressions * arguments // build asm function type Type* type = fd->type->nextOf()->toBasetype(); - const llvm::Type* ret_type = DtoType(type); + LLType* ret_type = DtoType(type); llvm::FunctionType* FT = llvm::FunctionType::get(ret_type, argtypes, false); // build asm call bool sideeffect = true; llvm::InlineAsm* ia = llvm::InlineAsm::get(FT, code, constraints, sideeffect); - llvm::Value* rv = gIR->ir->CreateCall(ia, args.begin(), args.end(), ""); + llvm::Value* rv = gIR->ir->CreateCall(ia, args, ""); // work around missing tuple support for users of the return value if (type->ty == Tstruct) diff --git a/gen/nested.cpp b/gen/nested.cpp index fe11c8da..cdac766e 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -392,7 +392,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { Logger::println("has nested frame"); // start with adding all enclosing parent frames until a static parent is reached - const LLStructType* innerFrameType = NULL; + LLStructType* innerFrameType = NULL; unsigned depth = -1; if (!fd->isStatic()) { if (FuncDeclaration* parfd = getParentFunc(fd, true)) { @@ -408,7 +408,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n'; - typedef std::vector TypeVec; + typedef std::vector TypeVec; TypeVec types; if (depth != 0) { assert(innerFrameType); @@ -444,7 +444,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { // so handle those cases specially by storing a pointer instead of a value. assert(vd->ir.irLocal->value); LLValue* value = vd->ir.irLocal->value; - const LLType* type = value->getType(); + LLType* type = value->getType(); if (llvm::isa(llvm::GetUnderlyingObject(value))) // This will be copied to the nesting frame. type = type->getContainedType(0); @@ -461,8 +461,8 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { } } - const LLStructType* frameType = LLStructType::get(gIR->context(), types); - gIR->module->addTypeName(std::string("nest.") + fd->toChars(), frameType); + LLStructType* frameType = LLStructType::create(gIR->context(), types, + std::string("nest.") + fd->toChars()); Logger::cout() << "frameType = " << *frameType << '\n'; @@ -521,7 +521,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) { int nelems = fd->nestedVars.size() + nparelems; // make array type for nested vars - const LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems); + LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems); // alloca it // FIXME align ? @@ -580,7 +580,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) { { IrFunction* irfunction = fd->ir.irFunc; unsigned depth = irfunction->depth; - const llvm::StructType *frameType = irfunction->frameType; + LLStructType *frameType = irfunction->frameType; // Create frame for current function and append to frames list // FIXME: alignment ? LLValue* frame = 0; diff --git a/gen/optimizer.cpp b/gen/optimizer.cpp index 2c4fd738..d3773978 100644 --- a/gen/optimizer.cpp +++ b/gen/optimizer.cpp @@ -10,6 +10,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/PassNameParser.h" +#include "llvm/Transforms/IPO.h" #include "root.h" // error() #include // strcmp(); @@ -174,7 +175,6 @@ static void addPassesForOptLevel(PassManager& pm) { if (optimizeLevel >= 3) { addPass(pm, createArgumentPromotionPass()); - addPass(pm, createTailDuplicationPass()); addPass(pm, createSimplifyLibCallsPass()); addPass(pm, createInstructionCombiningPass()); addPass(pm, createJumpThreadingPass()); @@ -202,7 +202,6 @@ static void addPassesForOptLevel(PassManager& pm) { addPass(pm, createDeadStoreEliminationPass()); addPass(pm, createAggressiveDCEPass()); addPass(pm, createCFGSimplificationPass()); - addPass(pm, createDeadTypeEliminationPass()); addPass(pm, createConstantMergePass()); } diff --git a/gen/passes/SimplifyDRuntimeCalls.cpp b/gen/passes/SimplifyDRuntimeCalls.cpp index 8e914616..9f4d996e 100644 --- a/gen/passes/SimplifyDRuntimeCalls.cpp +++ b/gen/passes/SimplifyDRuntimeCalls.cpp @@ -93,10 +93,10 @@ Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) { Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len, unsigned Align, IRBuilder<> &B) { Module *M = Caller->getParent(); - const Type* intTy = Len->getType(); - const Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty()); - const Type *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy}; - Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys, 3); + Type* intTy = Len->getType(); + Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty()); + Type *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy}; + Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, llvm::makeArrayRef(Tys, 3)); return B.CreateCall5(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len, ConstantInt::get(B.getInt32Ty(), Align), B.getFalse()); diff --git a/gen/rttibuilder.cpp b/gen/rttibuilder.cpp index c1c961d1..33fc9721 100644 --- a/gen/rttibuilder.cpp +++ b/gen/rttibuilder.cpp @@ -63,7 +63,7 @@ void RTTIBuilder::push_string(const char* str) void RTTIBuilder::push_null_void_array() { - const llvm::Type* T = DtoType(Type::tvoid->arrayOf()); + LLType* T = DtoType(Type::tvoid->arrayOf()); inits.push_back(getNullValue(T)); } @@ -143,18 +143,30 @@ void RTTIBuilder::push_funcptr(FuncDeclaration* fd, Type* castto) void RTTIBuilder::finalize(IrGlobal* tid) { - // create the inititalizer - LLConstant* tiInit = LLConstantStruct::get(gIR->context(), &inits[0], inits.size(), false); + finalize(tid->type, tid->value); +} - // refine global type - llvm::cast(tid->type.get())->refineAbstractTypeTo(tiInit->getType()); +void RTTIBuilder::finalize(LLType* type, LLValue* value) +{ + llvm::ArrayRef inits = llvm::makeArrayRef(this->inits); + LLStructType *st = isaStruct(type); + assert(st); + + // set struct body + std::vector types; + for (int i = 0, n = inits.size(); i < n; ++i) + types.push_back(inits[i]->getType()); + st->setBody(types); + + // create the inititalizer + LLConstant* tiInit = LLConstantStruct::get(st, inits); // set the initializer - isaGlobalVar(tid->value)->setInitializer(tiInit); + isaGlobalVar(value)->setInitializer(tiInit); } -LLConstant* RTTIBuilder::get_constant() +LLConstant* RTTIBuilder::get_constant(LLStructType *initType) { // just return the inititalizer - return LLConstantStruct::get(gIR->context(), &inits[0], inits.size(), false); + return LLConstantStruct::get(initType, inits); } diff --git a/gen/rttibuilder.h b/gen/rttibuilder.h index ef1d8c6d..d7f54540 100644 --- a/gen/rttibuilder.h +++ b/gen/rttibuilder.h @@ -56,9 +56,10 @@ struct RTTIBuilder /// Creates the initializer constant and assigns it to the global. void finalize(IrGlobal* tid); + void finalize(LLType* type, LLValue* value); /// Creates the initializer constant and assigns it to the global. - llvm::Constant* get_constant(); + llvm::Constant* get_constant(LLStructType *initType); }; #endif diff --git a/gen/runtime.cpp b/gen/runtime.cpp index 7c3ff780..87c7a06a 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -70,7 +70,7 @@ llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name LLVM_D_InitRuntime(); } - llvm::Function* fn = target->getFunction(name); + LLFunction* fn = target->getFunction(name); if (fn) return fn; @@ -81,8 +81,8 @@ llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name //return NULL; } - const llvm::FunctionType* fnty = fn->getFunctionType(); - llvm::Function* resfn = llvm::cast(target->getOrInsertFunction(name, fnty)); + LLFunctionType* fnty = fn->getFunctionType(); + LLFunction* resfn = llvm::cast(target->getOrInsertFunction(name, fnty)); resfn->setAttributes(fn->getAttributes()); return resfn; } @@ -91,7 +91,7 @@ llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name) { - llvm::GlobalVariable* gv = target->getNamedGlobal(name); + LLGlobalVariable* gv = target->getNamedGlobal(name); if (gv) { return gv; } @@ -106,46 +106,65 @@ llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* LLVM_D_InitRuntime(); } - llvm::GlobalVariable* g = M->getNamedGlobal(name); + LLGlobalVariable* g = M->getNamedGlobal(name); if (!g) { error("Runtime global '%s' was not found", name); fatal(); //return NULL; } - const llvm::PointerType* t = g->getType(); - return new llvm::GlobalVariable(*target, t->getElementType(),g->isConstant(),g->getLinkage(),NULL,g->getName()); + LLPointerType* t = g->getType(); + return new LLGlobalVariable(*target, t->getElementType(),g->isConstant(),g->getLinkage(),NULL,g->getName()); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static const LLType* rt_ptr(const LLType* t) +static LLType* rt_ptr(LLType* t) { return getPtrToType(t); } -static const LLType* rt_array(const LLType* elemty) +static LLType* rt_array(LLType* elemty) { - return llvm::StructType::get(gIR->context(), DtoSize_t(), rt_ptr(elemty), NULL); + llvm::SmallVector types; + types.push_back(DtoSize_t()); + types.push_back(rt_ptr(elemty)); + return LLStructType::get(gIR->context(), llvm::makeArrayRef(types)); } -static const LLType* rt_dg1() +static LLType* rt_dg1() { - std::vector types; + llvm::SmallVector types; types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context()))); types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context()))); - const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::getInt32Ty(gIR->context()), types, false); - return llvm::StructType::get(gIR->context(), rt_ptr(LLType::getInt8Ty(gIR->context())), rt_ptr(fty), NULL); + LLFunctionType* fty = LLFunctionType::get(LLType::getInt32Ty(gIR->context()), types, false); + + types.clear(); + types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context()))); + types.push_back(rt_ptr(fty)); + return LLStructType::get(gIR->context(), types); } -static const LLType* rt_dg2() +static LLType* rt_dg2() { - std::vector types; + llvm::SmallVector types; types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context()))); types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context()))); types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context()))); - const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::getInt32Ty(gIR->context()), types, false); - return llvm::StructType::get(gIR->context(), rt_ptr(LLType::getInt8Ty(gIR->context())), rt_ptr(fty), NULL); + LLFunctionType* fty = LLFunctionType::get(LLType::getInt32Ty(gIR->context()), types, false); + + types.clear(); + types.push_back(rt_ptr(LLType::getInt8Ty(gIR->context()))); + types.push_back(rt_ptr(fty)); + return LLStructType::get(gIR->context(), types); +} + +static LLType* rt_complex(LLType* type) +{ + llvm::SmallVector types; + types.push_back(type); + types.push_back(type); + return llvm::StructType::get(gIR->context(), types); } static void LLVM_D_BuildRuntimeModule() @@ -154,42 +173,42 @@ static void LLVM_D_BuildRuntimeModule() M = new llvm::Module("ldc internal runtime", gIR->context()); Logger::println("building basic types"); - const LLType* voidTy = LLType::getVoidTy(gIR->context()); - const LLType* boolTy = LLType::getInt1Ty(gIR->context()); - const LLType* byteTy = LLType::getInt8Ty(gIR->context()); - const LLType* shortTy = LLType::getInt16Ty(gIR->context()); - const LLType* intTy = LLType::getInt32Ty(gIR->context()); - const LLType* longTy = LLType::getInt64Ty(gIR->context()); - const LLType* sizeTy = DtoSize_t(); + LLType* voidTy = LLType::getVoidTy(gIR->context()); + LLType* boolTy = LLType::getInt1Ty(gIR->context()); + LLType* byteTy = LLType::getInt8Ty(gIR->context()); + LLType* shortTy = LLType::getInt16Ty(gIR->context()); + LLType* intTy = LLType::getInt32Ty(gIR->context()); + LLType* longTy = LLType::getInt64Ty(gIR->context()); + LLType* sizeTy = DtoSize_t(); Logger::println("building float types"); - const LLType* floatTy = LLType::getFloatTy(gIR->context()); - const LLType* doubleTy = LLType::getDoubleTy(gIR->context()); - const LLType* realTy; + LLType* floatTy = LLType::getFloatTy(gIR->context()); + LLType* doubleTy = LLType::getDoubleTy(gIR->context()); + LLType* realTy; if ((global.params.cpu == ARCHx86) || (global.params.cpu == ARCHx86_64)) realTy = LLType::getX86_FP80Ty(gIR->context()); else realTy = LLType::getDoubleTy(gIR->context()); - const LLType* cfloatTy = llvm::StructType::get(gIR->context(), floatTy, floatTy, NULL); - const LLType* cdoubleTy = llvm::StructType::get(gIR->context(), doubleTy, doubleTy, NULL); - const LLType* crealTy = llvm::StructType::get(gIR->context(), realTy, realTy, NULL); + LLType* cfloatTy = rt_complex(floatTy); + LLType* cdoubleTy = rt_complex(doubleTy); + LLType* crealTy = rt_complex(realTy); Logger::println("building aggr types"); - const LLType* voidPtrTy = rt_ptr(byteTy); - const LLType* voidArrayTy = rt_array(byteTy); - const LLType* voidArrayPtrTy = getPtrToType(voidArrayTy); - const LLType* stringTy = voidArrayTy; - const LLType* wstringTy = rt_array(shortTy); - const LLType* dstringTy = rt_array(intTy); + LLType* voidPtrTy = rt_ptr(byteTy); + LLType* voidArrayTy = rt_array(byteTy); + LLType* voidArrayPtrTy = getPtrToType(voidArrayTy); + LLType* stringTy = DtoType(Type::tchar->arrayOf()); + LLType* wstringTy = DtoType(Type::twchar->arrayOf()); + LLType* dstringTy = DtoType(Type::tdchar->arrayOf()); Logger::println("building class types"); - const LLType* objectTy = DtoType(ClassDeclaration::object->type); - const LLType* classInfoTy = DtoType(ClassDeclaration::classinfo->type); - const LLType* typeInfoTy = DtoType(Type::typeinfo->type); + LLType* objectTy = DtoType(ClassDeclaration::object->type); + LLType* classInfoTy = DtoType(ClassDeclaration::classinfo->type); + LLType* typeInfoTy = DtoType(Type::typeinfo->type); Logger::println("building aa type"); - const LLType* aaTy = rt_ptr(llvm::OpaqueType::get(gIR->context())); + LLType* aaTy = rt_ptr(LLStructType::get(gIR->context())); Logger::println("building functions"); @@ -238,10 +257,10 @@ static void LLVM_D_BuildRuntimeModule() // void _d_assert( char[] file, uint line ) { llvm::StringRef fname("_d_assert"); - std::vector types; + std::vector types; types.push_back(stringTy); types.push_back(intTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -254,14 +273,14 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_d_array_bounds"); llvm::StringRef fname2("_d_switch_error"); - std::vector types; + std::vector types; #if DMDV2 types.push_back(getPtrToType(DtoType(Module::moduleinfo->type))); #else types.push_back(stringTy); #endif types.push_back(intTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + 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); } @@ -269,11 +288,11 @@ static void LLVM_D_BuildRuntimeModule() // void _d_assert_msg( char[] msg, char[] file, uint line ) { llvm::StringRef fname("_d_assert_msg"); - std::vector types; + std::vector types; types.push_back(stringTy); types.push_back(stringTy); types.push_back(intTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -285,9 +304,9 @@ static void LLVM_D_BuildRuntimeModule() // void* _d_allocmemory(size_t sz) { llvm::StringRef fname("_d_allocmemory"); - std::vector types; + std::vector types; types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_NoAlias); } @@ -295,9 +314,9 @@ static void LLVM_D_BuildRuntimeModule() // void* _d_allocmemoryT(TypeInfo ti) { llvm::StringRef fname("_d_allocmemoryT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_NoAlias); } @@ -309,10 +328,10 @@ static void LLVM_D_BuildRuntimeModule() llvm::StringRef fname("_d_newarrayT"); llvm::StringRef fname2("_d_newarrayiT"); llvm::StringRef fname3("_d_newarrayvT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + 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) @@ -327,11 +346,11 @@ static void LLVM_D_BuildRuntimeModule() llvm::StringRef fname("_d_newarraymT"); llvm::StringRef fname2("_d_newarraymiT"); llvm::StringRef fname3("_d_newarraymvT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(sizeTy); types.push_back(rt_ptr(sizeTy)); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_NoAlias_3_NoCapture); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M) @@ -345,10 +364,10 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_d_newarrayT"); llvm::StringRef fname2("_d_newarrayiT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + 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); } @@ -357,10 +376,10 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_d_newarraymT"); llvm::StringRef fname2("_d_newarraymiT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true); + 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); } @@ -375,16 +394,16 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_d_arraysetlengthT"); llvm::StringRef fname2("_d_arraysetlengthiT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(sizeTy); #if DMDV2 types.push_back(voidArrayPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); #else types.push_back(sizeTy); types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); #endif llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); @@ -394,68 +413,68 @@ static void LLVM_D_BuildRuntimeModule() // byte[] _d_arrayappendcTX(TypeInfo ti, ref byte[] px, size_t n) { llvm::StringRef fname("_d_arrayappendcTX"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(voidArrayPtrTy); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } // void[] _d_arrayappendT(TypeInfo ti, byte[]* px, byte[] y) { llvm::StringRef fname("_d_arrayappendT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(voidArrayPtrTy); types.push_back(voidArrayTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } // void[] _d_arrayappendcd(ref char[] x, dchar c) { llvm::StringRef fname("_d_arrayappendcd"); - std::vector types; + std::vector types; types.push_back(getPtrToType(stringTy)); types.push_back(intTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + 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"); - std::vector types; + std::vector types; types.push_back(getPtrToType(wstringTy)); types.push_back(intTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } // byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y) { llvm::StringRef fname("_d_arraycatT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(voidArrayTy); types.push_back(voidArrayTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } // byte[] _d_arraycatnT(TypeInfo ti, uint n, ...) { llvm::StringRef fname("_d_arraycatnT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true); + LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, true); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } #else // DMDV1 // byte[] _d_arrayappendcT(TypeInfo ti, void* array, void* element) { llvm::StringRef fname("_d_arrayappendcT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(voidPtrTy); types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } #endif @@ -463,9 +482,9 @@ static void LLVM_D_BuildRuntimeModule() // Object _d_allocclass(ClassInfo ci) { llvm::StringRef fname(_d_allocclass); - std::vector types; + std::vector types; types.push_back(classInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_NoAlias); } @@ -475,10 +494,10 @@ static void LLVM_D_BuildRuntimeModule() // void _d_delarray_t(Array *p, TypeInfo ti) { llvm::StringRef fname("_d_delarray_t"); - std::vector types; + std::vector types; types.push_back(voidArrayPtrTy); types.push_back(typeInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -487,10 +506,10 @@ static void LLVM_D_BuildRuntimeModule() // void _d_delarray(size_t plength, void* pdata) { llvm::StringRef fname("_d_delarray"); - std::vector types; + std::vector types; types.push_back(sizeTy); types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -508,9 +527,9 @@ static void LLVM_D_BuildRuntimeModule() llvm::StringRef fname("_d_delmemory"); llvm::StringRef fname2("_d_delinterface"); llvm::StringRef fname3("_d_callfinalizer"); - std::vector types; + std::vector types; types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + 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); @@ -520,13 +539,13 @@ static void LLVM_D_BuildRuntimeModule() // D2: void _d_delclass(Object* p) { llvm::StringRef fname("_d_delclass"); - std::vector types; + std::vector types; #if DMDV2 types.push_back(rt_ptr(objectTy)); #else types.push_back(objectTy); #endif - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -543,7 +562,7 @@ static void LLVM_D_BuildRuntimeModule() types.push_back(sizeTy); types.push_back(voidPtrTy); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_1_3_NoCapture); } @@ -557,10 +576,10 @@ static void LLVM_D_BuildRuntimeModule() { \ llvm::StringRef fname(a); \ llvm::StringRef fname2(b); \ - std::vector types; \ + std::vector types; \ types.push_back(TY); \ types.push_back(rt_dg1()); \ - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ + 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); \ } @@ -574,10 +593,10 @@ static void LLVM_D_BuildRuntimeModule() { \ llvm::StringRef fname(a); \ llvm::StringRef fname2(b); \ - std::vector types; \ + std::vector types; \ types.push_back(TY); \ types.push_back(rt_dg2()); \ - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ + 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); \ } @@ -590,10 +609,10 @@ static void LLVM_D_BuildRuntimeModule() { \ llvm::StringRef fname(a); \ llvm::StringRef fname2(b); \ - std::vector types; \ + std::vector types; \ types.push_back(TY); \ types.push_back(rt_dg1()); \ - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ + 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); \ } @@ -606,10 +625,10 @@ static void LLVM_D_BuildRuntimeModule() { \ llvm::StringRef fname(a); \ llvm::StringRef fname2(b); \ - std::vector types; \ + std::vector types; \ types.push_back(TY); \ types.push_back(rt_dg2()); \ - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ + 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); \ } @@ -626,11 +645,11 @@ static void LLVM_D_BuildRuntimeModule() // size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz) { llvm::StringRef fname("_d_array_cast_len"); - std::vector types; + std::vector types; types.push_back(sizeTy); types.push_back(sizeTy); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(sizeTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadNone); } @@ -646,11 +665,11 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_d_arrayassign"); llvm::StringRef fname2("_d_arrayctor"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(voidArrayTy); types.push_back(voidArrayTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + 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); } @@ -660,12 +679,12 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_d_arraysetassign"); llvm::StringRef fname2("_d_arraysetctor"); - std::vector types; + std::vector types; types.push_back(voidPtrTy); types.push_back(voidPtrTy); types.push_back(sizeTy); types.push_back(typeInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + 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) @@ -682,9 +701,9 @@ static void LLVM_D_BuildRuntimeModule() // Object _d_toObject(void* p) { llvm::StringRef fname("_d_toObject"); - std::vector types; + std::vector types; types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly_NoUnwind); } @@ -693,10 +712,10 @@ static void LLVM_D_BuildRuntimeModule() // Object _d_interface_cast(void* p, ClassInfo c) { llvm::StringRef fname("_d_interface_cast"); - std::vector types; + std::vector types; types.push_back(voidPtrTy); types.push_back(classInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly_NoUnwind); } @@ -705,10 +724,10 @@ static void LLVM_D_BuildRuntimeModule() // Object _d_dynamic_cast(Object o, ClassInfo c) { llvm::StringRef fname("_d_dynamic_cast"); - std::vector types; + std::vector types; types.push_back(objectTy); types.push_back(classInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(objectTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly_NoUnwind); } @@ -722,9 +741,9 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_adReverseChar"); llvm::StringRef fname2("_adSortChar"); - std::vector types; + std::vector types; types.push_back(stringTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(stringTy, types, false); + 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); } @@ -734,9 +753,9 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_adReverseWchar"); llvm::StringRef fname2("_adSortWchar"); - std::vector types; + std::vector types; types.push_back(wstringTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(wstringTy, types, false); + 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); } @@ -744,10 +763,10 @@ static void LLVM_D_BuildRuntimeModule() // void[] _adReverse(void[] a, size_t szelem) { llvm::StringRef fname("_adReverse"); - std::vector types; + std::vector types; types.push_back(rt_array(byteTy)); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); + LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_NoUnwind); } @@ -755,10 +774,10 @@ static void LLVM_D_BuildRuntimeModule() // void[] _adDupT(TypeInfo ti, void[] a) { llvm::StringRef fname("_adDupT"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(rt_array(byteTy)); - const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); + LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -767,11 +786,11 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname(_adEq); llvm::StringRef fname2(_adCmp); - std::vector types; + std::vector types; types.push_back(rt_array(byteTy)); types.push_back(rt_array(byteTy)); types.push_back(typeInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + 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) @@ -781,10 +800,10 @@ static void LLVM_D_BuildRuntimeModule() // int _adCmpChar(void[] a1, void[] a2) { llvm::StringRef fname("_adCmpChar"); - std::vector types; + std::vector types; types.push_back(rt_array(byteTy)); types.push_back(rt_array(byteTy)); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly_NoUnwind); } @@ -792,10 +811,10 @@ static void LLVM_D_BuildRuntimeModule() // void[] _adSort(void[] a, TypeInfo ti) { llvm::StringRef fname("_adSort"); - std::vector types; + std::vector types; types.push_back(rt_array(byteTy)); types.push_back(typeInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); + LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -806,9 +825,9 @@ static void LLVM_D_BuildRuntimeModule() // size_t _aaLen(AA aa) { llvm::StringRef fname("_aaLen"); - std::vector types; + std::vector types; types.push_back(aaTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(sizeTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly_NoUnwind_1_NoCapture); } @@ -823,12 +842,12 @@ static void LLVM_D_BuildRuntimeModule() #else llvm::StringRef fname("_aaGet"); #endif - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(typeInfoTy); types.push_back(sizeTy); types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_1_4_NoCapture); } @@ -843,11 +862,11 @@ static void LLVM_D_BuildRuntimeModule() #else llvm::StringRef fname("_aaIn"); #endif - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(typeInfoTy); types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly_1_3_NoCapture); } @@ -862,11 +881,11 @@ static void LLVM_D_BuildRuntimeModule() #else llvm::StringRef fname("_aaDel"); #endif - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(typeInfoTy); types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_1_3_NoCapture); } @@ -874,11 +893,11 @@ static void LLVM_D_BuildRuntimeModule() // void[] _aaValues(AA aa, size_t keysize, size_t valuesize) { llvm::StringRef fname("_aaValues"); - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(sizeTy); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); + LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_NoAlias_1_NoCapture); } @@ -886,20 +905,20 @@ static void LLVM_D_BuildRuntimeModule() // void* _aaRehash(AA* paa, TypeInfo keyti) { llvm::StringRef fname("_aaRehash"); - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(typeInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } // void[] _aaKeys(AA aa, size_t keysize) { llvm::StringRef fname("_aaKeys"); - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(sizeTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); + LLFunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_NoAlias_1_NoCapture); } @@ -907,11 +926,11 @@ static void LLVM_D_BuildRuntimeModule() // int _aaApply(AA aa, size_t keysize, dg_t dg) { llvm::StringRef fname("_aaApply"); - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(sizeTy); types.push_back(rt_dg1()); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_1_NoCapture); } @@ -919,11 +938,11 @@ static void LLVM_D_BuildRuntimeModule() // int _aaApply2(AA aa, size_t keysize, dg2_t dg) { llvm::StringRef fname("_aaApply2"); - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(sizeTy); types.push_back(rt_dg2()); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_1_NoCapture); } @@ -932,33 +951,33 @@ static void LLVM_D_BuildRuntimeModule() // int _aaEqual(TypeInfo_AssociativeArray ti, AA e1, AA e2) { llvm::StringRef fname("_aaEqual"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(aaTy); types.push_back(aaTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_1_2_NoCapture); } // BB* _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values) { llvm::StringRef fname("_d_assocarrayliteralTX"); - std::vector types; + std::vector types; types.push_back(typeInfoTy); types.push_back(voidArrayTy); types.push_back(voidArrayTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } #else // int _aaEq(AA aa, AA ab, TypeInfo_AssociativeArray ti) { llvm::StringRef fname("_aaEq"); - std::vector types; + std::vector types; types.push_back(aaTy); types.push_back(aaTy); types.push_back(typeInfoTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_1_2_NoCapture); } @@ -973,8 +992,8 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_moduleCtor"); llvm::StringRef fname2("_moduleDtor"); - std::vector types; - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + std::vector types; + 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); } @@ -986,9 +1005,9 @@ static void LLVM_D_BuildRuntimeModule() // void _d_throw_exception(Object e) { llvm::StringRef fname("_d_throw_exception"); - std::vector types; + std::vector types; types.push_back(objectTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -999,10 +1018,10 @@ static void LLVM_D_BuildRuntimeModule() // int _d_switch_string(char[][] table, char[] ca) { llvm::StringRef fname("_d_switch_string"); - std::vector types; + std::vector types; types.push_back(rt_array(stringTy)); types.push_back(stringTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly); } @@ -1010,10 +1029,10 @@ static void LLVM_D_BuildRuntimeModule() // int _d_switch_ustring(wchar[][] table, wchar[] ca) { llvm::StringRef fname("_d_switch_ustring"); - std::vector types; + std::vector types; types.push_back(rt_array(wstringTy)); types.push_back(wstringTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly); } @@ -1021,10 +1040,10 @@ static void LLVM_D_BuildRuntimeModule() // int _d_switch_dstring(dchar[][] table, dchar[] ca) { llvm::StringRef fname("_d_switch_dstring"); - std::vector types; + std::vector types; types.push_back(rt_array(dstringTy)); types.push_back(dstringTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_ReadOnly); } @@ -1038,9 +1057,9 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_d_criticalenter"); llvm::StringRef fname2("_d_criticalexit"); - std::vector types; + std::vector types; types.push_back(rt_ptr(DtoMutexType())); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + 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); } @@ -1050,9 +1069,9 @@ static void LLVM_D_BuildRuntimeModule() { llvm::StringRef fname("_d_monitorenter"); llvm::StringRef fname2("_d_monitorexit"); - std::vector types; + std::vector types; types.push_back(objectTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) ->setAttributes(Attr_1_NoCapture); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M) @@ -1066,22 +1085,22 @@ static void LLVM_D_BuildRuntimeModule() // int _d_eh_personality(int ver, int actions, ulong eh_class, ptr eh_info, ptr context) { llvm::StringRef fname("_d_eh_personality"); - std::vector types; + std::vector types; types.push_back(intTy); types.push_back(intTy); types.push_back(longTy); types.push_back(voidPtrTy); types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(intTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } // void _d_eh_resume_unwind(ptr exc_struct) { llvm::StringRef fname("_d_eh_resume_unwind"); - std::vector types; + std::vector types; types.push_back(voidPtrTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -1092,9 +1111,9 @@ static void LLVM_D_BuildRuntimeModule() // void _d_invariant(Object o) { llvm::StringRef fname("_d_invariant"); - std::vector types; + std::vector types; types.push_back(objectTy); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } @@ -1102,7 +1121,7 @@ static void LLVM_D_BuildRuntimeModule() // void _d_hidden_func() { llvm::StringRef fname("_d_hidden_func"); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, false); + LLFunctionType* fty = llvm::FunctionType::get(voidTy, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } #endif diff --git a/gen/statements.cpp b/gen/statements.cpp index 4f74cf60..6cd0f05e 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -947,19 +947,19 @@ void SwitchStatement::toIR(IRState* p) inits[i] = c->str->toConstElem(p); } // build static array for ptr or final array - const LLType* elemTy = DtoType(condition->type); - const llvm::ArrayType* arrTy = llvm::ArrayType::get(elemTy, inits.size()); + LLType* elemTy = DtoType(condition->type); + LLArrayType* arrTy = llvm::ArrayType::get(elemTy, inits.size()); LLConstant* arrInit = LLConstantArray::get(arrTy, inits); - llvm::GlobalVariable* arr = new llvm::GlobalVariable(*gIR->module, arrTy, true, llvm::GlobalValue::InternalLinkage, arrInit, ".string_switch_table_data"); + LLGlobalVariable* arr = new llvm::GlobalVariable(*gIR->module, arrTy, true, llvm::GlobalValue::InternalLinkage, arrInit, ".string_switch_table_data"); - const LLType* elemPtrTy = getPtrToType(elemTy); + LLType* elemPtrTy = getPtrToType(elemTy); LLConstant* arrPtr = llvm::ConstantExpr::getBitCast(arr, elemPtrTy); // build the static table - std::vector types; + std::vector types; types.push_back(DtoSize_t()); types.push_back(elemPtrTy); - const llvm::StructType* sTy = llvm::StructType::get(gIR->context(), types); + LLStructType* sTy = llvm::StructType::get(gIR->context(), types); std::vector sinits; sinits.push_back(DtoConstSize_t(inits.size())); sinits.push_back(arrPtr); @@ -1164,7 +1164,7 @@ void ForeachStatement::toIR(IRState* p) Logger::println("aggr = %s", aggr->toChars()); // key - const LLType* keytype = key ? DtoType(key->type) : DtoSize_t(); + LLType* keytype = key ? DtoType(key->type) : DtoSize_t(); LLValue* keyvar; if (key) keyvar = DtoRawVarDeclaration(key); @@ -1524,7 +1524,7 @@ void WithStatement::toIR(IRState* p) static LLConstant* generate_unique_critical_section() { - const LLType* Mty = DtoMutexType(); + LLType* Mty = DtoMutexType(); return new llvm::GlobalVariable(*gIR->module, Mty, false, llvm::GlobalValue::InternalLinkage, LLConstant::getNullValue(Mty), ".uniqueCS"); } @@ -1627,7 +1627,7 @@ void SwitchErrorStatement::toIR(IRState* p) #if DMDV2 // module param LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol(); - const LLType *moduleInfoType = DtoType(Module::moduleinfo->type); + LLType *moduleInfoType = DtoType(Module::moduleinfo->type); args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType))); #else // file param @@ -1640,7 +1640,7 @@ void SwitchErrorStatement::toIR(IRState* p) args.push_back(c); // call - gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); + gIR->CreateCallOrInvoke(fn, args); gIR->ir->CreateUnreachable(); } diff --git a/gen/structs.cpp b/gen/structs.cpp index f3a68e93..661e4d0e 100644 --- a/gen/structs.cpp +++ b/gen/structs.cpp @@ -1,7 +1,6 @@ #include #include "gen/llvm.h" -#include "llvm/AbstractTypeUser.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/ManagedStatic.h" @@ -126,7 +125,7 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd) assert(field); // get the start pointer - const LLType* st = getPtrToType(DtoType(sd->type)); + LLType* st = getPtrToType(DtoType(sd->type)); // cast to the formal struct type src = DtoBitCast(src, st); @@ -185,7 +184,9 @@ size_t add_zeros(std::vector& values, size_t diff) return values.size() - n; } -std::vector DtoStructLiteralValues(const StructDeclaration* sd, const std::vector& inits) +std::vector DtoStructLiteralValues(const StructDeclaration* sd, + const std::vector& inits, + bool isConst) { // get arrays size_t nvars = sd->fields.dim; @@ -269,7 +270,7 @@ std::vector DtoStructLiteralValues(const StructDeclaration* sd, co assert(nextVar == var); // add any 0 padding needed before this field - if (os > lastoffset + lastsize) + if (!isConst && os > lastoffset + lastsize) { //printf("added %lu zeros\n", os - lastoffset - lastsize); add_zeros(values, os - lastoffset - lastsize); @@ -296,7 +297,7 @@ std::vector DtoStructLiteralValues(const StructDeclaration* sd, co } // fill out rest with default initializers - const LLType* structtype = DtoType(sd->type); + LLType* structtype = DtoType(sd->type); size_t structsize = getTypePaddedSize(structtype); // FIXME: this could probably share some code with the above @@ -348,7 +349,7 @@ std::vector DtoStructLiteralValues(const StructDeclaration* sd, co LLType* DtoUnpaddedStructType(Type* dty) { assert(dty->ty == Tstruct); - typedef llvm::DenseMap CacheT; + typedef llvm::DenseMap CacheT; static llvm::ManagedStatic cache; CacheT::iterator it = cache->find(dty); if (it != cache->end()) @@ -357,11 +358,11 @@ LLType* DtoUnpaddedStructType(Type* dty) { TypeStruct* sty = (TypeStruct*) dty; Array& fields = sty->sym->fields; - std::vector types; + std::vector types; for (unsigned i = 0; i < fields.dim; i++) { VarDeclaration* vd = (VarDeclaration*) fields.data[i]; - const LLType* fty; + LLType* fty; if (vd->type->ty == Tstruct) { // Nested structs are the only members that can contain padding fty = DtoUnpaddedStructType(vd->type); @@ -370,7 +371,7 @@ LLType* DtoUnpaddedStructType(Type* dty) { } types.push_back(fty); } - LLType* Ty = LLStructType::get(gIR->context(), types); + LLStructType* Ty = LLStructType::get(gIR->context(), types); cache->insert(std::make_pair(dty, Ty)); return Ty; } diff --git a/gen/structs.h b/gen/structs.h index f655e614..4056e958 100644 --- a/gen/structs.h +++ b/gen/structs.h @@ -10,7 +10,9 @@ void DtoResolveStruct(StructDeclaration* sd); LLConstant* DtoConstStructInitializer(StructInitializer* si); /// Build values for a struct literal. -std::vector DtoStructLiteralValues(const StructDeclaration* sd, const std::vector& inits); +std::vector DtoStructLiteralValues(const StructDeclaration* sd, + const std::vector& inits, + bool isConst = false); /// Returns a boolean=true if the two structs are equal. LLValue* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs); diff --git a/gen/tocall.cpp b/gen/tocall.cpp index 658cc031..b6390e34 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -63,7 +63,7 @@ llvm::CallingConv::ID DtoCallingConv(Loc loc, LINK l) DValue* DtoVaArg(Loc& loc, Type* type, Expression* valistArg) { DValue* expelem = valistArg->toElem(gIR); - const LLType* llt = DtoType(type); + LLType* llt = DtoType(type); if (DtoIsPassedByRef(type)) llt = getPtrToType(llt); // issue a warning for broken va_arg instruction. @@ -106,13 +106,13 @@ LLValue* DtoCallableValue(DValue* fn) ////////////////////////////////////////////////////////////////////////////////////////// -const LLFunctionType* DtoExtractFunctionType(const LLType* type) +LLFunctionType* DtoExtractFunctionType(LLType* type) { - if (const LLFunctionType* fty = isaFunction(type)) + if (LLFunctionType* fty = isaFunction(type)) return fty; - else if (const LLPointerType* pty = isaPointer(type)) + else if (LLPointerType* pty = isaPointer(type)) { - if (const LLFunctionType* fty = isaFunction(pty->getElementType())) + if (LLFunctionType* fty = isaFunction(pty->getElementType())) return fty; } return NULL; @@ -120,7 +120,7 @@ const LLFunctionType* DtoExtractFunctionType(const LLType* type) ////////////////////////////////////////////////////////////////////////////////////////// -static LLValue *fixArgument(DValue *argval, TypeFunction* tf, const LLType *callableArgType, int argIndex) +static LLValue *fixArgument(DValue *argval, TypeFunction* tf, LLType *callableArgType, int argIndex) { #if 0 if (Logger::enabled()) { @@ -179,12 +179,12 @@ void DtoBuildDVarArgList(std::vector& args, std::vector& attrs, TypeFunction* tf, Expressions* arguments, size_t argidx, - const LLFunctionType* callableTy) + LLFunctionType* callableTy) { Logger::println("doing d-style variadic arguments"); LOG_SCOPE - std::vector vtypes; + std::vector vtypes; // number of non variadic args int begin = Parameter::dim(tf->parameters); @@ -211,7 +211,7 @@ void DtoBuildDVarArgList(std::vector& args, { // ok then... so we build some type that is big enough // and aligned to PTRSIZE - std::vector gah; + std::vector gah; gah.reserve(asz/PTRSIZE); size_t gah_sz = 0; while (gah_sz < asz) @@ -223,7 +223,7 @@ void DtoBuildDVarArgList(std::vector& args, } } } - const LLStructType* vtype = LLStructType::get(gIR->context(), vtypes); + LLStructType* vtype = LLStructType::get(gIR->context(), vtypes); if (Logger::enabled()) Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; @@ -242,8 +242,8 @@ void DtoBuildDVarArgList(std::vector& args, } // build type info array - const LLType* typeinfotype = DtoType(Type::typeinfo->type); - const LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements()); + LLType* typeinfotype = DtoType(Type::typeinfo->type); + LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements()); llvm::GlobalVariable* typeinfomem = new llvm::GlobalVariable(*gIR->module, typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage"); @@ -265,8 +265,8 @@ void DtoBuildDVarArgList(std::vector& args, std::vector pinits; pinits.push_back(DtoConstSize_t(vtype->getNumElements())); pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype))); - const LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf()); - tiinits = LLConstantStruct::get(gIR->context(), pinits, false); + LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf()); + tiinits = LLConstantStruct::get(isaStruct(tiarrty), pinits); LLValue* typeinfoarrayparam = new llvm::GlobalVariable(*gIR->module, tiarrty, true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array"); @@ -341,7 +341,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* // get callee llvm value LLValue* callable = DtoCallableValue(fnval); - const LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType()); + LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType()); assert(callableTy); // if (Logger::enabled()) @@ -373,7 +373,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* // return in hidden ptr is first if (retinptr) { - LLValue* retvar = DtoRawAlloca(argiter->get()->getContainedType(0), resulttype->alignsize(), ".rettmp"); + LLValue* retvar = DtoRawAlloca((*argiter)->getContainedType(0), resulttype->alignsize(), ".rettmp"); ++argiter; args.push_back(retvar); @@ -391,7 +391,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* // ... which can be a 'this' argument if (thiscall && dfnval && dfnval->vthis) { - LLValue* thisarg = DtoBitCast(dfnval->vthis, argiter->get()); + LLValue* thisarg = DtoBitCast(dfnval->vthis, *argiter); ++argiter; args.push_back(thisarg); } @@ -407,7 +407,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* { ctxarg = gIR->ir->CreateExtractValue(fnval->getRVal(), 0, ".ptr"); } - ctxarg = DtoBitCast(ctxarg, argiter->get()); + ctxarg = DtoBitCast(ctxarg, *argiter); ++argiter; args.push_back(ctxarg); } @@ -575,7 +575,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* #endif // call the function - LLCallSite call = gIR->CreateCallOrInvoke(callable, args.begin(), args.end(), varname); + LLCallSite call = gIR->CreateCallOrInvoke(callable, args, varname); // get return value LLValue* retllval = (retinptr) ? args[0] : call.getInstruction(); diff --git a/gen/todebug.cpp b/gen/todebug.cpp index f0a2dee8..18db8014 100644 --- a/gen/todebug.cpp +++ b/gen/todebug.cpp @@ -65,7 +65,7 @@ llvm::DIFile DtoDwarfFile(Loc loc) static llvm::DIType dwarfBasicType(Type* type) { Type* t = type->toBasetype(); - const LLType* T = DtoType(type); + LLType* T = DtoType(type); // find encoding unsigned id; @@ -97,7 +97,7 @@ static llvm::DIType dwarfBasicType(Type* type) static llvm::DIType dwarfPointerType(Type* type) { - const LLType* T = DtoType(type); + LLType* T = DtoType(type); Type* t = type->toBasetype(); assert(t->ty == Tpointer && "only pointers allowed for debug info in dwarfPointerType"); @@ -121,7 +121,7 @@ static llvm::DIType dwarfPointerType(Type* type) static llvm::DIType dwarfMemberType(unsigned linnum, Type* type, llvm::DIFile file, const char* c_name, unsigned offset) { - const LLType* T = DtoType(type); + LLType* T = DtoType(type); Type* t = type->toBasetype(); // find base type @@ -131,6 +131,7 @@ static llvm::DIType dwarfMemberType(unsigned linnum, Type* type, llvm::DIFile fi basetype = llvm::DIType(NULL); return gIR->dibuilder.createMemberType( + llvm::DIDescriptor(file), c_name, // name file, // file linnum, // line number @@ -168,7 +169,7 @@ static void add_base_fields( static llvm::DIType dwarfCompositeType(Type* type) { - const LLType* T = DtoType(type); + LLType* T = DtoType(type); Type* t = type->toBasetype(); // defaults @@ -266,8 +267,7 @@ static llvm::DIType dwarfCompositeType(Type* type) } } - llvm::DIArray elemsArray = - gIR->dibuilder.getOrCreateArray(elems.data(), elems.size()); + llvm::DIArray elemsArray = gIR->dibuilder.getOrCreateArray(elems); llvm::DIType ret; if (t->ty == Tclass) { @@ -334,7 +334,7 @@ static void dwarfDeclare(LLValue* var, llvm::DIVariable divar) llvm::DIType dwarfArrayType(Type* type) { - const LLType* T = DtoType(type); + LLType* T = DtoType(type); Type* t = type->toBasetype(); llvm::DIFile file = DtoDwarfFile(Loc(gIR->dmodule, 0)); @@ -352,7 +352,7 @@ llvm::DIType dwarfArrayType(Type* type) { getTypeBitSize(T), // size in bits getABITypeAlign(T)*8, // alignment in bits 0, // What here? - gIR->dibuilder.getOrCreateArray(elems.data(), elems.size()) + gIR->dibuilder.getOrCreateArray(elems) ); } @@ -557,4 +557,11 @@ void DtoDwarfValue(LLValue* var, VarDeclaration* vd) instr->setDebugLoc(gIR->ir->getCurrentDebugLocation()); } +////////////////////////////////////////////////////////////////////////////////////////////////// + +void DtoDwarfModuleEnd() +{ + gIR->dibuilder.finalize(); +} + #endif diff --git a/gen/todebug.h b/gen/todebug.h index c78b666a..8518da56 100644 --- a/gen/todebug.h +++ b/gen/todebug.h @@ -48,6 +48,8 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd); */ llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd); +void DtoDwarfModuleEnd(); + #endif // DISABLE_DEBUG_INFO diff --git a/gen/toir.cpp b/gen/toir.cpp index b4226d07..c11e1730 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -167,7 +167,7 @@ DValue* VarExp::toElem(IRState* p) Logger::println("TypeInfoDeclaration"); tid->codegen(Type::sir); assert(tid->ir.getIrValue()); - const LLType* vartype = DtoType(type); + LLType* vartype = DtoType(type); LLValue* m = tid->ir.getIrValue(); if (m->getType() != getPtrToType(vartype)) m = p->ir->CreateBitCast(m, vartype, "tmp"); @@ -208,9 +208,8 @@ DValue* VarExp::toElem(IRState* p) Logger::println("a normal variable"); // take care of forward references of global variables - if (vd->isDataseg() || (vd->storage_class & STCextern)) { + if (vd->isDataseg() || (vd->storage_class & STCextern)) vd->codegen(Type::sir); - } LLValue* val; @@ -224,10 +223,8 @@ DValue* VarExp::toElem(IRState* p) fatal(); } - if (vd->isDataseg() || (vd->storage_class & STCextern)) { - DtoConstInitGlobal(vd); + if (vd->isDataseg() || (vd->storage_class & STCextern)) val = DtoBitCast(val, DtoType(type->pointerTo())); - } return new DVarValue(type, vd, val); } @@ -289,7 +286,7 @@ LLConstant* VarExp::toConstElem(IRState* p) if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration()) { - const LLType* vartype = DtoType(type); + LLType* vartype = DtoType(type); LLConstant* m = DtoTypeInfoOf(ti->tinfo, false); if (m->getType() != getPtrToType(vartype)) m = llvm::ConstantExpr::getBitCast(m, vartype); @@ -332,7 +329,7 @@ LLConstant* IntegerExp::toConstElem(IRState* p) { Logger::print("IntegerExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; - const LLType* t = DtoType(type); + LLType* t = DtoType(type); if (isaPointer(t)) { Logger::println("pointer"); LLConstant* i = LLConstantInt::get(DtoSize_t(),(uint64_t)value,false); @@ -382,7 +379,7 @@ LLConstant* NullExp::toConstElem(IRState* p) { Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars()); LOG_SCOPE; - const LLType* t = DtoType(type); + LLType* t = DtoType(type); if (type->ty == Tarray) { assert(isaStruct(t)); return llvm::ConstantAggregateZero::get(t); @@ -441,9 +438,9 @@ DValue* StringExp::toElem(IRState* p) Type* dtype = type->toBasetype(); Type* cty = dtype->nextOf()->toBasetype(); - const LLType* ct = DtoTypeNotVoid(cty); + LLType* ct = DtoTypeNotVoid(cty); //printf("ct = %s\n", type->nextOf()->toChars()); - const LLArrayType* at = LLArrayType::get(ct,len+1); + LLArrayType* at = LLArrayType::get(ct,len+1); LLConstant* _init; if (cty->size() == 1) { @@ -485,10 +482,10 @@ DValue* StringExp::toElem(IRState* p) if (dtype->ty == Tarray) { LLConstant* clen = LLConstantInt::get(DtoSize_t(),len,false); - return new DImValue(type, DtoConstSlice(clen, arrptr)); + return new DImValue(type, DtoConstSlice(clen, arrptr, dtype)); } else if (dtype->ty == Tsarray) { - const LLType* dstType = getPtrToType(LLArrayType::get(ct, len)); + LLType* dstType = getPtrToType(LLArrayType::get(ct, len)); LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); return new DVarValue(type, emem); } @@ -513,8 +510,8 @@ LLConstant* StringExp::toConstElem(IRState* p) bool nullterm = (t->ty != Tsarray); size_t endlen = nullterm ? len+1 : len; - const LLType* ct = DtoTypeNotVoid(cty); - const LLArrayType* at = LLArrayType::get(ct,endlen); + LLType* ct = DtoTypeNotVoid(cty); + LLArrayType* at = LLArrayType::get(ct,endlen); LLConstant* _init; if (cty->size() == 1) { @@ -564,7 +561,7 @@ LLConstant* StringExp::toConstElem(IRState* p) } else if (t->ty == Tarray) { LLConstant* clen = LLConstantInt::get(DtoSize_t(),len,false); - return DtoConstSlice(clen, arrptr); + return DtoConstSlice(clen, arrptr, type); } assert(0); @@ -678,7 +675,7 @@ LLConstant* AddExp::toConstElem(IRState* p) if (e1->type->ty == Tpointer && e2->type->isintegral()) { LLConstant *ptr = e1->toConstElem(p); LLConstant *index = e2->toConstElem(p); - ptr = llvm::ConstantExpr::getGetElementPtr(ptr, &index, 1); + ptr = llvm::ConstantExpr::getGetElementPtr(ptr, llvm::makeArrayRef(&index, 1)); return ptr; } @@ -730,7 +727,7 @@ LLConstant* MinExp::toConstElem(IRState* p) LLConstant *ptr = e1->toConstElem(p); LLConstant *index = e2->toConstElem(p); index = llvm::ConstantExpr::getNeg(index); - ptr = llvm::ConstantExpr::getGetElementPtr(ptr, &index, 1); + ptr = llvm::ConstantExpr::getGetElementPtr(ptr, llvm::makeArrayRef(&index, 1)); return ptr; } @@ -938,6 +935,77 @@ DValue* CallExp::toElem(IRState* p) if (expv->getType()->toBasetype()->ty != Tint32) expv = DtoCast(loc, expv, Type::tint32); return new DImValue(type, p->ir->CreateAlloca(LLType::getInt8Ty(gIR->context()), expv->getRVal(), ".alloca")); + // fence instruction + } else if (fndecl->llvmInternal == LLVMfence) { + gIR->ir->CreateFence(llvm::AtomicOrdering(((Expression*)arguments->data[0])->toInteger())); + return NULL; + // atomic store instruction + } else if (fndecl->llvmInternal == LLVMatomic_store) { + Expression* exp1 = (Expression*)arguments->data[0]; + Expression* exp2 = (Expression*)arguments->data[1]; + int atomicOrdering = ((Expression*)arguments->data[2])->toInteger(); + LLValue* val = exp1->toElem(p)->getRVal(); + LLValue* ptr = exp2->toElem(p)->getRVal(); + llvm::StoreInst* ret = gIR->ir->CreateStore(val, ptr, "tmp"); + ret->setAtomic(llvm::AtomicOrdering(atomicOrdering)); + ret->setAlignment(exp1->type->alignsize()); + return NULL; + // atomic load instruction + } else if (fndecl->llvmInternal == LLVMatomic_load) { + Expression* exp = (Expression*)arguments->data[0]; + int atomicOrdering = ((Expression*)arguments->data[1])->toInteger(); + LLValue* ptr = exp->toElem(p)->getRVal(); + Type* retType = exp->type->nextOf(); + llvm::LoadInst* val = gIR->ir->CreateLoad(ptr, "tmp"); + val->setAlignment(retType->alignsize()); + val->setAtomic(llvm::AtomicOrdering(atomicOrdering)); + return new DImValue(retType, val); + // cmpxchg instruction + } else if (fndecl->llvmInternal == LLVMatomic_cmp_xchg) { + Expression* exp1 = (Expression*)arguments->data[0]; + Expression* exp2 = (Expression*)arguments->data[1]; + Expression* exp3 = (Expression*)arguments->data[2]; + int atomicOrdering = ((Expression*)arguments->data[3])->toInteger(); + LLValue* ptr = exp1->toElem(p)->getRVal(); + LLValue* cmp = exp2->toElem(p)->getRVal(); + LLValue* val = exp3->toElem(p)->getRVal(); + LLValue* ret = gIR->ir->CreateAtomicCmpXchg(ptr, cmp, val, llvm::AtomicOrdering(atomicOrdering)); + return new DImValue(exp3->type, ret); + // atomicrmw instruction + } else if (fndecl->llvmInternal == LLVMatomic_rmw) { + static char *ops[] = { + "xchg", + "add", + "sub", + "and", + "nand", + "or", + "xor", + "max", + "min", + "umax", + "umin", + 0 + }; + + int op = 0; + for (; ; ++op) { + if (ops[op] == 0) { + error("unknown atomic_rmw operation %s", fndecl->intrinsicName.c_str()); + return NULL; + } + if (fndecl->intrinsicName == ops[op]) + break; + } + + Expression* exp1 = (Expression*)arguments->data[0]; + Expression* exp2 = (Expression*)arguments->data[1]; + int atomicOrdering = ((Expression*)arguments->data[2])->toInteger(); + LLValue* ptr = exp1->toElem(p)->getRVal(); + LLValue* val = exp2->toElem(p)->getRVal(); + LLValue* ret = gIR->ir->CreateAtomicRMW(llvm::AtomicRMWInst::BinOp(op), ptr, val, + llvm::AtomicOrdering(atomicOrdering)); + return new DImValue(exp2->type, ret); } } return DtoCallFunction(loc, type, fnval, arguments); @@ -974,7 +1042,7 @@ LLConstant* CastExp::toConstElem(IRState* p) LOG_SCOPE; LLConstant* res; - const LLType* lltype = DtoType(type); + LLType* lltype = DtoType(type); Type* tb = to->toBasetype(); // string literal to dyn array: @@ -1100,7 +1168,7 @@ LLConstant* AddrExp::toConstElem(IRState* p) vd->codegen(Type::sir); LLConstant* llc = llvm::dyn_cast(vd->ir.getIrValue()); assert(llc); - return llc; + return DtoBitCast(llc, DtoType(type)); } // static function else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration()) @@ -2073,7 +2141,7 @@ DValue* AndAndExp::toElem(IRState* p) // No need to create a PHI node. resval = ubool; } else { - llvm::PHINode* phi = p->ir->CreatePHI(LLType::getInt1Ty(gIR->context()), "andandval"); + llvm::PHINode* phi = p->ir->CreatePHI(LLType::getInt1Ty(gIR->context()), 2, "andandval"); // If we jumped over evaluation of the right-hand side, // the result is false. Otherwise it's the value of the right-hand side. phi->addIncoming(LLConstantInt::getFalse(gIR->context()), oldblock); @@ -2120,7 +2188,7 @@ DValue* OrOrExp::toElem(IRState* p) // No need to create a PHI node. resval = ubool; } else { - llvm::PHINode* phi = p->ir->CreatePHI(LLType::getInt1Ty(gIR->context()), "ororval"); + llvm::PHINode* phi = p->ir->CreatePHI(LLType::getInt1Ty(gIR->context()), 2, "ororval"); // If we jumped over evaluation of the right-hand side, // the result is true. Otherwise, it's the value of the right-hand side. phi->addIncoming(LLConstantInt::getTrue(gIR->context()), oldblock); @@ -2202,10 +2270,10 @@ DValue* DelegateExp::toElem(IRState* p) if(func->isStatic()) error("can't take delegate of static function %s, it does not require a context ptr", func->toChars()); - const LLPointerType* int8ptrty = getPtrToType(LLType::getInt8Ty(gIR->context())); + LLPointerType* int8ptrty = getPtrToType(LLType::getInt8Ty(gIR->context())); assert(type->toBasetype()->ty == Tdelegate); - const LLType* dgty = DtoType(type); + LLType* dgty = DtoType(type); DValue* u = e1->toElem(p); LLValue* uval; @@ -2251,7 +2319,7 @@ DValue* DelegateExp::toElem(IRState* p) castfptr = DtoBitCast(castfptr, dgty->getContainedType(1)); - return new DImValue(type, DtoAggrPair(castcontext, castfptr, ".dg")); + return new DImValue(type, DtoAggrPair(DtoType(type), castcontext, castfptr, ".dg")); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2502,7 +2570,7 @@ DValue* FuncExp::toElem(IRState* p) assert(fd->ir.irFunc->func); if(fd->tok == TOKdelegate) { - const LLType* dgty = DtoType(type); + LLType* dgty = DtoType(type); LLValue* cval; IrFunction* irfn = p->func(); @@ -2582,13 +2650,13 @@ DValue* ArrayLiteralExp::toElem(IRState* p) size_t len = elements->dim; // llvm target type - const LLType* llType = DtoType(arrayType); + LLType* llType = DtoType(arrayType); if (Logger::enabled()) Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; // llvm storage type - const LLType* llElemType = DtoTypeNotVoid(elemType); - const LLType* llStoType = LLArrayType::get(llElemType, len); + LLType* llElemType = DtoTypeNotVoid(elemType); + LLType* llStoType = LLArrayType::get(llElemType, len); if (Logger::enabled()) Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; @@ -2646,7 +2714,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p) Type* elemt = bt->nextOf(); // build llvm array type - const LLArrayType* arrtype = LLArrayType::get(DtoTypeNotVoid(elemt), elements->dim); + LLArrayType* arrtype = LLArrayType::get(DtoTypeNotVoid(elemt), elements->dim); // dynamic arrays can occur here as well ... bool dyn = (bt->ty != Tsarray); @@ -2660,7 +2728,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p) } // build the constant array initialize - const LLArrayType *t = elements->dim == 0 ? + LLArrayType *t = elements->dim == 0 ? arrtype : LLArrayType::get(vals.front()->getType(), elements->dim); LLConstant* initval = LLConstantArray::get(t, vals); @@ -2815,15 +2883,22 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p) inits[i] = exprs[i]->toConstElem(p); // vector of values to build aggregate from - std::vector values = DtoStructLiteralValues(sd, inits); + std::vector values = DtoStructLiteralValues(sd, inits, true); // we know those values are constants.. cast them std::vector constvals(values.size(), NULL); - for (size_t i = 0; i < values.size(); ++i) + std::vector types(values.size(), NULL); + for (size_t i = 0; i < values.size(); ++i) { constvals[i] = llvm::cast(values[i]); + types[i] = values[i]->getType(); + } // return constant struct - return LLConstantStruct::get(gIR->context(), constvals, sd->ir.irStruct->packed); + if (!constType) + constType = LLStructType::get(gIR->context(), types); + else + constType->setBody(types); + return LLConstantStruct::get(constType, llvm::makeArrayRef(constvals)); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2892,12 +2967,12 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p) Type* indexType = ((TypeAArray*)aatype)->index; llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assocarrayliteralTX"); - const llvm::FunctionType* funcTy = func->getFunctionType(); + LLFunctionType* funcTy = func->getFunctionType(); LLValue* aaTypeInfo = DtoTypeInfoOf(stripModifiers(aatype)); LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; - const LLArrayType* arrtype = LLArrayType::get(DtoType(indexType), keys->dim); + LLArrayType* arrtype = LLArrayType::get(DtoType(indexType), keys->dim); LLConstant* initval = LLConstantArray::get(arrtype, keysInits); LLConstant* globalstore = new LLGlobalVariable(*gIR->module, arrtype, false, LLGlobalValue::InternalLinkage, initval, ".aaKeysStorage"); LLConstant* slice = llvm::ConstantExpr::getGetElementPtr(globalstore, idxs, 2); @@ -2986,7 +3061,7 @@ DValue* TypeExp::toElem(IRState *p) DValue* TupleExp::toElem(IRState *p) { Logger::print("TupleExp::toElem() %s\n", toChars()); - std::vector types(exps->dim, NULL); + std::vector types(exps->dim, NULL); for (size_t i = 0; i < exps->dim; i++) { Expression *el = (Expression *)exps->data[i]; diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index be70c4ec..1b1d4091 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -51,7 +51,7 @@ unsigned DtoShouldExtend(Type* type) return llvm::Attribute::None; } -const LLType* DtoType(Type* t) +LLType* DtoType(Type* t) { t = stripModifiers( t ); @@ -177,12 +177,12 @@ const LLType* DtoType(Type* t) ////////////////////////////////////////////////////////////////////////////////////////// /* -const LLType* DtoStructTypeFromArguments(Arguments* arguments) +LLType* DtoStructTypeFromArguments(Arguments* arguments) { if (!arguments) return LLType::getVoidTy(gIR->context()); - std::vector types; + std::vector types; for (size_t i = 0; i < arguments->dim; i++) { Argument *arg = (Argument *)arguments->data[i]; @@ -196,9 +196,9 @@ const LLType* DtoStructTypeFromArguments(Arguments* arguments) ////////////////////////////////////////////////////////////////////////////////////////// -const LLType* DtoTypeNotVoid(Type* t) +LLType* DtoTypeNotVoid(Type* t) { - const LLType* lt = DtoType(t); + LLType* lt = DtoType(t); if (lt == LLType::getVoidTy(gIR->context())) return LLType::getInt8Ty(gIR->context()); return lt; @@ -367,8 +367,8 @@ llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym) LLValue* DtoPointedType(LLValue* ptr, LLValue* val) { - const LLType* ptrTy = ptr->getType()->getContainedType(0); - const LLType* valTy = val->getType(); + LLType* ptrTy = ptr->getType()->getContainedType(0); + LLType* valTy = val->getType(); // ptr points to val's type if (ptrTy == valTy) { @@ -379,8 +379,8 @@ LLValue* DtoPointedType(LLValue* ptr, LLValue* val) { // val is integer assert(valTy->isIntegerTy()); - const LLIntegerType* pt = llvm::cast(ptrTy); - const LLIntegerType* vt = llvm::cast(valTy); + LLIntegerType* pt = llvm::cast(ptrTy); + LLIntegerType* vt = llvm::cast(valTy); if (pt->getBitWidth() < vt->getBitWidth()) { return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb()); } @@ -399,10 +399,10 @@ LLValue* DtoPointedType(LLValue* ptr, LLValue* val) ////////////////////////////////////////////////////////////////////////////////////////// -const LLIntegerType* DtoSize_t() +LLIntegerType* DtoSize_t() { // the type of size_t does not change once set - static const LLIntegerType* t = NULL; + static LLIntegerType* t = NULL; if (t == NULL) t = (global.params.is64bit) ? LLType::getInt64Ty(gIR->context()) : LLType::getInt32Ty(gIR->context()); return t; @@ -422,7 +422,7 @@ LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::B LLSmallVector v(2); v[0] = i0; v[1] = i1; - return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var?var:"tmp", bb?bb:gIR->scopebb()); + return llvm::GetElementPtrInst::Create(ptr, v, var?var:"tmp", bb?bb:gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -439,7 +439,7 @@ LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var, llvm:: LLSmallVector v(2); v[0] = DtoConstUint(i0); v[1] = DtoConstUint(i1); - return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var?var:"tmp", bb?bb:gIR->scopebb()); + return llvm::GetElementPtrInst::Create(ptr, v, var?var:"tmp", bb?bb:gIR->scopebb()); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -456,11 +456,11 @@ void DtoMemSet(LLValue* dst, LLValue* val, LLValue* nbytes) { dst = DtoBitCast(dst,getVoidPtrType()); - const LLType* intTy = DtoSize_t(); - const LLType *VoidPtrTy = getVoidPtrType(); - const LLType *Tys[2] ={VoidPtrTy, intTy}; + LLType* intTy = DtoSize_t(); + LLType *VoidPtrTy = getVoidPtrType(); + LLType *Tys[2] ={VoidPtrTy, intTy}; llvm::Function* fn = llvm::Intrinsic::getDeclaration(gIR->module, - llvm::Intrinsic::memset, Tys, 2); + llvm::Intrinsic::memset, llvm::makeArrayRef(Tys, 2)); gIR->ir->CreateCall5(fn, dst, val, nbytes, DtoConstUint(1), DtoConstBool(false), ""); } @@ -479,11 +479,11 @@ void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes, unsigned align) dst = DtoBitCast(dst,getVoidPtrType()); src = DtoBitCast(src,getVoidPtrType()); - const LLType* intTy = DtoSize_t(); - const LLType *VoidPtrTy = getVoidPtrType(); - const LLType *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy}; + LLType* intTy = DtoSize_t(); + LLType *VoidPtrTy = getVoidPtrType(); + LLType *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy}; llvm::Function* fn = llvm::Intrinsic::getDeclaration(gIR->module, - llvm::Intrinsic::memcpy, Tys, 3); + llvm::Intrinsic::memcpy, llvm::makeArrayRef(Tys, 3)); gIR->ir->CreateCall5(fn, dst, src, nbytes, DtoConstUint(align), DtoConstBool(false), ""); } @@ -497,11 +497,11 @@ LLValue* DtoMemCmp(LLValue* lhs, LLValue* rhs, LLValue* nbytes) LLFunction* fn = gIR->module->getFunction("memcmp"); if (!fn) { - std::vector params(3); + std::vector params(3); params[0] = getVoidPtrType(); params[1] = getVoidPtrType(); params[2] = DtoSize_t(); - const LLFunctionType* fty = LLFunctionType::get(LLType::getInt32Ty(gIR->context()), params, false); + LLFunctionType* fty = LLFunctionType::get(LLType::getInt32Ty(gIR->context()), params, false); fn = LLFunction::Create(fty, LLGlobalValue::ExternalLinkage, "memcmp", gIR->module); } @@ -531,7 +531,8 @@ void DtoAggrCopy(LLValue* dst, LLValue* src) void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device) { - llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier); + // FIXME: implement me + /*llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier); assert(fn != NULL); LLSmallVector llargs; @@ -541,7 +542,7 @@ void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device) llargs.push_back(DtoConstBool(ss)); llargs.push_back(DtoConstBool(device)); - llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); + llvm::CallInst::Create(fn, llargs, "", gIR->scopebb());*/ } ////////////////////////////////////////////////////////////////////////////////////////// @@ -569,7 +570,7 @@ llvm::ConstantInt* DtoConstUbyte(unsigned char i) LLConstant* DtoConstFP(Type* t, long double value) { - const LLType* llty = DtoType(t); + LLType* llty = DtoType(t); assert(llty->isFloatingPointTy()); if(llty == LLType::getFloatTy(gIR->context()) || llty == LLType::getDoubleTy(gIR->context())) @@ -595,7 +596,8 @@ LLConstant* DtoConstString(const char* str) LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; return DtoConstSlice( DtoConstSize_t(s.size()), - llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2) + llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2), + Type::tchar->arrayOf() ); } LLConstant* DtoConstStringPtr(const char* str, const char* section) @@ -646,7 +648,7 @@ void DtoAlignedStore(LLValue* src, LLValue* dst) ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name) +LLValue* DtoBitCast(LLValue* v, LLType* t, const char* name) { if (v->getType() == t) return v; @@ -654,7 +656,7 @@ LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name) return gIR->ir->CreateBitCast(v, t, name ? name : "tmp"); } -LLConstant* DtoBitCast(LLConstant* v, const LLType* t) +LLConstant* DtoBitCast(LLConstant* v, LLType* t) { if (v->getType() == t) return v; @@ -675,42 +677,42 @@ LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name) ////////////////////////////////////////////////////////////////////////////////////////// -const LLPointerType* isaPointer(LLValue* v) +LLPointerType* isaPointer(LLValue* v) { return llvm::dyn_cast(v->getType()); } -const LLPointerType* isaPointer(const LLType* t) +LLPointerType* isaPointer(LLType* t) { return llvm::dyn_cast(t); } -const LLArrayType* isaArray(LLValue* v) +LLArrayType* isaArray(LLValue* v) { return llvm::dyn_cast(v->getType()); } -const LLArrayType* isaArray(const LLType* t) +LLArrayType* isaArray(LLType* t) { return llvm::dyn_cast(t); } -const LLStructType* isaStruct(LLValue* v) +LLStructType* isaStruct(LLValue* v) { return llvm::dyn_cast(v->getType()); } -const LLStructType* isaStruct(const LLType* t) +LLStructType* isaStruct(LLType* t) { return llvm::dyn_cast(t); } -const LLFunctionType* isaFunction(LLValue* v) +LLFunctionType* isaFunction(LLValue* v) { return llvm::dyn_cast(v->getType()); } -const LLFunctionType* isaFunction(const LLType* t) +LLFunctionType* isaFunction(LLType* t) { return llvm::dyn_cast(t); } @@ -737,73 +739,73 @@ llvm::GlobalVariable* isaGlobalVar(LLValue* v) ////////////////////////////////////////////////////////////////////////////////////////// -const LLPointerType* getPtrToType(const LLType* t) +LLPointerType* getPtrToType(LLType* t) { if (t == LLType::getVoidTy(gIR->context())) t = LLType::getInt8Ty(gIR->context()); return LLPointerType::get(t, 0); } -const LLPointerType* getVoidPtrType() +LLPointerType* getVoidPtrType() { return getPtrToType(LLType::getInt8Ty(gIR->context())); } -llvm::ConstantPointerNull* getNullPtr(const LLType* t) +llvm::ConstantPointerNull* getNullPtr(LLType* t) { - const LLPointerType* pt = llvm::cast(t); + LLPointerType* pt = llvm::cast(t); return llvm::ConstantPointerNull::get(pt); } -LLConstant* getNullValue(const LLType* t) +LLConstant* getNullValue(LLType* t) { return LLConstant::getNullValue(t); } ////////////////////////////////////////////////////////////////////////////////////////// -size_t getTypeBitSize(const LLType* t) +size_t getTypeBitSize(LLType* t) { return gTargetData->getTypeSizeInBits(t); } -size_t getTypeStoreSize(const LLType* t) +size_t getTypeStoreSize(LLType* t) { return gTargetData->getTypeStoreSize(t); } -size_t getTypePaddedSize(const LLType* t) +size_t getTypePaddedSize(LLType* t) { size_t sz = gTargetData->getTypeAllocSize(t); //Logger::cout() << "abi type size of: " << *t << " == " << sz << '\n'; return sz; } -size_t getTypeAllocSize(const LLType* t) +size_t getTypeAllocSize(LLType* t) { return gTargetData->getTypeAllocSize(t); } -unsigned char getABITypeAlign(const LLType* t) +unsigned char getABITypeAlign(LLType* t) { return gTargetData->getABITypeAlignment(t); } -unsigned char getPrefTypeAlign(const LLType* t) +unsigned char getPrefTypeAlign(LLType* t) { return gTargetData->getPrefTypeAlignment(t); } -const LLType* getBiggestType(const LLType** begin, size_t n) +LLType* getBiggestType(LLType** begin, size_t n) { - const LLType* bigTy = 0; + LLType* bigTy = 0; size_t bigSize = 0; size_t bigAlign = 0; - const LLType** end = begin+n; + LLType** end = begin+n; while (begin != end) { - const LLType* T = *begin; + LLType* T = *begin; size_t sz = getTypePaddedSize(T); size_t ali = getABITypeAlign(T); @@ -823,21 +825,21 @@ const LLType* getBiggestType(const LLType** begin, size_t n) ////////////////////////////////////////////////////////////////////////////////////////// -const LLStructType* DtoInterfaceInfoType() +LLStructType* DtoInterfaceInfoType() { if (gIR->interfaceInfoType) return gIR->interfaceInfoType; // build interface info type - std::vector types; + std::vector types; // ClassInfo classinfo ClassDeclaration* cd2 = ClassDeclaration::classinfo; DtoResolveClass(cd2); types.push_back(DtoType(cd2->type)); // void*[] vtbl - std::vector vtbltypes; + std::vector vtbltypes; vtbltypes.push_back(DtoSize_t()); - const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::getInt8Ty(gIR->context()))); + LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::getInt8Ty(gIR->context()))); vtbltypes.push_back(byteptrptrty); types.push_back(LLStructType::get(gIR->context(), vtbltypes)); // int offset @@ -850,7 +852,7 @@ const LLStructType* DtoInterfaceInfoType() ////////////////////////////////////////////////////////////////////////////////////////// -const LLStructType* DtoMutexType() +LLStructType* DtoMutexType() { if (gIR->mutexType) return gIR->mutexType; @@ -859,7 +861,7 @@ const LLStructType* DtoMutexType() if (global.params.os == OSWindows) { // CRITICAL_SECTION.sizeof == 68 - std::vector types(17, LLType::getInt32Ty(gIR->context())); + std::vector types(17, LLType::getInt32Ty(gIR->context())); return LLStructType::get(gIR->context(), types); } @@ -870,50 +872,44 @@ const LLStructType* DtoMutexType() } // pthread_fastlock - std::vector types2; + std::vector types2; types2.push_back(DtoSize_t()); types2.push_back(LLType::getInt32Ty(gIR->context())); - const LLStructType* fastlock = LLStructType::get(gIR->context(), types2); + LLStructType* fastlock = LLStructType::get(gIR->context(), types2); // pthread_mutex - std::vector types1; + std::vector types1; types1.push_back(LLType::getInt32Ty(gIR->context())); types1.push_back(LLType::getInt32Ty(gIR->context())); types1.push_back(getVoidPtrType()); types1.push_back(LLType::getInt32Ty(gIR->context())); types1.push_back(fastlock); - const LLStructType* pmutex = LLStructType::get(gIR->context(), types1); + LLStructType* pmutex = LLStructType::get(gIR->context(), types1); // D_CRITICAL_SECTION - LLOpaqueType* opaque = LLOpaqueType::get(gIR->context()); - std::vector types; - types.push_back(getPtrToType(opaque)); + LLStructType* mutex = LLStructType::create(gIR->context(), "D_CRITICAL_SECTION"); + std::vector types; + types.push_back(getPtrToType(mutex)); types.push_back(pmutex); + mutex->setBody(types); + gIR->mutexType = mutex; - // resolve type - pmutex = LLStructType::get(gIR->context(), types); - LLPATypeHolder pa(pmutex); - opaque->refineAbstractTypeTo(pa.get()); - pmutex = isaStruct(pa.get()); - - gIR->mutexType = pmutex; - gIR->module->addTypeName("D_CRITICAL_SECTION", pmutex); return pmutex; } ////////////////////////////////////////////////////////////////////////////////////////// -const LLStructType* DtoModuleReferenceType() +LLStructType* DtoModuleReferenceType() { if (gIR->moduleRefType) return gIR->moduleRefType; - // this is a recursive type so start out with the opaque - LLOpaqueType* opaque = LLOpaqueType::get(gIR->context()); + // this is a recursive type so start out with a struct without body + LLStructType* st = LLStructType::create(gIR->context(), "ModuleReference"); // add members - std::vector types; - types.push_back(getPtrToType(opaque)); + std::vector types; + types.push_back(getPtrToType(st)); #if DMDV1 types.push_back(DtoType(Module::moduleinfo->type)); #else @@ -921,20 +917,16 @@ const LLStructType* DtoModuleReferenceType() #endif // resolve type - const LLStructType* st = LLStructType::get(gIR->context(), types); - LLPATypeHolder pa(st); - opaque->refineAbstractTypeTo(pa.get()); - st = isaStruct(pa.get()); + st->setBody(types); // done gIR->moduleRefType = st; - gIR->module->addTypeName("ModuleReference", st); return st; } ////////////////////////////////////////////////////////////////////////////////////////// -LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* name) +LLValue* DtoAggrPair(LLType* type, LLValue* V1, LLValue* V2, const char* name) { LLValue* res = llvm::UndefValue::get(type); res = gIR->ir->CreateInsertValue(res, V1, 0, "tmp"); @@ -943,11 +935,14 @@ LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* n LLValue* DtoAggrPair(LLValue* V1, LLValue* V2, const char* name) { - const LLType* t = LLStructType::get(gIR->context(), V1->getType(), V2->getType(), NULL); + llvm::SmallVector types; + types.push_back(V1->getType()); + types.push_back(V2->getType()); + LLType* t = LLStructType::get(gIR->context(), types); return DtoAggrPair(t, V1, V2, name); } -LLValue* DtoAggrPaint(LLValue* aggr, const LLType* as) +LLValue* DtoAggrPaint(LLValue* aggr, LLType* as) { if (aggr->getType() == as) return aggr; diff --git a/gen/tollvm.h b/gen/tollvm.h index edee0926..4826b161 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -10,10 +10,10 @@ #include "gen/structs.h" // D->LLVM type handling stuff -const LLType* DtoType(Type* t); +LLType* DtoType(Type* t); // same as DtoType except it converts 'void' to 'i8' -const LLType* DtoTypeNotVoid(Type* t); +LLType* DtoTypeNotVoid(Type* t); // returns true is the type must be passed by pointer bool DtoIsPassedByRef(Type* type); @@ -23,7 +23,7 @@ unsigned DtoShouldExtend(Type* type); // tuple helper // takes a arguments list and makes a struct type out of them -//const LLType* DtoStructTypeFromArguments(Arguments* arguments); +//LLType* DtoStructTypeFromArguments(Arguments* arguments); // delegate helpers LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs); @@ -37,10 +37,10 @@ LLGlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym); LLValue* DtoPointedType(LLValue* ptr, LLValue* val); // some types -const LLIntegerType* DtoSize_t(); -const LLStructType* DtoInterfaceInfoType(); -const LLStructType* DtoMutexType(); -const LLStructType* DtoModuleReferenceType(); +LLIntegerType* DtoSize_t(); +LLStructType* DtoInterfaceInfoType(); +LLStructType* DtoMutexType(); +LLStructType* DtoModuleReferenceType(); // getelementptr helpers LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=0, llvm::BasicBlock* bb=NULL); @@ -66,48 +66,48 @@ LLValue* DtoLoad(LLValue* src, const char* name=0); LLValue* DtoAlignedLoad(LLValue* src, const char* name=0); void DtoStore(LLValue* src, LLValue* dst); void DtoAlignedStore(LLValue* src, LLValue* dst); -LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0); -LLConstant* DtoBitCast(LLConstant* v, const LLType* t); +LLValue* DtoBitCast(LLValue* v, LLType* t, const char* name=0); +LLConstant* DtoBitCast(LLConstant* v, LLType* t); LLValue* DtoInsertValue(LLValue* aggr, LLValue* v, unsigned idx, const char* name=0); LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name=0); // llvm::dyn_cast wrappers -const LLPointerType* isaPointer(LLValue* v); -const LLPointerType* isaPointer(const LLType* t); -const LLArrayType* isaArray(LLValue* v); -const LLArrayType* isaArray(const LLType* t); -const LLStructType* isaStruct(LLValue* v); -const LLStructType* isaStruct(const LLType* t); -const LLFunctionType* isaFunction(LLValue* v); -const LLFunctionType* isaFunction(const LLType* t); +LLPointerType* isaPointer(LLValue* v); +LLPointerType* isaPointer(LLType* t); +LLArrayType* isaArray(LLValue* v); +LLArrayType* isaArray(LLType* t); +LLStructType* isaStruct(LLValue* v); +LLStructType* isaStruct(LLType* t); +LLFunctionType* isaFunction(LLValue* v); +LLFunctionType* isaFunction(LLType* t); LLConstant* isaConstant(LLValue* v); LLConstantInt* isaConstantInt(LLValue* v); llvm::Argument* isaArgument(LLValue* v); LLGlobalVariable* isaGlobalVar(LLValue* v); // llvm::T::get(...) wrappers -const LLPointerType* getPtrToType(const LLType* t); -const LLPointerType* getVoidPtrType(); -llvm::ConstantPointerNull* getNullPtr(const LLType* t); -LLConstant* getNullValue(const LLType* t); +LLPointerType* getPtrToType(LLType* t); +LLPointerType* getVoidPtrType(); +llvm::ConstantPointerNull* getNullPtr(LLType* t); +LLConstant* getNullValue(LLType* t); // type sizes -size_t getTypeBitSize(const LLType* t); -size_t getTypeStoreSize(const LLType* t); -size_t getTypePaddedSize(const LLType* t); -size_t getTypeAllocSize(const LLType* t); +size_t getTypeBitSize(LLType* t); +size_t getTypeStoreSize(LLType* t); +size_t getTypePaddedSize(LLType* t); +size_t getTypeAllocSize(LLType* t); // type alignments -unsigned char getABITypeAlign(const LLType* t); -unsigned char getPrefTypeAlign(const LLType* t); +unsigned char getABITypeAlign(LLType* t); +unsigned char getPrefTypeAlign(LLType* t); // get biggest type, for unions ... -const LLType* getBiggestType(const LLType** begin, size_t n); +LLType* getBiggestType(LLType** begin, size_t n); // pair type helpers -LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* name = 0); +LLValue* DtoAggrPair(LLType* type, LLValue* V1, LLValue* V2, const char* name = 0); LLValue* DtoAggrPair(LLValue* V1, LLValue* V2, const char* name = 0); -LLValue* DtoAggrPaint(LLValue* aggr, const LLType* as); +LLValue* DtoAggrPaint(LLValue* aggr, LLType* as); LLValue* DtoAggrPairSwap(LLValue* aggr); /** diff --git a/gen/toobj.cpp b/gen/toobj.cpp index e9765e4e..1e7737ed 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -67,8 +67,8 @@ static llvm::cl::opt noVerify("noverify", ////////////////////////////////////////////////////////////////////////////////////////// // fwd decl -void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out); -void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath); +void emit_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out, + llvm::TargetMachine::CodeGenFileType fileType); ////////////////////////////////////////////////////////////////////////////////////////// @@ -158,6 +158,12 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir) } } + // finilize debugging + #ifndef DISABLE_DEBUG_INFO + if (global.params.symdebug) + DtoDwarfModuleEnd(); + #endif + // generate ModuleInfo genmoduleinfo(); @@ -244,20 +250,17 @@ void writeModule(llvm::Module* m, std::string filename) } // write native assembly - if (global.params.output_s || global.params.output_o) { + if (global.params.output_s) { LLPath spath = LLPath(filename); spath.eraseSuffix(); spath.appendSuffix(std::string(global.s_ext)); - if (!global.params.output_s) { - spath.createTemporaryFileOnDisk(); - } Logger::println("Writing native asm to: %s\n", spath.c_str()); std::string err; { llvm::raw_fd_ostream out(spath.c_str(), err); if (err.empty()) { - write_asm_to_file(*gTargetMachine, *m, out); + emit_file(*gTargetMachine, *m, out, llvm::TargetMachine::CGFT_AssemblyFile); } else { @@ -265,15 +268,23 @@ void writeModule(llvm::Module* m, std::string filename) fatal(); } } + } - // call gcc to convert assembly to object file - if (global.params.output_o) { - LLPath objpath = LLPath(filename); - assemble(spath, objpath); - } - - if (!global.params.output_s) { - spath.eraseFromDisk(); + if (global.params.output_o) { + LLPath objpath = LLPath(filename); + Logger::println("Writing object file to: %s\n", objpath.c_str()); + std::string err; + { + llvm::raw_fd_ostream out(objpath.c_str(), err); + if (err.empty()) + { + emit_file(*gTargetMachine, *m, out, llvm::TargetMachine::CGFT_ObjectFile); + } + else + { + error("cannot write object file: %s", err.c_str()); + fatal(); + } } } } @@ -281,7 +292,8 @@ void writeModule(llvm::Module* m, std::string filename) /* ================================================================== */ // based on llc code, University of Illinois Open Source License -void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out) +void emit_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out, + llvm::TargetMachine::CodeGenFileType fileType) { using namespace llvm; @@ -302,7 +314,7 @@ void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_f LastArg = CodeGenOpt::Aggressive; llvm::formatted_raw_ostream fout(out); - if (Target.addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, LastArg)) + if (Target.addPassesToEmitFile(Passes, fout, fileType, LastArg)) assert(0 && "no support for asm output"); Passes.doInitialization(); @@ -320,72 +332,6 @@ void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_f //assert(rmod); } -/* ================================================================== */ - -// uses gcc to make an obj out of an assembly file -// based on llvm-ld code, University of Illinois Open Source License -void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath) -{ - using namespace llvm; - - sys::Path gcc = getGcc(); - - // Run GCC to assemble and link the program into native code. - // - // Note: - // We can't just assemble and link the file with the system assembler - // and linker because we don't know where to put the _start symbol. - // GCC mysteriously knows how to do it. - std::vector args; - args.push_back(gcc.str()); - args.push_back("-fno-strict-aliasing"); - args.push_back("-O3"); - args.push_back("-c"); - args.push_back("-xassembler"); - args.push_back(asmpath.str()); - args.push_back("-o"); - args.push_back(objpath.str()); - - //FIXME: only use this if needed? - args.push_back("-fpic"); - - //FIXME: enforce 64 bit - if (global.params.is64bit) - args.push_back("-m64"); - else - // Assume 32-bit? - args.push_back("-m32"); - - // Now that "args" owns all the std::strings for the arguments, call the c_str - // method to get the underlying string array. We do this game so that the - // std::string array is guaranteed to outlive the const char* array. - std::vector Args; - for (unsigned i = 0, e = args.size(); i != e; ++i) - Args.push_back(args[i].c_str()); - Args.push_back(0); - - if (Logger::enabled()) { - Logger::println("Assembling with: "); - std::vector::const_iterator I = Args.begin(), E = Args.end(); - Stream logstr = Logger::cout(); - for (; I != E; ++I) - if (*I) - logstr << "'" << *I << "'" << " "; - logstr << "\n" << std::flush; - } - - // Run the compiler to assembly the program. - std::string ErrMsg; - int R = sys::Program::ExecuteAndWait( - gcc, &Args[0], 0, 0, 0, 0, &ErrMsg); - if (R) - { - error("Failed to invoke gcc. %s", ErrMsg.c_str()); - fatal(); - } -} - - /* ================================================================== */ static llvm::Function* build_module_function(const std::string &name, const std::list &funcs, @@ -399,8 +345,8 @@ static llvm::Function* build_module_function(const std::string &name, const std: return funcs.front()->ir.irFunc->func; } - std::vector argsTy; - const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false); + std::vector argsTy; + LLFunctionType* fnTy = LLFunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false); assert(gIR->module->getFunction(name) == NULL); llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module); fn->setCallingConv(DtoCallingConv(0, LINKd)); @@ -498,7 +444,7 @@ static llvm::Function* build_module_shared_dtor() static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo) { // build ctor type - const LLFunctionType* fty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector(), false); + LLFunctionType* fty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector(), false); // build ctor name std::string fname = "_D"; @@ -509,7 +455,7 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo) LLFunction* ctor = LLFunction::Create(fty, LLGlobalValue::InternalLinkage, fname, gIR->module); // provide the default initializer - const LLStructType* modulerefTy = DtoModuleReferenceType(); + LLStructType* modulerefTy = DtoModuleReferenceType(); std::vector mrefvalues; mrefvalues.push_back(LLConstant::getNullValue(modulerefTy->getContainedType(0))); mrefvalues.push_back(llvm::ConstantExpr::getBitCast(moduleinfo, modulerefTy->getContainedType(1))); @@ -523,7 +469,7 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo) // make sure _Dmodule_ref is declared LLConstant* mref = gIR->module->getNamedGlobal("_Dmodule_ref"); - const LLType *modulerefPtrTy = getPtrToType(modulerefTy); + LLType *modulerefPtrTy = getPtrToType(modulerefTy); if (!mref) mref = new LLGlobalVariable(*gIR->module, modulerefPtrTy, false, LLGlobalValue::ExternalLinkage, NULL, "_Dmodule_ref"); mref = DtoBitCast(mref, getPtrToType(modulerefPtrTy)); @@ -563,7 +509,7 @@ llvm::GlobalVariable* Module::moduleInfoSymbol() MIname.append("8__ModuleZ"); if (gIR->dmodule != this) { - const LLType* moduleinfoTy = DtoType(moduleinfo->type); + LLType* moduleinfoTy = DtoType(moduleinfo->type); LLGlobalVariable *var = gIR->module->getGlobalVariable(MIname); if (!var) var = new llvm::GlobalVariable(*gIR->module, moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname); @@ -575,7 +521,7 @@ llvm::GlobalVariable* Module::moduleInfoSymbol() // declare global // flags will be modified at runtime so can't make it constant - moduleInfoVar = new llvm::GlobalVariable(*gIR->module, moduleInfoType->get(), false, llvm::GlobalValue::ExternalLinkage, NULL, MIname); + moduleInfoVar = new llvm::GlobalVariable(*gIR->module, moduleInfoType, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname); return moduleInfoVar; } @@ -630,8 +576,8 @@ void Module::genmoduleinfo() RTTIBuilder b(moduleinfo); // some types - const LLType* moduleinfoTy = moduleinfo->type->irtype->getPA(); - const LLType* classinfoTy = ClassDeclaration::classinfo->type->irtype->getPA(); + LLType* moduleinfoTy = moduleinfo->type->irtype->getType(); + LLType* classinfoTy = ClassDeclaration::classinfo->type->irtype->getType(); // name b.push_string(toPrettyChars()); @@ -656,7 +602,7 @@ void Module::genmoduleinfo() // has import array? if (!importInits.empty()) { - const llvm::ArrayType* importArrTy = llvm::ArrayType::get(getPtrToType(moduleinfoTy), importInits.size()); + llvm::ArrayType* importArrTy = llvm::ArrayType::get(getPtrToType(moduleinfoTy), importInits.size()); c = LLConstantArray::get(importArrTy, importInits); std::string m_name("_D"); m_name.append(mangle()); @@ -707,7 +653,7 @@ void Module::genmoduleinfo() // has class array? if (!classInits.empty()) { - const llvm::ArrayType* classArrTy = llvm::ArrayType::get(getPtrToType(classinfoTy), classInits.size()); + llvm::ArrayType* classArrTy = llvm::ArrayType::get(getPtrToType(classinfoTy), classInits.size()); c = LLConstantArray::get(classArrTy, classInits); std::string m_name("_D"); m_name.append(mangle()); @@ -726,7 +672,7 @@ void Module::genmoduleinfo() b.push_uint(mi_flags); // function pointer type for next three fields - const LLType* fnptrTy = getPtrToType(LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector(), false)); + LLType* fnptrTy = getPtrToType(LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector(), false)); // ctor #if DMDV2 @@ -772,7 +718,7 @@ void Module::genmoduleinfo() b.push(c); // index + reserved void*[1] - const LLType* AT = llvm::ArrayType::get(getVoidPtrType(), 2); + LLType* AT = llvm::ArrayType::get(getVoidPtrType(), 2); c = getNullValue(AT); b.push(c); @@ -787,19 +733,17 @@ void Module::genmoduleinfo() }*/ // create and set initializer - LLConstant* constMI = b.get_constant(); - llvm::cast(moduleInfoType->get())->refineAbstractTypeTo(constMI->getType()); - moduleInfoSymbol()->setInitializer(constMI); + b.finalize(moduleInfoType, moduleInfoSymbol()); // build the modulereference and ctor for registering it LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSymbol()); // register this ctor in the magic llvm.global_ctors appending array - const LLFunctionType* magicfty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector(), false); - std::vector magictypes; + LLFunctionType* magicfty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector(), false); + std::vector magictypes; magictypes.push_back(LLType::getInt32Ty(gIR->context())); magictypes.push_back(getPtrToType(magicfty)); - const LLStructType* magicsty = LLStructType::get(gIR->context(), magictypes); + LLStructType* magicsty = LLStructType::get(gIR->context(), magictypes); // make the constant element std::vector magicconstants; @@ -808,7 +752,7 @@ void Module::genmoduleinfo() LLConstant* magicinit = LLConstantStruct::get(magicsty, magicconstants); // declare the appending array - const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(magicsty, 1); + llvm::ArrayType* appendArrTy = llvm::ArrayType::get(magicsty, 1); std::vector appendInits(1, magicinit); LLConstant* appendInit = LLConstantArray::get(appendArrTy, appendInits); std::string appendName("llvm.global_ctors"); diff --git a/gen/typinf.cpp b/gen/typinf.cpp index 59fa03f0..b65e4c29 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -303,12 +303,16 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid) LOG_SCOPE; IrGlobal* irg = new IrGlobal(tid); + if (tid->tinfo->builtinTypeInfo()) // this is a declaration of a builtin __initZ var + irg->type = Type::typeinfo->type->irtype->getType(); + else + irg->type = LLStructType::create(gIR->context(), tid->toPrettyChars()); std::string mangle(tid->mangle()); irg->value = gIR->module->getGlobalVariable(mangle); if (!irg->value) - irg->value = new llvm::GlobalVariable(*gIR->module, irg->type.get(), true, + irg->value = new llvm::GlobalVariable(*gIR->module, irg->type, true, TYPEINFO_LINKAGE_TYPE, NULL, mangle); tid->ir.irGlobal = irg; @@ -360,9 +364,6 @@ void DtoDeclareTypeInfo(TypeInfoDeclaration* tid) // this is a declaration of a builtin __initZ var if (tid->tinfo->builtinTypeInfo()) { - // fixup the global - const llvm::Type* rty = Type::typeinfo->type->irtype->getPA(); - llvm::cast(irg->type.get())->refineAbstractTypeTo(rty); LLGlobalVariable* g = isaGlobalVar(irg->value); g->setLinkage(llvm::GlobalValue::ExternalLinkage); return; @@ -446,7 +447,7 @@ void TypeInfoEnumDeclaration::llvmDefine() // otherwise emit a void[] with the default initializer else { - const LLType* memty = DtoType(sd->memtype); + LLType* memty = DtoType(sd->memtype); #if DMDV2 LLConstant* C = LLConstantInt::get(memty, sd->defaultval->toInteger(), !sd->memtype->isunsigned()); #else @@ -611,7 +612,7 @@ void TypeInfoStructDeclaration::llvmDefine() // void[] init // never emit a null array, even for zero initialized typeinfo // the size() method uses this array! - size_t init_size = getTypeStoreSize(tc->irtype->getPA()); + size_t init_size = getTypeStoreSize(tc->irtype->getType()); b.push_void_array(init_size, irstruct->getInitSymbol()); // toX functions ground work @@ -802,7 +803,7 @@ void TypeInfoTupleDeclaration::llvmDefine() std::vector arrInits; arrInits.reserve(dim); - const LLType* tiTy = DtoType(Type::typeinfo->type); + LLType* tiTy = DtoType(Type::typeinfo->type); for (size_t i = 0; i < dim; i++) { @@ -811,7 +812,7 @@ void TypeInfoTupleDeclaration::llvmDefine() } // build array - const LLArrayType* arrTy = LLArrayType::get(tiTy, dim); + LLArrayType* arrTy = LLArrayType::get(tiTy, dim); LLConstant* arrC = LLConstantArray::get(arrTy, arrInits); RTTIBuilder b(Type::typeinfotypelist); diff --git a/ir/irclass.cpp b/ir/irclass.cpp index 4890b6d9..94d41e40 100644 --- a/ir/irclass.cpp +++ b/ir/irclass.cpp @@ -38,7 +38,7 @@ LLGlobalVariable * IrStruct::getVtblSymbol() llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(aggrdecl); - const LLType* vtblTy = stripModifiers(type)->irtype->isClass()->getVtbl(); + LLType* vtblTy = stripModifiers(type)->irtype->isClass()->getVtbl(); vtbl = new llvm::GlobalVariable( *gIR->module, vtblTy, true, _linkage, NULL, initname); @@ -71,15 +71,15 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol() // classinfos cannot be constants since they're used a locks for synchronized classInfo = new llvm::GlobalVariable( - *gIR->module, tc->getPA().get(), false, _linkage, NULL, initname); + *gIR->module, tc->getType(), false, _linkage, NULL, initname); #if USE_METADATA // Generate some metadata on this ClassInfo if it's for a class. ClassDeclaration* classdecl = aggrdecl->isClassDeclaration(); if (classdecl && !aggrdecl->isInterfaceDeclaration()) { // Gather information - const LLType* type = DtoType(aggrdecl->type); - const LLType* bodyType = llvm::cast(type)->getElementType(); + LLType* type = DtoType(aggrdecl->type); + LLType* bodyType = llvm::cast(type)->getElementType(); bool hasDestructor = (classdecl->dtor != NULL); bool hasCustomDelete = (classdecl->aggDelete != NULL); // Construct the fields @@ -112,10 +112,10 @@ LLGlobalVariable * IrStruct::getInterfaceArraySymbol() "don't implement any interfaces"); VarDeclarationIter idx(ClassDeclaration::classinfo->fields, 3); - const llvm::Type* InterfaceTy = DtoType(idx->type->nextOf()); + LLType* InterfaceTy = DtoType(idx->type->nextOf()); // create Interface[N] - const llvm::ArrayType* array_type = llvm::ArrayType::get(InterfaceTy,n); + LLArrayType* array_type = llvm::ArrayType::get(InterfaceTy,n); // put it in a global std::string name("_D"); @@ -202,17 +202,18 @@ LLConstant * IrStruct::getVtblInit() } // build the constant struct - constVtbl = LLConstantStruct::get(gIR->context(), constants, false); + LLType* vtblTy = stripModifiers(type)->irtype->isClass()->getVtbl(); + constVtbl = LLConstantStruct::get(isaStruct(vtblTy), constants); #if 0 IF_LOG Logger::cout() << "constVtbl type: " << *constVtbl->getType() << std::endl; IF_LOG Logger::cout() << "vtbl type: " << *stripModifiers(type)->irtype->isClass()->getVtbl() << std::endl; #endif -#if 1 +#if 0 size_t nc = constants.size(); - const LLType* vtblTy = stripModifiers(type)->irtype->isClass()->getVtbl(); + for (size_t i = 0; i < nc; ++i) { if (constVtbl->getOperand(i)->getType() != vtblTy->getContainedType(i)) @@ -220,7 +221,7 @@ LLConstant * IrStruct::getVtblInit() Logger::cout() << "type mismatch for entry # " << i << " in vtbl initializer" << std::endl; constVtbl->getOperand(i)->dump(); - vtblTy->getContainedType(i)->dump(gIR->module); + vtblTy->getContainedType(i)->dump(); } } @@ -307,18 +308,11 @@ void IrStruct::addBaseClassInits( inter_idx++; } } - - // tail padding? - if (offset < base->structsize) - { - add_zeros(constants, base->structsize - offset); - offset = base->structsize; - } } ////////////////////////////////////////////////////////////////////////////// -LLConstant * IrStruct::createClassDefaultInitializer() +std::vector IrStruct::createClassDefaultInitializer() { ClassDeclaration* cd = aggrdecl->isClassDeclaration(); assert(cd && "invalid class aggregate"); @@ -345,10 +339,11 @@ LLConstant * IrStruct::createClassDefaultInitializer() // add data members recursively addBaseClassInits(constants, cd, offset, field_index); - // build the constant - llvm::Constant* definit = LLConstantStruct::get(gIR->context(), constants, false); + // tail padding? + if (offset < cd->structsize) + add_zeros(constants, cd->structsize - offset); - return definit; + return constants; } ////////////////////////////////////////////////////////////////////////////// @@ -413,7 +408,7 @@ llvm::GlobalVariable * IrStruct::getInterfaceVtbl(BaseClass * b, bool new_instan } // build the vtbl constant - llvm::Constant* vtbl_constant = LLConstantStruct::get(gIR->context(), constants, false); + llvm::Constant* vtbl_constant = LLConstantStruct::getAnon(gIR->context(), constants, false); // create the global variable to hold it llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(aggrdecl); @@ -470,9 +465,12 @@ LLConstant * IrStruct::getClassInfoInterfaces() LLSmallVector constants; constants.reserve(cd->vtblInterfaces->dim); - const LLType* classinfo_type = DtoType(ClassDeclaration::classinfo->type); - const LLType* voidptrptr_type = DtoType( + LLType* classinfo_type = DtoType(ClassDeclaration::classinfo->type); + LLType* voidptrptr_type = DtoType( Type::tvoid->pointerTo()->pointerTo()); + VarDeclarationIter idx(ClassDeclaration::classinfo->fields, 3); + LLStructType* interface_type = isaStruct(DtoType(idx->type->nextOf())); + assert(interface_type); for (size_t i = 0; i < n; ++i) { @@ -510,21 +508,15 @@ LLConstant * IrStruct::getClassInfoInterfaces() // create Interface struct LLConstant* inits[3] = { ci, vtb, off }; - LLConstant* entry = LLConstantStruct::get(gIR->context(), inits, 3, false); + LLConstant* entry = LLConstantStruct::get(interface_type, llvm::makeArrayRef(inits, 3)); constants.push_back(entry); } // create Interface[N] - const llvm::ArrayType* array_type = llvm::ArrayType::get( - constants[0]->getType(), - n); + LLArrayType* array_type = llvm::ArrayType::get(interface_type, n); - LLConstant* arr = LLConstantArray::get( - array_type, - &constants[0], - n); - - // apply the initializer + // create and apply initializer + LLConstant* arr = LLConstantArray::get(array_type, constants); classInterfacesArray->setInitializer(arr); // return null, only baseclass provide interfaces diff --git a/ir/irfunction.h b/ir/irfunction.h index 2bc13243..3393c4a7 100644 --- a/ir/irfunction.h +++ b/ir/irfunction.h @@ -89,7 +89,7 @@ struct IrFunction : IrBase llvm::Value* nestArg; // nested function 'this' arg llvm::Value* nestedVar; // nested var alloca - const llvm::StructType* frameType; // type of nested context (not for -nested-ctx=array) + llvm::StructType* frameType; // type of nested context (not for -nested-ctx=array) // number of enclosing functions with variables accessed by nested functions // (-1 if neither this function nor any enclosing ones access variables from enclosing functions) int depth; diff --git a/ir/irfuncty.h b/ir/irfuncty.h index c34eb0b9..8e698181 100644 --- a/ir/irfuncty.h +++ b/ir/irfuncty.h @@ -23,7 +23,7 @@ struct IrFuncTyArg : IrBase Type* type; /// This is the final LLVM Type used for the parameter/return value type - const llvm::Type* ltype; + llvm::Type* ltype; /** These are the final LLVM attributes used for the function. * Must be valid for the LLVM Type and byref setting */ diff --git a/ir/irlandingpad.cpp b/ir/irlandingpad.cpp index 9f769b07..93da79be 100644 --- a/ir/irlandingpad.cpp +++ b/ir/irlandingpad.cpp @@ -105,57 +105,20 @@ void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB) IRScope savedscope = gIR->scope(); gIR->scope() = IRScope(inBB,savedscope.end); - // eh_ptr = llvm.eh.exception(); - llvm::Function* eh_exception_fn = GET_INTRINSIC_DECL(eh_exception); - LLValue* eh_ptr = gIR->ir->CreateCall(eh_exception_fn); - - // build selector arguments - LLSmallVector selectorargs; - - // put in classinfos in the right order - bool hasFinally = false; - bool hasCatch = false; - std::deque::iterator it = infos.begin(), end = infos.end(); - for(; it != end; ++it) - { - if(it->finallyBody) - hasFinally = true; - else - { - hasCatch = true; - assert(it->catchType); - assert(it->catchType->ir.irStruct); - selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->getClassInfoSymbol()); - } - } - // if there's a finally, the eh table has to have a 0 action - if(hasFinally) - selectorargs.push_back(DtoConstUint(0)); - // personality fn llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality"); - LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::getInt8Ty(gIR->context()))); - selectorargs.insert(selectorargs.begin(), personality_fn_arg); + // create landingpad + LLType *retType = LLStructType::get(LLType::getInt8PtrTy(gIR->context()), LLType::getInt32Ty(gIR->context()), NULL); + llvm::LandingPadInst *landingPad = gIR->ir->CreateLandingPad(retType, personality_fn, 0); + LLValue* eh_ptr = DtoExtractValue(landingPad, 0); + LLValue* eh_sel = DtoExtractValue(landingPad, 1); - // eh storage target - selectorargs.insert(selectorargs.begin(), eh_ptr); - - // if there is a catch and some catch allocated storage, store exception object - if(hasCatch && catch_var) - { - const LLType* objectTy = DtoType(ClassDeclaration::object->type); - gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var); - } - - // eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, ); - llvm::Function* eh_selector_fn = GET_INTRINSIC_DECL(eh_selector); - LLValue* eh_sel = gIR->ir->CreateCall(eh_selector_fn, selectorargs.begin(), selectorargs.end()); - - // emit finallys and 'if' chain to catch the exception + // add landingpad clauses, emit finallys and 'if' chain to catch the exception llvm::Function* eh_typeid_for_fn = GET_INTRINSIC_DECL(eh_typeid_for); std::deque infos = this->infos; std::stack nInfos = this->nInfos; std::deque::reverse_iterator rit, rend = infos.rend(); + bool isFirstCatch = true; for(rit = infos.rbegin(); rit != rend; ++rit) { // if it's a finally, emit its code @@ -165,14 +128,28 @@ void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB) this->infos.resize(n); this->nInfos.pop(); rit->finallyBody->toIR(gIR); + landingPad->setCleanup(true); } // otherwise it's a catch and we'll add a if-statement else { + // if it is a first catch and some catch allocated storage, store exception object + if(isFirstCatch && catch_var) + { + LLType* objectTy = DtoType(ClassDeclaration::object->type); + gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var); + isFirstCatch = false; + } + // create next block llvm::BasicBlock *next = llvm::BasicBlock::Create(gIR->context(), "eh.next", gIR->topfunc(), gIR->scopeend()); - LLValue *classInfo = DtoBitCast(rit->catchType->ir.irStruct->getClassInfoSymbol(), - getPtrToType(DtoType(Type::tint8))); + // get class info symbol + LLValue *classInfo = rit->catchType->ir.irStruct->getClassInfoSymbol(); + // add that symbol as landing pad clause + landingPad->addClause(classInfo); + // call llvm.eh.typeid.for to get class info index in the exception table + classInfo = DtoBitCast(classInfo, getPtrToType(DtoType(Type::tint8))); LLValue *eh_id = gIR->ir->CreateCall(eh_typeid_for_fn, classInfo); + // check exception selector (eh_sel) against the class info index gIR->ir->CreateCondBr(gIR->ir->CreateICmpEQ(eh_sel, eh_id), rit->target, next); gIR->scope() = IRScope(next, gIR->scopeend()); } @@ -187,6 +164,7 @@ void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB) gIR->ir->CreateCall(unwind_resume_fn, eh_ptr); gIR->ir->CreateUnreachable(); + // restore scope gIR->scope() = savedscope; } diff --git a/ir/irstruct.cpp b/ir/irstruct.cpp index 118bdca5..5befa67c 100644 --- a/ir/irstruct.cpp +++ b/ir/irstruct.cpp @@ -20,7 +20,7 @@ IrStruct::IrStruct(AggregateDeclaration* aggr) : diCompositeType(NULL), - init_pa(llvm::OpaqueType::get(gIR->context())) + init_type(LLStructType::create(gIR->context(), std::string(aggr->toPrettyChars()) + "_init")) { aggrdecl = aggr; @@ -58,7 +58,7 @@ LLGlobalVariable * IrStruct::getInitSymbol() llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(aggrdecl); init = new llvm::GlobalVariable( - *gIR->module, init_pa.get(), true, _linkage, NULL, initname); + *gIR->module, init_type, true, _linkage, NULL, initname); // set alignment init->setAlignment(type->alignsize()); @@ -73,17 +73,20 @@ llvm::Constant * IrStruct::getDefaultInit() if (constInit) return constInit; - if (type->ty == Tstruct) - { - constInit = createStructDefaultInitializer(); - } - else - { - constInit = createClassDefaultInitializer(); - } + std::vector constants = type->ty == Tstruct ? + createStructDefaultInitializer() : + createClassDefaultInitializer(); - llvm::OpaqueType* o = llvm::cast(init_pa.get()); - o->refineAbstractTypeTo(constInit->getType()); + // set initializer type body + std::vector types; + std::vector::iterator itr = constants.begin(), end = constants.end(); + for (; itr != end; ++itr) + types.push_back((*itr)->getType()); + init_type->setBody(types, packed); + + // build constant struct + constInit = LLConstantStruct::get(init_type, constants); + IF_LOG Logger::cout() << "final default initializer: " << *constInit << std::endl; return constInit; } @@ -142,7 +145,7 @@ size_t add_zeros(std::vector& constants, size_t diff) // Matches the way the type is built in IrTypeStruct // maybe look at unifying the interface. -LLConstant * IrStruct::createStructDefaultInitializer() +std::vector IrStruct::createStructDefaultInitializer() { IF_LOG Logger::println("Building default initializer for %s", aggrdecl->toPrettyChars()); LOG_SCOPE; @@ -195,13 +198,7 @@ LLConstant * IrStruct::createStructDefaultInitializer() add_zeros(constants, aggrdecl->structsize - offset); } - // build constant struct - llvm::Constant* definit = LLConstantStruct::get(gIR->context(), constants, packed); -#if 0 - IF_LOG Logger::cout() << "final default initializer: " << *definit << std::endl; -#endif - - return definit; + return constants; } ////////////////////////////////////////////////////////////////////////////// @@ -383,9 +380,22 @@ LLConstant * IrStruct::createStructInitializer(StructInitializer * si) add_zeros(constants, diff); } + // get initializer type + LLStructType* <ype = si->ltype; + if (!ltype || ltype->isOpaque()) { + std::vector::iterator itr, end = constants.end(); + std::vector types; + for (itr = constants.begin(); itr != end; ++itr) + types.push_back((*itr)->getType()); + if (!ltype) + ltype = LLStructType::get(gIR->context(), types); + else + ltype->setBody(types); + } + // build constant assert(!constants.empty()); - llvm::Constant* c = LLConstantStruct::get(gIR->context(), &constants[0], constants.size(), packed); + llvm::Constant* c = LLConstantStruct::get(ltype, constants); IF_LOG Logger::cout() << "final struct initializer: " << *c << std::endl; return c; } diff --git a/ir/irstruct.h b/ir/irstruct.h index 1fbe9cd0..49faf2c5 100644 --- a/ir/irstruct.h +++ b/ir/irstruct.h @@ -65,19 +65,19 @@ struct IrStruct : IrBase ////////////////////////////////////////////////////////////////////////// protected: /// Static default initializer global. - llvm::GlobalVariable* init; + LLGlobalVariable* init; /// Static default initializer constant. LLConstant* constInit; - /// Static default initialier type holder. - llvm::PATypeHolder init_pa; + /// Static default initialier type. + LLStructType* init_type; /// Vtbl global. - llvm::GlobalVariable* vtbl; + LLGlobalVariable* vtbl; /// Vtbl initializer constant. LLConstant* constVtbl; /// ClassInfo global. - llvm::GlobalVariable* classInfo; + LLGlobalVariable* classInfo; /// ClassInfo initializer constant. LLConstant* constClassInfo; @@ -102,10 +102,10 @@ protected: ////////////////////////////////////////////////////////////////////////// /// Create static default initializer for struct. - LLConstant* createStructDefaultInitializer(); + std::vector createStructDefaultInitializer(); /// Create static default initializer for class. - LLConstant* createClassDefaultInitializer(); + std::vector createClassDefaultInitializer(); /// Returns vtbl for interface implementation, creates it if not already built. llvm::GlobalVariable* getInterfaceVtbl( diff --git a/ir/irtype.cpp b/ir/irtype.cpp index f3886858..92833314 100644 --- a/ir/irtype.cpp +++ b/ir/irtype.cpp @@ -11,14 +11,14 @@ ////////////////////////////////////////////////////////////////////////////// -extern const llvm::Type* DtoType(Type* dt); -extern const llvm::Type* DtoSize_t(); +extern LLType* DtoType(Type* dt); +extern LLType* DtoSize_t(); ////////////////////////////////////////////////////////////////////////////// -IrType::IrType(Type* dt, const llvm::Type* lt) +IrType::IrType(Type* dt, LLType* lt) : dtype(dt), - pa(lt) + type(lt) { assert(dt && "null D Type"); assert(lt && "null LLVM Type"); @@ -39,16 +39,26 @@ IrTypeBasic::IrTypeBasic(Type * dt) ////////////////////////////////////////////////////////////////////////////// -const llvm::Type * IrTypeBasic::buildType() +llvm::Type * IrTypeBasic::buildType() { - return pa.get(); + return type; } ////////////////////////////////////////////////////////////////////////////// -const llvm::Type * IrTypeBasic::basic2llvm(Type* t) +LLType* IrTypeBasic::getComplexType(llvm::LLVMContext& ctx, LLType* type) { - const llvm::Type* t2; + llvm::SmallVector types; + types.push_back(type); + types.push_back(type); + return llvm::StructType::get(ctx, types); +} + +////////////////////////////////////////////////////////////////////////////// + +llvm::Type * IrTypeBasic::basic2llvm(Type* t) +{ + LLType* t2; llvm::LLVMContext& ctx = llvm::getGlobalContext(); @@ -99,19 +109,20 @@ const llvm::Type * IrTypeBasic::basic2llvm(Type* t) else return llvm::Type::getDoubleTy(ctx); - case Tcomplex32: + case Tcomplex32: { t2 = llvm::Type::getFloatTy(ctx); - return llvm::StructType::get(ctx, t2, t2, NULL); + return getComplexType(ctx, t2); + } case Tcomplex64: t2 = llvm::Type::getDoubleTy(ctx); - return llvm::StructType::get(ctx, t2, t2, NULL); + return getComplexType(ctx, t2); case Tcomplex80: t2 = (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) ? llvm::Type::getX86_FP80Ty(ctx) : llvm::Type::getDoubleTy(ctx); - return llvm::StructType::get(ctx, t2, t2, NULL); + return getComplexType(ctx, t2); case Tbool: return llvm::Type::getInt1Ty(ctx); @@ -126,26 +137,24 @@ const llvm::Type * IrTypeBasic::basic2llvm(Type* t) ////////////////////////////////////////////////////////////////////////////// IrTypePointer::IrTypePointer(Type * dt) -: IrType(dt, llvm::OpaqueType::get(llvm::getGlobalContext())) +: IrType(dt, pointer2llvm(dt)) { } ////////////////////////////////////////////////////////////////////////////// -const llvm::Type * IrTypePointer::buildType() +llvm::Type * IrTypePointer::buildType() { - llvm::cast(pa.get())->refineAbstractTypeTo( - pointer2llvm(dtype)); - return pa.get(); + return type; } ////////////////////////////////////////////////////////////////////////////// -const llvm::Type * IrTypePointer::pointer2llvm(Type * dt) +llvm::Type * IrTypePointer::pointer2llvm(Type * dt) { assert(dt->ty == Tpointer && "not pointer type"); - const llvm::Type* elemType = DtoType(dt->nextOf()); + LLType* elemType = DtoType(dt->nextOf()); if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext())) elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext()); return llvm::PointerType::get(elemType, 0); @@ -156,27 +165,25 @@ const llvm::Type * IrTypePointer::pointer2llvm(Type * dt) ////////////////////////////////////////////////////////////////////////////// IrTypeSArray::IrTypeSArray(Type * dt) -: IrType(dt, llvm::OpaqueType::get(llvm::getGlobalContext())) +: IrType(dt, sarray2llvm(dt)) { - assert(dt->ty == Tsarray && "not static array type"); - TypeSArray* tsa = (TypeSArray*)dt; +} + +////////////////////////////////////////////////////////////////////////////// + +llvm::Type * IrTypeSArray::buildType() +{ + return type; +} + +////////////////////////////////////////////////////////////////////////////// + +llvm::Type * IrTypeSArray::sarray2llvm(Type * t) +{ + assert(t->ty == Tsarray && "not static array type"); + TypeSArray* tsa = (TypeSArray*)t; dim = (uint64_t)tsa->dim->toUInteger(); -} - -////////////////////////////////////////////////////////////////////////////// - -const llvm::Type * IrTypeSArray::buildType() -{ - llvm::cast(pa.get())->refineAbstractTypeTo( - sarray2llvm(dtype)); - return pa.get(); -} - -////////////////////////////////////////////////////////////////////////////// - -const llvm::Type * IrTypeSArray::sarray2llvm(Type * t) -{ - const llvm::Type* elemType = DtoType(t->nextOf()); + LLType* elemType = DtoType(t->nextOf()); if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext())) elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext()); return llvm::ArrayType::get(elemType, dim == 0 ? 1 : dim); @@ -187,36 +194,34 @@ const llvm::Type * IrTypeSArray::sarray2llvm(Type * t) ////////////////////////////////////////////////////////////////////////////// IrTypeArray::IrTypeArray(Type * dt) -: IrType(dt, llvm::OpaqueType::get(llvm::getGlobalContext())) +: IrType(dt, array2llvm(dt)) { } ////////////////////////////////////////////////////////////////////////////// -const llvm::Type * IrTypeArray::buildType() +llvm::Type * IrTypeArray::buildType() { - llvm::cast(pa.get())->refineAbstractTypeTo( - array2llvm(dtype)); - return pa.get(); + return type; } ////////////////////////////////////////////////////////////////////////////// -const llvm::Type * IrTypeArray::array2llvm(Type * t) +llvm::Type * IrTypeArray::array2llvm(Type * t) { assert(t->ty == Tarray && "not dynamic array type"); // get .ptr type - const llvm::Type* elemType = DtoType(t->nextOf()); + LLType* elemType = DtoType(t->nextOf()); if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext())) elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext()); elemType = llvm::PointerType::get(elemType, 0); // create struct type - const llvm::Type* at = llvm::StructType::get(llvm::getGlobalContext(), DtoSize_t(), elemType, NULL); - - // name dynamic array types - Type::sir->getState()->module->addTypeName(t->toChars(), at); + llvm::SmallVector types; + types.push_back(DtoSize_t()); + types.push_back(elemType); + LLType* at = llvm::StructType::get(llvm::getGlobalContext(), types/*, t->toChars()*/); return at; } diff --git a/ir/irtype.h b/ir/irtype.h index 507c46e5..c90ffcc8 100644 --- a/ir/irtype.h +++ b/ir/irtype.h @@ -26,7 +26,7 @@ class IrType { public: /// - IrType(Type* dt, const llvm::Type* lt); + IrType(Type* dt, llvm::Type* lt); /// virtual IrTypeAggr* isAggr() { return NULL; } @@ -50,19 +50,19 @@ public: /// Type* getD() { return dtype; } /// - virtual const llvm::Type* get() { return pa.get(); } + virtual llvm::Type* get() { return type; } /// - llvm::PATypeHolder& getPA() { return pa; } + llvm::Type* getType() { return type; } /// - virtual const llvm::Type* buildType() = 0; + virtual llvm::Type* buildType() = 0; protected: /// Type* dtype; - /// LLVM type holder. - llvm::PATypeHolder pa; + /// LLVM type. + llvm::Type* type; }; ////////////////////////////////////////////////////////////////////////////// @@ -78,11 +78,13 @@ public: IrTypeBasic* isBasic() { return this; } /// - const llvm::Type* buildType(); + llvm::Type* buildType(); protected: /// - const llvm::Type* basic2llvm(Type* t); + LLType* getComplexType(llvm::LLVMContext& ctx, LLType* type); + /// + llvm::Type* basic2llvm(Type* t); }; ////////////////////////////////////////////////////////////////////////////// @@ -98,11 +100,11 @@ public: IrTypePointer* isPointer() { return this; } /// - const llvm::Type* buildType(); + llvm::Type* buildType(); protected: /// - const llvm::Type* pointer2llvm(Type* t); + llvm::Type* pointer2llvm(Type* t); }; ////////////////////////////////////////////////////////////////////////////// @@ -118,11 +120,11 @@ public: IrTypeSArray* isSArray() { return this; } /// - const llvm::Type* buildType(); + llvm::Type* buildType(); protected: /// - const llvm::Type* sarray2llvm(Type* t); + llvm::Type* sarray2llvm(Type* t); /// Dimension. uint64_t dim; @@ -141,11 +143,11 @@ public: IrTypeArray* isArray() { return this; } /// - const llvm::Type* buildType(); + llvm::Type* buildType(); protected: /// - const llvm::Type* array2llvm(Type* t); + llvm::Type* array2llvm(Type* t); }; ////////////////////////////////////////////////////////////////////////////// diff --git a/ir/irtypeclass.cpp b/ir/irtypeclass.cpp index 2d66fdd5..53cf321e 100644 --- a/ir/irtypeclass.cpp +++ b/ir/irtypeclass.cpp @@ -14,7 +14,7 @@ ////////////////////////////////////////////////////////////////////////////// -extern size_t add_zeros(std::vector& defaultTypes, size_t diff); +extern size_t add_zeros(std::vector& defaultTypes, size_t diff); extern bool var_offset_sort_cb(const VarDeclaration* v1, const VarDeclaration* v2); ////////////////////////////////////////////////////////////////////////////// @@ -22,9 +22,11 @@ extern bool var_offset_sort_cb(const VarDeclaration* v1, const VarDeclaration* v IrTypeClass::IrTypeClass(ClassDeclaration* cd) : IrTypeAggr(cd), cd(cd), - tc((TypeClass*)cd->type), - vtbl_pa(llvm::OpaqueType::get(gIR->context())) + tc((TypeClass*)cd->type) { + std::string vtbl_name(cd->toPrettyChars()); + vtbl_name.append(".__vtbl"); + vtbl_type = LLStructType::create(gIR->context(), vtbl_name); vtbl_size = cd->vtbl.dim; num_interface_vtbls = 0; } @@ -32,7 +34,7 @@ IrTypeClass::IrTypeClass(ClassDeclaration* cd) ////////////////////////////////////////////////////////////////////////////// void IrTypeClass::addBaseClassData( - std::vector< const llvm::Type * > & defaultTypes, + std::vector & defaultTypes, ClassDeclaration * base, size_t & offset, size_t & field_index) @@ -184,7 +186,7 @@ void IrTypeClass::addBaseClassData( FuncDeclarations arr; b->fillVtbl(cd, &arr, new_instances); - const llvm::Type* ivtbl_type = buildVtblType(first, &arr); + llvm::Type* ivtbl_type = llvm::StructType::get(gIR->context(), buildVtblType(first, &arr)); defaultTypes.push_back(llvm::PointerType::get(ivtbl_type, 0)); offset += PTRSIZE; @@ -210,7 +212,7 @@ void IrTypeClass::addBaseClassData( ////////////////////////////////////////////////////////////////////////////// -const llvm::Type* IrTypeClass::buildType() +llvm::Type* IrTypeClass::buildType() { IF_LOG Logger::println("Building class type %s @ %s", cd->toPrettyChars(), cd->loc.toChars()); LOG_SCOPE; @@ -219,11 +221,11 @@ const llvm::Type* IrTypeClass::buildType() // find the fields that contribute to the default initializer. // these will define the default type. - std::vector defaultTypes; + std::vector defaultTypes; defaultTypes.reserve(32); // add vtbl - defaultTypes.push_back(llvm::PointerType::get(vtbl_pa.get(), 0)); + defaultTypes.push_back(llvm::PointerType::get(vtbl_type, 0)); // interfaces are just a vtable if (cd->isInterfaceDeclaration()) @@ -257,43 +259,27 @@ const llvm::Type* IrTypeClass::buildType() if (global.errors) fatal(); - // build the llvm type - const llvm::Type* st = llvm::StructType::get(gIR->context(), defaultTypes, false); - - // refine type - llvm::cast(pa.get())->refineAbstractTypeTo(st); - - // name type - Type::sir->getState()->module->addTypeName(cd->toPrettyChars(), pa.get()); + // set struct body + isaStruct(type)->setBody(defaultTypes, false); // VTBL - // build vtbl type - const llvm::Type* vtblty = buildVtblType( - ClassDeclaration::classinfo->type, - &cd->vtbl); + // set vtbl type body + vtbl_type->setBody(buildVtblType(ClassDeclaration::classinfo->type, &cd->vtbl)); - // refine vtbl pa - llvm::cast(vtbl_pa.get())->refineAbstractTypeTo(vtblty); - - // name vtbl type - std::string name(cd->toPrettyChars()); - name.append(".__vtbl"); - Type::sir->getState()->module->addTypeName(name, vtbl_pa.get()); - - IF_LOG Logger::cout() << "class type: " << *pa.get() << std::endl; + IF_LOG Logger::cout() << "class type: " << *type << std::endl; return get(); } ////////////////////////////////////////////////////////////////////////////// -const llvm::Type* IrTypeClass::buildVtblType(Type* first, Array* vtbl_array) +std::vector IrTypeClass::buildVtblType(Type* first, Array* vtbl_array) { IF_LOG Logger::println("Building vtbl type for class %s", cd->toPrettyChars()); LOG_SCOPE; - std::vector types; + std::vector types; types.reserve(vtbl_array->dim); // first comes the classinfo @@ -323,15 +309,14 @@ const llvm::Type* IrTypeClass::buildVtblType(Type* first, Array* vtbl_array) types.push_back(DtoType(fd->type->pointerTo())); } - // build the vtbl llvm type - return llvm::StructType::get(gIR->context(), types, false); + return types; } ////////////////////////////////////////////////////////////////////////////// -const llvm::Type * IrTypeClass::get() +llvm::Type * IrTypeClass::get() { - return llvm::PointerType::get(pa.get(), 0); + return llvm::PointerType::get(type, 0); } ////////////////////////////////////////////////////////////////////////////// diff --git a/ir/irtypeclass.h b/ir/irtypeclass.h index 0edb30c8..8459b6d8 100644 --- a/ir/irtypeclass.h +++ b/ir/irtypeclass.h @@ -2,6 +2,7 @@ #define __LDC_IR_IRTYPECLASS_H__ #include "ir/irtypestruct.h" +#include /// class IrTypeClass : public IrTypeAggr @@ -14,13 +15,13 @@ public: virtual IrTypeClass* isClass() { return this; } /// - const llvm::Type* buildType(); + llvm::Type* buildType(); /// - const llvm::Type* get(); + llvm::Type* get(); /// Returns the vtable type for this class. - const llvm::Type* getVtbl() { return vtbl_pa.get(); } + llvm::Type* getVtbl() { return vtbl_type; } /// Get index to interface implementation. /// Returns the index of a specific interface implementation in this @@ -40,8 +41,8 @@ protected: /// TypeClass* tc; - /// Type holder for the vtable type. - llvm::PATypeHolder vtbl_pa; + /// Vtable type. + llvm::StructType *vtbl_type; /// Number of pointers in vtable. unsigned vtbl_size; @@ -60,11 +61,11 @@ protected: /// Builds a vtable type given the type of the first entry and an array /// of all entries. - const llvm::Type* buildVtblType(Type* first, Array* vtbl_array); + std::vector buildVtblType(Type* first, Array* vtbl_array); /// void addBaseClassData( - std::vector& defaultTypes, + std::vector& defaultTypes, ClassDeclaration* base, size_t& offset, size_t& field_index); diff --git a/ir/irtypefunction.cpp b/ir/irtypefunction.cpp index afea1567..3ac0085a 100644 --- a/ir/irtypefunction.cpp +++ b/ir/irtypefunction.cpp @@ -7,41 +7,47 @@ #include "ir/irtypefunction.h" -IrTypeFunction::IrTypeFunction(Type * dt) -: IrType(dt, llvm::OpaqueType::get(gIR->context())) +IrTypeFunction::IrTypeFunction(Type* dt) +: IrType(dt, func2llvm(dt)) { irfty = NULL; } -const llvm::Type * IrTypeFunction::buildType() +llvm::Type * IrTypeFunction::buildType() { - const llvm::Type* T; - TypeFunction* tf = (TypeFunction*)dtype; + return type; +} + +llvm::Type* IrTypeFunction::func2llvm(Type* dt) +{ + llvm::Type* T; + TypeFunction* tf = (TypeFunction*)dt; if (tf->funcdecl) T = DtoFunctionType(tf->funcdecl); else T = DtoFunctionType(tf,NULL,NULL); - - llvm::cast(pa.get())->refineAbstractTypeTo(T); - return pa.get(); + return T; } ////////////////////////////////////////////////////////////////////////////// IrTypeDelegate::IrTypeDelegate(Type * dt) -: IrType(dt, llvm::OpaqueType::get(gIR->context())) +: IrType(dt, delegate2llvm(dt)) { } -const llvm::Type * IrTypeDelegate::buildType() +llvm::Type* IrTypeDelegate::buildType() { - assert(dtype->ty == Tdelegate); - const LLType* i8ptr = getVoidPtrType(); - const LLType* func = DtoFunctionType(dtype->nextOf(), NULL, Type::tvoid->pointerTo()); - const LLType* funcptr = getPtrToType(func); - const LLStructType* dgtype = LLStructType::get(gIR->context(), i8ptr, funcptr, NULL); - gIR->module->addTypeName(dtype->toChars(), dgtype); - - llvm::cast(pa.get())->refineAbstractTypeTo(dgtype); - return pa.get(); + return type; +} + +llvm::Type* IrTypeDelegate::delegate2llvm(Type* dt) +{ + assert(dt->ty == Tdelegate); + LLType* func = DtoFunctionType(dt->nextOf(), NULL, Type::tvoid->pointerTo()); + llvm::SmallVector types; + types.push_back(getVoidPtrType()); + types.push_back(getPtrToType(func)); + LLStructType* dgtype = LLStructType::get(gIR->context(), types); + return dgtype; } diff --git a/ir/irtypefunction.h b/ir/irtypefunction.h index d987c6c6..14bfda5c 100644 --- a/ir/irtypefunction.h +++ b/ir/irtypefunction.h @@ -16,11 +16,12 @@ public: IrTypeFunction* isFunction() { return this; } /// - const llvm::Type* buildType(); + llvm::Type* buildType(); IrFuncTy* fty() { return irfty; } protected: + llvm::Type* func2llvm(Type* dt); /// IrFuncTy* irfty; }; @@ -36,7 +37,9 @@ public: IrTypeDelegate* isDelegate() { return this; } /// - const llvm::Type* buildType(); + llvm::Type* buildType(); +protected: + llvm::Type* delegate2llvm(Type* dt); }; #endif diff --git a/ir/irtypestruct.cpp b/ir/irtypestruct.cpp index 926a1e0e..55b7d165 100644 --- a/ir/irtypestruct.cpp +++ b/ir/irtypestruct.cpp @@ -17,7 +17,7 @@ ////////////////////////////////////////////////////////////////////////////// IrTypeAggr::IrTypeAggr(AggregateDeclaration * ad) -: IrType(ad->type, llvm::OpaqueType::get(gIR->context())), +: IrType(ad->type, LLStructType::create(gIR->context(), ad->toPrettyChars())), aggr(ad) { } @@ -35,7 +35,7 @@ IrTypeStruct::IrTypeStruct(StructDeclaration * sd) ////////////////////////////////////////////////////////////////////////////// -size_t add_zeros(std::vector& defaultTypes, size_t diff) +size_t add_zeros(std::vector& defaultTypes, size_t diff) { size_t n = defaultTypes.size(); while (diff) @@ -75,7 +75,7 @@ bool var_offset_sort_cb(const VarDeclaration* v1, const VarDeclaration* v2) // this is pretty much the exact same thing we need to do for fields in each // base class of a class -const llvm::Type* IrTypeStruct::buildType() +llvm::Type* IrTypeStruct::buildType() { IF_LOG Logger::println("Building struct type %s @ %s", sd->toPrettyChars(), sd->loc.toChars()); @@ -83,7 +83,7 @@ const llvm::Type* IrTypeStruct::buildType() // if it's a forward declaration, all bets are off, stick with the opaque if (sd->sizeok != 1) - return pa.get(); + return type; // mirror the sd->fields array but only fill in contributors size_t n = sd->fields.dim; @@ -166,7 +166,7 @@ const llvm::Type* IrTypeStruct::buildType() } // ok. now we can build a list of llvm types. and make sure zeros are inserted if necessary. - std::vector defaultTypes; + std::vector defaultTypes; defaultTypes.reserve(16); size_t offset = 0; @@ -219,18 +219,12 @@ const llvm::Type* IrTypeStruct::buildType() add_zeros(defaultTypes, sd->structsize - offset); } - // build the llvm type - const llvm::Type* st = llvm::StructType::get(gIR->context(), defaultTypes, packed); + // set struct body + isaStruct(type)->setBody(defaultTypes, packed); - // refine type - llvm::cast(pa.get())->refineAbstractTypeTo(st); + IF_LOG Logger::cout() << "final struct type: " << type << std::endl; - // name types - Type::sir->getState()->module->addTypeName(sd->toPrettyChars(), pa.get()); - - IF_LOG Logger::cout() << "final struct type: " << *pa.get() << std::endl; - - return pa.get(); + return type; } ////////////////////////////////////////////////////////////////////////////// diff --git a/ir/irtypestruct.h b/ir/irtypestruct.h index 89617b46..7417fc0c 100644 --- a/ir/irtypestruct.h +++ b/ir/irtypestruct.h @@ -53,7 +53,7 @@ public: IrTypeStruct* isStruct() { return this; } /// - const llvm::Type* buildType(); + llvm::Type* buildType(); protected: /// StructDeclaration this type represents. diff --git a/ir/irvar.cpp b/ir/irvar.cpp index 782b8bce..dabf0382 100644 --- a/ir/irvar.cpp +++ b/ir/irvar.cpp @@ -18,9 +18,9 @@ IrVar::IrVar(VarDeclaration* var) ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v), - type(llvm::OpaqueType::get(gIR->context())) +IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v) { + type = NULL; constInit = NULL; } diff --git a/ir/irvar.h b/ir/irvar.h index 23223297..471442e7 100644 --- a/ir/irvar.h +++ b/ir/irvar.h @@ -17,7 +17,7 @@ struct IrGlobal : IrVar { IrGlobal(VarDeclaration* v); - llvm::PATypeHolder type; + llvm::Type *type; llvm::Constant* constInit; };