Skip to content

Commit a74601f

Browse files
authored
Merge pull request #3491 from kinke/iraggr2
Emit struct TypeInfos in referencing compilation units only
2 parents 3c5af94 + 818ac92 commit a74601f

14 files changed

+130
-152
lines changed

dmd/aggregate.h

+2
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,12 @@ class StructDeclaration : public AggregateDeclaration
167167
bool hasIdentityEquals; // true if has identity opEquals
168168
bool hasNoFields; // has no fields
169169
bool hasCopyCtor; // copy constructor
170+
#if !IN_LLVM
170171
// Even if struct is defined as non-root symbol, some built-in operations
171172
// (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
172173
// For those, today TypeInfo_Struct is generated in COMDAT.
173174
bool requestTypeInfo;
175+
#endif
174176

175177
FuncDeclarations postblits; // Array of postblit functions
176178
FuncDeclaration *postblit; // aggregate postblit

dmd/dstruct.d

+9
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,10 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t)
104104
Scope scx;
105105
scx._module = sd.getModule();
106106
getTypeInfoType(sd.loc, t, &scx);
107+
version (IN_LLVM) {} else
108+
{
107109
sd.requestTypeInfo = true;
110+
}
108111
}
109112
else if (!sc.minst)
110113
{
@@ -114,7 +117,10 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t)
114117
else
115118
{
116119
getTypeInfoType(sd.loc, t, sc);
120+
version (IN_LLVM) {} else
121+
{
117122
sd.requestTypeInfo = true;
123+
}
118124

119125
// https://issues.dlang.org/show_bug.cgi?id=15149
120126
// if the typeid operand type comes from a
@@ -205,10 +211,13 @@ extern (C++) class StructDeclaration : AggregateDeclaration
205211
bool hasIdentityEquals; // true if has identity opEquals
206212
bool hasNoFields; // has no fields
207213
bool hasCopyCtor; // copy constructor
214+
version (IN_LLVM) {} else
215+
{
208216
// Even if struct is defined as non-root symbol, some built-in operations
209217
// (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
210218
// For those, today TypeInfo_Struct is generated in COMDAT.
211219
bool requestTypeInfo;
220+
}
212221

213222
FuncDeclarations postblits; // Array of postblit functions
214223
FuncDeclaration postblit; // aggregate postblit

dmd/expressionsem.d

+1
Original file line numberDiff line numberDiff line change
@@ -7111,6 +7111,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
71117111
{
71127112
if (ad.dtor)
71137113
{
7114+
err |= !ad.dtor.functionSemantic();
71147115
err |= exp.checkPurity(sc, ad.dtor);
71157116
err |= exp.checkSafety(sc, ad.dtor);
71167117
err |= exp.checkNogc(sc, ad.dtor);

dmd/typinf.d

+19-10
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ void genTypeInfo(Loc loc, Type torig, Scope* sc)
7575
t.vtinfo = getTypeInfoDeclaration(t);
7676
assert(t.vtinfo);
7777

78+
version (IN_LLVM)
79+
{
80+
// LDC handles emission in the codegen layer
81+
}
82+
else
83+
{
7884
/* If this has a custom implementation in std/typeinfo, then
7985
* do not generate a COMDAT for it.
8086
*/
@@ -89,16 +95,10 @@ void genTypeInfo(Loc loc, Type torig, Scope* sc)
8995
}
9096
else // if in obj generation pass
9197
{
92-
version (IN_LLVM)
93-
{
94-
Declaration_codegen(t.vtinfo);
95-
}
96-
else
97-
{
9898
toObjFile(t.vtinfo, global.params.multiobj);
99-
}
10099
}
101100
}
101+
} // !IN_LLVM
102102
}
103103
if (!torig.vtinfo)
104104
torig.vtinfo = t.vtinfo; // Types aren't merged, but we can share the vtinfo's
@@ -157,12 +157,19 @@ private TypeInfoDeclaration getTypeInfoDeclaration(Type t)
157157
}
158158
}
159159

160+
version (IN_LLVM)
161+
{
162+
// LDC handles TypeInfo emission in the codegen layer
163+
// => no need to take care of speculative types.
164+
}
165+
else
166+
{
167+
160168
/**************************************************
161169
* Returns:
162170
* true if any part of type t is speculative.
163171
* if t is null, returns false.
164172
*/
165-
extern (C++) // IN_LLVM
166173
bool isSpeculativeType(Type t)
167174
{
168175
static bool visitVector(TypeVector t)
@@ -255,6 +262,8 @@ bool isSpeculativeType(Type t)
255262
}
256263
}
257264

265+
} // !IN_LLVM
266+
258267
/* ========================================================================= */
259268

260269
/* These decide if there's an instance for them already in std.typeinfo,
@@ -263,8 +272,8 @@ bool isSpeculativeType(Type t)
263272
// IN_LLVM: replaced `private` with `extern(C++)`
264273
extern(C++) bool builtinTypeInfo(Type t)
265274
{
266-
// LDC_FIXME: if I enable for Tclass, the way LDC does typeinfo will cause
267-
// a bunch of linker errors to missing ClassInfo init symbols.
275+
// IN_LLVM: the Tclass case seems to be a DMD hack
276+
// (in order not to define ClassInfos in each referencing module)
268277
if (t.isTypeBasic() || (!IN_LLVM && t.ty == Tclass) || t.ty == Tnull)
269278
return !t.mod;
270279
if (t.ty == Tarray)

gen/declarations.cpp

+42-38
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,23 @@ class CodegenVisitor : public Visitor {
9292
return;
9393
}
9494

95-
if (decl->members && decl->symtab) {
96-
DtoResolveClass(decl);
97-
decl->ir->setDefined();
95+
if (!(decl->members && decl->symtab)) {
96+
return;
97+
}
9898

99-
// Emit any members (e.g. final functions).
100-
for (auto m : *decl->members) {
101-
m->accept(this);
102-
}
99+
DtoResolveClass(decl);
100+
decl->ir->setDefined();
103101

104-
// Emit TypeInfo.
105-
IrClass *ir = getIrAggr(decl);
106-
if (!ir->suppressTypeInfo() && !isSpeculativeType(decl->type)) {
107-
llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol();
108-
defineGlobal(interfaceZ, ir->getClassInfoInit(), decl);
109-
}
102+
// Emit any members (e.g. final functions).
103+
for (auto m : *decl->members) {
104+
m->accept(this);
105+
}
106+
107+
// Emit TypeInfo.
108+
IrClass *ir = getIrAggr(decl);
109+
if (!ir->suppressTypeInfo()) {
110+
llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol();
111+
defineGlobal(interfaceZ, ir->getClassInfoInit(), decl);
110112
}
111113
}
112114

@@ -128,6 +130,7 @@ class CodegenVisitor : public Visitor {
128130
}
129131

130132
if (!(decl->members && decl->symtab)) {
133+
// nothing to do for opaque structs anymore
131134
return;
132135
}
133136

@@ -151,11 +154,9 @@ class CodegenVisitor : public Visitor {
151154
setLinkageAndVisibility(decl, initGlobal);
152155
}
153156

154-
// emit typeinfo
157+
// Emit special __xopEquals/__xopCmp/__xtoHash member functions required
158+
// for the TypeInfo.
155159
if (!ir->suppressTypeInfo()) {
156-
DtoTypeInfoOf(decl->type, /*base=*/false);
157-
158-
// Emit __xopEquals/__xopCmp/__xtoHash.
159160
if (decl->xeq && decl->xeq != decl->xerreq) {
160161
decl->xeq->accept(this);
161162
}
@@ -165,6 +166,8 @@ class CodegenVisitor : public Visitor {
165166
if (decl->xhash) {
166167
decl->xhash->accept(this);
167168
}
169+
170+
// the TypeInfo itself is emitted into each referencing CU
168171
}
169172
}
170173
}
@@ -188,31 +191,33 @@ class CodegenVisitor : public Visitor {
188191
return;
189192
}
190193

191-
if (decl->members && decl->symtab) {
192-
DtoResolveClass(decl);
193-
decl->ir->setDefined();
194+
if (!(decl->members && decl->symtab)) {
195+
return;
196+
}
194197

195-
for (auto m : *decl->members) {
196-
m->accept(this);
197-
}
198+
DtoResolveClass(decl);
199+
decl->ir->setDefined();
198200

199-
IrClass *ir = getIrAggr(decl);
201+
for (auto m : *decl->members) {
202+
m->accept(this);
203+
}
200204

201-
auto &initZ = ir->getInitSymbol();
202-
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
203-
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
204-
setLinkageAndVisibility(decl, initGlobal);
205+
IrClass *ir = getIrAggr(decl);
205206

206-
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
207-
defineGlobal(vtbl, ir->getVtblInit(), decl);
207+
auto &initZ = ir->getInitSymbol();
208+
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
209+
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
210+
setLinkageAndVisibility(decl, initGlobal);
208211

209-
ir->defineInterfaceVtbls();
212+
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
213+
defineGlobal(vtbl, ir->getVtblInit(), decl);
210214

211-
// Emit TypeInfo.
212-
if (!ir->suppressTypeInfo() && !isSpeculativeType(decl->type)) {
213-
llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
214-
defineGlobal(classZ, ir->getClassInfoInit(), decl);
215-
}
215+
ir->defineInterfaceVtbls();
216+
217+
// Emit TypeInfo.
218+
if (!ir->suppressTypeInfo()) {
219+
llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
220+
defineGlobal(classZ, ir->getClassInfoInit(), decl);
216221
}
217222
}
218223

@@ -503,8 +508,7 @@ class CodegenVisitor : public Visitor {
503508
//////////////////////////////////////////////////////////////////////////
504509

505510
void visit(TypeInfoDeclaration *decl) override {
506-
if (!irs->dcomputetarget)
507-
TypeInfoDeclaration_codegen(decl);
511+
llvm_unreachable("Should be emitted from codegen layer only");
508512
}
509513
};
510514

gen/llvmhelpers.cpp

+8-14
Original file line numberDiff line numberDiff line change
@@ -827,8 +827,9 @@ void DtoResolveDsymbol(Dsymbol *dsym) {
827827
}
828828

829829
void DtoResolveVariable(VarDeclaration *vd) {
830-
if (vd->isTypeInfoDeclaration()) {
831-
return DtoResolveTypeInfo(static_cast<TypeInfoDeclaration *>(vd));
830+
if (auto tid = vd->isTypeInfoDeclaration()) {
831+
DtoResolveTypeInfo(tid);
832+
return;
832833
}
833834

834835
IF_LOG Logger::println("DtoResolveVariable(%s)", vd->toPrettyChars());
@@ -1263,17 +1264,12 @@ LLConstant *DtoTypeInfoOf(Type *type, bool base) {
12631264
type->toChars(), base);
12641265
LOG_SCOPE
12651266

1266-
TypeInfoDeclaration *tidecl =
1267-
getOrCreateTypeInfoDeclaration(Loc(), type, nullptr);
1268-
assert(tidecl);
1269-
Declaration_codegen(tidecl);
1270-
assert(getIrGlobal(tidecl)->value != NULL);
1271-
LLConstant *c = isaConstant(getIrGlobal(tidecl)->value);
1272-
assert(c != NULL);
1267+
auto tidecl = getOrCreateTypeInfoDeclaration(Loc(), type);
1268+
auto tiglobal = DtoResolveTypeInfo(tidecl);
12731269
if (base) {
1274-
return llvm::ConstantExpr::getBitCast(c, DtoType(getTypeInfoType()));
1270+
return llvm::ConstantExpr::getBitCast(tiglobal, DtoType(getTypeInfoType()));
12751271
}
1276-
return c;
1272+
return tiglobal;
12771273
}
12781274

12791275
////////////////////////////////////////////////////////////////////////////////
@@ -1560,10 +1556,8 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) {
15601556
// typeinfo
15611557
if (TypeInfoDeclaration *tid = vd->isTypeInfoDeclaration()) {
15621558
Logger::println("TypeInfoDeclaration");
1563-
DtoResolveTypeInfo(tid);
1564-
assert(getIrValue(tid));
15651559
LLType *vartype = DtoType(type);
1566-
LLValue *m = getIrValue(tid);
1560+
LLValue *m = DtoResolveTypeInfo(tid);
15671561
if (m->getType() != getPtrToType(vartype)) {
15681562
m = gIR->ir->CreateBitCast(m, vartype);
15691563
}

gen/toir.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2669,8 +2669,8 @@ class ToElemVisitor : public Visitor {
26692669

26702670
void visit(TypeidExp *e) override {
26712671
if (Type *t = isType(e->obj)) {
2672-
result = DtoSymbolAddress(
2673-
e->loc, e->type, getOrCreateTypeInfoDeclaration(e->loc, t, nullptr));
2672+
result = DtoSymbolAddress(e->loc, e->type,
2673+
getOrCreateTypeInfoDeclaration(e->loc, t));
26742674
return;
26752675
}
26762676
if (Expression *ex = isExpression(e->obj)) {

0 commit comments

Comments
 (0)