mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 08:30:47 +03:00
Merge branch 'ltsmaster'
This commit is contained in:
commit
88f3de8bea
15 changed files with 96 additions and 156 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue