Merge branch 'ltsmaster'

This commit is contained in:
Kai Nacke 2016-03-22 19:05:07 +01:00
commit 88f3de8bea
15 changed files with 96 additions and 156 deletions

View file

@ -673,6 +673,10 @@ longdouble Port::strtold(const char *p, char **endp)
#include <assert.h> #include <assert.h>
#include "target.h" #include "target.h"
#if IN_LLVM
#include "llvm/ADT/APFloat.h"
#endif
double Port::nan; double Port::nan;
longdouble Port::ldbl_nan; longdouble Port::ldbl_nan;
longdouble Port::snan; longdouble Port::snan;
@ -703,84 +707,40 @@ static PortInitializer portinitializer;
PortInitializer::PortInitializer() PortInitializer::PortInitializer()
{ {
#if IN_LLVM #if IN_LLVM
union
{ unsigned int ui[2]; // Derive LLVM APFloat::fltSemantics from native format
double d; #if LDBL_MANT_DIG == 53
} nan = #define FLT_SEMANTIC llvm::APFloat::IEEEdouble
#if __LITTLE_ENDIAN__ #elif LDBL_MANT_DIG == 64
{{ 0, 0x7FF80000 }}; #define FLT_SEMANTIC llvm::APFloat::x87DoubleExtended
#elif LDBL_MANT_DIG == 106
#define FLT_SEMANTIC llvm::APFloat::PPCDoubleDouble
#elif LDBL_MANT_DIG == 113
#define FLT_SEMANTIC llvm::APFloat::IEEEquad
#else #else
{{ 0x7FF80000, 0 }}; #error "Unsupported native floating point format"
#endif #endif
Port::nan = *reinterpret_cast<const double*>(llvm::APFloat::getNaN(llvm::APFloat::IEEEdouble).bitcastToAPInt().getRawData());
Port::ldbl_nan = *reinterpret_cast<const long double*>(llvm::APFloat::getNaN(FLT_SEMANTIC).bitcastToAPInt().getRawData());
Port::snan = *reinterpret_cast<const long double*>(llvm::APFloat::getSNaN(FLT_SEMANTIC).bitcastToAPInt().getRawData());
#else #else
union union
{ unsigned int ui[2]; { unsigned int ui[2];
double d; double d;
} nan = {{ 0, 0x7FF80000 }}; } nan = {{ 0, 0x7FF80000 }};
#endif
Port::nan = nan.d; Port::nan = nan.d;
assert(!signbit(Port::nan)); assert(!signbit(Port::nan));
#if IN_LLVM
if (sizeof(double) == sizeof(longdouble))
{
// double and longdouble are same type.
// E.g. on ARM.
Port::ldbl_nan = Port::nan;
}
else
{
union
{ unsigned int ui[4];
longdouble ld;
} ldbl_nan =
#if __LITTLE_ENDIAN__
{{ 0, 0xC0000000, 0x7FFF, 0}};
#else
{{ 0, 0x7FFF, 0xC0000000, 0}};
#endif
Port::ldbl_nan = ldbl_nan.ld;
}
#else
union union
{ unsigned int ui[4]; { unsigned int ui[4];
longdouble ld; longdouble ld;
} ldbl_nan = {{ 0, 0xC0000000, 0x7FFF, 0}}; } ldbl_nan = {{ 0, 0xC0000000, 0x7FFF, 0}};
Port::ldbl_nan = ldbl_nan.ld; Port::ldbl_nan = ldbl_nan.ld;
#endif
assert(!signbit(Port::ldbl_nan)); assert(!signbit(Port::ldbl_nan));
#if IN_LLVM
if (sizeof(double) == sizeof(longdouble))
{
// double and longdouble are same type.
// E.g. on ARM.
union
{ unsigned int ui[2];
double d;
} snan =
#if __LITTLE_ENDIAN__
{{ 0, 0x7FFC0000 }};
#else
{{ 0x7FFC0000, 0 }};
#endif
Port::snan = snan.d;
}
else
{
union
{ unsigned int ui[4];
longdouble ld;
} snan =
#if __LITTLE_ENDIAN__
{{ 0, 0xA0000000, 0x7FFF, 0 }};
#else
{{ 0, 0x7FFF, 0xA0000000, 0 }};
#endif
Port::snan = snan.ld;
}
#else
union union
{ unsigned int ui[4]; { unsigned int ui[4];
longdouble ld; longdouble ld;

View file

@ -164,11 +164,7 @@ public:
IrAggr *ir = getIrAggr(decl); IrAggr *ir = getIrAggr(decl);
llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol(); llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol();
interfaceZ->setInitializer(ir->getClassInfoInit()); interfaceZ->setInitializer(ir->getClassInfoInit());
LinkageWithCOMDAT lwc = DtoLinkage(decl); setLinkage(decl, interfaceZ);
interfaceZ->setLinkage(lwc.first);
if (lwc.second) {
SET_COMDAT(interfaceZ, gIR->module);
}
} }
} }
@ -204,11 +200,7 @@ public:
IrAggr *ir = getIrAggr(decl); IrAggr *ir = getIrAggr(decl);
llvm::GlobalVariable *initZ = ir->getInitSymbol(); llvm::GlobalVariable *initZ = ir->getInitSymbol();
initZ->setInitializer(ir->getDefaultInit()); initZ->setInitializer(ir->getDefaultInit());
LinkageWithCOMDAT lwc = DtoLinkage(decl); setLinkage(decl, initZ);
initZ->setLinkage(lwc.first);
if (lwc.second) {
SET_COMDAT(initZ, gIR->module);
}
// emit typeinfo // emit typeinfo
DtoTypeInfoOf(decl->type); DtoTypeInfoOf(decl->type);
@ -251,28 +243,19 @@ public:
} }
IrAggr *ir = getIrAggr(decl); IrAggr *ir = getIrAggr(decl);
const LinkageWithCOMDAT lwc = DtoLinkage(decl); const auto lwc = DtoLinkage(decl);
llvm::GlobalVariable *initZ = ir->getInitSymbol(); llvm::GlobalVariable *initZ = ir->getInitSymbol();
initZ->setInitializer(ir->getDefaultInit()); initZ->setInitializer(ir->getDefaultInit());
initZ->setLinkage(lwc.first); setLinkage(lwc, initZ);
if (lwc.second) {
SET_COMDAT(initZ, gIR->module);
}
llvm::GlobalVariable *vtbl = ir->getVtblSymbol(); llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
vtbl->setInitializer(ir->getVtblInit()); vtbl->setInitializer(ir->getVtblInit());
vtbl->setLinkage(lwc.first); setLinkage(lwc, vtbl);
if (lwc.second) {
SET_COMDAT(vtbl, gIR->module);
}
llvm::GlobalVariable *classZ = ir->getClassInfoSymbol(); llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
classZ->setInitializer(ir->getClassInfoInit()); classZ->setInitializer(ir->getClassInfoInit());
classZ->setLinkage(lwc.first); setLinkage(lwc, classZ);
if (lwc.second) {
SET_COMDAT(classZ, gIR->module);
}
// No need to do TypeInfo here, it is <name>__classZ for classes in D2. // No need to do TypeInfo here, it is <name>__classZ for classes in D2.
} }
@ -335,11 +318,10 @@ public:
"manifest constant being codegen'd!"); "manifest constant being codegen'd!");
IrGlobal *irGlobal = getIrGlobal(decl); IrGlobal *irGlobal = getIrGlobal(decl);
llvm::GlobalVariable *gvar = LLGlobalVariable *gvar = llvm::cast<LLGlobalVariable>(irGlobal->value);
llvm::cast<llvm::GlobalVariable>(irGlobal->value);
assert(gvar && "DtoResolveVariable should have created value"); assert(gvar && "DtoResolveVariable should have created value");
const LinkageWithCOMDAT lwc = DtoLinkage(decl); const auto lwc = DtoLinkage(decl);
// Check if we are defining or just declaring the global in this module. // Check if we are defining or just declaring the global in this module.
if (!(decl->storage_class & STCextern)) { if (!(decl->storage_class & STCextern)) {
@ -354,9 +336,7 @@ public:
lwc.first, nullptr, lwc.first, nullptr,
"", // We take on the name of the old global below. "", // We take on the name of the old global below.
gvar->isThreadLocal()); gvar->isThreadLocal());
if (lwc.second) { setLinkage(lwc, newGvar);
SET_COMDAT(newGvar, gIR->module);
}
newGvar->setAlignment(gvar->getAlignment()); newGvar->setAlignment(gvar->getAlignment());
applyVarDeclUDAs(decl, newGvar); applyVarDeclUDAs(decl, newGvar);
@ -375,10 +355,7 @@ public:
assert(!irGlobal->constInit); assert(!irGlobal->constInit);
irGlobal->constInit = initVal; irGlobal->constInit = initVal;
gvar->setInitializer(initVal); gvar->setInitializer(initVal);
gvar->setLinkage(lwc.first); setLinkage(lwc, gvar);
if (lwc.second) {
SET_COMDAT(gvar, gIR->module);
}
// Also set up the debug info. // Also set up the debug info.
irs->DBuilder.EmitGlobalVariable(gvar, decl); irs->DBuilder.EmitGlobalVariable(gvar, decl);

View file

@ -583,7 +583,7 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
static LinkageWithCOMDAT lowerFuncLinkage(FuncDeclaration *fdecl) { static LinkageWithCOMDAT lowerFuncLinkage(FuncDeclaration *fdecl) {
// Intrinsics are always external. // Intrinsics are always external.
if (DtoIsIntrinsic(fdecl)) { if (DtoIsIntrinsic(fdecl)) {
return LinkageWithCOMDAT(llvm::GlobalValue::ExternalLinkage, false); return LinkageWithCOMDAT(LLGlobalValue::ExternalLinkage, false);
} }
// Generated array op functions behave like templates in that they might be // Generated array op functions behave like templates in that they might be
@ -596,7 +596,7 @@ static LinkageWithCOMDAT lowerFuncLinkage(FuncDeclaration *fdecl) {
// (also e.g. naked template functions which would otherwise be weak_odr, // (also e.g. naked template functions which would otherwise be weak_odr,
// but where the definition is in module-level inline asm). // but where the definition is in module-level inline asm).
if (!fdecl->fbody || fdecl->naked) { if (!fdecl->fbody || fdecl->naked) {
return LinkageWithCOMDAT(llvm::GlobalValue::ExternalLinkage, false); return LinkageWithCOMDAT(LLGlobalValue::ExternalLinkage, false);
} }
return DtoLinkage(fdecl); return DtoLinkage(fdecl);
@ -746,11 +746,8 @@ void DtoDefineFunction(FuncDeclaration *fd) {
IF_LOG Logger::println("Doing function body for: %s", fd->toChars()); IF_LOG Logger::println("Doing function body for: %s", fd->toChars());
gIR->functions.push_back(irFunc); gIR->functions.push_back(irFunc);
LinkageWithCOMDAT lwc = lowerFuncLinkage(fd); const auto lwc = lowerFuncLinkage(fd);
func->setLinkage(lwc.first); setLinkage(lwc, func);
if (lwc.second) {
SET_COMDAT(func, gIR->module);
}
// On x86_64, always set 'uwtable' for System V ABI compatibility. // On x86_64, always set 'uwtable' for System V ABI compatibility.
// TODO: Find a better place for this. // TODO: Find a better place for this.

View file

@ -93,8 +93,7 @@ llvm::Function *DtoInlineIRFunction(FuncDeclaration *fdecl) {
#endif #endif
LLFunction *fun = gIR->module.getFunction(mangled_name); LLFunction *fun = gIR->module.getFunction(mangled_name);
fun->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage); setLinkage({LLGlobalValue::LinkOnceODRLinkage, supportsCOMDAT()}, fun);
SET_COMDAT(fun, gIR->module);
fun->addFnAttr(LLAttribute::AlwaysInline); fun->addFnAttr(LLAttribute::AlwaysInline);
return fun; return fun;
} }

View file

@ -1814,4 +1814,4 @@ unsigned getFieldGEPIndex(AggregateDeclaration *ad, VarDeclaration *vd) {
bool supportsCOMDAT() { bool supportsCOMDAT() {
return !global.params.targetTriple->isOSBinFormatMachO(); return !global.params.targetTriple->isOSBinFormatMachO();
} }
#endif #endif

View file

@ -255,18 +255,4 @@ DValue *toElem(Expression *e, bool tryGetLvalue);
DValue *toElemDtor(Expression *e); DValue *toElemDtor(Expression *e);
LLConstant *toConstElem(Expression *e, IRState *p); LLConstant *toConstElem(Expression *e, IRState *p);
#if LDC_LLVM_VER >= 307
bool supportsCOMDAT();
#define SET_COMDAT(x, m) \
if (supportsCOMDAT()) \
x->setComdat(m.getOrInsertComdat(x->getName()))
#else
#define supportsCOMDAT() false
#define SET_COMDAT(x, m)
#endif
#endif #endif

View file

@ -895,7 +895,7 @@ static void genModuleInfo(Module *m, bool emitFullModuleInfo) {
// create and set initializer // create and set initializer
LLGlobalVariable *moduleInfoSym = getIrModule(m)->moduleInfoSymbol(); LLGlobalVariable *moduleInfoSym = getIrModule(m)->moduleInfoSymbol();
b.finalize(moduleInfoSym->getType()->getPointerElementType(), moduleInfoSym); b.finalize(moduleInfoSym->getType()->getPointerElementType(), moduleInfoSym);
moduleInfoSym->setLinkage(llvm::GlobalValue::ExternalLinkage); setLinkage({LLGlobalValue::ExternalLinkage, false}, moduleInfoSym);
if (global.params.targetTriple->isOSLinux() || global.params.targetTriple->isOSFreeBSD() || if (global.params.targetTriple->isOSLinux() || global.params.targetTriple->isOSFreeBSD() ||
#if LDC_LLVM_VER > 305 #if LDC_LLVM_VER > 305
@ -906,7 +906,7 @@ static void genModuleInfo(Module *m, bool emitFullModuleInfo) {
global.params.targetTriple->getOS() == llvm::Triple::OpenBSD || global.params.targetTriple->getOS() == llvm::Triple::OpenBSD ||
global.params.targetTriple->getOS() == llvm::Triple::DragonFly global.params.targetTriple->getOS() == llvm::Triple::DragonFly
#endif #endif
) { ) {
if (emitFullModuleInfo) { if (emitFullModuleInfo) {
build_dso_registry_calls(mangle(m), moduleInfoSym); build_dso_registry_calls(mangle(m), moduleInfoSym);
} else { } else {

View file

@ -70,7 +70,7 @@ bool StripExternals::runOnModule(Module &M) {
++I; ++I;
} }
for (Module::global_iterator I = M.global_begin(); I != M.global_end();) { for (auto I = M.global_begin(); I != M.global_end();) {
if (I->hasAvailableExternallyLinkage()) { if (I->hasAvailableExternallyLinkage()) {
assert(!I->isDeclaration() && assert(!I->isDeclaration() &&
"Declarations can't be available_externally"); "Declarations can't be available_externally");
@ -78,7 +78,7 @@ bool StripExternals::runOnModule(Module &M) {
++NumVariables; ++NumVariables;
if (I->use_empty()) { if (I->use_empty()) {
DEBUG(errs() << "Deleting global: " << *I); DEBUG(errs() << "Deleting global: " << *I);
Module::global_iterator todelete = I; auto todelete = I;
++I; ++I;
todelete->eraseFromParent(); todelete->eraseFromParent();
continue; continue;

View file

@ -86,9 +86,11 @@ void RTTIBuilder::push_void_array(llvm::Constant *CI, Type *valtype,
std::string initname(mangle(mangle_sym)); std::string initname(mangle(mangle_sym));
initname.append(".rtti.voidarr.data"); initname.append(".rtti.voidarr.data");
const LinkageWithCOMDAT lwc(TYPEINFO_LINKAGE_TYPE, supportsCOMDAT());
auto G = new LLGlobalVariable(gIR->module, CI->getType(), true, auto G = new LLGlobalVariable(gIR->module, CI->getType(), true,
TYPEINFO_LINKAGE_TYPE, CI, initname); lwc.first, CI, initname);
SET_COMDAT(G, gIR->module); setLinkage(lwc, G);
G->setAlignment(DtoAlignment(valtype)); G->setAlignment(DtoAlignment(valtype));
push_void_array(getTypeAllocSize(CI->getType()), G); push_void_array(getTypeAllocSize(CI->getType()), G);
@ -106,9 +108,11 @@ void RTTIBuilder::push_array(llvm::Constant *CI, uint64_t dim, Type *valtype,
initname.append(tmpStr); initname.append(tmpStr);
initname.append(".data"); initname.append(".data");
const LinkageWithCOMDAT lwc(TYPEINFO_LINKAGE_TYPE, supportsCOMDAT());
auto G = new LLGlobalVariable(gIR->module, CI->getType(), true, auto G = new LLGlobalVariable(gIR->module, CI->getType(), true,
TYPEINFO_LINKAGE_TYPE, CI, initname); lwc.first, CI, initname);
SET_COMDAT(G, gIR->module); setLinkage(lwc, G);
G->setAlignment(DtoAlignment(valtype)); G->setAlignment(DtoAlignment(valtype));
push_array(dim, DtoBitCast(G, DtoType(valtype->pointerTo()))); push_array(dim, DtoBitCast(G, DtoType(valtype->pointerTo())));
@ -165,8 +169,7 @@ void RTTIBuilder::finalize(LLType *type, LLValue *value) {
// set the initializer // set the initializer
llvm::GlobalVariable *gvar = llvm::cast<llvm::GlobalVariable>(value); llvm::GlobalVariable *gvar = llvm::cast<llvm::GlobalVariable>(value);
gvar->setInitializer(tiInit); gvar->setInitializer(tiInit);
gvar->setLinkage(TYPEINFO_LINKAGE_TYPE); setLinkage({TYPEINFO_LINKAGE_TYPE, supportsCOMDAT()}, gvar);
SET_COMDAT(gvar, gIR->module);
} }
LLConstant *RTTIBuilder::get_constant(LLStructType *initType) { LLConstant *RTTIBuilder::get_constant(LLStructType *initType) {

View file

@ -65,7 +65,7 @@ LLAttribute DtoShouldExtend(Type *type) {
case Tuns16: case Tuns16:
case Tchar: case Tchar:
case Twchar: case Twchar:
return LLAttribute::ZExt; return LLAttribute::ZExt;
default: default:
// Do not extend. // Do not extend.
@ -245,10 +245,27 @@ LLValue *DtoDelegateEquals(TOK op, LLValue *lhs, LLValue *rhs) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) { LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) {
if (DtoIsTemplateInstance(sym)) { auto linkage = (DtoIsTemplateInstance(sym) ? templateLinkage
return LinkageWithCOMDAT(templateLinkage, supportsCOMDAT()); : LLGlobalValue::ExternalLinkage);
} return {linkage, supportsCOMDAT()};
return LinkageWithCOMDAT(llvm::GlobalValue::ExternalLinkage, false); }
bool supportsCOMDAT() {
#if LDC_LLVM_VER >= 307
return !global.params.targetTriple.isOSBinFormatMachO();
#else
return false;
#endif
}
void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj) {
obj->setLinkage(lwc.first);
if (lwc.second)
obj->setComdat(gIR->module.getOrInsertComdat(obj->getName()));
}
void setLinkage(Dsymbol *sym, llvm::GlobalObject *obj) {
setLinkage(DtoLinkage(sym), obj);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -418,8 +435,8 @@ LLConstant *DtoConstFP(Type *t, longdouble value) {
uint64_t bits[2]; uint64_t bits[2];
} t; } t;
t.ld = value; t.ld = value;
return LLConstantFP::get( return LLConstantFP::get(gIR->context(),
gIR->context(), APFloat(APFloat::IEEEquad, APInt(128, 2, t.bits))); APFloat(APFloat::IEEEquad, APInt(128, 2, t.bits)));
} }
if (llty == LLType::getPPC_FP128Ty(gIR->context())) { if (llty == LLType::getPPC_FP128Ty(gIR->context())) {
uint64_t bits[] = {0, 0}; uint64_t bits[] = {0, 0};
@ -690,7 +707,7 @@ LLStructType *DtoMutexType() {
global.params.targetTriple->getOS() == llvm::Triple::OpenBSD || global.params.targetTriple->getOS() == llvm::Triple::OpenBSD ||
global.params.targetTriple->getOS() == llvm::Triple::DragonFly global.params.targetTriple->getOS() == llvm::Triple::DragonFly
#endif #endif
) { ) {
// Just a pointer // Just a pointer
return LLStructType::get(gIR->context(), DtoSize_t()); return LLStructType::get(gIR->context(), DtoSize_t());
} }

View file

@ -65,6 +65,10 @@ LLValue *DtoDelegateEquals(TOK op, LLValue *lhs, LLValue *rhs);
typedef std::pair<llvm::GlobalValue::LinkageTypes, bool> LinkageWithCOMDAT; typedef std::pair<llvm::GlobalValue::LinkageTypes, bool> LinkageWithCOMDAT;
LinkageWithCOMDAT DtoLinkage(Dsymbol *sym); LinkageWithCOMDAT DtoLinkage(Dsymbol *sym);
bool supportsCOMDAT();
void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj);
void setLinkage(Dsymbol *sym, llvm::GlobalObject *obj);
// some types // some types
LLIntegerType *DtoSize_t(); LLIntegerType *DtoSize_t();
LLStructType *DtoMutexType(); LLStructType *DtoMutexType();

View file

@ -713,6 +713,8 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
} }
IrGlobal *irg = getIrGlobal(decl, true); IrGlobal *irg = getIrGlobal(decl, true);
const LinkageWithCOMDAT lwc(LLGlobalValue::ExternalLinkage, false);
irg->value = gIR->module.getGlobalVariable(mangled); irg->value = gIR->module.getGlobalVariable(mangled);
if (irg->value) { if (irg->value) {
irg->type = irg->value->getType()->getContainedType(0); irg->type = irg->value->getType()->getContainedType(0);
@ -724,17 +726,16 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
} else { } else {
irg->type = LLStructType::create(gIR->context(), decl->toPrettyChars()); irg->type = LLStructType::create(gIR->context(), decl->toPrettyChars());
} }
irg->value = new llvm::GlobalVariable(gIR->module, irg->type, true, LLGlobalVariable *g = new LLGlobalVariable(gIR->module, irg->type, true,
llvm::GlobalValue::ExternalLinkage, lwc.first, nullptr, mangled);
nullptr, mangled); setLinkage(lwc, g);
irg->value = g;
} }
emitTypeMetadata(decl); emitTypeMetadata(decl);
// this is a declaration of a builtin __initZ var // this is a declaration of a builtin __initZ var
if (builtinTypeInfo(decl->tinfo)) { if (builtinTypeInfo(decl->tinfo)) {
LLGlobalVariable *g = isaGlobalVar(irg->value);
g->setLinkage(llvm::GlobalValue::ExternalLinkage);
return; return;
} }

View file

@ -340,10 +340,12 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
const char *thunkName = nameBuf.extractString(); const char *thunkName = nameBuf.extractString();
llvm::Function *thunk = gIR->module.getFunction(thunkName); llvm::Function *thunk = gIR->module.getFunction(thunkName);
if (!thunk) { if (!thunk) {
const LinkageWithCOMDAT lwc(LLGlobalValue::LinkOnceODRLinkage,
supportsCOMDAT());
thunk = LLFunction::Create( thunk = LLFunction::Create(
isaFunction(irFunc->func->getType()->getContainedType(0)), isaFunction(irFunc->func->getType()->getContainedType(0)), lwc.first,
llvm::GlobalValue::LinkOnceODRLinkage, thunkName, &gIR->module); thunkName, &gIR->module);
SET_COMDAT(thunk, gIR->module); setLinkage(lwc, thunk);
thunk->copyAttributesFrom(irFunc->func); thunk->copyAttributesFrom(irFunc->func);
// Thunks themselves don't have an identity, only the target // Thunks themselves don't have an identity, only the target
@ -436,13 +438,11 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
mangledName.append(mangle(b->sym)); mangledName.append(mangle(b->sym));
mangledName.append("6__vtblZ"); mangledName.append("6__vtblZ");
const LinkageWithCOMDAT lwc = DtoLinkage(cd); const auto lwc = DtoLinkage(cd);
llvm::GlobalVariable *GV = LLGlobalVariable *GV =
getOrCreateGlobal(cd->loc, gIR->module, vtbl_constant->getType(), true, getOrCreateGlobal(cd->loc, gIR->module, vtbl_constant->getType(), true,
lwc.first, vtbl_constant, mangledName); lwc.first, vtbl_constant, mangledName);
if (lwc.second) { setLinkage(lwc, GV);
SET_COMDAT(GV, gIR->module);
}
// insert into the vtbl map // insert into the vtbl map
interfaceVtblMap.insert(std::make_pair(b->sym, GV)); interfaceVtblMap.insert(std::make_pair(b->sym, GV));
@ -534,11 +534,7 @@ LLConstant *IrAggr::getClassInfoInterfaces() {
// create and apply initializer // create and apply initializer
LLConstant *arr = LLConstantArray::get(array_type, constants); LLConstant *arr = LLConstantArray::get(array_type, constants);
classInterfacesArray->setInitializer(arr); classInterfacesArray->setInitializer(arr);
const LinkageWithCOMDAT lwc = DtoLinkage(cd); setLinkage(cd, classInterfacesArray);
classInterfacesArray->setLinkage(lwc.first);
if (lwc.second) {
SET_COMDAT(classInterfacesArray, gIR->module);
}
// return null, only baseclass provide interfaces // return null, only baseclass provide interfaces
if (cd->vtblInterfaces->dim == 0) { if (cd->vtblInterfaces->dim == 0) {

@ -1 +1 @@
Subproject commit 47719ee31806bbbaf8ff9f2d1da4918d7eaf9cf1 Subproject commit b940a5f241706550779143b0d417435a1842914d

View file

@ -4,9 +4,9 @@ align(32) struct Outer { int a; }
struct Inner { align(32) int a; } struct Inner { align(32) int a; }
static Outer globalOuter; static Outer globalOuter;
// CHECK: constant %align.Outer_init zeroinitializer, align 32 // CHECK: constant %align.Outer_init zeroinitializer{{(, comdat)?}}, align 32
static Inner globalInner; static Inner globalInner;
// CHECK: constant %align.Inner_init zeroinitializer, align 32 // CHECK: constant %align.Inner_init zeroinitializer{{(, comdat)?}}, align 32
Outer passAndReturnOuterByVal(Outer arg) { return arg; } Outer passAndReturnOuterByVal(Outer arg) { return arg; }
// CHECK: define{{.*}} void @{{.*}}_D5align23passAndReturnOuterByValFS5align5OuterZS5align5Outer // CHECK: define{{.*}} void @{{.*}}_D5align23passAndReturnOuterByValFS5align5OuterZS5align5Outer