Skip to content

Commit 19e1b4d

Browse files
committed
Go a bit further
1 parent c959ab3 commit 19e1b4d

File tree

5 files changed

+29
-184
lines changed

5 files changed

+29
-184
lines changed

dmd/dsymbolsem.d

+1-15
Original file line numberDiff line numberDiff line change
@@ -6074,21 +6074,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
60746074
printf("\tit's a match with instance %p, %d\n", tempinst.inst, tempinst.inst.semanticRun);
60756075
}
60766076

6077-
if (tempinst.minst)
6078-
{
6079-
bool moduleHasSiblingAlready = false;
6080-
for (auto ti = tempinst.primaryInst; ti; ti = ti.tnext)
6081-
{
6082-
if (ti.memberOf is tempinst.minst)
6083-
{
6084-
moduleHasSiblingAlready = true;
6085-
break;
6086-
}
6087-
}
6088-
6089-
if (!moduleHasSiblingAlready)
6090-
tempinst.appendToModuleMember();
6091-
}
6077+
tempinst.appendToModuleMember();
60926078

60936079
return;
60946080
}

dmd/dtemplate.d

+21-160
Original file line numberDiff line numberDiff line change
@@ -6068,161 +6068,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
60686068
*/
60696069
final bool needsCodegen()
60706070
{
6071-
// Now -allInst is just for the backward compatibility.
6072-
if (global.params.allInst)
6073-
{
6074-
//printf("%s minst = %s, enclosing (%s).isNonRoot = %d\n",
6075-
// toPrettyChars(), minst ? minst.toChars() : NULL,
6076-
// enclosing ? enclosing.toPrettyChars() : NULL, enclosing && enclosing.inNonRoot());
6077-
if (enclosing)
6078-
{
6079-
/* https://issues.dlang.org/show_bug.cgi?id=14588
6080-
* If the captured context is not a function
6081-
* (e.g. class), the instance layout determination is guaranteed,
6082-
* because the semantic/semantic2 pass will be executed
6083-
* even for non-root instances.
6084-
*/
6085-
if (!enclosing.isFuncDeclaration())
6086-
return true;
6087-
6088-
/* https://issues.dlang.org/show_bug.cgi?id=14834
6089-
* If the captured context is a function,
6090-
* this excessive instantiation may cause ODR violation, because
6091-
* -allInst and others doesn't guarantee the semantic3 execution
6092-
* for that function.
6093-
*
6094-
* If the enclosing is also an instantiated function,
6095-
* we have to rely on the ancestor's needsCodegen() result.
6096-
*/
6097-
if (TemplateInstance ti = enclosing.isInstantiated())
6098-
return ti.needsCodegen();
6099-
6100-
/* https://issues.dlang.org/show_bug.cgi?id=13415
6101-
* If and only if the enclosing scope needs codegen,
6102-
* this nested templates would also need code generation.
6103-
*/
6104-
return !enclosing.inNonRoot();
6105-
}
6106-
return true;
6107-
}
6108-
6109-
if (!minst)
6110-
{
6111-
// If this is a speculative instantiation,
6112-
// 1. do codegen if ancestors really needs codegen.
6113-
// 2. become non-speculative if siblings are not speculative
6114-
6115-
TemplateInstance tnext = this.tnext;
6116-
TemplateInstance tinst = this.tinst;
6117-
// At first, disconnect chain first to prevent infinite recursion.
6118-
this.tnext = null;
6119-
this.tinst = null;
6120-
6121-
// Determine necessity of tinst before tnext.
6122-
if (tinst && tinst.needsCodegen())
6123-
{
6124-
minst = tinst.minst; // cache result
6125-
assert(minst);
6126-
assert(minst.isRoot() || minst.rootImports());
6127-
return true;
6128-
}
6129-
if (tnext && (tnext.needsCodegen() || tnext.minst))
6130-
{
6131-
minst = tnext.minst; // cache result
6132-
assert(minst);
6133-
return minst.isRoot() || minst.rootImports();
6134-
}
6135-
6136-
// Elide codegen because this is really speculative.
6137-
return false;
6138-
}
6139-
6140-
/* Even when this is reached to the codegen pass,
6141-
* a non-root nested template should not generate code,
6142-
* due to avoid ODR violation.
6143-
*/
6144-
if (enclosing && enclosing.inNonRoot())
6145-
{
6146-
if (tinst)
6147-
{
6148-
auto r = tinst.needsCodegen();
6149-
minst = tinst.minst; // cache result
6150-
return r;
6151-
}
6152-
if (tnext)
6153-
{
6154-
auto r = tnext.needsCodegen();
6155-
minst = tnext.minst; // cache result
6156-
return r;
6157-
}
6158-
return false;
6159-
}
6160-
6161-
if (true)//global.params.useUnitTests)
6162-
{
6163-
// Prefer instantiations from root modules, to maximize link-ability.
6164-
if (minst.isRoot())
6165-
return true;
6166-
6167-
TemplateInstance tnext = this.tnext;
6168-
TemplateInstance tinst = this.tinst;
6169-
this.tnext = null;
6170-
this.tinst = null;
6171-
6172-
if (tinst && tinst.needsCodegen())
6173-
{
6174-
minst = tinst.minst; // cache result
6175-
assert(minst);
6176-
assert(minst.isRoot() || minst.rootImports());
6177-
return true;
6178-
}
6179-
if (tnext && tnext.needsCodegen())
6180-
{
6181-
minst = tnext.minst; // cache result
6182-
assert(minst);
6183-
assert(minst.isRoot() || minst.rootImports());
6184-
return true;
6185-
}
6186-
6187-
// https://issues.dlang.org/show_bug.cgi?id=2500 case
6188-
if (false)//minst.rootImports())
6189-
return true;
6190-
6191-
// Elide codegen because this is not included in root instances.
6192-
return false;
6193-
}
6194-
else
6195-
{
6196-
// Prefer instantiations from non-root module, to minimize object code size.
6197-
6198-
/* If a TemplateInstance is ever instantiated by non-root modules,
6199-
* we do not have to generate code for it,
6200-
* because it will be generated when the non-root module is compiled.
6201-
*
6202-
* But, if the non-root 'minst' imports any root modules, it might still need codegen.
6203-
*
6204-
* The problem is if A imports B, and B imports A, and both A
6205-
* and B instantiate the same template, does the compilation of A
6206-
* or the compilation of B do the actual instantiation?
6207-
*
6208-
* See https://issues.dlang.org/show_bug.cgi?id=2500.
6209-
*/
6210-
if (!minst.isRoot() && !minst.rootImports())
6211-
return false;
6212-
6213-
TemplateInstance tnext = this.tnext;
6214-
this.tnext = null;
6215-
6216-
if (tnext && !tnext.needsCodegen() && tnext.minst)
6217-
{
6218-
minst = tnext.minst; // cache result
6219-
assert(!minst.isRoot());
6220-
return false;
6221-
}
6222-
6223-
// Do codegen because this is not included in non-root instances.
6224-
return true;
6225-
}
6071+
return minst && minst.isRoot();
62266072
}
62276073

62286074
/**********************************************
@@ -7165,9 +7011,14 @@ extern (C++) class TemplateInstance : ScopeDsymbol
71657011
}
71667012
*/
71677013

7168-
if (!mi)
7014+
if (!mi || !mi.isRoot())
71697015
return null;
71707016

7017+
// skip if a sibling has already been added
7018+
for (auto sibling = primaryInst; sibling; sibling = sibling.tnext)
7019+
if (sibling.memberOf is mi)
7020+
return null;
7021+
71717022
/++
71727023
//printf("%s.appendToModuleMember() enclosing = %s mi = %s\n",
71737024
// toPrettyChars(),
@@ -7228,10 +7079,20 @@ extern (C++) class TemplateInstance : ScopeDsymbol
72287079
Dsymbols* a = mi.members;
72297080
a.push(this);
72307081
memberOf = mi;
7231-
if (mi.semanticRun >= PASS.semantic2done && mi.isRoot())
7232-
Module.addDeferredSemantic2(this);
7233-
if (mi.semanticRun >= PASS.semantic3done && mi.isRoot())
7234-
Module.addDeferredSemantic3(this);
7082+
if (!primaryInst)
7083+
{
7084+
if (mi.semanticRun >= PASS.semantic2done)
7085+
Module.addDeferredSemantic2(this);
7086+
if (mi.semanticRun >= PASS.semantic3done)
7087+
Module.addDeferredSemantic3(this);
7088+
}
7089+
else if (!primaryInst.memberOf || !primaryInst.memberOf.isRoot())
7090+
{
7091+
//printf(".: deferredSemantic for non-root primaryInst: %s\n", primaryInst.toChars());
7092+
Module.addDeferredSemantic2(primaryInst);
7093+
Module.addDeferredSemantic3(primaryInst);
7094+
primaryInst.memberOf = mi; // HACK
7095+
}
72357096
return a;
72367097
}
72377098

gen/declarations.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -366,18 +366,16 @@ class CodegenVisitor : public Visitor {
366366
return;
367367
}
368368

369-
auto members = decl->primaryInst && decl->primaryInst->members
370-
? decl->primaryInst->members /*Dsymbol::arraySyntaxCopy(
371-
decl->primaryInst->members)*/
372-
: decl->members;
369+
auto members =
370+
decl->primaryInst ? decl->primaryInst->members : decl->members;
373371

374372
if (!members) {
375373
Logger::println("Has no members, skipping.");
376374
return;
377375
}
378376

379377
// FIXME: This is #673 all over again.
380-
if (false) { // (!decl->needsCodegen()) {
378+
if (!decl->needsCodegen()) {
381379
// Force codegen if this is a templated function with pragma(inline,
382380
// true).
383381
if (members->length == 1 && (*members)[0]->isFuncDeclaration() &&

gen/modules.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ void codegenModule(IRState *irs, Module *m) {
606606

607607
// process module members
608608
// NOTE: m->members may grow during codegen
609-
for (unsigned k = 0; k < m->members->length; k++) {
609+
for (d_size_t k = 0; k < m->members->length; k++) {
610610
Dsymbol *dsym = (*m->members)[k];
611611
assert(dsym);
612612
Declaration_codegen(dsym);

gen/runtime.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ static void checkForImplicitGCCall(const Loc &loc, const char *name) {
110110
////////////////////////////////////////////////////////////////////////////////
111111

112112
bool initRuntime() {
113-
Logger::println("*** Initializing D runtime declarations ***");
114-
LOG_SCOPE;
115-
116113
if (!M) {
114+
Logger::println("*** Initializing D runtime declarations ***");
115+
LOG_SCOPE;
116+
117117
buildRuntimeModule();
118118
}
119119

0 commit comments

Comments
 (0)