Skip to content

Commit

Permalink
Merge pull request #4944 from 9rnsr/fix14431
Browse files Browse the repository at this point in the history
[REG 2.067.0] Issue 14431 - huge slowdown of compilation speed
  • Loading branch information
MartinNowak committed Aug 30, 2015
2 parents b30556b + 083ea4a commit 92fcc9d
Show file tree
Hide file tree
Showing 23 changed files with 692 additions and 125 deletions.
5 changes: 5 additions & 0 deletions src/aggregate.h
Expand Up @@ -170,6 +170,11 @@ class StructDeclaration : public AggregateDeclaration
Type *arg1type;
Type *arg2type;

// Even if struct is defined as non-root symbol, some built-in operations
// (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
// For those, today TypeInfo_Struct is generated in COMDAT.
bool requestTypeInfo;

StructDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
Expand Down
5 changes: 4 additions & 1 deletion src/expression.c
Expand Up @@ -4156,7 +4156,7 @@ Expression *ArrayLiteralExp::semantic(Scope *sc)
return new ErrorExp();
}

semanticTypeInfo(sc, t0);
semanticTypeInfo(sc, type);

return this;
}
Expand Down Expand Up @@ -6112,6 +6112,9 @@ Expression *TypeidExp::semantic(Scope *sc)
// Handle this in the glue layer
e = new TypeidExp(loc, ta);
e->type = getTypeInfoType(ta, sc);

semanticTypeInfo(sc, ta);

if (ea)
{
e = new CommaExp(loc, ea, e); // execute ea
Expand Down
63 changes: 63 additions & 0 deletions src/inline.c
Expand Up @@ -919,6 +919,26 @@ Expression *doInline(Expression *e, InlineDoState *ids)
ne->newargs = arrayExpressiondoInline(e->newargs);
ne->arguments = arrayExpressiondoInline(e->arguments);
result = ne;

semanticTypeInfo(NULL, e->type);
}

void visit(DeleteExp *e)
{
visit((UnaExp *)e);

Type *tb = e->e1->type->toBasetype();
if (tb->ty == Tarray)
{
Type *tv = tb->nextOf()->baseElemOf();
if (tv->ty == Tstruct)
{
TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->dtor)
semanticTypeInfo(NULL, ts);
}
}
}

void visit(UnaExp *e)
Expand Down Expand Up @@ -957,6 +977,37 @@ Expression *doInline(Expression *e, InlineDoState *ids)
result = ce;
}

void visit(AssignExp *e)
{
visit((BinExp *)e);

if (e->e1->op == TOKarraylength)
{
ArrayLengthExp *ale = (ArrayLengthExp *)e->e1;
Type *tn = ale->e1->type->toBasetype()->nextOf();
semanticTypeInfo(NULL, tn);
}
}

void visit(EqualExp *e)
{
visit((BinExp *)e);

Type *t1 = e->e1->type->toBasetype();
if (t1->ty == Tarray || t1->ty == Tsarray)
{
Type *t = t1->nextOf()->toBasetype();
while (t->toBasetype()->nextOf())
t = t->nextOf()->toBasetype();
if (t->ty == Tstruct)
semanticTypeInfo(NULL, t);
}
else if (t1->ty == Taarray)
{
semanticTypeInfo(NULL, t1);
}
}

void visit(IndexExp *e)
{
IndexExp *are = (IndexExp *)e->copy();
Expand Down Expand Up @@ -1042,6 +1093,8 @@ Expression *doInline(Expression *e, InlineDoState *ids)

ce->elements = arrayExpressiondoInline(e->elements);
result = ce;

semanticTypeInfo(NULL, e->type);
}

void visit(AssocArrayLiteralExp *e)
Expand All @@ -1051,6 +1104,8 @@ Expression *doInline(Expression *e, InlineDoState *ids)
ce->keys = arrayExpressiondoInline(e->keys);
ce->values = arrayExpressiondoInline(e->values);
result = ce;

semanticTypeInfo(NULL, e->type);
}

void visit(StructLiteralExp *e)
Expand Down Expand Up @@ -1838,6 +1893,14 @@ static Expression *expandInline(FuncDeclaration *fd, FuncDeclaration *parent,
ids.parent = parent;
ids.fd = fd;

// When the function is actually expanded
if (TemplateInstance *ti = fd->isInstantiated())
{
// change ti to non-speculative instance
if (!ti->minst)
ti->minst = ti->tempdecl->getModule();
}

if (ps)
as = new Statements();

Expand Down
1 change: 1 addition & 0 deletions src/magicport.json
Expand Up @@ -248,6 +248,7 @@
"aggregate",
"argtypes",
"arraytypes",
"backend",
"clone",
"declaration",
"dmodule",
Expand Down
29 changes: 25 additions & 4 deletions src/struct.c
Expand Up @@ -24,6 +24,7 @@
#include "template.h"
#include "tokens.h"

Type *getTypeInfoType(Type *t, Scope *sc);
TypeTuple *toArgTypes(Type *t);

FuncDeclaration *StructDeclaration::xerreq; // object.xopEquals
Expand Down Expand Up @@ -100,12 +101,31 @@ void semanticTypeInfo(Scope *sc, Type *t)

// If the struct is in a non-root module, run semantic3 to get
// correct symbols for the member function.
// Note that, all instantiated symbols will run semantic3.
if (sd->inNonRoot())
if (TemplateInstance *ti = sd->isInstantiated())
{
//printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot());
Module::addDeferredSemantic3(sd);
if (ti->minst && !ti->minst->isRoot())
Module::addDeferredSemantic3(sd);
}
else
{
if (sd->inNonRoot())
{
//printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot());
Module::addDeferredSemantic3(sd);
}
}

if (!sc) // inline may request TypeInfo.
{
Scope scx;
scx.module = sd->getModule();
getTypeInfoType(t, &scx);
}
else
getTypeInfoType(t, sc);

if (!sc || sc->minst)
sd->requestTypeInfo = true;
}
void visit(TypeClass *t) { }
void visit(TypeTuple *t)
Expand Down Expand Up @@ -663,6 +683,7 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
ispod = ISPODfwd;
arg1type = NULL;
arg2type = NULL;
requestTypeInfo = false;

// For forward references
type = new TypeStruct(this);
Expand Down

0 comments on commit 92fcc9d

Please sign in to comment.