mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-13 22:48:43 +03:00
Emit struct TypeInfos & special member functions in owning module only
Analogous to ClassInfos, incl. normal linkage (external for non- templates, weak_odr for templates). This enables to get rid of frontend logic wrt. whether to add TypeInfoStructDeclarations to a module's members tree - previously, it was defined as linkonce_odr in the owning module and each referencing module (unless speculative) - and related extra semantic and codegen for the special member functions. I've gone a bit further and moved the entire TypeInfo emission for LDC to the codegen layer; no TypeInfoDeclarations are added to the module members anymore. Whenever we need a TypeInfo symbol during codegen, it is declared or defined, and we don't need to rely on brittle frontend logic with speculative-ness complications. This might slightly increase compilation speed due to less emitted TypeInfos and functions (possibly less work for the linker too). A slight drawback is that the job of stripping unused struct TypeInfos is fully delegated to the linker, as the TypeInfo is guaranteed to end up in the owning object file due to no linkonce_odr. Another theoretical drawback is that the optimizer can definitely not inline xtoHash/xopEquals/xopCmp/xtoString/xdtor[ti]/xpostblit function pointer indirections in non-owning CUs without LTO (neither the pointers nor the special member functions are defined anymore). These (public) members are probably hardly used directly though, and instead used by the virtual TypeInfo_Struct methods equals/compare/ getHash/destroy/postblit, which are exclusively defined in druntime's object.o (incl. the TypeInfo_Struct vtable) and aren't cross-module- inlined anyway (without LTO). Re-emitting the struct TypeInfos (and optionally the special member functions too) into each referencing CU could be handled in our codegen layer, which should be much simpler and more robust than the upstream scheme.
This commit is contained in:
parent
555f3ba233
commit
64aa4fe1e3
11 changed files with 124 additions and 160 deletions
|
@ -92,21 +92,23 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (decl->members && decl->symtab) {
|
||||
DtoResolveClass(decl);
|
||||
decl->ir->setDefined();
|
||||
if (!(decl->members && decl->symtab)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Emit any members (e.g. final functions).
|
||||
for (auto m : *decl->members) {
|
||||
m->accept(this);
|
||||
}
|
||||
DtoResolveClass(decl);
|
||||
decl->ir->setDefined();
|
||||
|
||||
// Emit TypeInfo.
|
||||
IrClass *ir = getIrAggr(decl);
|
||||
if (!ir->suppressTypeInfo() && !isSpeculativeType(decl->type)) {
|
||||
llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol();
|
||||
defineGlobal(interfaceZ, ir->getClassInfoInit(), decl);
|
||||
}
|
||||
// Emit any members (e.g. final functions).
|
||||
for (auto m : *decl->members) {
|
||||
m->accept(this);
|
||||
}
|
||||
|
||||
// Emit TypeInfo.
|
||||
IrClass *ir = getIrAggr(decl);
|
||||
if (!ir->suppressTypeInfo()) {
|
||||
llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol();
|
||||
defineGlobal(interfaceZ, ir->getClassInfoInit(), decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,6 +130,13 @@ public:
|
|||
}
|
||||
|
||||
if (!(decl->members && decl->symtab)) {
|
||||
// we need to emit TypeInfos for opaque structs too
|
||||
IrStruct *ir = getIrAggr(decl, true);
|
||||
if (!irs->dcomputetarget && !ir->suppressTypeInfo()) {
|
||||
llvm::GlobalVariable *typeInfo = ir->getTypeInfoSymbol();
|
||||
defineGlobal(typeInfo, ir->getTypeInfoInit(), decl);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -153,8 +162,6 @@ public:
|
|||
|
||||
// emit typeinfo
|
||||
if (!ir->suppressTypeInfo()) {
|
||||
DtoTypeInfoOf(decl->type, /*base=*/false);
|
||||
|
||||
// Emit __xopEquals/__xopCmp/__xtoHash.
|
||||
if (decl->xeq && decl->xeq != decl->xerreq) {
|
||||
decl->xeq->accept(this);
|
||||
|
@ -165,6 +172,10 @@ public:
|
|||
if (decl->xhash) {
|
||||
decl->xhash->accept(this);
|
||||
}
|
||||
|
||||
// define the TypeInfo_Struct symbol
|
||||
llvm::GlobalVariable *typeInfo = ir->getTypeInfoSymbol();
|
||||
defineGlobal(typeInfo, ir->getTypeInfoInit(), decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,31 +199,33 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (decl->members && decl->symtab) {
|
||||
DtoResolveClass(decl);
|
||||
decl->ir->setDefined();
|
||||
if (!(decl->members && decl->symtab)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto m : *decl->members) {
|
||||
m->accept(this);
|
||||
}
|
||||
DtoResolveClass(decl);
|
||||
decl->ir->setDefined();
|
||||
|
||||
IrClass *ir = getIrAggr(decl);
|
||||
for (auto m : *decl->members) {
|
||||
m->accept(this);
|
||||
}
|
||||
|
||||
auto &initZ = ir->getInitSymbol();
|
||||
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
|
||||
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
|
||||
setLinkageAndVisibility(decl, initGlobal);
|
||||
IrClass *ir = getIrAggr(decl);
|
||||
|
||||
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
|
||||
defineGlobal(vtbl, ir->getVtblInit(), decl);
|
||||
auto &initZ = ir->getInitSymbol();
|
||||
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
|
||||
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
|
||||
setLinkageAndVisibility(decl, initGlobal);
|
||||
|
||||
ir->defineInterfaceVtbls();
|
||||
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
|
||||
defineGlobal(vtbl, ir->getVtblInit(), decl);
|
||||
|
||||
// Emit TypeInfo.
|
||||
if (!ir->suppressTypeInfo() && !isSpeculativeType(decl->type)) {
|
||||
llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
|
||||
defineGlobal(classZ, ir->getClassInfoInit(), decl);
|
||||
}
|
||||
ir->defineInterfaceVtbls();
|
||||
|
||||
// Emit TypeInfo.
|
||||
if (!ir->suppressTypeInfo()) {
|
||||
llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
|
||||
defineGlobal(classZ, ir->getClassInfoInit(), decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -503,8 +516,7 @@ public:
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void visit(TypeInfoDeclaration *decl) override {
|
||||
if (!irs->dcomputetarget)
|
||||
TypeInfoDeclaration_codegen(decl);
|
||||
llvm_unreachable("Should be emitted from codegen layer only");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue