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 "target.h"
#if IN_LLVM
#include "llvm/ADT/APFloat.h"
#endif
double Port::nan;
longdouble Port::ldbl_nan;
longdouble Port::snan;
@ -703,84 +707,40 @@ static PortInitializer portinitializer;
PortInitializer::PortInitializer()
{
#if IN_LLVM
union
{ unsigned int ui[2];
double d;
} nan =
#if __LITTLE_ENDIAN__
{{ 0, 0x7FF80000 }};
// Derive LLVM APFloat::fltSemantics from native format
#if LDBL_MANT_DIG == 53
#define FLT_SEMANTIC llvm::APFloat::IEEEdouble
#elif LDBL_MANT_DIG == 64
#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
{{ 0x7FF80000, 0 }};
#error "Unsupported native floating point format"
#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
union
{ unsigned int ui[2];
double d;
} nan = {{ 0, 0x7FF80000 }};
#endif
Port::nan = nan.d;
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
{ unsigned int ui[4];
longdouble ld;
} ldbl_nan = {{ 0, 0xC0000000, 0x7FFF, 0}};
Port::ldbl_nan = ldbl_nan.ld;
#endif
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
{ unsigned int ui[4];
longdouble ld;

View file

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

View file

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

View file

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

View file

@ -255,18 +255,4 @@ DValue *toElem(Expression *e, bool tryGetLvalue);
DValue *toElemDtor(Expression *e);
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

View file

@ -895,7 +895,7 @@ static void genModuleInfo(Module *m, bool emitFullModuleInfo) {
// create and set initializer
LLGlobalVariable *moduleInfoSym = getIrModule(m)->moduleInfoSymbol();
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 LDC_LLVM_VER > 305

View file

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

View file

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

View file

@ -245,10 +245,27 @@ LLValue *DtoDelegateEquals(TOK op, LLValue *lhs, LLValue *rhs) {
////////////////////////////////////////////////////////////////////////////////
LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) {
if (DtoIsTemplateInstance(sym)) {
return LinkageWithCOMDAT(templateLinkage, supportsCOMDAT());
}
return LinkageWithCOMDAT(llvm::GlobalValue::ExternalLinkage, false);
auto linkage = (DtoIsTemplateInstance(sym) ? templateLinkage
: LLGlobalValue::ExternalLinkage);
return {linkage, supportsCOMDAT()};
}
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];
} t;
t.ld = value;
return LLConstantFP::get(
gIR->context(), APFloat(APFloat::IEEEquad, APInt(128, 2, t.bits)));
return LLConstantFP::get(gIR->context(),
APFloat(APFloat::IEEEquad, APInt(128, 2, t.bits)));
}
if (llty == LLType::getPPC_FP128Ty(gIR->context())) {
uint64_t bits[] = {0, 0};

View file

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

View file

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

View file

@ -340,10 +340,12 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
const char *thunkName = nameBuf.extractString();
llvm::Function *thunk = gIR->module.getFunction(thunkName);
if (!thunk) {
const LinkageWithCOMDAT lwc(LLGlobalValue::LinkOnceODRLinkage,
supportsCOMDAT());
thunk = LLFunction::Create(
isaFunction(irFunc->func->getType()->getContainedType(0)),
llvm::GlobalValue::LinkOnceODRLinkage, thunkName, &gIR->module);
SET_COMDAT(thunk, gIR->module);
isaFunction(irFunc->func->getType()->getContainedType(0)), lwc.first,
thunkName, &gIR->module);
setLinkage(lwc, thunk);
thunk->copyAttributesFrom(irFunc->func);
// 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("6__vtblZ");
const LinkageWithCOMDAT lwc = DtoLinkage(cd);
llvm::GlobalVariable *GV =
const auto lwc = DtoLinkage(cd);
LLGlobalVariable *GV =
getOrCreateGlobal(cd->loc, gIR->module, vtbl_constant->getType(), true,
lwc.first, vtbl_constant, mangledName);
if (lwc.second) {
SET_COMDAT(GV, gIR->module);
}
setLinkage(lwc, GV);
// insert into the vtbl map
interfaceVtblMap.insert(std::make_pair(b->sym, GV));
@ -534,11 +534,7 @@ LLConstant *IrAggr::getClassInfoInterfaces() {
// create and apply initializer
LLConstant *arr = LLConstantArray::get(array_type, constants);
classInterfacesArray->setInitializer(arr);
const LinkageWithCOMDAT lwc = DtoLinkage(cd);
classInterfacesArray->setLinkage(lwc.first);
if (lwc.second) {
SET_COMDAT(classInterfacesArray, gIR->module);
}
setLinkage(cd, classInterfacesArray);
// return null, only baseclass provide interfaces
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; }
static Outer globalOuter;
// CHECK: constant %align.Outer_init zeroinitializer, align 32
// CHECK: constant %align.Outer_init zeroinitializer{{(, comdat)?}}, align 32
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; }
// CHECK: define{{.*}} void @{{.*}}_D5align23passAndReturnOuterByValFS5align5OuterZS5align5Outer