Skip to content

Commit d38cc83

Browse files
committed
Cache the result of FuncDeclaration.isTypeIsolated() because it is potentially a very expensive check..
This resulted in a large compile-time improvement on the large codebase at Weka.io (11min --> 3.5min).
1 parent 88cbe0e commit d38cc83

File tree

5 files changed

+31
-2
lines changed

5 files changed

+31
-2
lines changed

src/dmd/declaration.h

+2
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,8 @@ class FuncDeclaration : public Declaration
535535
VarDeclaration *vresult; // result variable for out contracts
536536
LabelDsymbol *returnLabel; // where the return goes
537537

538+
void *isTypeIsolatedCache; // An AA on the D side to cache an expensive check result
539+
538540
// used to prevent symbols in different
539541
// scopes from having the same name
540542
DsymbolTable *localsymtab;

src/dmd/frontend.h

+2
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,7 @@ class Type : public ASTNode
19571957
bool equals(const RootObject* const o) const;
19581958
bool equivalent(Type* t);
19591959
DYNCAST dyncast() const;
1960+
size_t getUniqueID() const;
19601961
Covariant covariant(Type* t, uint64_t* pstc = nullptr);
19611962
const char* toChars() const;
19621963
char* toPrettyChars(bool QualifyTypes = false);
@@ -2680,6 +2681,7 @@ class FuncDeclaration : public Declaration
26802681
const char* mangleString;
26812682
VarDeclaration* vresult;
26822683
LabelDsymbol* returnLabel;
2684+
void* isTypeIsolatedCache;
26832685
DsymbolTable* localsymtab;
26842686
VarDeclaration* vthis;
26852687
bool isThis2;

src/dmd/func.d

+19-2
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ extern (C++) class FuncDeclaration : Declaration
262262
VarDeclaration vresult; /// result variable for out contracts
263263
LabelDsymbol returnLabel; /// where the return goes
264264

265+
bool[size_t] isTypeIsolatedCache; /// cache for the potentially very expensive isTypeIsolated check
266+
265267
// used to prevent symbols in different
266268
// scopes from having the same name
267269
DsymbolTable localsymtab;
@@ -1530,8 +1532,23 @@ extern (C++) class FuncDeclaration : Declaration
15301532
extern (D) final bool isTypeIsolated(Type t)
15311533
{
15321534
StringTable!Type parentTypes;
1533-
parentTypes._init();
1534-
return isTypeIsolated(t, parentTypes);
1535+
const uniqueTypeID = t.getUniqueID();
1536+
if (uniqueTypeID)
1537+
{
1538+
const cacheResultPtr = uniqueTypeID in isTypeIsolatedCache;
1539+
if (cacheResultPtr !is null)
1540+
return *cacheResultPtr;
1541+
1542+
parentTypes._init();
1543+
const isIsolated = isTypeIsolated(t, parentTypes);
1544+
isTypeIsolatedCache[uniqueTypeID] = isIsolated;
1545+
return isIsolated;
1546+
}
1547+
else
1548+
{
1549+
parentTypes._init();
1550+
return isTypeIsolated(t, parentTypes);
1551+
}
15351552
}
15361553

15371554
///ditto

src/dmd/mtype.d

+7
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,13 @@ extern (C++) abstract class Type : ASTNode
426426
return DYNCAST.type;
427427
}
428428

429+
/// Returns a non-zero unique ID for this Type, or returns 0 if the Type does not (yet) have a unique ID.
430+
/// If `semantic()` has not been run, 0 is returned.
431+
final size_t getUniqueID() const
432+
{
433+
return cast(size_t) deco;
434+
}
435+
429436
extern (D)
430437
final Mcache* getMcache()
431438
{

src/dmd/mtype.h

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ class Type : public ASTNode
224224
bool equivalent(Type *t);
225225
// kludge for template.isType()
226226
DYNCAST dyncast() const { return DYNCAST_TYPE; }
227+
size_t getUniqueID() const;
227228
Covariant covariant(Type *t, StorageClass *pstc = NULL);
228229
const char *toChars() const;
229230
char *toPrettyChars(bool QualifyTypes = false);

0 commit comments

Comments
 (0)